diff --git a/lib/afip_bill.rb b/lib/afip_bill.rb index d5857f5..48cd8b9 100644 --- a/lib/afip_bill.rb +++ b/lib/afip_bill.rb @@ -16,6 +16,8 @@ def self.configuration ingresos_brutos: nil, iva: nil, sale_point: nil, + logo_path: nil, + invoice_discounts_mode: nil } end end diff --git a/lib/afip_bill/assets/images/factura_a.jpg b/lib/afip_bill/assets/images/factura_a.jpg index fcc256e..69c029f 100644 Binary files a/lib/afip_bill/assets/images/factura_a.jpg and b/lib/afip_bill/assets/images/factura_a.jpg differ diff --git a/lib/afip_bill/assets/images/factura_b.jpg b/lib/afip_bill/assets/images/factura_b.jpg index 4aec529..6eca9cf 100644 Binary files a/lib/afip_bill/assets/images/factura_b.jpg and b/lib/afip_bill/assets/images/factura_b.jpg differ diff --git a/lib/afip_bill/assets/images/factura_c.jpg b/lib/afip_bill/assets/images/factura_c.jpg new file mode 100644 index 0000000..6eca9cf Binary files /dev/null and b/lib/afip_bill/assets/images/factura_c.jpg differ diff --git a/lib/afip_bill/generator.rb b/lib/afip_bill/generator.rb index 57587f9..1cf272b 100644 --- a/lib/afip_bill/generator.rb +++ b/lib/afip_bill/generator.rb @@ -7,45 +7,80 @@ module AfipBill class Generator - attr_reader :afip_bill, :bill_type, :user, :line_items, :header_text - + attr_reader :afip_bill, :bill_name, :bill_type, :user, :line_items, :header_text + HEADER_PATH = File.dirname(__FILE__) + '/views/shared/_factura_header.html.erb'.freeze FOOTER_PATH = File.dirname(__FILE__) + '/views/shared/_factura_footer.html.erb'.freeze - BRAVO_CBTE_TIPO = { "01" => "Factura A", "06" => "Factura B" }.freeze + BRAVO_CBTE_TIPO = { + '01' => { directory: 'bills', template: 'factura_a', doc_name: 'factura', doc_type: 'a' }, + '02' => { directory: 'bills', template: 'factura_a', doc_name: 'Nota de débito', doc_type: 'a' }, + '03' => { directory: 'bills', template: 'factura_a', doc_name: 'Nota de crédito', doc_type: 'a' }, + '06' => { directory: 'bills', template: 'factura_b', doc_name: 'factura', doc_type: 'b' }, + '07' => { directory: 'bills', template: 'factura_b', doc_name: 'Nota de débito', doc_type: 'b' }, + '08' => { directory: 'bills', template: 'factura_b', doc_name: 'Nota de crédito', doc_type: 'b' }, + '11' => { directory: 'bills', template: 'factura_b', doc_name: 'factura', doc_type: 'c' }, + '12' => { directory: 'bills', template: 'factura_b', doc_name: 'Nota de débito', doc_type: 'c' }, + '13' => { directory: 'bills', template: 'factura_b', doc_name: 'Nota de crédito', doc_type: 'c' } + }.freeze IVA = 21.freeze + DEFAULTS = { + "cond_venta" => 'Otra' + }.freeze def initialize(bill, user, line_items = [], header_text = 'ORIGINAL') - @afip_bill = JSON.parse(bill) + @afip_bill = DEFAULTS.merge(JSON.parse(bill)) @user = user - @bill_type = type_a_or_b_bill + @bill_name = bill_name_s + @bill_type = bill_type_s @line_items = line_items @template_header = ERB.new(File.read(HEADER_PATH)).result(binding) @template_footer = ERB.new(File.read(FOOTER_PATH)).result(binding) @header_text = header_text end - def type_a_or_b_bill - BRAVO_CBTE_TIPO[afip_bill["cbte_tipo"]][-1].downcase + def bill_name_s + BRAVO_CBTE_TIPO[afip_bill["cbte_tipo"]][:doc_name].capitalize + end + + def bill_type_s + BRAVO_CBTE_TIPO[afip_bill["cbte_tipo"]][:doc_type] end def barcode @barcode ||= Barby::Code25Interleaved.new(code_numbers) end + def pdfkit_options + { + zoom: '1.65', + 'margin-bottom': '0.05in', + 'margin-top': '0.05in', + 'margin-left': '0.2in', + 'margin-right': '0.2in' + } + end + def generate_pdf_file tempfile = Tempfile.new("afip_bill.pdf") - - PDFKit.new(template).to_file(tempfile.path) + PDFKit.new(template, pdfkit_options).to_file(tempfile.path) end def generate_pdf_string - PDFKit.new(template).to_pdf + PDFKit.new(template, pdfkit_options).to_pdf end private def bill_path - File.dirname(__FILE__) + "/views/bills/factura_#{bill_type}.html.erb" + File.dirname(__FILE__) + "/views/#{template_directory}/#{template_name}.html.erb" + end + + def template_name + BRAVO_CBTE_TIPO[afip_bill["cbte_tipo"]][:template] + end + + def template_directory + BRAVO_CBTE_TIPO[afip_bill["cbte_tipo"]][:directory] end def code_numbers diff --git a/lib/afip_bill/line_item.rb b/lib/afip_bill/line_item.rb index c1425cd..94a9d9d 100644 --- a/lib/afip_bill/line_item.rb +++ b/lib/afip_bill/line_item.rb @@ -1,12 +1,16 @@ module AfipBill class LineItem - attr_reader :name, :quantity, :imp_unitario - IVA = 21.freeze + attr_reader :name, :quantity, :imp_unitario, :iva, :code, :discount_percentage1, :discount_percentage2, :base_price - def initialize(name, quantity, imp_unitario) + def initialize(name, quantity, imp_unitario, iva=21, code=nil, discount_percentage1=nil, discount_percentage2=nil, base_price=nil) @name = name @quantity = quantity @imp_unitario = imp_unitario + @iva = iva + @code = code + @discount_percentage1 = discount_percentage1 + @discount_percentage2 = discount_percentage2 + @base_price = base_price end def imp_total_unitario @@ -14,7 +18,7 @@ def imp_total_unitario end def imp_iva - imp_total_unitario * IVA / 100 + imp_total_unitario * iva / 100 end def imp_total_unitario_con_iva diff --git a/lib/afip_bill/views/bills/factura_a.html.erb b/lib/afip_bill/views/bills/factura_a.html.erb index b51ed0b..d0f03eb 100644 --- a/lib/afip_bill/views/bills/factura_a.html.erb +++ b/lib/afip_bill/views/bills/factura_a.html.erb @@ -1,55 +1,91 @@ <%= @template_header %> -
Alicuota
Código
-
Producto / Servicio
-
Cantidad
-
U. medida
-
Precio Unit.
-
% Bonif
-
Subtotal
-
Subtotal c/IVA
-
IVA
+
Producto / Servicio
+
Cant.
+ +
Precio Unit.
+ +<% unless AfipBill.configuration[:invoice_discounts_mode].present? %> + +
Subtotal
+
Alicuota
IVA
+
Subtotal
c/IVA
+<% else %> +
Bonif 1
+
Bonif 2
+
Subtotal
s/IVA
+<% end %> <% top = 283 %> -<% @line_items.each_with_index do |line_item, index| %> -
<%= (index + 1).to_s.rjust(3, "0") %>
-
<%= line_item.name %>
-
<%= line_item.quantity.to_s.tr(".", ",") %>
-
unidades
-
<%= line_item.imp_unitario.to_s.tr(".", ",") %>
-
0,00
-
<%= line_item.imp_total_unitario.round(2).to_s.tr(".", ",") %>
-
21%
-
<%= line_item.imp_total_unitario_con_iva.round(2).to_s.tr(".", ",") %>
- <% top += 25 %> + +<% @line_items.each_with_index do |line_item, index| + item_code = line_item.code || (index + 1).to_s.rjust(3, "0") + small_code = item_code.length > 8 + precio_unitario = ('%.2f' % line_item.imp_unitario).to_s.tr(".", ",") + subtotal = ('%.2f' % line_item.imp_total_unitario).to_s.tr(".", ",") + alic_iva = ('%.2f' % line_item.iva).to_s.tr(".", ",") + subtotal_con_iva = ('%.2f' % line_item.imp_total_unitario_con_iva).to_s.tr(".", ",") + + if AfipBill.configuration[:invoice_discounts_mode].present? + #monto_descuento = ('%.2f' % line_item.discount_value).to_s.tr(".", ",") + perc_descuento1 = line_item.discount_percentage1 + perc_descuento2 = line_item.discount_percentage2 + precio_base = line_item.base_price + end + %> +
"><%= item_code %>
+
<%= line_item.name %>
+
<%= line_item.quantity.to_s.tr(".", ",") %>
+ + + +<% unless AfipBill.configuration[:invoice_discounts_mode].present? %> +
<%= precio_unitario %>
+ +
<%= subtotal %>
+
<%= alic_iva %>%
+
<%= subtotal_con_iva %>
+<% else %> +
<%= precio_base %>
+
<%= perc_descuento1 %>%
+
<%= perc_descuento2 %>%
+
<%= subtotal %>
<% end %> -
Otros Tributos
-
Descripción
-
Detalle
-
Alíc. %
-
Importe
-
Per./Ret. de Impuesto a las Ganancias
-
0,00
-
Per./Ret. de IVA
-
0,00
+ + <% top += 15 %> +<% end %> + +
+ <%= afip_bill["custom_text"] %> +
+ +
Otros Tributos
+
Descripción
+
Detalle
+
Alíc. %
+
Importe
+
Per./Ret. de Impuesto a las Ganancias
+
0,00
+
Per./Ret. de IVA
+
0,00
Importe Neto Gravado: $
<%= afip_bill["imp_neto"] %>
-
Per./Ret. Ingresos Brutos
-
0,00
+
Per./Ret. Ingresos Brutos
+
0,00
IVA 27%: $
0,00
-
Impuestos Internos
-
0,00
-
Impuestos Municipales
-
0,00
+
Impuestos Internos
+
0,00
+
Impuestos Municipales
+
0,00
IVA 21%: $
-
<%= afip_bill["imp_iva"] %>
-
Importe Otros Tributos: $
-
0,00
-
IVA 10.5%: $
-
0,00
+
<%= afip_bill["imp_iva_21"] %>
+
Importe Otros Tributos: $
+
0,00
+
IVA 10.5%: $
+
<%= afip_bill["imp_iva_105"] %>
IVA 5%: $
0,00
IVA 2.5%: $
diff --git a/lib/afip_bill/views/bills/factura_b.html.erb b/lib/afip_bill/views/bills/factura_b.html.erb index ebe0f77..a7961e6 100644 --- a/lib/afip_bill/views/bills/factura_b.html.erb +++ b/lib/afip_bill/views/bills/factura_b.html.erb @@ -1,32 +1,45 @@ <%= @template_header %> -
Código
-
Producto / Servicio
-
Cantidad
-
U. Medida
-
Precio Unit.
-
% Bonif
-
Imp. Bonif.
-
Subtotal
+
Código
+
Producto / Servicio
+
Cant.
+ +
Precio Unit.
+ +
Subtotal
-<% top = 293 %> - <% @line_items.each_with_index do |line_item, index| %> -
<%= (index + 1).to_s.rjust(3, "0") %>
-
<%= line_item.name %>
-
<%= line_item.quantity.round(2).to_s.tr(".", ",") %>
-
unidades
-
<%= line_item.imp_unitario.round(2).to_s.tr(".", ",") %>
-
0,00
-
0,00
-
<%= line_item.imp_total_unitario.round(2).to_s.tr(".", ",") %>
- <% top += 25 %> +<% top = 288 %> + <% @line_items.each_with_index do |line_item, index| + item_code = line_item.code || (index + 1).to_s.rjust(3, "0") + small_code = item_code.length > 8 + precio_unitario = ('%.2f' % line_item.imp_unitario).to_s.tr(".", ",") + subtotal = ('%.2f' % line_item.imp_total_unitario).to_s.tr(".", ",") + %> +
+ "><%= item_code %> +
+
<%= line_item.name %>
+
<%= line_item.quantity.round(2).to_s.tr(".", ",") %>
+ +
<%= precio_unitario %>
+ +
<%= subtotal %>
+ <% top += 15 %> <% end %> -
Subtotal: $
-
<%= afip_bill["imp_total"] %>
+
+ <%= afip_bill["custom_text"] %> +
+ +
+ Subtotal: $ +
+
<%= afip_bill["imp_total"] %>
Importe Otros Tributos: $
-
0,00
+
0,00
Importe Total: $
-
<%= afip_bill["imp_total"] %>
+
<%= afip_bill["imp_total"] %>
<%= @template_footer %> diff --git a/lib/afip_bill/views/notes/nota_a.html.erb b/lib/afip_bill/views/notes/nota_a.html.erb new file mode 100644 index 0000000..59e6a8d --- /dev/null +++ b/lib/afip_bill/views/notes/nota_a.html.erb @@ -0,0 +1,69 @@ +<%= @template_header %> + +
Alicuota
+
Código
+
Producto / Servicio
+
Cant.
+ +
Precio Unit.
+ +
Subtotal
+
Subtotal c/IVA
+
IVA
+ +<% top = 283 %> +<% @line_items.each_with_index do |line_item, index| + precio_unitario = ('%.2f' % line_item.imp_unitario).to_s.tr(".", ",") + subtotal = ('%.2f' % line_item.imp_total_unitario).to_s.tr(".", ",") + alic_iva = ('%.2f' % line_item.iva).to_s.tr(".", ",") + subtotal_con_iva = ('%.2f' % line_item.imp_total_unitario_con_iva).to_s.tr(".", ",") + %> +
<%= (index + 1).to_s.rjust(3, "0") %>
+
<%= line_item.name %>
+
<%= line_item.quantity.to_s.tr(".", ",") %>
+ +
<%= precio_unitario %>
+ +
<%= subtotal %>
+
<%= alic_iva %>%
+
<%= subtotal_con_iva %>
+ <% top += 25 %> +<% end %> + +
Otros Tributos
+
Descripción
+
Detalle
+
Alíc. %
+
Importe
+
Per./Ret. de Impuesto a las Ganancias
+
0,00
+
Per./Ret. de IVA
+
0,00
+
Importe Neto Gravado: $
+
<%= afip_bill["imp_neto"] %>
+
Per./Ret. Ingresos Brutos
+
0,00
+
IVA 27%: $
+
0,00
+
Impuestos Internos
+
0,00
+
Impuestos Municipales
+
0,00
+
IVA 21%: $
+
<%= afip_bill["imp_iva_21"] %>
+
Importe Otros Tributos: $
+
0,00
+
IVA 10.5%: $
+
<%= afip_bill["imp_iva_105"] %>
+
IVA 5%: $
+
0,00
+
IVA 2.5%: $
+
0,00
+
IVA 0%: $
+
0,00
+
Importe Otros Tributos: $
+
0,00
+
Importe Total: $
+
<%= afip_bill["imp_total"] %>
+ +<%= @template_footer %> diff --git a/lib/afip_bill/views/notes/nota_b.html.erb b/lib/afip_bill/views/notes/nota_b.html.erb new file mode 100644 index 0000000..e877b05 --- /dev/null +++ b/lib/afip_bill/views/notes/nota_b.html.erb @@ -0,0 +1,35 @@ +<%= @template_header %> + +
Código
+
Producto / Servicio
+
Cantidad
+ +
Precio Unit.
+ + +
Subtotal
+ +<% top = 293 %> + <% @line_items.each_with_index do |line_item, index| + precio_unitario = ('%.2f' % line_item.imp_unitario).to_s.tr(".", ",") + subtotal = ('%.2f' % line_item.imp_total_unitario).to_s.tr(".", ",") + %> +
<%= (index + 1).to_s.rjust(3, "0") %>
+
<%= line_item.name %>
+
<%= line_item.quantity.round(2).to_s.tr(".", ",") %>
+ +
<%= precio_unitario %>
+ + +
<%= subtotal %>
+ <% top += 25 %> +<% end %> + +
Subtotal: $
+
<%= afip_bill["imp_total"] %>
+
Importe Otros Tributos: $
+
0,00
+
Importe Total: $
+
<%= afip_bill["imp_total"] %>
+ +<%= @template_footer %> diff --git a/lib/afip_bill/views/shared/_factura_footer.html.erb b/lib/afip_bill/views/shared/_factura_footer.html.erb index 6f99c49..a247768 100644 --- a/lib/afip_bill/views/shared/_factura_footer.html.erb +++ b/lib/afip_bill/views/shared/_factura_footer.html.erb @@ -1,16 +1,30 @@
Pág. 1/1
Comprobante Autorizado
-
CAE N°: <%= afip_bill["cae"] %>
+
Esta Administración Federal no se responsabiliza por los datos ingresados en el detalle de la operación
-
Fecha de Vto. de CAE:
-
<%= Date.parse(afip_bill["fch_vto_pago"]).strftime("%d/%m/%Y") %>
-
<%= barcode.data %>
-
- <%= barcode.to_html %> +
+ CAE N°:
+ <%= afip_bill["cae"] %>
+
Fecha de Vto. de CAE:
+ +
+ <%= Date.parse(afip_bill["fch_vto_cae"]).strftime("%d/%m/%Y") %>
+ +
<%= barcode.data %>
+
+ <%= barcode.to_html %> +
+ +<% if afip_bill["qr_png"] %> +
+ "> +
+<% end %> + diff --git a/lib/afip_bill/views/shared/_factura_header.html.erb b/lib/afip_bill/views/shared/_factura_header.html.erb index d4c5b0e..ec78e0e 100644 --- a/lib/afip_bill/views/shared/_factura_header.html.erb +++ b/lib/afip_bill/views/shared/_factura_header.html.erb @@ -29,6 +29,7 @@ } body { line-height: 1; + width: 595px !important; } ol, ul { list-style: none; @@ -54,9 +55,11 @@ margin-left: -297px; top: 0px; width: 595px; - height: 842px; + width: 100%; + height: 790px; + max-height: 790px; overflow: hidden; - border: 1px solid grey; + border: none; } span.cls_003, div.cls_003, span.cls_009, div.cls_009, span.cls_004, div.cls_004, span.cls_010, div.cls_010, @@ -159,36 +162,81 @@
<%= header_text %>
-
<%= bill_type.upcase %>
-
FACTURA
-
<%= AfipBill.configuration[:header_business_name] || AfipBill.configuration[:business_name] %>
-
COD. 01
-
Punto de Venta:
+
<%= bill_type.upcase %>
+
<%= bill_name.upcase %>
+ <% if AfipBill.configuration[:logo_path].present? %> +
+ +
+ <% else %> +
+ + <%= AfipBill.configuration[:header_business_name] || AfipBill.configuration[:business_name] %> + +
+ <% end %> +
COD. <%= afip_bill["cbte_tipo"] %>
+
Punto de Venta:
<%= AfipBill.configuration[:sale_point] %>
Comp. Nro:
<%= afip_bill["cbte_hasta"].to_s.rjust(8, "0") %>
Razón Social: <%= AfipBill.configuration[:business_name] %>
-
Fecha de Emisión:
+
Fecha de Emisión:
<%= Date.parse(afip_bill["cbte_fch"]).strftime("%d/%m/%Y") %>
-
Domicilio Comercial: <%= AfipBill.configuration[:business_address] %>
+
Domicilio Comercial: <%= AfipBill.configuration[:business_address] %>
CUIT:
<%= AfipBill.configuration[:business_cuit] %>
<%= AfipBill.configuration[:city] %>
Ingresos Brutos:
<%= AfipBill.configuration[:ingresos_brutos] %>
-
Fecha de Inicio de Actividades:
+
Fecha de Inicio de Actividades:
<%= AfipBill.configuration[:business_start_date] %>
-
Condición frente al IVA: <%= AfipBill.configuration[:iva] %>
-
Período Facturado Desde:
-
<%= Date.parse(afip_bill["fch_serv_desde"]).strftime("%d/%m/%Y") %>
-
Hasta:<%= Date.parse(afip_bill["fch_serv_hasta"]).strftime("%d/%m/%Y") %>
-
Fecha de Vto. para el pago:
-
<%= Date.parse(afip_bill["fch_serv_hasta"]).strftime("%d/%m/%Y") %>
-
CUIT:
-
<%= afip_bill["doc_num"] %>
-
Apellido y Nombre / Razón Social:
-
<%= bill_type == "a" ? user.company_name : user.owner_name %>
-
Condición frente al IVA:
+
Condición frente al IVA: <%= AfipBill.configuration[:iva] %>
+ + <% if afip_bill["fch_serv_desde"].present? %> +
Período Facturado Desde:
+
<%= Date.parse(afip_bill["fch_serv_desde"]).strftime("%d/%m/%Y") %>
+ <% end %> + <% if afip_bill["fch_serv_hasta"].present? %> +
Hasta:<%= Date.parse(afip_bill["fch_serv_hasta"]).strftime("%d/%m/%Y") %>
+ <% end %> + <% if afip_bill["fch_vto_pago"].present? %> +
+ Fecha de Vto. para el pago: + <%= Date.parse(afip_bill["fch_vto_pago"]).strftime("%d/%m/%Y") %> +
+ <% end %> + +
+
CUIT:
+
<%= afip_bill["doc_num"] %>
+
Apellido y Nombre / Razón Social:
+
<%= bill_type == "a" ? user.company_name : user.owner_name %>
+
Condición frente al IVA:
<%= user.tax_category %>
-
Domicilio Comercial: <%= user.address %>
-
Condición de venta: Otra
+ +
+ Domicilio Comercial: +
+
+ + <%= user.address %> + +
+ +
Condición de venta: <%= afip_bill["cond_venta"] %>
+ + <% if afip_bill["header_obs"].present? %> +
<%= afip_bill["header_obs"].split(":").first %>: <%= afip_bill["header_obs"].split(":").second %>
+ <% end %> + + <%if afip_bill["related_invoice"].present? %> +
+ Fac. <%= afip_bill["related_invoice"]["type"].upcase %>: +
+
+ + <%= afip_bill["related_invoice"]["number"] %> + +
+ <%end%>