refactor: use highest unit price per material base in export
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
This commit is contained in:
@ -14,6 +14,7 @@ import datetime
|
||||
# 需要 pip install openpyxl
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class MaterialBaseService:
|
||||
@ -411,15 +412,59 @@ class MaterialBaseService:
|
||||
query_product = query_product.filter(cond)
|
||||
list_product = query_product.all()
|
||||
|
||||
# 2.4 计算每个物料基础的最高单价/成本
|
||||
buy_max = defaultdict(float)
|
||||
for stock, base in list_buy:
|
||||
p = float(stock.pre_tax_unit_price or 0)
|
||||
if p > buy_max[base.id]:
|
||||
buy_max[base.id] = p
|
||||
|
||||
semi_max = defaultdict(float)
|
||||
for stock, base in list_semi:
|
||||
p = float(stock.raw_material_cost or 0) + float(stock.manual_cost or 0)
|
||||
if p > semi_max[base.id]:
|
||||
semi_max[base.id] = p
|
||||
|
||||
product_max = defaultdict(float)
|
||||
for stock, base in list_product:
|
||||
p = float(stock.raw_material_cost or 0) + float(stock.manual_cost or 0)
|
||||
if p > product_max[base.id]:
|
||||
product_max[base.id] = p
|
||||
|
||||
highest_price = {}
|
||||
all_base_ids = set()
|
||||
for stock, base in list_buy:
|
||||
all_base_ids.add(base.id)
|
||||
for stock, base in list_semi:
|
||||
all_base_ids.add(base.id)
|
||||
for stock, base in list_product:
|
||||
all_base_ids.add(base.id)
|
||||
|
||||
for base_id in all_base_ids:
|
||||
price = None
|
||||
buy_val = buy_max.get(base_id)
|
||||
if buy_val is not None and buy_val > 0:
|
||||
price = buy_val
|
||||
else:
|
||||
semi_val = semi_max.get(base_id)
|
||||
if semi_val is not None and semi_val > 0:
|
||||
price = semi_val
|
||||
else:
|
||||
prod_val = product_max.get(base_id)
|
||||
if prod_val is not None and prod_val > 0:
|
||||
price = prod_val
|
||||
highest_price[base_id] = price or 0.0
|
||||
|
||||
# 3. 数据整合
|
||||
all_rows = []
|
||||
|
||||
# 处理采购件
|
||||
for stock, base in list_buy:
|
||||
# 价格计算
|
||||
unit_price = float(stock.pre_tax_unit_price or 0)
|
||||
# 价格计算:使用当前物料基础的最高单价
|
||||
unit_price = highest_price.get(base.id, 0.0)
|
||||
tax_rate = float(stock.tax_rate or 0)
|
||||
price_incl = float(stock.post_tax_unit_price or (unit_price * (1 + tax_rate / 100.0)))
|
||||
# 根据新单价重新计算含税单价
|
||||
price_incl = unit_price * (1 + tax_rate / 100.0)
|
||||
qty = float(stock.stock_quantity or 0)
|
||||
|
||||
# 计算不含税总价 = 数量 * 不含税单价
|
||||
@ -447,13 +492,14 @@ class MaterialBaseService:
|
||||
|
||||
# 处理半成品
|
||||
for stock, base in list_semi:
|
||||
cost = float(stock.raw_material_cost or 0) + float(stock.manual_cost or 0)
|
||||
# 使用当前物料基础的最高单价
|
||||
unit_price = highest_price.get(base.id, 0.0)
|
||||
qty = float(stock.stock_quantity or 0)
|
||||
|
||||
# 半成品不含税总价 = 数量 * 成本
|
||||
total_val_excl = qty * cost
|
||||
# 半成品不含税总价 = 数量 * 单价
|
||||
total_val_excl = qty * unit_price
|
||||
# 含税总价同上 (税率0)
|
||||
total_val_incl = qty * cost
|
||||
total_val_incl = qty * unit_price
|
||||
|
||||
ident = stock.batch_number or stock.serial_number or stock.barcode or stock.sku
|
||||
|
||||
@ -466,20 +512,21 @@ class MaterialBaseService:
|
||||
"date": stock.production_date,
|
||||
"qty": qty,
|
||||
"avail": float(stock.available_quantity or 0),
|
||||
"price_excl": cost,
|
||||
"price_excl": unit_price,
|
||||
"total_val_excl": total_val_excl,
|
||||
"tax": 0.0,
|
||||
"price_incl": cost,
|
||||
"price_incl": unit_price,
|
||||
"total_val": total_val_incl
|
||||
})
|
||||
|
||||
# 处理成品
|
||||
for stock, base in list_product:
|
||||
cost = float(stock.raw_material_cost or 0) + float(stock.manual_cost or 0)
|
||||
# 使用当前物料基础的最高单价
|
||||
unit_price = highest_price.get(base.id, 0.0)
|
||||
qty = float(stock.stock_quantity or 0)
|
||||
|
||||
total_val_excl = qty * cost
|
||||
total_val_incl = qty * cost
|
||||
total_val_excl = qty * unit_price
|
||||
total_val_incl = qty * unit_price
|
||||
|
||||
ident = stock.serial_number or stock.barcode or stock.sku
|
||||
|
||||
@ -492,10 +539,10 @@ class MaterialBaseService:
|
||||
"date": stock.production_date,
|
||||
"qty": qty,
|
||||
"avail": float(stock.available_quantity or 0),
|
||||
"price_excl": cost,
|
||||
"price_excl": unit_price,
|
||||
"total_val_excl": total_val_excl,
|
||||
"tax": 0.0,
|
||||
"price_incl": cost,
|
||||
"price_incl": unit_price,
|
||||
"total_val": total_val_incl
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user