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)