<?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.cordys.crm.contract.mapper.ExtContractPaymentRecordMapper">
    <select id="list" resultType="cn.cordys.crm.contract.dto.response.ContractPaymentRecordResponse">
        select cpr.id, cpr.owner, cpr.no, cpr.name, cpr.contract_id, cpr.payment_plan_id,
               cpr.record_amount, cpr.record_end_time, cpr.create_time, cpr.update_time,
               cpr.create_user, cpr.update_user, cpr.organization_id, ifnull(c.name, '') as contractName
        from contract_payment_record cpr left join contract c on c.id = cpr.contract_id

        <include refid="fieldConditionJoin">
            <property name="conditions" value="request.filters"/>
            <property name="tablePrefix" value="filter"/>
        </include>
        <include refid="fieldConditionJoin">
            <property name="conditions" value="request.combineSearch.conditions"/>
            <property name="tablePrefix" value="combine"/>
        </include>
        <include refid="fieldConditionJoin">
            <property name="conditions" value="request.viewCombineSearch.conditions"/>
            <property name="tablePrefix" value="viewCombine"/>
        </include>
        <include refid="fieldSortJoin">
            <property name="sort" value="request.sort"/>
        </include>

        <if test="dataPermission != null and dataPermission.deptIds.size() > 0">
            join sys_organization_user sou on cpr.owner = sou.user_id
            and (
            sou.department_id in
            <foreach collection="dataPermission.deptIds" item="deptId" open="(" close=")" separator=",">
                #{deptId}
            </foreach>
            <if test="dataPermission.viewId == 'ALL'">
                or sou.user_id = #{currentUser}
            </if>
            )
        </if>

        where cpr.organization_id = #{currentOrg}

        <if test="dataPermission != null and dataPermission.self">
            and cpr.owner = #{currentUser}
        </if>

        <if test="request.contractId != null and request.contractId != ''">
            and cpr.contract_id = #{request.contractId}
        </if>

        <if test="request.customerId != null and request.customerId != ''">
            and c.customer_id = #{request.customerId}
        </if>

        <if test="request.keyword != null and request.keyword != ''">
            and cpr.name like concat('%', #{request.keyword},'%')
        </if>

        <include refid="filters">
            <property name="filters" value="request.filters"/>
        </include>

        <include refid="combine">
            <property name="combineSearch" value="request.combineSearch"/>
        </include>
        <include refid="viewCombine">
            <property name="combineSearch" value="request.viewCombineSearch"/>
        </include>

        <include refid="sort">
            <property name="sort" value="request.sort"/>
        </include>
    </select>

    <select id="getListByIds" resultType="cn.cordys.crm.contract.dto.response.ContractPaymentRecordResponse">
        select cpr.id, cpr.owner, cpr.no, cpr.name, cpr.contract_id, cpr.payment_plan_id,
            cpr.record_amount, cpr.record_end_time, cpr.create_time, cpr.update_time,
            cpr.create_user, cpr.update_user, cpr.organization_id, c.name as contractName
        from contract_payment_record cpr
        join contract c on c.id = cpr.contract_id

        <if test="dataPermission != null and dataPermission.deptIds.size() > 0">
            join sys_organization_user sou on cpr.owner = sou.user_id
            and (
            sou.department_id in
            <foreach collection="dataPermission.deptIds" item="deptId" open="(" close=")" separator=",">
                #{deptId}
            </foreach>
            )
        </if>

        where cpr.organization_id = #{currentOrg} and cpr.id in
        <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>

        <if test="dataPermission != null and dataPermission.self">
            and cpr.owner = #{currentUser}
        </if>
    </select>

    <select id="sumCustomerRecordAmount" resultType="cn.cordys.crm.contract.dto.response.CustomerPaymentRecordStatisticResponse">
        select
            ifnull(sum(c.amount), 0) as totalAmount,
            ifnull(sum(cpr_sum.receivedAmount), 0) as receivedAmount,
            ifnull((sum(c.amount) - sum(cpr_sum.receivedAmount)), 0) as pendingAmount
        from contract c
        left join (
            select cpr.contract_id, sum(cpr.record_amount) as receivedAmount
            from contract_payment_record cpr
            <if test="dataPermission != null and dataPermission.deptIds.size() > 0">
                join sys_organization_user sou on cpr.owner = sou.user_id
                and (
                sou.department_id in
                <foreach collection="dataPermission.deptIds" item="deptId" open="(" close=")" separator=",">
                    #{deptId}
                </foreach>
                )
            </if>
            where cpr.organization_id = #{orgId}
            <if test="dataPermission != null and dataPermission.self">
                and cpr.owner = #{userId}
            </if>
            group by contract_id
        ) cpr_sum on c.id = cpr_sum.contract_id

        where c.organization_id = #{orgId}
        and c.customer_id = #{customerId}
    </select>

    <sql id="sort">
        <choose>
            <when test="${sort} != null and ${sort}.valid()">
                <bind name="sortType" value="${sort}.type"/>
                <bind name="sortName" value="${sort}.name"/>
                order by
                <choose>
                    <when test="${sort}.name in
                        {'name', 'no', 'owner', 'payment_plan_id', 'contract_id', 'record_amount', 'record_end_time', 'create_time', 'update_time', 'create_user', 'update_user'}">
                        cpr.${sortName} ${sortType}, cpr.id ASC
                    </when>
                    <when test="${sort}.name == 'department_id'">
                        sou_sort.${sortName} ${sortType}, cpr.id ASC
                    </when>
                    <otherwise>
                        CASE
                        WHEN module_table.type = 'INPUT_NUMBER'
                        THEN sort_table.field_value + 0
                        END ${sortType},
                        sort_table.field_value ${sortType},
                        cpr.id ASC
                    </otherwise>
                </choose>
            </when>
            <otherwise>
                order by cpr.create_time desc, cpr.id asc
            </otherwise>
        </choose>
    </sql>

    <sql id="fieldConditionJoin">
        <if test="${conditions} != null and ${conditions}.size() > 0">
            <foreach collection="${conditions}" item="condition" index="i">
                <if test="condition.name not in
                {'name', 'no', 'owner', 'paymentPlanId', 'contractId', 'createTime', 'updateTime', 'recordAmount', 'recordEndTime', 'createUser', 'updateUser', 'departmentId'}">
                    <if test="condition.multipleValue">
                        left join contract_payment_record_field_blob ${tablePrefix}_${i}
                        on cpr.id = ${tablePrefix}_${i}.resource_id and ${tablePrefix}_${i}.field_id = #{condition.name}
                    </if>
                    <if test="!condition.multipleValue">
                        left join contract_payment_record_field ${tablePrefix}_${i}
                        on cpr.id = ${tablePrefix}_${i}.resource_id and ${tablePrefix}_${i}.field_id = #{condition.name}
                    </if>
                </if>
                <if test="condition.name == 'departmentId'">
                    left join sys_organization_user ${tablePrefix}_${i}
                    on ${tablePrefix}_${i}.user_id = cpr.owner
                </if>
            </foreach>
        </if>
    </sql>

    <sql id="fieldSortJoin">
        <if test="${sort} != null and ${sort}.valid()">
            <bind name="sortName" value="${sort}.name"/>
            <choose>
                <when test="${sort}.name == 'department_id'">
                    left join sys_organization_user sou_sort on cpr.owner = sou_sort.user_id
                </when>
                <when test="${sort}.name not in
                        {'name', 'no', 'owner', 'create_time', 'update_time', 'contract_id', 'payment_plan_id', 'create_user', 'update_user', 'record_amount', 'record_end_time'}">
                    left join contract_payment_record_field sort_table
                    on cpr.id = sort_table.resource_id and sort_table.field_id = #{sortName}
                    left join sys_module_field module_table on sort_table.field_id = module_table.id
                </when>
            </choose>
        </if>
    </sql>

    <sql id="filters">
        <if test="${filters} != null and ${filters}.size() > 0">
            <trim prefix="and">
                <foreach collection="${filters}" item="condition" open="(" close=")" index="i" separator="and">
                    <include refid="condition">
                        <property name="condition" value="condition"/>
                        <property name="fieldTable" value="filter_${i}.field_value"/>
                    </include>
                </foreach>
            </trim>
        </if>
    </sql>

    <sql id="combine">
        <if test="${combineSearch} != null and ${combineSearch}.conditions != null and ${combineSearch}.conditions.size() > 0">
            <trim prefix="and">
                <trim prefix="(" suffix=")" suffixOverrides="and|or">
                    <foreach collection="${combineSearch}.conditions" index="i" item="condition">
                        <include refid="condition">
                            <property name="condition" value="condition"/>
                            <property name="fieldTable" value="combine_${i}.field_value"/>
                            <property name="table" value="combine_${i}"/>
                        </include>
                        <include refid="cn.cordys.common.mapper.CommonMapper.searchMode">
                            <property name="searchMode" value="${combineSearch}.searchMode"/>
                        </include>
                    </foreach>
                </trim>
            </trim>
        </if>
    </sql>

    <sql id="viewCombine">
        <if test="${combineSearch} != null and ${combineSearch}.conditions != null and ${combineSearch}.conditions.size() > 0">
            <trim prefix="and">
                <trim prefix="(" suffix=")" suffixOverrides="and|or">
                    <foreach collection="${combineSearch}.conditions" index="i" item="condition">
                        <include refid="condition">
                            <property name="condition" value="condition"/>
                            <property name="fieldTable" value="viewCombine_${i}.field_value"/>
                            <property name="table" value="viewCombine_${i}"/>
                        </include>
                        <include refid="cn.cordys.common.mapper.CommonMapper.searchMode">
                            <property name="searchMode" value="${combineSearch}.searchMode"/>
                        </include>
                    </foreach>
                </trim>
            </trim>
        </if>
    </sql>

    <sql id="condition">
        <choose>
            <when test="condition.name == 'name'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.name"/>
                </include>
            </when>
            <when test="condition.name == 'no'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.no"/>
                </include>
            </when>
            <when test="condition.name == 'owner'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.owner"/>
                </include>
            </when>
            <when test="condition.name == 'contractId'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.contract_id"/>
                </include>
            </when>
            <when test="condition.name == 'paymentPlanId'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.payment_plan_id"/>
                </include>
            </when>
            <when test="condition.name == 'recordAmount'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.record_amount"/>
                </include>
            </when>
            <when test="condition.name == 'recordEndTime'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.record_end_time"/>
                </include>
            </when>
            <when test="condition.name == 'createTime'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.create_time"/>
                </include>
            </when>
            <when test="condition.name == 'updateTime'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.update_time"/>
                </include>
            </when>
            <when test="condition.name == 'createUser'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.create_user"/>
                </include>
            </when>
            <when test="condition.name == 'updateUser'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="cpr.update_user"/>
                </include>
            </when>
            <when test="condition.name == 'departmentId'">
                <include refid="cn.cordys.common.mapper.CommonMapper.condition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="${table}.department_id"/>
                </include>
            </when>
            <otherwise>
                <include refid="cn.cordys.common.mapper.CommonMapper.moduleFieldCondition">
                    <property name="condition" value="condition"/>
                    <property name="column" value="${fieldTable}"/>
                </include>
            </otherwise>
        </choose>
    </sql>
</mapper>