Browse Source

New branch Dimatec

Giancarlo Voci 8 years ago
parent
commit
04867b9b2b

+ 3 - 3
config.ini

@@ -6,7 +6,7 @@ DEBUG=3
 ENCODING="UTF-8"
 HIGHLIGHT=false
 JAR.expire={{time()+31536000}}
-DBSETTINGS="mysql:host=localhost;port=3306;dbname=omlink_lamborghini"
+DBSETTINGS="mysql:host=localhost;port=3306;dbname=omlink"
 dbuser=root
 dbpass=giancarlo
 BASEURL=/lamborghini
@@ -22,8 +22,8 @@ CUSTOMERNAME=dimatec
 host=192.168.1.140
 ;host=127.0.0.1
 port=50443
-key=C0000000000011511187894
-pass=X8sCUiGBEbWTRWCUW72n95tRT7wYriac
+key=C0000000000011474023057
+pass=ZrgzkvJrOKnNSCnPnGz3u{A6eHSNXVvs
 
 [users]
 PASSWORD[0]=$2y$10$CrEtXO9ZMSZgGWTUcBFbB.TyDH0f2KfW6HuXvmrDNkc9FAdn2EEHy

+ 2 - 2
dbschema.sql

@@ -7,9 +7,9 @@ SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
 
 SET NAMES utf8mb4;
 
-DROP DATABASE IF EXISTS `omlink_lamborghini`;
+DROP DATABASE IF EXISTS `omlink`;
 CREATE DATABASE `omlink_lamborghini` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
-USE `omlink_lamborghini`;
+USE `omlink`;
 
 DROP TABLE IF EXISTS `articles`;
 CREATE TABLE `articles` (

+ 1 - 2
labels.ini

@@ -1,6 +1,5 @@
 [LABELS.TEMPLATES]
-DT31=1004,1026
-DT79=tplxslt,0
+DT31=dimatec2_2
 
 [BARCODE_COMMANDS]
 ANOMALIACODE=5

+ 19 - 99
omlinkimporter.php

@@ -5,109 +5,29 @@
  * @time 09:48
  */
 
-const DISTINTA_COLONNE = 20;
-const ARTICLES_COLONNE = 15;
+// Init Framework
+require_once 'lib/f3/base.php';
+$f3 = \Base::instance();
 
-class CSVImporter
-{
-  private $currentFileName;
-  private $folderToWatch;
-  private $dbMysql;
+\F3::set('ONERROR', function ($f3) {
+  print_r($f3->get('ERROR'));
+});
 
-  public function __construct($folderPath, $databaseName, $dbusername, $dbpassword)
-  {
-    $this->currentFileName = '';
-    $this->folderToWatch = $folderPath;
-    $this->dbMysql = new mysqli('localhost', $dbusername, $dbpassword, $databaseName);
-    if ($this->dbMysql->connect_error) {
-      die('Database connection error (' . $this->dbMysql->connect_errno . ') ' . $this->dbMysql->connect_error);
-    }
-  }
+require_once "src\OpenMind\System\OMUtils.php";
 
-  public function ScanAndStoreData()
-  {
-    foreach (glob("{$this->folderToWatch}/*.csv") as $fname) {
-      if (is_file($fname)) {
-        $allData = $this->loadCSV($fname);
+$frameworkUtils = new \OpenMind\System\OMUtils();
+$frameworkUtils->DieByOldPhpVersion();
+$frameworkUtils->LoadEncryptedConfig('config.bin');
 
-        // Esce se il file non è una distinta, lo riconosce solamente dal numero di colonne del file CSV
-        if ($allData == NULL)
-          return;
+$System = new \OpenMind\System\System();
 
-        switch (count($allData[0])) {
-          case DISTINTA_COLONNE:
-            $this->importOnDatabase($fname, $allData);
-            break;
-          case ARTICLES_COLONNE:
-            $this->mysqlLoadCSV(addslashes(realpath($fname)), 'articles');
-            break;
-          default:
-            echo "Numero di colonne non riconosciute ne come DISTINTA e ne come LISTA ARTICOLI per il file '{$fname}'";
-        }
-      }
-    }
-  }
+try {
+  echo PHP_EOL . 'Scanning import folder for new CSV to import...' . PHP_EOL . PHP_EOL;
 
-  private function loadCSV(string $path): ?array
-  {
-    $fh = fopen($path, "r");
-    $csvData = [];
-    while (($d = fgetcsv($fh, 0, ';'))) {
-      if ($d)
-        $csvData[] = $d;
-    }
-    fclose($fh);
-    return $csvData;
-  }
+  $importer = new \OpenMind\DataManager\CSVImporter('import');
+  $importer->ScanAndStoreData();
 
-  private function importOnDatabase(string $fileName, array $data)
-  {
-    $this->dbMysql->query("TRUNCATE TABLE `distinte`");
-    foreach ($data as $dataRow) {
-      $descr = $this->dbMysql->escape_string($dataRow[10]);
-      $sql = <<<EOL
-INSERT INTO distinte (
-origine, consegna, commessa, ordine_produzione, data_creazione, time_creazione, destinazione_merci, barcode, descrizione, qta_prelevare, qta_mancante
-) VALUES (
-'$dataRow[16]', '$dataRow[0]', '$dataRow[2]', '$dataRow[3]', str_to_date('$dataRow[6]','%d/%m/%Y'), '$dataRow[7]', '$dataRow[15]','$dataRow[9]',
-'$descr', '$dataRow[11]', 0
-);
-EOL;
-      if (!$this->dbMysql->query($sql)) {
-        echo "Error on query: {$sql}" . PHP_EOL;
-        echo $this->dbMysql->error . PHP_EOL;
-        return;
-      }
-    }
-    echo "{$fileName} successfully imported" . PHP_EOL;
-    $this->markFileAsDone($fileName);
-  }
-
-  private function markFileAsDone(string $csvPath)
-  {
-    rename($csvPath, "{$csvPath}_imported");
-  }
-
-  private function mysqlLoadCSV(string $CSVPath, string $tableName)
-  {
-    $this->dbMysql->query("TRUNCATE TABLE `{$tableName}`");
-    $sql = <<<EOF
-LOAD DATA INFILE '$CSVPath' INTO TABLE `$tableName`
-FIELDS TERMINATED BY ';' ENCLOSED BY '' LINES TERMINATED BY '\\n';
-EOF;
-    if (!$this->dbMysql->query($sql)) {
-      echo "Error on query: {$sql}" . PHP_EOL;
-      echo $this->dbMysql->error . PHP_EOL;
-      return;
-    }
-    echo "{$CSVPath} successfully imported" . PHP_EOL;
-    $this->markFileAsDone($CSVPath);
-  }
-}
-
-echo PHP_EOL . 'Scanning import folder for new CSV to import...' . PHP_EOL . PHP_EOL;
-
-$impoter = new CSVImporter('import', 'omlink_lamborghini', 'root', 'giancarlo');
-$impoter->ScanAndStoreData();
-
-echo PHP_EOL . '... end import' . PHP_EOL;
+  echo PHP_EOL . '... end import' . PHP_EOL;
+} catch (Exception $e) {
+  print_r($e);
+}

+ 3 - 6
src/Modules/Dimatec/Dimatec.php

@@ -22,16 +22,13 @@ class Dimatec extends PluginStrategy
     // Definisco il namespace del gestore delle pagine
     define('KITTING_SYSTEM', 'Modules\KittingDynamic');
 
-    $this->AddRoute('GET /import', __NAMESPACE__ . '\Dimatec->import');
-    $this->AddRoute('GET|POST /pick2light/@step', KITTING_SYSTEM . '\Pages->Pick2Light');
-    $this->AddRoute('GET /elencodistinta', KITTING_SYSTEM . '\Pages->ElencoDistinta');
+    $this->AddRoute('GET|POST /pick2light/@step', __NAMESPACE__ . '\Pages->Pick2Light');
+    $this->AddRoute("GET|POST /bind", __NAMESPACE__ . '\Pages->Bind');
 
     $imgClass = 'shadow p-3 rounded bg-white';
 
-    $this->AddMenuItem('as400import', ['url' => 'import', 'imgClass' => $imgClass, 'image' => 'ui/images/import.png']);
+    $this->AddMenuItem('bind', ['url' => 'bind', 'imgClass' => $imgClass, 'image' => 'ui/images/bind.png']);
     $this->AddMenuItem('pick2light', ['url' => 'pick2light/1', 'imgClass' => $imgClass, 'image' => 'ui/images/magazzinoverticale.png']);
-    $this->AddMenuItem('elencodistinta', ['url' => 'elencodistinta', 'imgClass' => $imgClass, 'image' => 'ui/images/kittingdynamic.png']);
-    $this->AddMenuItem('staging', ['url' => '/', 'imgClass' => $imgClass, 'image' => 'ui/images/staging.png']);
   }
 }
 

+ 132 - 0
src/Modules/Dimatec/Distinta.php

@@ -0,0 +1,132 @@
+<?php
+/**
+ * @author Open Mind
+ * @date 13/04/2018
+ * @time 11:43
+ */
+
+namespace Modules\Dimatec;
+
+class Distinta
+{
+  protected $dbHandle;
+  protected $userId;
+
+  public function __construct()
+  {
+    $this->dbHandle = \F3::get('DB');
+    $this->userId = \F3::get('USERID');
+  }
+
+  public function setCommessaEnd(string $commessa) {
+    $this->dbMysql->exec("UPDATE `distinte` SET deleted=1 WHERE commessa='{$commessa}' AND idUtente={$this->userId} AND deleted=0");
+  }
+
+  /**
+   * Clean table distinta_esplosa for current user
+   */
+  public function CleanDistintaTable()
+  {
+    $this->dbHandle->exec('UPDATE `distinte` SET deleted=1 WHERE idutente=' . $this->userId);
+  }
+
+  public function getListeToBind()
+  {
+    return $this->dbHandle->exec("SELECT DISTINCT commessa FROM `distinte` WHERE deleted=0 and idutente={$this->userId} AND commessa NOT IN (SELECT barcode FROM label_bindings) ORDER BY commessa");
+  }
+
+  /**
+   * @param string $maxArticles the LIMIT mysql query parameter
+   * @param bool $blink true if need to blink
+   * @param int $iterations
+   */
+  public function SaveProductsToFindBox(string $maxArticles, bool $blink, int $iterations = 20)
+  {
+    $CORE_SETTINGS = \F3::get('CORE.fb');
+    $findBoxCore = new FindBoxCoreSystem(...array_values($CORE_SETTINGS));
+
+    $datiDistinta = $this->getDistinta($maxArticles);
+    foreach($datiDistinta as $row) {
+
+      $labelId = $this->GetLabelIdFromBarcode($row['barcode']);
+      if ($labelId != null) {
+
+        $datiBind = new \DB\SQL\Mapper($this->dbHandle, 'label_bindings');
+        $datiBind->load("label_id='{$labelId}'");
+
+        if (!$datiBind->dry()) {
+          $oldHash = md5(join('', [$datiBind->barcode, $datiBind->descrizione, $datiBind->barcode, $datiBind->qta_prelevare]));
+          $newHash = md5(join('', [$row['barcode'], $row['descrizione'], $row['barcode'], $row['qta_prelevare']]));
+          if ($oldHash <> $newHash) {
+            $dataFields = array(
+              'qr_code' => $row['barcode'],
+              'qta_prelevare' => $row['qta_prelevare']
+            );
+            $findBoxCore->SaveProducts($row['barcode'], $row['descrizione'], $dataFields);
+            $datiBind->copyfrom([
+              'barcode' => $row['barcode'],
+              'descrizione' => $row['descrizione'],
+              'qr_code' => $row['barcode'],
+              'qta_prelevare' => $row['qta_prelevare']
+            ]);
+            $datiBind->update();
+
+          }
+        }
+
+        if ($blink) {
+          $label = new SmartESL($findBoxCore, [$labelId]);
+          $label->BlinkSpecial(2, 1, 1000, $iterations, 0);
+        }
+      }
+    }
+  }
+
+  public function getDistinta(string $maxRows = '3')
+  {
+    return $this->dbHandle->exec("SELECT * FROM distinta_esplosa WHERE idutente={$this->userId} AND qta_prelevare>0 and anomalie=0 ORDER BY sequenza LIMIT {$maxRows}");
+  }
+
+  public function GetLabelIdFromBarcode(string $barcode): ?string
+  {
+    $label = $this->dbHandle->exec("SELECT label_id FROM `label_bindings` WHERE barcode='{$barcode}'");
+    if (count($label) > 0)
+      return $label[0]['label_id'];
+    return null;
+  }
+
+  public function MarkBarcodeAsAnomalia(string $barcode)
+  {
+    $CORE_SETTINGS = \F3::get('CORE.fb');
+    $findBoxCore = new FindBoxCoreSystem(...array_values($CORE_SETTINGS));
+    $lblId = $this->GetLabelIdFromBarcode($barcode);
+    $label = new SmartESL($findBoxCore, [$lblId]);
+    $label->BlinkSpecial(3, 1, 1000, 10);
+
+    $sql = "UPDATE distinta_esplosa d JOIN label_bindings b ON d.barcode = b.barcode SET anomalie=1 WHERE idutente={$this->userId} AND b.barcode='{$barcode}'";
+    return $this->dbHandle->exec($sql);
+  }
+
+  public function RemoveQuantity(string $labelId)
+  {
+    $sql = "UPDATE distinta_esplosa d JOIN label_bindings b ON d.barcode = b.barcode SET d.qta_prelevare=d.qta_prelevare-1 WHERE idutente={$this->userId} AND b.barcode='{$labelId}' AND d.qta_prelevare>0";
+    $ret = $this->dbHandle->exec($sql);
+    return $ret;
+  }
+
+  public function GetArticleCount(string $barcode): int
+  {
+    $sql = "SELECT d.qta_prelevare from distinta_esplosa d JOIN label_bindings b ON d.barcode = b.barcode WHERE idutente={$this->userId} AND b.barcode='{$barcode}'";
+    $record = $this->dbHandle->exec($sql);
+    return $record[0]['qta_prelevare'];
+  }
+
+  public function GetBarcodeFromLabelId(string $labelId): ?string
+  {
+    $binding = $this->dbHandle->exec("SELECT barcode FROM `label_bindings` WHERE label_id='{$labelId}'");
+    if (count($binding) > 0)
+      return $binding[0]['barcode'];
+    return null;
+  }
+
+}

+ 201 - 0
src/Modules/Dimatec/Pages.php

@@ -0,0 +1,201 @@
+<?php
+/**
+ * @author Open Mind
+ * @date 10/04/2018
+ * @time 09:43
+ */
+
+namespace Modules\Dimatec;
+
+use OpenMind\FindBox\FindBoxCoreSystem;
+use OpenMind\FindBox\SmartESL;
+
+class Pages extends \OpenMind\Web\Controller
+{
+  private $CORE_SETTINGS;
+  private $findBoxCore;
+
+  public function __construct($f3)
+  {
+    parent::__construct($f3);
+    $this->CORE_SETTINGS = $f3->get('CORE.fb');
+    $this->findBoxCore = new FindBoxCoreSystem(...array_values($this->CORE_SETTINGS));
+  }
+
+  public function Pick2Light(object $f3, array $args)
+  {
+    $stepValues = [];
+    if ($args['step'] == 1) {
+      $f3->clear('COOKIE.p2l');
+      $f3->clear('COOKIE.consegna');
+      $f3->clear('COOKIE.labelid');
+    } else {
+      $stepValues = array_map('strtoupper', $this->getSanitizedPostRequest());
+      if (count($stepValues) == 0)
+        $stepValues = json_decode($f3->get('COOKIE.p2l'), true);
+    }
+
+    $distinta = new Distinta();
+
+    switch ($args['step']) {
+      case 3:
+        $distinta->CleanDistintaTable();
+        $distinta->CopyDistinta($stepValues['consegna']);
+
+        $label = new SmartESL($this->findBoxCore, [$stepValues['labelid']]);
+        $label->BlinkSpecial(0, 1, 1000, 8, 0);
+
+        $distinta->SaveProductsToFindBox('3', true, 50); // prende soltanto i primi 3 dalla tabella copia delle distinte
+
+        $f3->set('COOKIE.p2l', json_encode($stepValues));
+        $f3->set('COOKIE.consegna', $stepValues['consegna']);
+        $f3->set('COOKIE.labelid', $stepValues['labelid']);
+        $f3->reroute("/pick2light/4");
+        return;
+        break;
+      case 4:
+        $distinta->SaveProductsToFindBox('3, 2000', false); // LIMIT 3,1000 perchè i primi 3 sono stati fatti nel case 3
+        break;
+      case 5:
+        $datiCommessa['consegna'] = $f3->get('COOKIE.consegna');
+        $datiCommessa['labelid'] = $f3->get('COOKIE.labelid');
+        $pickedBarcode = $f3->get('POST.pickedlabelid');
+        // Decrease quantity and blink label
+        if ($pickedBarcode != null) {
+          // ANOMALIA
+          if ($pickedBarcode == $f3->get('BARCODE_COMMANDS.ANOMALIACODE')) {
+            // <Se è stato ancora passato un codice anomalia, cancella l'operazione di anomalia in corso
+            if (isset($stepValues['anomalia']))
+              unset($stepValues['anomalia']);
+            else
+              $f3->set('ANOMALIA', 'In attesa del codice anomalia');
+            //>
+          } else if ($stepValues['anomalia']) {
+            if ($distinta->MarkBarcodeAsAnomalia($pickedBarcode))
+              unset($stepValues['anomalia']);
+            else
+              $f3->set('ANOMALIA', 'Codice non trovato!');
+          } else { // E' stato passato un codice
+            $codeFromLabelId = $distinta->GetBarcodeFromLabelId($pickedBarcode);
+            $pickedBarcode = $codeFromLabelId ?? $pickedBarcode;
+            if ($distinta->RemoveQuantity($pickedBarcode)) {
+              // SPEGNE LED ETICHETTA DOPO PICKING
+              $label = new SmartESL($this->findBoxCore, [$distinta->GetLabelIdFromBarcode($pickedBarcode)]);
+              $label->BlinkOff();
+            } else {
+              $f3->set('INFOTEXT', 'Barcode non riconosciuto o non associato ad alcuna etichetta elettronica');
+              file_put_contents('not_found.log', $pickedBarcode . "\r\n", FILE_APPEND);
+            }
+          }
+        }
+
+        $rowsDistinta = $distinta->getDistinta();
+        $f3->set('PRODUCTS', $rowsDistinta);
+        // End Picking List
+        if (count($rowsDistinta) == 0) {
+          //$distinta->ResetDistintaLabels($datiCommessa['consegna'], $datiCommessa['labelid']);
+          $anomalie = $distinta->getAnomalieFromConsegne($datiCommessa['consegna']);
+          $f3->set('LISTANOMALIE', $anomalie);
+
+          //$label = new SmartESL($this->findBoxCore, [$datiCommessa['labelid']]);
+          $distinta->SaveLabelCarrello($datiCommessa['labelid'], $datiCommessa['labelid'], $datiCommessa['consegna']);
+
+          // Se non ci sono anomalie torna alla homepage
+          if (count($anomalie) == 0) {
+            $f3->reroute('/');
+            return;
+          }
+        } else {
+          // Seleziona le prossime tre etichette
+          foreach($rowsDistinta as $rowDist) {
+            $labelId = $distinta->GetLabelIdFromBarcode($rowDist['barcode']);
+            if ($labelId != null) {
+              $label = new SmartESL($this->findBoxCore, [$labelId]);
+              // Se è lo stesso barcode di quello appena pickato dall'operatore, non lo blinka di nuovo
+              if ($distinta->GetArticleCount($rowDist['barcode']) > 0) {
+                $label->BlinkSpecial(2, 1, 1000, 20);
+              }
+            }
+          }
+        }
+        break;
+    }
+
+    $f3->set('COOKIE.p2l', json_encode($stepValues));
+
+    $distinte = $distinta->getListeToBind();
+    $f3->set('DISTINTE', $distinte);
+    $f3->set('STEP', $args['step']);
+    $f3->set('PAGEVALUES', $stepValues);
+
+    $f3->set('CONTENT', 'pick2light.tpl');
+    echo \Template::instance()->render('masterpage.tpl');
+  }
+
+  public function Bind($f3)
+  {
+    $params = $this->getSanitizedPostRequest();
+    $distinta = new Distinta();
+
+    if (count($params)) {
+      $bindData = array_map('strtoupper', $this->getSanitizedPostRequest());
+      $err = $this->findBoxCore->Bind($bindData['labelid'], $bindData['labelid']);
+      $label = new SmartESL($this->findBoxCore, [$bindData['labelid']]);
+
+      $labelTemplateId = \F3::get("LABELS.TEMPLATES.DT31");
+
+      $err = $label->Display($labelTemplateId, $bindData['labelid']);
+      // TODO assegnare il template corretto ed i custom field
+      $eslData = array(
+        'Q.ta' => 0,
+        'Commessa' => $bindData['commessa']
+      );
+      $j_eslData = json_encode($eslData);
+      $err = $this->findBoxCore->SaveProducts($bindData['labelid'], '', $eslData);
+
+      $this->dbHandle->exec("DELETE FROM label_bindings WHERE label_id='{$bindData['labelid']}'");
+      $this->dbHandle->exec(
+        "INSERT INTO label_bindings (label_id, barcode, template_id, esl_datafields, descrizione) VALUES " .
+        "('{$bindData['labelid']}', '{$bindData['commessa']}', '{$labelTemplateId}', '{$j_eslData}', '{$bindData['commessa']}')"
+      );
+    }
+
+
+    $liste = $distinta->getListeToBind();
+    $f3->set('ORDINE', $liste[0]['commessa']);
+    $f3->set('LISTE', $liste);
+    $f3->set('CONTENT', 'bind.tpl');
+    echo \Template::instance()->render('masterpage.tpl');
+  }
+
+  /**
+   * @deprecated for now not used
+   * @param $f3
+   * @param array $args
+   */
+  public function UnBind($f3, array $args)
+  {
+    $stepValues = array_map('strtoupper', $this->getSanitizedPostRequest());
+    if ($args['step'] == 2) {
+      $success = $this->findBoxCore->UnBind($stepValues['labelid']);
+      if ($success['err'] <> 0) {
+        $f3->set('INFOTEXT', $success['value']);
+      }
+    }
+    $f3->set('STEP', $args['step']);
+    $f3->set('CONTENT', 'unbind.tpl');
+    echo \Template::instance()->render('masterpage.tpl');
+  }
+
+  /**
+   * @deprecated for now not used
+   * @param $f3
+   */
+  public function ElencoDistinta($f3)
+  {
+    $distinta = new Distinta();
+    $f3->set('PRODUCTS', $distinta->getDistinte());
+    $f3->set('CONTENT', 'distinta.tpl');
+    echo \Template::instance()->render('masterpage.tpl');
+  }
+}

+ 4 - 5
src/Modules/KittingDynamic/Distinta.php

@@ -43,7 +43,7 @@ EOF;
     $dataset = $this->dbHandle->exec($sql);
     $idutente = $this->userId;
 
-    foreach ($dataset as $row) {
+    foreach($dataset as $row) {
       $sqlInsert = "INSERT INTO distinta_esplosa (idutente, commessa, barcode, descrizione, origine, ubicazione, sequenza, qta_prelevare, anomalie)" .
         "VALUES ({$idutente}, '{$row['consegna']}', '{$row['barcode']}', '{$row['descrizione']}', '{$row['origine']}', '{$row['ubicazione']}', '{$row['sequenza']}', '{$row['qta_prelevare']}', 0)";
       $err = $this->dbHandle->exec($sqlInsert);
@@ -63,7 +63,7 @@ EOF;
     $findBoxCore = new FindBoxCoreSystem(...array_values($CORE_SETTINGS));
 
     $datiDistinta = $this->getDistinta($maxArticles);
-    foreach ($datiDistinta as $row) {
+    foreach($datiDistinta as $row) {
 
       $labelId = $this->GetLabelIdFromBarcode($row['barcode']);
       if ($labelId != null) {
@@ -201,7 +201,7 @@ EOF;
 
     $xmlField = '<?xml version="1.0" encoding="UTF-8"?><distinta>';
 
-    foreach ($articles as $i => $articolo) {
+    foreach($articles as $i => $articolo) {
       $xmlField .= "<materiale anomalia=\"{$articolo['anomalie']}\"><barcode>{$articolo['barcode']}</barcode><description>{$articolo['descrizione']}</description><qta_nominale>{$articolo['qta_nominale']}</qta_nominale><qta_prelevare>{$articolo['qta_prelevare']}</qta_prelevare></materiale>";
     }
 
@@ -237,13 +237,12 @@ EOF;
     $CORE_SETTINGS = \F3::get('CORE.fb');
     $findBoxCore = new FindBoxCoreSystem(...array_values($CORE_SETTINGS));
 
-    foreach ($dataset as $row) {
+    foreach($dataset as $row) {
       $dataFields = array(
         'qr_code' => $row['barcode'],
         'qta_prelevare' => ''
       );
 
-      // TODO #NODISPLAY da testare, rimuovere se è ok
       $findBoxCore->SaveProducts($row['barcode'], $row['descrizione'], $dataFields);
     }
   }

+ 183 - 0
src/OpenMind/DataManager/CSVImporter.php

@@ -0,0 +1,183 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Giancarlo
+ * Date: 24/07/2018
+ * Time: 17:36
+ */
+
+namespace OpenMind\DataManager;
+
+class ENUM_DIMATEC_CSV
+{
+  public const MXORDI = 7;
+  public const MXARTI = 10;
+  public const MXDESC = 12;
+  public const MXQTMI = 14;
+  public const MXUBIC = 16;
+}
+
+
+class CSVImporter
+{
+  const LAMBORGHINI_DISTINTA_COLONNE = 20;
+  const LAMBORGHINI_ARTICLES_COLONNE = 15;
+  const DIMATEC_LISTA_MOVIMENTI_AS400 = 32;
+
+  private $folderToWatch;
+  private $dbMysql;
+  private $output;
+  private $user;
+
+  /**
+   * @return mixed
+   */
+  public function getOutput()
+  {
+    return $this->output;
+  }
+
+  public function __construct(string $folderPath)
+  {
+    $this->user = (int)\F3::get('USERID');
+    $this->folderToWatch = $folderPath;
+    $this->dbMysql = \F3::get('DB');
+  }
+
+  /**
+   * Create MySQL temp table for smart operations
+   *
+   * @param string $table
+   * @return string temporary name
+   */
+  private function createTmpTableFrom(string $table)
+  {
+    $tempTableName = 'tmp' . rand(10, 200);
+    $this->dbMysql->exec("CREATE TEMPORARY TABLE IF NOT EXISTS `{$tempTableName}` AS (SELECT * FROM `{$table}`)");
+    return $tempTableName;
+  }
+
+  public function ScanAndStoreData()
+  {
+    foreach(glob("{$this->folderToWatch}/*.csv") as $fname) {
+      if (is_file($fname)) {
+        $allData = $this->loadCSV($fname);
+
+        // Esce se il file non è una distinta, lo riconosce solamente dal numero di colonne del file CSV
+        if ($allData == NULL)
+          return;
+
+        switch (count($allData[0])) {
+          case CSVImporter::LAMBORGHINI_DISTINTA_COLONNE:
+            $this->importOnDatabase($fname, $allData);
+            break;
+          case CSVImporter::LAMBORGHINI_ARTICLES_COLONNE:
+            $this->mysqlLoadCSV(addslashes(realpath($fname)), 'articles');
+            break;
+          case CSVImporter::DIMATEC_LISTA_MOVIMENTI_AS400:
+            //$tmpTableName = $this->createTmpTableFrom('distinte');
+            $this->dynamicImporter($fname, $allData, function ($data) {
+              if ($data[0] == "MXIDDM")
+                return;
+              try {
+                $distinta = new \DB\SQL\Mapper($this->dbMysql, 'distinte');
+                $distinta->idUtente = $this->user;
+                $distinta->commessa = $data[ENUM_DIMATEC_CSV::MXORDI];
+                $distinta->barcode = $data[ENUM_DIMATEC_CSV::MXARTI];
+                $distinta->descrizione = $data[ENUM_DIMATEC_CSV::MXDESC];
+                $distinta->qta_prelevare = $data[ENUM_DIMATEC_CSV::MXQTMI];
+                $distinta->save();
+              } catch (PDOException $e) {
+                $this->output .= $e->getMessage();
+              }
+            });
+            /*            $this->dbMysql->exec(
+                          "INSERT INTO `distinta_esplosa` (commessa, barcode, descrizione, qta_prelevare) " .
+                          "SELECT commessa, barcode, descrizione, SUM(qta_prelevare) as qta_prelevare " .
+                          "FROM `distinte` group by barcode order by commessa"
+                        );*/
+            $this->markFileAsDone($fname);
+            break;
+          default:
+            $this->output .= "Numero di colonne non riconosciute ne come DISTINTA e ne come LISTA ARTICOLI per il file '{$fname}'";
+        }
+      }
+    }
+  }
+
+  private function loadCSV(string $path): ?array
+  {
+    $fh = fopen($path, "r");
+    $csvData = [];
+    while (($d = fgetcsv($fh, 0, ';'))) {
+      if ($d)
+        $csvData[] = $d;
+    }
+    fclose($fh);
+    return $csvData;
+  }
+
+  /**
+   * Iterate on $data and call $func to make operations on rows
+   *
+   * @param string $fileName
+   * @param array $data
+   * @param function(array $dataRow) $func
+   */
+  private function dynamicImporter(string $fileName, array $data, $func)
+  {
+    foreach($data as $dataRow) {
+      $func($dataRow);
+    }
+    $this->output .= "{$fileName} successfully imported<br/>";
+  }
+
+  /**
+   * @deprecated from 24/07/2018
+   * @param string $fileName
+   * @param array $data
+   */
+  private function importOnDatabase(string $fileName, array $data)
+  {
+    $this->dbMysql->query("TRUNCATE TABLE `distinte`");
+    foreach($data as $dataRow) {
+      $descr = $this->dbMysql->escape_string($dataRow[10]);
+      $sql = <<<EOL
+INSERT INTO distinte (
+origine, consegna, commessa, ordine_produzione, data_creazione, time_creazione, destinazione_merci, barcode, descrizione, qta_prelevare, qta_mancante
+) VALUES (
+'$dataRow[16]', '$dataRow[0]', '$dataRow[2]', '$dataRow[3]', str_to_date('$dataRow[6]','%d/%m/%Y'), '$dataRow[7]', '$dataRow[15]','$dataRow[9]',
+'$descr', '$dataRow[11]', 0
+);
+EOL;
+      if (!$this->dbMysql->query($sql)) {
+        echo "Error on query: {$sql}" . PHP_EOL;
+        echo $this->dbMysql->error . PHP_EOL;
+        return;
+      }
+    }
+    echo "{$fileName} successfully imported" . PHP_EOL;
+    $this->markFileAsDone($fileName);
+  }
+
+  private function markFileAsDone(string $csvPath)
+  {
+    rename($csvPath, "{$csvPath}_imported");
+  }
+
+  private function mysqlLoadCSV(string $CSVPath, string $tableName)
+  {
+    $this->dbMysql->query("TRUNCATE TABLE `{$tableName}`");
+    $sql = <<<EOF
+LOAD DATA INFILE '$CSVPath' INTO TABLE `$tableName`
+FIELDS TERMINATED BY ';' ENCLOSED BY '' LINES TERMINATED BY '\\n';
+EOF;
+    if (!$this->dbMysql->query($sql)) {
+      echo "Error on query: {$sql}" . PHP_EOL;
+      echo $this->dbMysql->error . PHP_EOL;
+      return;
+    }
+    echo "{$CSVPath} successfully imported" . PHP_EOL;
+    $this->markFileAsDone($CSVPath);
+  }
+}

+ 17 - 13
src/OpenMind/System/System.php

@@ -15,24 +15,28 @@ class System extends PluginStrategy
 
   public function __construct()
   {
+    // Set Error Handler
+    \F3::set('ONERROR', __NAMESPACE__ . '\ErrorHandlers->Handler');
+
     $this->cache = \Cache::instance();
 
     $this->Logger = new \Log('Site.log');
 
     // Set Database connection
-    \F3::set('DB',
-      new \DB\SQL(
-        \F3::get('DBSETTINGS'),
-        \F3::get('dbuser'),
-        \F3::get('dbpass'),
-        array(
-          \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
-          \PDO::ATTR_PERSISTENT => TRUE
-        ))
-    );
+    try {
+      \F3::set('DB',
+        new \DB\SQL(
+          \F3::get('DBSETTINGS'),
+          \F3::get('dbuser'),
+          \F3::get('dbpass'),
+          array(
+            \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
+            \PDO::ATTR_PERSISTENT => TRUE
+          )));
+    } catch (PDOException $e) {
+      die($e->getMessage());
+    }
 
-    // Set Error Handler
-    \F3::set('ONERROR', __NAMESPACE__ . '\ErrorHandlers->Handler');
   }
 
   /**
@@ -56,5 +60,5 @@ class System extends PluginStrategy
   }
 }
 
-/** @var System $System **/
+/** @var System $System * */
 Global $System;

+ 23 - 5
src/OpenMind/Web/Web.php

@@ -14,16 +14,13 @@ class Web extends PluginStrategy
   public function __construct()
   {
     // Services
+    $this->AddRoute('GET /importdata', __NAMESPACE__ . '\Web->Import');
     $this->AddRoute('GET /homemenu', __NAMESPACE__ . '\Web->HomeMenu');
     $this->AddRoute('GET /', __NAMESPACE__ . '\Login->Login');
     $this->AddRoute("POST /loginform", __NAMESPACE__ . '\Login->LoginForm');
     $this->AddRoute("GET /logout", __NAMESPACE__ . '\Login->Logout');
 
-    /*    $imgClass = 'shadow p-3 rounded bg-white';
-        $this->AddMenuItem('bind', ['url' => 'bind/1', 'imgClass' => $imgClass, 'image' => 'ui/images/bind.png']);
-        $this->AddMenuItem('unbind', ['url' => 'unbind/1', 'imgClass' => $imgClass, 'image' => 'ui/images/unbind.png']);
-        $this->AddMenuItem('pick2light', ['url' => 'pick2light/1', 'imgClass' => $imgClass, 'image' => 'ui/images/pick2light.png']);
-        $this->AddMenuItem('elencodistinta', ['url' => 'elencodistinta', 'imgClass' => $imgClass, 'image' => 'ui/images/list.png']);*/
+    $this->AddMenuItem('genericimport', ['url' => 'importdata', 'imgClass' => 'shadow p-3 rounded bg-white', 'image' => 'ui/images/import.png']);
   }
 
   public function HomeMenu($f3)
@@ -31,6 +28,27 @@ class Web extends PluginStrategy
     $f3->set('CONTENT', 'homemenu.tpl');
     echo \Template::instance()->render('masterpage.tpl');
   }
+
+  public function Import($f3)
+  {
+    $output = '';
+    try {
+      $output .= 'Scanning import folder for new CSV to import...<br/><br/>';
+
+      $importer = new \OpenMind\DataManager\CSVImporter('import');
+      $importer->ScanAndStoreData();
+      $output .= $importer->getOutput();
+
+    } catch (Exception $e) {
+      $output .= $e->getMessage();
+    }
+
+    $output .= '<br/>... end import<br/>';
+
+    $f3->set('IMPORT_RESULT', $output);
+    $f3->set('CONTENT', 'import.tpl');
+    echo \Template::instance()->render('masterpage.tpl');
+  }
 }
 
 /** @var \OpenMind\Web\Web $Web */

+ 25 - 18
ui/bind.tpl

@@ -1,19 +1,26 @@
-<div class="row h-100 justify-content-center">
-    <div class="col-md-5 align-self-center">
-        <form class="form" method="post" action="{{@BASEURL}}/bind/{{@STEP+1}}">
-            <input type="submit" hidden id="submitform"/>
-            <input type="text" name="labelid" class="form-control form-control" placeholder="Label ID" required {{@AUTOFOCUS1}} autocomplete="false" value="{{ @POST.labelid }}"/>
-            <check if="{{ @STEP > 1 }}">
-                <input type="text" name="barcode" class="form-control form-control mt-3" placeholder="Barcode" required {{@AUTOFOCUS2}} autocomplete="false" value="{{ @POST.barcode }}"/>
-            </check>
-        </form>
-        <check if="{{@STEP==3}}">
-            <div class="alert alert-info mt-5" role="alert">
-                Invio bind
-            </div>
-            <script>
-              window.location.href = "{{@BASEURL}}/bind/1";
-            </script>
-        </check>
-    </div>
+<div class="row h-100 justify-content-center w-100">
+	<div class="col-md-5 align-self-center">
+		<div>
+
+			<table class="table table-sm table-striped table-light">
+				<thead class="bg-secondary">
+				<tr>
+					<th class="text-center text-uppercase text-white" scope="col">Binding Elenco Ordini</th>
+				</tr>
+				</thead>
+				<tbody>
+				<repeat group="{{ @LISTE }}" key="{{@key}}" value="{{ @LISTA }}">
+					<tr>
+						<td {{(@key==0)? 'class="blink bg-success text-white font-weight-bold"': ''}}>{{@LISTA.commessa}}</td>
+					</tr>
+				</repeat>
+				</tbody>
+			</table>
+		</div>
+		<form class="form" method="post" action="{{@BASEURL}}/bind">
+			<input type="hidden" value="{{@ORDINE}}" hidden name="commessa"/>
+			<input type="submit" hidden id="submitform"/>
+			<input type="text" name="labelid" class="form-control form-control" placeholder="Etichetta Cesta" required autofocus autocomplete="false" value=""/>
+		</form>
+	</div>
 </div>

+ 50 - 1
ui/css/omlink.css

@@ -13,13 +13,17 @@
  * @date 16/07/2018
  * @time 16:00
  */
+.navbar.fixed-bottom {
+  color: white;
+}
+
 html, body {
   height: 100%;
 }
 
 body {
   background-color: white !important;
-  color: white !important;
+  color: black !important;
   font-family: "Roboto";
 }
 
@@ -109,4 +113,49 @@ input::-ms-input-placeholder {
   border-radius: 15px !important;
 }
 
+@keyframes blink {
+  0% {
+    -webkit-opacity: 0;
+    -moz-opacity: 0;
+    -ms-opacity: 0;
+    -o-opacity: 0;
+    opacity: 0;
+  }
+  100% {
+    -webkit-opacity: 1;
+    -moz-opacity: 1;
+    -ms-opacity: 1;
+    -o-opacity: 1;
+    opacity: 1;
+  }
+}
+@-webkit-keyframes blink {
+  0% {
+    -webkit-opacity: 0;
+    -moz-opacity: 0;
+    -ms-opacity: 0;
+    -o-opacity: 0;
+    opacity: 0;
+  }
+  100% {
+    -webkit-opacity: 1;
+    -moz-opacity: 1;
+    -ms-opacity: 1;
+    -o-opacity: 1;
+    opacity: 1;
+  }
+}
+.blink {
+  -webkit-transition: all 0.1s ease-in-out;
+  -moz-transition: all 0.1s ease-in-out;
+  -ms-transition: all 0.1s ease-in-out;
+  -o-transition: all 0.1s ease-in-out;
+  transition: all 0.1s ease-in-out;
+  -webkit-animation: blink alternate 1s infinite ease-in-out;
+  -moz-animation: blink alternate 1s infinite ease-in-out;
+  -ms-animation: blink alternate 1s infinite ease-in-out;
+  -o-animation: blink alternate 1s infinite ease-in-out;
+  animation: blink alternate 1s infinite ease-in-out;
+}
+
 /*# sourceMappingURL=omlink.css.map */

+ 30 - 0
ui/css/omlink.scss

@@ -125,3 +125,33 @@ input::-ms-input-placeholder {
 .rounded {
   border-radius: 15px !important;
 }
+
+@mixin prefix($property, $parameters...) {
+  @each $prefix in -webkit-, -moz-, -ms-, -o-, "" {
+    #{$prefix}#{$property}: $parameters;
+  }
+}
+
+// Blink Effect
+@keyframes blink {
+  0% {
+    @include prefix(opacity, 0);
+  }
+  100% {
+    @include prefix(opacity, 1);
+  }
+}
+
+@-webkit-keyframes blink {
+  0% {
+    @include prefix(opacity, 0);
+  }
+  100% {
+    @include prefix(opacity, 1);
+  }
+}
+
+.blink {
+  @include prefix(transition, all 0.1s ease-in-out);
+  @include prefix(animation, blink alternate 1s infinite ease-in-out);
+}

+ 5 - 1
ui/customizations/dimatec.scss

@@ -10,7 +10,7 @@
 $mainColor: white !important;
 
 // Main text color
-$textColor: white !important;
+$textColor: black !important;
 
 // Upper and Lower navbar background color
 $navbarsColor: rgba(94, 103, 178, 0.95) !important;
@@ -23,3 +23,7 @@ $inputBgColor: rgb(77, 80, 153);
 $inputColor: white;
 
 $placeholderColor: gray !important;
+
+.navbar.fixed-bottom {
+  color: white;
+}

BIN
ui/images/svg/bind.png


+ 3 - 0
ui/import.tpl

@@ -0,0 +1,3 @@
+<div class="d-flex flex-wrap justify-content-around align-items-center flex-fill">
+	<div class="shadow p-3 rounded bg-info text-light">{{@IMPORT_RESULT | raw}}</div>
+</div>

+ 0 - 8
ui/pick2light.tpl

@@ -3,15 +3,7 @@
     <div class="col-md-5 align-self-center">
       <form class="form" method="post" action="{{@BASEURL}}/pick2light/{{@STEP+1}}">
         <input type="submit" hidden id="submitform"/>
-        <select name="consegna" class="form-control form-control bg-secondary mb-3" onchange="javascript:$('#submitform').click()">
-          <option {{isset(@PAGEVALUES.consegna) ? '' : 'selected'}} >Selezionare una distinta</option>
-          <repeat group="{{ @DISTINTE }}" value="{{ @DISTINTA }}">
-            <option {{@PAGEVALUES.consegna == @@DISTINTA.consegna ? 'selected' : ''}} value="{{@@DISTINTA.consegna}}">{{@@DISTINTA.consegna}} - {{@@DISTINTA.data_creazione}} - {{@@DISTINTA.time_creazione}} - {{@@DISTINTA.destinazione_merci}}</option>
-          </repeat>
-        </select>
-        <check if="{{ @STEP > 1}}">
           <input type="text" name="labelid" {{ @STEP==2 ? 'autofocus' : ''}} value="{{@PAGEVALUES.labelid}}" class="form-control form-control-lg mb-3" placeholder="Codice etichetta" required autocomplete="false"/>
-        </check>
         <check if="{{ isset(@INFOTEXT) }}">
           <div class="alert alert-info mt-3" role="alert">
             {{@INFOTEXT}}