add FTP Upload

This commit is contained in:
Marko
2023-09-27 15:07:34 +02:00
parent a1a2eb84b3
commit a97fec167c
29 changed files with 175 additions and 25090 deletions

View File

@@ -1,124 +0,0 @@
<?php
namespace App\Command;
use App\Controller\ShopwareController;
use App\Entity\Order;
use App\Helper\Shopware;
use App\Repository\OrdersRepository;
use Doctrine\ORM\Mapping as ORM;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Vin\ShopwareSdk\Client\AdminAuthenticator;
use Vin\ShopwareSdk\Client\GrantType\ClientCredentialsGrantType;
use Vin\ShopwareSdk\Data\Context;
use Vin\ShopwareSdk\Data\Criteria;
use Vin\ShopwareSdk\Data\Entity\EntityCollection;
use Vin\ShopwareSdk\Data\Entity\Order\OrderDefinition;
use Vin\ShopwareSdk\Data\Filter\EqualsAnyFilter;
use Vin\ShopwareSdk\Data\Filter\EqualsFilter;
use Vin\ShopwareSdk\Factory\RepositoryFactory;
#[AsCommand(
name: 'sw:get-orders',
description: 'Holt alle offenen Bestellungen von Shopware ab',
)]
class SwGetOrdersCommand extends Command
{
private $orderRepository;
private $logger;
private $sw;
private $orderData;
public function __construct(OrdersRepository $orderRepository, LoggerInterface $logger)
{
$this->orderRepository = $orderRepository;
$this->logger = $logger;
$this->sw = new Shopware($logger);
parent::__construct();
}
protected function configure(): void
{
// $this
// ->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')
// ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
// ;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
// $arg1 = $input->getArgument('arg1');
//
// if ($arg1) {
// $io->note(sprintf('You passed an argument: %s', $arg1));
// }
//
// if ($input->getOption('option1')) {
// // ...
// }
//offene Bestellungen aus Datenbank holen
$this->orderData = $this->getOrders();
$this->getOrderDetails();
$io->success('Done!');
return Command::SUCCESS;
}
/**
* @return array
*/
private function getOrders():array
{
return $this->orderRepository->findAll();
}
/**
* @return void
*/
public function getOrderDetails(): void
{
//Bestelldetails aus SW holen
$this->getOrdersDataFromSW();
foreach ($this->orderData as $order) {
$this->saveOrdersData($order);
}
}
/**
* holt alle fehlende Bestelldetails aus SW
*/
private function getOrdersDataFromSW(): void
{
foreach ($this->orderData as $value) {
// Bei Shopware API anmelden
$value->setData((array)$this->sw->getOrders($value));
}
}
/**
* @param $orderData
* @return void
*/
private function saveOrdersData($orderData): void
{
$orderData->setStatus = 1;
$this->ordersRepository->add($orderData, true);
}
}

View File

@@ -1,111 +0,0 @@
<?php
namespace App\Command;
use App\Helper\Shopware;
use App\Repository\ProductRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
#[AsCommand(
name: 'sw:push-stock',
description: 'Übermittelt den Bestand an Shopware',
)]
class SwPushStockCommand extends Command
{
private $productRepository;
private $logger;
public function __construct(ProductRepository $productRepository, LoggerInterface $logger)
{
$this->productRepository = $productRepository;
$this->logger = $logger;
parent::__construct();
}
protected function configure(): void
{
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
// $arg1 = $input->getArgument('arg1');
// if ($arg1) {
// $io->note(sprintf('You passed an argument: %s', $arg1));
// }
//
// if ($input->getOption('option1')) {
// // ...
// }
$shopware = new Shopware($this->logger);
$products = $this->getProducts();
if (count($products) > 0) {
foreach ($products as $product) {
//prüfen ob Shopware ID vorhanden
if($product->getShopwareId() == null) {
$swID = $this->getShopwareId($product);
if($swID != null) {
$product->setShopwareId($swID->id);
}else{
continue;
}
}
$shopware->setProduct($product);
}
}
$io->success('Done.');
return Command::SUCCESS;
}
protected function getProducts()
{
$products = $this->productRepository->findAll();
$arrProducts = array();
foreach ($products as $product) {
$arrProducts[$product->getGtin()] = $product;
}
return $arrProducts;
}
/**
* @param Product $product
* @return int|null
*/
protected function getShopwareId($product)
{
$shopware = new Shopware($this->logger);
$shopwareProduct = $shopware->getShopwareIdbyGtin($product->getGtin());
if($shopwareProduct != null) {
//dump($shopwareProduct);
$product->setShopwareId($shopwareProduct->id);
$this->productRepository->save($product, true);
}
return $shopwareProduct;
}
}

View File

@@ -20,14 +20,7 @@ class Product
#[ORM\Column(length: 255)]
private ?string $gtin = null;
// #[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(name: 'change_date', type: Types::DATETIME_MUTABLE, nullable: true, options: ['default' => 'CURRENT_TIMESTAMP'])]
#[ORM\Column(name: 'update_time', type: Types::DATETIME_MUTABLE, nullable: true, options: ['default' => 'CURRENT_TIMESTAMP'])]
private ?\DateTimeInterface $updateTime = null;
@@ -47,40 +40,6 @@ 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
// {
// return $this->shopwareId;
// }
//
// public function setShopwareId(string $shopwareId): self
// {
// $this->shopwareId = $shopwareId;
//
// return $this;
// }
public function getUpdateTime(): ?\DateTimeInterface
{

View File

@@ -29,7 +29,7 @@ class Stock
#[ORM\ManyToOne(inversedBy: 'stocks')]
private ?Warehouse $warehouse = null;
#[ORM\Column(name: 'change_date',type: Types::DATETIME_MUTABLE, nullable: true, options: ['default' => 'CURRENT_TIMESTAMP'])]
#[ORM\Column(name: 'update_time',type: Types::DATETIME_MUTABLE, nullable: true, options: ['default' => 'CURRENT_TIMESTAMP'])]
private ?\DateTimeInterface $update_time = null;

View File

@@ -73,30 +73,51 @@ class Ftp
}
/**
* @param string $localFile
* @return bool
* Uploads a local file to a remote FTP server.
*
* @param string $localFile The local file path to upload.
*
* @throws \Exception If the upload fails or encounters an error.
*
* @return void
*/
public function uploadFile(string $localFile): bool
public function uploadFile(string $localFile): void
{
$ftp = ftp_ssl_connect($this->getHost(),$this->getPort());
$ftp_login = ftp_login($ftp,$this->getUser(), $this->getPassword());
$ftp = ftp_ssl_connect($this->getHost(), $this->getPort());
if (!$ftp) {
throw new \Exception("Failed to connect to FTP server");
}
$ftp_login = ftp_login($ftp, $this->getUser(), $this->getPassword());
if (!$ftp_login) {
throw new \Exception("FTP login failed");
}
ftp_pasv($ftp, true);
$remoteFile = 'stock_hiltes.csv';
if($ftp_login){
$r = ftp_put($ftp,$this->getRemoteDir().$remoteFile, $localFile);
ftp_close($ftp);
// dump(array('$r'=>$r,$this->getRemoteDir().$remoteFile, $localFile,'Line'=>__LINE__));
if($r){
// if(ftp_rename($ftp,$this->getRemoteDir().$remoteFile.'.tmp',$this->getRemoteDir().$remoteFile)){
// ftp_close($ftp);
return unlink($localFile); # löschen der datei
//}
}else
return false;
if (!file_exists($localFile)) {
throw new \Exception("Local file does not exist: $localFile");
}
return false;
$r = ftp_nb_put($ftp, $this->getRemoteDir() . $remoteFile, $localFile, FTP_BINARY);
while ($r == FTP_MOREDATA) {
// Continue uploading...
$r = ftp_nb_continue($ftp);
}
if ($r != FTP_FINISHED) {
throw new \Exception("File upload failed");
}
ftp_close($ftp);
if (!unlink($localFile)) {
throw new \Exception("Failed to delete local file: $localFile");
}
}
}

View File

@@ -12,7 +12,6 @@ use App\Repository\WarehouseRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Finder\Finder;
use App\Helper\App\Helper\SplFileInfo;
class HiltesImport
{
@@ -51,18 +50,19 @@ class HiltesImport
foreach ($this->arrData['orgFiles']['data'] as $file) {
if(is_file($file['realPath'])){
$count += $this->loadFiles($file['realPath'],$file['fileSize']);
$count += $this->loadFiles($file['realPath']);
}else{
throw new \RuntimeException("Error: File not found - " . $file['realPath']);
}
}
return array('error'=>1,'text'=>'Error is_file('.$file['realPath'].')');
$this->logger->info("Imported $count stocks");
} else {
$this->logger->info('No Files');
}
}
dump("Imported $count stocks");
}else
return array('success'=>1,'text'=>'No Files');
}else
return array('error'=>1,'text'=>'Error in getFiles or no file WS.FERTIG');
} else {
throw new \RuntimeException('Error in getFiles or no file WS.FERTIG');
}
}
/**
@@ -82,7 +82,6 @@ class HiltesImport
}
if ($finder->hasResults()) {
#dump($finder);
foreach ($finder as $file) {
if($file->getExtension() != 'Ende') {
//prüfen ob Ende Datei vorhanden ist
@@ -103,132 +102,92 @@ class HiltesImport
}
protected function getStocks()
{
$r = $this->stockRepository->findAll();
foreach ($r as $v) {
$this->cachedStockIds[$v->getProductId()][$v->getWarehouse()->getId()] = $v;
$stocks = $this->stockRepository->findAll();
foreach ($stocks as $stock) {
$this->cachedStockIds[$stock->getProductId()][$stock->getWarehouse()->getId()] = $stock;
}
#dd($this->cachedStockIds);
}
/**
* @param $srcFile
* @param $size
* @return int
*/
protected function loadFiles($srcFile,$size)
protected function loadFiles($srcFile)
{
#*** Check File ****
#dd($srcFile);
$file = new \SplFileObject($srcFile);
#dump($file->getRealPath());
try {
$file = new \SplFileObject($srcFile);
$this->logger->info('Starte Import von ' . $file->getRealPath());
$count = 0;
$this->logger->info('Starte Import von ' . $file->getRealPath());
dump('Starte Import von ' . $file->getRealPath());
$c = 0;
while (!$file->eof()) {
while (!$file->eof()) {
$this->processLine($file->fgets());
$count++;
}
}catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
// #*** Convertiert die Zeile in UTF8
// $data = iconv('ISO-8859-1','UTF-8',$file->fgets());
//
// #*** Überspringt die erste Zeile
// if($c == 0){
// $c++;
// continue;
// }
unlink($srcFile);
unlink($srcFile . '.Ende');
#*** Speichert die Zeile
$this->switchSaveData($this->splitLine($file->fgets()));
$c++;
$this->logger->info($count . ' Datensätze importiert');
}
//unlink($file->getRealPath());
dump($c . ' Datensätze importiert');
return $c;
}
protected function splitLine($str){
return str_getcsv($str,';','"');
return $count;
}
/**
* Hier wird festgelegt wo und wie die Zeile gespeichert wird
*
* @param array $arr
* @return void
*/
protected function switchSaveData(array $arr){
if(!empty($arr[0])){
#*** Leerzeichen löschen bei den einzelnen Einträgen **********
$this->trimArray($arr);
#***
$this->saveData($arr);
protected function processLine($line)
{
$data = str_getcsv($line, ';', '"');
if (!empty($data[0])) {
$this->trimArray($data);
$this->saveData($data);
}
}
protected function trimArray(Array &$arr){
protected function trimArray(array &$arr)
{
foreach ($arr as $k=>$v) {
$arr[$k] = trim($v);
}
}
protected function saveData(array $data)
{
$warehouse = $this->checkWarehouseName($data[3]);
$gtin = $this->checkProduct(substr($data[0], 1));
/**
* @param array $arr
* @return void
*/
protected function saveData(Array $arr){
//dump($arr);
#*** Speichert und/oder Holt WareHouse ab
$wareHouse = $this->checkWareHouseName($arr[3]);
#*** PRodukt wird angelegt oder geholt ****
#filiale;etikettnr;menge;
$gtin = $this->checkProduct(substr($arr[0],1));
#*** Ermitteln ob schon ein ID vorhanden für ProdId und WareHouseId
if(!empty($wareHouse) && !empty($this->cachedStockIds[$gtin][$wareHouse->getId()])){
$stock = $this->cachedStockIds[$gtin][$wareHouse->getId()];
if (!empty($warehouse) && !empty($this->cachedStockIds[$gtin][$warehouse->getId()])) {
$stock = $this->cachedStockIds[$gtin][$warehouse->getId()];
}else{
$stock = new Stock();
$stock->setProductId($gtin);
$stock->setWarehouse($wareHouse);
$stock->setWarehouse($warehouse);
}
//dd('CHCEK');
$stock->setInstock((int)$arr[1]/100);
#$stock->setWarehouseId($wareHouseId);
//dump($stock);
$stock->setInstock((int) $data[1] / 100);
$this->stockRepository->save($stock,true);
}
/**
* @param string $wareHouseName
* @return Warehouse|false|int|mixed|null
*/
private function checkWareHouseName(string $wareHouseName){
private function checkWarehouseName(string $warehouseName)
{
$warehouseName = ltrim($warehouseName, 0);
$wareHouseName = ltrim($wareHouseName,0);
#*** WEnn keine geCached Id Vorhanden
if(empty($this->cachedWarehouseIds[$wareHouseName])){
#*** Check
$warehouse2 = $this->warehouseRepository->findOneBy(['id'=> (int)$wareHouseName]);
if(empty($warehouse2)){
if (empty($this->cachedWarehouseIds[$warehouseName])) {
$warehouse = $this->warehouseRepository->findOneBy(['id' => (int) $warehouseName]);
if (empty($warehouse)) {
$warehouse = new Warehouse();
$warehouse->setId((int)$wareHouseName);
$warehouse->setName($wareHouseName);
#
$warehouse->setId((int) $warehouseName);
$warehouse->setName($warehouseName);
$this->warehouseRepository->save($warehouse,true);
$this->cachedWarehouseIds[$wareHouseName] = $warehouse;
#*****************
#$warehouse2 = $this->warehouseRepository->findOneBy(['id'=> (int)$wareHouseName]);
#dump($warehouse2);
$this->cachedWarehouseIds[$warehouseName] = $warehouse;
}else{
$this->cachedWarehouseIds[$wareHouseName] = $warehouse2;
$this->cachedWarehouseIds[$warehouseName] = $warehouse;
}
}
if (!empty($this->cachedWarehouseIds[$warehouseName])) {
return $this->cachedWarehouseIds[$warehouseName];
}
if(!empty($this->cachedWarehouseIds[$wareHouseName]))
return $this->cachedWarehouseIds[$wareHouseName];
return false;
}
@@ -239,28 +198,21 @@ class HiltesImport
private function checkProduct(string $gtin){
#*** WEnn keine geCached Id Vorhanden
if(empty($this->cachedProdIds[$gtin])){
#*** Check
//dump($gtin);
$prod2 = $this->productRepository->findOneBy(['gtin'=> $gtin]);
//dump($prod2);
if(empty($prod2)){
$prod = new Product();
$prod->setGtin($gtin);
// $prod->setModellNr($modellNr);
// $prod->setModellBez($modellBez);
// $prod->setShopwareId("");
#
$this->cachedProdIds[$gtin] = $this->productRepository->save($prod,true);
#*****************
//$prod2 = $this->productRepository->findOneBy(['gtin'=> $gtin]);
#dump($warehouse2);
$product = $this->productRepository->findOneBy(['gtin' => $gtin]);
if (empty($product)) {
$product = new Product();
$product->setGtin($gtin);
$this->cachedProdIds[$gtin] = $this->productRepository->save($product, true);
}else{
$this->cachedProdIds[$gtin] = $prod2->getId();
$this->cachedProdIds[$gtin] = $product->getId();
}
}
}
if(!empty($this->cachedProdIds[$gtin]))
if (!empty($this->cachedProdIds[$gtin])) {
return $this->cachedProdIds[$gtin];
}
return false;
}
}

View File

@@ -1,132 +0,0 @@
<?php
namespace App\Helper;
use Psr\Log\LoggerInterface;
use Vin\ShopwareSdk\Client\AdminAuthenticator;
use Vin\ShopwareSdk\Client\GrantType\ClientCredentialsGrantType;
use Vin\ShopwareSdk\Data\Context;
use Vin\ShopwareSdk\Data\Criteria;
use Vin\ShopwareSdk\Data\Entity\Order\OrderDefinition;
use Vin\ShopwareSdk\Data\Entity\Product\ProductDefinition;
use Vin\ShopwareSdk\Data\Filter\EqualsFilter;
use Vin\ShopwareSdk\Factory\RepositoryFactory;
class Shopware
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
//parent::__construct();
}
/**
* Anmeldung bei der Shopwar API
* @return \Vin\ShopwareSdk\Data\AccessToken|void
*/
public function shopwareAuth()
{
try {
$grantType = new ClientCredentialsGrantType($_ENV['SHOPWARE_API_ID'], $_ENV['SHOPWARE_API_KEY']);
$adminClient = new AdminAuthenticator($grantType, $_ENV['SHOPWARE_API_URL']);
return $adminClient->fetchAccessToken();
} catch (\Exception $e) {
dump($e->getMessage());
$this->logger->error($e->getMessage());
}
}
/**
* @param string $orderId
* @return OrderDefinition
*/
public function getOrders(string $orderId):OrderDefinition{
$context = new Context($_ENV['SHOPWARE_API_URL'], $this->shopwareAuth());
// Create the repository for the entity
$orderRepository = RepositoryFactory::create(OrderDefinition::ENTITY_NAME);
// Create the criteria
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $orderId));
//Beziehungen zu Produkten holen
$criteria->addAssociation('lineItems');
$orders = false;
try {
$orders = $orderRepository->search($criteria, $context);
//$value->setData((array)$orders->getEntities());
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
return $orders->getEntities();
}
/**
* @param $prod
*/
public function setProduct($prod): void
{
$context = new Context($_ENV['SHOPWARE_API_URL'], $this->shopwareAuth());
//prüfen ob Shopware Produktid schon bekannt ist
if($prod->getShopwareId() == null){
$this->logger->error('Shopware Produkt ID ist nicht bekannt');
return;
}
$productRepository = RepositoryFactory::create(ProductDefinition::ENTITY_NAME);
#dump($prod->getShopwareId());
try {
$productRepository->update([
'id' => $prod->getShopwareId(),
'stock' => $prod->getStock()->getInStock()
], $context);
} catch (\ShopwareResponseException $e) {
$this->logger->error($e->getResponse());
}
}
public function getShopwareIdbyGtin($gtin)
{
$context = new Context($_ENV['SHOPWARE_API_URL'], $this->shopwareAuth());
// Create the repository for the entity
$productRepository = RepositoryFactory::create(ProductDefinition::ENTITY_NAME);
// Create the criteria
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('ean', $gtin));
$products = $productRepository->search($criteria, $context);
//dump($products->getEntities()->first());
if($products->count() > 0){
$productCollection = $products->getEntities();
return $productCollection->first();
//$prod->setShopwareId($products->getEntities()->first()->getId());
//return $products->getEntities()->first();
}else{
return null;
}
}
}