192 lines
7.1 KiB
Plaintext
192 lines
7.1 KiB
Plaintext
|
|
user_id = await get_user()
|
|
user_orgid = await get_userorgid()
|
|
dbname = get_module_dbname('supplychain')
|
|
|
|
# Parse input
|
|
data = params_kw.get("data", "{}")
|
|
if isinstance(data, str):
|
|
data = json.loads(data)
|
|
|
|
productid = data.get("productid")
|
|
prodtypeid = data.get("prodtypeid")
|
|
quantity = float(data.get("quantity", 0))
|
|
unit_price = float(data.get("unit_price", 0))
|
|
sub_distributor_id = data.get("sub_distributor_id")
|
|
sale_date = data.get("sale_date", curDateString())
|
|
source_type = data.get("source_type", "2")
|
|
source_id = data.get("source_id")
|
|
remark = data.get("remark", "")
|
|
|
|
if not productid or quantity <= 0 or unit_price <= 0:
|
|
return json.dumps({"status": "error", "message": "缺少必要参数: productid, quantity, unit_price"})
|
|
|
|
db = DBPools()
|
|
total_amount = quantity * unit_price
|
|
|
|
async with db.sqlorContext(dbname) as sor:
|
|
# Step 1: Find active supply contract with product discount
|
|
supply_contract_id = None
|
|
supply_contract_item_id = None
|
|
supplier_id = None
|
|
supply_discount = 1.0
|
|
supply_amount = total_amount
|
|
|
|
if prodtypeid:
|
|
sql_sci = """SELECT sci.id, sci.contract_id, sci.discount, sci.settlement_price, sc.supplier_id
|
|
FROM supply_contract_items sci
|
|
JOIN supply_contracts sc ON sci.contract_id = sc.id
|
|
WHERE sci.resellerid = ${resellerid}$
|
|
AND sc.status = '1'
|
|
AND sc.start_date <= ${sale_date}$
|
|
AND (sc.end_date IS NULL OR sc.end_date >= ${sale_date}$)
|
|
AND sci.productid = ${productid}$
|
|
ORDER BY sci.created_at DESC LIMIT 1"""
|
|
ns_sci = {"resellerid": user_orgid, "sale_date": sale_date, "productid": productid}
|
|
sci_recs = await sor.sqlExe(sql_sci, ns_sci)
|
|
|
|
if not prodtypeid or not sci_recs:
|
|
sql_sci = """SELECT sci.id, sci.contract_id, sci.discount, sci.settlement_price, sc.supplier_id
|
|
FROM supply_contract_items sci
|
|
JOIN supply_contracts sc ON sci.contract_id = sc.id
|
|
WHERE sci.resellerid = ${resellerid}$
|
|
AND sc.status = '1'
|
|
AND sc.start_date <= ${sale_date}$
|
|
AND (sc.end_date IS NULL OR sc.end_date >= ${sale_date}$)
|
|
AND sci.prodtypeid = ${prodtypeid}$
|
|
ORDER BY sci.created_at DESC LIMIT 1"""
|
|
ns_sci = {"resellerid": user_orgid, "sale_date": sale_date, "prodtypeid": prodtypeid}
|
|
sci_recs = await sor.sqlExe(sql_sci, ns_sci)
|
|
|
|
if sci_recs:
|
|
supply_contract_item_id = sci_recs[0].id
|
|
supply_contract_id = sci_recs[0].contract_id
|
|
supplier_id = sci_recs[0].supplier_id
|
|
supply_discount = float(sci_recs[0].discount) if sci_recs[0].discount else 1.0
|
|
if sci_recs[0].settlement_price:
|
|
supply_amount = float(sci_recs[0].settlement_price) * quantity
|
|
else:
|
|
supply_amount = total_amount * supply_discount
|
|
else:
|
|
sql_sc = """SELECT id, supplier_id, default_discount FROM supply_contracts
|
|
WHERE resellerid = ${resellerid}$
|
|
AND status = '1'
|
|
AND start_date <= ${sale_date}$
|
|
AND (end_date IS NULL OR end_date >= ${sale_date}$)
|
|
ORDER BY created_at DESC LIMIT 1"""
|
|
sc_recs = await sor.sqlExe(sql_sc, {"resellerid": user_orgid, "sale_date": sale_date})
|
|
if sc_recs:
|
|
supply_contract_id = sc_recs[0].id
|
|
supplier_id = sc_recs[0].supplier_id
|
|
supply_discount = float(sc_recs[0].default_discount) if sc_recs[0].default_discount else 1.0
|
|
supply_amount = total_amount * supply_discount
|
|
|
|
# Step 2: Find active distribution agreement with product discount
|
|
distribution_agreement_id = None
|
|
distribution_agreement_item_id = None
|
|
dist_discount = 1.0
|
|
dist_amount = total_amount
|
|
|
|
if sub_distributor_id:
|
|
sql_dai = """SELECT dai.id, dai.agreement_id, dai.discount, dai.settlement_price
|
|
FROM distribution_agreement_items dai
|
|
JOIN distribution_agreements da ON dai.agreement_id = da.id
|
|
WHERE dai.resellerid = ${resellerid}$
|
|
AND da.sub_distributor_id = ${sub_distributor_id}$
|
|
AND da.status = '1'
|
|
AND da.start_date <= ${sale_date}$
|
|
AND (da.end_date IS NULL OR da.end_date >= ${sale_date}$)
|
|
AND dai.productid = ${productid}$
|
|
ORDER BY dai.created_at DESC LIMIT 1"""
|
|
ns_dai = {"resellerid": user_orgid, "sub_distributor_id": sub_distributor_id,
|
|
"sale_date": sale_date, "productid": productid}
|
|
dai_recs = await sor.sqlExe(sql_dai, ns_dai)
|
|
|
|
if not dai_recs and prodtypeid:
|
|
sql_dai = """SELECT dai.id, dai.agreement_id, dai.discount, dai.settlement_price
|
|
FROM distribution_agreement_items dai
|
|
JOIN distribution_agreements da ON dai.agreement_id = da.id
|
|
WHERE dai.resellerid = ${resellerid}$
|
|
AND da.sub_distributor_id = ${sub_distributor_id}$
|
|
AND da.status = '1'
|
|
AND da.start_date <= ${sale_date}$
|
|
AND (da.end_date IS NULL OR da.end_date >= ${sale_date}$)
|
|
AND dai.prodtypeid = ${prodtypeid}$
|
|
ORDER BY dai.created_at DESC LIMIT 1"""
|
|
dai_recs = await sor.sqlExe(sql_dai, {"resellerid": user_orgid,
|
|
"sub_distributor_id": sub_distributor_id,
|
|
"sale_date": sale_date,
|
|
"prodtypeid": prodtypeid})
|
|
|
|
if dai_recs:
|
|
distribution_agreement_item_id = dai_recs[0].id
|
|
distribution_agreement_id = dai_recs[0].agreement_id
|
|
dist_discount = float(dai_recs[0].discount) if dai_recs[0].discount else 1.0
|
|
if dai_recs[0].settlement_price:
|
|
dist_amount = float(dai_recs[0].settlement_price) * quantity
|
|
else:
|
|
dist_amount = total_amount * dist_discount
|
|
else:
|
|
sql_da = """SELECT id, default_discount FROM distribution_agreements
|
|
WHERE resellerid = ${resellerid}$
|
|
AND sub_distributor_id = ${sub_distributor_id}$
|
|
AND status = '1'
|
|
AND start_date <= ${sale_date}$
|
|
AND (end_date IS NULL OR end_date >= ${sale_date}$)
|
|
ORDER BY created_at DESC LIMIT 1"""
|
|
da_recs = await sor.sqlExe(sql_da, {"resellerid": user_orgid,
|
|
"sub_distributor_id": sub_distributor_id,
|
|
"sale_date": sale_date})
|
|
if da_recs:
|
|
distribution_agreement_id = da_recs[0].id
|
|
dist_discount = float(da_recs[0].default_discount) if da_recs[0].default_discount else 1.0
|
|
dist_amount = total_amount * dist_discount
|
|
|
|
# Step 3: Calculate profit
|
|
profit_amount = dist_amount - supply_amount
|
|
|
|
# Step 4: Create accounting record
|
|
accounting_id = getID()
|
|
record = {
|
|
"id": accounting_id,
|
|
"resellerid": user_orgid,
|
|
"supply_contract_id": supply_contract_id,
|
|
"supply_contract_item_id": supply_contract_item_id,
|
|
"distribution_agreement_id": distribution_agreement_id,
|
|
"distribution_agreement_item_id": distribution_agreement_item_id,
|
|
"sub_distributor_id": sub_distributor_id,
|
|
"supplier_id": supplier_id,
|
|
"prodtypeid": prodtypeid,
|
|
"productid": productid,
|
|
"quantity": quantity,
|
|
"unit_price": unit_price,
|
|
"supply_discount": supply_discount,
|
|
"supply_amount": supply_amount,
|
|
"dist_discount": dist_discount,
|
|
"dist_amount": dist_amount,
|
|
"profit_amount": profit_amount,
|
|
"sale_date": sale_date,
|
|
"source_type": source_type,
|
|
"source_id": source_id,
|
|
"remark": remark,
|
|
"created_by": user_id,
|
|
"created_at": timestampstr()
|
|
}
|
|
|
|
await sor.C("supplychain_accounting", record)
|
|
|
|
result = {
|
|
"status": "ok",
|
|
"data": record,
|
|
"summary": {
|
|
"total_amount": total_amount,
|
|
"supply_amount": supply_amount,
|
|
"dist_amount": dist_amount,
|
|
"profit_amount": profit_amount,
|
|
"supply_discount": supply_discount,
|
|
"dist_discount": dist_discount
|
|
}
|
|
}
|
|
|
|
return json.dumps(result)
|