|
@@ -20,157 +20,197 @@ class MazdaConfig:
|
|
|
|
|
|
|
|
|
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'
|
|
|
+ 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/mazda/'
|
|
|
+redirect_uri = "https://localhost/"
|
|
|
+base_dir = "/home/robert/projekte/mazda/"
|
|
|
|
|
|
|
|
|
def date_format(d: datetime):
|
|
|
if d == 0:
|
|
|
- return '' # '0000-00-00T00:00:00.000Z'
|
|
|
- date_str = d.isoformat(sep='T')
|
|
|
+ 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'
|
|
|
+ return date_str + ".000Z"
|
|
|
+ return date_str[:-3] + "Z"
|
|
|
|
|
|
|
|
|
def convert_csv(import_csv, export_json, 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(import_csv, 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'])
|
|
|
+ date_cols = ["invoiceDate", "orderDate", "orderCompletionDate", "vehicleIntakeDate", "nextMotDueDate"]
|
|
|
+ df = pd.read_csv(import_csv, 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')
|
|
|
+ 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')
|
|
|
+ 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["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'])
|
|
|
+ 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'] = []
|
|
|
+ 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']
|
|
|
+ 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"] == "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']
|
|
|
+ )
|
|
|
+ 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']
|
|
|
+ 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)
|
|
|
+ "creationDate": date_format(datetime.now()),
|
|
|
+ "invoices": invoices,
|
|
|
+ "orders": orders,
|
|
|
+ "timeRangeBegin": date_format(date_min),
|
|
|
+ "timeRangeEnd": date_format(date_max),
|
|
|
}
|
|
|
|
|
|
- json.dump(res, open(export_json, 'w'), indent=2)
|
|
|
+ json.dump(res, open(export_json, "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',
|
|
|
+ "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'] = []
|
|
|
+ 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]
|
|
|
+ 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:
|
|
|
+ with open(base_dir + f"logs/invoice_{i['invoiceNumber']}.log", "w") as fwh:
|
|
|
fwh.write(r.text)
|
|
|
|
|
|
|
|
|
def main():
|
|
|
- data = convert_csv(base_dir + 'data/Workshop_Order_Report.csv', base_dir + 'temp/mazda_export.json', 2021, 6)
|
|
|
+ data = convert_csv(base_dir + "data/Workshop_Order_Report.csv", base_dir + "temp/mazda_export.json", 2021, 6)
|
|
|
# data = json.load(open(base_dir + 'mazda_export.json', 'r'))
|
|
|
upload(None, data)
|
|
|
|
|
|
|
|
|
-if __name__ == '__main__':
|
|
|
+if __name__ == "__main__":
|
|
|
main()
|