boris-savic / python-furs-fiscal Goto Github PK
View Code? Open in Web Editor NEWPython library for simplified communication with FURS (Finančna uprava Republike Slovenije).
License: MIT License
Python library for simplified communication with FURS (Finančna uprava Republike Slovenije).
License: MIT License
When I try to send data for changed invoice I get error "S002 - Sporočilo ni v skladu s shemo JSON". It is problem with these variables:
If I remove this values everything works fine. Variable values are the same as this:
Since commits from 12.nov I get openssl error.
Exception return: "[('system library', 'fopen', 'Broken pipe'), ('BIO routines', 'FILE_CTRL', 'system lib'), ('SSL routines', 'SSL_CTX_use_certificate_file', 'system lib')]"
python furs_script.py
Traceback (most recent call last):
File "furs_script.py", line 35, in
invoice_amount=66.71)
File "build/bdist.linux-x86_64/egg/furs_fiscal/api.py", line 347, in get_invoice_eor
File "build/bdist.linux-x86_64/egg/furs_fiscal/base_api.py", line 45, in _send_request
File "build/bdist.linux-x86_64/egg/furs_fiscal/connector.py", line 124, in post
File "build/bdist.linux-x86_64/egg/furs_fiscal/connector.py", line 111, in _jwt_sign
TypeError: sign() got an unexpected keyword argument 'claims'
Reading invoice_demo.py it is not obvious no remote calls are being made. One is clearly creating API object. It is used only for signing, but this is only clear after reading api.py.
I think it would make more sense to have one API class, not three separate (FURSBaseAPI, FURSBusinessPremiseAPI and FURSInvoiceAPI), which would handle all remote calls. Using this class then makes clear remote calls are being made.
Signing functions are also used locally, it may be sensible to bring signing logic/cert handling together. Signing is now done in connector.py and in base_api.py.
Local Invoice API part could maybe benefit from a richer set of objects, such as:
class Register(object):
invoice_serial = 0
def __init__(self, tax_number, business_premise_id, electronic_device_id):
self.tax_number = tax_numbe
self.business_premise_id = business_premise_id
self.electronic_device_id = electronic_device_id
def invoice(self, issued_date, invoice_amount, low_tax_rate_base, low_tax_rate_amount, ...):
# generate Invoice object, which has ZOI and EOR (after requesting) attributes
Register.invoice_serial += 1
return Invoice(Register.invoice_serial, issued_date, invoice_amount, ...)
Since there's a possibility of reissuing requests, you also probably want to abstract this and keep the state of invoice somewhere, maybe check presence of eor attribute.
Also consider adding warning if you see floats as input values. All kinds of madness lies in mixing floats with money.
Please correct to:
message['InvoiceRequest']['Invoice']['SubsequentSubmit'] = True
message['InvoiceRequest']['Invoice']['CustomerVATNumber'] = customer_vat_number
Vir:
http://www.datoteke.fu.gov.si/dpr/files/wsdl_v1/FiscalVerificationSchema.json
Add TLS certificate verification for production environment.
In case you want to send request from abroad you get generic error instead of real message.
furs_fiscal/api.py", line 378, in get_invoice_eor
response = self._send_request(path=INVOICE_ISSUE_PATH, data=message)
furs_fiscal/base_api.py", line 54, in _send_request
server_response = json.loads(jws.get_unverified_claims(response.json()['token']))
requests/models.py", line 975, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
We added our logger to module to checked why and that's the response we get:
13:41:47 23-06-15[SI] _send_request | <html><head><title>Request Rejected</title></head><body>Vaša zahteva je bila zavrnjena. <br> Preverite prosim zahteve za povezavo na sistem Davčnih Blagajn http://www.fu.gov.si/ ali pišite nam na dev.blagajne.fu(at)gov.si. Pri pošiljanju vprašanje se sklicujte na to številko napake: 7171623449764729547. <br>
Najpogostejša vzroka sta poskus dostopa iz tujine (izven SLO) ali napačen URL naslov v zahtevku. <br><br>
Your request was rejected. <br> Please check the requirements at http://www.fu.gov.si/ or contact us at dev.blagajne.fu (at) gov.si. When sending a question, please refer to this error id: 7171623449764729547. <br>
The most common causes are an attempt to access from abroad (outside SLO ) or an incorrect URL in the request. <br></body></html>
Solution is to send them an IP and they whitelist it, but this module should return that information without hacking.
Hello!
Please add support for ClosingTag:
Vpiše se podatek o zaprtju poslovnega prostora, če gre za trajno zaprtje. Možna je vrednost »Z«. Po zaprtju v tem poslovnem prostoru ni več možno izdajati računov in računov z oznako tega poslovnega prostora ni več možno posredovati davčnemu organu. / The data is entered about the closure of business premises if the closure is permanent. The possible value is »Z«. After closure issuing invoices is not possible anymore in these business premises and it is not possible to submit invoices to the tax authority with the mark of these business premises.
def _build_common_message_body(*args, **kwargs):
data = dict()
clotag = kwargs['closing_tag']
data['BusinessPremiseRequest'] = {
'Header': FURSBusinessPremiseAPI._prepare_business_premise_request_header(),
'BusinessPremise': {
'TaxNumber': kwargs['tax_number'],
'BusinessPremiseID': kwargs['premise_id'],
'ValidityDate': kwargs['validity_date'].strftime("%Y-%m-%d"),
'ClosingTag': clotag,
'SpecialNotes': kwargs['special_notes'],
'SoftwareSupplier': [
FURSBusinessPremiseAPI._prepare_software_supplier_json(kwargs['software_supplier_tax_number'],
kwargs['foreign_software_supplier_name'])
],
'BPIdentifier': {}
}
}
if (clotag is None) or clotag=='':
data['BusinessPremiseRequest']['BusinessPremise'].pop('ClosingTag')
return data
Jose 'sign()' function changed. Argument 'claims' changed to 'payload'. It would be great if it will be changed in furs fiscal too.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.