<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the Affero GNU General Public License as published by
# the Software Foundation; either version 3, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# Copyright 2013 by <NAME>
# Based on code "factura_electronica" by <NAME> 
# Based on code "openerp-iva-argentina" by <NAME> / <NAME>
# Based on code "l10n_ar_wsafip_fe" by OpenERP - Team de Localización Argentina

"Electronic Invoice for Argentina Federal Tax Administration (AFIP) webservices"

__author__ = "<NAME> (<EMAIL>)"
__copyright__ = "Copyright (C) 2013 <NAME> and others"
__license__ = "AGPL 3.0+"


from osv import fields, osv
import os, time
import datetime
import decimal
import os
import socket
import sys
import traceback

DEBUG = True


class electronic_invoice(osv.osv):
    _name = "account.invoice"
    _inherit = "account.invoice"
    _order = "id"
    _columns = {
        'pyafipws_concept': fields.selection([
                        ('1','1-Productos'),
                        ('2','2-Servicios'),
                        ('3','3-Productos y Servicios (mercado interno)'),
                        ('4','4-Otros (exportación)'),
                        ], 'Concepto', 
            select=True, required=True, 
            readonly=True, states={'draft': [('readonly', False)]}),
        'pyafipws_billing_start_date': fields.date('Fecha Desde',
            readonly=True, states={'draft': [('readonly', False)]},
            help="Seleccionar fecha de fin de servicios - Sólo servicios"),
        'pyafipws_billing_end_date': fields.date('Fecha Hasta',
            readonly=True, states={'draft': [('readonly', False)]},
            help="Seleccionar fecha de inicio de servicios - Sólo servicios"),
        'pyafipws_incoterms': fields.many2one('stock.incoterms', 'INCOTERMS', 
            readonly=True, states={'draft': [('readonly', False)]},
            help="Términos de comercio internacional (exportación)"),
        'pyafipws_result': fields.selection([
                ('', 'n/a'),
                ('A', 'Aceptado'),
                ('R', 'Rechazado'),
                ('O', 'Observado'),
            ], 'Resultado', size=1, readonly=True,
            help="Resultado procesamiento de la Solicitud, devuelto por AFIP"),
        'pyafipws_cae': fields.char('CAE', size=14, readonly=True,
            help="Código de Autorización Electrónico, devuelto por AFIP"),
        'pyafipws_cae_due_date': fields.date('Vencimiento CAE', readonly=True,
            help="Fecha tope para verificar CAE, devuelto por AFIP"),
        'pyafipws_message': fields.text('Mensaje', readonly=True,
            help="Mensaje de error u observación, devuelto por AFIP"),
        'pyafipws_xml_request': fields.text('Requerimiento XML', readonly=True,
            help="Mensaje XML enviado a AFIP (depuración)"),
        'pyafipws_xml_response': fields.text('Respuesta XML', readonly=True,
            help="Mensaje XML recibido de AFIP (depuración)"),
        'pyafipws_barcode': fields.char('Codigo de Barras', size=40, 
            help="Código de barras para usar en la impresión", readonly=True,),
    }
    _defaults = {
         'pyafipws_concept': lambda *a: '1',
    }

    def do_pyafipws_request_cae(self, cr, uid, ids, *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)

            # import AFIP webservice helper for electronic invoice
            if service == 'wsfe':
                from pyafipws.wsfev1 import WSFEv1, SoapFault   # local market
                ws = WSFEv1()
            elif service == 'wsfex':
                from pyafipws.wsfexv1 import WSFEXv1, SoapFault # foreign trade
                ws = WSFEXv1()
            else:
                raise osv.except_osv('Error !', "%s no soportado" % service)
            
            # connect to the webservice and call to the test method
            ws.Conectar()
            # 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 = invoice.number[-8:]
            # get the last invoice number registered in AFIP
            if service == 'wsfe':
                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 False and cbte_nro != cbte_nro_next:
                raise osv.except_osv('Error !', 
                        'Referencia: %s \n' 
                        '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.replace("-", "")

            # due and billing dates only for concept "services" 
            concepto = tipo_expo = invoice.pyafipws_concept
            if int(concepto) != 1:
                fecha_venc_pago = invoice.date_invoice.replace("-", "")
                if invoice.pyafipws_billing_start_date:
                    fecha_serv_desde = invoice.pyafipws_billing_start_date.replace("-", "")
                else:
                    fecha_serv_desde = None
                if  invoice.pyafipws_billing_end_date:
                    fecha_serv_hasta = invoice.pyafipws_billing_end_date.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
<commit_msg>fixed invoice concept type issue<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the Affero GNU General Public License as published by
# the Software Foundation; either version 3, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# Copyright 2013 by <NAME>
# Based on code "factura_electronica" by <NAME> 
# Based on code "openerp-iva-argentina" by <NAME> / <NAME>
# Based on code "l10n_ar_wsafip_fe" by OpenERP - Team de Localización Argentina

"Electronic Invoice for Argentina Federal Tax Administration (AFIP) webservices"

__author__ = "<NAME> (<EMAIL>)"
__copyright__ = "Copyright (C) 2013 <NAME> and others"
__license__ = "AGPL 3.0+"


from osv import fields, osv
import os, time
import datetime
import decimal
import os
import socket
import sys
import traceback

DEBUG = True


class electronic_invoice(osv.osv):
    _name = "account.invoice"
    _inherit = "account.invoice"
    _order = "id"
    _columns = {
        'pyafipws_concept': fields.selection([
                        ('1','1-Productos'),
                        ('2','2-Servicios'),
                        ('3','3-Productos y Servicios (mercado interno)'),
                        ('4','4-Otros (exportación)'),
                        ], 'Concepto', 
            select=True, required=True, 
            readonly=True, states={'draft': [('readonly', False)]}),
        'pyafipws_billing_start_date': fields.date('Fecha Desde',
            readonly=True, states={'draft': [('readonly', False)]},
            help="Seleccionar fecha de fin de servicios - Sólo servicios"),
        'pyafipws_billing_end_date': fields.date('Fecha Hasta',
            readonly=True, states={'draft': [('readonly', False)]},
            help="Seleccionar fecha de inicio de servicios - Sólo servicios"),
        'pyafipws_incoterms': fields.many2one('stock.incoterms', 'INCOTERMS', 
            readonly=True, states={'draft': [('readonly', False)]},
            help="Términos de comercio internacional (exportación)"),
        'pyafipws_result': fields.selection([
                ('', 'n/a'),
                ('A', 'Aceptado'),
                ('R', 'Rechazado'),
                ('O', 'Observado'),
            ], 'Resultado', size=1, readonly=True,
            help="Resultado procesamiento de la Solicitud, devuelto por AFIP"),
        'pyafipws_cae': fields.char('CAE', size=14, readonly=True,
            help="Código de Autorización Electrónico, devuelto por AFIP"),
        'pyafipws_cae_due_date': fields.date('Vencimiento CAE', readonly=True,
            help="Fecha tope para verificar CAE, devuelto por AFIP"),
        'pyafipws_message': fields.text('Mensaje', readonly=True,
            help="Mensaje de error u observación, devuelto por AFIP"),
        'pyafipws_xml_request': fields.text('Requerimiento XML', readonly=True,
            help="Mensaje XML enviado a AFIP (depuración)"),
        'pyafipws_xml_response': fields.text('Respuesta XML', readonly=True,
            help="Mensaje XML recibido de AFIP (depuración)"),
        'pyafipws_barcode': fields.char('Codigo de Barras', size=40, 
            help="Código de barras para usar en la impresión", readonly=True,),
    }
    _defaults = {
         'pyafipws_concept': lambda *a: '1',
    }

    def do_pyafipws_request_cae(self, cr, uid, ids, *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)

            # import AFIP webservice helper for electronic invoice
            if service == 'wsfe':
                from pyafipws.wsfev1 import WSFEv1, SoapFault   # local market
                ws = WSFEv1()
            elif service == 'wsfex':
                from pyafipws.wsfexv1 import WSFEXv1, SoapFault # foreign trade
                ws = WSFEXv1()
            else:
                raise osv.except_osv('Error !', "%s no soportado" % service)
            
            # connect to the webservice and call to the test method
            ws.Conectar()
            # 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 = invoice.number[-8:]
            # get the last invoice number registered in AFIP
            if service == 'wsfe':
                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 False and cbte_nro != cbte_nro_next:
                raise osv.except_osv('Error !', 
                        'Referencia: %s \n' 
                        '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.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.replace("-", "")
                if invoice.pyafipws_billing_start_date:
                    fecha_serv_desde = invoice.pyafipws_billing_start_date.replace("-", "")
                else:
                    fecha_serv_desde = None
                if  invoice.pyafipws_billing_end_date:
                    fecha_serv_hasta = invoice.pyafipws_billing_end_date.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

{'fraction_non_alphanumeric': 0.09716438627800912, 'fraction_numerical': 0.006808116861656421, 'mean_word_length': 2.052249344361509, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1510253', 'n_tokens_mistral': 4714, 'n_tokens_neox': 4464, 'n_words': 1212}