Cancel old with Finkok
This commit is contained in:
parent
854c7fb4a2
commit
7639f20ae7
|
@ -78,6 +78,8 @@ class PACComercioDigital(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.error = ''
|
self.error = ''
|
||||||
|
# ~ self.cfdi_uuid = ''
|
||||||
|
# ~ self.date_stamped = ''
|
||||||
|
|
||||||
def _error(self, msg):
|
def _error(self, msg):
|
||||||
self.error = str(msg)
|
self.error = str(msg)
|
||||||
|
@ -229,9 +231,10 @@ class PACComercioDigital(object):
|
||||||
|
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
def cancel_xml(self, cfdi, xml, info, auth={}):
|
def cancel_xml(self, xml, auth={}, cfdi='', info={'tipo': 'cfdi3.3'}):
|
||||||
if not auth:
|
if DEBUG or not auth:
|
||||||
auth = AUTH
|
auth = AUTH
|
||||||
|
|
||||||
url = self.URL['cancelxml']
|
url = self.URL['cancelxml']
|
||||||
headers = self._get_headers_cancel_xml(cfdi, info, auth)
|
headers = self._get_headers_cancel_xml(cfdi, info, auth)
|
||||||
result = self._post(url, xml, headers)
|
result = self._post(url, xml, headers)
|
||||||
|
@ -246,7 +249,14 @@ class PACComercioDigital(object):
|
||||||
self._error(result.headers['errmsg'])
|
self._error(result.headers['errmsg'])
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
return result.text
|
tree = ET.fromstring(result.text)
|
||||||
|
date_cancel = tree.xpath('string(//Acuse/@Fecha)')[:19]
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'acuse': result.text,
|
||||||
|
'date': date_cancel,
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
def status(self, data, auth={}):
|
def status(self, data, auth={}):
|
||||||
if not auth:
|
if not auth:
|
||||||
|
|
|
@ -47,7 +47,7 @@ logging.getLogger('zeep').setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
|
||||||
TIMEOUT = 10
|
TIMEOUT = 10
|
||||||
DEBUG_SOAP = True
|
DEBUG_SOAP = False
|
||||||
|
|
||||||
|
|
||||||
class DebugPlugin(Plugin):
|
class DebugPlugin(Plugin):
|
||||||
|
@ -113,6 +113,10 @@ class PACFinkok(object):
|
||||||
self._error = 'UUID ' + self.CODE['NE']
|
self._error = 'UUID ' + self.CODE['NE']
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
if ce == 'UUID Not Found':
|
||||||
|
self._error = 'UUID ' + self.CODE['NE']
|
||||||
|
return {}
|
||||||
|
|
||||||
if self.CODE['200'] != ce:
|
if self.CODE['200'] != ce:
|
||||||
log.error('CodEstatus', type(ce), ce)
|
log.error('CodEstatus', type(ce), ce)
|
||||||
return result
|
return result
|
||||||
|
@ -192,7 +196,7 @@ class PACFinkok(object):
|
||||||
return rfc_emisor, cfdi_uuid
|
return rfc_emisor, cfdi_uuid
|
||||||
|
|
||||||
def cancel(self, cfdi, info, auth={}):
|
def cancel(self, cfdi, info, auth={}):
|
||||||
if not auth:
|
if DEBUG or not auth:
|
||||||
auth = AUTH
|
auth = AUTH
|
||||||
|
|
||||||
rfc_emisor, cfdi_uuid = self._get_data_cancel(cfdi)
|
rfc_emisor, cfdi_uuid = self._get_data_cancel(cfdi)
|
||||||
|
@ -228,8 +232,8 @@ class PACFinkok(object):
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def cancel_xml(self, xml, auth={}):
|
def cancel_xml(self, xml, auth={}, cfdi=''):
|
||||||
if not auth:
|
if DEBUG or not auth:
|
||||||
auth = AUTH
|
auth = AUTH
|
||||||
|
|
||||||
method = 'cancel'
|
method = 'cancel'
|
||||||
|
@ -251,6 +255,12 @@ class PACFinkok(object):
|
||||||
|
|
||||||
folio = result['Folios']['Folio'][0]
|
folio = result['Folios']['Folio'][0]
|
||||||
status = folio['EstatusUUID']
|
status = folio['EstatusUUID']
|
||||||
|
|
||||||
|
if status == '708':
|
||||||
|
self._error = 'Error 708 del SAT, intenta más tarde.'
|
||||||
|
log.error(self.error)
|
||||||
|
return ''
|
||||||
|
|
||||||
if status != '201':
|
if status != '201':
|
||||||
log.debug(f'Cancel status: {status} -')
|
log.debug(f'Cancel status: {status} -')
|
||||||
|
|
||||||
|
|
|
@ -1,230 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
#~ import re
|
|
||||||
#~ from xml.etree import ElementTree as ET
|
|
||||||
#~ from requests import Request, Session, exceptions
|
|
||||||
import datetime
|
|
||||||
import hashlib
|
|
||||||
import os
|
|
||||||
import requests
|
|
||||||
import time
|
|
||||||
from lxml import etree
|
|
||||||
from xml.dom.minidom import parseString
|
|
||||||
from xml.sax.saxutils import escape, unescape
|
|
||||||
from uuid import UUID
|
|
||||||
|
|
||||||
from logbook import Logger
|
|
||||||
from zeep import Client
|
|
||||||
from zeep.plugins import HistoryPlugin
|
|
||||||
from zeep.cache import SqliteCache
|
|
||||||
from zeep.transports import Transport
|
|
||||||
from zeep.exceptions import Fault, TransportError
|
|
||||||
from requests.exceptions import ConnectionError
|
|
||||||
|
|
||||||
|
|
||||||
class Finkok(object):
|
|
||||||
|
|
||||||
def _get_xml(self, uuid):
|
|
||||||
if not self._validate_uuid(uuid):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
method = 'util'
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
|
|
||||||
args = {
|
|
||||||
'username': self._auth['USER'],
|
|
||||||
'password': self._auth['PASS'],
|
|
||||||
'uuid': uuid,
|
|
||||||
'taxpayer_id': self.rfc,
|
|
||||||
'invoice_type': 'I',
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
result = client.service.get_xml(**args)
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
except TransportError as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
if result.error:
|
|
||||||
self.error = result.error
|
|
||||||
return ''
|
|
||||||
|
|
||||||
tree = parseString(result.xml)
|
|
||||||
xml = tree.toprettyxml(encoding='utf-8').decode('utf-8')
|
|
||||||
return xml
|
|
||||||
|
|
||||||
def recupera_xml(self, file_xml='', uuid=''):
|
|
||||||
self.error = ''
|
|
||||||
if uuid:
|
|
||||||
return self._get_xml(uuid)
|
|
||||||
|
|
||||||
method = 'timbra'
|
|
||||||
ok, xml = self._validate_xml(file_xml)
|
|
||||||
if not ok:
|
|
||||||
return ''
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
try:
|
|
||||||
result = client.service.stamped(
|
|
||||||
xml, self._auth['user'], self._auth['pass'])
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return self._check_result(method, result)
|
|
||||||
|
|
||||||
def estatus_xml(self, uuid):
|
|
||||||
method = 'timbra'
|
|
||||||
if not self._validate_uuid(uuid):
|
|
||||||
return ''
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
try:
|
|
||||||
result = client.service.query_pending(
|
|
||||||
self._auth['USER'], self._auth['PASS'], uuid)
|
|
||||||
return result.status
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def get_acuse(self, rfc, uuids, type_acuse='C'):
|
|
||||||
for u in uuids:
|
|
||||||
if not self._validate_uuid(u):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
method = 'cancel'
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
|
|
||||||
args = {
|
|
||||||
'username': self._auth['USER'],
|
|
||||||
'password': self._auth['PASS'],
|
|
||||||
'taxpayer_id': rfc,
|
|
||||||
'uuid': '',
|
|
||||||
'type': type_acuse,
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
result = []
|
|
||||||
for u in uuids:
|
|
||||||
args['uuid'] = u
|
|
||||||
r = client.service.get_receipt(**args)
|
|
||||||
result.append(r)
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def estatus_cancel(self, uuids):
|
|
||||||
for u in uuids:
|
|
||||||
if not self._validate_uuid(u):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
method = 'cancel'
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
|
|
||||||
args = {
|
|
||||||
'username': self._auth['USER'],
|
|
||||||
'password': self._auth['PASS'],
|
|
||||||
'uuid': '',
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
result = []
|
|
||||||
for u in uuids:
|
|
||||||
args['uuid'] = u
|
|
||||||
r = client.service.query_pending_cancellation(**args)
|
|
||||||
result.append(r)
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def get_date(self):
|
|
||||||
method = 'util'
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
try:
|
|
||||||
result = client.service.datetime(AUTH['USER'], AUTH['PASS'])
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
if result.error:
|
|
||||||
self.error = result.error
|
|
||||||
return
|
|
||||||
|
|
||||||
return result.datetime
|
|
||||||
|
|
||||||
def edit_client(self, rfc, status=True):
|
|
||||||
"""
|
|
||||||
Se requiere cuenta de reseller para usar este método
|
|
||||||
status = 'A' or 'S'
|
|
||||||
"""
|
|
||||||
auth = AUTH['RESELLER']
|
|
||||||
|
|
||||||
sv = {False: 'S', True: 'A'}
|
|
||||||
method = 'client'
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
args = {
|
|
||||||
'reseller_username': auth['USER'],
|
|
||||||
'reseller_password': auth['PASS'],
|
|
||||||
'taxpayer_id': rfc,
|
|
||||||
'status': sv[status],
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
result = client.service.edit(**args)
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def get_client(self, rfc):
|
|
||||||
"""Regresa el estatus del cliente
|
|
||||||
.
|
|
||||||
Se requiere cuenta de reseller para usar este método
|
|
||||||
|
|
||||||
Args:
|
|
||||||
rfc (str): El RFC del emisor
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict
|
|
||||||
'message': None,
|
|
||||||
'users': {
|
|
||||||
'ResellerUser': [
|
|
||||||
{
|
|
||||||
'status': 'A',
|
|
||||||
'counter': 0,
|
|
||||||
'taxpayer_id': '',
|
|
||||||
'credit': 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
} or None si no existe
|
|
||||||
"""
|
|
||||||
auth = AUTH['RESELLER']
|
|
||||||
|
|
||||||
method = 'client'
|
|
||||||
client = Client(
|
|
||||||
URL[method], transport=self._transport, plugins=self._plugins)
|
|
||||||
args = {
|
|
||||||
'reseller_username': auth['USER'],
|
|
||||||
'reseller_password': auth['PASS'],
|
|
||||||
'taxpayer_id': rfc,
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
result = client.service.get(**args)
|
|
||||||
except Fault as e:
|
|
||||||
self.error = str(e)
|
|
||||||
return ''
|
|
||||||
except TransportError as e:
|
|
||||||
self.errorcancel = str(e)
|
|
||||||
return ''
|
|
||||||
|
|
||||||
return result
|
|
Loading…
Reference in New Issue