<?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.bonus.canteen.core.report.mapper.TradeReportMapper">
    <select id="selectTradeFlow" resultType="com.bonus.canteen.core.report.domain.TradeFlowVO">
        select
        su.user_id,
        su.user_name,
        su.user_type,
        su.phonenumber,
        sd.dept_id,
        sd.dept_name,
        sd.dept_full_name,
        at2.acc_all_bal,
        at2.trade_time,
        at2.trade_type,
        at2.pay_type,
        at2.machine_sn,
        di.device_name,
        at2.create_by,
        IFNULL(CASE
        WHEN at2.trade_type in (10, 20, 130) then
        at2.actual_amount
        end, 0)as income,
        IFNULL(CASE
        WHEN at2.trade_type in (30, 100, 110) then
        at2.actual_amount
        end, 0) as outcome
        from
        acc_trade at2
        left join sys_user su on
        at2.user_id = su.user_id
        left join sys_dept sd on
        su.dept_id = sd.dept_id
        left join device_info di on
        at2.machine_sn = di.device_sn
        where
        at2.pay_state = 3
        and at2.trade_time <![CDATA[ >= ]]> #{param.startDateTime}
        and at2.trade_time <![CDATA[ <= ]]> #{param.endDateTime}
        <if test="param.deptIdList != null and param.deptIdList.size() > 0">
            and su.dept_id IN
            <foreach collection="param.deptIdList" item="deptId" separator="," open="(" close=")">
                #{deptId}
            </foreach>
        </if>
        <if test="param.searchValue != null and param.searchValue != ''">
            and (
            su.nick_name like CONCAT('%',#{param.searchValue},'%')
            or su.phonenumber = #{encryptedSearchValue}
            or su.user_id like concat('%', #{param.searchValue}, '%')
            )
        </if>
        order by at2.trade_time desc
    </select>
    
    <select id="selectOperatingRevenue" resultType="com.bonus.canteen.core.report.domain.OperatingRevenueVO">
        select
            count(distinct oi.user_id) as user_count,
            count(oi.order_id) as order_count,
            sum(oi.payable_amount) as payable_amount ,
            sum(oi.discounts_amount) as discounts_amount ,
            sum(oi.real_amount - oi.refund_amount) as real_amount,
            sum(b.personal_wallet_count) as personal_wallet_count,
            sum(b.sub_wallet_count) as sub_wallet_count
        from
            order_info oi
                left join sys_user su on
                oi.user_id = su.user_id
                left join (
                select
                    ats.order_no,
                    sum(case when atwd.wallet_id = 1 and ats.trade_type = 110 and ats.pay_state = 3 then
                                 ifnull(atwd.amount, 0) ELSE 0 end) -
                    sum(case when atwd.wallet_id = 1 and ats.trade_type = 130 and ats.pay_state = 3 then
                                 ifnull(atwd.amount, 0) ELSE 0 end) as personal_wallet_count,
                    sum(case when atwd.wallet_id = 2 and ats.trade_type = 110 and ats.pay_state = 3 then
                                 ifnull(atwd.amount, 0) ELSE 0 end) -
                    sum(case when atwd.wallet_id = 2 and ats.trade_type = 130 and ats.pay_state = 3 then
                                 ifnull(atwd.amount, 0) ELSE 0 end) as sub_wallet_count
                from
                    acc_trade ats
                        left join acc_trade_wallet_detail atwd on
                        ats.trade_id = atwd.trade_id
                group by
                    ats.order_no) b on
                oi.order_id = b.order_no
        where oi.pay_state = 3 and oi.order_state in (1, 2)
        and oi.pay_time <![CDATA[ >= ]]> #{param.startDateTime}
        and oi.pay_time <![CDATA[ <= ]]> #{param.endDateTime}
        <if test="param.deptIdList != null and param.deptIdList.size() > 0">
            and su.dept_id IN
            <foreach collection="param.deptIdList" item="deptId" separator="," open="(" close=")">
                #{deptId}
            </foreach>
        </if>
    </select>

    <select id="selectCanteenStallRevenue" resultType="com.bonus.canteen.core.report.domain.CanteenStallRevenueVO">
        select
            oi.canteen_id,
            oi.stall_id,
            CONCAT(ac.canteen_name , '/', ast.stall_name) as canteenAndStallName,
            count(distinct case when oi.mealtime_type = 1 then
                                    oi.user_id else null
                end) as breakfast_user_count,
            count(case when oi.mealtime_type = 1 then
                           oi.order_id else null
                end) as breakfast_order_count,
            sum(case when oi.mealtime_type = 1 then
                         oi.real_amount - oi.refund_amount else 0
                end) as breakfast_consume_count,
            count(distinct case when oi.mealtime_type = 2 then
                                    oi.user_id else null
                end) as lunch_user_count,
            count(case when oi.mealtime_type = 2 then
                           oi.order_id else null
                end) as lunch_order_count,
            sum(case when oi.mealtime_type = 2 then
                         oi.real_amount - oi.refund_amount else 0
                end) as lunch_consume_count,
            count(distinct case when oi.mealtime_type = 3 then
                                    oi.user_id else null
                end) as afternoon_tea_user_count,
            count(case when oi.mealtime_type = 3 then
                           oi.order_id else null
                end) as afternoon_tea_order_count,
            sum(case when oi.mealtime_type = 3 then
                         oi.real_amount - oi.refund_amount else 0
                end) as afternoon_tea_consume_count,
            count(distinct case when oi.mealtime_type = 4 then
                                    oi.user_id else null
                end) as dinner_user_count,
            count(case when oi.mealtime_type = 4 then
                           oi.order_id else null
                end) as dinner_order_count,
            sum(case when oi.mealtime_type = 4 then
                         oi.real_amount - oi.refund_amount else 0
                end) as dinner_consume_count,
            count(distinct case when oi.mealtime_type = 5 then
                                    oi.user_id else null
                end) as midnight_snack_user_count,
            count(case when oi.mealtime_type = 5 then
                           oi.order_id else null
                end) as midnight_snack_order_count,
            sum(case when oi.mealtime_type = 5 then
                         oi.real_amount - oi.refund_amount else 0
                end) as midnight_snack_consume_count
        from
            order_info oi
                left join sys_user su on
                oi.user_id = su.user_id
                left join alloc_canteen ac on
                oi.canteen_id = ac.canteen_id
                left join alloc_stall ast on
                oi.stall_id = ast.stall_id
        where oi.pay_state = 3 and oi.order_state in (1, 2)
        and oi.pay_time <![CDATA[ >= ]]> #{param.startDateTime}
        and oi.pay_time <![CDATA[ <= ]]> #{param.endDateTime}
        <if test="param.deptIdList != null and param.deptIdList.size() > 0">
            and su.dept_id IN
            <foreach collection="param.deptIdList" item="deptId" separator="," open="(" close=")">
                #{deptId}
            </foreach>
        </if>
        group by
            oi.canteen_id,
            oi.stall_id
    </select>

    <select id="selectDeviceRevenue" resultType="com.bonus.canteen.core.report.domain.DeviceRevenueVO">
        select
            di.device_num,
            di.device_sn,
            di.device_name,
            count(distinct case when oi.mealtime_type = 1 then
                                    oi.user_id else null
                end) as breakfast_user_count,
            count(case when oi.mealtime_type = 1 then
                           oi.order_id else null
                end) as breakfast_order_count,
            sum(case when oi.mealtime_type = 1 then
                         oi.real_amount - oi.refund_amount else 0
                end) as breakfast_consume_count,
            count(distinct case when oi.mealtime_type = 2 then
                                    oi.user_id else null
                end) as lunch_user_count,
            count(case when oi.mealtime_type = 2 then
                           oi.order_id else null
                end) as lunch_order_count,
            sum(case when oi.mealtime_type = 2 then
                         oi.real_amount - oi.refund_amount else 0
                end) as lunch_consume_count,
            count(distinct case when oi.mealtime_type = 3 then
                                    oi.user_id else null
                end) as afternoon_tea_user_count,
            count(case when oi.mealtime_type = 3 then
                           oi.order_id else null
                end) as afternoon_tea_order_count,
            sum(case when oi.mealtime_type = 3 then
                         oi.real_amount - oi.refund_amount else 0
                end) as afternoon_tea_consume_count,
            count(distinct case when oi.mealtime_type = 4 then
                                    oi.user_id else null
                end) as dinner_user_count,
            count(case when oi.mealtime_type = 4 then
                           oi.order_id else null
                end) as dinner_order_count,
            sum(case when oi.mealtime_type = 4 then
                         oi.real_amount - oi.refund_amount else 0
                end) as dinner_consume_count,
            count(distinct case when oi.mealtime_type = 5 then
                                    oi.user_id else null
                end) as midnight_snack_user_count,
            count(case when oi.mealtime_type = 5 then
                           oi.order_id else null
                end) as midnight_snack_order_count,
            sum(case when oi.mealtime_type = 5 then
                         oi.real_amount - oi.refund_amount else 0
                end) as midnight_snack_consume_count
        from
            order_info oi
                left join sys_user su on
                oi.user_id = su.user_id
                left join device_info di on
                oi.device_sn = di.device_sn and oi.device_num = di.device_num
        where oi.source_type = 20 and oi.pay_state = 3 and oi.order_state in (1, 2)
        and oi.pay_time <![CDATA[ >= ]]> #{param.startDateTime}
        and oi.pay_time <![CDATA[ <= ]]> #{param.endDateTime}
        <if test="param.deptIdList != null and param.deptIdList.size() > 0">
            and su.dept_id IN
            <foreach collection="param.deptIdList" item="deptId" separator="," open="(" close=")">
                #{deptId}
            </foreach>
        </if>
        <if test="param.searchValue != null and param.searchValue != ''">
            and (
            di.device_num = #{param.searchValue}
            or di.device_name like concat('%', #{param.searchValue}, '%')
            )
        </if>
        group by
            oi.device_sn,
            oi.device_num
    </select>

    <select id="selectUserRevenue" resultType="com.bonus.canteen.core.report.domain.UserRevenueVO">
        select
            oi.user_id,
            su.nick_name,
            sd.dept_full_name,
            count(distinct case when oi.mealtime_type = 1 then
                                    oi.user_id else null
                end) as breakfast_user_count,
            count(case when oi.mealtime_type = 1 then
                           oi.order_id else null
                end) as breakfast_order_count,
            sum(case when oi.mealtime_type = 1 then
                         oi.real_amount - oi.refund_amount else 0
                end) as breakfast_consume_count,
            count(distinct case when oi.mealtime_type = 2 then
                                    oi.user_id else null
                end) as lunch_user_count,
            count(case when oi.mealtime_type = 2 then
                           oi.order_id else null
                end) as lunch_order_count,
            sum(case when oi.mealtime_type = 2 then
                         oi.real_amount - oi.refund_amount else 0
                end) as lunch_consume_count,
            count(distinct case when oi.mealtime_type = 3 then
                                    oi.user_id else null
                end) as afternoon_tea_user_count,
            count(case when oi.mealtime_type = 3 then
                           oi.order_id else null
                end) as afternoon_tea_order_count,
            sum(case when oi.mealtime_type = 3 then
                         oi.real_amount - oi.refund_amount else 0
                end) as afternoon_tea_consume_count,
            count(distinct case when oi.mealtime_type = 4 then
                                    oi.user_id else null
                end) as dinner_user_count,
            count(case when oi.mealtime_type = 4 then
                           oi.order_id else null
                end) as dinner_order_count,
            sum(case when oi.mealtime_type = 4 then
                         oi.real_amount - oi.refund_amount else 0
                end) as dinner_consume_count,
            count(distinct case when oi.mealtime_type = 5 then
                                    oi.user_id else null
                end) as midnight_snack_user_count,
            count(case when oi.mealtime_type = 5 then
                           oi.order_id else null
                end) as midnight_snack_order_count,
            sum(case when oi.mealtime_type = 5 then
                         oi.real_amount - oi.refund_amount else 0
                end) as midnight_snack_consume_count
        from
            order_info oi
                left join sys_user su on
                oi.user_id = su.user_id
                left join sys_dept sd on
                su.dept_id = sd.dept_id
        where oi.pay_state = 3 and oi.order_state in (1, 2)
        and oi.pay_time <![CDATA[ >= ]]> #{param.startDateTime}
        and oi.pay_time <![CDATA[ <= ]]> #{param.endDateTime}
        <if test="param.deptIdList != null and param.deptIdList.size() > 0">
            and su.dept_id IN
            <foreach collection="param.deptIdList" item="deptId" separator="," open="(" close=")">
                #{deptId}
            </foreach>
        </if>
        <if test="param.searchValue != null and param.searchValue != ''">
            and (
            su.nick_name like CONCAT('%',#{param.searchValue},'%')
            or su.phonenumber = #{encryptedSearchValue}
            or su.user_id like concat('%', #{param.searchValue}, '%')
            )
        </if>
        group by
            oi.user_id
    </select>

    <select id="selectGoodsRevenue" resultType="com.bonus.canteen.core.report.domain.GoodsRevenueVO">
        select
            od.goods_id,
            od.goods_name,
            ifnull(mrd.sale_price, 0) as sale_price,
            sum(case when oi.mealtime_type = 1 then
                         od.quantity else 0
                end) as breakfast_quantity_count,
            sum(case when oi.mealtime_type = 1 then
                         od.real_amount - od.refund_amount else 0
                end) as breakfast_consume_count,
            sum(case when oi.mealtime_type = 2 then
                         od.quantity else 0
                end) as lunch_quantity_count,
            sum(case when oi.mealtime_type = 2 then
                         od.real_amount - od.refund_amount else 0
                end) as lunch_consume_count,
            sum(case when oi.mealtime_type = 3 then
                         od.quantity else 0
                end) as afternoon_tea_quantity_count,
            sum(case when oi.mealtime_type = 3 then
                         od.real_amount - od.refund_amount else 0
                end) as afternoon_tea_consume_count,
            sum(case when oi.mealtime_type = 4 then
                         od.quantity else 0
                end) as dinner_quantity_count,
            sum(case when oi.mealtime_type = 4 then
                         od.real_amount - od.refund_amount else 0
                end) as dinner_consume_count,
            sum(case when oi.mealtime_type = 5 then
                         od.quantity else 0
                end) as midnight_snack_quantity_count,
            sum(case when oi.mealtime_type = 5 then
                         od.real_amount - od.refund_amount else 0
                end) as midnight_snack_consume_count,
            sum(case when oi.mealtime_type not in (1, 2, 3, 4, 5) then
                         od.quantity else 0
                end) as other_quantity_count,
            sum(case when oi.mealtime_type not in (1, 2, 3, 4, 5) then
                         od.real_amount - od.refund_amount else 0
                end) as other_consume_count
        from
            order_detail od
                left join order_info oi on
                oi.order_id = od.order_id
                left join sys_user su on
                oi.user_id = su.user_id
                left join menu_recipe_dishes mrd on
                        od.menu_detail_id = mrd.detail_id
                    and od.goods_id = mrd.dishes_id
        where
            oi.pay_state = 3
        and oi.order_state in (1, 2)
        and oi.pay_time <![CDATA[ >= ]]> #{param.startDateTime}
        and oi.pay_time <![CDATA[ <= ]]> #{param.endDateTime}
        <if test="param.deptIdList != null and param.deptIdList.size() > 0">
            and su.dept_id IN
            <foreach collection="param.deptIdList" item="deptId" separator="," open="(" close=")">
                #{deptId}
            </foreach>
        </if>
        <if test="param.orderDetailTypeList != null and param.orderDetailTypeList.size() > 0">
            and od.detail_type IN
            <foreach collection="param.orderDetailTypeList" item="detailType" separator="," open="(" close=")">
                #{detailType}
            </foreach>
        </if>
        group by
            od.goods_id
    </select>

</mapper>