class ECpayInvoice::InvoiceParamVerify

Public Class Methods

new(apiname) click to toggle source
# File lib/ecpay_invoice/verification.rb, line 203
def initialize(apiname)
    @inv_basic_param = self.get_basic_params(apiname).freeze
    @inv_conditional_param = self.get_cond_param(apiname).freeze
    @all_param_pattern = self.get_all_pattern(apiname).freeze
end

Public Instance Methods

verify_inv_allowance_invalid_param(params) click to toggle source
# File lib/ecpay_invoice/verification.rb, line 955
def verify_inv_allowance_invalid_param(params)
    if params.is_a?(Hash)
        param_diff = @inv_basic_param - params.keys
        unless param_diff == []
            raise ECpayInvalidParam, "Lack required param #{param_diff}"
        end

        #Verify Value pattern of each param
        self.verify_param_by_pattern(params, @all_param_pattern)

    else
        raise TypeError, "Recieved argument is not a hash"
    end

end
verify_inv_allowance_param(params) click to toggle source
# File lib/ecpay_invoice/verification.rb, line 825
def verify_inv_allowance_param(params)
    if params.is_a?(Hash)
        #發票所有參數預設要全帶

        if params.has_value?(nil)
            raise ECpayInvalidParam, %Q{Parameter value cannot be nil}
        end
        #1. 比對欄位是否缺乏
        param_diff = @inv_basic_param - params.keys()
        unless param_diff == []
            raise ECpayInvalidParam, %Q{Lack required invoice param #{param_diff}}
        end

        #2. 比對特殊欄位值相依需求
        #NotifyPhone和NotifyMail至少一個有值
        if params['AllowanceNotify'].to_s == 'S'
            if params['NotifyPhone'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[NotifyPhone] cannot be empty."
            end
        elsif params['AllowanceNotify'].to_s == 'E'
            if params['NotifyMail'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[NotifyMail] cannot be empty."
            end
        elsif params['AllowanceNotify'].to_s == 'A'
            if params['NotifyPhone'].to_s.empty? or params['NotifyMail'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[NotifyPhone] and [NotifyMail] can not be empty."
            end
        end

        vat_params = ['ItemCount', 'ItemAmount']
        # 商品價錢含有管線 => 認為是多樣商品 *ItemCount , *ItemPrice , *ItemAmount 逐一用管線分割,計算數量後與第一個比對
        # 驗證單筆ItemAmount = (ItemPrice * ItemCount)
        if !params['ItemPrice'].include?('|')
            unless params['ItemAmount'].to_i == (params['ItemPrice'].to_i * params['ItemCount'].to_i).round
                raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{params['ItemPrice'].to_i}) times [ItemCount] (#{params['ItemCount'].to_i}) subtotal not equal [ItemAmount] (#{params['ItemAmount'].to_i})}
            end
            # 驗證單筆商品合計是否等於發票金額
            unless params['AllowanceAmount'].to_i == params['ItemAmount'].to_i
                raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{params['ItemAmount'].to_i}) not equal [AllowanceAmount] (#{params['AllowanceAmount'].to_i})}
            end
        elsif params['ItemPrice'].include?('|')
            vat_cnt = params['ItemPrice'].split('|').length
            vat_params.each do |param_name|
                # Check if there's empty value.
                unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
                    raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
                end
                p_cnt = params[param_name].split('|').length
                unless vat_cnt == p_cnt
                    raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [ItemCount] (#{vat_cnt})}
                end
            end
            vat_amount_arr = params['ItemAmount'].split('|')
            vat_price_arr = params['ItemPrice'].split('|')
            vat_count_arr = params['ItemCount'].split('|')
            (1..vat_cnt).each do |index|
                unless vat_amount_arr[index - 1].to_i == (vat_price_arr[index - 1].to_i * vat_count_arr[index - 1].to_i).round
                    raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{vat_price_arr[index - 1]}) times [ItemCount] (#{vat_count_arr[index - 1]}) not match [ItemAmount] (#{vat_amount_arr[index - 1].to_i})}
                end
                #Verify ItemAmount subtotal equal SalesAmount
                chk_amount_subtotal = 0
                vat_amount_arr.each do |val|
                    chk_amount_subtotal += val.to_i
                end
                unless params['AllowanceAmount'].to_i == chk_amount_subtotal
                    raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{vat_amount_arr}) subtotal not equal [AllowanceAmount] (#{params['AllowanceAmount'].to_i})}
                end
            end
        end

        #3. 比對商品名稱,數量,單位,價格,tax,合計,備註項目數量是否一致,欄位是否為空
        if params['ItemName'].to_s.empty? or params['ItemWord'].to_s.empty?
            raise ECpayInvoiceRuleViolate, "[ItemName] or [ItemWord] cannot be empty"
        end
        item_params = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount']
        #商品名稱含有管線 => 認為是多樣商品 *ItemName, *ItemCount ,*ItemWord, *ItemPrice, *ItemAmount逐一用管線分割,計算數量後與第一個比對
        if params['ItemName'].include?('|')
            item_cnt = params['ItemName'].split('|').length
            item_params.each do |param_name|
                # Check if there's empty value.
                unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
                    raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
                end
                p_cnt = params[param_name].split('|').length
                unless item_cnt == p_cnt
                    raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [ItemCount] (#{item_cnt})}
                end
            end
            # ItemTaxType 能含有1,2 3(and at least contains one 1 and other)
            if params['ItemTaxType'].include?('|')
                item_tax = params['ItemTaxType'].split('|')
                aval_tax_type = ['1', '3']
                vio_tax_t = (item_tax - aval_tax_type)
                unless vio_tax_t == []
                    raise ECpayInvoiceRuleViolate, "Ilegal [ItemTaxType]: #{vio_tax_t}"
                end
            end
        else
            #沒有管線 => 逐一檢查後6項有無管線
            item_params.each do |param_name|
                if params[param_name].include?('|')
                    raise "Item info [#{param_name}] contains pipeline delimiter but there's only one item in param [ItemName]"
                end
            end
        end

        #4 比對所有欄位Pattern
        self.verify_param_by_pattern(params, @all_param_pattern)

    else
        raise TypeError, "Recieved argument is not a hash"
    end
end
verify_inv_delay_param(params) click to toggle source
# File lib/ecpay_invoice/verification.rb, line 557
def verify_inv_delay_param(params)
    if params.is_a?(Hash)
        #發票所有參數預設要全帶

        if params.has_value?(nil)
            raise ECpayInvalidParam, %Q{Parameter value cannot be nil}
        end
        #1. 比對欄位是否缺乏
        param_diff = @inv_basic_param - params.keys()
        unless param_diff == []
            raise ECpayInvalidParam, %Q{Lack required invoice param #{param_diff}}
        end

        #2. 比對特殊欄位值相依需求
        #a [CarruerType]為 1 => CustomerID 不能為空
        if params['CarruerType'].to_s == '1'
            if params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerID] can not be empty when [CarruerType] is 1."
            end
            # [CustomerID]不為空 => CarruerType 不能為空
        elsif params['CarruerType'].to_s == ''
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CarruerType] can not be empty when [CustomerID] is not empty."
            end
        end
        #b 列印註記[Print]為 1 => CustomerName, CustomerAddr
        if params['Print'].to_s == '1'
            if params['CustomerName'].to_s.empty? or params['CustomerAddr'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerName] and [CustomerAddr] can not be empty when [Print] is 1."
            end
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[Print] can not be '1' when [CustomerID] is not empty."
            end
            unless params['CarruerType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[Print] can not be '1' when [CarruerType] is not empty."
            end
            unless params['CarruerNum'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[Print] can not be '1' when [CarruerNum] is not empty."
            end
        end

        #c CustomerPhone和CustomerEmail至少一個有值
        if  params['CustomerPhone'].to_s.empty? and params['CustomerEmail'].to_s.empty?
            raise ECpayInvoiceRuleViolate, "[CustomerPhone] and [CustomerEmail] can not both be empty."
        end

        #d [TaxType]為 2 => ClearanceMark = 必須為 1 or 2,ItemTaxType 必須為空
        if params['TaxType'].to_s == '2'
            @tax_fee = 1.05
            @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount']
            @vat_params_list = ['ItemCount', 'ItemAmount']
            unless ['1', '2'].include?(params['ClearanceMark'].to_s)
                raise ECpayInvoiceRuleViolate, "[ClearanceMark] has to be 1 or 2 when [TaxType] is 2."
            end
            unless params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must be empty when [TaxType] is 2."
            end
            #d.1 [TaxType]為 1 => ItemTaxType, ClearanceMark 必須為空
        elsif params['TaxType'].to_s == '1'
            @tax_fee = 1
            @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount']
            @vat_params_list = ['ItemCount', 'ItemAmount']
            unless params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must be empty when [TaxType] is 1."
            end
            unless params['ClearanceMark'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ClearanceMark] must be empty when [TaxType] is 1."
            end
            #d.2 [TaxType]為 3 => ItemTaxType, ClearanceMark 必須為空
        elsif params['TaxType'].to_s == '3'
            @tax_fee = 1.05
            @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount']
            @vat_params_list = ['ItemCount', 'ItemAmount']
            unless params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must be empty when [TaxType] is 3."
            end
            unless params['ClearanceMark'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ClearanceMark] must be empty when [TaxType] is 3."
            end
            #d.3 [TaxType]為 9 => ItemTaxType 必須為兩項商品(含)以上,且不可為空
        elsif params['TaxType'].to_s == '9'
            @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount', 'ItemTaxType']
            @vat_params_list = ['ItemCount', 'ItemAmount', 'ItemTaxType']
            unless params['ItemTaxType'].include?('|')
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must contain at lease one '|'."
            end
            if params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] can not be empty when [TaxType] is 9."
            end
        end

        #e 統一編號[CustomerIdentifier]有值時 => CarruerType != 1, 2 or 3, *Donation = 2, print = 1
        unless params['CustomerIdentifier'].to_s.empty?
            if ['1', '2', '3'].include?(params['CarruerType'].to_s)
                raise ECpayInvoiceRuleViolate, "[CarruerType] Cannot be 1, 2 or 3 when [CustomerIdentifier] is given."
            end
            unless params['Donation'].to_s == '2' and params['Print'].to_s == '1'
                raise ECpayInvoiceRuleViolate, "[Print] must be 1 and [Donation] must be 2 when [CustomerIdentifier] is given."
            end
        end

        # DelayFlag Rules When [DelayFlag] is '1' the [DelayDay] range be between 1 and 15
        # When [DelayFlag] is '2' the [DelayDay] range be between 0 and 15
        if params['DelayFlag'].to_s == '1'
            if params['DelayDay'].to_i > 15 or params['DelayDay'].to_i < 1
                raise ECpayInvoiceRuleViolate, "[DelayDay] must be between 1 and 15  when [DelayFlag] is '1'."
            end
        elsif params['DelayFlag'].to_s == '2'
            if params['DelayDay'].to_i > 15 or params['DelayDay'].to_i < 0
                raise ECpayInvoiceRuleViolate, "[DelayDay] must be between 0 and 15  when [DelayFlag] is '2'."
            end
        end

        # [CarruerType]為'' or 1 時 => CarruerNum = '', [CarruerType]為 2, CarruerNum = 固定長度為 16 且格式為 2 碼大小寫字母加上 14 碼數字。 [CarruerType]為 3 ,帶固定長度為 8 且格式為 1 碼斜線「/」加上由 7 碼數字及大小寫字母組成
        if ['', '1'].include?(params['CarruerType'].to_s)
            unless params['CarruerNum'].to_s == ''
                raise ECpayInvoiceRuleViolate, "[CarruerNum] must be empty when [CarruerType] is empty or 1."
            end
        elsif params['CarruerType'].to_s == '2'
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerID] must be empty when [CarruerType] is 3."
            end
            if /[A-Za-z]{2}[0-9]{14}/.match(params['CarruerNum']).nil?
                raise ECpayInvoiceRuleViolate, "[CarruerNum] must be 2 alphabets and 14 numbers when [CarruerType] is 2."
            end
        elsif params['CarruerType'].to_s == '3'
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerID] must be empty when [CarruerType] is 3."
            end
            if /^\/[A-Za-z0-9\s+-]{7}$/.match(params['CarruerNum']).nil?
                raise ECpayInvoiceRuleViolate, "[CarruerNum] must start with '/' followed by 7 alphabet and number characters when [CarruerType] is 3."
            end
        else
            raise ECpayInvoiceRuleViolate, "Unexpected value in [CarruerType]."
        end

        # Donation = 1 => LoveCode不能為空, print = 0
        if params['Donation'].to_s == '1'
            if params['LoveCode'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[LoveCode] cannot be empty when [Donation] is 1."
            end
            unless params['Print'].to_s == '0'
                raise ECpayInvoiceRuleViolate, "[Print] must be 0 when [Donation] is 1."
            end
        # Donation = 2 => LoveCode不能有值
        elsif params['Donation'].to_s == '2'
            unless params['LoveCode'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[LoveCode] must be empty when [Donation] is 2."
            end
        end

        vat_params = @vat_params_list
        # 商品價錢含有管線 => 認為是多樣商品 *ItemCount , *ItemPrice , *ItemAmount 逐一用管線分割,計算數量後與第一個比對
        if !params['ItemPrice'].include?('|')
            unless params['ItemAmount'].to_i == (params['ItemPrice'].to_i * params['ItemCount'].to_i / @tax_fee).round
                raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{params['ItemPrice'].to_i}) times [ItemCount] (#{params['ItemCount'].to_i}) '/' tax (#{@tax_fee}) subtotal not equal [ItemAmount] (#{params['ItemAmount'].to_i})}
            end
            # 驗證單筆商品合計是否等於發票金額
            unless params['SalesAmount'].to_i == params['ItemAmount'].to_i
                raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{params['ItemAmount'].to_i}) not equal [SalesAmount] (#{params['SalesAmount'].to_i})}
            end
        elsif params['ItemPrice'].include?('|')
            vat_cnt = params['ItemPrice'].split('|').length
            vat_params.each do |param_name|
                # Check if there's empty value.
                unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
                    raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
                end
                p_cnt = params[param_name].split('|').length
                unless vat_cnt == p_cnt
                    raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [ItemCount] (#{vat_cnt})}
                end
            end
            vat_amount_arr = params['ItemAmount'].split('|')
            vat_price_arr = params['ItemPrice'].split('|')
            vat_count_arr = params['ItemCount'].split('|')
            (1..vat_cnt).each do |index|
                if @vat_params_list.length == 3
                    vat_tax_arr = params['ItemTaxType'].split('|')
                    if vat_tax_arr[index - 1].to_s == '1'
                        @tax_fee = 1
                    elsif vat_tax_arr[index - 1].to_s == '2' or vat_tax_arr[index - 1].to_s == '3'
                        @tax_fee = 1.05
                    else
                        raise ECpayInvoiceRuleViolate, "[ItemTaxType] can not be (#{vat_tax_arr[index - 1]}). Avaliable option: (1, 2, 3)."
                    end
                end
                unless vat_amount_arr[index - 1].to_i == (vat_price_arr[index - 1].to_i * vat_count_arr[index - 1].to_i / @tax_fee).round
                    raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{vat_price_arr[index - 1]}) times [ItemCount] (#{vat_count_arr[index - 1]}) '/' tax(#{@tax_fee}) not match [ItemAmount] (#{vat_amount_arr[index - 1].to_i})}
                end
                #Verify ItemAmount subtotal equal SalesAmount
                chk_amount_subtotal = 0
                vat_amount_arr.each do |val|
                    chk_amount_subtotal += val.to_i
                end
                unless params['SalesAmount'].to_i == chk_amount_subtotal
                    raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{vat_amount_arr}) subtotal not equal [SalesAmount] (#{params['SalesAmount'].to_i})}
                end
            end
        end

        #3. 比對商品名稱,數量,單位,價格,tax,合計,備註項目數量是否一致,欄位是否為空
        if params['ItemName'].to_s.empty? or params['ItemWord'].to_s.empty?
            raise ECpayInvoiceRuleViolate, "[ItemName] or [ItemWord] cannot be empty"
        end
        item_params = @item_params_list
        #商品名稱含有管線 => 認為是多樣商品 *ItemName, *ItemCount ,*ItemWord, *ItemPrice, *ItemAmount逐一用管線分割,計算數量後與第一個比對
        if params['ItemName'].include?('|')
            item_cnt = params['ItemName'].split('|').length
            item_params.each do |param_name|
                # Check if there's empty value.
                unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
                    raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
                end
                p_cnt = params[param_name].split('|').length
                unless item_cnt == p_cnt
                    raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [ItemCount] (#{item_cnt})}
                end
            end
            # 課稅類別[TaxType] = 9 時 => ItemTaxType 能含有1,2 3(and at least contains one 1 and other)
            if params['TaxType'].to_s == '9'
                item_tax = params['ItemTaxType'].split('|')
                p item_tax
                aval_tax_type = ['1', '2', '3']
                vio_tax_t = (item_tax - aval_tax_type)
                unless vio_tax_t == []
                    raise ECpayInvoiceRuleViolate, "Ilegal [ItemTaxType]: #{vio_tax_t}"
                end
                unless item_tax.include?('1')
                    raise ECpayInvoiceRuleViolate, "[ItemTaxType] must contain at lease one '1'."
                end
                if !item_tax.include?('2') and !item_tax.include?('3')
                    raise ECpayInvoiceRuleViolate, "[ItemTaxType] cannot be all 1 when [TaxType] is 9."
                end
            end
        else
            #沒有管線 => 逐一檢查後6項有無管線
            item_params.each do |param_name|
                if params[param_name].include?('|')
                    raise "Item info [#{param_name}] contains pipeline delimiter but there's only one item in param [ItemName]"
                end
            end
        end

        #4 比對所有欄位Pattern
        self.verify_param_by_pattern(params, @all_param_pattern)

    else
        raise TypeError, "Recieved argument is not a hash"
    end
end
verify_inv_issue_invalid_param(params) click to toggle source
# File lib/ecpay_invoice/verification.rb, line 939
def verify_inv_issue_invalid_param(params)
    if params.is_a?(Hash)
        param_diff = @inv_basic_param - params.keys
        unless param_diff == []
            raise ECpayInvalidParam, "Lack required param #{param_diff}"
        end

        #Verify Value pattern of each param
        self.verify_param_by_pattern(params, @all_param_pattern)

    else
        raise TypeError, "Recieved argument is not a hash"
    end

end
verify_inv_issue_param(params) click to toggle source
# File lib/ecpay_invoice/verification.rb, line 209
def verify_inv_issue_param(params)
    if params.is_a?(Hash)
        #發票所有參數預設要全帶

        if params.has_value?(nil)
            raise ECpayInvalidParam, %Q{Parameter value cannot be nil}
        end
        #1. 比對欄位是否缺乏
        param_diff = @inv_basic_param - params.keys()
        unless param_diff == []
            raise ECpayInvalidParam, %Q{Lack required invoice param #{param_diff}}
        end

        #2. 比對特殊欄位值相依需求
        #a [CarruerType]為 1 => CustomerID 不能為空
        if params['CarruerType'].to_s == '1'
            if params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerID] can not be empty when [CarruerType] is 1."
            end
        # [CustomerID]不為空 => CarruerType 不能為空
        elsif params['CarruerType'].to_s == ''
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CarruerType] can not be empty when [CustomerID] is not empty."
            end
        end
        #b 列印註記[Print]為 1 => CustomerName, CustomerAddr
        if params['Print'].to_s == '1'
            if params['CustomerName'].to_s.empty? or params['CustomerAddr'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerName] and [CustomerAddr] can not be empty when [Print] is 1."
            end
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[Print] can not be '1' when [CustomerID] is not empty."
            end
            unless params['CarruerType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[Print] can not be '1' when [CarruerType] is not empty."
            end
            unless params['CarruerNum'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[Print] can not be '1' when [CarruerNum] is not empty."
            end
        end

        #c CustomerPhone和CustomerEmail至少一個有值
        if  params['CustomerPhone'].to_s.empty? and params['CustomerEmail'].to_s.empty?
            raise ECpayInvoiceRuleViolate, "[CustomerPhone] and [CustomerEmail] can not both be empty."
        end

        #d [TaxType]為 2 => ClearanceMark = 必須為 1 or 2,ItemTaxType 必須為空
        if params['TaxType'].to_s == '2'
            if !params['ItemRemark'].to_s.empty?
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount', 'ItemRemark']
            else
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount']
            end
            @vat_params_list = ['ItemCount', 'ItemAmount']
            unless ['1', '2'].include?(params['ClearanceMark'].to_s)
                raise ECpayInvoiceRuleViolate, "[ClearanceMark] has to be 1 or 2 when [TaxType] is 2."
            end
            unless params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must be empty when [TaxType] is 2."
            end
            # 當[TaxType]為2時為零稅率,vat為0時商品單價為免稅,不須再加稅
            # 若vat為1時商品單價為含稅,須再退稅
            if params['vat'].to_s == '0'
                @tax_fee = 1
            elsif params['vat'].to_s == '1'
                @tax_fee = 1.05
            end
        #d.1 [TaxType]為 1 => ItemTaxType, ClearanceMark 必須為空
        elsif params['TaxType'].to_s == '1'
            if !params['ItemRemark'].to_s.empty?
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount', 'ItemRemark']
            else
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount']
            end
            @vat_params_list = ['ItemCount', 'ItemAmount']
            unless params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must be empty when [TaxType] is 1."
            end
            unless params['ClearanceMark'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ClearanceMark] must be empty when [TaxType] is 1."
            end
            # 當[TaxType]為1時為應稅,vat為0時商品單價為免稅,須再加稅
            # 若vat為1時商品單價為含稅,不須再加稅
            if params['vat'].to_s == '0'
                @tax_fee = 1.05
            elsif params['vat'].to_s == '1'
                @tax_fee = 1
            end
        #d.2 [TaxType]為 3 => ItemTaxType, ClearanceMark 必須為空
        elsif params['TaxType'].to_s == '3'
            if !params['ItemRemark'].to_s.empty?
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount', 'ItemRemark']
            else
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount']
            end
            @vat_params_list = ['ItemCount', 'ItemAmount']
            unless params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must be empty when [TaxType] is 3."
            end
            unless params['ClearanceMark'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ClearanceMark] must be empty when [TaxType] is 3."
            end
            # 當[TaxType]為3時為免稅,vat為0時商品單價為免稅,不須再加稅
            # 若vat為1時商品單價為含稅,須再退稅
            if params['vat'].to_s == '0'
                @tax_fee = 1
            elsif params['vat'].to_s == '1'
                @tax_fee = 1.05
            end
        #d.3 [TaxType]為 9 => ItemTaxType 必須為兩項商品(含)以上,且不可為空
        elsif params['TaxType'].to_s == '9'
            if !params['ItemRemark'].to_s.empty?
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount', 'ItemRemark', 'ItemTaxType']
            else
                @item_params_list = ['ItemCount', 'ItemWord', 'ItemPrice', 'ItemAmount', 'ItemTaxType']
            end
            @vat_params_list = ['ItemCount', 'ItemAmount', 'ItemTaxType']
            unless params['ItemTaxType'].include?('|')
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] must contain at lease one '|'."
            end
            if params['ItemTaxType'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[ItemTaxType] can not be empty when [TaxType] is 9."
            end
            # 當[ItmeTaxType]含2選項的話[ClearanceMark]須為1或2
            if params['ItemTaxType'].include?('2')
                unless ['1', '2'].include?(params['ClearanceMark'].to_s)
                    raise ECpayInvoiceRuleViolate, "[ClearanceMark] has to be 1 or 2 when [ItemTaxType] has 2."
                end
            end
        end

        #e 統一編號[CustomerIdentifier]有值時 => CarruerType != 1, 2 or 3, *Donation = 2, print = 1
        unless params['CustomerIdentifier'].to_s.empty?
            if ['1', '2', '3'].include?(params['CarruerType'].to_s)
                raise ECpayInvoiceRuleViolate, "[CarruerType] Cannot be 1, 2 or 3 when [CustomerIdentifier] is given."
            end
            unless params['Donation'].to_s == '2' and params['Print'].to_s == '1'
                raise ECpayInvoiceRuleViolate, "[Print] must be 1 and [Donation] must be 2 when [CustomerIdentifier] is given."
            end
        end

        # [CarruerType]為'' or 1 時 => CarruerNum = '', [CarruerType]為 2, CarruerNum = 固定長度為 16 且格式為 2 碼大小寫字母加上 14 碼數字。 [CarruerType]為 3 ,帶固定長度為 8 且格式為 1 碼斜線「/」加上由 7 碼數字及大小寫字母組成
        if ['', '1'].include?(params['CarruerType'].to_s)
            unless params['CarruerNum'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CarruerNum] must be empty when [CarruerType] is empty or 1."
            end
        elsif params['CarruerType'].to_s == '2'
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerID] must be empty when [CarruerType] is 2."
            end
            if /[A-Za-z]{2}[0-9]{14}/.match(params['CarruerNum']).nil?
                raise ECpayInvoiceRuleViolate, "[CarruerNum] must be 2 alphabets and 14 numbers when [CarruerType] is 2."
            end
        elsif params['CarruerType'].to_s == '3'
            unless params['CustomerID'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[CustomerID] must be empty when [CarruerType] is 3."
            end
            if /^\/[A-Za-z0-9\s+-]{7}$/.match(params['CarruerNum']).nil?
                raise ECpayInvoiceRuleViolate, "[CarruerNum] must start with '/' followed by 7 alphabet and number characters when [CarruerType] is 3."
            end
        else
            raise ECpayInvoiceRuleViolate, "Unexpected value in [CarruerType]."
        end

        # Donation = 1 => LoveCode不能為空, print = 0
        if params['Donation'].to_s == '1'
            if params['LoveCode'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[LoveCode] cannot be empty when [Donation] is 1."
            end
            unless params['Print'].to_s == '0'
                raise ECpayInvoiceRuleViolate, "[Print] must be 0 when [Donation] is 1."
            end
        # Donation = 2 => LoveCode不能有值
        elsif params['Donation'].to_s == '2'
            unless params['LoveCode'].to_s.empty?
                raise ECpayInvoiceRuleViolate, "[LoveCode] must be empty when [Donation] is 2."
            end
        end

        # [vat]為0時 => ItemPrice = 未稅, ItemAmount = (ItemPrice * ItemCount) + (ItemPrice * ItemCount * tax(5%))
        # 未稅加稅單一商品時直接四捨五入帶入ItemAmount,且ItemAmount等於SalesAmount
        # 未稅加稅多樣商品時先算稅金加總帶入ItemAmount,且ItemAmount全部金額加總後帶入SalesAmount後四捨五入
        vat_params = @vat_params_list
        # 商品價錢含有管線 => 認為是多樣商品 *ItemCount , *ItemPrice , *ItemAmount 逐一用管線分割,計算數量後與第一個比對
        if params['vat'].to_s == '0'
            if !params['ItemPrice'].include?('|')
                unless params['ItemAmount'].to_i == (params['ItemPrice'].to_i * params['ItemCount'].to_i * @tax_fee).round
                    raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{params['ItemPrice'].to_i}) times [ItemCount] (#{params['ItemCount'].to_i}) '*' tax (#{@tax_fee}) subtotal not equal [ItemAmount] (#{params['ItemAmount'].to_i})}
                end
                # 驗證單筆商品合計是否等於發票金額
                unless params['SalesAmount'].to_i == params['ItemAmount'].to_i
                    raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{params['ItemAmount'].to_i}) not equal [SalesAmount] (#{params['SalesAmount'].to_i})}
                end

            elsif params['ItemPrice'].include?('|')
                vat_cnt = params['ItemPrice'].split('|').length
                vat_params.each do |param_name|
                    # Check if there's empty value.
                    unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
                        raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
                    end
                    p_cnt = params[param_name].split('|').length
                    unless vat_cnt == p_cnt
                        raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [ItemCount] (#{vat_cnt})}
                    end
                end
                vat_amount_arr = params['ItemAmount'].split('|')
                vat_price_arr = params['ItemPrice'].split('|')
                vat_count_arr = params['ItemCount'].split('|')
                (1..vat_cnt).each do |index|
                    if @vat_params_list.length == 3
                        vat_tax_arr = params['ItemTaxType'].split('|')
                        if vat_tax_arr[index - 1].to_s == '1'
                            @tax_fee = 1.05
                        elsif vat_tax_arr[index - 1].to_s == '2' or vat_tax_arr[index - 1].to_s == '3'
                            @tax_fee = 1
                        else
                            raise ECpayInvoiceRuleViolate, "[ItemTaxType] can not be (#{vat_tax_arr[index - 1]}). Avaliable option: (1, 2, 3)."
                        end
                    end
                    unless vat_amount_arr[index - 1].to_f == (vat_price_arr[index - 1].to_i * vat_count_arr[index - 1].to_i * @tax_fee)
                        raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{vat_price_arr[index - 1].to_i}) times [ItemCount] (#{vat_count_arr[index - 1].to_i}) '*' tax(#{@tax_fee}) not match [ItemAmount] (#{vat_amount_arr[index - 1].to_f})}
                    end
                    #Verify ItemAmount subtotal equal SalesAmount
                    chk_amount_subtotal = 0
                    vat_amount_arr.each do |val|
                        chk_amount_subtotal += val.to_f
                    end
                    unless params['SalesAmount'].to_i == chk_amount_subtotal.round
                        raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{vat_amount_arr}) subtotal not equal [SalesAmount] (#{params['SalesAmount'].to_i})}
                    end
                end
            end
        end

        # [vat]為1時 => ItemPrice = 含稅, ItemAmount = ItemPrice * ItemCount
        # 商品價錢含有管線 => 認為是多樣商品 *ItemCount , *ItemPrice , *ItemAmount 逐一用管線分割,計算數量後與第一個比對
        # 含稅扣稅單一商品時直接四捨五入帶入ItemAmount,且ItemAmount等於SalesAmount
        # 含稅扣稅多樣商品時先算稅金加總四捨五入後帶入ItemAmount,且ItemAmount全部金額加總後等於SalesAmount
        if params['vat'].to_s == '1'
            if !params['ItemPrice'].include?('|')

                unless params['ItemAmount'].to_i == (params['ItemPrice'].to_i * params['ItemCount'].to_i / @tax_fee).round
                    raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{params['ItemPrice'].to_i}) times [ItemCount] (#{params['ItemCount'].to_i}) '/' tax (#{@tax_fee}) subtotal not equal [ItemAmount] (#{params['ItemAmount'].to_i})}
                end
                # 驗證單筆商品合計是否等於發票金額
                unless params['SalesAmount'].to_i == params['ItemAmount'].to_i
                    raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{params['ItemAmount'].to_i}) not equal [SalesAmount] (#{params['SalesAmount'].to_i})}
                end
            elsif params['ItemPrice'].include?('|')
                vat_cnt = params['ItemPrice'].split('|').length
                vat_params.each do |param_name|
                    # Check if there's empty value.
                    unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
                        raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
                    end
                    p_cnt = params[param_name].split('|').length
                    unless vat_cnt == p_cnt
                        raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [ItemCount] (#{vat_cnt})}
                    end
                end
                vat_amount_arr = params['ItemAmount'].split('|')
                vat_price_arr = params['ItemPrice'].split('|')
                vat_count_arr = params['ItemCount'].split('|')
                (1..vat_cnt).each do |index|
                    if @vat_params_list.length == 3
                        vat_tax_arr = params['ItemTaxType'].split('|')
                        if vat_tax_arr[index - 1].to_s == '1'
                            @tax_fee = 1
                        elsif vat_tax_arr[index - 1].to_s == '2' or vat_tax_arr[index - 1].to_s == '3'
                            @tax_fee = 1.05
                        else
                            raise ECpayInvoiceRuleViolate, "[ItemTaxType] can not be (#{vat_tax_arr[index - 1]}). Avaliable option: (1, 2, 3)."
                        end
                    end
                    unless vat_amount_arr[index - 1].to_i == (vat_price_arr[index - 1].to_i * vat_count_arr[index - 1].to_i / @tax_fee).round
                        raise ECpayInvoiceRuleViolate, %Q{[ItemPrice] (#{vat_price_arr[index - 1]}) times [ItemCount] (#{vat_count_arr[index - 1]}) '/' tax(#{@tax_fee}) not match [ItemAmount] (#{vat_amount_arr[index - 1].to_i})}
                    end
                    #Verify ItemAmount subtotal equal SalesAmount
                    chk_amount_subtotal = 0
                    vat_amount_arr.each do |val|
                        chk_amount_subtotal += val.to_i
                    end
                    unless params['SalesAmount'].to_i == chk_amount_subtotal
                        raise ECpayInvoiceRuleViolate, %Q{[ItemAmount] (#{vat_amount_arr}) subtotal not equal [SalesAmount] (#{params['SalesAmount'].to_i})}
                    end
                end
            end
        end

        #3. 比對商品名稱,數量,單位,價格,tax,合計,備註項目數量是否一致,欄位是否為空
        if params['ItemName'].to_s.empty? or params['ItemWord'].to_s.empty?
            raise ECpayInvoiceRuleViolate, "[ItemName] or [ItemWord] cannot be empty"
        end

        # ItemTaxType and ItemRemark會因為TaxType and ItemRemark is not empty 新增至@item_params_list
        item_params = @item_params_list
        #商品名稱含有管線 => 認為是多樣商品 *ItemName, *ItemCount ,*ItemWord, *ItemPrice, *ItemAmount, *ItemTaxType, *ItemRemark逐一用管線分割,計算數量後與第一個比對
        if params['ItemName'].include?('|')
            item_cnt = params['ItemName'].split('|').length
            item_params.each do |param_name|
                # Check if there's empty value.
                unless /(\|\||^\||\|$)/.match(params[param_name]).nil?
                    raise ECpayInvoiceRuleViolate, "[#{param_name}] contains empty value."
                end
                p_cnt = params[param_name].split('|').length
                unless item_cnt == p_cnt
                    raise ECpayInvoiceRuleViolate, %Q{Count of item info [#{param_name}] (#{p_cnt}) not match item count from [ItemCount] (#{item_cnt})}
                end
            end
            # 課稅類別[TaxType] = 9 時 => ItemTaxType 能含有1,2 3(and at least contains one 1 and other)
            if params['TaxType'].to_s == '9'
                item_tax = params['ItemTaxType'].split('|')
                p item_tax
                aval_tax_type = ['1', '2', '3']
                vio_tax_t = (item_tax - aval_tax_type)
                unless vio_tax_t == []
                    raise ECpayInvoiceRuleViolate, "Ilegal [ItemTaxType]: #{vio_tax_t}"
                end
                unless item_tax.include?('1')
                    raise ECpayInvoiceRuleViolate, "[ItemTaxType] must contain at lease one '1'."
                end
                if item_cnt >= 2
                    if !item_tax.include?('2') and !item_tax.include?('3')
                        raise ECpayInvoiceRuleViolate, "[ItemTaxType] cannot be all 1 when [TaxType] is 9."
                    end
                end
                if item_tax.include?('2') and item_tax.include?('3')
                    raise ECpayInvoiceRuleViolate, "[ItemTaxType] cannot contain 2 and 3 at the same time."
                end
            end
        else
            #沒有管線 => 逐一檢查@item_params_list的欄位有無管線
            item_params.each do |param_name|
                if params[param_name].include?('|')
                    raise "Item info [#{param_name}] contains pipeline delimiter but there's only one item in param [ItemName]"
                end
            end
        end

        #4 比對所有欄位Pattern
        self.verify_param_by_pattern(params, @all_param_pattern)

    else
        raise TypeError, "Recieved argument is not a hash"
    end
end
verify_inv_trigger_param(params) click to toggle source
# File lib/ecpay_invoice/verification.rb, line 809
def verify_inv_trigger_param(params)
    if params.is_a?(Hash)
        param_diff = @inv_basic_param - params.keys
        unless param_diff == []
            raise ECpayInvalidParam, "Lack required param #{param_diff}"
        end

        #Verify Value pattern of each param
        self.verify_param_by_pattern(params, @all_param_pattern)

    else
        raise TypeError, "Recieved argument is not a hash"
    end

end