diff --git a/Produktionsplanung.ipynb b/Produktionsplanung.ipynb index 0de3fb2..6e97fde 100644 --- a/Produktionsplanung.ipynb +++ b/Produktionsplanung.ipynb @@ -6,7 +6,6 @@ "metadata": {}, "outputs": [], "source": [ - "import re\n", "import math\n", "import datetime\n", "\n", @@ -47,7 +46,7 @@ "\n", "@dataclass\n", "class Abpackung:\n", - " artikelNummer: int # ArtNr\n", + " artikelNummer: str # ArtNr\n", " abpackMenge: int # in KG\n", " bemerkung: str\n", " planPos: int # Wochenplannummer\n", @@ -67,7 +66,7 @@ "\n", "@dataclass\n", "class MischBedarf:\n", - " artikelNummer: int # ArtNr\n", + " artikelNummer: str # ArtNr\n", " abpackMenge: int # in KG\n", " kw_reich: float # KW REICH\n", " bem_ek: str # Bemerkung Einkauf\n", @@ -260,7 +259,7 @@ "source": [ "# read Dispo\n", "\n", - "def readDispo(sheet, prodStamm):\n", + "def readDispo(sheet, prodStamm, prodDict):\n", " DISPO_DICT = {}\n", " ABPACK_DICT = {}\n", " MISCH_DICT = {}\n", @@ -275,10 +274,16 @@ " if row[0].value is None:\n", " break\n", "\n", - " product = prodStamm.get(row[0].value, None)\n", + " product = prodDict.get(f\"s{row[0].value}\")\n", + " if product is None:\n", + " product = prodDict.get(f\"g{row[0].value}\")\n", + " \n", + " if product is None:\n", + " print(f\"Product {row[0].value} could neither be found in the spielberger nor gehrsitz database. Skipping!\")\n", + " continue\n", "\n", " d = DispoBedarf(\n", - " artikelNummer=row[0].value,\n", + " artikelNummer=product.number,\n", " palettenziel=row[4].value,\n", " bestandL00=row[5].value,\n", " bestandL01=row[6].value,\n", @@ -299,9 +304,13 @@ " DISPO_DICT[d.artikelNummer] = d\n", " GEB_GROESSE[d.artikelNummer] = g\n", "\n", + " prodBase = prodStamm.get(product.number, None)\n", + "\n", " if not (row[25].value is None):\n", + " if prodBase is None:\n", + " print(f\"Product {product.number} could not be found in the production parameters database. Default parameters would be used for the production planing\")\n", " a = Abpackung(\n", - " artikelNummer=d.artikelNummer,\n", + " artikelNummer=product.number,\n", " abpackMenge=int(row[25].value),\n", " bemerkung=\"\",\n", " planPos= 999 if row[29].value is None else int(int(row[29].value)),\n", @@ -314,7 +323,9 @@ "\n", " ABPACK_DICT[d.artikelNummer]=a\n", "\n", - " if not product is None and product.muehleMisch == 1:\n", + " if prodBase is None:\n", + " print(f\"Product {product.number} could not be found in the production parameters database. Cannot determine mixing status\")\n", + " elif prodBase.muehleMisch == 1:\n", " MISCH_DICT[d.artikelNummer] = MischBedarf(\n", " artikelNummer = d.artikelNummer,\n", " abpackMenge = int(row[25].value) if not row[25].value is None else 0,\n", @@ -345,8 +356,13 @@ "\n", " counter = 0\n", " for pack, mischDispo in [(\"Pack1\", dP1), (\"Pack2\", dP2), (\"Pack3\", dP3), (\"Pack4\", dP4)]:\n", + " if mischDispo is None:\n", + " continue\n", + "\n", + " mischDispo = mischDispo[3]\n", + "\n", " for d in mischDispo.values():\n", - " p = prodDict.get(d.artikelNummer, None)\n", + " p = prodDict.get(d.artikelNummer)\n", " if p is None:\n", " print(f\"ERROR: Product {p.artikelNummer} not found\")\n", " counter += 1\n", @@ -356,7 +372,7 @@ " sheet.add_table(tab)\n", "\n", "\n", - "def writeSchedule(vorlage, dispo, prodDict, pack):\n", + "def writeSchedule(vorlage, dispo, pack):\n", " name = f\"Schedule {pack}\"\n", "\n", " _dispoDict, abpackDict, gebGroesse, _mischDict = dispo\n", @@ -390,7 +406,7 @@ " print(f\"Für Produkt {pa.artikelNummer} in Pack {pack} ist keine gültige Abpackmenge eingetragen\")\n", " continue\n", "\n", - " time = writePASchedule(sheet, pa, leistung, prodDict, gebGroesse, pack, time)\n", + " time = writePASchedule(sheet, pa, leistung, gebGroesse, pack, time)\n", " modus = new_modus\n", " writeEnd(sheet)\n", "\n", @@ -414,11 +430,9 @@ "def prodTime(nbrBags, performance, min_t = 30):\n", " return max(int(nbrBags * 60 / performance), min_t)\n", "\n", - "def writePASchedule(sheet, pa, l, prodDict, gebGroeDict, pack, start):\n", + "def writePASchedule(sheet, pa, l, gebGroeDict, pack, start):\n", " row = sheet.max_row + 1\n", " geb = gebGroeDict[pa.artikelNummer]\n", - " prod = prodDict[pa.artikelNummer]\n", - " # t = math.ceil(60 * pa.anzBeutel(gebGroeDict) / beutelProH(pa.artikelNummer, pack))\n", " t = prodTime(pa.anzBeutel(gebGroeDict), beutelProH(pa.artikelNummer, pack))\n", " sheet.cell(row=row, column = 1).value = pa.artikelNummer\n", " sheet.cell(row=row, column = 2).value = shortName(pa.artikelNummer)\n", @@ -516,10 +530,10 @@ " 18,\n", " begin,\n", " (\n", - " (\"MO\", Workday.to_1_schicht_WU(begin)),\n", - " (\"DI\", Workday.to_1_schicht_WU(begin)),\n", - " (\"MI\", Workday.to_1_schicht_WU(begin)),\n", - " (\"DO\", Workday.to_holliday()),\n", + " (\"MO\", Workday.to_holliday()),\n", + " (\"DI\", Workday.to_holliday()),\n", + " (\"MI\", Workday.to_holliday()),\n", + " (\"DO\", Workday.to_1_schicht_WU(begin)),\n", " (\"FR\", Workday.to_1_schicht_WU(begin)),\n", " (\"SA\", Workday.to_1_schicht_WU(begin))\n", " ),\n", @@ -596,12 +610,12 @@ " 36,\n", " begin,\n", " (\n", - " (\"MO\", Workday.to_2_schicht(begin)),\n", - " (\"DI\", Workday.to_2_schicht(begin)),\n", + " (\"MO\", Workday.to_2_schicht_one_only(begin)),\n", + " (\"DI\", Workday.to_2_schicht_one_only(begin)),\n", " (\"MI\", Workday.to_2_schicht_one_only(begin)),\n", - " (\"DO\", Workday.to_2_schicht_one_only(begin)),\n", - " (\"FR\", Workday.to_2_schicht_one_only(begin)),\n", - " (\"SA\", Workday.to_2_schicht_one_only(begin)),\n", + " (\"DO\", Workday.to_2_schicht(begin)),\n", + " (\"FR\", Workday.to_2_schicht(begin)),\n", + " (\"SA\", Workday.to_2_schicht(begin)),\n", " )\n", " )\n", " \n", @@ -635,8 +649,23 @@ "metadata": {}, "outputs": [], "source": [ - "ibmconnect = IBMConnector(True)\n", - "prodDict = ibmconnect.getProductsTable()\n" + "@dataclass\n", + "class ProdDict:\n", + " gProdDict: dict()\n", + " sProdDict: dict()\n", + "\n", + " def get(self, pnr):\n", + " if pnr[0] == \"s\" or len(pnr) == 6:\n", + " return self.sProdDict.get(pnr, None)\n", + " elif pnr[0] == \"g\":\n", + " return self.gProdDict.get(pnr, None)\n", + "\n", + "g_ibmconnect = IBMConnector(False)\n", + "s_ibmconnect = IBMConnector(True)\n", + "prodDict = ProdDict(\n", + " sProdDict= s_ibmconnect.getProductsTable(),\n", + " gProdDict= g_ibmconnect.getProductsTable()\n", + ")" ] }, { @@ -652,7 +681,7 @@ "metadata": {}, "outputs": [], "source": [ - "KW = 3\n", + "KW = 6\n", "YEAR = 2022\n", "\n", "# ACHTUNG: Beim Lesen von der Dispo (FROM_DISPO = True) gehen alle bisherigen Planungen verloren!\n", @@ -673,7 +702,7 @@ "\n", "WEEK_P1 = WTemplate.to_2_schicht(5, \"Pack1\")\n", "WEEK_P2 = WTemplate.to_2_schicht(5, \"Pack2\")\n", - "WEEK_P3 = WTemplate.to_1_schicht(6, \"Pack3\")\n", + "WEEK_P3 = WTemplate.to_2_schicht(5, \"Pack3\")\n", "WEEK_P4 = WTemplate.to_1_schicht(7, \"Pack4\")" ] }, @@ -698,7 +727,7 @@ "sheet = vorlage[\"TLeistungsdaten\"]\n", "PACK_VORLAGE = packVorlage(sheet)\n", "LEISTUNGS_DICT = packLeistung(sheet)\n", - "\n", + "#\n", "print(\"Read Produktionsstammdaten\")\n", "sheet = vorlage[\"ProduktionStammdaten\"]\n", "PROD_STAMM = produktionStammdaten(sheet)\n", @@ -724,18 +753,34 @@ "# read Schedule from Dispo\n", "if FROM_DISPO:\n", " dispo = load_workbook(filename = DISPO, data_only = True, read_only = True)\n", - " if P1: dispoP1 = readDispo(dispo[\"Dispo Abpackplanung P1\"], LEISTUNGS_DICT)\n", - " if P2: dispoP2 = readDispo(dispo[\"Dispo Abpackplanung P2\"], LEISTUNGS_DICT)\n", - " if P3: dispoP3 = readDispo(dispo[\"Dispo Abpackplanung P3\"], LEISTUNGS_DICT)\n", - " if P4: dispoP4 = readDispo(dispo[\"Dispo Abpackplanung P4\"], LEISTUNGS_DICT)\n", + " if P1:\n", + " print(\"Reading Dispo P1\") \n", + " dispoP1 = readDispo(dispo[\"Dispo Abpackplanung P1\"], LEISTUNGS_DICT, prodDict)\n", + " if dispoP1 is None:\n", + " print(\".. encountered an error. Skipping!\")\n", + " if P2: \n", + " print(\"Reading Dispo P2\") \n", + " dispoP2 = readDispo(dispo[\"Dispo Abpackplanung P2\"], LEISTUNGS_DICT, prodDict)\n", + " if dispoP2 is None:\n", + " print(\".. encountered an error. Skipping!\")\n", + " if P3: \n", + " print(\"Reading Dispo P3\") \n", + " dispoP3 = readDispo(dispo[\"Dispo Abpackplanung P3\"], LEISTUNGS_DICT, prodDict)\n", + " if dispoP3 is None:\n", + " print(\".. encountered an error. Skipping!\")\n", + " if P4: \n", + " print(\"Reading Dispo P4\") \n", + " dispoP4 = readDispo(dispo[\"Dispo Abpackplanung P4\"], LEISTUNGS_DICT, prodDict)\n", + " if dispoP4 is None:\n", + " print(\".. encountered an error. Skipping!\")\n", " dispo.close()\n", "\n", " vorlage = load_workbook(filename = VORDEF, data_only = False, read_only = False)\n", - " writeMischDispo(vorlage, dispoP1[3], dispoP2[3], dispoP3[3], dispoP4[3], prodDict)\n", - " if P4: writeSchedule(vorlage, dispoP4, prodDict, \"Pack4\")\n", - " if P3: writeSchedule(vorlage, dispoP3, prodDict, \"Pack3\")\n", - " if P2: writeSchedule(vorlage, dispoP2, prodDict, \"Pack2\")\n", - " if P1: writeSchedule(vorlage, dispoP1, prodDict, \"Pack1\")\n", + " writeMischDispo(vorlage, dispoP1, dispoP2, dispoP3, dispoP4, prodDict)\n", + " if P4: writeSchedule(vorlage, dispoP4, \"Pack4\")\n", + " if P3: writeSchedule(vorlage, dispoP3, \"Pack3\")\n", + " if P2: writeSchedule(vorlage, dispoP2, \"Pack2\")\n", + " if P1: writeSchedule(vorlage, dispoP1, \"Pack1\")\n", " vorlage.save(PLANUNG_PATH)\n", " vorlage.close() \n" ] @@ -763,9 +808,10 @@ " marking = row[0].fill\n", " ))\n", " else: \n", - " l = LEISTUNGS_DICT[row[0].value]\n", + " prod_nr = row[0].value\n", + " l = LEISTUNGS_DICT[prod_nr]\n", " pas.append(Produktionsauftrag(\n", - " artikelNummer= row[0].value,\n", + " artikelNummer= prod_nr,\n", " artikelBezeichnung= row[1].value,\n", " gebindeGroesse= row[2].value,\n", " abpackMenge= int(row[3].value),\n", @@ -859,7 +905,7 @@ " marking = copy(row[0].fill)\n", " ))\n", " else:\n", - " prod = prodDict.get(f\"s{row[0].value}\", None)\n", + " prod = prodDict.get(row[0].value)\n", " if prod is None:\n", " print(f\"Could not find product data of {row[0].value}\")\n", " bundle = Bundle.fromString(prod.bundle)\n", @@ -868,7 +914,7 @@ " nbrBundles = int(nbrBags / bundle.nbrBags) if row[4].value is None else int(row[4].value)\n", " performance = int(row[7].value)\n", " if performance is None:\n", - " l = getPackLeistung(prod.number[1:])\n", + " l = getPackLeistung(prod.number)\n", " if l.artikelNummer == \"000000\":\n", " print(f\"Leistungsdaten für Produkt {prod.number} nicht verfügbar!\")\n", " \n", @@ -883,7 +929,7 @@ " \n", "\n", " pas.append(Produktionsauftrag(\n", - " artikelNummer= prod.number[1:],\n", + " artikelNummer= prod.number,\n", " artikelBezeichnung= prod.name,\n", " gebindeGroesse= bundle.szBundle,\n", " abpackMenge= amount,\n", @@ -1026,9 +1072,9 @@ " sheet.cell(row=rowOffset+startSlot, column=columnOffset+2).value = pa.gebindeGroesse\n", " sheet.cell(row=rowOffset+startSlot, column=columnOffset+4).value = pa.artikelBezeichnung\n", " else:\n", - " sheet.cell(row=rowOffset+startSlot, column=columnOffset+3).value = f\"p{pa.artikelNummer}\"\n", + " sheet.cell(row=rowOffset+startSlot, column=columnOffset+3).value = pa.artikelNummer\n", " sheet.cell(row=rowOffset+startSlot, column=columnOffset+7).value = pa.abpackMenge\n", - " prod = prodDict.get(pa.artikelNummer, None)\n", + " prod = prodDict.get(pa.artikelNummer)\n", " sheet.cell(row=rowOffset+startSlot, column=columnOffset+6).value = math.ceil(pa.anzGebinde / prod.palSize) if not prod is None else None\n", " if pa.bemerkung != \"\" and not pa.bemerkung is None and pa.pDauer >= 60:\n", " sheet.cell(row=rowOffset + startSlot + 1, column=columnOffset+4).value=pa.bemerkung\n", @@ -1203,7 +1249,7 @@ " writeAbpackplan(vorlage, WEEK_P3, scheduleP3, prodDict)\n", " if P2: \n", " print(\"Updating P2 ...\")\n", - " scheduleP2 = updateSchedule(vorlage[\"Schedule Pack2\"], \"Pack1\")\n", + " scheduleP2 = updateSchedule(vorlage[\"Schedule Pack2\"], \"Pack2\")\n", " writeSchedule2(vorlage, scheduleP2, \"Pack2\")\n", " writeAbpackplan(vorlage, WEEK_P2, scheduleP2, prodDict)\n", " if P1:\n", @@ -1214,6 +1260,7 @@ "\n", " sheet = vorlage[\"Mischungen\"]\n", " sheet[\"B2\"] = KW\n", + " sheet[\"B3\"] = YEAR\n", " \n", " print(\"\\nWriting to file ...\")\n", " vorlage.save(PLANUNG_PATH)\n", @@ -1423,7 +1470,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.1" + "version": "3.10.2" }, "metadata": { "interpreter": {