feat(solucion_factible): nuevo esquema de cancelacion

se agrega sf_consult para consultar el estado del cfdi, y en la cancelacion se verifica que el
estatus sea 200(cancelada) o 211 (en proceso)
parent 5271509b
......@@ -3,3 +3,4 @@
from . import pac_answer
from . import xpd_envelopes
from . import finkok_envelopes
from . import sf_envelopes
# -*- coding: utf-8 -*-
_SOAPENV_CONSULTAR = """<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.cfdi.solucionfactible.com" xmlns:xsd="http://ws.cfdi.solucionfactible.com/xsd">
<soapenv:Header/>
<soapenv:Body>
<ws:getStatusCancelacionAsincrona>
<!--Optional:-->
<ws:usuario>%s</ws:usuario>
<!--Optional:-->
<ws:password>%s</ws:password>
<!--Optional:-->
<ws:transactionId>%s</ws:transactionId>
<!--Zero or more repetitions:-->
<ws:properties>
<!--Optional:-->
<xsd:key></xsd:key>
<!--Optional:-->
<xsd:value></xsd:value>
</ws:properties>
</ws:getStatusCancelacionAsincrona>
</soapenv:Body>
</soapenv:Envelope>
"""
\ No newline at end of file
......@@ -6,19 +6,25 @@ import codecs
import logging
import time
import xml.dom.minidom
from requests import Request, Session
import xmltodict
from SOAPpy import WSDL
from SOAPpy.Errors import HTTPError, RecursionError, UnderflowError, UnknownTypeError
from openerp import api, fields, models, tools
from openerp.tools.translate import _
from ..lib.pac_answer import PacCancelAnswer
from ..lib import sf_envelopes
from ..lib.pac_answer import PacCancelAnswer, PacConsultAnswer
from ..models import exceptions as pac_exceptions
logger = logging.getLogger(__name__)
TIMEOUT = 60
_ACTIONS = {"timbrar": "", "cancelar": "", "consultar": '"urn:getStatusCancelacionAsincrona"'}
class ParamsPac(models.Model):
_inherit = "params.pac"
......@@ -52,6 +58,20 @@ class ParamsPac(models.Model):
factura_mx_type__fc.update({"pac_sf": self.sf_cancel})
return factura_mx_type__fc
def get_driver_fc_consult(self):
factura_mx_type__fc = super(ParamsPac, self).get_driver_fc_cancel()
if factura_mx_type__fc is None:
factura_mx_type__fc = {}
factura_mx_type__fc.update({"pac_sf": self.sf_consult})
return factura_mx_type__fc
@classmethod
def create_header(cls, method):
return {
"SOAPAction": "%s" % (_ACTIONS[method]),
"Content-Type": "text/xml;charset=UTF-8",
}
def sf_cancel(self, uuid):
vat_emmiter = self.company_id.partner_id.vat_split
# Get values necessary values from PAC configuration
......@@ -103,7 +123,7 @@ class ParamsPac(models.Model):
code=cancel_answer, message=mensaje_cancel,
)
# Cancel process was unsuccessful
elif cancel_answer.estatus not in "200":
elif cancel_answer.estatus not in ("200", "211"):
raise Exception(
" ".join(["Code", status_cancel, mensaje_cancel]),
)
......@@ -288,3 +308,62 @@ class ParamsPac(models.Model):
attrs_types=node_partner_attrs_types,
)
return xml_res_str
def sf_consult(self, uuid):
""" Consul the cfdi status
:param uuid: UUID of CFDI to consult
"""
method = "consultar"
cfdi = self.env["ir.attachment.facturae.mx"].search([["uuid", "=", uuid]])
try:
data = sf_envelopes._SOAPENV_CONSULTAR % (
self.user,
self.password,
cfdi.uuid.encode("utf-8"),
)
except Exception as e:
e.message = "Error al crear ENVELOPE"
logger.info(e)
raise e
else:
logger.debug(data)
headers = self.create_header(method)
s = Session()
req = Request("POST", self.url_webservice_cancel, data=data, headers=headers)
prepped = req.prepare()
try:
# Timbrar factura
response = s.send(prepped, timeout=TIMEOUT)
res = xmltodict.parse(response.text)
logger.debug(res)
except Exception as e:
# Error al establecer comunicación con el PAC
logger.debug(e)
raise e
# Procesar los resultados obtenidos del PAC
try:
resultado = res["soapenv:Envelope"]["soapenv:Body"][
"ns:getStatusCancelacionAsincronaResponse"
][
"ns:return"
]
except KeyError as e:
resultado = res["soapenv:Envelope"]["soapenv:Body"][
"ns2:consultarCfdiResponse"
][
"ns2:consultarCfdiResponse"
] # noqa
logger.debug(e)
except Exception as e:
logger.debug(e)
raise UserError(_("Unknow answer.\n%s") % resultado)
status_cancelacion = resultado["ax27:status"]
if status_cancelacion in ("211", "213", "204"):
estado_cfdi = "Vigente"
elif status_cancelacion in "200":
estado_cfdi = "Cancelado"
elif status_cancelacion in "702":
estado_cfdi = "No encontrado"
consult_answer = PacConsultAnswer(uuid, estado_cfdi, status_cancelacion)
return consult_answer
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment