305 lines
8.3 KiB
Python
305 lines
8.3 KiB
Python
import math
|
|
import numpy
|
|
# 환율
|
|
EXCHANGE_RATE = 190
|
|
|
|
# 카드 결제 수수료
|
|
CARD_FEE = 0.035
|
|
|
|
# 마켓 수수료
|
|
MARKET_FEE = 0.13
|
|
|
|
# 최종 마진율 범위
|
|
FINAL_MARGIN_RANGE = (0.22, 0.29)
|
|
|
|
# 허용 오차 범위
|
|
PRICE_TOLERANCE = (0.1, -0.1)
|
|
|
|
|
|
# 기본 마진
|
|
BASE_MARGIN = 0.22
|
|
|
|
# 더하기 마진 기본값
|
|
PLUS_MARGIN_DEFAULT = 5000
|
|
|
|
# 반품 비용
|
|
RETURN_FEE = 0
|
|
|
|
# 네이버 상품 정보
|
|
ns_low_price = 90000 # 최저가
|
|
ns_avg_price = 150000 # 평균가
|
|
ns_high_price = 220000 # 최고가
|
|
|
|
# 타오바오 상품 정보
|
|
tao_low_price = 200 # 최저가 (위안)
|
|
tao_high_price = 300 # 최고가 (위안)
|
|
delv_fee = 30000 # 배송비
|
|
|
|
# 포장비
|
|
packing_fee = 5000
|
|
|
|
# 상품 무게
|
|
weight = 1 # kg
|
|
|
|
# 최종 판매 가격
|
|
my_price = None
|
|
|
|
# 최종 마진율
|
|
final_margin = None
|
|
|
|
# 더하기 마진
|
|
plus_margin = None
|
|
|
|
# 상품 원가
|
|
product_cost = None
|
|
|
|
# 마켓 수수료
|
|
market_fee_amount = None
|
|
|
|
# 판매 마진
|
|
margin = None
|
|
|
|
def calculate_product_cost(tao_price, delv_fee, packing_fee, plus_margin=0):
|
|
"""
|
|
상품 원가를 계산합니다.
|
|
|
|
Args:
|
|
tao_price: 타오바오 상품 가격 (위안)
|
|
delv_fee: 배송비
|
|
packing_fee: 포장비
|
|
plus_margin: 더하기 마진
|
|
|
|
Returns:
|
|
상품 원가
|
|
"""
|
|
return (
|
|
tao_price * EXCHANGE_RATE * (1 + CARD_FEE) * (1 + BASE_MARGIN + plus_margin)
|
|
+ delv_fee
|
|
+ packing_fee
|
|
)
|
|
|
|
|
|
def calculate_minimum_plus_margin(product_cost, return_fee):
|
|
"""
|
|
최소 더하기 마진을 계산합니다.
|
|
|
|
Args:
|
|
product_cost: 상품 원가
|
|
return_fee: 반품 비용
|
|
|
|
Returns:
|
|
최소 더하기 마진
|
|
"""
|
|
return max(PLUS_MARGIN_DEFAULT, product_cost + delv_fee - return_fee)
|
|
|
|
|
|
def calculate_final_margin(my_price, product_cost):
|
|
"""
|
|
최종 마진율을 계산합니다.
|
|
|
|
Args:
|
|
my_price: 판매 가격
|
|
product_cost: 상품 원가
|
|
|
|
Returns:
|
|
최종 마진율
|
|
"""
|
|
return(my_price - product_cost) / my_price
|
|
|
|
|
|
def adjust_plus_margin(my_price, ns_avg_price, price_tolerance, final_margin_range):
|
|
"""
|
|
더하기 마진을 조정합니다.
|
|
|
|
Args:
|
|
my_price: 판매 가격
|
|
ns_avg_price: 네이버 평균 가격
|
|
price_tolerance: 허용 오차 범위
|
|
final_margin_range: 최종 마진율 범위
|
|
|
|
Returns:
|
|
조정된 더하기 마진
|
|
"""
|
|
min_price = ns_avg_price * (1 + price_tolerance[0])
|
|
max_price = ns_avg_price * (1 + price_tolerance[1])
|
|
|
|
if my_price < min_price:
|
|
return my_price - product_cost - market_fee_amount
|
|
|
|
if my_price > max_price:
|
|
return max(PLUS_MARGIN_DEFAULT, calculate_minimum_plus_margin(product_cost, return_fee))
|
|
|
|
min_plus_margin = calculate_minimum_plus_margin(product_cost, return_fee)
|
|
max_plus_margin = (
|
|
max_price
|
|
- product_cost
|
|
- market_fee_amount
|
|
- delv_fee
|
|
- packing_fee
|
|
)
|
|
|
|
for plus_margin in numpy.arange(min_plus_margin, max_plus_margin + 1):
|
|
final_margin = calculate_final_margin(
|
|
my_price, calculate_product_cost(tao_low_price, delv_fee, packing_fee, plus_margin)
|
|
)
|
|
|
|
if final_margin_range[0] <= final_margin <= final_margin_range[1]:
|
|
return plus_margin
|
|
|
|
return None
|
|
|
|
def calculate_optimal_price(
|
|
tao_low_price,
|
|
tao_high_price,
|
|
delv_fee,
|
|
packing_fee,
|
|
ns_low_price,
|
|
ns_avg_price,
|
|
ns_high_price,
|
|
):
|
|
"""
|
|
최적의 더하기 마진을 찾아 최종 판매 가격을 계산합니다.
|
|
|
|
Args:
|
|
tao_low_price: 타오바오 상품 최저가 (위안)
|
|
tao_high_price: 타오바오 상품 최고가 (위안)
|
|
delv_fee: 배송비
|
|
packing_fee: 포장비
|
|
ns_low_price: 네이버 최저가
|
|
ns_avg_price: 네이버 평균가
|
|
ns_high_price: 네이버 최고가
|
|
|
|
Returns:
|
|
상품 가격 정보
|
|
"""
|
|
|
|
min_product_cost = calculate_product_cost(tao_low_price, delv_fee, packing_fee)
|
|
max_product_cost = calculate_product_cost(tao_high_price, delv_fee, packing_fee)
|
|
|
|
min_avg_price = ns_avg_price * (1 - price_tolerance[1])
|
|
max_avg_price = ns_avg_price * (1 + price_tolerance[0])
|
|
|
|
# 1천원 단위로 더하기 마진 조정
|
|
|
|
for plus_margin in range(PLUS_MARGIN_DEFAULT, max_product_cost + 1000, 1000):
|
|
my_price = calculate_product_cost(tao_low_price, delv_fee, packing_fee, plus_margin)
|
|
market_fee_amount = my_price * MARKET_FEE
|
|
final_margin = calculate_final_margin(my_price, product_cost)
|
|
|
|
# 최종 마진율 범위에 포함되면 결과 출력
|
|
if FINAL_MARGIN_RANGE[0] <= final_margin <= FINAL_MARGIN_RANGE[1]:
|
|
return {
|
|
"min_product_cost": min_product_cost,
|
|
"max_product_cost": max_product_cost,
|
|
"min_avg_price": min_avg_price,
|
|
"max_avg_price": max_avg_price,
|
|
"my_price": my_price,
|
|
"plus_margin": plus_margin,
|
|
"market_fee_amount": market_fee_amount,
|
|
"margin": my_price - product_cost - market_fee_amount,
|
|
"final_margin": final_margin,
|
|
}
|
|
|
|
# 최종 마진율 범위에 포함되는 더하기 마진을 찾지 못하면 오류 메시지 출력
|
|
raise ValueError(
|
|
f"최종 마진율 범위({FINAL_MARGIN_RANGE[0]:.2%} ~ {FINAL_MARGIN_RANGE[1]:.2%})에 "
|
|
f"포함되는 더하기 마진을 찾지 못했습니다."
|
|
)
|
|
|
|
|
|
def calculate_price(
|
|
tao_low_price,
|
|
tao_high_price,
|
|
delv_fee,
|
|
packing_fee,
|
|
ns_low_price,
|
|
ns_avg_price,
|
|
ns_high_price,
|
|
):
|
|
"""
|
|
상품 가격을 계산합니다.
|
|
|
|
Args:
|
|
tao_low_price: 타오바오 상품 최저가 (위안)
|
|
tao_high_price: 타오바오 상품 최고가 (위안)
|
|
delv_fee: 배송비
|
|
packing_fee: 포장비
|
|
ns_low_price: 네이버 최저가
|
|
ns_avg_price: 네이버 평균가
|
|
ns_high_price: 네이버 최고가
|
|
|
|
Returns:
|
|
상품 가격 정보
|
|
"""
|
|
|
|
# 1. 상품 원가 계산
|
|
|
|
min_product_cost = calculate_product_cost(tao_low_price, delv_fee, packing_fee)
|
|
max_product_cost = calculate_product_cost(tao_high_price, delv_fee, packing_fee)
|
|
|
|
# 2. 네이버 평균 가격 기준 내 상품 가격 범위 계산
|
|
|
|
min_avg_price = ns_avg_price * (1 - price_tolerance[1])
|
|
max_avg_price = ns_avg_price * (1 + price_tolerance[0])
|
|
|
|
plus_margin = PLUS_MARGIN_DEFAULT
|
|
|
|
my_price = calculate_product_cost(
|
|
tao_low_price, delv_fee, packing_fee, plus_margin
|
|
) + market_fee_amount * my_price
|
|
|
|
# **오류 해결**: `final_margin` 변수 선언
|
|
final_margin = calculate_final_margin(my_price, product_cost)
|
|
|
|
if final_margin < FINAL_MARGIN_RANGE[0]:
|
|
plus_margin = adjust_plus_margin(
|
|
my_price, ns_avg_price, price_tolerance, final_margin_range
|
|
)
|
|
my_price = calculate_product_cost(
|
|
tao_low_price, delv_fee, packing_fee, plus_margin
|
|
) + market_fee_amount * my_price
|
|
final_margin = calculate_final_margin(my_price, product_cost)
|
|
|
|
elif final_margin > FINAL_MARGIN_RANGE[1]:
|
|
plus_margin = adjust_plus_margin(
|
|
my_price, ns_avg_price, price_tolerance, final_margin_range
|
|
)
|
|
my_price = calculate_product_cost(
|
|
tao_low_price, delv_fee, packing_fee, plus_margin
|
|
) + market_fee_amount * my_price
|
|
final_margin = calculate_final_margin(my_price, product_cost)
|
|
|
|
return {
|
|
"min_product_cost": min_product_cost,
|
|
"max_product_cost": max_product_cost,
|
|
"min_avg_price": min_avg_price,
|
|
"max_avg_price": max_avg_price,
|
|
"my_price": my_price,
|
|
"plus_margin": plus_margin,
|
|
"final_margin": final_margin,
|
|
}
|
|
|
|
|
|
|
|
tao_low_price = float(input("타오바오 최저가 (위안): "))
|
|
tao_high_price = float(input("타오바오 최고가 (위안): "))
|
|
delv_fee = int(input("배송비: "))
|
|
packing_fee = int(input("포장비: "))
|
|
ns_low_price = int(input("네이버 최저가: "))
|
|
ns_high_price = int(input("네이버 최고가: "))
|
|
ns_avg_price = (ns_low_price + ns_high_price)/2
|
|
|
|
# 최적의 더하기 마진 계산
|
|
result = calculate_optimal_price(
|
|
tao_low_price,
|
|
tao_high_price,
|
|
delv_fee,
|
|
packing_fee,
|
|
ns_low_price,
|
|
ns_avg_price,
|
|
ns_high_price,
|
|
)
|
|
|
|
# 결과 출력
|
|
for key, value in result.items():
|
|
print(f"{key}: {value}") |