<?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.cyksj.mapper.manage.coupon.CouponUserMapper">

    <select id="getAvailableCouponList" resultType="com.cyksj.model.views.CouponUserView">
        select * from (select distinct cu.id,
        cp.id as coupon_id,
        cp.name,
        cp.goods_type,
        cp.type,
        cp.goods_sku_ids,
        cp.discount,
        cp.reduce_condition,
        cp.reduce_money,
        cp.is_valid_time,
        cu.valid_start_time,
        cu.valid_end_time,
        cp.valid_days,
        cp.valid_hours,
        cp.use_scope,
        cu.created_time,
        cu.status as couponUserStatus,
        if(type = 'discount',${skuMoney} * (1-cp.discount),reduce_money) as couponMoney,
        if(ck.id is null, 0, 1) as 'isAvailable',
        if(ca.id is not null and ca.expiry_status = 0,false,true) flag,
        (case
        when cu.valid_start_time > now() then 1
        when cu.valid_end_time &lt; now() then 2
        when cu.status = 'unused' then 0
        end)                 as orderby
        from `coupon_user` cu
        left join `coupon` cp on cp.id = cu.coupon_id
        left join `coupon_active` ca on ca.id = cu.coupon_active_id
        left join `coupon_sku` ck on ck.coupon_id = cp.id
        <if test="goodsId != null">
            and ck.goods_id = #{goodsId}
        </if>
        <if test="goodsId == null">
            and ck.sku_id = #{skuId}
        </if>
        <choose>
            <when test="isRenew != null and isRenew">
                and cp.use_scope != 'orders'
            </when>
            <otherwise>
                and cp.use_scope != 'renew'
            </otherwise>
        </choose>
        where cu.user_id = #{userId}
        and cu.channel != 'exCode'
        and cu.valid_end_time > now()
        <if test="couponId == null">
            order by isAvailable desc,orderby,couponMoney desc
        </if>
        <if test="couponId != null">
            order by case when cp.id = #{couponId} then 2 else isAvailable end desc,orderby,couponMoney desc
        </if>)s where flag = 1 and couponUserStatus != 'used' and orderby != 2
    </select>

    <select id="countAvailableCouponList" resultType="com.cyksj.model.views.CouponUserView">
        select distinct id,reduce_condition,`type`
        from (select cu.id,ca.expiry_status as flag,
                     cp.reduce_condition,
                     cp.type
        from `coupon_user` cu
        left join `coupon` cp on cp.id = cu.coupon_id
        left join `coupon_sku` ck on ck.coupon_id = cp.id
        left join `coupon_active` ca on ca.id = cu.coupon_active_id
        where
        <if test="goodsId != null">
            ck.goods_id = #{goodsId}
        </if>
        <if test="goodsId == null">
            ck.sku_id = #{skuId}
        </if>
        and cu.user_id = #{userId}
        and cu.status = 'unused'
        and cu.channel != 'exCode'
        and cu.valid_start_time &lt; now()
        and cu.valid_end_time > now()
        <choose>
            <when test="isRenew != null and isRenew">
                and cp.use_scope != 'orders'
            </when>
            <otherwise>
                and cp.use_scope != 'renew'
            </otherwise>
        </choose>
        )s where flag != 0 or flag is null
    </select>

    <select id="couponCenterList" resultType="com.cyksj.model.views.CouponActiveView">
        select *
        from (select ca.id,
                     c.id                                                                     as coupon_id,
                     c.name,
                     c.goods_type,
                     c.type,
                     c.reduce_condition,
                     c.reduce_money,
                     c.discount,
                     c.scope,
                     c.goods_sku_ids,
                     c.is_valid_time,
                     c.valid_start_time,
                     c.valid_end_time,
                     c.valid_days,
                     c.valid_hours,
                     ca.num,
                     ca.`status`,
                     ca.expiry_status,
                     ca.remain_num,
                     (case
                          when ca.remain_num &lt;= 0 then 'over'
                          when cu.id is null then 'collecting'
                          when cu.id is not null and cu.status != 'unused' then 'used'
                          when cu.id is not null and cu.status = 'unused' then 'received'
                         end)                                                                 as couponStatus,
                     (case
                          when remain_num &lt;= 0 then 2
                          when cu.id is null then 0
                          when cu.id is not null and cu.status = 'unused' then 1
                         end)                                                                 as `order`,
                     if(c.is_valid_time is true and c.valid_end_time &lt; now(), false, true) as flag
              from coupon_active ca
                       left join coupon c
                                 on c.id = ca.coupon_id
                       left join coupon_user cu on cu.coupon_id = c.id and cu.user_id = #{userId}
              where ca.deleted is true
                and c.deleted is true
                and cu.id is null
                and ca.expiry_status != 0
        and ca.`status` != 0
             ) s
        where couponStatus in ('over', 'collecting')
          and flag = 1
        order by `order`
    </select>

    <select id="couponPersonalList" resultType="com.cyksj.model.views.CouponUserView">
        select s.* from (select cu.id,
               cu.channel,
               cu.user_id,
               c.id                     as couponId,
               ca.id                    as couponActiveId,
               c.name,
               c.goods_type,
               c.type,
               c.reduce_condition,
               c.reduce_money,
               c.discount,
               c.use_scope,
               c.goods_sku_ids,
               c.is_valid_time,
               cu.valid_start_time,
               c.valid_days,
               c.valid_hours,
               cu.valid_end_time,
               (case
                    when cu.status = 'used' then 'used'
                    when cu.valid_end_time &lt; now() then 'expired'
                    when ca.id is not null and ca.expiry_status = 0 then 'invalid'
                    when cu.valid_start_time > now() then 'notEffective'
                    else cu.status end) as couponUserStatus,
               (case
                    when cu.status = 'used' then 4
                    when cu.valid_end_time &lt; now() then 2
                    when ca.id is not null and ca.expiry_status = 0 then 3
                    when cu.valid_start_time > now() then 1
                    when cu.status = 'unused' then 0
                   end)                 as orderby
        from `coupon_user` cu
                 left join `coupon` c on c.id = cu.coupon_id
                 left join `coupon_active` ca on ca.id = cu.coupon_active_id
        where cu.user_id = #{userId}
        <if test="couponId !=null">
            and cu.coupon_id = #{couponId}
        </if>
        and cu.channel != 'exCode'
        order by `orderby`)s where s.couponUserStatus != 'expired' and s.couponUserStatus != 'invalid'
    </select>

    <select id="getNewUserWelfareCouponsByUserId" resultType="com.cyksj.model.views.CouponUserView">
        select cu.*,
               c.name,
               c.goods_type,
               c.type,
               c.reduce_condition,
               c.reduce_money,
               c.discount,
               c.use_scope,
               c.goods_sku_ids,
               cu.valid_start_time,
               cu.valid_end_time,
               unix_timestamp(cu.valid_end_time) * 1000 as validEndTimestamp
        from (select coupon_id,
                     valid_start_time,
                     valid_end_time,
                     status as couponUserStatus
              from `coupon_user`
              where coupon_id = #{couponId}
                and user_id = #{userId}
                 and status = 'unused' limit 1) cu
                 inner join coupon c on c.id = cu.coupon_id
    </select>

    <select id="getCouponByCouponUserId" resultType="com.cyksj.model.entity.CouponUser">
        select *
        from coupon_user
        where id = #{couponUserId} limit 1
    </select>

    <select id="getCouponDetailById" resultType="com.cyksj.model.views.CouponUserView">
        select cu.*,
               c.name,
               c.goods_type,
               c.type,
               c.reduce_condition,
               c.reduce_money,
               c.discount,
               c.use_scope,
               c.goods_sku_ids,
               cu.valid_start_time,
               cu.valid_end_time,
               unix_timestamp(cu.valid_end_time) * 1000 as validEndTimestamp
        from (select coupon_id,
                     valid_start_time,
                     valid_end_time,
                     status as couponUserStatus
              from `coupon_user`
              where user_id = #{userId}
                and coupon_id = #{couponId} limit 1) cu
                 inner join coupon c on c.id = cu.coupon_id
    </select>

    <select id="selectCouponUserNumData" resultType="java.util.Map">
        select count(if(status = 'used', 1, NULL)) usedNum, count(*) receiptNum
        from coupon_user
        where coupon_id = #{couponId}
    </select>

    <select id="couponPersonalByCouponIds" resultType="com.cyksj.model.views.CouponUserView">
        select cu.id,
        cu.channel,
        cu.user_id,
        c.id as couponId,
        ca.id as couponActiveId,
        c.name,
        c.goods_type,
        c.type,
        c.reduce_condition,
        c.reduce_money,
        c.discount,
        c.use_scope,
        c.goods_sku_ids,
        c.is_valid_time,
        cu.valid_start_time,
        c.valid_days,
        c.valid_hours,
        cu.valid_end_time,
        (case
        when cu.status = 'used' then 'used'
        when cu.valid_end_time &lt; now() then 'expired'
        when ca.id is not null and ca.expiry_status = 0 then 'invalid'
        when cu.valid_start_time > now() then 'notEffective'
        else cu.status end) as couponUserStatus,
        (case
        when cu.status = 'used' then 4
        when cu.valid_end_time &lt; now() then 2
        when ca.id is not null and ca.expiry_status = 0 then 3
        when cu.valid_start_time > now() then 1
        when cu.status = 'unused' then 0
        end) as orderby
        from `coupon_user` cu
        left join `coupon` c on c.id = cu.coupon_id
        left join `coupon_active` ca on ca.id = cu.coupon_active_id
        where cu.user_id in
        <foreach collection="userIds" item="userId" open="(" separator="," close=")">
            #{userId}
        </foreach>
        and cu.coupon_id in
        <foreach collection="couponIds" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
        and cu.channel != 'exCode'
        order by `orderby`
    </select>

    <select id="selectUserCouponByGidAndPrice" resultType="com.cyksj.model.entity.Coupon">
        select c.id,
               c.discount,
               c.reduce_money,
               cu.valid_start_time,
               cu.valid_end_time,
               if(type = 'discount', sku.price * (1 - c.discount), c.reduce_money) as couponMoney
        from (select * from coupon_user where user_id = #{userId} and status = 'unused' and valid_start_time &lt; now() and valid_end_time > now()) cu
                 inner join coupon c on c.id = cu.coupon_id
                 inner join coupon_sku cs on cs.coupon_id = c.id and cs.goods_id = #{goodsId}
                 inner join goods_don_sku sku on sku.id = cs.sku_id and sku.status is true and sku.price = #{price}
        order by couponMoney desc limit 1
    </select>

    <select id="selectUserCouponBySkuId" resultType="com.cyksj.model.entity.Coupon">
        select c.id,
               c.discount,
               c.reduce_money,
               cu.valid_start_time,
               cu.valid_end_time,
               if(type = 'discount', sku.price * (1 - c.discount), c.reduce_money) as couponMoney
        from (select * from coupon_user where user_id = #{userId} and status = 'unused' and valid_start_time &lt; now() and valid_end_time > now()) cu
                 inner join coupon c on c.id = cu.coupon_id
                 inner join coupon_sku cs on cs.coupon_id = c.id and cs.sku_id = #{skuId}
                 inner join goods_don_sku sku on sku.id = cs.sku_id and sku.status is true
        order by couponMoney desc limit 1
    </select>
</mapper>