import pandas as pd import numpy as np import json from dataclasses import dataclass from datetime import datetime @dataclass class MazdaConfig: domain: str webservice: str module: str auth_url: str token_url: str client_id: str client_secret: str username: str password: str dealer_number: str cfg = MazdaConfig( domain='https://mappsacc.mazdaeur.com', webservice='/dogma-restapi-dms/api', module='/vehicles/workshop/order-report', auth_url='/oauth/authorize', token_url='/oauth/token', client_id='E7FC943B-B73F-F48E-B71A-419EA4CD4AC7', client_secret='^bH=rk@c58zrr^Apc#9fzy$c', username='mmd88888.cdk', password='MazdaCX30', dealer_number='88888/MMD' ) redirect_uri = 'https://localhost/' base_dir = '/home/robert/projekte/python/mazda/' def date_format(d: datetime): if d == 0: return '' # '0000-00-00T00:00:00.000Z' date_str = d.isoformat(sep='T') if len(date_str) == 19: return date_str + '.000Z' return date_str[:-3] + 'Z' def convert_csv(csv_file, json_file, year, month): date_min = datetime(year, month, 1, 0, 0, 0) date_max = datetime(year, month + 1, 1, 0, 0, 0) date_cols = ['invoiceDate', 'orderDate', 'orderCompletionDate', 'vehicleIntakeDate', 'nextMotDueDate'] df = pd.read_csv(csv_file, encoding='latin-1', decimal=',', sep=';', parse_dates=date_cols) df = df.fillna(0)[(df['invoiceDate'] >= date_min) & (df['invoiceDate'] <= date_max)] df = df.sort_values(by=['invoiceDate', 'invoiceNumber', 'orderNumber', 'lineNumber']) df['vin'] = np.where(df['vin'] == 0, '0' * 17, df['vin']) # print(df[['currency','documentType','invoiceCategory','invoiceDate','invoiceNumber']].drop_duplicates().info()) invoices_filter = ['currency', 'documentType', 'invoiceCategory', 'invoiceDate', 'invoiceNumber'] invoices = df[invoices_filter].drop_duplicates().to_dict('records') invoice_items_filter = ['invoiceNumber', 'orderLineNumber', 'orderNumber', 'amount', 'discount', 'portion', 'unitPrice'] invoice_items = df[invoice_items_filter].groupby('invoiceNumber') for invoice in invoices: invoice['invoiceDate'] = date_format(invoice['invoiceDate']) items = invoice_items.get_group(invoice['invoiceNumber']) items.pop('invoiceNumber') invoice['invoiceItems'] = items.to_dict('records') orders = df[['orderNumber', 'orderDate', 'orderCompletionDate', 'vehicleIntakeDate']].drop_duplicates().to_dict('records') orders_vehicle_filter = ['orderNumber', 'licensePlate', 'nextMotDueDate', 'odometer', 'odometerUnit', 'vin'] orders_vehicle = df[orders_vehicle_filter].drop_duplicates().groupby('orderNumber') orders_items = df[[ 'orderNumber', 'lineNumber', 'orderItemType', 'category', 'descriptionOperation', 'hours', 'operationCode', 'standardHours', 'descriptionOther', 'type', 'descriptionPart', 'isDamageCausal', 'manufacturer', 'partNumber', 'quantity', 'serialNumber', 'unit', 'company', 'descriptionPurchase', 'invoiceCode', 'invoiceDate', 'invoiceNumber' ]].drop_duplicates().groupby('orderNumber') for order in orders: order['vehicle'] = orders_vehicle.get_group(order['orderNumber']).to_dict('records')[0] order['vehicle']['nextMotDueDate'] = date_format(order['vehicle']['nextMotDueDate']) order['orderDate'] = date_format(order['orderDate']) order['orderCompletionDate'] = date_format(order['orderCompletionDate']) order['vehicleIntakeDate'] = date_format(order['vehicleIntakeDate']) items = orders_items.get_group(order['orderNumber']).to_dict('records') order['items'] = [] for item in items: if item['orderItemType'] == 'operation': order['items'].append({ 'lineNumber': item['lineNumber'], 'operation': { 'category': item['category'], 'description': item['descriptionOperation'], 'hours': item['hours'], 'operationCode': item['operationCode'], 'standardHours': item['standardHours'] } }) elif item['orderItemType'] == 'part': order['items'].append({ 'lineNumber': item['lineNumber'], 'part': { 'description': item['descriptionPart'], 'isDamageCausal': item['isDamageCausal'], 'manufacturer': item['manufacturer'], 'partNumber': item['partNumber'], 'quantity': item['quantity'], 'serialNumber': item['serialNumber'], 'unit': item['unit'] } }) elif item['orderItemType'] == 'other': order['items'].append({ 'lineNumber': item['lineNumber'], 'other': { 'description': item['descriptionOther'], 'type': item['type'] } }) else: order['items'].append({ 'lineNumber': item['lineNumber'], 'purchaseInvoice': { 'company': item['company'], 'description': item['descriptionPurchase'], 'invoiceCode': item['invoiceCode'], 'invoiceDate': date_format(item['invoiceDate']), 'invoiceNumber': item['invoiceNumber'] } }) res = { 'creationDate': date_format(datetime.now()), 'invoices': invoices, 'orders': orders, 'timeRangeBegin': date_format(date_min), 'timeRangeEnd': date_format(date_max) } json.dump(res, open(json_file, 'w'), indent=2) return res def upload(oauth, data): headers = { 'accept': 'application/vnd.mazdaeur.dms.v4+json', 'x-mme-organisation': cfg.dealer_number, 'X-mazda-org': cfg.dealer_number, 'Content-Type': 'application/json', # 'Authorization': 'Bearer ' + token } invoices = data['invoices'] orders = data['orders'] data['orders'] = [] for i in invoices: data['invoices'] = [i] order_no = [item['orderNumber'] for item in i['invoiceItems']] data['orders'] = [o for o in orders if o['orderNumber'] in order_no] r = oauth.post(cfg.domain + cfg.webservice + cfg.module, json.dumps(data), headers=headers) print(f"{i['invoiceNumber']} => {r.status_code}") with open(base_dir + f"logs/invoice_{i['invoiceNumber']}.log", 'w') as fwh: fwh.write(r.text) def main(): data = convert_csv(base_dir + 'Workshop_Order_Report.csv', base_dir + 'mazda_export.json', 2021, 6) # data = json.load(open(base_dir + 'mazda_export.json', 'r')) upload(None, data) if __name__ == '__main__': main()