浏览代码

Upload für Winter Bretnig, erster Erfolg

gc-server3 1 年之前
父节点
当前提交
acca41861c
共有 8 个文件被更改,包括 180 次插入30 次删除
  1. 1 1
      config/nasa_config.crypt
  2. 2 2
      config/nasa_config.json
  3. 二进制
      docs/Mazda NASA-Schnittstelle.pdf
  4. 11 0
      export/2024-01_auftraege.csv
  5. 119 0
      export/2024-01_mitarbeiter.csv
  6. 12 7
      mazda_upload.py
  7. 15 5
      mazda_webservice.py
  8. 20 15
      nasa_upload.py

+ 1 - 1
config/nasa_config.crypt

@@ -1 +1 @@
-gAAAAABfNACvqaaql4hPMHggE6DdlK8qJ_FA7-iktrGGeq0OGccuCULZ_nfHUIrGwtYYhv1n2btF1xHkWBi0Mr24HW3rVyXHUZYWOfxLyIt54d6WBPeMJknnNC7Aq3EQTUx9hKGyasTCeMgwHuFZqkVDYo3iPv5Zwfrm71stibCJ4YBR4X-f-mKkv-4XiFbHorFd14pnzs4ll5APF3XQnsohqZd8ZCFRMxHFOsJ3sC7cSgiZ_VM1fE7vXtR2dlgPkXZZjoiT1t8z5-VEHpf9lRc229vgtTCbJdidi8weubExYkt_e5dBX8tebPHU-MKXdQxNYNWtnMQb2GJLGUIDRdXhbGb5RfPKWhF1dMQy9n0Gs1g-OM836U903o78E9ELUh9Ibhj9UqFdHj909PEW4yXz2nzXN0BcJXIvkJoPNFj8aCs8wqynNhMFKXvf15oEmlMcuzrBMlQmfgtokHelsf_2TvhbznWNTTwpscsEGGd7vw2OgFkGcu5XrM0HRoJ9gI1S9SIcyfBSHUHkXqrm1Axg3B9YJq0Lhsi3Rhltw5Fo5b0lLZUzyJmhasbK0yws1xGdKZd2fKG5Ef4KrGFPSR_DhmCxQQcx5A==
+gAAAAABlyyOMCr55SJi3YRyNG8G6jJH35ThUCLRFeEgpXRmzNOaqN2AQ6XehG3ATKECp5VMABA_JwdqVey5ITkcfEbBsOMaaZF-RYnPnLBPWybRxiE-LLKWai-uPTqFTKzYyPObdn7tCzaj2G9Vrm_YToBgXQ_m_B7_HI3FBoVvafom2nJCmWRayYNCeO7q4_Xz2WuTlx_UJLYGLAcabixApUpahtqBareKsr1lArKc0HEA7qIENZ3vC-C80iwi5C-MvU1U03PcZIIBV7_1lpWNVZZ_GGaz2NsdgLOHADkY9winH3RxmBymekgMl2Ymtq_BlGRO5GWN_ncc0dlA4qxffmTQ3dV2oZoNZ2fWaZ29QBq8-rtSjwldviyc7al1DiaA7sQ6DYz1IgrI1QKyRrdPNXffuRArSF4eySHaLxc-8Xxhw5tjkGCQVRYYsnl09ac92hvkInv4DaCYcCr6RsNuYJw082YUsUUHCnkNwbO07vfoAaXLVjlb0ZePzq3HkXjKwd3rXEMy2tjeINak9yQSUYQqoQF4_1CrkJf3Thcqb1PY-Foe3mP8J8S4QygOBt8uU5_2Twk5b

+ 2 - 2
config/nasa_config.json

@@ -1,11 +1,11 @@
 {
-    "service_url": "https://nasa.macs-online.com/services/MacsAfterSalesAnalyseTest.wsdl",
+    "service_url": "https://nasa.macs-online.com/services/MacsAfterSalesAnalyse.wsdl",
     "credentials": {
         "token": "MDDq3CUd9ix0iSqR",
         "username": "global-cube", 
         "password": "ATPoIL*O6*%1BE%-"
     },
-    "client_id": "11197",
+    "client_id": "15972",
     "selected_year": "2020",
     "selected_month": "05",
     "source_dsn": { 

二进制
docs/Mazda NASA-Schnittstelle.pdf


+ 11 - 0
export/2024-01_auftraege.csv

@@ -0,0 +1,11 @@
+AuftragsArt;AuftragsArtId;TeileUmsatz;LohnUmsatz;SonstigeUmsatz;GesamtUmsatz;AnzahlAuftraege
+Inspektion;2;30118,96;15231,56;5967,61;51318,13;108
+Karosseriearbeit;2;0,0;675,69;0,0;675,69;0
+Sonstiges;2;0,0;145,53;0,0;145,53;0
+Sonstiges;4;30900,94;-15,0;407,37;31293,31;231
+Inspektion;1;167353,25;106108,9;33960,46;307422,61;1116
+Karosseriearbeit;1;0,0;3952,4;0,0;3952,4;4
+Sonstiges;1;640,22;568,18;-653,28;555,12;33
+Inspektion;3;41727,64;29821,25;5520,13;77069,02;310
+Karosseriearbeit;3;0,0;725,69;0,0;725,69;1
+Sonstiges;3;1525,69;268,49;0,0;1794,18;70

+ 119 - 0
export/2024-01_mitarbeiter.csv

@@ -0,0 +1,119 @@
+Periode;Produktiv;Mitarbeiter;Name;Prod;Jahr;Monat;Periode_Filter
+2024-01;nicht produktiv;ANE;Annett Eggeling;0;2024;1;2024-01
+2024-01;nicht produktiv;ANKA;Andreas Kabisch;0;2024;1;2024-01
+2024-01;nicht produktiv;ANMU;Andreas Müller;0;2024;1;2024-01
+2024-01;nicht produktiv;ASTI;Anja Sticht;0;2024;1;2024-01
+2024-01;nicht produktiv;CADI;Carsten Dittrich;0;2024;1;2024-01
+2024-01;nicht produktiv;CLA;Claudia Zieschwauk;0;2024;1;2024-01
+2024-01;nicht produktiv;CLKA;Claudia Karraß;0;2024;1;2024-01
+2024-01;nicht produktiv;CLRO;Clarissa Rötschke;0;2024;1;2024-01
+2024-01;nicht produktiv;CLS;Claudia Schiffel;0;2024;1;2024-01
+2024-01;nicht produktiv;DOLS;Doreen Lehmann;0;2024;1;2024-01
+2024-01;nicht produktiv;ELNE;Eleen Neumann;0;2024;1;2024-01
+2024-01;nicht produktiv;ELWI;Elisa Winter;0;2024;1;2024-01
+2024-01;nicht produktiv;ENKV;Enrico Koenig-Viehfe;0;2024;1;2024-01
+2024-01;nicht produktiv;FLKR;Florian Krauß;0;2024;1;2024-01
+2024-01;nicht produktiv;FRMA;Frank Martin;0;2024;1;2024-01
+2024-01;nicht produktiv;FRRE;Frank Rentsch;0;2024;1;2024-01
+2024-01;nicht produktiv;GARE;Gabriele Reichardt;0;2024;1;2024-01
+2024-01;nicht produktiv;GUP;Gunter Paul;0;2024;1;2024-01
+2024-01;nicht produktiv;GWA;Günter Watzlawik;0;2024;1;2024-01
+2024-01;nicht produktiv;JABR;Jan Breyer;0;2024;1;2024-01
+2024-01;nicht produktiv;JEBA;Jens Bartosch;0;2024;1;2024-01
+2024-01;nicht produktiv;JEFR;Jens Fritzsche;0;2024;1;2024-01
+2024-01;nicht produktiv;JOFI;Jonas Fitzke;0;2024;1;2024-01
+2024-01;nicht produktiv;KABI;Kathleen Birkner;0;2024;1;2024-01
+2024-01;nicht produktiv;KABO;Kathleen Böhmig;0;2024;1;2024-01
+2024-01;nicht produktiv;KAM;Kathleen May;0;2024;1;2024-01
+2024-01;nicht produktiv;KARI;Karina Käppler;0;2024;1;2024-01
+2024-01;nicht produktiv;KAWA;Katrin Wagner;0;2024;1;2024-01
+2024-01;nicht produktiv;KEB;Kerstin Borrmann;0;2024;1;2024-01
+2024-01;nicht produktiv;KESC;Kenny Schlacht;0;2024;1;2024-01
+2024-01;nicht produktiv;KOMA;Konstantin Marschner;0;2024;1;2024-01
+2024-01;nicht produktiv;LEMO;Lea Marlen Opitz;0;2024;1;2024-01
+2024-01;nicht produktiv;LISC;Lisa Schröder;0;2024;1;2024-01
+2024-01;nicht produktiv;MABO;Martin Boese;0;2024;1;2024-01
+2024-01;nicht produktiv;MAGR;Matthias Grolms;0;2024;1;2024-01
+2024-01;nicht produktiv;MAKL;Maria Klinner;0;2024;1;2024-01
+2024-01;nicht produktiv;MANB;Mandy Beck;0;2024;1;2024-01
+2024-01;nicht produktiv;MBE;Margitta Bendel;0;2024;1;2024-01
+2024-01;nicht produktiv;MID;Mike Dittrich;0;2024;1;2024-01
+2024-01;nicht produktiv;MSCH;Marlies Schäfer;0;2024;1;2024-01
+2024-01;nicht produktiv;OLKN;Olaf Knothe;0;2024;1;2024-01
+2024-01;nicht produktiv;PEG;Petra Glowienka;0;2024;1;2024-01
+2024-01;nicht produktiv;REG;Rene Göpfert;0;2024;1;2024-01
+2024-01;nicht produktiv;RES;René Scholz;0;2024;1;2024-01
+2024-01;nicht produktiv;ROBA;Robin Baumbach;0;2024;1;2024-01
+2024-01;nicht produktiv;SAHO;Sarah Hommel;0;2024;1;2024-01
+2024-01;nicht produktiv;SANI;Sascha Nicks;0;2024;1;2024-01
+2024-01;nicht produktiv;SAS;Sandro Storch;0;2024;1;2024-01
+2024-01;nicht produktiv;SEBU;Service Burkau;0;2024;1;2024-01
+2024-01;nicht produktiv;SIME;Silke Mehnert;0;2024;1;2024-01
+2024-01;nicht produktiv;SIS;Simone Stephan;0;2024;1;2024-01
+2024-01;nicht produktiv;SMAE;Stefanie Maedler;0;2024;1;2024-01
+2024-01;nicht produktiv;STFI;Steffi Fitzner;0;2024;1;2024-01
+2024-01;nicht produktiv;STGU;Steffen Gungl;0;2024;1;2024-01
+2024-01;nicht produktiv;STK;Steffen Kowalewski;0;2024;1;2024-01
+2024-01;nicht produktiv;STRO;Steffen Robel;0;2024;1;2024-01
+2024-01;nicht produktiv;SUHA;Susann Haase;0;2024;1;2024-01
+2024-01;nicht produktiv;SVLI;Sven Liebich;0;2024;1;2024-01
+2024-01;nicht produktiv;SVTH;Sven Thomas;0;2024;1;2024-01
+2024-01;nicht produktiv;TATH;Tamara Theiß;0;2024;1;2024-01
+2024-01;nicht produktiv;THPU;Thomas Putzke;0;2024;1;2024-01
+2024-01;nicht produktiv;TIH;Tilo Heintze;0;2024;1;2024-01
+2024-01;nicht produktiv;TIK;Tino Käppler;0;2024;1;2024-01
+2024-01;nicht produktiv;TOHE;Tom Heinzelmann;0;2024;1;2024-01
+2024-01;nicht produktiv;TOLE;Thomas Lehmann;0;2024;1;2024-01
+2024-01;nicht produktiv;TOS;Tom Schumann;0;2024;1;2024-01
+2024-01;produktiv;99;Dummy Monteur;1;2024;1;2024-01
+2024-01;produktiv;ADDO;Adrian Donath;1;2024;1;2024-01
+2024-01;produktiv;ALBO;Aline Börner;1;2024;1;2024-01
+2024-01;produktiv;ANBE;Bernstein;1;2024;1;2024-01
+2024-01;produktiv;ANKI;Andrea Kieschnick;1;2024;1;2024-01
+2024-01;produktiv;ANPA;Andreas Paschke;1;2024;1;2024-01
+2024-01;produktiv;ANST;Andreas Stender;1;2024;1;2024-01
+2024-01;produktiv;DAKR;Dario Krause;1;2024;1;2024-01
+2024-01;produktiv;DANI;Danny Nitzsche;1;2024;1;2024-01
+2024-01;produktiv;DASC;Danny Schlenkrich;1;2024;1;2024-01
+2024-01;produktiv;DAWE;Danny Werner;1;2024;1;2024-01
+2024-01;produktiv;DAWI;Dawid Wegrzyn;1;2024;1;2024-01
+2024-01;produktiv;ERHE;Erik Heide;1;2024;1;2024-01
+2024-01;produktiv;ERSM;Eric Smrcka;1;2024;1;2024-01
+2024-01;produktiv;FEBÖ;Felix Böhm;1;2024;1;2024-01
+2024-01;produktiv;FL;Fremdleistung;1;2024;1;2024-01
+2024-01;produktiv;FRBU;Franz Burkhardt;1;2024;1;2024-01
+2024-01;produktiv;FRFR;Frank Frenzel;1;2024;1;2024-01
+2024-01;produktiv;GLWA;Gian-Luca Wätzlich;1;2024;1;2024-01
+2024-01;produktiv;HAH;Hans-Jürgen Hartmann;1;2024;1;2024-01
+2024-01;produktiv;HAT;Harald Teich;1;2024;1;2024-01
+2024-01;produktiv;HEWI;Heiko Wiedemann;1;2024;1;2024-01
+2024-01;produktiv;JAKU;Jason Kühnel;1;2024;1;2024-01
+2024-01;produktiv;JEO;Jens Olbort;1;2024;1;2024-01
+2024-01;produktiv;JSC;Jörg Schubert;1;2024;1;2024-01
+2024-01;produktiv;JSI;Jens Sicker;1;2024;1;2024-01
+2024-01;produktiv;KAMI;Kay Mirschinka;1;2024;1;2024-01
+2024-01;produktiv;LAKM;Leiharbeiter Kamenz;1;2024;1;2024-01
+2024-01;produktiv;MAEI;Marek Eisner;1;2024;1;2024-01
+2024-01;produktiv;MAKO;Martin Kovanda;1;2024;1;2024-01
+2024-01;produktiv;MAM;Mathias Meinhardt;1;2024;1;2024-01
+2024-01;produktiv;MAS;Mathias Strobel;1;2024;1;2024-01
+2024-01;produktiv;MAVE;Marcel Ventzke;1;2024;1;2024-01
+2024-01;produktiv;MAZS;Markus Zschorlich;1;2024;1;2024-01
+2024-01;produktiv;MHE;Markus Hentschel;1;2024;1;2024-01
+2024-01;produktiv;NASC;Nadine Scharf;1;2024;1;2024-01
+2024-01;produktiv;NIGR;Niklas Großer;1;2024;1;2024-01
+2024-01;produktiv;OLKR;Olaf Kruscha;1;2024;1;2024-01
+2024-01;produktiv;PES;Peter Stolpe;1;2024;1;2024-01
+2024-01;produktiv;RALI;Robert-André Lißner;1;2024;1;2024-01
+2024-01;produktiv;REA;Rene Altenberger;1;2024;1;2024-01
+2024-01;produktiv;ROFR;Robin Freudenberg;1;2024;1;2024-01
+2024-01;produktiv;RORA;Ronny Rarisch;1;2024;1;2024-01
+2024-01;produktiv;SABE;Sabrina Benad;1;2024;1;2024-01
+2024-01;produktiv;SEPW;Sebastian Philipp WL;1;2024;1;2024-01
+2024-01;produktiv;STPR;Stanley Prokop;1;2024;1;2024-01
+2024-01;produktiv;STW;Steffen Wulst;1;2024;1;2024-01
+2024-01;produktiv;THB;Thomas Berndt;1;2024;1;2024-01
+2024-01;produktiv;THHO;Thomas Hoberg;1;2024;1;2024-01
+2024-01;produktiv;TOLA;Tomasz Laszczak;1;2024;1;2024-01
+2024-01;produktiv;ZBRE;ZBRE;1;2024;1;2024-01
+2024-01;produktiv;ZKM;Zeiterfassung Kamenz;1;2024;1;2024-01

+ 12 - 7
mazda_upload.py

@@ -1,8 +1,10 @@
 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
@@ -29,11 +31,11 @@ cfg = MazdaConfig(
     client_secret="^bH=rk@c58zrr^Apc#9fzy$c",
     username="mmd88888.cdk",
     password="MazdaCX30",
-    dealer_number="88888/MMD",
+    dealer_number="15972/MMD",
 )
 
-redirect_uri = "https://localhost/"
-base_dir = "/home/robert/projekte/mazda/"
+redirect_uri = "https://localhost:8085/"
+base_dir = "C:/projekte/mazda/"
 
 
 def date_format(d: datetime):
@@ -47,7 +49,7 @@ def date_format(d: datetime):
 
 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_max = datetime(year, month, 1, 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)
@@ -115,6 +117,8 @@ def convert_csv(import_csv, export_json, year, month):
     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(odo_str) if odo_str.isnumeric() else 0
 
         order["orderDate"] = date_format(order["orderDate"])
         order["orderCompletionDate"] = date_format(order["orderCompletionDate"])
@@ -184,7 +188,7 @@ def convert_csv(import_csv, export_json, year, month):
     return res
 
 
-def upload(oauth, data):
+def upload(oauth: OAuth2Session, data):
     headers = {
         "accept": "application/vnd.mazdaeur.dms.v4+json",
         "x-mme-organisation": cfg.dealer_number,
@@ -202,8 +206,9 @@ def upload(oauth, data):
         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)
+        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():

+ 15 - 5
mazda_webservice.py

@@ -28,7 +28,7 @@ class Token:
 app = Flask(__name__)
 
 cfg: mazda_upload.MazdaConfig = mazda_upload.cfg
-base_dir = "/home/robert/projekte/mazda/"
+base_dir = "C:/projekte/mazda/"
 
 
 def token_save(token):
@@ -61,8 +61,12 @@ def demo():
 
     if oauth.authorized:
         return redirect("/profile")
+    return redirect("/login")
 
-    redirect_uri = request.base_url + "callback"
+
+@app.route("/login")
+def login():
+    redirect_uri = request.base_url.rsplit("/", 1)[0] + "/callback"
     print(redirect_uri)
     oauth = OAuth2Session(cfg.client_id, redirect_uri=redirect_uri)
     authorization_url, state = oauth.authorization_url(cfg.domain + cfg.auth_url)
@@ -93,11 +97,17 @@ def callback():
 
 @app.route("/profile", methods=["GET"])
 def profile():
-    oauth = OAuth2Session(cfg.client_id, token=session.get("oauth_token"))
+    oauth = OAuth2Session(cfg.client_id, token=get_token())
+    if not oauth.authorized:
+        return redirect("/")
+
     data = mazda_upload.convert_csv(
-        base_dir + "data/Workshop_Order_Report.csv", base_dir + "temp/mazda_export.json", 2021, 6
+        base_dir + "data/Workshop_Order_Report.csv", base_dir + "temp/mazda_export.json", 2024, 1
     )
-    mazda_upload.upload(oauth, data)
+    try:
+        mazda_upload.upload(oauth, data)
+    except OAuth2Error:
+        return redirect("/")
     return app.response_class(response=json.dumps(data, indent=2), mimetype="application/json")
 
 

+ 20 - 15
nasa_upload.py

@@ -1,3 +1,4 @@
+import logging
 import pandas as pd
 import json
 from pathlib import Path
@@ -8,6 +9,10 @@ from suds.client import Client
 from cryptography.fernet import Fernet
 
 
+logging.basicConfig(filename="logs/nasa.log", level=logging.DEBUG)
+logger = logging.getLogger()
+
+
 def get_config():
     fernet_key = b"YBckeKYt-8g7LFvpG7XqAAcEbsYESnI-yl8by9rjeQQ="
     fernet = Fernet(fernet_key)
@@ -42,13 +47,13 @@ def load_data(config, source, year=None, month=None):
 
     payload = {
         "HaendlerNr": config["client_id"],
-        "Filiale": "1",
+        "Filiale": config["client_id"],
         "Jahr": year,
         "Monat": month,
         "Fabrikat": "Mazda",
-        "AnzahlMitarbeiter": "0",
-        "AnzahlProduktiv": "0.0",
-        "WerkstattDurchlaeufe": "0",
+        "AnzahlMitarbeiter": 0,
+        "AnzahlProduktiv": 0.0,
+        "WerkstattDurchlaeufe": 0,
         "Token": config["credentials"]["token"],
     }
 
@@ -58,17 +63,8 @@ def load_data(config, source, year=None, month=None):
     else:
         df = pd.read_csv(source_auftraege, sep=";", encoding="latin-1", decimal=",")
 
-    df.to_csv(
-        f"export/{period}_auftraege.csv",
-        sep=";",
-        encoding="latin-1",
-        decimal=",",
-        index=False,
-    )
-
-    # Array in gewünschtes Format bringen
-    auftragsart = ["Extern", "Garantie", "Intern", "Theke"]
-    auftragstyp = ["Inspektion", "Karosseriearbeit", "Lackierung", "Verschleißteile", "Sonstiges"]
+    # auftragsart = ["Extern", "Garantie", "Intern", "Theke"]
+    # auftragstyp = ["Inspektion", "Karosseriearbeit", "Lackierung", "Verschleißteile", "Sonstiges"]
 
     columns = [
         "AuftragsArt",
@@ -81,6 +77,15 @@ def load_data(config, source, year=None, month=None):
     ]
 
     df = df[columns]
+
+    df.to_csv(
+        f"export/{period}_auftraege.csv",
+        sep=";",
+        encoding="latin-1",
+        decimal=",",
+        index=False,
+    )
+
     payload["WerkstattDurchlaeufe"] = df["AnzahlAuftraege"].sum()
     payload["AfterSalesPositionen"] = df.to_dict("records")