Created
June 8, 2018 03:38
-
-
Save ugurunver/07aa149770c4cfe2e698a807de19fd1e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import requests | |
try: | |
from urllib import urlencode | |
except ImportError: | |
from urllib.parse import urlencode | |
API = 'http://localhost:8000/api/v1/' | |
class Client(object): | |
""" | |
Api istek-cevap iskeletini olusturan siniftir. username ve password alir, call_api metodunu saglar. | |
""" | |
token = None | |
def __init__(self, username, password): | |
super(Client, self).__init__() | |
self.token = self._get_token(username, password) | |
def _get_token(self, username, password): | |
assert not self.token | |
data = {'username': username, 'password': password} | |
auth_url = API+'api-token-auth/' | |
response = self.call_api('POST', auth_url, data) | |
# response => {'expire_date': '2016-08-29T20:04:00.696+03:00', 'token': '3f6388844726fcacd892838df380ff2dda418d7b'} | |
return response['token'] | |
def call_api(self, method, url, data=None): | |
# donusleri json olarak yapmasi icin Accept header'i gerekli | |
headers = { | |
'Accept': 'application/json', | |
'Content-Type': 'application/json' | |
} | |
# login isteginde token olmayacak, o nedenle sarta bagli tutuldu ve parametre zorunlu yapilmadi | |
if self.token: | |
headers['Authorization'] = 'Token {}'.format(self.token) | |
data = json.dumps(data) | |
resp = requests.request(method, url, data=data, headers=headers) | |
if resp.headers.get('Content-Type') == 'application/json': | |
return resp.json() | |
return resp.content | |
class SaleClient(Client): | |
""" | |
Fatura olusturma sureci boyunca kullanilacak api metotlarini saglayan siniftir. | |
""" | |
customer_endpoint = API + 'core/customer/' | |
customer_address_endpoint = API + 'core/customeraddress/' | |
sale_endpoint = API + 'core/sale/create_nested/' | |
invoice_endpoint = API + 'finance/saleinvoice/' | |
item_endpoint = API + 'core/item/' | |
def get_currencies(self): | |
return self.call_api(method='GET', url=API + 'core/currency/')['results'] | |
def get_units(self): | |
return self.call_api(method='GET', url=API + 'core/liquidstockunits/')['results'] | |
def create_sale(self, data, create_invoice=False, send_invoice=False, fatura_tarihi=None): | |
endpoint = self.sale_endpoint + '?' | |
if create_invoice: | |
endpoint += 'create_invoice=true' | |
if send_invoice: | |
endpoint += '&send_invoice=true' | |
if create_invoice or send_invoice: | |
assert fatura_tarihi | |
endpoint += '&' + urlencode(dict(invoice_date=str(fatura_tarihi))) | |
return self.call_api(method='POST', url=endpoint, data=data) | |
def send_invoice(self, siparis_id, fatura_tarihi=None): | |
# siparis olusturulurken send_invoice True gonderilmez ise sonraki asamalarda faturasini gondermek icin | |
# bu metot kullanilir | |
endpoint = self.invoice_endpoint + 'send_invoice_for_sale/?sale_id='+str(siparis_id) | |
if fatura_tarihi: | |
endpoint += '&'+urlencode(dict(invoice_date=str(fatura_tarihi))) | |
return self.call_api(method='POST', url=endpoint) | |
def get_invoice(self, fatura_id): | |
return self.call_api(method='GET', url=self.invoice_endpoint + str(fatura_id) + '/') | |
def get_invoice_html(self, fatura_id): | |
return self.call_api(method='GET', url=self.invoice_endpoint + str(fatura_id) + '/html/') | |
def main(): | |
""" | |
Asagida ortalama bir fatura bilgisi parcalar halinde ve Propars apisindeki alan isimleriyle (urunKodu haric) bulunmakta. | |
currency ve unit id'leri cok seyrek olarak guncellendigi icin kod icinde kullanilabilir. Degerleri gormek icin | |
print(api_client.get_currencies()) | |
print(api_client.get_units()) | |
:return: | |
""" | |
api_client = SaleClient('eposta', 'parola') # panele giris yapilabilen bir eposta-parola cifti | |
""" | |
Kargo odeme secenekleri: | |
's' => "Satıcı öder" | |
'b' => "Alıcı öder" | |
'h' => "Elden teslim" (varsayilan deger budur. alan bos gonderilirse siparis elden teslim olarak kaydedilir.) | |
""" | |
""" | |
Odeme yontemleri: | |
'finance.cash' => Nakit | |
'finance.payatthedoor' => Kapida odeme | |
'finance.creditcard' => Kredi karti | |
'finance.virtualpos' => Sanal pos | |
'finance.check' => Cek | |
'finance.eft' => EFT | |
'finance.voucher' => Senet | |
'finance.moneyorder' => Havale | |
""" | |
fatura_data = { | |
'order_date': '2017-07-01T09:00:00+0300', | |
'notes': 'Fatura notları serbest metin', | |
'currency': 1, | |
'box': 'SENTBOX', # SENTBOX: Giden fatura, INBOX: Gelen fatura (varsayilani SENTBOX) | |
'einvoice_type': 'SATIS', | |
'einvoice_profile': 'TEMELFATURA', | |
'source': 'store', # store veya website olabiliyor. | |
'order_number': '012345678a', # secmeli alandir, bos birakilabilir | |
'payment_method_model': 'finance.virtualpos', | |
'cargo_payment': 'h', | |
'website_url': 'http://orneksiteadi.com', # bos birakilabilir, kaynak website iken kullanilir | |
'customer_detail': { | |
"name": 'Test Müşteri', | |
"integration_store_id": 'abc-12345', # musteri kodu | |
"email": "[email protected]", | |
"telephone_number": "02120001122", | |
"fax_number": "", | |
"city_name": "İstanbul", | |
"district": "Avcılar", | |
"company_title": "Firma Ünvanı", | |
"tax_office": "Avcılar", # vergi dairesi | |
"tax_number": "1234567890", # kurumsal musteride bu alana 10 haneli vkn yazilacak | |
"tc_identity_number": "", # bireysel musteride bu alana 11 haneli vkn yazilacak | |
"customer_type": "organizational" # bireyselde individual, kurumsalda organizational | |
}, | |
'billing_address_detail': { | |
"name": "Fatura alıcı adı veya ünvan", | |
"code": "xyz-1234", # adres kodu | |
"telephone_number": "02129998877", | |
"fax_number": "", | |
"city_name": "İstanbul", | |
"district": "Avcılar", | |
"address": "Test mahallesi. Test sokak. No: 1" | |
}, | |
'items': [ | |
{ | |
'product_name': 'Test Ürünü 1', | |
'product_code': 'abc-321---', | |
'price': '123.45', # decimal birim fiyat | |
'quantity': '10.553', # decimal miktar | |
'vat_rate': '18', # kdv orani | |
'discount_rate': '10', # iskonto orani, | |
'unit': 1, | |
'barcode': '8591111111111', # bos birakilabilir | |
'notes': 'Satır Açıklaması', # bos birakilabilir | |
'cargo_campaign_code': '1231212412312312321' # bos birakilabilir | |
}, | |
{ | |
'product_name': 'Test Ürünü 2', | |
'product_code': 'abc-321-2---', | |
'price': '10.00', # decimal birim fiyat | |
'quantity': '25.67', # decimal miktar | |
'vat_rate': '8', # kdv orani | |
'discount_rate': '0', # decimal iskonto orani, | |
'unit': 1, | |
'barcode': '8591111111112', | |
'notes': 'Satır Açıklaması', # bos birakilabilir | |
'cargo_campaign_code': '1231212412312312321' # bos birakilabilir | |
} | |
] | |
} | |
""" | |
1. Yöntem: Önce sipariş oluşturulur, fatura daha sonra farkli bir istek ile gonderilir | |
# POST /api/v1/core/sale/create_nested/?create_invoice=true&invoice_date=2018-05-02T09%3A00%3A00%2B0300 HTTP/1.1 | |
siparis = api_client.create_sale(fatura_data, create_invoice=True, fatura_tarihi='2018-05-02T09:00:00+0300') | |
fatura = api_client.send_invoice(siparis_id=siparis['id']) | |
""" | |
# 2. Yontem: Fatura siparisle ayni istekle gonderilebilir | |
# POST /api/v1/core/sale/create_nested/?send_invoice=true&invoice_date=2018-05-02T09%3A00%3A00%2B0300 HTTP/1.1 | |
siparis = api_client.create_sale(fatura_data, send_invoice=True, fatura_tarihi='2018-05-02T09:00:00+0300') | |
fatura = siparis['invoice_detail'] | |
#print(siparis) | |
print(fatura) | |
if fatura['einvoice_status'] in ('SENT', 'FAILED'): | |
# fatura turu efaturadir | |
imzali_xml_url = fatura['einvoice_xml'] | |
# ornek: http://localhost:8000/media/einvoice_dir/7F502FC4-AE5A-4C32-B03E-815DB52A21A4.xml | |
elif fatura['earchive_status'] in ('SENT', 'FAILED'): | |
earsiv_html_url = fatura['earchive_url'] | |
earsiv_zip_url = earsiv_html_url + '&type=xml' | |
# Fatura html ciktisi getirme: | |
# GET /api/v1/finance/saleinvoice/36234/html/ HTTP/1.1 | |
html = api_client.get_invoice_html(fatura_id=fatura['id']) | |
#print(html) | |
# Fatura objesini getirme | |
# GET /api/v1/finance/saleinvoice/36234/ HTTP/1.1 | |
fatura_ = api_client.get_invoice(fatura_id=fatura['id']) | |
#print(fatura_) | |
""" | |
Efatura gonderildiginde alinacak 'fatura' ornegi: | |
{'einvoice_status': 'SENT', 'einvoice_tax_exclusive_amount': None, 'earchive_url': None, | |
'einvoice_number': 'ABE2018000000006', 'earchive_failure': None, 'id': 36220, 'earchive_cancelled': False, | |
'invoice_number': 'ABE2018000000006', 'earchive_mail_sent': False, 'client': 462130, 'einvoice_type': 'SATIS', | |
'einvoice_uuid': '7F502FC4-AE5A-4C32-B03E-815DB52A21A4', 'einvoice_approval_status_code': 'KABUL', | |
'einvoice_total_tax_amount': None, 'einvoice_total_amount': None, 'einvoice_total_vat_amount': None, | |
'earchive_id': None, 'currency': 1, 'company': 10, 'earchive_status': 'PENDING', 'einvoice_approval_status': None, | |
'can_respond_einvoice': False, 'earchive_email': None, 'einvoice_failure': None, 'cancelled': False, | |
'uuid': 'd2ebfa70-39dc-47a3-8e92-1f69629a736b', 'earchive_token': None, | |
'einvoice_xml': 'http://localhost:8000/media/einvoice_dir/7F502FC4-AE5A-4C32-B03E-815DB52A21A4.xml', | |
'related_sale': 41345, 'einvoice_profile': 'TEMELFATURA', 'due_date': '2018-05-02', | |
'einvoice_sending_status_code': '0', 'earchive_signed': False, 'einvoice_response_sent': False, 'box': 'SENTBOX', | |
'einvoice_sending_status': 'BEKLEMEDE', 'invoice_date': '2018-05-02T06:00:00Z', 'notes': 'Fatura notları metni'} | |
einvoice_status -> SENT (veya hata olustu ise FAILED) | |
invoice_number -> fatura numarasi | |
'einvoice_xml': 'http://localhost:8000/media/einvoice_dir/7F502FC4-AE5A-4C32-B03E-815DB52A21A4.xml' | |
""" | |
""" | |
Earsiv gonderildiginde alinacak 'fatura' ornegi: | |
{'earchive_status': 'SENT', 'einvoice_total_tax_amount': None, 'can_respond_einvoice': False, | |
'einvoice_approval_status': None, 'earchive_mail_sent': False, 'cancelled': False, 'earchive_signed': False, | |
'earchive_url': 'http://172.17.0.6:8000/invoice/?uuid=4a093787-3167-4794-9803-b662353f5c4a&token=5ubOS4DR3lS7dnNdDCTNXfqG7Rb94C8LfccxDsWtP7a8bTp5PH', | |
'earchive_token': '5ubOS4DR3lS7dnNdDCTNXfqG7Rb94C8LfccxDsWtP7a8bTp5PH', 'einvoice_total_amount': None, 'id': 36228, | |
'einvoice_uuid': None, 'einvoice_status': 'PENDING', 'einvoice_response_sent': False, 'einvoice_number': None, | |
'uuid': '4a093787-3167-4794-9803-b662353f5c4a', 'earchive_id': '4a093787-3167-4794-9803-b662353f5c4a', | |
'einvoice_failure': None, 'einvoice_xml': None, 'client': 462128, 'einvoice_tax_exclusive_amount': None, | |
'invoice_date': '2018-05-02T06:00:00Z', 'earchive_cancelled': False, 'einvoice_profile': 'TEMELFATURA', | |
'einvoice_approval_status_code': 'KABUL', 'einvoice_sending_status': None, 'earchive_failure': None, | |
'einvoice_type': 'SATIS', 'earchive_email': '[email protected]', 'notes': 'Fatura notları serbest metin', | |
'company': 10, 'related_sale': 41353, 'einvoice_total_vat_amount': None, 'due_date': '2018-05-02', | |
'einvoice_sending_status_code': None, 'box': 'SENTBOX', 'currency': 1, 'invoice_number': 'ABC2018000000017'} | |
earchive_status -> SENT (veya hata olustu ise FAILED) | |
invoice_number -> fatura numarasi | |
'earchive_url': 'http://172.17.0.6:8000/invoice/?uuid=4a093787-3167-4794-9803-b662353f5c4a&token=5ubOS4DR3lS7dnNdDCTNXfqG7Rb94C8LfccxDsWtP7a8bTp5PH' | |
earsiv xml'ine erişmek için bu url'in sonuna &type=xml eklenir. bu adresten içinde xml olan zip indirilir: | |
http://172.17.0.6:8000/invoice/?uuid=4a093787-3167-4794-9803-b662353f5c4a&token=5ubOS4DR3lS7dnNdDCTNXfqG7Rb94C8LfccxDsWtP7a8bTp5PH&type=xml | |
""" | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment