~openerp-spain-team/openerp-spain/6.0-git

« back to all changes in this revision

Viewing changes to l10n_es_facturae/wizard/create_facturae.py

  • Committer: Borja L.S.
  • Date: 2010-10-18 10:04:25 UTC
  • Revision ID: git-v1:271c47a993616dbba60585d48b8b98d603199d93
[REF] *: Refactorización para portar a 6.0 - Paso 1.

- Se han renombrado los módulos para usar la nomenclatura propuesta
  por OpenERP: l10n_es para el módulo base de localización (plan de 
  cuentas), l10n_es_* para el resto de módulos.

- Se eliminan los módulos extra_addons/* que deberían moverse a 
  los extra-addons genéricos (no son específicos de España).

- Se renombran los __terp__.py por __openerp__.py

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- encoding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (c) 2009 Alejandro Sanchez (http://www.asr-oss.com) All Rights Reserved.
 
6
#                       Alejandro Sanchez <alejandro@asr-oss.com>
 
7
#    $Id$
 
8
#
 
9
#    This program is free software: you can redistribute it and/or modify
 
10
#    it under the terms of the GNU General Public License as published by
 
11
#    the Free Software Foundation, either version 3 of the License, or
 
12
#    (at your option) any later version.
 
13
#
 
14
#    This program is distributed in the hope that it will be useful,
 
15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
#    GNU General Public License for more details.
 
18
#
 
19
#    You should have received a copy of the GNU General Public License
 
20
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
#
 
22
##############################################################################
 
23
 
 
24
import pooler
 
25
import wizard
 
26
import base64
 
27
import mx.DateTime
 
28
from mx.DateTime import now
 
29
import netsvc
 
30
from tools.translate import _
 
31
 
 
32
logger = netsvc.Logger()
 
33
 
 
34
facturae_form = """<?xml version="1.0"?>
 
35
<form string="Create Factura-E">
 
36
    <label string="Do you want to Create Factura-E?"/>
 
37
</form>"""
 
38
 
 
39
facturae_fields = {}
 
40
 
 
41
export_form = """<?xml version="1.0"?>
 
42
<form string="Payment order export">
 
43
    <field name="facturae" filename="facturae_fname"/>
 
44
    <field name="facturae_fname" invisible="1"/>
 
45
    <field name="note" colspan="4" nolabel="1"/>
 
46
</form>"""
 
47
 
 
48
export_fields = {
 
49
    'facturae' : {
 
50
        'string':'Factura-E file',
 
51
        'type':'binary',
 
52
        'required': False,
 
53
        'readonly':True,
 
54
    },
 
55
    'facturae_fname': {'string':'File name', 'type':'char', 'size':64},
 
56
    'note' : {'string':'Log', 'type':'text'},
 
57
}
 
58
 
 
59
def conv_ascii(text):
 
60
    """Convierte vocales accentuadas, ñ y ç a sus caracteres equivalentes ASCII"""
 
61
    old_chars = ['á','é','í','ó','ú','à','è','ì','ò','ù','ä','ë','ï','ö','ü','â','ê','î','ô','û','Á','É','Í','Ú','Ó','À','È','Ì','Ò','Ù','Ä','Ë','Ï','Ö','Ü','Â','Ê','Î','Ô','Û','ñ','Ñ','ç','Ç','ª','º']
 
62
    new_chars = ['a','e','i','o','u','a','e','i','o','u','a','e','i','o','u','a','e','i','o','u','A','E','I','O','U','A','E','I','O','U','A','E','I','O','U','A','E','I','O','U','n','N','c','C','a','o']
 
63
    for old, new in zip(old_chars, new_chars):
 
64
        text = text.replace(unicode(old,'UTF-8'), new)
 
65
    return text
 
66
 
 
67
class Log(Exception):
 
68
    def __init__(self):
 
69
        self.content = ""
 
70
        self.error = False
 
71
    def add(self, s, error=True):
 
72
        self.content = self.content + s
 
73
        if error:
 
74
            self.error = error
 
75
    def __call__(self):
 
76
        return self.content
 
77
    def __str__(self):
 
78
        return self.content
 
79
 
 
80
 
 
81
def _create_facturae_file(self, cr, uid, data, context):
 
82
 
 
83
    def _format_xml():
 
84
        #formato y definicion del fichero xml
 
85
        texto = '<?xml version="1.0" encoding="UTF-8"?>'
 
86
        texto = '<fe:Facturae xmlns:fe="http://www.facturae.es/Facturae/2007/v3.1/Facturae" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">'
 
87
        return texto
 
88
 
 
89
    def _persona(vat):
 
90
        texto = ''
 
91
        if vat[2:3].isdigit() == True:
 
92
            texto = 'F'
 
93
        else:
 
94
            texto = 'J'
 
95
        return texto
 
96
 
 
97
    def _apoyo_batch():
 
98
 
 
99
        texto = ''
 
100
        currency = invoice.currency_id
 
101
 
 
102
        texto += '<TotalInvoicesAmount>'
 
103
        texto += '<TotalAmount>' + str('%.2f' % invoice.amount_total) + '</TotalAmount>'
 
104
        texto += '</TotalInvoicesAmount>'
 
105
 
 
106
        texto += '<TotalOutstandingAmount>'
 
107
        texto += '<TotalAmount>' + str('%.2f' % invoice.amount_total) + '</TotalAmount>'
 
108
        texto += '</TotalOutstandingAmount>'
 
109
 
 
110
        texto += '<TotalExecutableAmount>'
 
111
        texto += '<TotalAmount>' + str('%.2f' % invoice.amount_total) + '</TotalAmount>'
 
112
        texto += '</TotalExecutableAmount>'
 
113
        texto += '<InvoiceCurrencyCode>' + currency.code + '</InvoiceCurrencyCode>'
 
114
 
 
115
        return texto
 
116
 
 
117
    def _header_facturae(cr, context):
 
118
 
 
119
        company_partner_obj = invoice.company_id.partner_id        
 
120
 
 
121
        schemaversion = '3.1'
 
122
        modality = 'I'
 
123
        
 
124
        if not invoice.number:
 
125
            log.add(_('User error:\n\nCan not create Factura-E file if invoice has no number.'))
 
126
            raise log
 
127
 
 
128
        if company_partner_obj.vat:
 
129
            BatchIdentifier = invoice.number + company_partner_obj.vat
 
130
        else:
 
131
            log.add(_('User error:\n\nCompany %s has no VAT number.') % (company_partner_obj.name), True)
 
132
            raise log
 
133
 
 
134
        texto = ''
 
135
        texto += '<FileHeader>'
 
136
        texto += '<SchemaVersion>' + schemaversion + '</SchemaVersion>'
 
137
        texto += '<Modality>' + modality + '</Modality>'
 
138
        texto += '<InvoiceIssuerType>EM</InvoiceIssuerType>'
 
139
        texto += '<Batch>'
 
140
        texto += '<BatchIdentifier>' + BatchIdentifier + '</BatchIdentifier>'
 
141
        texto += '<InvoicesCount>1</InvoicesCount>'
 
142
        texto += _apoyo_batch()
 
143
        texto += '</Batch>'
 
144
        texto += '</FileHeader>'
 
145
        return texto
 
146
 
 
147
    def _parties_facturae(cr, context):
 
148
 
 
149
        pool = pooler.get_pool(cr.dbname)
 
150
        company_obj = invoice.company_id
 
151
        company_partner_obj = company_obj.partner_id
 
152
        invoice_partner_obj = invoice.partner_id
 
153
        invoice_partner_address_obj = invoice.address_invoice_id
 
154
 
 
155
        #obtencion direccion company recogemos la de facura adress_get si no encuentra invoice devuelve primera
 
156
        company_address_id = pool.get('res.partner').address_get(cr, uid, [company_obj.partner_id.id], ['invoice'])
 
157
        if not company_address_id['invoice']:
 
158
            log.add(_('User error:\n\nCompany %s does not have an invoicing address.') % (company_partner_obj.name))
 
159
            raise log
 
160
        company_address_obj = pool.get('res.partner.address').browse(cr, uid, company_address_id['invoice'])
 
161
 
 
162
        #obtencion de la direccion del partner
 
163
        partner_address_invoice = invoice.address_invoice_id
 
164
        
 
165
        tipo_seller = _persona(company_partner_obj.vat)
 
166
 
 
167
        if invoice_partner_obj.vat:
 
168
            tipo_buyer = _persona(invoice_partner_obj.vat)
 
169
        else:
 
170
            log.add(_('User error:\n\nPartner %s does not have a VAT number.') % (invoice_partner_obj.name), True)
 
171
            raise log
 
172
        
 
173
        texto = ''
 
174
        texto += '<Parties>'
 
175
        texto += '<SellerParty>'
 
176
        texto += '<TaxIdentification>'
 
177
        texto += '<PersonTypeCode>' + tipo_seller + '</PersonTypeCode>'
 
178
        texto += '<ResidenceTypeCode>U</ResidenceTypeCode>'
 
179
        texto += '<TaxIdentificationNumber>' + company_partner_obj.vat + '</TaxIdentificationNumber>'
 
180
        texto += '</TaxIdentification>'
 
181
        
 
182
        if tipo_seller == 'F':
 
183
            texto += '<Individual>'
 
184
            texto += '<Name>' + invoice_partner_obj.name + '</Name>'
 
185
            texto += '<FirstSurname></FirstSurname>'
 
186
            texto += '<SecondSurname></SecondSurname>'
 
187
        else:
 
188
            texto += '<LegalEntity>'
 
189
            texto += '<CorporateName>' + company_obj.name + '</CorporateName>'
 
190
            texto += '<TradeName>' + company_obj.name + '</TradeName>'
 
191
 
 
192
        #Fijo hasta que se tome una decision no son obligatorios
 
193
        #texto += '<RegistrationData>'
 
194
        #texto += '<Book>1</Book>'
 
195
        #texto += '<RegisterOfCompaniesLocation>12AP22</RegisterOfCompaniesLocation>'
 
196
        #texto += '<Sheet>3</Sheet>'
 
197
        #texto += '<Folio>15</Folio>'
 
198
        #texto += '<Section>2</Section>'
 
199
        #texto += '<Volume>12</Volume>'
 
200
        #texto += '<AdditionalRegistrationData>Sin datos</AdditionalRegistrationData>'
 
201
        #texto += '</RegistrationData>'
 
202
        #fin
 
203
        texto += '<AddressInSpain>'
 
204
        if company_address_obj.street:
 
205
            if company_address_obj.street2:
 
206
                texto += '<Address>' + company_address_obj.street + ' ' + company_address_obj.street2 + '</Address>'
 
207
            else:
 
208
                texto += '<Address>' + company_address_obj.street + '</Address>'
 
209
        else:
 
210
            log.add(_('User error:\n\nCompany %s has no street.') % (company_partner_obj.name), True)
 
211
            raise log
 
212
        if company_address_obj.zip:
 
213
            texto += '<PostCode>' + company_address_obj.zip + '</PostCode>'
 
214
        else:
 
215
            log.add(_('User error:\n\nCompany %s has no zip code.') % (company_partner_obj.name), True)
 
216
            raise log
 
217
        if company_address_obj.city:
 
218
            texto += '<Town>' + company_address_obj.city + '</Town>'
 
219
        else:
 
220
            log.add(_('User error:\n\nCompany %s has no city.') % (company_partner_obj.name), True)
 
221
            raise log
 
222
        if  company_address_obj.state_id.name:
 
223
            texto += '<Province>' + company_address_obj.state_id.name + '</Province>'
 
224
        else:
 
225
            log.add(_('User error:\n\nCompany %s has no province.') % (company_partner_obj.name), True)
 
226
            raise log
 
227
        if company_address_obj.country_id.code_3166:
 
228
            texto += '<CountryCode>' + company_address_obj.country_id.code_3166 + '</CountryCode>'
 
229
        else:
 
230
            log.add(_('User error:\n\nCompany %s has no country.') % (company_partner_obj.name), True)
 
231
            raise log
 
232
        texto += '</AddressInSpain>'
 
233
 
 
234
        texto += '<ContactDetails>'
 
235
        if company_address_obj.phone:
 
236
            texto += '<Telephone>' + company_address_obj.phone + '</Telephone>'
 
237
        if company_address_obj.fax:
 
238
            texto += '<TeleFax>' + company_address_obj.fax + '</TeleFax>'
 
239
        if company_partner_obj.website:
 
240
            texto += '<WebAddress>' + company_partner_obj.website + '</WebAddress>'
 
241
        if company_address_obj.email:
 
242
            texto += '<ElectronicMail>' + company_address_obj.email + '</ElectronicMail>'
 
243
        if company_address_obj.name:
 
244
            texto += '<ContactPersons>' + company_address_obj.name + '</ContactPersons>'
 
245
        texto += '</ContactDetails>'
 
246
 
 
247
        if tipo_seller == 'F':
 
248
            texto += '</Individual>'
 
249
        else:
 
250
            texto += '</LegalEntity>'
 
251
 
 
252
        texto += '</SellerParty>'
 
253
        texto += '<BuyerParty>'
 
254
        texto += '<TaxIdentification>'
 
255
        texto += '<PersonTypeCode>' + tipo_buyer + '</PersonTypeCode>'
 
256
        texto += '<ResidenceTypeCode>U</ResidenceTypeCode>'
 
257
        texto += '<TaxIdentificationNumber>' + invoice_partner_obj.vat + '</TaxIdentificationNumber>'
 
258
        texto += '</TaxIdentification>'
 
259
 
 
260
        if tipo_buyer == 'F':
 
261
            texto += '<Individual>'
 
262
            texto += '<Name>' + invoice_partner_obj.name + '</Name>'
 
263
            texto += '<FirstSurname></FirstSurname>'
 
264
            texto += '<SecondSurname></SecondSurname>'
 
265
        else:
 
266
            texto += '<LegalEntity>'
 
267
            texto += '<CorporateName>' + invoice_partner_obj.name + '</CorporateName>'
 
268
 
 
269
 
 
270
        texto += '<AddressInSpain>'
 
271
        if invoice_partner_address_obj.street:
 
272
            if company_address_obj.street2:
 
273
                texto += '<Address>' + invoice_partner_address_obj.street + ' ' + company_address_obj.street2 + '</Address>'
 
274
            else:
 
275
                texto += '<Address>' + invoice_partner_address_obj.street + '</Address>'
 
276
        else:
 
277
            log.add(_('User error:\n\nPartner %s has no street.') % (invoice_partner_address_obj.name), True)
 
278
            raise log
 
279
        if invoice_partner_address_obj.zip:
 
280
            texto += '<PostCode>' + invoice_partner_address_obj.zip + '</PostCode>'
 
281
        else:
 
282
            log.add(_('User error:\n\nPartner %s has no zip code.') % (invoice_partner_obj.name), True)
 
283
            raise log
 
284
 
 
285
        if invoice_partner_address_obj.city:
 
286
            texto += '<Town>' + invoice_partner_address_obj.city + '</Town>'
 
287
        else:
 
288
            log.add(_('User error:\n\nPartner %s has no city.') % (invoice_partner_obj.name), True)
 
289
            raise log
 
290
        if invoice_partner_address_obj.state_id.name:
 
291
            texto += '<Province>' + invoice_partner_address_obj.state_id.name + '</Province>'
 
292
        else:
 
293
            log.add(_('User error:\n\nPartner %s has no province.') % (invoice_partner_obj.name), True)
 
294
            raise log
 
295
        if invoice_partner_address_obj.country_id.code_3166:
 
296
            texto += '<CountryCode>' + invoice_partner_address_obj.country_id.code_3166 + '</CountryCode>'
 
297
        else:
 
298
            log.add(_('User error:\n\nPartner %s has no country.') % (invoice_partner_obj.name), True)
 
299
            raise log
 
300
        texto += '</AddressInSpain>'
 
301
 
 
302
        texto += '<ContactDetails>'
 
303
        if invoice_partner_address_obj.phone:
 
304
            texto += '<Telephone>' + invoice_partner_address_obj.phone + '</Telephone>'
 
305
        if invoice_partner_address_obj.fax:
 
306
            texto += '<TeleFax>' + invoice_partner_address_obj.fax + '</TeleFax>'
 
307
        if invoice_partner_obj.website:
 
308
            texto += '<WebAddress>' + invoice_partner_obj.website + '</WebAddress>'
 
309
        if invoice_partner_address_obj.email:
 
310
            texto += '<ElectronicMail>' + invoice_partner_address_obj.email + '</ElectronicMail>'
 
311
        if invoice_partner_address_obj.name:
 
312
            texto += '<ContactPersons>' + invoice_partner_address_obj.name + '</ContactPersons>'
 
313
        texto += '</ContactDetails>'
 
314
 
 
315
        if tipo_buyer == 'F':
 
316
            texto += '</Individual>'
 
317
        else:
 
318
            texto += '</LegalEntity>'
 
319
        texto += '</BuyerParty>'
 
320
        texto += '</Parties>'
 
321
        return texto
 
322
 
 
323
    def _taxes_output():
 
324
        
 
325
        texto = ''
 
326
        rate = 0.0
 
327
        taxes_withhel = 0.0
 
328
 
 
329
        texto += '<TaxesOutputs>'
 
330
 
 
331
        for l in invoice.tax_line:
 
332
            taxes_withhel += l.base_amount
 
333
            texto += '<Tax>'
 
334
            texto += '<TaxTypeCode>01</TaxTypeCode>'
 
335
            cr.execute('SELECT t.amount FROM account_tax t WHERE t.tax_code_id =%s',(l.tax_code_id.id,))
 
336
            res = cr.fetchone()
 
337
            texto += '<TaxRate>' + str('%.2f' % (res[0] * 100)) + '</TaxRate>'
 
338
            texto += '<TaxableBase>'
 
339
            texto += '<TotalAmount>' + str('%.2f' % l.base_amount) + '</TotalAmount>'
 
340
            texto += '</TaxableBase>'
 
341
            texto += '<TaxAmount>'
 
342
            texto += '<TotalAmount>' + str('%.2f' % l.tax_amount) + '</TotalAmount>'
 
343
            texto += '</TaxAmount>'
 
344
            texto += '</Tax>'
 
345
 
 
346
        texto += '</TaxesOutputs>'
 
347
 
 
348
        texto += '<TaxesWithheld>'
 
349
        texto += '<Tax>'
 
350
        texto += '<TaxTypeCode>01</TaxTypeCode>'
 
351
        texto += '<TaxRate>0.00</TaxRate>'
 
352
        texto += '<TaxableBase>'
 
353
        texto += '<TotalAmount>' + str('%.2f' % taxes_withhel) + '</TotalAmount>'
 
354
        texto += '</TaxableBase>'
 
355
        texto += '<TaxAmount>'
 
356
        texto += '<TotalAmount>0.00</TotalAmount>'
 
357
        texto += '</TaxAmount>'
 
358
        texto += '</Tax>'
 
359
        texto += '</TaxesWithheld>'
 
360
 
 
361
        return texto
 
362
 
 
363
    def _invoice_totals():
 
364
        
 
365
        total_gross_amount = 0.0
 
366
        texto = ''
 
367
        
 
368
        for line in invoice.invoice_line:
 
369
            total_gross_amount += line.price_subtotal
 
370
 
 
371
        texto += '<InvoiceTotals>'
 
372
        texto += '<TotalGrossAmount>' + str('%.2f' % total_gross_amount) + '</TotalGrossAmount>'
 
373
        #despues descuentos cabercera pero en OpenERP no se donde estan
 
374
        #despues gastos de envio no se como aplicar si se pueden
 
375
        #si se utilizaran los anteriores aqui se le restaria descuentos y sumarian gastos
 
376
        texto += '<TotalGrossAmountBeforeTaxes>' + str('%.2f' % total_gross_amount) + '</TotalGrossAmountBeforeTaxes>'
 
377
        texto += '<TotalTaxOutputs>' + str('%.2f' % invoice.amount_tax) + '</TotalTaxOutputs>'
 
378
        texto += '<TotalTaxesWithheld>0.00</TotalTaxesWithheld>'
 
379
        texto += '<InvoiceTotal>' + str('%.2f' % invoice.amount_total) + '</InvoiceTotal>'
 
380
        #aqui se descontaria los pagos realizados a cuenta
 
381
        texto += '<TotalOutstandingAmount>' + str('%.2f' % invoice.amount_total) + '</TotalOutstandingAmount>'
 
382
        texto += '<TotalExecutableAmount>' + str('%.2f' % invoice.amount_total) + '</TotalExecutableAmount>'
 
383
 
 
384
        texto += '</InvoiceTotals>'
 
385
        return texto
 
386
 
 
387
    def _invoice_items():
 
388
        
 
389
        rate = 0.0
 
390
        texto = ''
 
391
        texto += '<Items>'
 
392
        
 
393
        for line in invoice.invoice_line:
 
394
            texto += '<InvoiceLine>'
 
395
            texto += '<ItemDescription>' + line.name + '</ItemDescription>'
 
396
            texto += '<Quantity>' + str(line.quantity) + '</Quantity>'
 
397
            texto += '<UnitPriceWithoutTax>' + str('%.6f' % line.price_unit) + '</UnitPriceWithoutTax>'
 
398
            texto += '<TotalCost>' + str('%.2f' % (line.quantity * line.price_unit)) + '</TotalCost>'
 
399
            texto += '<DiscountsAndRebates>'
 
400
            texto += '<Discount>'
 
401
            texto += '<DiscountReason>Descuento</DiscountReason>'
 
402
            texto += '<DiscountRate>' + str('%.4f' % line.discount) + '</DiscountRate>'
 
403
            texto += '<DiscountAmount>' + str('%.2f' % ( (line.price_unit*line.quantity) - line.price_subtotal)) + '</DiscountAmount>'
 
404
            texto += '</Discount>'
 
405
            texto += '</DiscountsAndRebates>'
 
406
            texto += '<GrossAmount>' + str('%.2f' % line.price_subtotal) + '</GrossAmount>'
 
407
            texto += '<TaxesWithheld>'
 
408
            texto += '<Tax>'
 
409
            texto += '<TaxTypeCode>01</TaxTypeCode>'
 
410
            texto += '<TaxRate>0.00</TaxRate>'
 
411
            texto += '<TaxableBase>'
 
412
            texto += '<TotalAmount>' + str('%.2f' % line.price_subtotal) + '</TotalAmount>'
 
413
            texto += '</TaxableBase>'
 
414
            texto += '</Tax>'
 
415
            texto += '</TaxesWithheld>'
 
416
            texto += '<TaxesOutputs>'
 
417
            for l in line.invoice_line_tax_id:
 
418
                rate = '%.2f' % (l.amount * 100)
 
419
                texto += '<Tax>'
 
420
                texto += '<TaxTypeCode>01</TaxTypeCode>'
 
421
                texto += '<TaxRate>' + str(rate) + '</TaxRate>'
 
422
                texto += '<TaxableBase>'
 
423
                texto += '<TotalAmount>' + str('%.2f' % line.price_subtotal) + '</TotalAmount>'
 
424
                texto += '</TaxableBase>'
 
425
                texto += '</Tax>'
 
426
            texto += '</TaxesOutputs>'
 
427
            texto += '</InvoiceLine>'
 
428
 
 
429
        texto += '</Items>'
 
430
        return texto
 
431
 
 
432
    def _invoices_facturae():
 
433
 
 
434
        texto = ''
 
435
        texto += '<Invoices>'
 
436
        texto += '<Invoice>'
 
437
        texto += '<InvoiceHeader>'
 
438
        texto += '<InvoiceNumber>' + invoice.number + '</InvoiceNumber>'
 
439
        texto += '<InvoiceSeriesCode>' + invoice.number + '</InvoiceSeriesCode>'
 
440
        texto += '<InvoiceDocumentType>FC</InvoiceDocumentType>'
 
441
        texto += '<InvoiceClass>OO</InvoiceClass>'
 
442
        texto += '</InvoiceHeader>'
 
443
        texto += '<InvoiceIssueData>'
 
444
        texto += '<IssueDate>' + invoice.date_invoice + '</IssueDate>'
 
445
        texto += '<InvoiceCurrencyCode>' + invoice.currency_id.code + '</InvoiceCurrencyCode>'
 
446
        texto += '<TaxCurrencyCode>' + invoice.currency_id.code + '</TaxCurrencyCode>'
 
447
        texto += '<LanguageName>es</LanguageName>'
 
448
        texto += '</InvoiceIssueData>'
 
449
        texto += _taxes_output()
 
450
        texto += _invoice_totals()
 
451
        texto += _invoice_items()
 
452
        texto += '<AdditionalData>'
 
453
        texto += '<InvoiceAdditionalInformation>' + str(invoice.comment) + '</InvoiceAdditionalInformation>'
 
454
        texto += '</AdditionalData>'
 
455
        texto += '</Invoice>'
 
456
        texto += '</Invoices>'
 
457
        return texto
 
458
 
 
459
    def _end_document():
 
460
        return '</fe:Facturae>'
 
461
 
 
462
    xml_facturae = ''
 
463
    log = Log()
 
464
    try:
 
465
        pool = pooler.get_pool(cr.dbname)
 
466
        invoice = pool.get('account.invoice').browse(cr, uid, data['id'], context)
 
467
        contador = 1
 
468
        lines_issued = []
 
469
        xml_facturae += _format_xml()
 
470
        xml_facturae += _header_facturae(cr, context)
 
471
        xml_facturae += _parties_facturae(cr, context)
 
472
        xml_facturae += _invoices_facturae()
 
473
        xml_facturae += _end_document()
 
474
        xml_facturae = conv_ascii(xml_facturae)
 
475
    except Log:
 
476
        return {'note':log(), 'reference': 'id', 'facturae':False, 'state':'failed'}
 
477
    else:
 
478
        file = base64.encodestring(xml_facturae)
 
479
        fname = (_('facturae') + '_' + invoice.number + '.xml').replace('/','-')
 
480
        pool.get('ir.attachment').create(cr, uid, {
 
481
            'name': '%s %s' % (_('FacturaE'), invoice.number),
 
482
            'datas': file,
 
483
            'datas_fname': fname,
 
484
            'res_model': 'account.invoice',
 
485
            'res_id': invoice.id,
 
486
            }, context=context)
 
487
        log.add(_("Export successful\n\nSummary:\nInvoice number: %s\n") % (invoice.number))
 
488
        pool.get('account.invoice').set_done(cr,uid,invoice.id,context)
 
489
 
 
490
        return {'note':log(), 'reference':invoice.id, 'facturae':file, 'facturae_fname':fname, 'state':'succeeded'}
 
491
 
 
492
class wizard_facturae_file(wizard.interface):
 
493
    states = {
 
494
        'init' : {
 
495
            'actions' : [],
 
496
            'result' : {'type' : 'form',
 
497
                        'arch' : facturae_form,
 
498
                        'fields' : facturae_fields,
 
499
                        'state' : [('end', 'Cancel'),('export', 'Export','gtk-ok') ]}
 
500
        },
 
501
        'export': {
 
502
            'actions' : [_create_facturae_file],
 
503
            'result' : {'type' : 'form',
 
504
                        'arch' : export_form,
 
505
                        'fields' : export_fields,
 
506
                        'state' : [('end', 'Ok','gtk-ok') ]}
 
507
        }
 
508
 
 
509
    }
 
510
wizard_facturae_file('create_facturae_file')
 
511
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 
512