forked from erp-dev/erp
703 lines
22 KiB
Python
703 lines
22 KiB
Python
"""日结模块统计服务函数"""
|
||
import logging
|
||
from datetime import datetime, date, time, timedelta
|
||
from decimal import Decimal, InvalidOperation
|
||
|
||
from django.db.models import Prefetch
|
||
from django.db.models import Q, Sum, Case, When, Value, CharField, IntegerField, Count
|
||
from django.db.models.fields.json import KeyTextTransform
|
||
from django.db.models.functions import Concat
|
||
from django.utils.dateparse import parse_datetime
|
||
from django.utils import timezone
|
||
|
||
from printing.models import PlateOrder
|
||
from stateflow.models import StateFlowRecord, StateLogParameterRecord
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
DEFAULT_DESIGNER_SUMMARY_STATE_NAMES = ("画图完成",)
|
||
DEFAULT_DESIGNER_TASK_STATE_NAME_SUFFIX = "完成"
|
||
DEFAULT_DESIGNER_PARAM_KEY = "设计师名称"
|
||
DEFAULT_DESIGNER_TASK_QUANTITY_PARAM_KEY = "完成数量"
|
||
DEFAULT_DESIGNER_TASK_TIME_PARAM_KEY = "完成时间"
|
||
DEFAULT_EMPTY_TASK_QUANTITY = Decimal("1")
|
||
|
||
|
||
def get_plate_order_summary_by_customer(
|
||
merchant_id: int,
|
||
settlement_date: date,
|
||
user=None
|
||
) -> list[dict]:
|
||
"""
|
||
获取按客户分组的开版订单统计
|
||
|
||
Args:
|
||
merchant_id: 商户ID
|
||
settlement_date: 统计日期
|
||
user: 当前用户(用于客户可见性过滤)
|
||
|
||
Returns:
|
||
list[dict]: 客户统计列表
|
||
"""
|
||
logger.info(
|
||
f'[settlement.services] 获取开版订单统计: '
|
||
f'merchant_id={merchant_id}, date={settlement_date}'
|
||
)
|
||
|
||
settlement_date = _validate_and_normalize_summary_args(
|
||
merchant_id=merchant_id,
|
||
settlement_date=settlement_date,
|
||
)
|
||
|
||
queryset = _get_plate_order_queryset(merchant_id, user)
|
||
aggregated_data = _aggregate_plate_orders_by_customer_and_type(
|
||
queryset, settlement_date
|
||
)
|
||
return _format_plate_order_summary(aggregated_data)
|
||
|
||
|
||
def get_plate_order_summary_by_designer(
|
||
merchant_id: int,
|
||
settlement_date: date,
|
||
user=None,
|
||
state_names: list[str] | tuple[str, ...] | None = None,
|
||
designer_param_key: str = DEFAULT_DESIGNER_PARAM_KEY,
|
||
) -> list[dict]:
|
||
"""
|
||
获取按设计师分组的开版订单统计。
|
||
|
||
设计师来源于 stateflow 参数记录,默认只统计“画图完成”节点下的
|
||
``parameters["设计师名称"]``。同一设计师在同一开版单同一类型下出现多次只计 1 单。
|
||
"""
|
||
logger.info(
|
||
f'[settlement.services] 获取开版订单设计师统计: '
|
||
f'merchant_id={merchant_id}, date={settlement_date}, states={state_names}'
|
||
)
|
||
|
||
settlement_date = _validate_and_normalize_summary_args(
|
||
merchant_id=merchant_id,
|
||
settlement_date=settlement_date,
|
||
)
|
||
normalized_state_names = _normalize_designer_summary_state_names(state_names)
|
||
if not designer_param_key or not str(designer_param_key).strip():
|
||
raise ValueError('designer_param_key 不能为空')
|
||
|
||
month_start_dt, next_day_dt, today_start_dt = _get_summary_datetime_ranges(
|
||
settlement_date
|
||
)
|
||
queryset = _get_designer_plate_order_queryset(
|
||
merchant_id=merchant_id,
|
||
user=user,
|
||
state_names=normalized_state_names,
|
||
designer_param_key=designer_param_key,
|
||
month_start_dt=month_start_dt,
|
||
next_day_dt=next_day_dt,
|
||
)
|
||
aggregated_data = _aggregate_plate_orders_by_designer_and_type(
|
||
queryset=queryset,
|
||
today_start_dt=today_start_dt,
|
||
next_day_dt=next_day_dt,
|
||
)
|
||
return _format_plate_order_designer_summary(aggregated_data)
|
||
|
||
|
||
def get_designer_workflow_task_summary(
|
||
merchant_id: int,
|
||
settlement_date: date,
|
||
user=None,
|
||
state_names: list[str] | tuple[str, ...] | None = None,
|
||
designer_names: list[str] | tuple[str, ...] | None = None,
|
||
designer_param_key: str = DEFAULT_DESIGNER_PARAM_KEY,
|
||
quantity_param_key: str = DEFAULT_DESIGNER_TASK_QUANTITY_PARAM_KEY,
|
||
time_param_key: str = DEFAULT_DESIGNER_TASK_TIME_PARAM_KEY,
|
||
) -> list[dict]:
|
||
"""
|
||
获取设计师工序任务量统计。
|
||
|
||
统计单位是未撤销的 StateFlowRecord。每条状态流转记录最多计入一次,
|
||
即使其下存在多条 StateLogParameterRecord。
|
||
"""
|
||
logger.info(
|
||
f'[settlement.services] 获取设计师工序任务量统计: '
|
||
f'merchant_id={merchant_id}, date={settlement_date}, states={state_names}'
|
||
)
|
||
|
||
settlement_date = _validate_and_normalize_summary_args(
|
||
merchant_id=merchant_id,
|
||
settlement_date=settlement_date,
|
||
)
|
||
normalized_state_names = _normalize_optional_state_names(state_names)
|
||
normalized_designer_names = _normalize_optional_names(designer_names)
|
||
for key, label in [
|
||
(designer_param_key, 'designer_param_key'),
|
||
(quantity_param_key, 'quantity_param_key'),
|
||
(time_param_key, 'time_param_key'),
|
||
]:
|
||
if not key or not str(key).strip():
|
||
raise ValueError(f'{label} 不能为空')
|
||
|
||
month_start_dt, next_day_dt, today_start_dt = _get_summary_datetime_ranges(
|
||
settlement_date
|
||
)
|
||
queryset = _get_designer_workflow_task_queryset(
|
||
merchant_id=merchant_id,
|
||
user=user,
|
||
state_names=normalized_state_names,
|
||
designer_param_key=designer_param_key,
|
||
)
|
||
summary = _aggregate_designer_workflow_tasks(
|
||
queryset=queryset,
|
||
month_start_dt=month_start_dt,
|
||
today_start_dt=today_start_dt,
|
||
next_day_dt=next_day_dt,
|
||
designer_names=normalized_designer_names,
|
||
designer_param_key=designer_param_key,
|
||
quantity_param_key=quantity_param_key,
|
||
time_param_key=time_param_key,
|
||
)
|
||
return _format_designer_workflow_task_summary(summary)
|
||
|
||
|
||
def _normalize_optional_names(
|
||
names: list[str] | tuple[str, ...] | None,
|
||
) -> tuple[str, ...] | None:
|
||
if names is None:
|
||
return None
|
||
normalized = tuple(name.strip() for name in names if isinstance(name, str) and name.strip())
|
||
if not normalized:
|
||
raise ValueError('designer_names 不能为空')
|
||
return normalized
|
||
|
||
|
||
def _normalize_optional_state_names(
|
||
state_names: list[str] | tuple[str, ...] | None,
|
||
) -> tuple[str, ...] | None:
|
||
if state_names is None:
|
||
return None
|
||
normalized = tuple(
|
||
name.strip() for name in state_names if isinstance(name, str) and name.strip()
|
||
)
|
||
if not normalized:
|
||
raise ValueError('state_names 不能为空')
|
||
return normalized
|
||
|
||
|
||
def _normalize_designer_summary_state_names(
|
||
state_names: list[str] | tuple[str, ...] | None,
|
||
) -> tuple[str, ...]:
|
||
"""标准化设计师统计节点名。"""
|
||
if state_names is None:
|
||
return DEFAULT_DESIGNER_SUMMARY_STATE_NAMES
|
||
|
||
normalized = tuple(
|
||
name.strip() for name in state_names if isinstance(name, str) and name.strip()
|
||
)
|
||
if not normalized:
|
||
raise ValueError('state_names 不能为空')
|
||
return normalized
|
||
|
||
|
||
def _get_summary_datetime_ranges(settlement_date: date):
|
||
"""返回月初、次日、当天起始的当前时区 aware datetime。"""
|
||
current_tz = timezone.get_current_timezone()
|
||
month_start = settlement_date.replace(day=1)
|
||
month_start_dt = timezone.make_aware(
|
||
datetime.combine(month_start, time.min), current_tz
|
||
)
|
||
today_start_dt = timezone.make_aware(
|
||
datetime.combine(settlement_date, time.min), current_tz
|
||
)
|
||
next_day_dt = timezone.make_aware(
|
||
datetime.combine(settlement_date + timedelta(days=1), time.min), current_tz
|
||
)
|
||
return month_start_dt, next_day_dt, today_start_dt
|
||
|
||
|
||
def _get_designer_workflow_task_queryset(
|
||
*,
|
||
merchant_id: int,
|
||
user=None,
|
||
state_names: tuple[str, ...] | None,
|
||
designer_param_key: str,
|
||
):
|
||
queryset = StateFlowRecord.objects.filter(
|
||
is_cancelled=False,
|
||
business_object__plate_order__merchant_id=merchant_id,
|
||
business_object__plate_order__plate_type__isnull=False,
|
||
business_object__plate_order__production_method__isnull=False,
|
||
parameter_records__parameters__has_key=designer_param_key,
|
||
).select_related(
|
||
'state',
|
||
'business_object__plate_order',
|
||
'business_object__plate_order__customer',
|
||
).prefetch_related(
|
||
Prefetch(
|
||
'parameter_records',
|
||
queryset=StateLogParameterRecord.objects.order_by('created_at', 'id'),
|
||
to_attr='_prefetched_parameter_records',
|
||
)
|
||
).distinct()
|
||
|
||
if state_names is None:
|
||
queryset = queryset.filter(state__name__endswith=DEFAULT_DESIGNER_TASK_STATE_NAME_SUFFIX)
|
||
else:
|
||
queryset = queryset.filter(state__name__in=state_names)
|
||
|
||
if user and not user.is_superuser:
|
||
emp = getattr(user, 'employee', None)
|
||
if emp:
|
||
queryset = queryset.filter(
|
||
Q(business_object__plate_order__customer__created_by=emp) |
|
||
Q(business_object__plate_order__customer__visible_employees=emp)
|
||
).distinct()
|
||
|
||
return queryset.order_by('id')
|
||
|
||
|
||
def _aggregate_designer_workflow_tasks(
|
||
*,
|
||
queryset,
|
||
month_start_dt: datetime,
|
||
today_start_dt: datetime,
|
||
next_day_dt: datetime,
|
||
designer_names: tuple[str, ...] | None,
|
||
designer_param_key: str,
|
||
quantity_param_key: str,
|
||
time_param_key: str,
|
||
) -> dict[tuple[str, str, str], dict[str, Decimal]]:
|
||
summary: dict[tuple[str, str, str], dict[str, Decimal]] = {}
|
||
designer_name_filter = set(designer_names) if designer_names is not None else None
|
||
|
||
for state_log in queryset:
|
||
parameters = _merge_state_log_parameters(state_log)
|
||
designer_name = str(parameters.get(designer_param_key) or '').strip()
|
||
if not designer_name:
|
||
continue
|
||
if designer_name_filter is not None and designer_name not in designer_name_filter:
|
||
continue
|
||
|
||
effective_time = _resolve_task_effective_time(
|
||
parameters.get(time_param_key),
|
||
fallback=state_log.completed_at,
|
||
)
|
||
if effective_time is None or effective_time < month_start_dt or effective_time >= next_day_dt:
|
||
continue
|
||
|
||
plate_order = state_log.business_object.plate_order
|
||
task_quantity = _parse_task_quantity(parameters.get(quantity_param_key))
|
||
key = (
|
||
designer_name,
|
||
state_log.state.name,
|
||
f'{plate_order.plate_type}-{plate_order.production_method}',
|
||
)
|
||
if key not in summary:
|
||
summary[key] = {'today': Decimal('0'), 'current_month': Decimal('0')}
|
||
|
||
summary[key]['current_month'] += task_quantity
|
||
if today_start_dt <= effective_time < next_day_dt:
|
||
summary[key]['today'] += task_quantity
|
||
|
||
return summary
|
||
|
||
|
||
def _merge_state_log_parameters(state_log: StateFlowRecord) -> dict:
|
||
records = getattr(state_log, '_prefetched_parameter_records', None)
|
||
if records is None:
|
||
records = state_log.parameter_records.all().order_by('created_at', 'id')
|
||
|
||
merged = {}
|
||
for record in records:
|
||
if isinstance(record.parameters, dict):
|
||
merged.update(record.parameters)
|
||
return merged
|
||
|
||
|
||
def _parse_task_quantity(value) -> Decimal:
|
||
try:
|
||
quantity = Decimal(str(value).strip())
|
||
except (InvalidOperation, ValueError, TypeError, AttributeError):
|
||
return DEFAULT_EMPTY_TASK_QUANTITY
|
||
if quantity > 0:
|
||
return quantity
|
||
return DEFAULT_EMPTY_TASK_QUANTITY
|
||
|
||
|
||
def _resolve_task_effective_time(value, *, fallback):
|
||
parsed = None
|
||
if isinstance(value, datetime):
|
||
parsed = value
|
||
elif isinstance(value, str) and value.strip():
|
||
raw_value = value.strip()
|
||
parsed = parse_datetime(raw_value)
|
||
if parsed is None:
|
||
for fmt in ('%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d'):
|
||
try:
|
||
parsed = datetime.strptime(raw_value, fmt)
|
||
break
|
||
except ValueError:
|
||
continue
|
||
|
||
effective = parsed or fallback
|
||
if effective is None:
|
||
return None
|
||
if timezone.is_naive(effective):
|
||
effective = timezone.make_aware(effective, timezone.get_current_timezone())
|
||
return effective.astimezone(timezone.get_current_timezone())
|
||
|
||
|
||
def _format_decimal_quantity(value: Decimal):
|
||
if value == value.to_integral_value():
|
||
return int(value)
|
||
return str(value.normalize())
|
||
|
||
|
||
def _format_designer_workflow_task_summary(
|
||
summary: dict[tuple[str, str, str], dict[str, Decimal]],
|
||
) -> list[dict]:
|
||
result: dict[str, dict] = {}
|
||
for (designer_name, state_name, type_name), counts in sorted(summary.items()):
|
||
if designer_name not in result:
|
||
result[designer_name] = {
|
||
'designer_name': designer_name,
|
||
'task_count': [],
|
||
'today': Decimal('0'),
|
||
'current_month': Decimal('0'),
|
||
}
|
||
result[designer_name]['task_count'].append({
|
||
'state_name': state_name,
|
||
'type': type_name,
|
||
'today': _format_decimal_quantity(counts['today']),
|
||
'current_month': _format_decimal_quantity(counts['current_month']),
|
||
})
|
||
result[designer_name]['today'] += counts['today']
|
||
result[designer_name]['current_month'] += counts['current_month']
|
||
|
||
formatted = []
|
||
for item in result.values():
|
||
item['today'] = _format_decimal_quantity(item['today'])
|
||
item['current_month'] = _format_decimal_quantity(item['current_month'])
|
||
formatted.append(item)
|
||
return formatted
|
||
|
||
|
||
def _get_designer_plate_order_queryset(
|
||
*,
|
||
merchant_id: int,
|
||
user=None,
|
||
state_names: tuple[str, ...],
|
||
designer_param_key: str,
|
||
month_start_dt: datetime,
|
||
next_day_dt: datetime,
|
||
):
|
||
"""获取设计师统计的 stateflow 参数记录基础查询集。"""
|
||
queryset = StateLogParameterRecord.objects.filter(
|
||
parameters__has_key=designer_param_key,
|
||
state_log__is_cancelled=False,
|
||
state_log__state__name__in=state_names,
|
||
state_log__business_object__plate_order__merchant_id=merchant_id,
|
||
state_log__business_object__plate_order__plate_type__isnull=False,
|
||
state_log__business_object__plate_order__production_method__isnull=False,
|
||
state_log__business_object__plate_order__plate_date__gte=month_start_dt,
|
||
state_log__business_object__plate_order__plate_date__lt=next_day_dt,
|
||
).annotate(
|
||
designer_name=KeyTextTransform(designer_param_key, 'parameters'),
|
||
type=Concat(
|
||
'state_log__business_object__plate_order__plate_type',
|
||
Value('-'),
|
||
'state_log__business_object__plate_order__production_method',
|
||
output_field=CharField(),
|
||
),
|
||
).exclude(
|
||
designer_name__isnull=True,
|
||
).exclude(
|
||
designer_name='',
|
||
)
|
||
|
||
if user and not user.is_superuser:
|
||
emp = getattr(user, 'employee', None)
|
||
if emp:
|
||
queryset = queryset.filter(
|
||
Q(state_log__business_object__plate_order__customer__created_by=emp) |
|
||
Q(state_log__business_object__plate_order__customer__visible_employees=emp)
|
||
).distinct()
|
||
|
||
return queryset
|
||
|
||
|
||
def _aggregate_plate_orders_by_designer_and_type(
|
||
*,
|
||
queryset,
|
||
today_start_dt: datetime,
|
||
next_day_dt: datetime,
|
||
):
|
||
"""按设计师和类型聚合开版订单数量。"""
|
||
plate_order_path = 'state_log__business_object__plate_order'
|
||
return queryset.values(
|
||
'designer_name',
|
||
'type',
|
||
).annotate(
|
||
today=Count(
|
||
plate_order_path,
|
||
filter=Q(
|
||
state_log__business_object__plate_order__plate_date__gte=today_start_dt,
|
||
state_log__business_object__plate_order__plate_date__lt=next_day_dt,
|
||
),
|
||
distinct=True,
|
||
),
|
||
current_month=Count(
|
||
plate_order_path,
|
||
distinct=True,
|
||
),
|
||
).order_by('designer_name', 'type')
|
||
|
||
|
||
def _format_plate_order_designer_summary(aggregated_data):
|
||
"""格式化设计师聚合结果为 API 返回格式。"""
|
||
result = {}
|
||
|
||
for item in aggregated_data:
|
||
designer_name = item['designer_name']
|
||
if designer_name not in result:
|
||
result[designer_name] = {
|
||
'designer_name': designer_name,
|
||
'plate_order_count': [],
|
||
}
|
||
|
||
result[designer_name]['plate_order_count'].append({
|
||
'type': item['type'],
|
||
'today': item['today'],
|
||
'current_month': item['current_month'],
|
||
})
|
||
|
||
for designer_name in result:
|
||
result[designer_name]['plate_order_count'] = _filter_zero_data(
|
||
result[designer_name]['plate_order_count']
|
||
)
|
||
|
||
return [v for v in result.values() if v['plate_order_count']]
|
||
|
||
|
||
def _validate_and_normalize_summary_args(
|
||
merchant_id: int,
|
||
settlement_date: date,
|
||
) -> date:
|
||
"""校验并标准化统计参数。"""
|
||
if not isinstance(merchant_id, int) or merchant_id <= 0:
|
||
raise ValueError('merchant_id 必须为正整数')
|
||
|
||
if isinstance(settlement_date, datetime):
|
||
settlement_date = settlement_date.date()
|
||
|
||
if not isinstance(settlement_date, date):
|
||
raise ValueError('settlement_date 必须为 date 或 datetime 类型')
|
||
|
||
return settlement_date
|
||
|
||
|
||
def _get_plate_order_queryset(merchant_id: int, user=None):
|
||
"""
|
||
获取开版订单的基础查询集
|
||
|
||
Args:
|
||
merchant_id: 商户ID
|
||
user: 当前用户(用于客户可见性过滤)
|
||
|
||
Returns:
|
||
QuerySet[PlateOrder]: 过滤后的查询集
|
||
"""
|
||
queryset = PlateOrder.objects.filter(
|
||
merchant_id=merchant_id,
|
||
plate_type__isnull=False,
|
||
production_method__isnull=False
|
||
).select_related('customer')
|
||
|
||
if user and not user.is_superuser:
|
||
emp = getattr(user, 'employee', None)
|
||
if emp:
|
||
visible_customer_filter = (
|
||
Q(customer__created_by=emp) |
|
||
Q(customer__visible_employees=emp)
|
||
)
|
||
no_customer_filter = Q(customer__isnull=True)
|
||
queryset = queryset.filter(
|
||
visible_customer_filter | no_customer_filter
|
||
).distinct()
|
||
|
||
return queryset
|
||
|
||
|
||
def _get_month_date_range(settlement_date: date) -> tuple[date, date]:
|
||
"""
|
||
获取从月初到指定日期的日期范围
|
||
|
||
Args:
|
||
settlement_date: 统计日期
|
||
|
||
Returns:
|
||
tuple[date, date]: (月初日期, 统计日期)
|
||
"""
|
||
month_start = settlement_date.replace(day=1)
|
||
return month_start, settlement_date
|
||
|
||
|
||
def _aggregate_plate_orders_by_customer_and_type(queryset, settlement_date: date):
|
||
"""
|
||
按客户和类型分组聚合订单数据
|
||
|
||
Args:
|
||
queryset: 基础查询集
|
||
settlement_date: 统计日期
|
||
|
||
Returns:
|
||
QuerySet[PlateOrder]: 添加了聚合标注的查询集
|
||
"""
|
||
month_start, _ = _get_month_date_range(settlement_date)
|
||
|
||
queryset = queryset.annotate(
|
||
type=Concat(
|
||
'plate_type',
|
||
Value('-'),
|
||
'production_method',
|
||
output_field=CharField()
|
||
)
|
||
).values(
|
||
'customer__id',
|
||
'customer__name',
|
||
'type'
|
||
).annotate(
|
||
today=Sum(
|
||
Case(
|
||
When(
|
||
plate_date__date=settlement_date,
|
||
then=1
|
||
),
|
||
default=0,
|
||
output_field=IntegerField()
|
||
)
|
||
),
|
||
current_month=Sum(
|
||
Case(
|
||
When(
|
||
plate_date__date__gte=month_start,
|
||
plate_date__date__lte=settlement_date,
|
||
then=1
|
||
),
|
||
default=0,
|
||
output_field=IntegerField()
|
||
)
|
||
)
|
||
).order_by('customer__name', 'customer__id', 'type')
|
||
|
||
return queryset
|
||
|
||
|
||
def _format_plate_order_summary(aggregated_data):
|
||
"""
|
||
格式化聚合结果为 API 返回格式
|
||
|
||
Args:
|
||
aggregated_data: 聚合后的查询集
|
||
|
||
Returns:
|
||
list[dict]: 格式化后的数据
|
||
"""
|
||
result = {}
|
||
|
||
for item in aggregated_data:
|
||
client_id = item['customer__id']
|
||
client_name = item['customer__name']
|
||
client_key = (client_id, client_name)
|
||
if client_key not in result:
|
||
result[client_key] = {
|
||
'client_id': client_id,
|
||
'client_name': client_name,
|
||
'plate_order_count': []
|
||
}
|
||
|
||
plate_order_count = {
|
||
'type': item['type'],
|
||
'today': item['today'],
|
||
'current_month': item['current_month']
|
||
}
|
||
|
||
result[client_key]['plate_order_count'].append(plate_order_count)
|
||
|
||
for client_key in result:
|
||
result[client_key]['plate_order_count'] = _filter_zero_data(
|
||
result[client_key]['plate_order_count']
|
||
)
|
||
|
||
return [v for k, v in result.items() if v['plate_order_count']]
|
||
|
||
|
||
def _filter_zero_data(plate_order_counts):
|
||
"""
|
||
过滤全0数据
|
||
|
||
Args:
|
||
plate_order_counts: 订单统计列表
|
||
|
||
Returns:
|
||
list[dict]: 过滤后的列表
|
||
"""
|
||
return [
|
||
item for item in plate_order_counts
|
||
if item['today'] > 0 or item['current_month'] > 0
|
||
]
|
||
|
||
|
||
def calculate_plate_order_daily_summary(
|
||
merchant_id: int,
|
||
settlement_date: datetime.date
|
||
) -> dict:
|
||
"""
|
||
计算开版订单日结汇总(空壳实现)
|
||
|
||
Args:
|
||
merchant_id: 商户ID
|
||
settlement_date: 结算日期
|
||
|
||
Returns:
|
||
dict: 统计结果(空壳)
|
||
"""
|
||
logger.info(
|
||
f'[settlement.services] 计算开版订单日结汇总: '
|
||
f'merchant_id={merchant_id}, date={settlement_date}'
|
||
)
|
||
|
||
return {
|
||
'merchant_id': merchant_id,
|
||
'settlement_date': str(settlement_date),
|
||
'total_orders': 0,
|
||
'completed_orders': 0,
|
||
'in_progress_orders': 0,
|
||
}
|
||
|
||
|
||
def calculate_printing_order_daily_summary(
|
||
merchant_id: int,
|
||
settlement_date: datetime.date
|
||
) -> dict:
|
||
"""
|
||
计算生产订单日结汇总(空壳实现)
|
||
|
||
Args:
|
||
merchant_id: 商户ID
|
||
settlement_date: 结算日期
|
||
|
||
Returns:
|
||
dict: 统计结果(空壳)
|
||
"""
|
||
logger.info(
|
||
f'[settlement.services] 计算生产订单日结汇总: '
|
||
f'merchant_id={merchant_id}, date={settlement_date}'
|
||
)
|
||
|
||
return {
|
||
'merchant_id': merchant_id,
|
||
'settlement_date': str(settlement_date),
|
||
'total_orders': 0,
|
||
'completed_orders': 0,
|
||
'in_progress_orders': 0,
|
||
}
|