123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- import pandas as pd
- import numpy as np
- import json
- from requests_oauthlib import OAuth2Session
- from dataclasses import dataclass
- from datetime import datetime
- from dateutil.relativedelta import relativedelta
- @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="15972/MMD",
- )
- redirect_uri = "https://localhost:8085/"
- base_dir = "C:/projekte/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(import_csv, export_json, year, month):
- date_min = datetime(year, month, 5, 0, 0, 0)
- date_max = datetime(year, month, 5, 0, 0, 0) + relativedelta(days=5)
- 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")
- 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"])
- # odo_str = str(order["vehicle"]["odometer"])
- order["vehicle"]["odometer"] = int(order["vehicle"]["odometer"])
- 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": str(item["serialNumber"]),
- "unit": str(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(export_json, "w"), indent=2)
- return res
- def upload(oauth: OAuth2Session, data):
- headers = {
- "accept": "application/vnd.mazdaeur.dms.v5+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}")
- if r.status_code not in [200, 202]:
- with open(base_dir + f"logs/invoice_{i['invoiceNumber']}.log", "wb") as fwh:
- fwh.write(r.content)
- def main():
- 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__":
- main()
|