<?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="taxInvoice">

  <select id="getTaxInvoiceList" parameterType="map" resultType="map">
    SELECT
      ID, COMPANY_CODE, INVOICE_NUMBER, INVOICE_TYPE, INVOICE_STATUS,
      SUPPLIER_BUSINESS_NO, SUPPLIER_NAME, SUPPLIER_CEO_NAME, SUPPLIER_ADDRESS,
      SUPPLIER_BUSINESS_TYPE, SUPPLIER_BUSINESS_ITEM,
      BUYER_BUSINESS_NO, BUYER_NAME, BUYER_CEO_NAME, BUYER_ADDRESS, BUYER_EMAIL,
      SUPPLY_AMOUNT, TAX_AMOUNT, TOTAL_AMOUNT, INVOICE_DATE, ISSUE_DATE,
      REMARKS, ORDER_ID, CUSTOMER_ID, COST_TYPE, WRITER,
      CREATED_DATE, UPDATED_DATE
    FROM TAX_INVOICE
    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    <if test="invoice_type != null and invoice_type != ''">
      AND INVOICE_TYPE = #{invoice_type}
    </if>
    <if test="invoice_status != null and invoice_status != ''">
      AND INVOICE_STATUS = #{invoice_status}
    </if>
    <if test="start_date != null and start_date != ''">
      AND INVOICE_DATE &gt;= #{start_date}
    </if>
    <if test="end_date != null and end_date != ''">
      AND INVOICE_DATE &lt;= #{end_date}
    </if>
    <if test="search != null and search != ''">
      AND (INVOICE_NUMBER ILIKE '%' || #{search} || '%'
        OR BUYER_NAME ILIKE '%' || #{search} || '%'
        OR SUPPLIER_NAME ILIKE '%' || #{search} || '%')
    </if>
    <if test="buyer_name != null and buyer_name != ''">
      AND BUYER_NAME ILIKE '%' || #{buyer_name} || '%'
    </if>
    <if test="cost_type != null and cost_type != ''">
      AND COST_TYPE = #{cost_type}
    </if>
    ORDER BY CREATED_DATE DESC
    <include refid="common.pagination"/>
  </select>

  <select id="getTaxInvoiceListCnt" parameterType="map" resultType="int">
    SELECT COUNT(*)
    FROM TAX_INVOICE
    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    <if test="invoice_type != null and invoice_type != ''">
      AND INVOICE_TYPE = #{invoice_type}
    </if>
    <if test="invoice_status != null and invoice_status != ''">
      AND INVOICE_STATUS = #{invoice_status}
    </if>
    <if test="start_date != null and start_date != ''">
      AND INVOICE_DATE &gt;= #{start_date}
    </if>
    <if test="end_date != null and end_date != ''">
      AND INVOICE_DATE &lt;= #{end_date}
    </if>
    <if test="search != null and search != ''">
      AND (INVOICE_NUMBER ILIKE '%' || #{search} || '%'
        OR BUYER_NAME ILIKE '%' || #{search} || '%'
        OR SUPPLIER_NAME ILIKE '%' || #{search} || '%')
    </if>
    <if test="buyer_name != null and buyer_name != ''">
      AND BUYER_NAME ILIKE '%' || #{buyer_name} || '%'
    </if>
    <if test="cost_type != null and cost_type != ''">
      AND COST_TYPE = #{cost_type}
    </if>
  </select>

  <select id="getTaxInvoiceInfo" parameterType="map" resultType="map">
    SELECT
      ID, COMPANY_CODE, INVOICE_NUMBER, INVOICE_TYPE, INVOICE_STATUS,
      SUPPLIER_BUSINESS_NO, SUPPLIER_NAME, SUPPLIER_CEO_NAME, SUPPLIER_ADDRESS,
      SUPPLIER_BUSINESS_TYPE, SUPPLIER_BUSINESS_ITEM,
      BUYER_BUSINESS_NO, BUYER_NAME, BUYER_CEO_NAME, BUYER_ADDRESS, BUYER_EMAIL,
      SUPPLY_AMOUNT, TAX_AMOUNT, TOTAL_AMOUNT, INVOICE_DATE, ISSUE_DATE,
      REMARKS, ORDER_ID, CUSTOMER_ID, COST_TYPE, WRITER,
      CREATED_DATE, UPDATED_DATE
    FROM TAX_INVOICE
    WHERE ID = #{id}
    <include refid="common.companyCodeFilter"/>
  </select>

  <select id="getLastInvoiceNumber" parameterType="map" resultType="String">
    SELECT INVOICE_NUMBER
    FROM TAX_INVOICE
    WHERE (COMPANY_CODE = #{company_code} OR COMPANY_CODE = '*')
    AND INVOICE_NUMBER LIKE #{prefix}
    ORDER BY INVOICE_NUMBER DESC
    LIMIT 1
  </select>

  <select id="getTaxInvoiceItems" parameterType="map" resultType="map">
    SELECT
      ID, TAX_INVOICE_ID, COMPANY_CODE, ITEM_SEQ,
      ITEM_DATE, ITEM_NAME, ITEM_SPEC, QUANTITY, UNIT_PRICE,
      SUPPLY_AMOUNT, TAX_AMOUNT, REMARKS
    FROM TAX_INVOICE_ITEM
    WHERE TAX_INVOICE_ID = #{id}
    AND (COMPANY_CODE = #{company_code} OR COMPANY_CODE = '*')
    ORDER BY ITEM_SEQ
  </select>

  <insert id="insertTaxInvoice" parameterType="map" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO TAX_INVOICE (
      COMPANY_CODE, INVOICE_NUMBER, INVOICE_TYPE, INVOICE_STATUS,
      SUPPLIER_BUSINESS_NO, SUPPLIER_NAME, SUPPLIER_CEO_NAME, SUPPLIER_ADDRESS,
      SUPPLIER_BUSINESS_TYPE, SUPPLIER_BUSINESS_ITEM,
      BUYER_BUSINESS_NO, BUYER_NAME, BUYER_CEO_NAME, BUYER_ADDRESS, BUYER_EMAIL,
      SUPPLY_AMOUNT, TAX_AMOUNT, TOTAL_AMOUNT, INVOICE_DATE,
      REMARKS, ORDER_ID, CUSTOMER_ID, COST_TYPE, WRITER,
      CREATED_DATE, UPDATED_DATE
    ) VALUES (
      #{company_code}, #{invoice_number}, #{invoice_type}, 'draft',
      #{supplier_business_no}, #{supplier_name}, #{supplier_ceo_name}, #{supplier_address},
      #{supplier_business_type}, #{supplier_business_item},
      #{buyer_business_no}, #{buyer_name}, #{buyer_ceo_name}, #{buyer_address}, #{buyer_email},
      #{supply_amount}, #{tax_amount}, #{total_amount}, #{invoice_date},
      #{remarks}, #{order_id}, #{customer_id}, #{cost_type}, #{writer},
      NOW(), NOW()
    )
  </insert>

  <insert id="insertTaxInvoiceItem" parameterType="map" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO TAX_INVOICE_ITEM (
      TAX_INVOICE_ID, COMPANY_CODE, ITEM_SEQ,
      ITEM_DATE, ITEM_NAME, ITEM_SPEC, QUANTITY, UNIT_PRICE,
      SUPPLY_AMOUNT, TAX_AMOUNT, REMARKS
    ) VALUES (
      #{tax_invoice_id}, #{company_code}, #{item_seq},
      #{item_date}, #{item_name}, #{item_spec}, #{quantity}, #{unit_price},
      #{supply_amount}, #{tax_amount}, #{remarks}
    )
  </insert>

  <update id="updateTaxInvoice" parameterType="map">
    UPDATE TAX_INVOICE
    <set>
      <if test="supplier_business_no != null">
        SUPPLIER_BUSINESS_NO = #{supplier_business_no},
      </if>
      <if test="supplier_name != null">
        SUPPLIER_NAME = #{supplier_name},
      </if>
      <if test="supplier_ceo_name != null">
        SUPPLIER_CEO_NAME = #{supplier_ceo_name},
      </if>
      <if test="supplier_address != null">
        SUPPLIER_ADDRESS = #{supplier_address},
      </if>
      <if test="supplier_business_type != null">
        SUPPLIER_BUSINESS_TYPE = #{supplier_business_type},
      </if>
      <if test="supplier_business_item != null">
        SUPPLIER_BUSINESS_ITEM = #{supplier_business_item},
      </if>
      <if test="buyer_business_no != null">
        BUYER_BUSINESS_NO = #{buyer_business_no},
      </if>
      <if test="buyer_name != null">
        BUYER_NAME = #{buyer_name},
      </if>
      <if test="buyer_ceo_name != null">
        BUYER_CEO_NAME = #{buyer_ceo_name},
      </if>
      <if test="buyer_address != null">
        BUYER_ADDRESS = #{buyer_address},
      </if>
      <if test="buyer_email != null">
        BUYER_EMAIL = #{buyer_email},
      </if>
      <if test="supply_amount != null">
        SUPPLY_AMOUNT = #{supply_amount},
      </if>
      <if test="tax_amount != null">
        TAX_AMOUNT = #{tax_amount},
      </if>
      <if test="total_amount != null">
        TOTAL_AMOUNT = #{total_amount},
      </if>
      <if test="invoice_date != null">
        INVOICE_DATE = #{invoice_date},
      </if>
      <if test="remarks != null">
        REMARKS = #{remarks},
      </if>
      <if test="order_id != null">
        ORDER_ID = #{order_id},
      </if>
      <if test="customer_id != null">
        CUSTOMER_ID = #{customer_id},
      </if>
      <if test="cost_type != null">
        COST_TYPE = #{cost_type},
      </if>
      UPDATED_DATE = NOW()
    </set>
    WHERE ID = #{id}
    <include refid="common.companyCodeFilter"/>
  </update>

  <update id="issueTaxInvoice" parameterType="map">
    UPDATE TAX_INVOICE
    SET
      INVOICE_STATUS = 'issued',
      ISSUE_DATE = NOW(),
      UPDATED_DATE = NOW()
    WHERE ID = #{id}
    AND INVOICE_STATUS = 'draft'
    <include refid="common.companyCodeFilter"/>
  </update>

  <update id="cancelTaxInvoice" parameterType="map">
    UPDATE TAX_INVOICE
    SET
      INVOICE_STATUS = 'cancelled',
      <if test="cancel_reason != null and cancel_reason != ''">
      REMARKS = #{cancel_reason},
      </if>
      UPDATED_DATE = NOW()
    WHERE ID = #{id}
    AND INVOICE_STATUS IN ('draft', 'issued')
    <include refid="common.companyCodeFilter"/>
  </update>

  <delete id="deleteTaxInvoice" parameterType="map">
    DELETE FROM TAX_INVOICE
    WHERE ID = #{id}
    <include refid="common.companyCodeFilter"/>
  </delete>

  <delete id="deleteTaxInvoiceItemsByInvoiceId" parameterType="map">
    DELETE FROM TAX_INVOICE_ITEM
    WHERE TAX_INVOICE_ID = #{id}
    AND (COMPANY_CODE = #{company_code} OR COMPANY_CODE = '*')
  </delete>

  <select id="getMonthlyStats" parameterType="map" resultType="map">
    SELECT
      INVOICE_TYPE,
      COUNT(*) AS COUNT,
      COALESCE(SUM(SUPPLY_AMOUNT), 0) AS SUPPLY_AMOUNT,
      COALESCE(SUM(TAX_AMOUNT), 0) AS TAX_AMOUNT,
      COALESCE(SUM(TOTAL_AMOUNT), 0) AS TOTAL_AMOUNT
    FROM TAX_INVOICE
    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    AND INVOICE_DATE &gt;= #{start_date}
    AND INVOICE_DATE &lt;= #{end_date}
    AND INVOICE_STATUS != 'cancelled'
    GROUP BY INVOICE_TYPE
  </select>

  <select id="getCostTypeStats" parameterType="map" resultType="map">
    SELECT
      COST_TYPE,
      COUNT(*) AS COUNT,
      COALESCE(SUM(SUPPLY_AMOUNT), 0) AS SUPPLY_AMOUNT,
      COALESCE(SUM(TAX_AMOUNT), 0) AS TAX_AMOUNT,
      COALESCE(SUM(TOTAL_AMOUNT), 0) AS TOTAL_AMOUNT
    FROM TAX_INVOICE
    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    AND INVOICE_STATUS != 'cancelled'
    <if test="start_date != null">
      AND INVOICE_DATE &gt;= #{start_date}
    </if>
    <if test="end_date != null">
      AND INVOICE_DATE &lt;= #{end_date}
    </if>
    <if test="start_date == null and year != null">
      AND EXTRACT(YEAR FROM INVOICE_DATE)::INTEGER = #{year}
    </if>
    GROUP BY COST_TYPE
    ORDER BY TOTAL_AMOUNT DESC
  </select>

  <select id="getCostTypeStatsByMonth" parameterType="map" resultType="map">
    SELECT
      TO_CHAR(INVOICE_DATE, 'YYYY-MM') AS YEAR_MONTH,
      COST_TYPE,
      COUNT(*) AS COUNT,
      COALESCE(SUM(TOTAL_AMOUNT), 0) AS TOTAL_AMOUNT
    FROM TAX_INVOICE
    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    AND INVOICE_STATUS != 'cancelled'
    <if test="start_date != null">
      AND INVOICE_DATE &gt;= #{start_date}
    </if>
    <if test="end_date != null">
      AND INVOICE_DATE &lt;= #{end_date}
    </if>
    <if test="start_date == null and year != null">
      AND EXTRACT(YEAR FROM INVOICE_DATE)::INTEGER = #{year}
    </if>
    GROUP BY TO_CHAR(INVOICE_DATE, 'YYYY-MM'), COST_TYPE
    ORDER BY YEAR_MONTH DESC, COST_TYPE
  </select>

  <select id="getCostTypeStatsSummary" parameterType="map" resultType="map">
    SELECT
      COUNT(*) AS TOTAL_COUNT,
      COALESCE(SUM(TOTAL_AMOUNT), 0) AS TOTAL_AMOUNT,
      COALESCE(SUM(CASE WHEN COST_TYPE = 'purchase' THEN TOTAL_AMOUNT ELSE 0 END), 0) AS PURCHASE_AMOUNT,
      COALESCE(SUM(CASE WHEN COST_TYPE = 'installation' THEN TOTAL_AMOUNT ELSE 0 END), 0) AS INSTALLATION_AMOUNT,
      COALESCE(SUM(CASE WHEN COST_TYPE = 'repair' THEN TOTAL_AMOUNT ELSE 0 END), 0) AS REPAIR_AMOUNT,
      COALESCE(SUM(CASE WHEN COST_TYPE = 'maintenance' THEN TOTAL_AMOUNT ELSE 0 END), 0) AS MAINTENANCE_AMOUNT,
      COALESCE(SUM(CASE WHEN COST_TYPE = 'disposal' THEN TOTAL_AMOUNT ELSE 0 END), 0) AS DISPOSAL_AMOUNT,
      COALESCE(SUM(CASE WHEN COST_TYPE = 'other' THEN TOTAL_AMOUNT ELSE 0 END), 0) AS OTHER_AMOUNT
    FROM TAX_INVOICE
    WHERE 1=1
    <include refid="common.companyCodeFilter"/>
    AND INVOICE_STATUS != 'cancelled'
    <if test="start_date != null">
      AND INVOICE_DATE &gt;= #{start_date}
    </if>
    <if test="end_date != null">
      AND INVOICE_DATE &lt;= #{end_date}
    </if>
    <if test="start_date == null and year != null">
      AND EXTRACT(YEAR FROM INVOICE_DATE)::INTEGER = #{year}
    </if>
  </select>

</mapper>
