<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.biz.ExpenseItemMapper">


    <select id="selectCurrentMonthList" resultType="cn.iocoder.yudao.module.system.dal.dataobject.biz.ExpenseItemDO">
        SELECT
            eei.*
        FROM
            elderly_expense ee
                INNER JOIN elderly_expense_item eei ON ee.id = eei.expense_id
        WHERE
            ee.elder_id = #{elderlyId}
          AND eei.type = #{type}
--           AND eei.change_flag = 0
          AND DATE_FORMAT( eei.change_start_date, '%Y-%m' ) = DATE_FORMAT(#{retreatDate},'%Y-%m')
    </select>
    <select id="selectListByMonth"
            resultType="cn.iocoder.yudao.module.system.dal.dataobject.biz.ExpenseItemDO">
        SELECT
            eei.*
        FROM
            elderly_expense ee
                INNER JOIN elderly_expense_item eei ON ee.id = eei.expense_id
        WHERE
            ee.elder_id = #{elderId}
            AND eei.type = #{type}
            AND DATE_FORMAT( eei.change_start_date, '%Y-%m' ) = DATE_FORMAT(#{queryDate},'%Y-%m')
            ORDER BY eei.change_start_date asc
    </select>
    <!-- 月度账单生成查询 -->
    <select id="generateMonthlyBill" resultType="cn.iocoder.yudao.module.system.dal.dataobject.biz.ExpenseItemDO">
        <![CDATA[
    SELECT
        expense_data.id,
        expense_data.expenseId,
        expense_data.itemId,
        expense_data.itemCategoryId,
        expense_data.itemCategoryName,
        COALESCE(soc.charge_name, expense_data.itemName) AS itemName,
        expense_data.billAmount AS amount,
        expense_data.billAmount AS actualAmount,
        expense_data.isDiscount,
        expense_data.discount,
        expense_data.isMonthlyExpense,
        expense_data.isOneTimeFee,
        expense_data.isDeposit,
        expense_data.isFreeGift,
        expense_data.freeStartTime,
        expense_data.freeEndTime,
        expense_data.isHirePurchase,
        expense_data.hirePurchaseNumber,
        expense_data.hirePurchaseAmount,
        expense_data.count,
        expense_data.billAmount AS totalAmount,
        expense_data.type,
        expense_data.discountAmount,
        expense_data.tenantId,
        expense_data.changeStartDate,
        expense_data.changeEndDate,
        expense_data.changeFlag,
        expense_data.createTime,
        expense_data.billAmount,
        expense_data.isDayCalculate
    FROM (
        SELECT
            eei.id,
            eei.expense_id AS expenseId,
            -- 判断依据：账单月内是否有针对此费用项的变更记录（基于 change_date）
            CASE
                WHEN EXISTS (
                    SELECT 1
                    FROM elderly_change_record ecr
                    WHERE ecr.elderly_id = ee.elder_id
                      AND (ecr.expect_overhead_charge_id = eei.item_id OR ecr.overhead_charge_id = eei.item_id)
                      AND DATE_FORMAT(ecr.change_date, '%Y-%m') = #{billingMonth}
                      AND ecr.deleted = 0
                )
                THEN COALESCE(
                    (
                        SELECT ecr.overhead_charge_id
                        FROM elderly_change_record ecr
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                        LIMIT 1
                    ),
                    (
                        SELECT epcr.original_id
                        FROM elderly_change_record ecr
                        INNER JOIN elderly_price_change_record epcr ON ecr.id = epcr.change_id
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                          AND epcr.deleted = 0
                        LIMIT 1
                    ),
                    eei.item_id
                )
                ELSE eei.item_id
            END AS itemId,
            eei.item_category_id AS itemCategoryId,
            CASE
                WHEN EXISTS (
                    SELECT 1
                    FROM elderly_change_record ecr
                    WHERE ecr.elderly_id = ee.elder_id
                      AND (ecr.expect_overhead_charge_id = eei.item_id OR ecr.overhead_charge_id = eei.item_id)
                      AND DATE_FORMAT(ecr.change_date, '%Y-%m') = #{billingMonth}
                      AND ecr.deleted = 0
                )
                THEN COALESCE(
                    (
                        SELECT ecr.category_name
                        FROM elderly_change_record ecr
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                        LIMIT 1
                    ),
                    (
                        SELECT epcr.category_name
                        FROM elderly_change_record ecr
                        INNER JOIN elderly_price_change_record epcr ON ecr.id = epcr.change_id
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                          AND epcr.deleted = 0
                        LIMIT 1
                    ),
                    eei.item_category_name
                )
                ELSE eei.item_category_name
            END AS itemCategoryName,
            CASE
                WHEN EXISTS (
                    SELECT 1
                    FROM elderly_change_record ecr
                    WHERE ecr.elderly_id = ee.elder_id
                      AND (ecr.expect_overhead_charge_id = eei.item_id OR ecr.overhead_charge_id = eei.item_id)
                      AND DATE_FORMAT(ecr.change_date, '%Y-%m') = #{billingMonth}
                      AND ecr.deleted = 0
                )
                THEN COALESCE(
                    (
                        SELECT ecr.original_name
                        FROM elderly_change_record ecr
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                        LIMIT 1
                    ),
                    (
                        SELECT epcr.original_name
                        FROM elderly_change_record ecr
                        INNER JOIN elderly_price_change_record epcr ON ecr.id = epcr.change_id
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                          AND epcr.deleted = 0
                        LIMIT 1
                    ),
                    eei.item_name
                )
                ELSE eei.item_name
            END AS itemName,
            eei.is_discount AS isDiscount,
            eei.discount,
            eei.is_monthly_expense AS isMonthlyExpense,
            eei.is_one_time_fee AS isOneTimeFee,
            eei.is_deposit AS isDeposit,
            eei.is_free_gift AS isFreeGift,
            eei.free_start_time AS freeStartTime,
            eei.free_end_time AS freeEndTime,
            eei.is_hire_purchase AS isHirePurchase,
            eei.hire_purchase_number AS hirePurchaseNumber,
            eei.hire_purchase_amount AS hirePurchaseAmount,
            eei.count,
            eei.type,
            eei.discount_amount AS discountAmount,
            eei.tenant_id AS tenantId,
            eei.change_start_date AS changeStartDate,
            eei.change_end_date AS changeEndDate,
            eei.change_flag AS changeFlag,
            eei.create_time AS createTime,
            eei.is_day_calculate AS isDayCalculate,
            -- billAmount 修正（同样基于实际变更日期）
            CASE
                WHEN EXISTS (
                    SELECT 1
                    FROM elderly_change_record ecr
                    WHERE ecr.elderly_id = ee.elder_id
                      AND (ecr.expect_overhead_charge_id = eei.item_id OR ecr.overhead_charge_id = eei.item_id)
                      AND DATE_FORMAT(ecr.change_date, '%Y-%m') = #{billingMonth}
                      AND ecr.deleted = 0
                )
                THEN COALESCE(
                    (
                        SELECT pcr.original_amount
                        FROM elderly_price_change_record pcr
                        INNER JOIN elderly_change_record ecr ON pcr.change_id = ecr.id
                        WHERE pcr.original_id = eei.item_id
                          AND ecr.elderly_id = ee.elder_id
                          AND pcr.deleted = 0
                          AND ecr.deleted = 0
                          AND ecr.change_date = STR_TO_DATE(CONCAT(#{billingMonth}, '-01'), '%Y-%m-%d')
                        LIMIT 1
                    ),
                    (
                        SELECT pcr.original_amount
                        FROM elderly_price_change_record pcr
                        INNER JOIN elderly_change_record ecr ON pcr.change_id = ecr.id
                        WHERE pcr.original_id = eei.item_id
                          AND ecr.elderly_id = ee.elder_id
                          AND pcr.deleted = 0
                          AND ecr.deleted = 0
                        ORDER BY ecr.change_date DESC
                        LIMIT 1
                    ),
                    (
                        SELECT original_amount
                        FROM elderly_change_record ecr
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                          AND ecr.change_date = STR_TO_DATE(CONCAT(#{billingMonth}, '-01'), '%Y-%m-%d')
                        ORDER BY ecr.change_date DESC
                        LIMIT 1
                    ),
                    (
                        SELECT original_amount
                        FROM elderly_change_record ecr
                        WHERE ecr.elderly_id = ee.elder_id
                          AND (ecr.overhead_charge_id = eei.item_id OR ecr.expect_overhead_charge_id = eei.item_id)
                          AND ecr.deleted = 0
                        ORDER BY ecr.change_date DESC
                        LIMIT 1
                    ),
                    eei.actual_amount
                )
                ELSE eei.actual_amount
            END AS billAmount
        FROM elderly_expense_item eei
        INNER JOIN elderly_expense ee ON eei.expense_id = ee.id
        INNER JOIN (
            SELECT
                eei2.item_id,
                MAX(eei2.create_time) AS max_create_time
            FROM elderly_expense_item eei2
            INNER JOIN elderly_expense ee2 ON eei2.expense_id = ee2.id
            WHERE eei2.is_monthly_expense = 1
              AND ee2.elder_id = #{elderId}
              AND (
                  (DATE_FORMAT(eei2.change_start_date, '%Y-%m') <= #{billingMonth}
                   AND DATE_FORMAT(eei2.change_end_date, '%Y-%m') >= #{billingMonth})
                  OR (DATE_FORMAT(eei2.change_start_date, '%Y-%m') <= #{billingMonth}
                      AND eei2.change_end_date IS NULL)
              )
              AND NOT (
                  DATE_FORMAT(eei2.change_start_date, '%Y-%m') = #{billingMonth}
                  AND eei2.change_start_date > STR_TO_DATE(CONCAT(#{billingMonth}, '-01'), '%Y-%m-%d')
                  AND EXISTS (
                      SELECT 1
                      FROM elderly_change_record ecr
                      WHERE ecr.elderly_id = ee2.elder_id
                        AND ecr.expect_overhead_charge_id = eei2.item_id
                        AND DATE_FORMAT(ecr.change_date, '%Y-%m') = #{billingMonth}
                        AND ecr.deleted = 0
                  )
              )
            GROUP BY eei2.item_id
        ) latest ON eei.item_id = latest.item_id AND eei.create_time = latest.max_create_time
        WHERE eei.is_monthly_expense = 1
          AND ee.elder_id = #{elderId}
          AND (
              (DATE_FORMAT(eei.change_start_date, '%Y-%m') <= #{billingMonth}
               AND DATE_FORMAT(eei.change_end_date, '%Y-%m') >= #{billingMonth})
              OR (DATE_FORMAT(eei.change_start_date, '%Y-%m') <= #{billingMonth}
                  AND eei.change_end_date IS NULL)
          )
          AND NOT (
              DATE_FORMAT(eei.change_start_date, '%Y-%m') = #{billingMonth}
              AND eei.change_start_date > STR_TO_DATE(CONCAT(#{billingMonth}, '-01'), '%Y-%m-%d')
              AND EXISTS (
                  SELECT 1
                  FROM elderly_change_record ecr
                  WHERE ecr.elderly_id = ee.elder_id
                    AND ecr.expect_overhead_charge_id = eei.item_id
                    AND DATE_FORMAT(ecr.change_date, '%Y-%m') = #{billingMonth}
                    AND ecr.deleted = 0
              )
          )
    ) expense_data
    LEFT JOIN sys_overhead_charge soc ON soc.id = expense_data.itemId
    ]]>
    </select>
</mapper>
