36 lines
1.2 KiB
Python
36 lines
1.2 KiB
Python
"""商品中心服务:多单位换算等。
|
|
|
|
约定:
|
|
- Product.base_unit 为基本单位;UnitConversion.rate 表示 1 个录入单位 = rate × 基本单位
|
|
- 单据行 quantity 恒存基本单位数量;录入单位/数量存 source_unit/source_quantity
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from decimal import Decimal
|
|
|
|
from .models import Product, UnitConversion
|
|
|
|
|
|
class UnitConversionNotFound(Exception):
|
|
"""商品缺少该单位的换算率。"""
|
|
|
|
|
|
def to_base(product: Product, unit, quantity: Decimal) -> Decimal:
|
|
"""把"录入单位数量"换算成基本单位数量。
|
|
|
|
unit 可以是 Unit 实例、pk 或 code;与基本单位相同(或未传)时原样返回。
|
|
"""
|
|
if unit in (None, ""):
|
|
return Decimal(str(quantity))
|
|
base = product.base_unit
|
|
if base is not None and (unit == base or getattr(unit, "pk", None) == base.pk):
|
|
return Decimal(str(quantity))
|
|
conv = UnitConversion.objects.filter(product=product, unit=unit).first()
|
|
if conv is None:
|
|
unit_code = getattr(unit, "code", str(unit))
|
|
raise UnitConversionNotFound(
|
|
f"product {product.code} has no conversion for unit {unit_code}"
|
|
)
|
|
return Decimal(str(quantity)) * conv.rate
|