dy-dashboard/services/order_progress.py
2026-10-29 10:36:31 +08:00

86 lines
3.0 KiB
Python

"""国内/海外订单统一在途进度口径。"""
from datetime import datetime
from services.db import query
def _order_time_value(value):
"""把历史订单中的 datetime、YYYY-MM-DD 和斜杠日期转成可比较值。"""
if value is None:
return None
if isinstance(value, datetime):
return value
text = str(value).strip()
if not text:
return None
text = text.replace('/', '-').replace('T', ' ')
for fmt in ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d', '%Y-%m-%d %H:%M'):
try:
return datetime.strptime(text[:19], fmt)
except ValueError:
continue
return None
def unfinished_order_progress_map(product_codes=None):
"""按货品编号返回国内/海外最早一笔未完结订单的详情进度。
下单时间沿用订单管理口径:订单下达供应商时间优先,其次订单日期,
最后使用计划下单时间;无日期的历史记录排在有日期记录之后。
"""
source_codes = list(product_codes) if product_codes is not None else None
requested = {
str(code or '').strip() for code in (source_codes or []) if str(code or '').strip()
}
if source_codes is not None and not requested:
return {}
rows = []
for source_order, (table, code_column) in enumerate((
('domestic_orders', '货品编号'),
('overseas_orders', '产品编码'),
)):
params = []
code_where = ''
if requested:
code_where = f" AND `{code_column}` IN ({','.join(['%s'] * len(requested))})"
params.extend(sorted(requested))
sql = f"""
SELECT `{code_column}` AS product_code, `进度`,
`订单下达供应商时间` AS supplier_ordered_at,
`日期` AS order_date, `计划下单时间` AS planned_ordered_at, id
FROM {table}
WHERE `状态`='未完结'{code_where}
"""
for row in query(sql, tuple(params)):
row['_source_order'] = source_order
rows.append(row)
def sort_key(row):
ordered_at = (
_order_time_value(row.get('supplier_ordered_at'))
or _order_time_value(row.get('order_date'))
or _order_time_value(row.get('planned_ordered_at'))
)
return (
0 if ordered_at else 1,
ordered_at or datetime.max,
row.get('_source_order', 0),
row.get('id') or 0,
)
rows.sort(key=sort_key)
result = {}
for row in rows:
code = str(row.get('product_code') or '').strip()
if code and code not in result:
result[code] = row.get('进度') or ''
return result
def attach_unfinished_order_progress(rows):
"""为计划预测行批量附加“在途进度”,避免逐 SKU 查询。"""
progress = unfinished_order_progress_map(row.get('product_code') for row in rows)
for row in rows:
row['在途进度'] = progress.get(str(row.get('product_code') or '').strip(), '')
return rows