Esempio n. 1
0
 def get_pyafipws_last_invoice(self, cr, uid, ids, 
                               fields_name=None, arg=None, context=None):
     ret = {}
     for journal in self.browse(cr, uid, ids):
         company = journal.company_id
         tipo_cbte = journal.pyafipws_invoice_type
         punto_vta = journal.pyafipws_point_of_sale
         service = journal.pyafipws_electronic_invoice_service
         # authenticate:
         auth_data = company.pyafipws_authenticate(service=service)            
         # import AFIP webservice helper for electronic invoice       
         if service == "wsfe":
             from pyafipws.wsfev1 import WSFEv1
             ws = WSFEv1()
         elif service == "wsfex":
             from pyafipws.wsfexv1 import WSFEXv1
             ws = WSFEXv1()
         elif service == "wsmtxca":
             from pyafipws.wsmtx import WSMTXCA
             ws = WSMTXCA()
         # create the proxy and get the configuration system parameters:
         cfg = self.pool.get('ir.config_parameter')
         cache = cfg.get_param(cr, uid, 'pyafipws.cache', context=context)
         proxy = cfg.get_param(cr, uid, 'pyafipws.proxy', context=context)
         wsdl = cfg.get_param(cr, uid, 'pyafipws.%s.url' % service, context=context)
         # connect to the webservice and call to the query method
         ws.Conectar(cache or "", wsdl or "", proxy or "")
         if auth_data['token']:
             # set AFIP webservice credentials:
             ws.Cuit = company.pyafipws_cuit
             ws.Token = auth_data['token']
             ws.Sign = auth_data['sign']
             # call the webservice method to get the last invoice at AFIP:
             if service == "wsfe" or service == "wsmtxca":
                 ult = ws.CompUltimoAutorizado(tipo_cbte, punto_vta)
             elif service == "wsfex":
                 ult = ws.GetLastCMP(tipo_cbte, punto_vta)
             msg = u"Ult.Cbte: Nro %s" % (ult, )
             msg += u" - ".join([ws.Excepcion, ws.ErrMsg, ws.Obs])
             self.log(cr, uid, ids[0], u"Ult.Cbte: N° %s %s" % (ult, msg))
             # OpenChatter (new)
             self.message_post(cr, uid, ids, "AFIP Ult. Nro", msg, context=context)
             ##raise Warning(msg)
             ret[journal.id] = str(ult)
         else:
             msg = auth_data['err_msg']
             raise osv.except_osv(_("ERROR"), msg)
     return ret
Esempio n. 2
0
 def get_pyafipws_last_invoice(self, cr, uid, ids, 
                               fields_name=None, arg=None, context=None):
     ret = {}
     for journal in self.browse(cr, uid, ids):
         company = journal.company_id
         tipo_cbte = journal.pyafipws_invoice_type
         punto_vta = journal.pyafipws_point_of_sale
         service = journal.pyafipws_electronic_invoice_service
         # authenticate:
         auth_data = company.pyafipws_authenticate(service=service)            
         # import AFIP webservice helper for electronic invoice       
         if service == "wsfe":
             from pyafipws.wsfev1 import WSFEv1
             ws = WSFEv1()
         elif service == "wsfex":
             from pyafipws.wsfexv1 import WSFEXv1
             ws = WSFEXv1()
         elif service == "wsmtxca":
             from pyafipws.wsmtx import WSMTXCA
             ws = WSMTXCA()
         # create the proxy and get the configuration system parameters:
         cfg = self.pool.get('ir.config_parameter')
         cache = cfg.get_param(cr, uid, 'pyafipws.cache', context=context)
         proxy = cfg.get_param(cr, uid, 'pyafipws.proxy', context=context)
         wsdl = cfg.get_param(cr, uid, 'pyafipws.%s.url' % service, context=context)
         # connect to the webservice and call to the query method
         ws.Conectar(cache or "", wsdl or "", proxy or "")
         if auth_data['token']:
             # set AFIP webservice credentials:
             ws.Cuit = company.pyafipws_cuit
             ws.Token = auth_data['token']
             ws.Sign = auth_data['sign']
             # call the webservice method to get the last invoice at AFIP:
             if service == "wsfe" or service == "wsmtxca":
                 ult = ws.CompUltimoAutorizado(tipo_cbte, punto_vta)
             elif service == "wsfex":
                 ult = ws.GetLastCMP(tipo_cbte, punto_vta)
             msg = " - ".join([ws.Excepcion, ws.ErrMsg, ws.Obs])
             self.log(cr, uid, ids[0], u"Ult.Cbte: N° %s %s" % (ult, msg))
             ret[journal.id] = str(ult)
         else:
             msg = auth_data['err_msg']
             raise osv.except_osv(_("ERROR"), msg)
     return ret
    def get(self, cr, uid, ids, context={}):
        #invoice = self.pool.get('account.invoice')
        for wiz in self.browse(cr, uid, ids):
            company = wiz.journal.company_id
            tipo_cbte = wiz.journal.pyafipws_invoice_type
            punto_vta = wiz.journal.pyafipws_point_of_sale
            service = wiz.journal.pyafipws_electronic_invoice_service
            # check if it is an electronic invoice sale point:
            if not tipo_cbte or not punto_vta or not service:
                raise osv.except_osv('Error !', "Solo factura electrónica")

            # authenticate against AFIP:
            auth_data = company.pyafipws_authenticate(service=service)
            # create the proxy and get the configuration system parameters:
            cfg = self.pool.get('ir.config_parameter')
            cache = cfg.get_param(cr, uid, 'pyafipws.cache', context=context)
            proxy = cfg.get_param(cr, uid, 'pyafipws.proxy', context=context)
            wsdl = cfg.get_param(cr,
                                 uid,
                                 'pyafipws.%s.url' % service,
                                 context=context)

            # import the AFIP webservice helper for electronic invoice
            if service == 'wsfe':
                from pyafipws.wsfev1 import WSFEv1, SoapFault  # local market
                ws = WSFEv1()
            elif service == 'wsmtxca':
                from pyafipws.wsmtx import WSMTXCA, SoapFault  # local + detail
                wsdl = cfg.get_param(cr,
                                     uid,
                                     'pyafipws.wsmtxca.url',
                                     context=context)
                ws = WSMTXCA()
            elif service == 'wsfex':
                from pyafipws.wsfexv1 import WSFEXv1, SoapFault  # foreign trade
                wsdl = cfg.get_param(cr,
                                     uid,
                                     'pyafipws.wsfex.url',
                                     context=context)
                ws = WSFEXv1()
            else:
                raise osv.except_osv('Error !', "%s no soportado" % service)

            # connect to the webservice and call to the test method
            ws.Conectar(cache or "", wsdl or "", proxy or "")
            # set AFIP webservice credentials:
            ws.Cuit = company.pyafipws_cuit
            ws.Token = auth_data['token']
            ws.Sign = auth_data['sign']

            if service in ('wsfe', 'wsmtxca'):
                if not wiz.cbte_nro:
                    wiz.cbte_nro = ws.CompUltimoAutorizado(
                        tipo_cbte, punto_vta)
                ws.CompConsultar(tipo_cbte, punto_vta, wiz.cbte_nro)
                vat = ws.ImptoLiq
            else:
                if not wiz.cbte_nro:
                    wiz.cbte_nro = ws.GetLastCMP(tipo_cbte, punto_vta)
                ws.GetCMP(tipo_cbte, punto_vta, wiz.cbte_nro)
                vat = 0

            # update the form fields with the values returned from AFIP:
            self.write(cr,
                       uid,
                       ids, {
                           'cae': ws.CAE,
                           'cae_due': ws.Vencimiento,
                           'total': ws.ImpTotal or 0,
                           'vat': vat,
                           'cbte_nro': ws.CbteNro,
                       },
                       context=context)
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'pyafipws.invoice.wizard',
                'view_mode': 'form',
                'view_type': 'form',
                'res_id': wiz.id,
                'views': [(False, 'form')],
                'target': 'new',
            }
    def do_pyafipws_request_cae(self, cr, uid, ids, context=None, *args):
        "Request to AFIP the invoices' Authorization Electronic Code (CAE)"
        for invoice in self.browse(cr, uid, ids):
            # if already authorized (electronic invoice with CAE), ignore
            if invoice.pyafipws_cae:
                continue
            # get the electronic invoice type, point of sale and service:
            journal = invoice.journal_id
            company = journal.company_id
            tipo_cbte = journal.pyafipws_invoice_type
            punto_vta = journal.pyafipws_point_of_sale
            service = journal.pyafipws_electronic_invoice_service
            # check if it is an electronic invoice sale point:
            if not tipo_cbte or not punto_vta or not service:
                continue
            # authenticate against AFIP:
            auth_data = company.pyafipws_authenticate(service=service)

            # create the proxy and get the configuration system parameters:
            cfg = self.pool.get('ir.config_parameter')
            cache = cfg.get_param(cr, uid, 'pyafipws.cache', context=context)
            proxy = cfg.get_param(cr, uid, 'pyafipws.proxy', context=context)
            wsdl = cfg.get_param(cr,
                                 uid,
                                 'pyafipws.%s.url' % service,
                                 context=context)

            # import the AFIP webservice helper for electronic invoice
            if service == 'wsfe':
                from pyafipws.wsfev1 import WSFEv1  # local market
                ws = WSFEv1()
            elif service == 'wsmtxca':
                from pyafipws.wsmtx import WSMTXCA  # local + detail
                wsdl = cfg.get_param(cr,
                                     uid,
                                     'pyafipws.wsmtxca.url',
                                     context=context)
                ws = WSMTXCA()
            elif service == 'wsfex':
                from pyafipws.wsfexv1 import WSFEXv1
                wsdl = cfg.get_param(cr,
                                     uid,
                                     'pyafipws.wsfex.url',
                                     context=context)
                ws = WSFEXv1()
            else:
                raise osv.except_osv('Error !', "%s no soportado" % service)

            from pyafipws.utils import SoapFault
            # connect to the webservice and call to the test method
            ws.Conectar(cache or "", wsdl or "", proxy or "")
            # set AFIP webservice credentials:
            ws.Cuit = company.pyafipws_cuit
            ws.Token = auth_data['token']
            ws.Sign = auth_data['sign']

            # get the last 8 digit of the invoice number
            cbte_nro = int(invoice.number[-8:])
            # get the last invoice number registered in AFIP
            if service == "wsfe" or service == "wsmtxca":
                cbte_nro_afip = ws.CompUltimoAutorizado(tipo_cbte, punto_vta)
            elif service == 'wsfex':
                cbte_nro_afip = ws.GetLastCMP(tipo_cbte, punto_vta)
            cbte_nro_next = int(cbte_nro_afip or 0) + 1
            # verify that the invoice is the next one to be registered in AFIP
            if cbte_nro != cbte_nro_next:
                raise osv.except_osv(
                    u'Error !', u'Referencia: %s \n'
                    u'El número del comprobante debería ser %s y no %s' %
                    (str(invoice.number), str(cbte_nro_next), str(cbte_nro)))

            # invoice number range (from - to) and date:
            cbte_nro = cbt_desde = cbt_hasta = cbte_nro_next
            fecha_cbte = invoice.date_invoice
            if service != 'wsmtxca':
                fecha_cbte = fecha_cbte.replace("-", "")

            # due and billing dates only for concept "services"
            concepto = tipo_expo = int(invoice.pyafipws_concept or 0)
            if int(concepto) != 1:
                fecha_venc_pago = invoice.date_invoice
                if service != 'wsmtxca':
                    fecha_venc_pago = fecha_venc_pago.replace("-", "")
                if invoice.pyafipws_billing_start_date:
                    fecha_serv_desde = invoice.pyafipws_billing_start_date
                    if service != 'wsmtxca':
                        fecha_serv_desde = fecha_serv_desde.replace("-", "")
                else:
                    fecha_serv_desde = None
                if invoice.pyafipws_billing_end_date:
                    fecha_serv_hasta = invoice.pyafipws_billing_end_date
                    if service != 'wsmtxca':
                        fecha_serv_desde = fecha_serv_desde.replace("-", "")
                else:
                    fecha_serv_hasta = None
            else:
                fecha_venc_pago = fecha_serv_desde = fecha_serv_hasta = None

            # customer tax number:
            if invoice.partner_id.vat:
                nro_doc = invoice.partner_id.vat.replace("-", "")
            else:
                nro_doc = "0"  # only "consumidor final"
            tipo_doc = None
            if nro_doc.startswith("AR"):
                nro_doc = nro_doc[2:]
                if int(nro_doc) == 0:
                    tipo_doc = 99  # consumidor final
                elif len(nro_doc) < 11:
                    tipo_doc = 96  # DNI
                else:
                    tipo_doc = 80  # CUIT

            # invoice amount totals:
            imp_total = str("%.2f" % abs(invoice.amount_total))
            imp_tot_conc = "0.00"
            imp_neto = str("%.2f" % abs(invoice.amount_untaxed))
            imp_iva = str("%.2f" % abs(invoice.amount_tax))
            imp_subtotal = imp_neto  # TODO: not allways the case!
            imp_trib = "0.00"
            imp_op_ex = "0.00"
            if invoice.currency_id.name == 'ARS':
                moneda_id = "PES"
                moneda_ctz = 1
            else:
                moneda_id = {'USD': 'DOL'}[invoice.currency_id.name]
                moneda_ctz = str(invoice.currency_id.rate)

            # foreign trade data: export permit, country code, etc.:
            if False:  ##invoice.pyafipws_incoterms:
                incoterms = invoice.pyafipws_incoterms.code
                incoterms_ds = invoice.pyafipws_incoterms.name
            else:
                incoterms = incoterms_ds = None
            if int(tipo_cbte) == 19 and tipo_expo == 1:
                permiso_existente = "N" or "S"  # not used now
            else:
                permiso_existente = ""
            obs_generales = invoice.comment
            if invoice.payment_term:
                forma_pago = invoice.payment_term.name
                obs_comerciales = invoice.payment_term.name
            else:
                forma_pago = obs_comerciales = None
            idioma_cbte = 1  # invoice language: spanish / español

            # customer data (foreign trade):
            nombre_cliente = invoice.partner_id.name
            if invoice.partner_id.vat:
                if invoice.partner_id.vat.startswith("AR"):
                    # use the Argentina AFIP's global CUIT for the country:
                    cuit_pais_cliente = invoice.partner_id.vat[2:]
                    id_impositivo = None
                else:
                    # use the VAT number directly
                    id_impositivo = invoice.partner_id.vat[2:]
                    # TODO: the prefix could be used to map the customer country
                    cuit_pais_cliente = None
            else:
                cuit_pais_cliente = id_impositivo = None
            # OpenERP 7 no tiene address_invoice_id
            if invoice.partner_id:
                domicilio_cliente = " - ".join([
                    invoice.partner_id.name or '',
                    invoice.partner_id.street or '',
                    invoice.partner_id.street2 or '',
                    invoice.partner_id.zip or '',
                    invoice.partner_id.city or '',
                ])
            else:
                domicilio_cliente = ""
            if invoice.partner_id.country_id:
                # map ISO country code to AFIP destination country code:
                iso_code = invoice.partner_id.country_id.code.lower()
                pais_dst_cmp = AFIP_COUNTRY_CODE_MAP[iso_code]

            # create the invoice internally in the helper
            if service == 'wsfe':
                ws.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte,
                                punto_vta, cbt_desde, cbt_hasta, imp_total,
                                imp_tot_conc, imp_neto, imp_iva, imp_trib,
                                imp_op_ex, fecha_cbte, fecha_venc_pago,
                                fecha_serv_desde, fecha_serv_hasta, moneda_id,
                                moneda_ctz)
            elif service == 'wsmtxca':
                ws.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte,
                                punto_vta, cbt_desde, cbt_hasta, imp_total,
                                imp_tot_conc, imp_neto, imp_subtotal, imp_trib,
                                imp_op_ex, fecha_cbte, fecha_venc_pago,
                                fecha_serv_desde, fecha_serv_hasta, moneda_id,
                                moneda_ctz, obs_generales)
            elif service == 'wsfex':
                ws.CrearFactura(tipo_cbte, punto_vta, cbte_nro, fecha_cbte,
                                imp_total, tipo_expo, permiso_existente,
                                pais_dst_cmp, nombre_cliente,
                                cuit_pais_cliente, domicilio_cliente,
                                id_impositivo, moneda_id, moneda_ctz,
                                obs_comerciales, obs_generales, forma_pago,
                                incoterms, idioma_cbte, incoterms_ds)

            # analyze VAT (IVA) and other taxes (tributo):
            if service in ('wsfe', 'wsmtxca'):
                for tax_line in invoice.tax_line:
                    if "IVA" in tax_line.name:
                        if '0%' in tax_line.name:
                            iva_id = 3
                        elif '10,5%' in tax_line.name:
                            iva_id = 4
                        elif '21%' in tax_line.name:
                            iva_id = 5
                        elif '27%' in tax_line.name:
                            iva_id = 6
                        else:
                            iva_id = 0
                        base_imp = ("%.2f" % abs(tax_line.base))
                        importe = ("%.2f" % abs(tax_line.amount))
                        # add the vat detail in the helper
                        ws.AgregarIva(iva_id, base_imp, importe)
                    else:
                        if 'impuesto' in tax_line.name.lower():
                            tributo_id = 1  # nacional
                        elif 'iibbb' in tax_line.name.lower():
                            tributo_id = 3  # provincial
                        elif 'tasa' in tax_line.name.lower():
                            tributo_id = 4  # municipal
                        else:
                            tributo_id = 99
                        desc = tax_line.name
                        base_imp = ("%.2f" % abs(tax_line.base))
                        importe = ("%.2f" % abs(tax_line.amount))
                        alic = "%.2f" % tax_line.base
                        # add the other tax detail in the helper
                        ws.AgregarTributo(id, desc, base_imp, alic, importe)

            # analize line items - invoice detail
            if service in ('wsfex', 'wsmtxca'):
                for line in invoice.invoice_line:
                    codigo = line.product_id.code
                    u_mtx = 1  # TODO: get it from uom?
                    cod_mtx = line.product_id.ean13
                    ds = line.name
                    qty = line.quantity
                    umed = 7  # TODO: line.uos_id...?
                    precio = line.price_unit
                    importe = line.price_subtotal
                    bonif = line.discount or None
                    if line.invoice_line_tax_id:
                        iva_id = 5  # TODO: line.tax_code_id?
                        imp_iva = importe * line.invoice_line_tax_id[0].amount
                    else:
                        iva_id = 1
                        imp_iva = 0
                    if service == 'wsmtxca':
                        ws.AgregarItem(u_mtx, cod_mtx, codigo, ds, qty, umed,
                                       precio, bonif, iva_id, imp_iva,
                                       importe + imp_iva)
                    elif service == 'wsfex':
                        ws.AgregarItem(codigo, ds, qty, umed, precio, importe,
                                       bonif)

            # Request the authorization! (call the AFIP webservice method)
            vto = None
            try:
                if service == 'wsfe':
                    ws.CAESolicitar()
                    vto = ws.Vencimiento
                elif service == 'wsmtxca':
                    ws.AutorizarComprobante()
                    vto = ws.Vencimiento
                elif service == 'wsfex':
                    ws.Authorize(invoice.id)
                    vto = ws.FchVencCAE
            except SoapFault as fault:
                msg = 'Falla SOAP %s: %s' % (fault.faultcode,
                                             fault.faultstring)
            except Exception, e:
                if ws.Excepcion:
                    # get the exception already parsed by the helper
                    msg = ws.Excepcion
                else:
                    # avoid encoding problem when reporting exceptions to the user:
                    msg = traceback.format_exception_only(
                        sys.exc_type, sys.exc_value)[0]
            else:
                msg = u"\n".join([ws.Obs or "", ws.ErrMsg or ""])
            # calculate the barcode:
            if ws.CAE:
                cae_due = ''.join([c for c in str(vto or '') if c.isdigit()])
                bars = ''.join([
                    str(ws.Cuit),
                    "%02d" % int(tipo_cbte),
                    "%04d" % int(punto_vta),
                    str(ws.CAE), cae_due
                ])
                bars = bars + self.pyafipws_verification_digit_modulo10(bars)
            else:
                bars = ""
            # store the results
            self.write(
                cr, uid, invoice.id, {
                    'pyafipws_cae': ws.CAE,
                    'pyafipws_cae_due_date': vto or None,
                    'pyafipws_result': ws.Resultado,
                    'pyafipws_message': msg,
                    'pyafipws_xml_request': ws.XmlRequest,
                    'pyafipws_xml_response': ws.XmlResponse,
                    'pyafipws_barcode': bars,
                })
    def do_pyafipws_request_cae(self, cr, uid, ids, context=None, *args):
        "Request to AFIP the invoices' Authorization Electronic Code (CAE)"
        for invoice in self.browse(cr, uid, ids):
            # if already authorized (electronic invoice with CAE), ignore
            if invoice.pyafipws_cae:
                continue
            # get the electronic invoice type, point of sale and service:
            journal = invoice.journal_id
            company = journal.company_id
            tipo_cbte = journal.pyafipws_invoice_type
            punto_vta = journal.pyafipws_point_of_sale
            service = journal.pyafipws_electronic_invoice_service
            # check if it is an electronic invoice sale point:
            if not tipo_cbte or not punto_vta or not service:
                continue
            # authenticate against AFIP:
            auth_data = company.pyafipws_authenticate(service=service)

            # create the proxy and get the configuration system parameters:
            cfg = self.pool.get('ir.config_parameter')
            cache = cfg.get_param(cr, uid, 'pyafipws.cache', context=context)
            proxy = cfg.get_param(cr, uid, 'pyafipws.proxy', context=context)
            wsdl = cfg.get_param(cr, uid, 'pyafipws.%s.url' % service, context=context)
            
            # import the AFIP webservice helper for electronic invoice
            if service == 'wsfe':
                from pyafipws.wsfev1 import WSFEv1 # local market
                ws = WSFEv1()
            elif service == 'wsmtxca':
                from pyafipws.wsmtx import WSMTXCA # local + detail
                wsdl = cfg.get_param(cr, uid, 'pyafipws.wsmtxca.url', context=context)
                ws = WSMTXCA()
            elif service == 'wsfex':
                from pyafipws.wsfexv1 import WSFEXv1 
                wsdl = cfg.get_param(cr, uid, 'pyafipws.wsfex.url', context=context)
                ws = WSFEXv1()
            else:
                raise osv.except_osv('Error !', "%s no soportado" % service)

            from pyafipws.utils import SoapFault
            # connect to the webservice and call to the test method
            ws.Conectar(cache or "", wsdl or "", proxy or "")
            # set AFIP webservice credentials:
            ws.Cuit = company.pyafipws_cuit
            ws.Token = auth_data['token']
            ws.Sign = auth_data['sign']

            # get the last 8 digit of the invoice number
            cbte_nro = int(invoice.number[-8:])
            # get the last invoice number registered in AFIP
            if service == "wsfe" or service == "wsmtxca":
                cbte_nro_afip = ws.CompUltimoAutorizado(tipo_cbte, punto_vta)
            elif service == 'wsfex':
                cbte_nro_afip = ws.GetLastCMP(tipo_cbte, punto_vta)
            cbte_nro_next = int(cbte_nro_afip or 0) + 1
            # verify that the invoice is the next one to be registered in AFIP    
            if cbte_nro != cbte_nro_next:
                raise osv.except_osv(u'Error !', 
                        u'Referencia: %s \n' 
                        u'El número del comprobante debería ser %s y no %s' % (
                        str(invoice.number), str(cbte_nro_next), str(cbte_nro)))

            # invoice number range (from - to) and date:
            cbte_nro = cbt_desde = cbt_hasta = cbte_nro_next
            fecha_cbte = invoice.date_invoice
            if service != 'wsmtxca':
                fecha_cbte = fecha_cbte.replace("-", "")

            # due and billing dates only for concept "services" 
            concepto = tipo_expo = int(invoice.pyafipws_concept or 0)
            if int(concepto) != 1:
                fecha_venc_pago = invoice.date_invoice
                if service != 'wsmtxca':
                        fecha_venc_pago = fecha_venc_pago.replace("-", "")
                if invoice.pyafipws_billing_start_date:
                    fecha_serv_desde = invoice.pyafipws_billing_start_date
                    if service != 'wsmtxca':
                        fecha_serv_desde = fecha_serv_desde.replace("-", "")
                else:
                    fecha_serv_desde = None
                if  invoice.pyafipws_billing_end_date:
                    fecha_serv_hasta = invoice.pyafipws_billing_end_date
                    if service != 'wsmtxca':
                        fecha_serv_desde = fecha_serv_desde.replace("-", "")
                else:
                    fecha_serv_hasta = None
            else:
                fecha_venc_pago = fecha_serv_desde = fecha_serv_hasta = None

            # customer tax number:
            if invoice.partner_id.vat:
                nro_doc = invoice.partner_id.vat.replace("-","")
            else:
                nro_doc = "0"               # only "consumidor final"
            tipo_doc = None
            if nro_doc.startswith("AR"):
                nro_doc = nro_doc[2:]
                if int(nro_doc)  == 0:
                    tipo_doc = 99           # consumidor final
                elif len(nro_doc) < 11:
                    tipo_doc = 96           # DNI
                else:
                    tipo_doc = 80           # CUIT

            # invoice amount totals:
            imp_total = str("%.2f" % abs(invoice.amount_total))
            imp_tot_conc = "0.00"
            imp_neto = str("%.2f" % abs(invoice.amount_untaxed))
            imp_iva = str("%.2f" % abs(invoice.amount_tax))
            imp_subtotal = imp_neto  # TODO: not allways the case!
            imp_trib = "0.00"
            imp_op_ex = "0.00"
            if invoice.currency_id.name == 'ARS':                
                moneda_id = "PES"
                moneda_ctz = 1
            else:
                moneda_id = {'USD':'DOL'}[invoice.currency_id.name]
                moneda_ctz = str(invoice.currency_id.rate)

            # foreign trade data: export permit, country code, etc.:
            if False:##invoice.pyafipws_incoterms:
                incoterms = invoice.pyafipws_incoterms.code
                incoterms_ds = invoice.pyafipws_incoterms.name
            else:
                incoterms = incoterms_ds = None
            if int(tipo_cbte) == 19 and tipo_expo == 1:
                permiso_existente =  "N" or "S"     # not used now
            else:
                permiso_existente = ""
            obs_generales = invoice.comment
            if invoice.payment_term:
                forma_pago = invoice.payment_term.name
                obs_comerciales = invoice.payment_term.name
            else:
                forma_pago = obs_comerciales = None
            idioma_cbte = 1     # invoice language: spanish / español

            # customer data (foreign trade):
            nombre_cliente = invoice.partner_id.name
            if invoice.partner_id.vat:
                if invoice.partner_id.vat.startswith("AR"):
                    # use the Argentina AFIP's global CUIT for the country:
                    cuit_pais_cliente = invoice.partner_id.vat[2:]
                    id_impositivo = None
                else:
                    # use the VAT number directly
                    id_impositivo = invoice.partner_id.vat[2:] 
                    # TODO: the prefix could be used to map the customer country
                    cuit_pais_cliente = None
            else:
                cuit_pais_cliente = id_impositivo = None
            # OpenERP 7 no tiene address_invoice_id
            if invoice.partner_id:
                domicilio_cliente = " - ".join([
                                    invoice.partner_id.name or '',
                                    invoice.partner_id.street or '',
                                    invoice.partner_id.street2 or '',
                                    invoice.partner_id.zip or '',
                                    invoice.partner_id.city or '',
                                    ])
            else:
                domicilio_cliente = ""
            if invoice.partner_id.country_id:
                # map ISO country code to AFIP destination country code:
                iso_code = invoice.partner_id.country_id.code.lower()
                pais_dst_cmp = AFIP_COUNTRY_CODE_MAP[iso_code]
                

            # create the invoice internally in the helper
            if service == 'wsfe':
                ws.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta,
                    cbt_desde, cbt_hasta, imp_total, imp_tot_conc, imp_neto,
                    imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, 
                    fecha_serv_desde, fecha_serv_hasta,
                    moneda_id, moneda_ctz)
            elif service == 'wsmtxca':
                ws.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta,
                    cbt_desde, cbt_hasta, imp_total, imp_tot_conc, imp_neto,
                    imp_subtotal, imp_trib, imp_op_ex, fecha_cbte, 
                    fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta,
                    moneda_id, moneda_ctz, obs_generales)
            elif service == 'wsfex':
                ws.CrearFactura(tipo_cbte, punto_vta, cbte_nro, fecha_cbte,
                    imp_total, tipo_expo, permiso_existente, pais_dst_cmp, 
                    nombre_cliente, cuit_pais_cliente, domicilio_cliente,
                    id_impositivo, moneda_id, moneda_ctz, obs_comerciales, 
                    obs_generales, forma_pago, incoterms, 
                    idioma_cbte, incoterms_ds)

            # analyze VAT (IVA) and other taxes (tributo):
            if service in ('wsfe', 'wsmtxca'):
                for tax_line in invoice.tax_line:
                    if "IVA" in tax_line.name:
                        if '0%' in tax_line.name:
                            iva_id = 3
                        elif '10,5%' in tax_line.name:
                            iva_id = 4
                        elif '21%' in tax_line.name:
                            iva_id = 5
                        elif '27%' in tax_line.name:
                            iva_id = 6
                        else:
                            iva_id = 0
                        base_imp = ("%.2f" % abs(tax_line.base))
                        importe = ("%.2f" % abs(tax_line.amount))
                        # add the vat detail in the helper
                        ws.AgregarIva(iva_id, base_imp, importe)
                    else:
                        if 'impuesto' in tax_line.name.lower():
                            tributo_id = 1  # nacional
                        elif 'iibbb' in tax_line.name.lower():
                            tributo_id = 3  # provincial
                        elif 'tasa' in tax_line.name.lower():
                            tributo_id = 4  # municipal
                        else:
                            tributo_id = 99
                        desc = tax_line.name
                        base_imp = ("%.2f" % abs(tax_line.base))
                        importe = ("%.2f" % abs(tax_line.amount))
                        alic = "%.2f" % tax_line.base
                        # add the other tax detail in the helper
                        ws.AgregarTributo(id, desc, base_imp, alic, importe)                    

            # analize line items - invoice detail
            if service in ('wsfex', 'wsmtxca'):
                for line in invoice.invoice_line:
                    codigo = line.product_id.code
                    u_mtx = 1                       # TODO: get it from uom? 
                    cod_mtx = line.product_id.ean13
                    ds = line.name
                    qty = line.quantity
                    umed = 7                        # TODO: line.uos_id...?
                    precio = line.price_unit
                    importe = line.price_subtotal
                    bonif = line.discount or None
                    if line.invoice_line_tax_id:
                        iva_id = 5                      # TODO: line.tax_code_id?
                        imp_iva = importe * line.invoice_line_tax_id[0].amount
                    else:
                        iva_id = 1
                        imp_iva = 0
                    if service == 'wsmtxca':
                        ws.AgregarItem(u_mtx, cod_mtx, codigo, ds, qty, umed, 
                                precio, bonif, iva_id, imp_iva, importe+imp_iva)
                    elif service == 'wsfex':
                        ws.AgregarItem(codigo, ds, qty, umed, precio, importe, 
                                bonif)
            
            # Request the authorization! (call the AFIP webservice method)
            vto = None
            try:
                if service == 'wsfe':
                    ws.CAESolicitar()
                    vto = ws.Vencimiento
                elif service == 'wsmtxca':
                    ws.AutorizarComprobante()
                    vto = ws.Vencimiento
                elif service == 'wsfex':
                    ws.Authorize(invoice.id)
                    vto = ws.FchVencCAE
            except SoapFault as fault:
                msg = 'Falla SOAP %s: %s' % (fault.faultcode, fault.faultstring)
            except Exception, e:
                if ws.Excepcion:
                    # get the exception already parsed by the helper
                    msg = ws.Excepcion
                else:
                    # avoid encoding problem when reporting exceptions to the user:
                    msg = traceback.format_exception_only(sys.exc_type, 
                                                          sys.exc_value)[0]
            else:
                msg = u"\n".join([ws.Obs or "", ws.ErrMsg or ""])
            # calculate the barcode:
            if ws.CAE:
                cae_due = ''.join([c for c in str(vto or '') 
                                           if c.isdigit()])
                bars = ''.join([str(ws.Cuit), "%02d" % int(tipo_cbte), 
                                  "%04d" % int(punto_vta), 
                                  str(ws.CAE), cae_due])
                bars = bars + self.pyafipws_verification_digit_modulo10(bars)
            else:
                bars = ""
            # store the results
            self.write(cr, uid, invoice.id, 
                       {'pyafipws_cae': ws.CAE,
                        'pyafipws_cae_due_date': vto or None,
                        'pyafipws_result': ws.Resultado,
                        'pyafipws_message': msg,
                        'pyafipws_xml_request': ws.XmlRequest,
                        'pyafipws_xml_response': ws.XmlResponse,
                        'pyafipws_barcode': bars,
                       })
    def get(self,cr,uid,ids,context={}):
        #invoice = self.pool.get('account.invoice')
        for wiz in self.browse(cr, uid, ids):
            company = wiz.journal.company_id
            tipo_cbte = wiz.journal.pyafipws_invoice_type
            punto_vta = wiz.journal.pyafipws_point_of_sale
            service = wiz.journal.pyafipws_electronic_invoice_service
            # check if it is an electronic invoice sale point:
            if not tipo_cbte or not punto_vta or not service:
                raise osv.except_osv('Error !', "Solo factura electrónica")

            # authenticate against AFIP:
            auth_data = company.pyafipws_authenticate(service=service)
            # create the proxy and get the configuration system parameters:
            cfg = self.pool.get('ir.config_parameter')
            cache = cfg.get_param(cr, uid, 'pyafipws.cache', context=context)
            proxy = cfg.get_param(cr, uid, 'pyafipws.proxy', context=context)
            wsdl = cfg.get_param(cr, uid, 'pyafipws.%s.url' % service, context=context)
            
            # import the AFIP webservice helper for electronic invoice
            if service == 'wsfe':
                from pyafipws.wsfev1 import WSFEv1, SoapFault   # local market
                ws = WSFEv1()
            elif service == 'wsmtxca':
                from pyafipws.wsmtx import WSMTXCA, SoapFault   # local + detail
                wsdl = cfg.get_param(cr, uid, 'pyafipws.wsmtxca.url', context=context)
                ws = WSMTXCA()
            elif service == 'wsfex':
                from pyafipws.wsfexv1 import WSFEXv1, SoapFault # foreign trade
                wsdl = cfg.get_param(cr, uid, 'pyafipws.wsfex.url', context=context)
                ws = WSFEXv1()
            else:
                raise osv.except_osv('Error !', "%s no soportado" % service)
            
            # connect to the webservice and call to the test method
            ws.Conectar(cache or "", wsdl or "", proxy or "")
            # set AFIP webservice credentials:
            ws.Cuit = company.pyafipws_cuit
            ws.Token = auth_data['token']
            ws.Sign = auth_data['sign']

            if service in ('wsfe', 'wsmtxca'):
                if not wiz.cbte_nro:
                    wiz.cbte_nro = ws.CompUltimoAutorizado(tipo_cbte, punto_vta)
                ws.CompConsultar(tipo_cbte, punto_vta, wiz.cbte_nro)
                vat = ws.ImptoLiq
            else:
                if not wiz.cbte_nro:
                    wiz.cbte_nro = ws.GetLastCMP(tipo_cbte, punto_vta)
                ws.GetCMP(tipo_cbte, punto_vta, wiz.cbte_nro)
                vat = 0

            # update the form fields with the values returned from AFIP:
            self.write(cr, uid, ids, {'cae': ws.CAE, 'cae_due': ws.Vencimiento,
                                      'total': ws.ImpTotal or 0, 'vat': vat,
                                      'cbte_nro': ws.CbteNro,                                    
                                     }, context=context)
            return {
                'type': 'ir.actions.act_window',
                'res_model': 'pyafipws.invoice.wizard',
                'view_mode': 'form',
                'view_type': 'form',
                'res_id': wiz.id,
                'views': [(False, 'form')],
                'target': 'new',
                 }