Files

152 lines
5.3 KiB
Python

"""商家罚款规格:解析、序列化、后台维护辅助。"""
from decimal import Decimal, InvalidOperation
from orders.models import PenaltySpec
def serialize_spec(spec):
return {
'id': spec.id,
'club_id': spec.ClubID or '',
'name': spec.Name or '',
'amount': float(spec.Amount or 0),
'amount_str': f'{Decimal(str(spec.Amount or 0)):.2f}',
'enabled': bool(spec.Enabled),
'sort_order': int(spec.SortOrder or 0),
'remark': spec.Remark or '',
'create_time': spec.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if spec.CreateTime else '',
'update_time': spec.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if spec.UpdateTime else '',
}
def list_enabled_specs(club_id):
club_id = (club_id or '').strip() or 'xq'
qs = (
PenaltySpec.objects
.filter(ClubID=club_id, Enabled=True)
.order_by('SortOrder', 'id')
)
return [serialize_spec(s) for s in qs]
def list_all_specs(club_id):
club_id = (club_id or '').strip() or 'xq'
qs = (
PenaltySpec.objects
.filter(ClubID=club_id)
.order_by('SortOrder', 'id')
)
return [serialize_spec(s) for s in qs]
def resolve_enabled_spec(club_id, spec_id):
"""
商家申请用:必须同俱乐部且启用。
成功返回 {'ok': True, 'spec': PenaltySpec, 'amount': Decimal, 'name': str}
"""
club_id = (club_id or '').strip() or 'xq'
if spec_id is None or spec_id == '':
return {'ok': False, 'code': 2, 'msg': '请选择罚款规格'}
try:
sid = int(spec_id)
except (TypeError, ValueError):
return {'ok': False, 'code': 2, 'msg': '罚款规格无效'}
try:
spec = PenaltySpec.objects.get(id=sid)
except PenaltySpec.DoesNotExist:
return {'ok': False, 'code': 2, 'msg': '罚款规格不存在'}
if (spec.ClubID or '').strip() != club_id:
return {'ok': False, 'code': 2, 'msg': '罚款规格不属于当前俱乐部'}
if not spec.Enabled:
return {'ok': False, 'code': 2, 'msg': '该罚款规格已停用,请重新选择'}
amount = Decimal(str(spec.Amount or 0))
if amount <= 0:
return {'ok': False, 'code': 2, 'msg': '罚款规格金额异常,请联系客服'}
return {
'ok': True,
'spec': spec,
'amount': amount,
'name': (spec.Name or '').strip()[:100],
'spec_id': spec.id,
}
def create_spec(club_id, name, amount, *, enabled=True, sort_order=0, remark=''):
club_id = (club_id or '').strip() or 'xq'
name = (name or '').strip()
if not name:
return {'ok': False, 'code': 400, 'msg': '规格名称不能为空'}
if len(name) > 100:
return {'ok': False, 'code': 400, 'msg': '规格名称最多100字'}
try:
amt = Decimal(str(amount))
if amt <= 0:
raise InvalidOperation
except (InvalidOperation, TypeError, ValueError):
return {'ok': False, 'code': 400, 'msg': '金额必须为正数'}
try:
sort_order = int(sort_order or 0)
except (TypeError, ValueError):
sort_order = 0
spec = PenaltySpec.objects.create(
ClubID=club_id[:16],
Name=name,
Amount=amt,
Enabled=bool(enabled),
SortOrder=sort_order,
Remark=(remark or '').strip()[:200],
)
return {'ok': True, 'code': 0, 'msg': '已创建', 'data': serialize_spec(spec)}
def update_spec(club_id, spec_id, *, name=None, amount=None, enabled=None, sort_order=None, remark=None):
club_id = (club_id or '').strip() or 'xq'
try:
sid = int(spec_id)
except (TypeError, ValueError):
return {'ok': False, 'code': 400, 'msg': '规格ID无效'}
try:
spec = PenaltySpec.objects.get(id=sid, ClubID=club_id)
except PenaltySpec.DoesNotExist:
return {'ok': False, 'code': 404, 'msg': '规格不存在'}
if name is not None:
name = str(name).strip()
if not name:
return {'ok': False, 'code': 400, 'msg': '规格名称不能为空'}
if len(name) > 100:
return {'ok': False, 'code': 400, 'msg': '规格名称最多100字'}
spec.Name = name
if amount is not None:
try:
amt = Decimal(str(amount))
if amt <= 0:
raise InvalidOperation
except (InvalidOperation, TypeError, ValueError):
return {'ok': False, 'code': 400, 'msg': '金额必须为正数'}
spec.Amount = amt
if enabled is not None:
spec.Enabled = bool(enabled)
if sort_order is not None:
try:
spec.SortOrder = int(sort_order)
except (TypeError, ValueError):
return {'ok': False, 'code': 400, 'msg': '排序须为整数'}
if remark is not None:
spec.Remark = str(remark).strip()[:200]
spec.save()
return {'ok': True, 'code': 0, 'msg': '已更新', 'data': serialize_spec(spec)}
def delete_spec(club_id, spec_id):
"""物理删除规格;已生成罚单仍保留快照,不受影响。"""
club_id = (club_id or '').strip() or 'xq'
try:
sid = int(spec_id)
except (TypeError, ValueError):
return {'ok': False, 'code': 400, 'msg': '规格ID无效'}
deleted, _ = PenaltySpec.objects.filter(id=sid, ClubID=club_id).delete()
if not deleted:
return {'ok': False, 'code': 404, 'msg': '规格不存在'}
return {'ok': True, 'code': 0, 'msg': '已删除'}