<?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="com.ruoyi.oa.mapper.SalaryDashboardMapper">

    <!-- 查询卡片指标数据 -->
    <select id="queryCardMetrics" resultType="com.ruoyi.oa.domain.vo.CardMetricsVo">
        SELECT
            -- 薪资支出总额：只计算salary类型的实际支出
            SUM(CASE WHEN d.template_type = 'salary' THEN d.paid_amount ELSE 0 END) AS totalSalaryExpenditure,
            -- 公司总支出：包括薪资和社保的所有实际支出
            SUM(d.paid_amount) AS totalCompanyExpenditure,
            COUNT(DISTINCT b.employee_id) AS employeeCount,
            COUNT(DISTINCT e.dept_id) AS departmentCount
        FROM
            oa_employee_template_binding b
                JOIN oa_binding_item_detail d ON b.binding_id = d.binding_id
                JOIN oa_employee e ON b.employee_id = e.employee_id
        WHERE
            b.pay_year = #{year}
          AND b.pay_month = #{month}
          AND b.del_flag = 0
          AND e.del_flag = 0
          AND d.del_flag = 0
    </select>

    <!-- 查询年度每月总支出 -->
    <select id="queryMonthlyExpenditures" resultType="com.ruoyi.oa.domain.vo.MonthlyExpenditureVo">
        SELECT
            b.pay_month AS month,
            SUM(d.paid_amount) AS totalExpenditure
        FROM
            oa_employee_template_binding b
                JOIN oa_binding_item_detail d ON b.binding_id = d.binding_id
        WHERE
            b.pay_year = #{year}
          AND b.del_flag = 0
          AND d.del_flag = 0
        GROUP BY
            b.pay_month
        ORDER BY
            b.pay_month
    </select>

    <!-- 查询薪资构成 -->
    <select id="querySalaryComponents" resultType="com.ruoyi.oa.domain.vo.SalaryComponentVo">
        SELECT
            sdt.salary_item AS itemName,
            SUM(bid.paid_amount) AS totalAmount
        FROM
            oa_binding_item_detail bid
                JOIN oa_employee_template_binding betb ON bid.binding_id = betb.binding_id
                JOIN oa_salary_template_detail sdt ON bid.item_detail_id = sdt.salary_detail_id
        WHERE
            betb.pay_year = #{year}
          AND betb.pay_month = #{month}
          AND bid.template_type = 'salary'
          AND betb.del_flag = 0
          AND bid.del_flag = 0
        GROUP BY
            sdt.salary_item
    </select>

    <!-- 查询折线图数据 -->
    <select id="queryLineChartData" resultType="com.ruoyi.oa.domain.vo.LineChartPointVo">
        SELECT
            b.pay_month AS month,
            -- 总支出：所有实际支出（包括薪资和社保）
            SUM(d.paid_amount) AS totalExpenditure,
            -- 平均工资：只计算salary类型的实际支出的平均值
            AVG(CASE WHEN d.template_type = 'salary' THEN d.paid_amount ELSE 0 END) AS avgSalary
        FROM
            oa_employee_template_binding b
                JOIN oa_binding_item_detail d ON b.binding_id = d.binding_id
        WHERE
            b.pay_year = #{year}
          AND b.del_flag = 0
          AND d.del_flag = 0
        GROUP BY
            b.pay_month
        ORDER BY
            b.pay_month
    </select>

    <!-- 查询部门统计数据 -->
    <select id="queryDepartmentStats" resultType="com.ruoyi.oa.domain.vo.DepartmentStatVo">
        WITH CurrentYearStats AS (
            SELECT
                e.dept_id,
                -- 部门总支出：该部门所有员工的所有实际支出
                SUM(d.paid_amount) AS totalExpenditure,
                -- 部门平均工资：该部门所有员工的salary类型实际支出的平均值
                AVG(CASE WHEN d.template_type = 'salary' THEN d.paid_amount ELSE 0 END) AS avgSalary,
                COUNT(DISTINCT e.employee_id) AS employeeCount
            FROM
                oa_employee_template_binding b
                    JOIN oa_employee e ON b.employee_id = e.employee_id
                    JOIN oa_binding_item_detail d ON b.binding_id = d.binding_id
            WHERE
                b.pay_year = #{year}
              AND b.pay_month = #{month}
              AND b.del_flag = 0
              AND d.del_flag = 0
            GROUP BY
                e.dept_id
        ),
             LastYearStats AS (
                 SELECT
                     e.dept_id,
                     -- 去年同期部门平均工资：只计算salary类型的实际支出
                     AVG(CASE WHEN d.template_type = 'salary' THEN d.paid_amount ELSE 0 END) AS lastYearAvgSalary
                 FROM
                     oa_employee_template_binding b
                         JOIN oa_employee e ON b.employee_id = e.employee_id
                         JOIN oa_binding_item_detail d ON b.binding_id = d.binding_id
                 WHERE
                     b.pay_year = #{year} - 1
                   AND b.pay_month = #{month}
                   AND b.del_flag = 0
                   AND d.del_flag = 0
                 GROUP BY
                     e.dept_id
             )
        SELECT
            d.dept_id,
            d.dept_name,
            COALESCE(cys.totalExpenditure, 0) AS totalExpenditure,
            COALESCE(cys.avgSalary, 0) AS avgSalary,
            COALESCE(cys.employeeCount, 0) AS employeeCount,
            CASE
                WHEN lys.lastYearAvgSalary IS NULL OR lys.lastYearAvgSalary = 0 THEN 0
                ELSE ((COALESCE(cys.avgSalary, 0) - lys.lastYearAvgSalary) / lys.lastYearAvgSalary) * 100
                END AS yearOnYearGrowthRate
        FROM
            sys_dept d
                LEFT JOIN CurrentYearStats cys ON d.dept_id = cys.dept_id
                LEFT JOIN LastYearStats lys ON d.dept_id = lys.dept_id
        WHERE
            d.del_flag = '0'
          AND cys.employeeCount > 0
        ORDER BY
            totalExpenditure DESC
    </select>
    <!-- 查询卡片指标数据 -->
    <select id="queryNewCardMetrics" resultType="com.ruoyi.oa.domain.vo.dashboard.NewCardMetricsVo">
        SELECT
            COALESCE(SUM(d.net_salary), 0) as totalNetSalary,
            COALESCE(SUM(d.gross_salary), 0) as totalGrossSalary,
            COALESCE(SUM(d.unit_total_expense), 0) as totalUnitExpense,
            COUNT(DISTINCT d.detail_id) as employeeCount,
            COUNT(DISTINCT m.unit_name) as unitCount
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0
          AND d.del_flag = 0
    </select>

    <!-- 查询月度支出数据 -->
    <select id="queryMonthlyExpenses" resultType="com.ruoyi.oa.domain.vo.dashboard.MonthlyExpenseVo">
        SELECT
            CAST(SUBSTRING(m.salary_period, 6, 2) AS UNSIGNED) as month,
            COALESCE(SUM(d.net_salary), 0) as totalNetSalary,
            COALESCE(SUM(d.gross_salary), 0) as totalGrossSalary,
            COALESCE(SUM(d.unit_total_expense), 0) as totalUnitExpense
        FROM oa_salary_master m
            LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE SUBSTRING(m.salary_period, 1, 4) = #{year}
          AND m.del_flag = 0
          AND d.del_flag = 0
        GROUP BY CAST(SUBSTRING(m.salary_period, 6, 2) AS UNSIGNED)
        ORDER BY month
    </select>

    <!-- 查询工资构成数据 -->
    <select id="querySalaryStructures" resultType="com.ruoyi.oa.domain.vo.dashboard.SalaryStructureVo">
        SELECT
            '基本工资' as itemName,
            COALESCE(SUM(d.basic_salary), 0) as totalAmount,
            CASE
                WHEN SUM(d.gross_salary) > 0 THEN ROUND((SUM(d.basic_salary) / SUM(d.gross_salary)) * 100, 2)
                ELSE 0
                END as percentage
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '岗位工资' as itemName,
            COALESCE(SUM(d.post_salary), 0) as totalAmount,
            CASE
                WHEN SUM(d.gross_salary) > 0 THEN ROUND((SUM(d.post_salary) / SUM(d.gross_salary)) * 100, 2)
                ELSE 0
                END as percentage
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '餐补' as itemName,
            COALESCE(SUM(d.meal_allowance), 0) as totalAmount,
            CASE
                WHEN SUM(d.gross_salary) > 0 THEN ROUND((SUM(d.meal_allowance) / SUM(d.gross_salary)) * 100, 2)
                ELSE 0
                END as percentage
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '住房补贴' as itemName,
            COALESCE(SUM(d.housing_allowance), 0) as totalAmount,
            CASE
                WHEN SUM(d.gross_salary) > 0 THEN ROUND((SUM(d.housing_allowance) / SUM(d.gross_salary)) * 100, 2)
                ELSE 0
                END as percentage
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '公交补贴' as itemName,
            COALESCE(SUM(d.bus_allowance), 0) as totalAmount,
            CASE
                WHEN SUM(d.gross_salary) > 0 THEN ROUND((SUM(d.bus_allowance) / SUM(d.gross_salary)) * 100, 2)
                ELSE 0
                END as percentage
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '出差补助' as itemName,
            COALESCE(SUM(d.business_allowance), 0) as totalAmount,
            CASE
                WHEN SUM(d.gross_salary) > 0 THEN ROUND((SUM(d.business_allowance) / SUM(d.gross_salary)) * 100, 2)
                ELSE 0
                END as percentage
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '加班工资' as itemName,
            COALESCE(SUM(d.overtime_total), 0) as totalAmount,
            CASE
                WHEN SUM(d.gross_salary) > 0 THEN ROUND((SUM(d.overtime_total) / SUM(d.gross_salary)) * 100, 2)
                ELSE 0
                END as percentage
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        ORDER BY totalAmount DESC
    </select>

    <!-- 查询工资趋势数据 -->
    <select id="querySalaryTrendData" resultType="com.ruoyi.oa.domain.vo.dashboard.SalaryTrendPointVo">
        SELECT
            CAST(SUBSTRING(m.salary_period, 6, 2) AS UNSIGNED) as month,
            COALESCE(SUM(d.net_salary), 0) as totalNetSalary,
            COALESCE(SUM(d.gross_salary), 0) as totalGrossSalary,
            CASE
                WHEN COUNT(DISTINCT d.detail_id) > 0 THEN ROUND(SUM(d.net_salary) / COUNT(DISTINCT d.detail_id), 2)
                ELSE 0
        END as avgNetSalary
        FROM oa_salary_master m
        LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE SUBSTRING(m.salary_period, 1, 4) = #{year}
        AND m.del_flag = 0
        AND d.del_flag = 0
        GROUP BY CAST(SUBSTRING(m.salary_period, 6, 2) AS UNSIGNED)
        ORDER BY month
    </select>

    <!-- 查询社保公积金统计数据 -->
    <select id="queryInsuranceStats" resultType="com.ruoyi.oa.domain.vo.dashboard.InsuranceStatVo">
        SELECT
            '养老保险' as itemName,
            COALESCE(SUM(d.personal_pension), 0) as personalTotal,
            COALESCE(SUM(d.enterprise_pension), 0) as enterpriseTotal,
            COALESCE(SUM(d.personal_pension) + SUM(d.enterprise_pension), 0) as total
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '医疗保险' as itemName,
            COALESCE(SUM(d.personal_medical), 0) as personalTotal,
            COALESCE(SUM(d.enterprise_medical), 0) as enterpriseTotal,
            COALESCE(SUM(d.personal_medical) + SUM(d.enterprise_medical), 0) as total
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '失业保险' as itemName,
            COALESCE(SUM(d.personal_unemployment), 0) as personalTotal,
            COALESCE(SUM(d.enterprise_unemployment), 0) as enterpriseTotal,
            COALESCE(SUM(d.personal_unemployment) + SUM(d.enterprise_unemployment), 0) as total
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '住房公积金' as itemName,
            COALESCE(SUM(d.personal_housing_fund), 0) as personalTotal,
            COALESCE(SUM(d.enterprise_housing_fund), 0) as enterpriseTotal,
            COALESCE(SUM(d.personal_housing_fund) + SUM(d.enterprise_housing_fund), 0) as total
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '工伤保险' as itemName,
            0 as personalTotal,
            COALESCE(SUM(d.enterprise_injury), 0) as enterpriseTotal,
            COALESCE(SUM(d.enterprise_injury), 0) as total
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        UNION ALL

        SELECT
            '生育保险' as itemName,
            0 as personalTotal,
            COALESCE(SUM(d.enterprise_maternity), 0) as enterpriseTotal,
            COALESCE(SUM(d.enterprise_maternity), 0) as total
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0 AND d.del_flag = 0

        ORDER BY total DESC
    </select>

    <!-- 查询单位统计数据 -->
    <select id="queryUnitStats" resultType="com.ruoyi.oa.domain.vo.dashboard.UnitStatVo">
        SELECT
            m.unit_name as unitName,
            COUNT(DISTINCT d.detail_id) as employeeCount,
            COALESCE(SUM(d.net_salary), 0) as totalNetSalary,
            COALESCE(SUM(d.gross_salary), 0) as totalGrossSalary,
            COALESCE(SUM(d.unit_total_expense), 0) as totalUnitExpense,
            CASE
                WHEN COUNT(DISTINCT d.detail_id) > 0 THEN ROUND(SUM(d.net_salary) / COUNT(DISTINCT d.detail_id), 2)
                ELSE 0
                END as avgNetSalary,
            m.salary_period as salaryPeriod,
            0 as yearOnYearGrowthRate
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0
          AND d.del_flag = 0
        GROUP BY m.unit_name, m.salary_period
        ORDER BY totalNetSalary DESC
    </select>

    <!-- 查询部门统计数据 -->
    <select id="queryDeptSalaryStats" resultType="com.ruoyi.oa.domain.vo.dashboard.DeptSalaryStatVo">
        SELECT
            COALESCE(d.dept, '未分配部门') as deptName,
            COUNT(DISTINCT d.detail_id) as employeeCount,
            COALESCE(SUM(d.net_salary), 0) as totalNetSalary,
            COALESCE(SUM(d.gross_salary), 0) as totalGrossSalary,
            CASE
                WHEN COUNT(DISTINCT d.detail_id) > 0 THEN ROUND(SUM(d.net_salary) / COUNT(DISTINCT d.detail_id), 2)
                ELSE 0
                END as avgNetSalary,
            CASE
                WHEN COUNT(DISTINCT d.detail_id) > 0 THEN ROUND(SUM(d.gross_salary) / COUNT(DISTINCT d.detail_id), 2)
                ELSE 0
                END as avgGrossSalary,
            0 as yearOnYearGrowthRate
        FROM oa_salary_master m
                 LEFT JOIN oa_salary_detail d ON m.master_id = d.main_id
        WHERE m.salary_period = #{salaryPeriod}
          AND m.del_flag = 0
          AND d.del_flag = 0
        GROUP BY d.dept
        ORDER BY totalNetSalary DESC
    </select>
</mapper>