diff --git a/README.md b/README.md index 4ef5727..f146a08 100644 --- a/README.md +++ b/README.md @@ -18,15 +18,30 @@ Installiere Abhängigkeiten Starte MySQL-Server: > docker compose up -Erstelle Datenbank +Erstelle Datenbank (nicht die Tabellen) > bin/console doctrine:database:create > Erstelle Tabellen > bin/console doctrine:migrations:migrate +Erstellen der Tabellen +> bin/console doctrine:migrations:migrate + +Update der Datenbank +> bin/console doctrine:migrations:execute + Starte Server > make dev-server API-Übersicht -> https://127.0.0.1:8000/api \ No newline at end of file +> https://127.0.0.1:8000/api + +Update Symphony +> composer update + +# Benutzen +-------------- + +Hiltes Import +> bin/console hiltes:import \ No newline at end of file diff --git a/migrations/Version20230202141118.php b/migrations/Version20230202141118.php index abce620..eec2051 100644 --- a/migrations/Version20230202141118.php +++ b/migrations/Version20230202141118.php @@ -21,18 +21,18 @@ final class Version20230202141118 extends AbstractMigration { // this up() migration is auto-generated, please modify it to your needs $this->addSql('CREATE TABLE `order` (id INT AUTO_INCREMENT NOT NULL, order_id VARCHAR(255) NOT NULL, status INT NOT NULL, data LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\', PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); - $this->addSql('CREATE TABLE product (id INT AUTO_INCREMENT NOT NULL, stock_id INT DEFAULT NULL, gtin VARCHAR(255) NOT NULL, shopware_id VARCHAR(255) NOT NULL, update_time DATETIME NOT NULL, UNIQUE INDEX UNIQ_D34A04ADDCD6110 (stock_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE product (id INT AUTO_INCREMENT NOT NULL, gtin VARCHAR(255) NOT NULL, shopware_id VARCHAR(255) DEFAULT NULL, modellnr VARCHAR(255) NOT NULL, modellbez VARCHAR(255) NOT NULL, update_time DATETIME NOT NULL,PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); $this->addSql('CREATE TABLE settings (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, value VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); - $this->addSql('CREATE TABLE stock (id INT AUTO_INCREMENT NOT NULL, warehouse_id INT DEFAULT NULL, instock INT NOT NULL, INDEX IDX_4B3656605080ECDE (warehouse_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('CREATE TABLE stock (id INT AUTO_INCREMENT NOT NULL, product_id INT DEFAULT NULL, warehouse_id INT DEFAULT NULL, instock INT NOT NULL, INDEX IDX_4B3656605080ECDE (warehouse_id), INDEX IDX_4B3656605080ECFF (product_id),UNIQUE INDEX UNIQ_D34A04ADDCD6110 (warehouse_id,product_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); $this->addSql('CREATE TABLE warehouse (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, prio INT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); - $this->addSql('ALTER TABLE product ADD CONSTRAINT FK_D34A04ADDCD6110 FOREIGN KEY (stock_id) REFERENCES stock (id)'); +# $this->addSql('ALTER TABLE product ADD CONSTRAINT FK_D34A04ADDCD6110 FOREIGN KEY (stock_id) REFERENCES stock (id)'); $this->addSql('ALTER TABLE stock ADD CONSTRAINT FK_4B3656605080ECDE FOREIGN KEY (warehouse_id) REFERENCES warehouse (id)'); } public function down(Schema $schema): void { // this down() migration is auto-generated, please modify it to your needs - $this->addSql('ALTER TABLE product DROP FOREIGN KEY FK_D34A04ADDCD6110'); +# $this->addSql('ALTER TABLE product DROP FOREIGN KEY FK_D34A04ADDCD6110'); $this->addSql('ALTER TABLE stock DROP FOREIGN KEY FK_4B3656605080ECDE'); $this->addSql('DROP TABLE `order`'); $this->addSql('DROP TABLE product'); diff --git a/migrations/Version20230223121613.php b/migrations/Version20230223121613.php new file mode 100644 index 0000000..761d826 --- /dev/null +++ b/migrations/Version20230223121613.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE stock ADD update_time DATETIME DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE stock DROP update_time'); + } +} diff --git a/src/Command/HiltesImportCommand.php b/src/Command/HiltesImportCommand.php index b9be897..fc453b4 100644 --- a/src/Command/HiltesImportCommand.php +++ b/src/Command/HiltesImportCommand.php @@ -57,7 +57,7 @@ class HiltesImportCommand extends Command /** * @var HiltesImport */ - $hiltesImport = new HiltesImport($this->productRepository,$this->logger); + $hiltesImport = new HiltesImport($this->productRepository,$this->warehouseRepository,$this->stockRepository,$this->logger); $r = $hiltesImport->startImport(); diff --git a/src/Entity/Product.php b/src/Entity/Product.php index c5d0ea0..8203956 100644 --- a/src/Entity/Product.php +++ b/src/Entity/Product.php @@ -21,12 +21,14 @@ class Product #[ORM\Column(length: 255)] private ?string $shopwareId = null; + #[ORM\Column(length: 255)] + private ?string $modellnr = null; + #[ORM\Column(length: 255)] + private ?string $modellbez = null; #[ORM\Column(type: Types::DATETIME_MUTABLE)] private ?\DateTimeInterface $updateTime = null; - #[ORM\OneToOne(inversedBy: 'product', cascade: ['persist', 'remove'])] - private ?Stock $stock = null; public function getId(): ?int { @@ -44,6 +46,28 @@ class Product return $this; } + public function getModellNr(): ?string + { + return $this->modellnr; + } + + public function setModellNr(string $modellnr): self + { + $this->modellnr = $modellnr; + + return $this; + } + public function getModellBez(): ?string + { + return $this->modellbez; + } + + public function setModellBez(string $modellbez): self + { + $this->modellbez = $modellbez; + + return $this; + } public function getShopwareId(): ?string { @@ -69,15 +93,4 @@ class Product return $this; } - public function getStock(): ?Stock - { - return $this->stock; - } - - public function setStock(?Stock $stock): self - { - $this->stock = $stock; - - return $this; - } } diff --git a/src/Entity/Stock.php b/src/Entity/Stock.php index 291a80b..8e09af1 100644 --- a/src/Entity/Stock.php +++ b/src/Entity/Stock.php @@ -3,9 +3,17 @@ namespace App\Entity; use App\Repository\StockRepository; +#use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; + +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: StockRepository::class)] +#[ORM\UniqueEntity(['warehouse_id', 'product_id'])] +#[ORM\UniqueConstraint( + name: 'UNIQ_D34A04ADDCD6110', + columns: ['warehouse_id', 'product_id'] +)] class Stock { #[ORM\Id] @@ -15,17 +23,26 @@ class Stock #[ORM\Column] private ?int $instock = null; - - #[ORM\OneToOne(mappedBy: 'stock', cascade: ['persist', 'remove'])] - private ?Product $product = null; + #[ORM\Column] + private ?int $product_id = null; #[ORM\ManyToOne(inversedBy: 'stocks')] private ?Warehouse $warehouse = null; + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)] + private ?\DateTimeInterface $update_time = null; + + + public function getId(): ?int { return $this->id; } + public function setId(int $id): ?self + { + $this->id = $id; + return $this; + } public function getInstock(): ?int { @@ -38,6 +55,28 @@ class Stock return $this; } + public function getProductId(): ?int + { + return $this->product_id; + } + + public function setProductId(int $product_id): self + { + $this->product_id = $product_id; + + return $this; + } + public function getWarehouseId(): ?int + { + return $this->warehouse_id; + } + + public function setWarehouseId(int $warehouse_id): self + { + $this->warehouse_id = $warehouse_id; + + return $this; + } public function getProduct(): ?Product { @@ -72,4 +111,16 @@ class Stock return $this; } + + public function getUpdateTime(): ?\DateTimeInterface + { + return $this->update_time; + } + + public function setUpdateTime(?\DateTimeInterface $update_time): self + { + $this->update_time = $update_time; + + return $this; + } } diff --git a/src/Entity/Warehouse.php b/src/Entity/Warehouse.php index 3b943d9..ba0ee8e 100644 --- a/src/Entity/Warehouse.php +++ b/src/Entity/Warehouse.php @@ -33,6 +33,11 @@ class Warehouse { return $this->id; } + public function setId(int $id): self + { + $this->id = $id; + return $this; + } public function getName(): ?string { diff --git a/src/Helper/HiltesImport.php b/src/Helper/HiltesImport.php index 8f30376..817e2bf 100644 --- a/src/Helper/HiltesImport.php +++ b/src/Helper/HiltesImport.php @@ -7,20 +7,28 @@ use App\Entity\Product; use App\Entity\Stock; use App\Entity\Warehouse; use App\Repository\ProductRepository; +use App\Repository\StockRepository; +use App\Repository\WarehouseRepository; use Psr\Log\LoggerInterface; use Symfony\Component\Finder\Finder; class HiltesImport { private $productRepository; + private $stockRepository; private $warehouseRepository; private $logger; protected $currentDirPath; + protected $cachedWarehouseIds; + private $cachedProdIds; + private $cachedStockIds; protected $arrData = array(); - public function __construct(ProductRepository $productRepository, LoggerInterface $logger) + public function __construct(ProductRepository $productRepository,WarehouseRepository $warehouseRepository,StockRepository $stockRepository, LoggerInterface $logger) { $this->productRepository = $productRepository; + $this->warehouseRepository = $warehouseRepository; + $this->stockRepository = $stockRepository; $this->logger = $logger; $this->currentDirPath = getcwd(); @@ -34,6 +42,8 @@ class HiltesImport { #*** Holt alle Dateien if($this->getFiles()){ + #*** Holt Alle Stocks und setzt ein Array ************** + $this->getStocks(); if(!empty($this->arrData['orgFiles']['data']) && count($this->arrData['orgFiles']['data'])){ foreach ($this->arrData['orgFiles']['data'] as $file) { if(is_file($file['realPath'])){ @@ -46,7 +56,7 @@ class HiltesImport }else return array('success'=>1,'text'=>'No Files'); }else - return array('error'=>1,'text'=>'Error in getFiles'); + return array('error'=>1,'text'=>'Error in getFiles or no file WS.FERTIG'); } /** @@ -61,10 +71,14 @@ class HiltesImport #->filter(static function (SplFileInfo $file) { # return $file->isDir() || \preg_match('/\.(php|json)$/', $file->getPathname()); #}); + $hasFoundFertigFile = false; if ($finder->hasResults()) { - - dump($finder); + #dump($finder); foreach ($finder as $file) { + if($file->getRelativePathname()=='WS.FERTIG'){ + $hasFoundFertigFile = true; + continue; + } $this->arrData['orgFiles']['data'][] = array( 'realPath' => $file->getRealPath(), 'fileSize' => $file->getFileInfo()->getSize(), @@ -75,16 +89,25 @@ class HiltesImport return false; } - return true; + return $hasFoundFertigFile; + } + protected function getStocks() + { + $r = $this->stockRepository->findAll(); + foreach ($r as $v) { + $this->cachedStockIds[$v->getProductId()][$v->getWarehouse()->getId()] = $v; + } + #dd($this->cachedStockIds); } protected function loadFiles($srcFile,$size) { - + #*** Check File **** + #dd($srcFile); $file = new \SplFileObject($srcFile); - dump($file->getRealPath()); + #dump($file->getRealPath()); $this->logger->info('Starte Import von ' . $file->getRealPath()); - + dump('Starte Import von ' . $file->getRealPath()); $c = 0; while (!$file->eof()) { // Header überspringen @@ -119,52 +142,6 @@ class HiltesImport #*** Leerzeichen löschen bei den einzelnen Einträgen ********** $this->trimArray($arr); #*** -// $arr[0] = strtolower($arr[0]); -// switch ($arr[0]){ -// case 'datei': # Datei -// $this->saveInfoDatei($arr); -// break; -// case 'filiale': # Filiale -// #$this->saveInfoFiliale($arr); -// break; -// case 'land': # Länder -// $this->saveInfoLand($arr); -// break; -// case 'hwg': # Hauptwarengruppe -// #$this->saveInfoHauptWarenGruppe($arr); -// break; -// case 'wg': # Warengruppe -// #$this->saveInfoWarenGruppe($arr); -// break; -// case 'anrede': # Anrede -// #$this->saveInfoAnrede($arr); -// break; -// case 'lieferant': # Lieferant -// #$this->saveInfoLieferant($arr); -// break; -// case 'farb': # Farbcodierung -// #$this->saveInfoFarbCodierung($arr); -// break; -// case 'nlart': # NachlassArt -// #$this->saveInfoNachlassArt($arr); -// break; -// case 'kollektion': # Kollektion -// #$this->saveInfoKollektion($arr); -// break; -// case 'bestand': # Bestand -// #$this->saveInfoBestand($arr); -// break; -// case 'merkmale': # Made In XXXX = Land -// #$this->saveInfoMerkmale($arr); -// break; -// case 'material': # MAterial -// #$this->saveInfoMaterial($arr); -// break; -// default: # -// dump('!!!!! KEIN DEFINIERTER ANFANG "'.$arr[0].'" !!!!!!!!!'); -// break; -// } - $this->saveData($arr); } @@ -182,28 +159,27 @@ class HiltesImport */ protected function saveData(Array $arr){ #dump($arr); - $prod = new Product(); - - $stock = new Stock(); + #*** Speichert und/oder Holt WareHouse ab + $wareHouse = $this->checkWareHouseName($arr[0]); + #*** PRodukt wird angelegt oder geholt **** + #filiale;etikettnr;menge;modellnr;modellbez + $prodId = $this->checkProduct($arr[1],$arr[3],$arr[4]); + #*** Ermitteln ob schon ein ID vorhadnen für ProdId und WareHouseId + if(!empty($wareHouse) && !empty($this->cachedStockIds[$prodId][$wareHouse->getId()])){ + $stock = $this->cachedStockIds[$prodId][$wareHouse->getId()]; + #dd('JAAAAA'); + }else{ + $stock = new Stock(); + $stock->setProductId($prodId); + $stock->setWarehouse($wareHouse); + } + #dd('CHCEK'); $stock->setInstock((int)$arr[2]); + #$stock->setWarehouseId($wareHouseId); + #dump($stock); + $this->stockRepository->save($stock,true); - $warehouse = new Warehouse(); - $warehouse->setName($arr[0]); - // $stock->setWarehouse($warehouse); - - #menge; - $prod->setStock($stock); - - #eanzuIdent; - $prod->setGtin($arr[13]); - - $prod->setShopwareId(""); - - - // dump($prod); - - $this->productRepository->save($prod,true); - + #dd($stock); //$stock->setStock((int)$arr[2]); #filiale; @@ -236,28 +212,53 @@ class HiltesImport } - /** - * @param $id - * @return mixed - */ - private function getWarehouseId($id){ - $warehouse = $this->warehouseRepository->findOneBy(array('id'=>$id)); - if($warehouse instanceof Warehouse){ - return $warehouse->getId(); - }else{ - $warehouse = new Warehouse(); - - - $warehouse->setPriority(0); - $warehouse->setId($this->warehouseRepository->add($warehouse, true)); - - dump($warehouse); - - - - return $warehouse; - } - } + private function checkWareHouseName(string $wareHouseName){ + #*** WEnn keine geCached Id Vorhanden + $warehouse2 = false; + if(empty($this->cachedWarehouseIds[$wareHouseName])){ + #*** Check + $warehouse2 = $this->warehouseRepository->findOneBy(['id'=> (int)$wareHouseName]); + #dump($warehouse2); + if(empty($warehouse2)){ + $warehouse = new Warehouse(); + $warehouse->setId((int)$wareHouseName); + $warehouse->setName($wareHouseName); + # + $this->warehouseRepository->save($warehouse,true); + #***************** + $warehouse2 = $this->warehouseRepository->findOneBy(['id'=> (int)$wareHouseName]); + #dump($warehouse2); + } + $this->cachedWarehouseIds[$wareHouseName] = $warehouse2; + } + if(!empty($this->cachedWarehouseIds[$wareHouseName])) + return $this->cachedWarehouseIds[$wareHouseName]; + return false; + } + private function checkProduct(string $gtin,string $modellNr,string $modellBez){ + #*** WEnn keine geCached Id Vorhanden + if(empty($this->cachedProdIds[$gtin])){ + #*** Check + $prod2 = $this->productRepository->findOneBy(['gtin'=> $gtin]); + #dump($warehouse2); + if(empty($prod2)){ + $prod = new Product(); + $prod->setGtin($gtin); + $prod->setModellNr($modellNr); + $prod->setModellBez($modellBez); + $prod->setShopwareId(""); + # + $this->productRepository->save($prod,true); + #***************** + $prod2 = $this->productRepository->findOneBy(['gtin'=> $gtin]); + #dump($warehouse2); + } + $this->cachedProdIds[$gtin] = $prod2->getId(); + } + if(!empty($this->cachedProdIds[$gtin])) + return $this->cachedProdIds[$gtin]; + return false; + } } diff --git a/src/Repository/StockRepository.php b/src/Repository/StockRepository.php index 4e19631..fd07de2 100644 --- a/src/Repository/StockRepository.php +++ b/src/Repository/StockRepository.php @@ -23,6 +23,8 @@ class StockRepository extends ServiceEntityRepository public function save(Stock $entity, bool $flush = false): void { + $entity->setUpdateTime(new \DateTime()); + $this->getEntityManager()->persist($entity); if ($flush) { diff --git a/src/Repository/WarehouseRepository.php b/src/Repository/WarehouseRepository.php index 183d31b..1bbe4b6 100644 --- a/src/Repository/WarehouseRepository.php +++ b/src/Repository/WarehouseRepository.php @@ -23,6 +23,7 @@ class WarehouseRepository extends ServiceEntityRepository public function save(Warehouse $entity, bool $flush = false): void { + $entity->setPrio(0); $this->getEntityManager()->persist($entity); if ($flush) {