>> */ public static function rules(): array { return [ '主体期间来源' => [ [ 'code' => 'R1', 'object' => '期初数据(已变更店铺)', 'logic' => '变更店铺由负责人提供的期初数据锁定:老主体 2026-07-01 生效、失效时间为店铺变更到新主体的前一天;新主体从变更当天生效,失效时间显示「存续中」。', 'source' => '店铺变更初始数据(' . self::INITIAL_PERIODS_CONFIG . ')', 'priority' => '期初数据优先,覆盖流程历史', ], [ 'code' => 'R2', 'object' => '其他店铺的期初期间', 'logic' => '未列入期初数据的店铺自 2026-07-01 起按财务系统登记主体生成一条期间,失效时间显示「存续中」;系统主体缺失时退回店铺基础信息页展示的主体。', 'source' => 'ops_fys_shop_info + ops_fys_company_info', 'priority' => '一条期间,从 2026-07-01 起', ], [ 'code' => 'R3', 'object' => '爬虫抓到的新主体', 'logic' => '爬虫主体先按统一社会信用代码归一到工商主体名称;与当前期间最后一个主体不同时生成新期间,生效时间为首次抓到日期,老期间失效时间改为前一天,新期间失效时间显示「存续中」。', 'source' => 'crawl_shop_company + store_report_shop_period_changes', 'priority' => '爬虫驱动新增期间,日期一经记录不再前移', ], [ 'code' => 'R4', 'object' => '主体名称笔误', 'logic' => '爬虫名称与系统名称不同、但税号归一到同一工商主体时不算主体变更,只保留名称不一致预警,不新增期间。', 'source' => 'crawl_shop_company + fys_companyInfo', 'priority' => '同税号视为同一主体', ], ], '期间切割与展示' => [ [ 'code' => 'R5', 'object' => '一行一期间', 'logic' => '同一店铺的每个主体期间在报表中只显示一行,不再展开流程表历史记录;期间按日期严格衔接,不重复、不留空档。', 'source' => 'StoreReportPeriodBuilder', 'priority' => '去重后按主体期间展示', ], [ 'code' => 'R6', 'object' => '流程历史行的处理', 'logic' => '报表期间不再直接读取 fys_shopInfo_flow 的原始行(历史重复行来源);流程数据仅作备查和同日冲突预警,不参与期间生成。', 'source' => 'store_report_lifecycle_rows(备查)', 'priority' => '不作为期间来源', ], [ 'code' => 'R7', 'object' => '关店与非正常状态', 'logic' => '店铺状态为关店、关店中或其他非正常状态时,生效时间和失效时间都显示「-」;只有正常在营店铺展示期间日期。', 'source' => 'ops_fys_shop_info.shopState', 'priority' => '状态优先于期间展示', ], [ 'code' => 'R8', 'object' => '销量归属', 'logic' => '期间销量按实际发生日期归属:变更日当天归新主体,老主体统计到变更日前一天,主体切换不重复统计、不少计销量。', 'source' => 'store_report_paid_sales_rows + 主体期间', 'priority' => '按日归属,区间不重叠', ], [ 'code' => 'R9', 'object' => '销量口径', 'logic' => '销量=业绩明细(店铺收款匹配订单明细)的「收入金额 + 优惠金额 + 冲减金额 + 违约赔付(冲减收入) + 退款金额」合计,按「店铺名称 + 发生日期」逐日汇总;退款及各项抵减按账单净额(负数)计入,不再使用订单实付/实收金额。收入列仍按平台账单日汇总,两个口径分开统计、不互相覆盖。', 'source' => 'store_receipt_order_match_rows → store_report_paid_sales_rows', 'priority' => '与业绩明细同口径', ], ], ]; } }