"""国内/海外订单统一在途进度口径。""" 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