diff --git a/product_management/core.py b/product_management/core.py index d4319cf..c785b72 100644 --- a/product_management/core.py +++ b/product_management/core.py @@ -1389,12 +1389,16 @@ class ProductManager: async def calculate_product_cost(self, product_id=None, product_code=None, usage_data=None, user_org_id=None): - """计算消费费用:资源真实定价 × 产品级折扣。 + """计算消费费用:资源真实定价 + 客户折扣(售价) + 供应商折扣(成本)。 - 折扣精确到 product_id(discount_detail.productid),三类折扣取最优惠: - - 客户折扣:get_min_product_discount(product_id, resellerid, customerid) - - 分销商折扣:get_min_distributor_discount(product_id, resellerid, distributorid) - - 供应商折扣:get_min_supplier_discount(product_id, resellerid, supplierid) + 三类折扣各自独立、归属不同环节,不取 min: + - 客户折扣 discount 模块 get_min_product_discount → amount(客户应付售价) + - 供应商折扣 supplychain 模块 calculate_sale_amounts → cost(平台进货成本) + - 分销商折扣 分销场景单独用(calculate_sale_amounts 的 distribution_amount), + 不进本函数。 + + 返回:original_amount(资源真实定价)、amount(售价=原价×客户折扣)、 + cost(成本=原价×供应商折扣)、discount(客户折扣率) """ iface, product, err = await self._get_product_interface( product_id, product_code) @@ -1423,51 +1427,59 @@ class ProductManager: original_amount = float(result.get('original_amount', result.get('amount', 0) or 0)) - # 2. 产品级折扣:精确到 product_id,取最优惠(min) env = ServerEnv() resellerid = product.get('org_id') or '0' pid = product.get('id') or '' - final_discount = 1.0 - # 2a. 客户折扣(customerid 精确 + '*'/NULL 通配) + # 2. 客户折扣(discount 模块,售价侧)→ amount + discount = 1.0 if user_org_id: try: d = await env.get_min_product_discount(pid, resellerid, user_org_id) if d not in (None, '', 0): - final_discount = min(final_discount, float(d)) + discount = float(d) except Exception: pass + amount = original_amount * discount - # 2b. 分销商折扣(客户归属的分销商,discount_customer_bind) + # 3. 供应商折扣(supplychain 模块,成本侧)→ cost + # 供应商折扣是平台进货折扣,与客户折扣独立,不取 min。 + cost = original_amount try: - dbname = self._get_dbname() - async with DBPools().sqlorContext(dbname) as sor: - binds = await sor.R('discount_customer_bind', - {'customerid': user_org_id}) - if binds: - distributorid = getattr(binds[0], 'resellerid', '') or '' - if distributorid: - d = await env.get_min_distributor_discount( - pid, resellerid, distributorid) - if d not in (None, '', 0): - final_discount = min(final_discount, float(d)) + supplier_id = product.get('providerid') or '' + if not supplier_id: + # 从 supplychain 的产品→供应商映射查首选供应商 + dbname = self._get_dbname() + async with DBPools().sqlorContext(dbname) as sor: + maps = await sor.R('product_supplier_mapping', + {'product_id': pid}) + if maps: + pref = [m for m in maps + if str(getattr(m, 'is_preferred', '')) == '1'] or maps + supplier_id = (getattr(pref[0], 'external_supplier_id', '') + or getattr(pref[0], 'supplier_org_id', '') + or '') + if supplier_id: + sc = await env.calculate_sale_amounts(None, { + 'resellerid': resellerid, + 'supplier_id': supplier_id, + 'productid': pid, + 'prodtypeid': product.get('category_id') or '', + 'quantity': 1, + 'unit_price': original_amount, + }) + if sc: + sc_data = json.loads(sc) if isinstance(sc, str) else sc + sc_data = sc_data.get('data', {}) if isinstance(sc_data, dict) else {} + supply_discount = float(sc_data.get('supply_discount', 1.0) or 1.0) + cost = original_amount * supply_discount except Exception: - pass + cost = original_amount - # 2c. 供应商折扣(product.providerid) - supplierid = product.get('providerid') or '' - if supplierid: - try: - d = await env.get_min_supplier_discount(pid, resellerid, supplierid) - if d not in (None, '', 0): - final_discount = min(final_discount, float(d)) - except Exception: - pass - - amount = original_amount * final_discount result['amount'] = round(amount, 6) result['original_amount'] = round(original_amount, 6) - result['discount'] = final_discount + result['cost'] = round(cost, 6) + result['discount'] = discount return result async def llm_id_to_product_id(self, llm_id):