Class: SunatInvoice::Invoice
- Includes:
- Utils
- Defined in:
- lib/sunat_invoice/invoice.rb
Constant Summary collapse
- UBL_VERSION =
'2.0'
- CUSTOMIZATION =
'1.0'
Constants included from Utils
Instance Attribute Summary collapse
-
#document_number ⇒ Object
Returns the value of attribute document_number.
-
#document_type ⇒ Object
Returns the value of attribute document_type.
-
#items ⇒ Object
Returns the value of attribute items.
Instance Method Summary collapse
- #add_item(item) ⇒ Object
- #attributes ⇒ Object
- #build_items(xml) ⇒ Object
- #build_sale_totals(xml) ⇒ Object
- #build_tax_totals(xml) ⇒ Object
- #build_total(xml) ⇒ Object
- #calculate_sale_totals ⇒ Object
- #calculate_tax_totals ⇒ Object
- #calculate_total ⇒ Object
- #document_name ⇒ Object
- #get_total_code(tax) ⇒ Object
- #get_total_igv_code(exemption_reason) ⇒ Object
-
#initialize(*args) ⇒ Invoice
constructor
A new instance of Invoice.
- #prepare_totals ⇒ Object
- #xml ⇒ Object
Methods included from Utils
Constructor Details
#initialize(*args) ⇒ Invoice
Returns a new instance of Invoice.
18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/sunat_invoice/invoice.rb', line 18 def initialize(*args) super(*args) opts = args[0] || {} @provider = opts[:provider] || SunatInvoice::Provider.new @customer = opts[:customer] || SunatInvoice::Customer.new @date = opts[:date] || DateTime.now.strftime('%Y-%m-%d') @document_type = opts[:document_type] || '01' @document_number = opts[:document_number] || 'F001-1' @currency = opts[:currency] || 'PEN' @items ||= [] @signature = SunatInvoice::Signature.new(provider: @provider) end |
Instance Attribute Details
#document_number ⇒ Object
Returns the value of attribute document_number.
13 14 15 |
# File 'lib/sunat_invoice/invoice.rb', line 13 def document_number @document_number end |
#document_type ⇒ Object
Returns the value of attribute document_type.
13 14 15 |
# File 'lib/sunat_invoice/invoice.rb', line 13 def document_type @document_type end |
#items ⇒ Object
Returns the value of attribute items.
13 14 15 |
# File 'lib/sunat_invoice/invoice.rb', line 13 def items @items end |
Instance Method Details
#add_item(item) ⇒ Object
132 133 134 |
# File 'lib/sunat_invoice/invoice.rb', line 132 def add_item(item) items << item if item.is_a?(SunatInvoice::Item) end |
#attributes ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/sunat_invoice/invoice.rb', line 158 def attributes { attributes!: { 'cbc:InvoicedQuantity' => { '@unitCode' => :unit }, 'cbc:PriceAmount' => { '@currencyID' => :currency }, # PEN 'cbc:TaxAmount' => { '@currencyID' => :currency }, # PEN 'cbc:PayableAmount' => { '@currencyID' => :currency }, # PEN 'cbc:LineExtensionAmount' => { '@currencyID' => :currency }, # PEN 'cbc:ChargeTotalAmount' => { '@currencyID' => :currency }, # PEN } } end |
#build_items(xml) ⇒ Object
97 98 99 100 101 |
# File 'lib/sunat_invoice/invoice.rb', line 97 def build_items(xml) items.each_with_index do |item, index| item.xml(xml, index, @currency) end end |
#build_sale_totals(xml) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/sunat_invoice/invoice.rb', line 113 def build_sale_totals(xml) ubl_ext(xml) do xml['sac'].AdditionalInformation do @sale_totals.each do |code, amount| xml['sac'].AdditionalMonetaryTotal do xml['cbc'].ID code amount_xml(xml['cbc'], 'PayableAmount', amount, @currency) end end end end end |
#build_tax_totals(xml) ⇒ Object
107 108 109 110 111 |
# File 'lib/sunat_invoice/invoice.rb', line 107 def build_tax_totals(xml) @tax_totals.each do |key, value| SunatInvoice::Tax.new(tax_type: key, amount: value).xml(xml, @currency) end end |
#build_total(xml) ⇒ Object
126 127 128 129 130 |
# File 'lib/sunat_invoice/invoice.rb', line 126 def build_total(xml) xml['cac'].LegalMonetaryTotal do amount_xml(xml['cbc'], 'PayableAmount', @total, @currency) end end |
#calculate_sale_totals ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/sunat_invoice/invoice.rb', line 73 def calculate_sale_totals @sale_totals = {} # get bi totals according kind of sale (gravado, inafecto, exonerado ..) items.each do |item| # TODO: I think in most cases only be one tax for item, but should # handle more cases total_code = get_total_code(item.taxes.first) if total_code @sale_totals[total_code] = 0 unless @sale_totals[total_code] @sale_totals[total_code] += item.bi_value end end end |
#calculate_tax_totals ⇒ Object
87 88 89 90 91 92 93 94 95 |
# File 'lib/sunat_invoice/invoice.rb', line 87 def calculate_tax_totals # concat item's sale_taxes @tax_totals = {} taxes = items.map(&:sale_taxes).flatten taxes.each do |tax| @tax_totals[tax.keys.first] ||= 0 @tax_totals[tax.keys.first] += tax.values.sum end end |
#calculate_total ⇒ Object
66 67 68 69 70 71 |
# File 'lib/sunat_invoice/invoice.rb', line 66 def calculate_total # calculate invoice total @total = 0 @total += @tax_totals.values.sum @total += @sale_totals.values.sum end |
#document_name ⇒ Object
103 104 105 |
# File 'lib/sunat_invoice/invoice.rb', line 103 def document_name "#{@provider.ruc}-#{document_type}-#{document_number}" end |
#get_total_code(tax) ⇒ Object
136 137 138 139 140 141 142 143 144 |
# File 'lib/sunat_invoice/invoice.rb', line 136 def get_total_code(tax) return unless tax case tax.tax_type when :igv get_total_igv_code(tax.tax_exemption_reason) # when :isc # tax.tier_range end end |
#get_total_igv_code(exemption_reason) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/sunat_invoice/invoice.rb', line 146 def get_total_igv_code(exemption_reason) if Catalogs::CATALOG_07.first == exemption_reason Catalogs::CATALOG_14.first elsif Catalogs::CATALOG_07[1..6].include?(exemption_reason) Catalogs::CATALOG_14[3] elsif Catalogs::CATALOG_07[7] == exemption_reason Catalogs::CATALOG_14[2] elsif Catalogs::CATALOG_07[8..14].include?(exemption_reason) Catalogs::CATALOG_14[1] end end |
#prepare_totals ⇒ Object
60 61 62 63 64 |
# File 'lib/sunat_invoice/invoice.rb', line 60 def prepare_totals calculate_tax_totals calculate_sale_totals calculate_total end |
#xml ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/sunat_invoice/invoice.rb', line 31 def xml prepare_totals build = Nokogiri::XML::Builder.new do |xml| xml.Invoice(UBL_NAMESPACES) do xml['ext'].UBLExtensions do build_sale_totals(xml) @signature.signature_ext(xml) end xml['cbc'].UBLVersionID UBL_VERSION xml['cbc'].CustomizationID CUSTOMIZATION xml['cbc'].ID @document_number xml['cbc'].IssueDate @date xml['cbc'].InvoiceTypeCode @document_type xml['cbc'].DocumentCurrencyCode @currency @signature.signer_data(xml) @provider.info(xml) @customer.info(xml) build_tax_totals(xml) build_total(xml) build_items(xml) end end invoice_xml = build.to_xml @signature.sign(invoice_xml) end |