fm_layout 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,306 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'DSL para generar el layout de Facturación moderna' do
5
+ context 'factura' do
6
+ context 'llenando todos los campos' do
7
+ let(:hora) {Time.now.strftime("%FT%T")}
8
+ let(:prueba) do
9
+ # DSL
10
+ FmLayout.define_layout do |f|
11
+ f.encabezado do |e|
12
+ e.serie 'A'
13
+ e.folio 10
14
+ e.fecha hora
15
+ e.tipo_de_comprobante 'ingreso'
16
+ e.forma_de_pago 'PAGO EN UNA SOLA EXHIBICIÓN'
17
+ e.metodo_de_pago 'Transferencia Electrónica'
18
+ e.condiciones_de_pago 'Contado'
19
+ e.numero_de_cuenta_de_pago '0098-HSBC'
20
+ e.subtotal 100.00
21
+ e.descuento 0.00
22
+ e.total 116.00
23
+ e.moneda 'MXN'
24
+ e.tipo_de_cambio 1.0
25
+ e.numero_de_certificado '111222111'
26
+ e.lugar_de_expedicion 'Nuevo León, México'
27
+ end
28
+ f.datos_adicionales do |d|
29
+ d.tipo_de_documento 'Factura'
30
+ d.numero_de_pedido '123456'
31
+ d.observaciones 'Efectos Fiscales al Pago'
32
+ end
33
+ f.emisor do |e|
34
+ e.rfc 'TUMG620310R95'
35
+ e.nombre 'FACTURACION MODERNA S.A de C.V.'
36
+ e.regimen_fiscal 'REGIMEN GENERAL DE LEY PERSONAS MORALES'
37
+ end
38
+ f.domicilio_fiscal do |d|
39
+ d.calle 'Calle 1'
40
+ d.numero_exterior 'Número Exterior'
41
+ d.numero_interior 'Número Interior'
42
+ d.colonia 'Colonia'
43
+ d.localidad 'Localidad'
44
+ d.municipio 'Municipio'
45
+ d.estado 'NUEVO LEON'
46
+ d.pais 'México'
47
+ d.codigo_postal '66260'
48
+ end
49
+ f.expedido_en do |d|
50
+ d.calle 'Calle 2'
51
+ d.numero_exterior 'Número Exterior 2'
52
+ d.numero_interior 'Número Interior 2'
53
+ d.colonia 'Colonia 2'
54
+ d.localidad 'Localidad 2'
55
+ d.municipio 'Municipio 2'
56
+ d.estado 'OAXACA'
57
+ d.pais 'México'
58
+ d.codigo_postal '68000'
59
+ end
60
+ f.receptor do |r|
61
+ r.rfc 'XAXX010101000'
62
+ r.nombre 'PUBLICO EN GENERAL'
63
+ r.numero_de_cliente '987654'
64
+ r.email 'soporte@facturacionmoderna.com'
65
+ end
66
+ f.domicilio do |d|
67
+ d.calle 'Calle 3'
68
+ d.numero_exterior 'Número Exterior 3'
69
+ d.numero_interior 'Número Interior 3'
70
+ d.colonia 'Colonia 3'
71
+ d.localidad 'Localidad 3'
72
+ d.municipio 'Municipio 3'
73
+ d.estado 'PUEBLA'
74
+ d.pais 'México'
75
+ d.codigo_postal '72500'
76
+ end
77
+ f.concepto do |c|
78
+ c.cantidad 1
79
+ c.unidad 'No Aplica'
80
+ c.numero_de_identificacion '111222333'
81
+ c.descripcion 'Caja Hojas Blancas Tamaño Carta'
82
+ c.valor_unitario 100.00
83
+ c.importe 100.00
84
+ c.cuenta_predial '123-132123'
85
+ end
86
+ f.concepto do |c|
87
+ c.cantidad 2
88
+ c.unidad 'mts'
89
+ c.numero_de_identificacion '1111'
90
+ c.descripcion 'Plástico para forrar libros'
91
+ c.valor_unitario 10.00
92
+ c.importe 20.00
93
+ end
94
+ f.impuesto_trasladado do |i|
95
+ i.impuesto 'IVA'
96
+ i.importe 150.00
97
+ i.tasa 16.00
98
+ end
99
+
100
+ f.impuesto_retenido do |i|
101
+ i.impuesto 'IVA'
102
+ i.importe 100.00
103
+ end
104
+
105
+ f.impuesto_retenido do |i|
106
+ i.impuesto 'ISR'
107
+ i.importe 10.00
108
+ end
109
+ end
110
+ end
111
+
112
+ context 'encabezado' do
113
+ let(:encabezado){ prueba.to_h['Encabezado'] }
114
+ it{ expect(encabezado['serie']).to eq('A') }
115
+ it{ expect(encabezado['folio']).to eq(10) }
116
+ it{ expect(encabezado['fecha']).to eq(hora) }
117
+ it{ expect(encabezado['tipoDeComprobante']).to eq('ingreso') }
118
+ it{ expect(encabezado['formaDePago']).to eq('PAGO EN UNA SOLA EXHIBICIÓN') }
119
+ it{ expect(encabezado['condicionesDePago']).to eq('Contado') }
120
+ it{ expect(encabezado['subTotal']).to eq(100.00) }
121
+ it{ expect(encabezado['descuento']).to eq(0.00) }
122
+ it{ expect(encabezado['total']).to eq(116.00) }
123
+ it{ expect(encabezado['Moneda']).to eq('MXN') }
124
+ it{ expect(encabezado['TipoCambio']).to eq(1.0) }
125
+ it{ expect(encabezado['noCertificado']).to eq('111222111') }
126
+ it{ expect(encabezado['LugarExpedicion']).to eq('Nuevo León, México') }
127
+ end
128
+
129
+ context 'datos adicionales' do
130
+ let(:datos_adicionales){ prueba.to_h['Datos Adicionales'] }
131
+ it{ expect(datos_adicionales['tipoDocumento']).to eq('Factura') }
132
+ it{ expect(datos_adicionales['numeropedido']).to eq('123456') }
133
+ it{ expect(datos_adicionales['observaciones']).to eq('Efectos Fiscales al Pago') }
134
+ end
135
+
136
+ context 'emisor' do
137
+ let(:emisor){ prueba.to_h['Emisor'] }
138
+ it{ expect(emisor['rfc']).to eq('TUMG620310R95') }
139
+ it{ expect(emisor['nombre']).to eq('FACTURACION MODERNA S.A de C.V.') }
140
+ it{ expect(emisor['RegimenFiscal']).to eq('REGIMEN GENERAL DE LEY PERSONAS MORALES') }
141
+ end
142
+
143
+ context 'domicilio fiscal' do
144
+ let(:domicilio_fiscal){ prueba.to_h['DomicilioFiscal'] }
145
+ it{ expect(domicilio_fiscal['calle']).to eq('Calle 1') }
146
+ it{ expect(domicilio_fiscal['noExterior']).to eq('Número Exterior') }
147
+ it{ expect(domicilio_fiscal['noInterior']).to eq('Número Interior') }
148
+ it{ expect(domicilio_fiscal['colonia']).to eq('Colonia') }
149
+ it{ expect(domicilio_fiscal['localidad']).to eq('Localidad') }
150
+ it{ expect(domicilio_fiscal['municipio']).to eq('Municipio') }
151
+ it{ expect(domicilio_fiscal['estado']).to eq('NUEVO LEON') }
152
+ it{ expect(domicilio_fiscal['pais']).to eq('México') }
153
+ it{ expect(domicilio_fiscal['codigoPostal']).to eq('66260') }
154
+ end
155
+
156
+ context 'expedido en' do
157
+ let(:expedido_en){ prueba.to_h['ExpedidoEn'] }
158
+ it{ expect(expedido_en['calle']).to eq('Calle 2') }
159
+ it{ expect(expedido_en['noExterior']).to eq('Número Exterior 2') }
160
+ it{ expect(expedido_en['noInterior']).to eq('Número Interior 2') }
161
+ it{ expect(expedido_en['colonia']).to eq('Colonia 2') }
162
+ it{ expect(expedido_en['localidad']).to eq('Localidad 2') }
163
+ it{ expect(expedido_en['municipio']).to eq('Municipio 2') }
164
+ it{ expect(expedido_en['estado']).to eq('OAXACA') }
165
+ it{ expect(expedido_en['pais']).to eq('México') }
166
+ it{ expect(expedido_en['codigoPostal']).to eq('68000') }
167
+ end
168
+
169
+ context 'receptor' do
170
+ let(:receptor){ prueba.to_h['Receptor'] }
171
+ it{ expect(receptor['rfc']).to eq('XAXX010101000') }
172
+ it{ expect(receptor['nombre']).to eq('PUBLICO EN GENERAL') }
173
+ it{ expect(receptor['NumCliente']).to eq('987654') }
174
+ it{ expect(receptor['emailCliente']).to eq('soporte@facturacionmoderna.com') }
175
+ end
176
+
177
+ context 'domilicio' do
178
+ let(:domicilio){ prueba.to_h['Domicilio'] }
179
+ it{ expect(domicilio['calle']).to eq('Calle 3') }
180
+ it{ expect(domicilio['noExterior']).to eq('Número Exterior 3') }
181
+ it{ expect(domicilio['noInterior']).to eq('Número Interior 3') }
182
+ it{ expect(domicilio['colonia']).to eq('Colonia 3') }
183
+ it{ expect(domicilio['localidad']).to eq('Localidad 3') }
184
+ it{ expect(domicilio['municipio']).to eq('Municipio 3') }
185
+ it{ expect(domicilio['estado']).to eq('PUEBLA') }
186
+ it{ expect(domicilio['pais']).to eq('México') }
187
+ it{ expect(domicilio['codigoPostal']).to eq('72500') }
188
+ end
189
+
190
+ context 'primer concepto' do
191
+ let(:concepto){ prueba.to_h['Conceptos'].first['Concepto'] }
192
+ it{ expect(concepto['cantidad']).to eq(1) }
193
+ it{ expect(concepto['unidad']).to eq('No Aplica') }
194
+ it{ expect(concepto['noIdentificacion']).to eq('111222333') }
195
+ it{ expect(concepto['descripcion']).to eq('Caja Hojas Blancas Tamaño Carta') }
196
+ it{ expect(concepto['valorUnitario']).to eq(100.00) }
197
+ it{ expect(concepto['importe']).to eq(100.00) }
198
+ it{ expect(concepto['CuentaPredial']).to eq('123-132123') }
199
+ end
200
+
201
+ context 'segundo concepto' do
202
+ let(:concepto){ prueba.to_h['Conceptos'].last['Concepto'] }
203
+ it{ expect(concepto['cantidad']).to eq(2) }
204
+ it{ expect(concepto['unidad']).to eq('mts') }
205
+ it{ expect(concepto['noIdentificacion']).to eq('1111') }
206
+ it{ expect(concepto['descripcion']).to eq('Plástico para forrar libros') }
207
+ it{ expect(concepto['valorUnitario']).to eq(10.00) }
208
+ it{ expect(concepto['importe']).to eq(20.00) }
209
+ it{ expect(concepto['CuentaPredial']).to eq(nil) }
210
+ end
211
+
212
+ context 'primer impuesto trasladado' do
213
+ let(:traslado){ prueba.to_h['ImpuestosTrasladados'].first['ImpuestoTrasladado'] }
214
+ it{ expect(traslado['impuesto']).to eq('IVA') }
215
+ it{ expect(traslado['importe']).to eq(150.00) }
216
+ it{ expect(traslado['tasa']).to eq(16.00) }
217
+ end
218
+
219
+ context 'primer impuesto retenido' do
220
+ let(:retencion){ prueba.to_h['ImpuestosRetenidos'].first['ImpuestoRetenido'] }
221
+ it{ expect(retencion['impuesto']).to eq('IVA') }
222
+ it{ expect(retencion['importe']).to eq(100.00) }
223
+ end
224
+
225
+ context 'segundo impuesto retenido' do
226
+ let(:retencion){ prueba.to_h['ImpuestosRetenidos'].last['ImpuestoRetenido'] }
227
+ it{ expect(retencion['impuesto']).to eq('ISR') }
228
+ it{ expect(retencion['importe']).to eq(10.00) }
229
+ end
230
+
231
+ context 'salida en texto' do
232
+ let(:salida){ prueba.to_s }
233
+ it{ expect(salida).to match(/\[Encabezado\]/) }
234
+ it{ expect(salida).to match(/\[Datos Adicionales\]/) }
235
+ it{ expect(salida).to match(/\[Emisor\]/) }
236
+ it{ expect(salida).to match(/\[DomicilioFiscal\]/) }
237
+ it{ expect(salida).to match(/\[ExpedidoEn\]/) }
238
+ it{ expect(salida).to match(/\[Receptor\]/) }
239
+ it{ expect(salida).to match(/\[Domicilio\]/) }
240
+ it{ expect(salida).to match(/\[Concepto\]/) }
241
+ it{ expect(salida).to match(/\[ImpuestoTrasladado\]/) }
242
+ it{ expect(salida).to match(/\[ImpuestoRetenido\]/) }
243
+ end
244
+ end
245
+
246
+ context 'llenado sin campos' do
247
+ let(:prueba) do
248
+ # DSL
249
+ FmLayout.define_layout do |f|
250
+ f.encabezado do |e|
251
+ end
252
+ f.datos_adicionales do |d|
253
+ end
254
+ f.emisor do |e|
255
+ end
256
+ f.receptor do |r|
257
+ end
258
+ f.domicilio do |d|
259
+ end
260
+ f.concepto do |c|
261
+ end
262
+ f.impuesto_trasladado do |i|
263
+ end
264
+ f.impuesto_retenido do |i|
265
+ end
266
+ end
267
+ end
268
+
269
+ context 'encabezado' do
270
+ let(:encabezado){ prueba.to_h['Encabezado'] }
271
+ it{ expect(encabezado['fecha']).to eq('asignarFecha') }
272
+ it{ expect(encabezado['folio']).to eq('asignarFolio') }
273
+ end
274
+
275
+ context 'datos adicionales' do
276
+ let(:datos_adicionales){ prueba.to_h['Datos Adicionales'] }
277
+ it{ expect(datos_adicionales['tipoDocumento']).to eq('Factura') }
278
+ end
279
+
280
+ context 'domicilio fiscal' do
281
+ let(:domicilio){ prueba.to_h['Domicilio'] }
282
+ it{ expect(domicilio['pais']).to eq('México') }
283
+ end
284
+
285
+ context 'primer concepto' do
286
+ let(:concepto){ prueba.to_h['Conceptos'].first['Concepto'] }
287
+ it{ expect(concepto['cantidad']).to eq(1) }
288
+ end
289
+
290
+ context 'salida en texto' do
291
+ let(:salida){ prueba.to_s }
292
+ it{ expect(salida).to match(/\[Encabezado\]/) }
293
+ it{ expect(salida).to match(/\[Datos Adicionales\]/) }
294
+ it{ expect(salida).to match(/\[Emisor\]/) }
295
+ it{ expect(salida).not_to match(/\[DomicilioFiscal\]/) }
296
+ it{ expect(salida).not_to match(/\[ExpedidoEn\]/) }
297
+ it{ expect(salida).to match(/\[Receptor\]/) }
298
+ it{ expect(salida).to match(/\[Domicilio\]/) }
299
+ it{ expect(salida).to match(/\[Concepto\]/) }
300
+ it{ expect(salida).to match(/\[ImpuestoTrasladado\]/) }
301
+ it{ expect(salida).to match(/\[ImpuestoRetenido\]/) }
302
+ end
303
+
304
+ end
305
+ end
306
+ end
@@ -0,0 +1,4 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
4
+ require 'fm_layout'
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fm_layout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Hermes Ojeda Ruiz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Generador del Layout para la conexión con Facturación Moderna a través
56
+ de un DSL
57
+ email:
58
+ - hermes.ojeda@logicalbricks.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - .gitignore
64
+ - .rspec
65
+ - .travis.yml
66
+ - Gemfile
67
+ - LICENSE
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - fm_layout.gemspec
72
+ - lib/fm_layout.rb
73
+ - lib/fm_layout/concepto.rb
74
+ - lib/fm_layout/datos_adicionales.rb
75
+ - lib/fm_layout/domicilio.rb
76
+ - lib/fm_layout/emisor.rb
77
+ - lib/fm_layout/encabezado.rb
78
+ - lib/fm_layout/fm_layout.rb
79
+ - lib/fm_layout/fm_seccion.rb
80
+ - lib/fm_layout/impuesto_retenido.rb
81
+ - lib/fm_layout/impuesto_trasladado.rb
82
+ - lib/fm_layout/nomina/complemento_nomina.rb
83
+ - lib/fm_layout/nomina/deduccion.rb
84
+ - lib/fm_layout/nomina/horas_extra.rb
85
+ - lib/fm_layout/nomina/incapacidad.rb
86
+ - lib/fm_layout/nomina/nomina.rb
87
+ - lib/fm_layout/nomina/percepcion.rb
88
+ - lib/fm_layout/receptor.rb
89
+ - lib/fm_layout/version.rb
90
+ - spec/fm_layout_nomina_spec.rb
91
+ - spec/fm_layout_spec.rb
92
+ - spec/spec_helper.rb
93
+ homepage: ''
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.1.11
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Generador del Layout para la conexión con Facturación Moderna a través de
117
+ un DSL
118
+ test_files:
119
+ - spec/fm_layout_nomina_spec.rb
120
+ - spec/fm_layout_spec.rb
121
+ - spec/spec_helper.rb