-- =============================================================================
-- 酒厂账单一次性修复（v4.0.6）
-- 库：生产 dukang_prod（也可在已同步的本地 dukang_haoke 先演练）
--
-- 规则（与代码一致）：
--   起点 WINERY_BILL_EPOCH_YMD = 2026-08-01
--   周期 WINERY_SETTLEMENT_PERIOD_DAYS = 3
--   出账日 8/4、8/7、8/10 … ；纳入窗口 [出账日-3, 出账日)
--   订单：status=COMPLETED AND pay_status=PAID
--         delivery_type IN ('LOCAL','CROSS_CITY','ON_SITE_PICKUP')
--   账期归属：completed_at（缺则 paid_at）的北京日历日
--   应付 = ROUND(实付合计 × 0.3, 2)；出账日无单仍留账单（无需打款）
--   已打款账单不改明细
--   起点之前已入账的订单（如 7/28 同城挂在 7/31）保持原账单，不迁到 8/4
--
-- 本脚本会：
--   1) 补现场提货等缺 completed_at 的已完成单
--   2) 按周期补齐出账日账单（含中间应付为 0 的空账）
--   3) 把未入账 / 挂错期（如 8/29）的同城、跨城、现场提货订单迁入对应出账日
--   4) 按明细重算未打款表头
--   5) 删除未打款、无明细、且非周期日的空账单（7/29、8/1、8/29 等）
--
-- 建议：先部署含「每 3 天出一期」的 API，再跑本脚本。
--       若必须先修数据：跑完后尽快发版，避免旧「每日只收 D-3 当天」任务回刷 8/28。
--
-- 用法（生产）：
--   mysql -u... -p dukang_prod < fix-winery-bills-v406.sql
-- =============================================================================

START TRANSACTION;

-- 1) 现场提货等：支付即完成但未写 completed_at
UPDATE user_order
SET completed_at = paid_at
WHERE status = 'COMPLETED'
  AND pay_status = 'PAID'
  AND completed_at IS NULL
  AND paid_at IS NOT NULL;

-- 2) 补齐周期出账日（8/4 起至「今天北京日」能落到的最后一张）
INSERT INTO winery_bill (
  bill_no, bill_date, order_count, order_amount, winery_rate, winery_amount, status, created_at
)
WITH RECURSIVE issue_days AS (
  SELECT DATE('2026-08-04') AS issue_ymd
  UNION ALL
  SELECT DATE_ADD(issue_ymd, INTERVAL 3 DAY)
  FROM issue_days
  WHERE DATE_ADD(issue_ymd, INTERVAL 3 DAY) <= DATE(DATE_ADD(UTC_TIMESTAMP(), INTERVAL 8 HOUR))
)
SELECT
  CONCAT('WBFIX', DATE_FORMAT(d.issue_ymd, '%Y%m%d')) AS bill_no,
  TIMESTAMP(DATE_ADD(d.issue_ymd, INTERVAL -8 HOUR)) AS bill_date,
  0,
  0.00,
  0.3000,
  0.00,
  'UNPAID',
  TIMESTAMP(DATE_ADD(d.issue_ymd, INTERVAL -8 HOUR))
FROM issue_days d
WHERE NOT EXISTS (
  SELECT 1
  FROM winery_bill b
  WHERE b.bill_date = TIMESTAMP(DATE_ADD(d.issue_ymd, INTERVAL -8 HOUR))
);

-- 3) 起点日及之后：从未打款账单上拿掉挂错期的明细（已打款账单因 status 过滤不会动）
DELETE i
FROM winery_bill_item i
INNER JOIN winery_bill b ON b.id = i.winery_bill_id
INNER JOIN user_order o ON o.id = i.order_id
INNER JOIN winery_bill target
  ON target.bill_date = TIMESTAMP(DATE_ADD(
    DATE_ADD(
      DATE('2026-08-01'),
      INTERVAL (FLOOR(DATEDIFF(
        DATE(CONVERT_TZ(COALESCE(o.completed_at, o.paid_at), '+00:00', '+08:00')),
        DATE('2026-08-01')
      ) / 3) + 1) * 3 DAY
    ),
    INTERVAL -8 HOUR
  ))
WHERE b.status = 'UNPAID'
  AND b.id <> target.id
  AND o.status = 'COMPLETED'
  AND o.pay_status = 'PAID'
  AND o.delivery_type IN ('LOCAL', 'CROSS_CITY', 'ON_SITE_PICKUP')
  AND COALESCE(o.completed_at, o.paid_at) IS NOT NULL
  AND DATE(CONVERT_TZ(COALESCE(o.completed_at, o.paid_at), '+00:00', '+08:00')) >= '2026-08-01';

-- 4) 把未入账的同城/跨城/现场提货订单写入对应周期账单
INSERT INTO winery_bill_item (
  winery_bill_id, order_id, order_no, delivery_type, pay_amount, winery_amount, paid_at, created_at
)
SELECT
  target.id,
  o.id,
  o.order_no,
  o.delivery_type,
  o.pay_amount,
  ROUND(o.pay_amount * 0.3, 2),
  COALESCE(o.paid_at, o.completed_at),
  UTC_TIMESTAMP(3)
FROM user_order o
INNER JOIN winery_bill target
  ON target.bill_date = TIMESTAMP(DATE_ADD(
    DATE_ADD(
      DATE('2026-08-01'),
      INTERVAL (FLOOR(DATEDIFF(
        DATE(CONVERT_TZ(COALESCE(o.completed_at, o.paid_at), '+00:00', '+08:00')),
        DATE('2026-08-01')
      ) / 3) + 1) * 3 DAY
    ),
    INTERVAL -8 HOUR
  ))
LEFT JOIN winery_bill_item existing ON existing.order_id = o.id
WHERE o.status = 'COMPLETED'
  AND o.pay_status = 'PAID'
  AND o.delivery_type IN ('LOCAL', 'CROSS_CITY', 'ON_SITE_PICKUP')
  AND COALESCE(o.completed_at, o.paid_at) IS NOT NULL
  AND DATE(CONVERT_TZ(COALESCE(o.completed_at, o.paid_at), '+00:00', '+08:00')) >= '2026-08-01'
  AND existing.id IS NULL;

-- 5) 按明细重算所有未打款表头（应付为 0 的周期账单也保留）
UPDATE winery_bill b
LEFT JOIN (
  SELECT
    winery_bill_id,
    COUNT(*) AS order_count,
    ROUND(SUM(pay_amount), 2) AS order_amount
  FROM winery_bill_item
  GROUP BY winery_bill_id
) x ON x.winery_bill_id = b.id
SET
  b.order_count = IFNULL(x.order_count, 0),
  b.order_amount = IFNULL(x.order_amount, 0.00),
  b.winery_rate = 0.3000,
  b.winery_amount = ROUND(IFNULL(x.order_amount, 0) * 0.3, 2)
WHERE b.status = 'UNPAID';

-- 6) 清掉误生成的非周期日空账单（有明细的如 7/31 保留；8/1 虽 MOD=0 但未满 3 天，仍删）
DELETE b
FROM winery_bill b
LEFT JOIN winery_bill_item i ON i.winery_bill_id = b.id
WHERE b.status = 'UNPAID'
  AND i.id IS NULL
  AND NOT (
    DATEDIFF(DATE(CONVERT_TZ(b.bill_date, '+00:00', '+08:00')), DATE('2026-08-01')) >= 3
    AND MOD(DATEDIFF(DATE(CONVERT_TZ(b.bill_date, '+00:00', '+08:00')), DATE('2026-08-01')), 3) = 0
  );

COMMIT;

-- -----------------------------------------------------------------------------
-- 核对（不改数据）
-- -----------------------------------------------------------------------------
SELECT '=== 账单列表 ===' AS s;
SELECT
  DATE(CONVERT_TZ(bill_date, '+00:00', '+08:00')) AS bill_ymd,
  bill_no,
  order_count,
  order_amount,
  winery_amount,
  status
FROM winery_bill
ORDER BY bill_date;

SELECT '=== 明细按配送类型 ===' AS s;
SELECT delivery_type, COUNT(*) AS cnt, ROUND(SUM(pay_amount), 2) AS pay_sum
FROM winery_bill_item
GROUP BY delivery_type;

SELECT '=== 应入账但未入账（应为 0 行）===' AS s;
SELECT o.id, o.order_no, o.delivery_type, o.pay_amount,
  DATE(CONVERT_TZ(COALESCE(o.completed_at, o.paid_at), '+00:00', '+08:00')) AS attr_ymd
FROM user_order o
LEFT JOIN winery_bill_item i ON i.order_id = o.id
WHERE o.status = 'COMPLETED'
  AND o.pay_status = 'PAID'
  AND o.delivery_type IN ('LOCAL', 'CROSS_CITY', 'ON_SITE_PICKUP')
  AND i.id IS NULL;

SELECT '=== 非周期日仍在的账单（仅允许起点前已入账的，如 7/31）===' AS s;
SELECT
  DATE(CONVERT_TZ(bill_date, '+00:00', '+08:00')) AS bill_ymd,
  bill_no,
  order_count,
  order_amount,
  status
FROM winery_bill
WHERE NOT (
  DATEDIFF(DATE(CONVERT_TZ(bill_date, '+00:00', '+08:00')), DATE('2026-08-01')) >= 3
  AND MOD(DATEDIFF(DATE(CONVERT_TZ(bill_date, '+00:00', '+08:00')), DATE('2026-08-01')), 3) = 0
)
ORDER BY bill_date;
