Should be replaced with a proper locale solution someday TODO function FormatMenge ($value) { return(number_format($value,0,',','.')); // DE // return(number_format($value,0,'.',',')); // EN } function __construct($app, $intern = false) { $this->app = $app; if ($intern) return; $this->app->ActionHandlerInit($this); $this->app->ActionHandler("list", "produktion_list"); $this->app->ActionHandler("create", "produktion_edit"); // This automatically adds a "New" button $this->app->ActionHandler("edit", "produktion_edit"); $this->app->ActionHandler("copy", "produktion_copy"); $this->app->ActionHandler("minidetail", "produktion_minidetail"); $this->app->ActionHandler("delete", "produktion_delete"); $this->app->DefaultActionHandler("list"); $this->app->ActionHandlerListen($app); $this->Install(); } public function Install() { } public function TableSearch(&$app, $name, $erlaubtevars) { switch ($name) { case "produktion_list": $allowed['produktion_list'] = array('list'); // $heading = array('','','datum', 'art', 'projekt', 'belegnr', 'internet', 'bearbeiter', 'angebot', 'freitext', 'internebemerkung', 'status', 'adresse', 'name', 'abteilung', 'unterabteilung', 'strasse', 'adresszusatz', 'ansprechpartner', 'plz', 'ort', 'land', 'ustid', 'ust_befreit', 'ust_inner', 'email', 'telefon', 'telefax', 'betreff', 'kundennummer', 'versandart', 'vertrieb', 'zahlungsweise', 'zahlungszieltage', 'zahlungszieltageskonto', 'zahlungszielskonto', 'bank_inhaber', 'bank_institut', 'bank_blz', 'bank_konto', 'kreditkarte_typ', 'kreditkarte_inhaber', 'kreditkarte_nummer', 'kreditkarte_pruefnummer', 'kreditkarte_monat', 'kreditkarte_jahr', 'firma', 'versendet', 'versendet_am', 'versendet_per', 'versendet_durch', 'autoversand', 'keinporto', 'keinestornomail', 'abweichendelieferadresse', 'liefername', 'lieferabteilung', 'lieferunterabteilung', 'lieferland', 'lieferstrasse', 'lieferort', 'lieferplz', 'lieferadresszusatz', 'lieferansprechpartner', 'packstation_inhaber', 'packstation_station', 'packstation_ident', 'packstation_plz', 'packstation_ort', 'autofreigabe', 'freigabe', 'nachbesserung', 'gesamtsumme', 'inbearbeitung', 'abgeschlossen', 'nachlieferung', 'lager_ok', 'porto_ok', 'ust_ok', 'check_ok', 'vorkasse_ok', 'nachnahme_ok', 'reserviert_ok', 'bestellt_ok', 'zeit_ok', 'versand_ok', 'partnerid', 'folgebestaetigung', 'zahlungsmail', 'stornogrund', 'stornosonstiges', 'stornorueckzahlung', 'stornobetrag', 'stornobankinhaber', 'stornobankkonto', 'stornobankblz', 'stornobankbank', 'stornogutschrift', 'stornogutschriftbeleg', 'stornowareerhalten', 'stornomanuellebearbeitung', 'stornokommentar', 'stornobezahlt', 'stornobezahltam', 'stornobezahltvon', 'stornoabgeschlossen', 'stornorueckzahlungper', 'stornowareerhaltenretour', 'partnerausgezahlt', 'partnerausgezahltam', 'kennen', 'logdatei', 'bezeichnung', 'datumproduktion', 'anschreiben', 'usereditid', 'useredittimestamp', 'steuersatz_normal', 'steuersatz_zwischen', 'steuersatz_ermaessigt', 'steuersatz_starkermaessigt', 'steuersatz_dienstleistung', 'waehrung', 'schreibschutz', 'pdfarchiviert', 'pdfarchiviertversion', 'typ', 'reservierart', 'auslagerart', 'projektfiliale', 'datumauslieferung', 'datumbereitstellung', 'unterlistenexplodieren', 'charge', 'arbeitsschrittetextanzeigen', 'einlagern_ok', 'auslagern_ok', 'mhd', 'auftragmengenanpassen', 'internebezeichnung', 'mengeoriginal', 'teilproduktionvon', 'teilproduktionnummer', 'parent', 'parentnummer', 'bearbeiterid', 'mengeausschuss', 'mengeerfolgreich', 'abschlussbemerkung', 'auftragid', 'funktionstest', 'seriennummer_erstellen', 'unterseriennummern_erfassen', 'datumproduktionende', 'standardlager', 'Menü'); $heading = array('','','Produktion','Kd-Nr.','Kunde','Vom','Bezeichnung','Soll','Ist','Zeit geplant','Zeit gebucht','Projekt','Status','Monitor','Menü'); $alignright = array(8,9,10,11); $width = array('1%','1%','10%'); // Fill out manually later $bezeichnung = "CONCAT ( IFNULL((SELECT CONCAT(a.name_de,' (',a.nummer,')','
') FROM artikel a INNER JOIN produktion_position pp ON pp.artikel = a.id WHERE pp.stuecklistestufe = 1 AND pp.produktion = p.id LIMIT 1),''), CONCAT('',internebezeichnung,'') )"; $adresse = "(SELECT name FROM adresse WHERE kundennummer = p.kundennummer AND p.kundennummer != 0 LIMIT 1)"; $findcols = array('p.id','p.id','p.belegnr','p.kundennummer',$adresse,'p.datum',$bezeichnung,'soll','ist', 'zeit_geplant','zeit_geplant', 'projekt','p.status','icons','id'); $searchsql = array('p.belegnr','p.kundennummer','p.name',$bezeichnung); $defaultorder = 1; $defaultorderdesc = 0; $dropnbox = "'' AS `open`, CONCAT('') AS `auswahl`"; $menu = "
" . "Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\"> ". "Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\">" . "Conf->WFconf['defaulttheme']}/images/copy.svg\" border=\"0\">" . "
"; // $sql = "SELECT SQL_CALC_FOUND_ROWS p.id, $dropnbox, p.datum, p.art, p.projekt, p.belegnr, p.internet, p.bearbeiter, p.angebot, p.freitext, p.internebemerkung, p.status, p.adresse, p.name, p.abteilung, p.unterabteilung, p.strasse, p.adresszusatz, p.ansprechpartner, p.plz, p.ort, p.land, p.ustid, p.ust_befreit, p.ust_inner, p.email, p.telefon, p.telefax, p.betreff, p.kundennummer, p.versandart, p.vertrieb, p.zahlungsweise, p.zahlungszieltage, p.zahlungszieltageskonto, p.zahlungszielskonto, p.bank_inhaber, p.bank_institut, p.bank_blz, p.bank_konto, p.kreditkarte_typ, p.kreditkarte_inhaber, p.kreditkarte_nummer, p.kreditkarte_pruefnummer, p.kreditkarte_monat, p.kreditkarte_jahr, p.firma, p.versendet, p.versendet_am, p.versendet_per, p.versendet_durch, p.autoversand, p.keinporto, p.keinestornomail, p.abweichendelieferadresse, p.liefername, p.lieferabteilung, p.lieferunterabteilung, p.lieferland, p.lieferstrasse, p.lieferort, p.lieferplz, p.lieferadresszusatz, p.lieferansprechpartner, p.packstation_inhaber, p.packstation_station, p.packstation_ident, p.packstation_plz, p.packstation_ort, p.autofreigabe, p.freigabe, p.nachbesserung, p.gesamtsumme, p.inbearbeitung, p.abgeschlossen, p.nachlieferung, p.lager_ok, p.porto_ok, p.ust_ok, p.check_ok, p.vorkasse_ok, p.nachnahme_ok, p.reserviert_ok, p.bestellt_ok, p.zeit_ok, p.versand_ok, p.partnerid, p.folgebestaetigung, p.zahlungsmail, p.stornogrund, p.stornosonstiges, p.stornorueckzahlung, p.stornobetrag, p.stornobankinhaber, p.stornobankkonto, p.stornobankblz, p.stornobankbank, p.stornogutschrift, p.stornogutschriftbeleg, p.stornowareerhalten, p.stornomanuellebearbeitung, p.stornokommentar, p.stornobezahlt, p.stornobezahltam, p.stornobezahltvon, p.stornoabgeschlossen, p.stornorueckzahlungper, p.stornowareerhaltenretour, p.partnerausgezahlt, p.partnerausgezahltam, p.kennen, p.logdatei, p.bezeichnung, p.datumproduktion, p.anschreiben, p.usereditid, p.useredittimestamp, p.steuersatz_normal, p.steuersatz_zwischen, p.steuersatz_ermaessigt, p.steuersatz_starkermaessigt, p.steuersatz_dienstleistung, p.waehrung, p.schreibschutz, p.pdfarchiviert, p.pdfarchiviertversion, p.typ, p.reservierart, p.auslagerart, p.projektfiliale, p.datumauslieferung, p.datumbereitstellung, p.unterlistenexplodieren, p.charge, p.arbeitsschrittetextanzeigen, p.einlagern_ok, p.auslagern_ok, p.mhd, p.auftragmengenanpassen, p.internebezeichnung, p.mengeoriginal, p.teilproduktionvon, p.teilproduktionnummer, p.parent, p.parentnummer, p.bearbeiterid, p.mengeausschuss, p.mengeerfolgreich, p.abschlussbemerkung, p.auftragid, p.funktionstest, p.seriennummer_erstellen, p.unterseriennummern_erfassen, p.datumproduktionende, p.standardlager, p.id FROM produktion p"; // $sql = "SELECT SQL_CALC_FOUND_ROWS p.id, $dropnbox, p.belegnr, p.kundennummer, p.name, p.datum, \"SUBSELECT\", \"SUBSELECT\", p.mengeerfolgreich, \"-\", \"-\", p.projekt, p.status, p.status, p.id FROM produktion p"; $sql = "SELECT SQL_CALC_FOUND_ROWS p.id, $dropnbox, p.belegnr, p.kundennummer, ".$adresse." as name, DATE_FORMAT(datum,'%d.%m.%Y') as datum, ".$bezeichnung." as bezeichnung, FORMAT((SELECT SUM(menge) FROM produktion_position pp WHERE pp.produktion = p.id AND pp.stuecklistestufe = 1),0,'de_DE') as soll, FORMAT(p.mengeerfolgreich,0,'de_DE') as ist, \"-\" as zeit_geplant, \"-\" as zeit_erfasst, (SELECT projekt.abkuerzung FROM projekt WHERE p.projekt = projekt.id LIMIT 1) as projekt, p.status, (" . $app->YUI->IconsSQL_produktion('p') . ") AS `icons`, p.id FROM produktion p "; $where = "0"; // Toggle filters $this->app->Tpl->Add('JQUERYREADY', "$('#angelegte').click( function() { fnFilterColumn1( 0 ); } );"); $this->app->Tpl->Add('JQUERYREADY', "$('#offene').click( function() { fnFilterColumn2( 0 ); } );"); $this->app->Tpl->Add('JQUERYREADY', "$('#geschlossene').click( function() { fnFilterColumn3( 0 ); } );"); $this->app->Tpl->Add('JQUERYREADY', "$('#stornierte').click( function() { fnFilterColumn4( 0 ); } );"); for ($r = 1;$r <= 4;$r++) { $this->app->Tpl->Add('JAVASCRIPT', ' function fnFilterColumn' . $r . ' ( i ) { if(oMoreData' . $r . $name . '==1) oMoreData' . $r . $name . ' = 0; else oMoreData' . $r . $name . ' = 1; $(\'#' . $name . '\').dataTable().fnFilter( \'\', i, 0,0 ); } '); } $more_data1 = $this->app->Secure->GetGET("more_data1"); if ($more_data1 == 1) { $where .= " OR p.status IN ('angelegt')"; } else { } $more_data2 = $this->app->Secure->GetGET("more_data2"); if ($more_data2 == 1) { $where .= " OR p.status IN ('freigegeben','gestartet')"; } else { } $more_data3 = $this->app->Secure->GetGET("more_data3"); if ($more_data3 == 1) { $where .= " OR p.status IN ('abgeschlossen')"; } else { } $more_data4 = $this->app->Secure->GetGET("more_data4"); if ($more_data4 == 1) { $where .= " OR p.status IN ('storniert')"; } else { } // END Toggle filters $moreinfo = true; // Allow drop down details $menucol = 14; // For moredata if ($where=='0') { $where = " p.status IN ('freigegeben','gestartet')"; } $count = "SELECT count(DISTINCT p.id) FROM produktion p INNER JOIN produktion_position pp ON pp.produktion = pp.id WHERE $where"; // $groupby = ""; break; case "produktion_position_source_list": $id = $app->Secure->GetGET('id'); $sql = "SELECT standardlager FROM produktion WHERE id=$id"; $standardlager = $app->DB->SelectArr($sql)[0]['standardlager']; $allowed['produktion_position_list'] = array('list'); $sql = "SELECT menge FROM produktion_position pp WHERE produktion=$id AND stuecklistestufe=1"; $produktionsmenge = $app->DB->SelectArr($sql)[0]['menge']; // Get status to control UI element menu availability $sql = "SELECT p.status from produktion p WHERE p.id = $id"; $result = $app->DB->SelectArr($sql)[0]; $status = $result['status']; if (in_array($status,array('angelegt','freigegeben'))) { $heading = array('','','Nummer', 'Artikel', 'Projekt', 'Planmenge pro Stück', 'Lager alle (verfügbar)', 'Lager (verfügbar)', 'Reserviert', 'Planmenge', 'Verbraucht', 'Menü'); $width = array( '1%','1%','5%', '30%', '5%', '1%', '1%', '1%' , '1%', '1%', '1%' ,'1%'); $menu = "
" . "Conf->WFconf['defaulttheme']}/images/edit.svg\" border=\"0\"> " . "Conf->WFconf['defaulttheme']}/images/delete.svg\" border=\"0\">" . "
"; } else { $heading = array('','','Nummer', 'Artikel', 'Projekt','Planmenge pro Stück', 'Lager alle (verfügbar)', 'Lager (verfügbar)', 'Reserviert', 'Planmenge', 'Verbraucht', ''); $width = array( '1%','1%','5%', '30%', '5%', '1%', '1%', '1%' , '1%', '1%', '1%' ,'1%'); $menu = ""; } $alignright = array(6,7,8,9,10); $findcols = array('','p.artikel','(SELECT a.nummer FROM artikel a WHERE a.id = p.artikel LIMIT 1)','(SELECT a.name_de FROM artikel a WHERE a.id = p.artikel LIMIT 1)','projekt','stueckmenge','lageralle','lager','reserviert','menge','geliefert_menge'); $searchsql = array('p.artikel','nummer','name','projekt','lager','menge','reserviert','geliefert_menge'); $defaultorder = 1; $defaultorderdesc = 0; $dropnbox = "'' AS `open`, CONCAT('') AS `auswahl`"; $sql = "SELECT SQL_CALC_FOUND_ROWS p.id, $dropnbox, (SELECT a.nummer FROM artikel a WHERE a.id = p.artikel LIMIT 1) as nummer, (SELECT a.name_de FROM artikel a WHERE a.id = p.artikel LIMIT 1) as name, (SELECT projekt.abkuerzung FROM projekt INNER JOIN artikel a WHERE a.projekt = projekt.id AND a.id = p.artikel LIMIT 1) as projekt, FORMAT(p.menge/$produktionsmenge,0,'de_DE') as stueckmenge, IF ((SELECT lagerartikel FROM artikel a WHERE a.id = p.artikel LIMIT 1) != 0, CONCAT ( FORMAT (IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.artikel = p.artikel),0),0,'de_DE'), ' (', FORMAT ( IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.artikel = p.artikel),0)- IFNULL((SELECT SUM(menge) FROM lager_reserviert r WHERE r.artikel = p.artikel),0), 0, 'de_DE' ), ')' ),'') as lageralle, if (('$standardlager' != '0') && ((SELECT lagerartikel FROM artikel a WHERE a.id = p.artikel LIMIT 1) != 0), CONCAT ( FORMAT (IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.lager_platz = $standardlager AND lpi.artikel = p.artikel),0),0,'de_DE'), ' (', FORMAT ( IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.lager_platz = $standardlager AND lpi.artikel = p.artikel),0)- IFNULL((SELECT SUM(menge) FROM lager_reserviert r WHERE r.lager_platz = $standardlager AND r.artikel = p.artikel),0), 0, 'de_DE' ), ')' ) ,'' ) as lager, FORMAT ((SELECT SUM(menge) FROM lager_reserviert r WHERE r.lager_platz = $standardlager AND r.artikel = p.artikel AND r.objekt = 'produktion' AND r.parameter = $id AND r.posid = p.id),0,'de_DE') as Reserviert, FORMAT(p.menge,0,'de_DE'), FORMAT(p.geliefert_menge,0,'de_DE') as geliefert_menge, p.id FROM produktion_position p"; $where = " stuecklistestufe = 0 AND produktion = $id"; $count = "SELECT count(DISTINCT id) FROM produktion_position WHERE $where"; // $groupby = ""; break; case "produktion_source_list": // Aggregated per artikel $id = $app->Secure->GetGET('id'); $sql = "SELECT menge FROM produktion_position pp WHERE produktion=$id AND stuecklistestufe=1"; $produktionsmenge = $app->DB->SelectArr($sql)[0]['menge']; $sql = "SELECT standardlager FROM produktion WHERE id=$id"; $standardlager = $app->DB->SelectArr($sql)[0]['standardlager']; $allowed['produktion_position_list'] = array('list'); $heading = array('','Nummer', 'Artikel', 'Projekt','Planmenge pro Stück', 'Lager alle (verfügbar)' ,'Lager (verfügbar)', 'Reserviert','Planmenge', 'Verbraucht',''); $width = array('1%','5%', '30%', '5%', '1%', '1%', '1%', '1%' , '1%', '1%' ,'1%'); $alignright = array(5,6,7,8,9); $findcols = array('p.artikel','(SELECT a.nummer FROM artikel a WHERE a.id = p.artikel LIMIT 1)','(SELECT a.name_de FROM artikel a WHERE a.id = p.artikel LIMIT 1)','projekt','stueckmenge','lageralle','lager','reserviert','menge','geliefert_menge'); $searchsql = array('p.artikel','nummer','name','projekt','lager','menge','reserviert','geliefert_menge'); $defaultorder = 1; $defaultorderdesc = 0; $drop = "'' AS `open`"; $sql = "SELECT SQL_CALC_FOUND_ROWS p.artikel, $drop, (SELECT a.nummer FROM artikel a WHERE a.id = p.artikel LIMIT 1) as nummer, (SELECT a.name_de FROM artikel a WHERE a.id = p.artikel LIMIT 1) as name, (SELECT projekt.abkuerzung FROM projekt INNER JOIN artikel a WHERE a.projekt = projekt.id AND a.id = p.artikel LIMIT 1) as projekt, FORMAT(SUM(p.menge)/$produktionsmenge,0,'de_DE') as stueckmenge, IF ((SELECT lagerartikel FROM artikel a WHERE a.id = p.artikel LIMIT 1) != 0, CONCAT ( FORMAT (IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.artikel = p.artikel),0),0,'de_DE'), ' (', FORMAT ( IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.artikel = p.artikel),0)- IFNULL((SELECT SUM(menge) FROM lager_reserviert r WHERE r.artikel = p.artikel),0), 0, 'de_DE' ), ')' ),'') as lageralle, if (('$standardlager' != '0') && ((SELECT lagerartikel FROM artikel a WHERE a.id = p.artikel LIMIT 1) != 0), CONCAT ( FORMAT (IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.lager_platz = $standardlager AND lpi.artikel = p.artikel),0),0,'de_DE'), ' (', FORMAT ( IFNULL((SELECT SUM(menge) FROM lager_platz_inhalt lpi WHERE lpi.lager_platz = $standardlager AND lpi.artikel = p.artikel),0)- IFNULL((SELECT SUM(menge) FROM lager_reserviert r WHERE r.lager_platz = $standardlager AND r.artikel = p.artikel),0), 0, 'de_DE' ), ')' ) ,'' ) as lager, FORMAT ((SELECT SUM(menge) FROM lager_reserviert r WHERE r.lager_platz = $standardlager AND r.artikel = p.artikel AND r.objekt = 'produktion' AND r.parameter = $id),0,'de_DE') as reserviert, FORMAT(SUM(p.menge),0,'de_DE') as menge, FORMAT(SUM(p.geliefert_menge),0,'de_DE') as geliefert_menge, p.id FROM produktion_position p"; $where = " stuecklistestufe = 0 AND produktion = $id"; $count = "SELECT count(DISTINCT id) FROM produktion_position WHERE $where"; $groupby = " GROUP BY p.artikel "; break; } $erg = false; foreach ($erlaubtevars as $k => $v) { if (isset($$v)) { $erg[$v] = $$v; } } return $erg; } function produktion_list() { $this->app->erp->MenuEintrag("index.php?module=produktion&action=list", "Übersicht"); $this->app->erp->MenuEintrag("index.php?module=produktion&action=create", "Neu anlegen"); $this->app->erp->MenuEintrag("index.php", "Zurück"); $this->StatusBerechnen(0); // all open ones $this->app->YUI->TableSearch('TAB1', 'produktion_list', "show", "", "", basename(__FILE__), __CLASS__); $this->app->Tpl->Parse('PAGE', "produktion_list.tpl"); } public function produktion_delete() { $id = (int) $this->app->Secure->GetGET('id'); // Check if storno possible -> No partial production yet $geliefert_menge = $this->app->DB->SelectArr("SELECT SUM(geliefert_menge) as menge FROM produktion_position pp WHERE pp.produktion = $id")[0]['menge']; if ($geliefert_menge == 0) { $sql = "UPDATE produktion SET status='storniert' WHERE id = '$id'"; $this->app->DB->Update($sql); $this->app->Tpl->Set('MESSAGE', "
Der Eintrag wurde storniert.
"); } else { $this->app->Tpl->Set('MESSAGE', "
Der Eintrag kann nicht storniert werden, da bereits Buchungen vorhanden sind.
"); } $this->produktion_list(); } /* * Edit produktion item * If id is empty, create a new one */ function produktion_edit($id = NULL) { if (empty($id)) { $id = $this->app->Secure->GetGET('id'); } if($this->app->erp->DisableModul('produktion',$id)) { return; } $submit = $this->app->Secure->GetPOST('submit'); $this->app->Tpl->Set('ID', $id); $this->app->erp->MenuEintrag("index.php?module=produktion&action=edit&id=$id", "Details"); $this->app->erp->MenuEintrag("index.php?module=produktion&action=list", "Zurück zur Übersicht"); $input = $this->GetInput(); $msg = $this->app->erp->base64_url_decode($this->app->Secure->GetGET('msg')); $sql = "SELECT status, belegnr, projekt, standardlager FROM produktion WHERE id = '$id'"; $from_db = $this->app->DB->SelectArr($sql)[0]; $global_status = $from_db['status']; $global_produktionsnummer = $from_db['belegnr']; $global_projekt = $from_db['projekt']; $global_standardlager = $from_db['standardlager']; // foreach ($input as $key => $value) { // echo($key." -> ".$value."
\n"); // } $this->app->Tpl->Set('MESSAGE', ""); if (empty($id)) { // New item $id = 'NULL'; } else { } if ($submit != '') { $msg = ""; switch ($submit) { case 'speichern': // Write to database // Add checks here if (empty($input['datum'])) { $input['datum'] = date("Y-m-d"); } else { $input['datum'] = $this->app->erp->ReplaceDatum(true,$input['datum'],true); } if ($id == 'NULL') { $input['status'] = 'angelegt'; } $input['datumauslieferung'] = $this->app->erp->ReplaceDatum(true,$input['datumauslieferung'],true); $input['datumbereitstellung'] = $this->app->erp->ReplaceDatum(true,$input['datumbereitstellung'],true); $input['datumproduktion'] = $this->app->erp->ReplaceDatum(true,$input['datumproduktion'],true); $input['datumproduktionende'] = $this->app->erp->ReplaceDatum(true,$input['datumproduktionende'],true); $input['projekt'] = $this->app->erp->ReplaceProjekt(true,$input['projekt'],true); $columns = "id, "; $values = "$id, "; $update = ""; $fix = ""; foreach ($input as $key => $value) { $columns = $columns.$fix.$key; $values = $values.$fix."'".$value."'"; $update = $update.$fix.$key." = '$value'"; $fix = ", "; } $sql = "INSERT INTO produktion (".$columns.") VALUES (".$values.") ON DUPLICATE KEY UPDATE ".$update; $this->app->DB->Update($sql); if ($id == 'NULL') { $id = $this->app->DB->GetInsertID(); if (!empty($id)) { $this->ProtokollSchreiben($id,'Produktion angelegt'); $msg = "
Das Element wurde erfolgreich angelegt.
"; // Overwrite old MSG $msg = $this->app->erp->base64_url_encode($msg); header("Location: index.php?module=produktion&action=edit&id=$id&msg=$msg"); } } else { $msg .= "
Die Einstellungen wurden erfolgreich übernommen.
"; } break; case 'planen': // Check // Parse positions $sql = "SELECT artikel FROM produktion_position pp WHERE produktion=$id AND stuecklistestufe=1"; $produktionsartikel = $this->app->DB->SelectArr($sql); if (!empty($produktionsartikel)) { $msg .= "
Bereits geplant.
"; break; } $artikel_planen_id = $this->app->erp->ReplaceArtikel(true, $this->app->Secure->GetPOST('artikel_planen'),true); // Convert from form to artikel number $artikel_planen_menge = $this->app->Secure->GetPOST('artikel_planen_menge'); if (!$artikel_planen_id) { $msg .= "
Artikel ist keine Stückliste.
"; break; } if ($artikel_planen_menge < 1) { $msg .= "
Ungültige Planmenge.
"; break; } // Insert positions $position_array = array(); $sql = "SELECT '".$id."' as id, artikel, menge, '0' as stuecklistestufe FROM stueckliste WHERE stuecklistevonartikel = ".$artikel_planen_id; $stueckliste = $this->app->DB->SelectArr($sql); if (empty($stueckliste)) { $msg .= "
Stückliste ist leer.
"; break; } foreach ($stueckliste as $key => $value) { $value['menge'] = $value['menge'] * $artikel_planen_menge; $position_values[] = '('.implode(",",$value).',\'\')'; } $sql = "INSERT INTO produktion_position (produktion, artikel, menge, stuecklistestufe, projekt) VALUES ( $id, $artikel_planen_id, $artikel_planen_menge, 1, '$global_projekt'), ".implode(',',$position_values); $this->app->DB->Update($sql); $msg .= "
Planung angelegt.
"; $this->ProtokollSchreiben($id,"Produktion geplant ($artikel_planen_menge)"); break; case 'freigeben': $this->app->erp->BelegFreigabe("produktion",$id); $this->ProtokollSchreiben($id,'Produktion freigegeben'); break; case 'reservieren': // Check quantities and reserve for every position if($global_standardlager == 0) { break; } $fortschritt = $this->MengeFortschritt($id,$global_standardlager); if (empty($fortschritt)) { break; } $sql = "SELECT pp.id, pp.artikel, a.name_de, a.nummer, pp.menge as menge, pp.geliefert_menge as geliefert_menge FROM produktion_position pp INNER JOIN artikel a ON a.id = pp.artikel WHERE pp.produktion=$id AND pp.stuecklistestufe=0"; $materialbedarf = $this->app->DB->SelectArr($sql); // Try to reserve material $reservierung_durchgefuehrt = false; foreach ($materialbedarf as $materialbedarf_position) { // Calculate new needed quantity if there is scrap $materialbedarf_position['menge'] = $materialbedarf_position['menge']*($fortschritt['ausschuss']+$fortschritt['geplant'])/$fortschritt['geplant']; $result = $this->ArtikelReservieren($materialbedarf_position['artikel'], $global_standardlager, $materialbedarf_position['menge']-$materialbedarf_position['geliefert_menge'], 0, 'produktion', $id, $materialbedarf_position['id'],"Produktion $global_produktionsnummer"); if ($result > 0) { $reservierung_durchgefuehrt = true; } } // Message output if ($reservierung_durchgefuehrt) { $msg .= "
Reservierung durchgeführt.
"; } else { $msg .= "
Keine Reservierung durchgeführt!
"; } break; case 'produzieren': // Check quanitites // Parse positions $sql = "SELECT artikel, menge, geliefert_menge FROM produktion_position pp WHERE produktion=$id AND stuecklistestufe=1"; $produktionsartikel_position = $this->app->DB->SelectArr($sql)[0]; if (empty($produktionsartikel_position)) { $msg .= "
Keine Planung vorhanden.
"; break; } $menge_produzieren = $this->app->Secure->GetPOST('menge_produzieren'); if (empty($menge_produzieren)) { $menge_produzieren = 0; } $menge_ausschuss = $this->app->Secure->GetPOST('menge_ausschuss_produzieren'); if (empty($menge_ausschuss)) { $menge_ausschuss = 0; } $menge_plan = $produktionsartikel_position['menge']; $menge_geliefert = $produktionsartikel_position['geliefert_menge']; $menge_auslagern = $menge_produzieren+$menge_ausschuss; if ($menge_auslagern < 1) { $msg .= "
Ungültige Menge.
"; break; } $menge_moeglich = $this->LagerCheckProduktion($id, $global_standardlager, false); if ($menge_auslagern > $menge_moeglich) { $msg .= "
Lagermenge nicht ausreichend. ($menge_auslagern > $menge_moeglich)
"; break; } $sql = "UPDATE produktion SET status = 'gestartet' WHERE id=$id"; $this->app->DB->Update($sql); $sql = "SELECT pp.id, pp.artikel, pp.menge, pp.geliefert_menge, pp.stuecklistestufe, a.lagerartikel FROM produktion_position pp INNER JOIN artikel a ON a.id = pp.artikel WHERE pp.produktion=$id"; $material = $this->app->DB->SelectArr($sql); foreach ($material as $material_position) { // Calculate quantity to be removed $menge_artikel_auslagern = $material_position['menge']/$produktionsartikel_position['menge']*$menge_auslagern; // Remove material from stock if ($material_position['stuecklistestufe'] == 0 && $material_position['lagerartikel']) { $result = $this->app->erp->LagerAuslagernRegal($material_position['artikel'],$global_standardlager,$menge_artikel_auslagern,$global_projekt,'Produktion '.$global_produktionsnummer); if ($result != 1) { $msg .= "
Kritischer Fehler beim Ausbuchen! (Position ".$material_position['id'].", Menge ".$menge_artikel_auslagern.").
". $error = true; break; } // Adjust reservation $result = $this->ArtikelReservieren($material_position['artikel'],$global_standardlager,-$menge_artikel_auslagern,0,'produktion',$id,$material_position['id'],"Produktion $global_produktionsnummer"); } // Update position $sql = "UPDATE produktion_position SET geliefert_menge = geliefert_menge + $menge_artikel_auslagern WHERE id = ".$material_position['id']; $this->app->DB->Update($sql); } if ($error) { break; } // Insert produced parts into stock // Check target stock, if not existing, use default stock of article, if not given use production stock $ziellager_from_form = $this->app->erp->ReplaceLagerPlatz(true,$this->app->Secure->GetPOST('ziellager'),true); // Parameters: Target db?, value, from form? $use_artikel_lager = false; $ziellager = $global_standardlager; if (!empty($ziellager_from_form)) { $sql = "SELECT id FROM lager_platz WHERE id = ".$ziellager_from_form; $result = $this->app->DB->SelectArr($sql); if (!empty($result)) { $ziellager = $ziellager_from_form; } else { $use_artikel_lager = true; } } else { $use_artikel_lager = true; } if ($use_artikel_lager) { $sql = "SELECT lager_platz FROM artikel WHERE id = ".$produktionsartikel_position['artikel']; $result = $this->app->DB->SelectArr($sql); if (!empty($result) && !empty($result[0]['lager_platz'])) { $ziellager = $result[0]['lager_platz']; } else { } } else { } $sql = "SELECT kurzbezeichnung FROM lager_platz WHERE id = $ziellager"; $lagername = $this->app->DB->SelectArr($sql)[0]['kurzbezeichnung']; // ERPAPI // function LagerEinlagern($artikel,$menge,$regal,$projekt,$grund="",$importer="",$paketannahme="",$doctype = "", $doctypeid = 0, $vpeid = 0, $permanenteinventur = 0, $adresse = 0) $this->app->erp->LagerEinlagern($produktionsartikel_position['artikel'],$menge_produzieren,$ziellager,$global_projekt,"Produktion $global_produktionsnummer"); // No error handling in LagerEinlagern... $sql = "UPDATE produktion SET mengeerfolgreich = mengeerfolgreich + $menge_produzieren, mengeausschuss = mengeausschuss + $menge_ausschuss WHERE id = $id"; $this->app->DB->Update($sql); if ($menge_produzieren > 0) { $lagertext = ", eingelagert in $lagername"; } $text = "Produktion durchgeführt ($menge_produzieren erfolgreich, $menge_ausschuss Ausschuss)$lagertext"; $msg .= "
$text.
"; $this->ProtokollSchreiben($id,$text); break; case 'teilen': // Create partial production $menge_abteilen = $this->app->Secure->GetPOST('menge_produzieren'); $fortschritt = $this->MengeFortschritt($id,$global_standardlager); if (empty($fortschritt)) { break; } if (($menge_abteilen < 1) || ($menge_abteilen > $fortschritt['offen'])) { $msg .= "
Ungültige Teilmenge.
"; break; } $sql = "SELECT * from produktion WHERE id = $id"; $produktion_alt = $this->app->DB->SelectArr($sql)[0]; // Part production of part production -> select parent $hauptproduktion_id = $produktion_alt['teilproduktionvon']; if ($hauptproduktion_id != 0) { $sql = "SELECT belegnr FROM produktion WHERE id = $hauptproduktion_id"; $hauptproduktion_belegnr = $this->app->DB->SelectArr($sql)[0]['belegnr']; } else { $hauptproduktion_id = $produktion_alt['id']; $hauptproduktion_belegnr = $produktion_alt['belegnr']; } $sql = "SELECT MAX(teilproduktionnummer) as tpn FROM produktion WHERE teilproduktionvon = $hauptproduktion_id"; $teilproduktionnummer = $this->app->DB->SelectArr($sql)[0]['tpn']; if (empty($teilproduktionnummer) || $teilproduktionnummer == 0) { $teilproduktionnummer = '1'; } else { $teilproduktionnummer++; } $produktion_neu = array(); $produktion_neu['status'] = 'angelegt'; $produktion_neu['datum'] = date("Y-m-d"); $produktion_neu['art'] = $produktion_alt['art']; $produktion_neu['projekt'] = $produktion_alt['projekt']; $produktion_neu['angebot'] = $produktion_alt['angebot']; $produktion_neu['kundennummer'] = $produktion_alt['kundennummer']; $produktion_neu['auftragid'] = $produktion_alt['auftragid']; $produktion_neu['freitext'] = $produktion_alt['freitext']; $produktion_neu['internebemerkung'] = $produktion_alt['internebemerkung']; $produktion_neu['adresse'] = $produktion_alt['adresse']; $produktion_neu['internebemerkung'] = $produktion_alt['internebemerkung']; $produktion_neu['internebezeichnung '] = $produktion_alt['internebezeichnung']; $produktion_neu['standardlager'] = $produktion_alt['standardlager']; $produktion_neu['belegnr'] = $hauptproduktion_belegnr."-".$teilproduktionnummer; $produktion_neu['teilproduktionvon'] = $hauptproduktion_id; $produktion_neu['teilproduktionnummer'] = $teilproduktionnummer; $columns = ""; $values = ""; $update = ""; $fix = ""; foreach ($produktion_neu as $key => $value) { $columns = $columns.$fix.$key; $values = $values.$fix."'".$value."'"; $update = $update.$fix.$key." = '$value'"; $fix = ", "; } $sql = "INSERT INTO produktion (".$columns.") VALUES (".$values.")"; $this->app->DB->Update($sql); $produktion_neu_id = $this->app->DB->GetInsertID(); // Now add the positions $sql = "SELECT * FROM produktion_position WHERE produktion = $id"; $positionen = $this->app->DB->SelectArr($sql); foreach ($positionen as $position) { $columns = ""; // Preserve these values $pos_id = $position['id']; $geliefert_menge = $position['geliefert_menge']; $menge = $position['menge']; $produktion_alt_id = $position['produktion']; $menge_pro_stueck = $menge/$fortschritt['geplant']; // For the new positions $position['id'] = 'NULL'; $position['geliefert_menge'] = 0; $position['menge'] = $menge_abteilen*$menge_pro_stueck; $position['produktion'] = $produktion_neu_id; $values = ""; $fix = ""; foreach ($position as $key => $value) { $columns = $columns.$fix.$key; $values = $values.$fix."'".$value."'"; $fix = ", "; } $sql = "INSERT INTO produktion_position (".$columns.") VALUES (".$values.")"; $this->app->DB->Update($sql); // For the old positions // Reduce positions in old production $position['id'] = $pos_id; $position['geliefert_menge'] = $geliefert_menge; $position['menge'] = $menge - $position['menge']; // old quantity - partial quantity $position['produktion'] = $produktion_alt_id; $fix = ""; $update = ""; foreach ($position as $key => $value) { $update = $update.$fix.$key." = '".($value)."'"; $fix = ", "; } $sql = "UPDATE produktion_position SET $update WHERE id = $pos_id"; $this->app->DB->Update($sql); // Free surplus reservations $restreservierung = $menge_pro_stueck * $fortschritt['offen']-$menge_abteilen; $result = $this->ArtikelReservieren($position['artikel'],$global_standardlager,0,$restreservierung,'produktion',$id,$position['id'],"Produktion $global_produktionsnummer"); } $this->ProtokollSchreiben($id,"Teilproduktion erstellt: ".$produktion_neu['belegnr']." (Menge $menge_abteilen)"); $msg = "
Das Element wurde erfolgreich angelegt.
"; // Overwrite old MSG $msg = $this->app->erp->base64_url_encode($msg); header("Location: index.php?module=produktion&action=edit&id=$produktion_neu_id&msg=$msg"); break; case 'leeren': if ($global_status == 'angelegt' || $global_status == 'freigegeben') { $sql = "SELECT id, artikel, menge, geliefert_menge FROM produktion_position pp WHERE produktion=$id AND stuecklistestufe=0"; $material = $this->app->DB->SelectArr($sql); foreach ($material as $material_position) { // Remove reservation $result = $this->ArtikelReservieren($material_position['artikel'],$global_standardlager,0,0,'produktion',$id,$material_position['id'],"Produktion $global_produktionsnummer"); } $sql = "DELETE FROM produktion_position WHERE produktion = $id"; $this->app->DB->Update($sql); $msg .= "
Planung geleert.
"; } else { $msg .= "
Planung kann nicht geleert werden.
"; } break; case 'anpassen': if ($global_status == 'angelegt' || $global_status == 'freigegeben' || $global_status == 'gestartet') { $menge_anpassen = $this->app->Secure->GetPOST('menge_produzieren'); if (empty($menge_anpassen)) { $msg .= "
Ungültige Planmenge.
"; break; } $fortschritt = $this->MengeFortschritt($id,$global_standardlager); $result = $this->MengeAnpassen($id,$menge_anpassen,$global_standardlager); if ($result == -1) { $msg .= "
Ungültige Planmenge.
"; } else { $msg .= "
Planmenge angepasst.
"; } } $this->ProtokollSchreiben($id,"Menge angepasst auf ".$this->FormatMenge($menge_anpassen)); break; case 'abschliessen': $sql = "UPDATE produktion SET status = 'abgeschlossen' WHERE id=$id"; $this->app->DB->Update($sql); $sql = "SELECT id, artikel, menge, geliefert_menge FROM produktion_position pp WHERE produktion=$id AND stuecklistestufe=0"; $material = $this->app->DB->SelectArr($sql); foreach ($material as $material_position) { // Remove reservation $result = $this->ArtikelReservieren($material_position['artikel'],$global_standardlager,0,0,'produktion',$id,$material_position['id'],"Produktion $global_produktionsnummer"); } $this->ProtokollSchreiben($id,'Produktion abgeschlossen'); break; } } // Load values again from database // toDo: cleanup $sql = "SELECT SQL_CALC_FOUND_ROWS p.id, (SELECT pp.bezeichnung FROM produktion_position pp WHERE pp.produktion = p.id AND pp.stuecklistestufe = 1 LIMIT 1) as artikelname, p.datum, p.art, p.projekt, p.belegnr, p.internet, p.bearbeiter, p.angebot, p.freitext, p.internebemerkung, p.status, p.adresse, p.name, p.abteilung, p.unterabteilung, p.strasse, p.adresszusatz, p.ansprechpartner, p.plz, p.ort, p.land, p.ustid, p.ust_befreit, p.ust_inner, p.email, p.telefon, p.telefax, p.betreff, p.kundennummer, p.versandart, p.vertrieb, p.zahlungsweise, p.zahlungszieltage, p.zahlungszieltageskonto, p.zahlungszielskonto, p.bank_inhaber, p.bank_institut, p.bank_blz, p.bank_konto, p.kreditkarte_typ, p.kreditkarte_inhaber, p.kreditkarte_nummer, p.kreditkarte_pruefnummer, p.kreditkarte_monat, p.kreditkarte_jahr, p.firma, p.versendet, p.versendet_am, p.versendet_per, p.versendet_durch, p.autoversand, p.keinporto, p.keinestornomail, p.abweichendelieferadresse, p.liefername, p.lieferabteilung, p.lieferunterabteilung, p.lieferland, p.lieferstrasse, p.lieferort, p.lieferplz, p.lieferadresszusatz, p.lieferansprechpartner, p.packstation_inhaber, p.packstation_station, p.packstation_ident, p.packstation_plz, p.packstation_ort, p.autofreigabe, p.freigabe, p.nachbesserung, p.gesamtsumme, p.inbearbeitung, p.abgeschlossen, p.nachlieferung, p.lager_ok, p.porto_ok, p.ust_ok, p.check_ok, p.vorkasse_ok, p.nachnahme_ok, p.reserviert_ok, p.bestellt_ok, p.zeit_ok, p.versand_ok, p.partnerid, p.folgebestaetigung, p.zahlungsmail, p.stornogrund, p.stornosonstiges, p.stornorueckzahlung, p.stornobetrag, p.stornobankinhaber, p.stornobankkonto, p.stornobankblz, p.stornobankbank, p.stornogutschrift, p.stornogutschriftbeleg, p.stornowareerhalten, p.stornomanuellebearbeitung, p.stornokommentar, p.stornobezahlt, p.stornobezahltam, p.stornobezahltvon, p.stornoabgeschlossen, p.stornorueckzahlungper, p.stornowareerhaltenretour, p.partnerausgezahlt, p.partnerausgezahltam, p.kennen, p.logdatei, p.bezeichnung, p.datumproduktion, p.anschreiben, p.usereditid, p.useredittimestamp, p.steuersatz_normal, p.steuersatz_zwischen, p.steuersatz_ermaessigt, p.steuersatz_starkermaessigt, p.steuersatz_dienstleistung, p.waehrung, p.schreibschutz, p.pdfarchiviert, p.pdfarchiviertversion, p.typ, p.reservierart, p.auslagerart, p.projektfiliale, p.datumauslieferung, p.datumbereitstellung, p.unterlistenexplodieren, p.charge, p.arbeitsschrittetextanzeigen, p.einlagern_ok, p.auslagern_ok, p.mhd, p.auftragmengenanpassen, p.internebezeichnung, p.mengeoriginal, p.teilproduktionvon, p.teilproduktionnummer, p.parent, p.parentnummer, p.bearbeiterid, p.mengeausschuss, p.mengeerfolgreich, p.abschlussbemerkung, p.auftragid, p.funktionstest, p.seriennummer_erstellen, p.unterseriennummern_erfassen, p.datumproduktionende, p.standardlager, p.id FROM produktion p"." WHERE id=$id"; $produktion_from_db = $this->app->DB->SelectArr($sql)[0]; foreach ($produktion_from_db as $key => $value) { $this->app->Tpl->Set(strtoupper($key), $value); } /* * Add displayed items later */ $this->StatusBerechnen((int)$id); $sql = "SELECT " . $this->app->YUI->IconsSQL_produktion('p') . " AS `icons` FROM produktion p WHERE id=$id"; $icons = $this->app->DB->SelectArr($sql); $this->app->Tpl->Add('STATUSICONS', $icons[0]['icons']); if ($produktion_from_db['teilproduktionvon'] != 0) { $sql = "SELECT belegnr FROM produktion WHERE id = ".$produktion_from_db['teilproduktionvon']; $hauptproduktion_belegnr = $this->app->DB->SelectArr($sql)[0]['belegnr']; $this->app->Tpl->Set('TEILPRODUKTIONINFO',"Teilproduktion von ".$hauptproduktion_belegnr); } $sql = "SELECT belegnr FROM produktion WHERE teilproduktionvon = $id"; $teilproduktionen = $this->app->DB->SelectArr($sql); if (!empty($teilproduktionen)) { $this->app->Tpl->Set('TEILPRODUKTIONINFO',"Zu dieser Produktion gehören die Teilproduktionen: ".implode(', ',array_column($teilproduktionen,'belegnr'))); } if($produktion_from_db['standardlager'] == 0) { $msg .= "
Kein Materiallager ausgewählt.
"; } $this->app->Tpl->Set('PROJEKT',$this->app->erp->ReplaceProjekt(false,$produktion_from_db['projekt'],false)); $this->app->YUI->AutoComplete("projekt", "projektname", 1); $this->app->YUI->AutoComplete("kundennummer", "kunde", 1); $this->app->YUI->AutoComplete("auftragid", "auftrag", 1); $this->app->YUI->AutoComplete("artikel_planen", "stuecklistenartikel"); $this->app->YUI->AutoComplete("artikel_hinzu", "artikelnummer"); $this->app->YUI->AutoComplete("standardlager", "lagerplatz"); $this->app->YUI->AutoComplete("ziellager", "lagerplatz"); $this->app->YUI->AutoComplete("artikel", "artikelnummer"); $this->app->Tpl->Set('STANDARDLAGER', $this->app->erp->ReplaceLagerPlatz(false,$produktion_from_db['standardlager'],false)); // Convert ID to form display $this->app->YUI->DatePicker("datum"); $this->app->Tpl->Set('DATUM',$this->app->erp->ReplaceDatum(false,$produktion_from_db['datum'],true)); $this->app->YUI->DatePicker("datumauslieferung"); $this->app->Tpl->Set('DATUMAUSLIEFERUNG',$this->app->erp->ReplaceDatum(false,$produktion_from_db['datumauslieferung'],false)); $this->app->YUI->DatePicker("datumbereitstellung"); $this->app->Tpl->Set('DATUMBEREITSTELLUNG',$this->app->erp->ReplaceDatum(false,$produktion_from_db['datumbereitstellung'],false)); $this->app->YUI->DatePicker("datumproduktion"); $this->app->Tpl->Set('DATUMPRODUKTION',$this->app->erp->ReplaceDatum(false,$produktion_from_db['datumproduktion'],false)); $this->app->YUI->DatePicker("datumproduktionende"); $this->app->Tpl->Set('DATUMPRODUKTIONENDE',$this->app->erp->ReplaceDatum(false,$produktion_from_db['datumproduktionende'],false)); $this->app->YUI->CkEditor("freitext","internal", null, 'JQUERY'); $this->app->YUI->CkEditor("internebemerkung","internal", null, 'JQUERY'); /* UI Elements AKTION_SPEICHERN_DISABLED AKTION_PLANEN_VISIBLE AKTION_FREIGEBEN_VISIBLE AKTION_RESERVIEREN_VISIBLE AKTION_PRODUZIEREN_VISIBLE AKTION_ABSCHLIESSEN_VISIBLE POSITIONEN_TAB_VISIBLE */ // Reparse positions $sql = "SELECT id,artikel, menge, geliefert_menge FROM produktion_position pp WHERE produktion=$id AND stuecklistestufe=1"; $produktionsartikel_position = $this->app->DB->SelectArr($sql)[0]; // Not planned if (empty($produktionsartikel_position)) { $this->app->Tpl->Set('AKTION_FREIGEBEN_VISIBLE','hidden'); $this->app->Tpl->Set('ARTIKEL_MENGE_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_PRODUZIEREN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_LEEREN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_RESERVIEREN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_TEILEN_VISIBLE','hidden'); } else { // Planned $fortschritt = $this->MengeFortschritt((int) $id, 0); if (!empty($fortschritt)) { $this->app->Tpl->Set('MENGE_GEPLANT',$this->FormatMenge($fortschritt['geplant'])); $this->app->Tpl->Set('MENGE_PRODUZIERT',$this->FormatMenge($fortschritt['produziert'])); $this->app->Tpl->Set('MENGE_OFFEN',$this->FormatMenge($fortschritt['offen'])); $this->app->Tpl->Set('MENGE_RESERVIERT',$this->FormatMenge($fortschritt['reserviert'])); $this->app->Tpl->Set('MENGE_PRODUZIERBAR',$this->FormatMenge($fortschritt['produzierbar'])); $this->app->Tpl->Set('MENGE_ERFOLGREICH',$this->FormatMenge($fortschritt['erfolgreich'])); $this->app->Tpl->Set('MENGE_AUSSCHUSS',$this->FormatMenge($fortschritt['ausschuss'])); } if ($fortschritt['produziert'] > $fortschritt['geplant']) { $msg .= "
Planmenge überschritten.
"; } $this->app->Tpl->Set('AKTION_PLANEN_VISIBLE','hidden'); $this->app->YUI->TableSearch('PRODUKTION_POSITION_SOURCE_POSITION_TABELLE', 'produktion_position_source_list', "show", "", "", basename(__FILE__), __CLASS__); $this->app->YUI->TableSearch('PRODUKTION_POSITION_SOURCE_TABELLE', 'produktion_source_list', "show", "", "", basename(__FILE__), __CLASS__); $produktionsartikel_id = $produktionsartikel_position['artikel']; $sql = "SELECT name_de,nummer FROM artikel WHERE id=".$produktionsartikel_id; $produktionsartikel = $this->app->DB->SelectArr($sql)[0]; $produktionsartikel_name = $produktionsartikel['name_de']; $produktionsartikel_nummer = $produktionsartikel['nummer']; } if (empty($produktion_from_db['belegnr'])) { $this->app->Tpl->SetText('KURZUEBERSCHRIFT2', 'ENTWURF - '.$produktionsartikel_name." (".$produktionsartikel_nummer.")"); } else { $this->app->Tpl->SetText('KURZUEBERSCHRIFT2', $produktion_from_db['belegnr']." ".$produktionsartikel_name." (".$produktionsartikel_nummer.")"); } $this->app->Tpl->SetText('ARTIKELNAME', $produktionsartikel_name); // Action menu switch ($produktion_from_db['status']) { case 'angelegt': $this->app->Tpl->Set('AKTION_RESERVIEREN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_PRODUZIEREN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_ABSCHLIESSEN_VISIBLE','hidden'); break; case 'freigegeben': $this->app->Tpl->Set('AKTION_FREIGEBEN_VISIBLE','hidden'); break; case 'gestartet': $this->app->Tpl->Set('AKTION_FREIGEBEN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_PLANEN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_LEEREN_VISIBLE','hidden'); break; case 'abgeschlossen': case 'storniert': $this->app->Tpl->Set('AKTION_SPEICHERN_DISABLED','disabled'); $this->app->Tpl->Set('AKTION_PLANEN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_FREIGEBEN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_RESERVIEREN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_PRODUZIEREN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_TEILEN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_ABSCHLIESSEN_VISIBLE','hidden'); $this->app->Tpl->Set('AKTION_LEEREN_VISIBLE','hidden'); break; default: // new item $this->app->Tpl->Set('POSITIONEN_TAB_VISIBLE','hidden="hidden"'); break; } $this->app->Tpl->Set('PRODUKTION_ID',$id); $this->app->Tpl->Set('MESSAGE', $msg); $this->produktion_minidetail('MINIDETAILINEDIT'); $this->app->Tpl->Parse('PAGE', "produktion_edit.tpl"); } /* Create a copy as draft */ function produktion_copy() { $id = (int) $this->app->Secure->GetGET('id'); if (empty($id)) { return; } $result = $this->Copy($id,0); if ($result <= 0) { $msg .= "
Fehler beim Anlegen der Kopie.
"; $this->app->Tpl->Set('MESSAGE', $msg); $this->produktion_list(); } else { $msg .= "
Kopie angelegt. $result new $id old
"; $this->app->Tpl->Set('MESSAGE', $msg); $this->produktion_edit((int) $result); } } public function produktion_minidetail($parsetarget='',$menu=true) { $id = $this->app->Secure->GetGET('id'); $fortschritt = $this->MengeFortschritt((int) $id, 0); if (!empty($fortschritt)) { $this->app->Tpl->Set('MINI_MENGE_GEPLANT',$this->FormatMenge($fortschritt['geplant'])); $this->app->Tpl->Set('MINI_MENGE_PRODUZIERT',$this->FormatMenge($fortschritt['produziert'])); $this->app->Tpl->Set('MINI_MENGE_OFFEN',$this->FormatMenge($fortschritt['offen'])); $this->app->Tpl->Set('MINI_MENGE_RESERVIERT',$this->FormatMenge($fortschritt['reserviert'])); $this->app->Tpl->Set('MINI_MENGE_PRODUZIERBAR',$this->FormatMenge($fortschritt['produzierbar'])); $this->app->Tpl->Set('MINI_MENGEERFOLGREICH',$this->FormatMenge($fortschritt['erfolgreich'])); $this->app->Tpl->Set('MINI_MENGEAUSSCHUSS',$this->FormatMenge($fortschritt['ausschuss'])); } $this->ProtokollTabelleErzeugen($id, 'PROTOKOLL'); if($parsetarget=='') { $this->app->Tpl->Output('produktion_minidetail.tpl'); $this->app->ExitXentral(); } $this->app->Tpl->Parse($parsetarget,'produktion_minidetail.tpl'); } /** * Get all paramters from html form and save into $input */ public function GetInput(): array { $input = array(); $input['kundennummer'] = $this->app->Secure->GetPOST('kundennummer'); $input['projekt'] = $this->app->Secure->GetPOST('projekt'); $input['auftragid'] = $this->app->Secure->GetPOST('auftragid'); $input['internebezeichnung'] = $this->app->Secure->GetPOST('internebezeichnung'); $input['datum'] = $this->app->Secure->GetPOST('datum'); $input['standardlager'] = $this->app->Secure->GetPOST('standardlager'); $input['standardlager'] = $this->app->erp->ReplaceLagerPlatz(true,$input['standardlager'],true); // Parameters: Target db?, value, from form? $input['reservierart'] = $this->app->Secure->GetPOST('reservierart'); $input['auslagerart'] = $this->app->Secure->GetPOST('auslagerart'); $input['unterlistenexplodieren'] = $this->app->Secure->GetPOST('unterlistenexplodieren'); $input['funktionstest'] = $this->app->Secure->GetPOST('funktionstest'); $input['arbeitsschrittetextanzeigen'] = $this->app->Secure->GetPOST('arbeitsschrittetextanzeigen'); $input['seriennummer_erstellen'] = $this->app->Secure->GetPOST('seriennummer_erstellen'); $input['datumauslieferung'] = $this->app->Secure->GetPOST('datumauslieferung'); $input['datumbereitstellung'] = $this->app->Secure->GetPOST('datumbereitstellung'); $input['datumproduktion'] = $this->app->Secure->GetPOST('datumproduktion'); $input['datumproduktionende'] = $this->app->Secure->GetPOST('datumproduktionende'); $input['freitext'] = $this->app->Secure->GetPOST('freitext'); $input['internebemerkung'] = $this->app->Secure->GetPOST('internebemerkung'); return $input; } // Check stock situation and reservation // Return possible production quantity for all stock or just the reserved function LagerCheckProduktion(int $produktion_id, int $lager, bool $only_reservations) : int { $menge_moeglich = PHP_INT_MAX; $sql = "SELECT pp.id, artikel, SUM(menge) as menge, geliefert_menge FROM produktion_position pp INNER JOIN artikel a ON pp.artikel = a.id WHERE pp.produktion=$produktion_id AND pp.stuecklistestufe=0 AND a.lagerartikel != 0 GROUP BY artikel"; $materialbedarf_gesamt = $this->app->DB->SelectArr($sql); $sql = "SELECT id, artikel, SUM(menge) as menge, geliefert_menge as geliefert_menge FROM produktion_position pp WHERE produktion=$produktion_id AND stuecklistestufe=1 GROUP BY artikel"; $result = $this->app->DB->SelectArr($sql)[0]; $menge_plan_gesamt = $result['menge']; if ($menge_plan_gesamt == 0) { return(0); } $sql = "SELECT SUM(mengeerfolgreich) as menge FROM produktion WHERE id=$produktion_id"; $result = $this->app->DB->SelectArr($sql)[0]; $menge_geliefert_gesamt = $result['menge']; foreach ($materialbedarf_gesamt as $materialbedarf_artikel) { $artikel = $materialbedarf_artikel['artikel']; $position = $materialbedarf_artikel['id']; $menge_plan_artikel = $materialbedarf_artikel['menge']; $menge_geliefert = $materialbedarf_artikel['menge_geliefert']; $sql = "SELECT SUM(menge) as menge FROM lager_reserviert r WHERE lager_platz=$lager AND artikel = $artikel AND r.objekt = 'produktion' AND r.parameter = $produktion_id"; $menge_reserviert_diese = $this->app->DB->SelectArr($sql)[0]['menge']; if ($only_reservations) { $menge_verfuegbar = $menge_reserviert_diese; } else { $sql = "SELECT SUM(menge) as menge FROM lager_platz_inhalt WHERE lager_platz=$lager AND artikel = $artikel"; $menge_lager = $this->app->DB->SelectArr($sql)[0]['menge']; $sql = "SELECT SUM(menge) as menge FROM lager_reserviert r WHERE lager_platz=$lager AND artikel = $artikel"; $menge_reserviert_lager = $this->app->DB->SelectArr($sql)[0]['menge']; $sql = "SELECT SUM(menge) as menge FROM lager_reserviert r WHERE artikel = $artikel"; $menge_reserviert_gesamt = $this->app->DB->SelectArr($sql)[0]['menge']; $menge_verfuegbar = $menge_lager-$menge_reserviert_lager+$menge_reserviert_diese; } $menge_moeglich_artikel = round($menge_verfuegbar / ($menge_plan_artikel/$menge_plan_gesamt), 0, PHP_ROUND_HALF_DOWN); if ($menge_moeglich_artikel < $menge_moeglich) { $menge_moeglich = $menge_moeglich_artikel; } // echo("------------------------Lager $lager a $artikel menge_plan_artikel $menge_plan_artikel menge_geliefert $menge_geliefert menge_lager $menge_lager menge_reserviert_diese $menge_reserviert_diese menge_reserviert_gesamt $menge_reserviert_gesamt menge_verfuegbar $menge_verfuegbar menge_moeglich_artikel $menge_moeglich_artikel menge_moeglich $menge_moeglich
"); } if ($menge_moeglich < 0) { $menge_moeglich = 0; } return($menge_moeglich); } // Modify or add reservation // If quantity is negative, the existing reservation will be reduced // If current quantity is higher as menge_reservieren_limit, current quantity will be reduced // Returns amount that is reserved function ArtikelReservieren(int $artikel, $lager, int $menge_reservieren, int $menge_reservieren_limit, string $objekt, int $objekt_id, int $position_id, string $text) : int { if($lager <= 0 || $artikel <= 0 || $position_id <= 0) { return 0; } $sql = "SELECT menge FROM lager_reserviert WHERE objekt='$objekt' AND parameter = $objekt_id AND artikel = $artikel AND lager_platz = $lager AND posid = $position_id"; $menge_reserviert_diese = $this->app->DB->SelectArr($sql)[0]['menge']; if ($menge_reserviert_diese == null) { $menge_reserviert_diese = 0; } $sql = "SELECT menge FROM lager_reserviert WHERE artikel = $artikel AND lager_platz = $lager"; $menge_reserviert_lager_platz = $this->app->DB->SelectArr($sql)[0]['menge']; if ($menge_reserviert_lager_platz == null) { $menge_reserviert_lager_platz = 0; } $sql = "SELECT menge FROM lager_platz_inhalt WHERE artikel = $artikel AND lager_platz = $lager"; $menge_lager = $this->app->DB->SelectArr($sql)[0]['menge']; if ($menge_lager == null) { $menge_lager = 0; } if ($menge_reservieren < 0) { // Relative reduction $menge_reservieren = $menge_reserviert_diese+$menge_reservieren; if ($menge_reservieren < 0) { $menge_reservieren = 0; } } if (($menge_reservieren == 0) && ($menge_reservieren_limit <= 0)) { $sql = "DELETE FROM lager_reserviert WHERE objekt = '$objekt' AND parameter = $objekt_id AND artikel = $artikel AND posid = $position_id"; $this->app->DB->Update($sql); return(0); } $menge_lager_reservierbar = $menge_lager - $menge_reserviert_lager_platz + $menge_reserviert_diese; if ($menge_reservieren_limit > 0) { if ($menge_reserviert_diese > $menge_reservieren_limit) { $menge_reservieren = $menge_reservieren_limit; } else { // Nothing to do return($menge_reserviert_diese); } } if ($menge_lager_reservierbar > 0) { if ($menge_reserviert_diese > 0) { // Modify given entry if ($menge_reservieren > $menge_lager_reservierbar) { $menge_reservieren = $menge_lager_reservierbar; // Take all that is there } $sql = "UPDATE lager_reserviert SET menge = $menge_reservieren WHERE objekt = '$objekt' AND parameter = $objekt_id AND artikel = $artikel AND posid = $position_id"; $this->app->DB->Update($sql); } else { // Create new entry if ($menge_reservieren > $menge_lager_reservierbar) { $menge_reservieren = $menge_lager_reservierbar; // Take all that is there } $sql = "INSERT INTO lager_reserviert (menge,objekt,parameter,artikel,posid,lager_platz,grund) VALUES (". $menge_reservieren.",". "'$objekt',". $objekt_id.",". $artikel.",". $position_id.",". $lager.",". "'$text'". ")"; $this->app->DB->Update($sql); } } else { $menge_reservieren = 0; } return ($menge_reservieren); } /* Adjust the planned quantity of a produktion Lower limit is the already produced quantity Return -1 if not possible, else 1 */ function MengeAnpassen(int $produktion_id, int $menge_neu, int $lager) : int { $fortschritt = $this->MengeFortschritt($produktion_id,$lager); $sql = "SELECT menge,geliefert_menge FROM produktion_position WHERE produktion = $produktion_id AND stuecklistestufe = 1"; $produktionsmengen_alt = $this->app->DB->SelectArr($sql)[0]; if (empty($produktionsmengen_alt)) { return(-1); } if ($menge_neu < $produktionsmengen_alt['geliefert_menge']) { return(-1); } $sql = "SELECT * from produktion WHERE id = $produktion_id"; $produktion_alt = $this->app->DB->SelectArr($sql)[0]; // Process positions $sql = "SELECT * FROM produktion_position WHERE produktion = $produktion_id"; $positionen = $this->app->DB->SelectArr($sql); foreach ($positionen as $position) { $menge_pro_stueck = $position['menge']/$produktionsmengen_alt['menge']; $position_menge_neu = $menge_neu*$menge_pro_stueck; $sql = "UPDATE produktion_position SET menge=".$position_menge_neu." WHERE id =".$position['id']; $this->app->DB->Update($sql); // Free surplus reservations $restreservierung = $menge_pro_stueck * ($menge_neu+$fortschritt['ausschuss']-$fortschritt['produziert']); $result = $this->ArtikelReservieren($position['artikel'],$lager,0,$restreservierung,'produktion',$produktion_id,$position['id'],"Produktion ".$produktion_alt['belegnr']); } return(1); } /* Output progress information ['geplant'] ['produziert'] ['erfolgreich'] ['ausschuss'] ['offen'] ['reserviert'] ['produzierbar'] If lager <= 0 -> use lager from database */ function MengeFortschritt(int $produktion_id, int $lager) : array { $result = array(); if ($lager <= 0) { $sql = "SELECT standardlager FROM produktion WHERE id = $produktion_id"; $lager = $this->app->DB->SelectArr($sql)[0]['standardlager']; } $sql = "SELECT menge as geplant, geliefert_menge as produziert FROM produktion_position WHERE produktion = $produktion_id AND stuecklistestufe = 1"; $position_values = $this->app->DB->SelectArr($sql)[0]; if (empty($position_values)) { return($result); } $sql = "SELECT mengeerfolgreich as erfolgreich, mengeausschuss as ausschuss FROM produktion WHERE id = $produktion_id"; $produktion_values = $this->app->DB->SelectArr($sql)[0]; if (empty($produktion_values)) { return($result); } $result['geplant'] = $position_values['geplant']; $result['produziert'] = $position_values['produziert']; $result['erfolgreich'] = $produktion_values['erfolgreich']; $result['ausschuss'] = $produktion_values['ausschuss']; $result['offen'] = $result['geplant']-$result['erfolgreich']; if (empty($lager)) { $result['reserviert'] = 0; $result['produzierbar'] = 0; } else { $result['reserviert'] = $this->LagerCheckProduktion($produktion_id, $lager, true); $result['produzierbar'] = $this->LagerCheckProduktion($produktion_id, $lager, false); } return($result); } // Do calculations for the status icon display // id = 0 for all open ones function StatusBerechnen(int $produktion_id) { $where = "WHERE status IN ('freigegeben','gestartet') "; if ($produktion_id > 0) { $where .= "AND id = $produktion_id"; } $sql = "SELECT id, lager_ok, reserviert_ok, auslagern_ok, einlagern_ok, zeit_ok, versand_ok FROM produktion ".$where; $produktionen = $this->app->DB->SelectArr($sql); foreach ($produktionen as $produktion) { $produktion_id = $produktion['id']; $fortschritt = $this->MengeFortschritt($produktion_id,-1); if (empty($fortschritt)) { continue; } // lager_ok if ($fortschritt['produzierbar'] >= $fortschritt['offen']) { $values['lager_ok'] = 1; // } else if ($fortschritt['produzierbar'] > 0) { // $values['lager_ok'] = 2; } else { $values['lager_ok'] = 0; } // reserviert_ok if ($fortschritt['reserviert'] >= $fortschritt['offen']) { $values['reserviert_ok'] = 1; // } else if ($fortschritt['reserviert'] > 0) { // $values['reserviert_ok'] = 2; } else { $values['reserviert_ok'] = 0; } // auslagern_ok if ($fortschritt['produziert'] >= $fortschritt['geplant']) { $values['auslagern_ok'] = 1; // } else if ($fortschritt['produziert'] > 0) { // $values['auslagern_ok'] = 2; } else { $values['auslagern_ok'] = 0; } // einlagern_ok if ($fortschritt['erfolgreich'] >= $fortschritt['geplant']) { $values['einlagern_ok'] = 1; // } else if ($fortschritt['erfolgreich'] > 0) { // $values['einlagern_ok'] = 2; } else { $values['einlagern_ok'] = 0; } // reserviert_ok if ($fortschritt['produziert'] >= $fortschritt['geplant']) { $values['auslagern_ok'] = 1; // } else if ($fortschritt['produziert'] > 0) { // $values['auslagern_ok'] = 2; } else { $values['auslagern_ok'] = 0; } $fix = ""; $update = ""; foreach ($values as $key => $value) { $update = $update.$fix.$key." = '".($value)."'"; $fix = ", "; } $sql = "UPDATE produktion SET $update WHERE id = $produktion_id"; $this->app->DB->Update($sql); } } // Copy an existing produktion as draft, with option to adjust the quantity // return id on sucess, else negative number function Copy($produktion_id, $menge_abteilen) : int { if (empty($produktion_id)) { return(-1); } $fortschritt = $this->MengeFortschritt($produktion_id,0); if (empty($fortschritt)) { return(-2); } if ($menge_abteilen < 1) { $menge_abteilen = $fortschritt['geplant']; } $sql = "SELECT * from produktion WHERE id = $produktion_id"; $produktion_alt = $this->app->DB->SelectArr($sql)[0]; if (empty($produktion_alt)) { return (-3); } $menge_pro_stueck = $menge_abteilen/$fortschritt['geplant']; $produktion_neu = array(); $produktion_neu['status'] = 'angelegt'; $produktion_neu['datum'] = date("Y-m-d"); $produktion_neu['art'] = $produktion_alt['art']; $produktion_neu['projekt'] = $produktion_alt['projekt']; $produktion_neu['angebot'] = $produktion_alt['angebot']; $produktion_neu['kundennummer'] = $produktion_alt['kundennummer']; $produktion_neu['auftragid'] = $produktion_alt['auftragid']; $produktion_neu['freitext'] = $produktion_alt['freitext']; $produktion_neu['internebemerkung'] = $produktion_alt['internebemerkung']; $produktion_neu['adresse'] = $produktion_alt['adresse']; if ($produktion_alt['belegnr'] != '') { $produktion_neu['internebezeichnung '] = "Kopie von ".$produktion_alt['belegnr']." ".$produktion_alt['internebezeichnung']; } else { $produktion_neu['internebezeichnung '] = $produktion_alt['internebezeichnung']; } $produktion_neu['standardlager'] = $produktion_alt['standardlager']; $columns = ""; $values = ""; $update = ""; $fix = ""; foreach ($produktion_neu as $key => $value) { $columns = $columns.$fix.$key; $values = $values.$fix."'".$value."'"; $update = $update.$fix.$key." = '$value'"; $fix = ", "; } $sql = "INSERT INTO produktion (".$columns.") VALUES (".$values.")"; $this->app->DB->Update($sql); $produktion_neu_id = $this->app->DB->GetInsertID(); // Now add the positions $sql = "SELECT * FROM produktion_position WHERE produktion = $produktion_id"; $positionen = $this->app->DB->SelectArr($sql); foreach ($positionen as $position) { $columns = ""; // For the new positions $position['id'] = 'NULL'; $position['geliefert_menge'] = 0; $position['menge'] = $menge_abteilen*$menge_pro_stueck; $position['produktion'] = $produktion_neu_id; $values = ""; $fix = ""; foreach ($position as $key => $value) { $columns = $columns.$fix.$key; $values = $values.$fix."'".$value."'"; $fix = ", "; } $sql = "INSERT INTO produktion_position (".$columns.") VALUES (".$values.")"; $this->app->DB->Update($sql); } return($produktion_neu_id); } /* Write something into the log */ function ProtokollSchreiben(int $produktion_id, string $text) { $sql = "INSERT INTO produktion_protokoll (produktion, zeit, bearbeiter, grund) VALUES ($produktion_id, NOW(), '".$this->app->DB->real_escape_string($this->app->User->GetName())."','".$this->app->DB->real_escape_string($text)."')"; $this->app->DB->Insert($sql); } function ProtokollTabelleErzeugen($produktion_id, $parsetarget) { $tmp = new EasyTable($this->app); $tmp->Query("SELECT zeit,bearbeiter,grund FROM produktion_protokoll WHERE produktion='$produktion_id' ORDER by zeit DESC"); $tmp->DisplayNew($parsetarget,'Protokoll','noAction'); } }