Creare factură¶
Descriere - Creare factură¶
Această secțiune este dedicată creării unei facturi noi
Această operațiune va returna identificatorul Keez al noii facturi externalId
Nu se poate crea sau modifica o factură fără articole, dacă nu există articolul pentru factură, acesta se creează înaintea facturii: Vezi Creare Articol
Facturile sunt de 2 tipuri:
Facturi pentru persoane fizice
Facturi pentru persoane juridice
Diferența dintre facturile PF și PJ o face modul de completare a proprietății «partner» din modelul de request:
Pentru PJ se va folosi Vezi Model Persoane juridice
Pentru PF se va folosi Vezi Model Persoane fizice
- Operații care se pot realiza după ce o factură a fost creată:
Model de utilizare API - Creare factură¶
Așa cum este explicat în zona de Informații generale utilizare API orice apel către API se face prin URL-ul de bază + endpoint-ul respectivei operații
Notă
Verb: POST
Endpoint: /{clientEid}/invoices
Request parameter: {clientEid}
Request body: {data_body}
Returns: externalId
Type of return: String
Atenționare
A se observa parametrul {clientEid} și tipul acestuia (path variable)
A se observa parametrul {data_body} și tipul acestuia (request body)
Model de request body - Creare factură¶
Request body-ul se creează în prealabil, înaintea apelului către API
Acesta va conține informațiile specifice acelei facturi
Modelul acestui request body se regăsește în tabelul din Vezi Model factură
Informațiile obligatorii de completat pentru o factură sunt semnalizate în coloana «Coloană obligatorie» din modelul de mai sus
Formatul de date primit de fiecare parametrul în parte este specificat în coloana «Format» din modelul de mai sus
Model pentru facturi PF:
data_body = {
'series': 'SERIE',
'documentDate': 20190102,
'dueDate': 20190102,
'vatOnCollection': False,
'currencyCode': 'EUR',
'exchangeRate': 4.82,
'originalNetAmount': 482,
'originalNetAmountCurrency': 100,
'originalVatAmount': 0,
'originalVatAmountCurrency': 0,
'netAmount': 482,
'netAmountCurrency': 100,
'vatAmount': 0,
'vatAmountCurrency': 0,
'grossAmount': 482,
'grossAmountCurrency': 100,
'paymentTypeId': 1,
'partner': {
'isLegalPerson': False,
'identificationNumber': '1930912217543',
'partnerName': 'Marian Ion',
'countryCode': 'RO',
'countryName': 'Romania',
'countyCode': 'RO-B',
'countyName': 'Bucuresti',
'cityName': 'Sector 1',
'addressDetails': 'Strada Maria Tanase nr. 1'
},
'invoiceDetails': [
{
'itemExternalId': '{ID_EXTERN_ARTICOL}',
'measureUnitId': 1,
'quantity': 1,
'unitPrice': 100,
'originalNetAmount': 482,
'originalNetAmountCurrency': 100,
'originalVatAmount': 0,
'originalVatAmountCurrency': 0,
'netAmount': 482,
'netAmountCurrency': 100,
'vatAmount': 0,
'vatAmountCurrency': 0,
'grossAmount': 482,
'grossAmountCurrency': 100,
}
]
}
Model pentru facturi PF:
data_body = {
'series': 'SERIE',
'number': 1,
'documentDate': 20190102,
'dueDate': 20190102,
'vatOnCollection': False,
'currencyCode': 'RON',
'originalNetAmount': 100,
'originalNetAmountCurrency': 100,
'originalVatAmount': 0,
'originalVatAmountCurrency': 0,
'netAmount': 100,
'netAmountCurrency': 100,
'vatAmount': 0,
'vatAmountCurrency': 0,
'grossAmount': 100,
'grossAmountCurrency': 100,
'paymentTypeId': 1,
'partner': {
'isLegalPerson': true,
'partnerName': 'CENTRUL MEDICAL UNIREA SRL',
'registrationNumber': 'J40/15930/1991',
'identificationNumber': '5919324',
'taxAttribute': 'RO',
'countryCode': 'RO',
'countryName': 'Romania',
'countyCode': 'RO-B',
'countyName': 'BUCURESTI',
'cityName': 'Sector 1',
'addressDetails': 'PŢA. CHARLES DE GAULLE, NR.15, BL.CLADIREA CHARLES DE GAULLE PLAZA, ET.4 '
},
'invoiceDetails': [
{
'itemExternalId': '{ID_EXTERN_ARTICOL}',
'measureUnitId': 1,
'quantity': 1,
'unitPrice': 100,
'originalNetAmount': 100,
'originalNetAmountCurrency': 100,
'originalVatAmount': 0,
'originalVatAmountCurrency': 0,
'netAmount': 100,
'netAmountCurrency': 100,
'vatAmount': 0,
'vatAmountCurrency': 0,
'grossAmount': 100,
'grossAmountCurrency': 120
}
]
}
Notă
Dacă există deja o factură cu o anumită serie, nu mai trebuie completat numărul, acesta se va completa cu următorul disponibil Exemplu:
Dacă fac prima factură cu seria SRS atunci va trebui să completez proprietatea «number» cu numărul de început al acestei serii (nu trebuie să fie neapărat 1)
Dacă există deja o factură pe seria SRS atunci NU trebuie să pun proprietatea «number». Se va completa automat.
Validări - Creare factură¶
La momentul executării acestui apel se vor verifica și valida următoarele:
Dacă există factura
Toate proprietățile obligatorii trebuie să fie completate
Seria facturii nu permite spații
Se verifică dacă pentru seria facturii create există deja un număr generat
Data scadentă nu poate să fie mai mică decât data facturii
Dacă discount-ul este global atunci toate valorile de discount de pe articol trebuie să fie egale cu cele de pe factură
Dacă discount-ul este procentual atunci procentul de discount trebuie completat
Dacă discount-ul este valoric atunci procentul de discount nu trebuie să fie completat
Valoarea discount-ului pentru articol nu poate să fie mai mare decât valoarea netă a articolului
Procentul de discount pentru articol nu poate să fie mai mare de 100%
Dacă factura are articole care conțin accize atunci factura și articolul trebuie să conțină acest calcul
Este obligatoriu pentru persoanele fizice completarea adresei sau a CNP-ului
Verificările și validările vor arunca (throw) mesaje de eroare sub formă de excepție (Vezi Model Excepție) atașate de un cod HTTP error 500. Vezi Coduri eroare posibile
Mod de folosire - Wrapper - Creare factură¶
- Dacă se folosește wrapper-ul scris în Python se utilizează astfel:
Se preia token-ul Vezi Autorizarea
Se apelează metoda specifică acestui request POST
token_url = 'https://staging.keez.ro/idp/connect/token' api_url = f'https://{ENVIRONMENT}.keez.ro/api/v1.0/public-api' client_eid = '{RECEIVED_CLIENT_EID}' application_id = '{RECEIVED_APPLICATION_ID}' secret = '{RECEIVED_SECRET}' api = KeezPublicApi(app=application_id, secret=secret, token_url=token_url, api_url=api_url) data_body = { 'series': 'SERIE', 'documentDate': 20190102, 'dueDate': 20190102, 'vatOnCollection': False, 'currencyCode': 'EUR', 'exchangeRate': 4.82, 'originalNetAmount': 482, 'originalNetAmountCurrency': 100, 'originalVatAmount': 0, 'originalVatAmountCurrency': 0, 'netAmount': 482, 'netAmountCurrency': 100, 'vatAmount': 0, 'vatAmountCurrency': 0, 'grossAmount': 482, 'grossAmountCurrency': 100, 'paymentTypeId': 1, 'partner': { 'isLegalPerson': False, 'identificationNumber': '1930912217543', 'partnerName': 'Marian Ion', 'countryCode': 'RO', 'countryName': 'Romania', 'countyCode': 'RO-B', 'countyName': 'Bucuresti', 'cityName': 'Sector 1', 'addressDetails': 'Strada Maria Tanase nr. 1' }, 'invoiceDetails': [ { 'itemExternalId': '{ID_EXTERN_ARTICOL}', 'measureUnitId': 1, 'quantity': 1, 'unitPrice': 100, 'originalNetAmount': 482, 'originalNetAmountCurrency': 100, 'originalVatAmount': 0, 'originalVatAmountCurrency': 0, 'netAmount': 482, 'netAmountCurrency': 100, 'vatAmount': 0, 'vatAmountCurrency': 0, 'grossAmount': 482, 'grossAmountCurrency': 100, } ] } result = api.create_invoice(client_eid, data_body)
Mod de folosire - Fără Wrapper - Creare factură¶
class InvoiceService: def __init__(self): token = TokenService() self.auth_token = token.generate_token() self.token = f'{self.auth_token.get("token_type")} {self.auth_token.get("access_token")}' self.client_eid = token.client_eid self.api_endpoint = token.api_endpoint def createInvoice(self): invoice_url = f'{self.api_endpoint}/{self.client_eid}/invoices' data_body = { 'series': 'SERIE', 'documentDate': 20190102, 'dueDate': 20190102, 'vatOnCollection': False, 'currencyCode': 'EUR', 'exchangeRate': 4.82, 'originalNetAmount': 482, 'originalNetAmountCurrency': 100, 'originalVatAmount': 0, 'originalVatAmountCurrency': 0, 'netAmount': 482, 'netAmountCurrency': 100, 'vatAmount': 0, 'vatAmountCurrency': 0, 'grossAmount': 482, 'grossAmountCurrency': 100, 'paymentTypeId': 1, 'partner': { 'isLegalPerson': False, 'identificationNumber': '1930912217543', 'partnerName': 'Marian Ion', 'countryCode': 'RO', 'countryName': 'Romania', 'countyCode': 'RO-B', 'countyName': 'Bucuresti', 'cityName': 'Sector 1', 'addressDetails': 'Strada Maria Tanase nr. 1' }, 'invoiceDetails': [ { 'itemExternalId': '{ID_EXTERN_ARTICOL}', 'measureUnitId': 1, 'quantity': 1, 'unitPrice': 100, 'originalNetAmount': 482, 'originalNetAmountCurrency': 100, 'originalVatAmount': 0, 'originalVatAmountCurrency': 0, 'netAmount': 482, 'netAmountCurrency': 100, 'vatAmount': 0, 'vatAmountCurrency': 0, 'grossAmount': 482, 'grossAmountCurrency': 100, } ] } _req = requests.post(url=invoice_url, headers={'Content-Type': 'application/json', 'Authorization': self.token}, json=data_body) return _req.json() if __name__ == '__main__': service = InvoiceService() invoice = service.createInvoice() print(invoice)Notă
Clasa TokenService() se găsește la secțiunea Autorizarea: Vezi Autorizarea