Files

38 lines
1.3 KiB
Python

"""Exact fixed point arithmetic shared by persistence, forms and PDF output."""
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
ZERO = Decimal('0')
CENT = Decimal('0.01')
UNIT = Decimal('0.0001')
MAX_VALUE = Decimal('999999999')
MAX_TOTAL = Decimal('999999999999.99')
def number(value, label='数值', allow_zero=True):
try:
result = Decimal(str(value if value not in (None, '') else 0).strip())
except (InvalidOperation, ValueError):
raise ValueError('%s必须是有效数字' % label)
if not result.is_finite() or result < 0 or result > MAX_VALUE:
raise ValueError('%s必须在 0 到 %s 之间' % (label, MAX_VALUE))
if result != result.quantize(UNIT):
raise ValueError('%s最多保留四位小数' % label)
if not allow_zero and result == 0:
raise ValueError('%s必须大于零' % label)
return result.quantize(UNIT)
def money(value):
return Decimal(str(value or 0)).quantize(CENT, rounding=ROUND_HALF_UP)
def line_amount(qty, price):
amount = money(number(qty, '数量') * number(price, '单价'))
if amount > MAX_TOTAL:
raise ValueError('明细金额过大')
return amount
def format_price(value):
return format(Decimal(str(value or 0)), '.4f').rstrip('0').rstrip('.') or '0'