Private
Public Access
1
0
Files
rowsandall/rowers/idoklad.py
2024-12-30 15:01:41 +01:00

250 lines
7.6 KiB
Python

import requests
import json, yaml
from requests.auth import HTTPBasicAuth
import urllib.parse
from rowers.utils import dologging
import datetime
from django.utils import timezone
from rowsandall_app.settings import (
IDOKLAD_CLIENT_ID, IDOKLAD_CLIENT_SECRET,
)
contacts_url = 'https://api.idoklad.cz/v3/Contacts'
invoice_url = 'https://api.idoklad.cz/v3/IssuedInvoices'
email_url = 'https://api.idoklad.cz/v3/Mails/IssuedInvoice/Send'
from rowers.tasks import handle_send_email_noinvoice
from rowers.utils import myqueue
import django_rq
queuehigh = django_rq.get_queue('high')
from rowers.models import iDokladToken
#idoklad_countries = json.loads(open('rowers/idoklad_countries.json').read())["Data"]["Items"]
with open('rowers/idoklad_countries.yaml') as f:
idoklad_countries = yaml.load(f, Loader=yaml.FullLoader)["Data"]["Items"]
def get_country_id(code):
for c in idoklad_countries:
if c['Code'] == code:
return c['Id']
return 1
def idoklad_token():
try:
token = iDokladToken.objects.all().order_by('-updated_at')[0]
except iDokladToken.DoesNotExist:
return None
except IndexError:
return None
if token.updated_at + datetime.timedelta(seconds=token.expires_in) < timezone.now():
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {
'grant_type': 'refresh_token',
'client_id': IDOKLAD_CLIENT_ID,
'client_secret': IDOKLAD_CLIENT_SECRET,
'scope': 'eet offline_access',
'refresh_token': token.refresh_token,
}
response = requests.post('https://identity.idoklad.cz/server/connect/token', headers=headers, data=data)
if response.status_code == 200:
token_json = response.json()
token = iDokladToken.objects.all().order_by('-updated_at')[0]
token.access_token = token_json['access_token']
token.id_token = token_json['id_token']
token.refresh_token = token_json['refresh_token']
token.expires_in = token_json['expires_in']
token.updated_at = timezone.now()
token.save()
return token
else:
return None
return token
def get_contacts(rower):
token = idoklad_token()
if token is None:
return None
headers = {
'Authorization': 'Bearer {t}'.format(t=token.access_token),
}
url = contacts_url+'?filter=(Email~eq~'+urllib.parse.quote(rower.user.email)+')'
dologging('idoklad.log','Searching Contact url: '+str(url))
res = requests.get(url, headers=headers)
dologging('idoklad.log','Searching Contact Status code '+str(res.status_code)+'\n')
if res.status_code != 200: # pragma: no cover
return None
data = res.json()['Data']['Items']
if len(data) >= 1:
r = data[0]
return r['Id']
return None # pragma
def get_api_get(url):
token = idoklad_token()
if token is None:
return None
headers = {
'Authorization': 'Bearer {t}'.format(t=token.access_token),
}
res = requests.get(url, headers=headers)
return res
def create_contact(rower):
token = idoklad_token()
if token is None:
return None
data = {
'City': rower.city,
'CompanyName': rower.user.first_name+" "+rower.user.last_name,
'CountryId': get_country_id(rower.country.code),
'Email': rower.user.email,
'Firstname': rower.user.first_name,
'PostalCode': rower.postal_code,
'Street': rower.street_address,
'Surname': rower.user.last_name,
'DeliveryAddresses': []
}
if rower.country.numeric is None:
data['CountryId'] = 1
dologging('idoklad.log','Creating idoklad contact for '+str(rower.user.email)+'\n')
headers = {
'Authorization': 'Bearer {t}'.format(t=token.access_token),
"Content-Type": "application/json",
"Accept": "application/json",
}
res = requests.post(contacts_url, json=data, headers=headers)
if res.status_code not in [200, 201]:
dologging('idoklad.log','Contact Created - reason '+str(res.reason)+'\n')
_ = myqueue.enqueue(
queuehigh, handle_send_email_noinvoice,
rower.user.email,
rower.user.first_name,
rower.user.last_name,
'idoklad Contact creation failed for '+str(rower.user.email)+'\n'+str(res.text)
)
return 0
id = res.json()['Data']['Id']
return id
def create_invoice(rower, amount, braintreeid, dosend=True, contact_id=None, name=None):
t = idoklad_token()
if t is None:
return None
if not contact_id:
contact_id = get_contacts(rower)
if not name:
name = 'Rowsandall Subscription '+str(braintreeid)
if not contact_id:
return 0
token = idoklad_token()
if token is None:
return 0
dologging('idoklad.log','Creating idoklad invoice for '+str(rower.user.email)+'\n')
headers = {
'Authorization': 'Bearer {t}'.format(t=token.access_token),
}
res = requests.get(invoice_url+'/Default', headers=headers)
post_data = res.json()['Data']
post_data['DateOfPayment'] = timezone.now().strftime('%Y-%m-%d')
post_data['Description'] = name
post_data['Items'][0]['Name'] = name
post_data['Items'][0]['UnitPrice'] = amount
post_data['PartnerId'] = contact_id
post_data['ItemsTextPrefix'] = 'We invoice you for '+str(name)+' in the amount of '+str(amount)+' EUR.'
post_data['ItemsTextSuffix'] = 'This invoice was already paid. Please do not pay it again.'
post_data['Items'][0]['VatRate'] = 0.0
post_data['Items'][0]['VatRateType'] = 2
post_data['Items'][0]['PaymentOptionId'] = 2
post_data['Items'][0]['VatCodeId'] = 3
post_data['CurrencyId'] = 2
post_data['ReportLanguage'] = 3
post_data.pop('ExchangeRate', None)
res = requests.post(invoice_url, json=post_data, headers=headers)
dologging('idoklad.log','Invoice Created - status code '+str(res.status_code)+'\n')
if res.status_code not in [200, 201]:
dologging('idoklad.log','Invoice Created - reason '+str(res.reason)+'\n')
return 0
id = res.json()['Data']['Id']
if dosend:
data = {
'AttachmentIds': [],
'DocumentId': id,
'EmailBody': 'Dear customer, we are sending you the invoice for your subscription. Please do not hesitate to contact us if you have any questions. Best regards, Rowsandall Team',
'EmailSubject': 'Rowsandall Subscription Invoice',
'Method': 1,
'ReportLanguage': 3,
'SendToSelf': True,
'SendToPartner': True,
'SendToAccountant': False,
}
headers = {
'Authorization': 'Bearer {access_token}'.format(access_token=token.access_token),
'Content-Type': 'application/json',
'Accept': 'application/json',
}
res = requests.post(email_url, json=data, headers=headers)
dologging('idoklad.log','Invoice Sent - status code '+str(res.status_code)+'\n')
if res.status_code not in [200, 201]:
dologging('idoklad.log','Invoice Sent - reason '+str(res.text)+'\n')
_ = myqueue.enqueue(
queuehigh, handle_send_email_noinvoice,
rower.user.email,
rower.user.first_name,
rower.user.last_name,
'idoklad Invoice sending failed for '+str(rower.user.email)+'\n'+str(res.text)
)
return id