Skip to content

Instantly share code, notes, and snippets.

@ugurunver
Created June 8, 2018 03:38
Show Gist options
  • Save ugurunver/07aa149770c4cfe2e698a807de19fd1e to your computer and use it in GitHub Desktop.
Save ugurunver/07aa149770c4cfe2e698a807de19fd1e to your computer and use it in GitHub Desktop.
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