Files
thetool/application/WarehouseArticle/WarehouseArticleController.php
2024-07-24 13:25:49 +00:00

239 lines
12 KiB
PHP

<?php
class WarehouseArticleController extends TTCrud {
protected string $headerTitle = 'Artikel';
protected string $createText = 'Artikel erstellen';
// @formatter:off
protected array $columns = [
['key' => 'title', 'text' => 'Titel', 'required' => true, 'table' => ['priority' => 9]],
['key' => 'description', 'text' => 'Beschreibung', 'required' => true, 'table' => false],
['key' => 'category', 'text' => 'Kategorie', 'required' => true],
['key' => 'unit', 'text' => 'Einheit', 'required' => true,'table' => false], // Boolean value
['key' => 'defaultSellMultiplier', 'text' => 'Standard Multiplikator','regex' => '/^[0-9]*$/' , 'required' => true,'modal' => ['type' => 'number'], 'table' => false], // Boolean value
['key' => 'revenueAccount', 'text' => 'Erlöskonto', 'required' => true,'modal' => ['type' => 'number'], 'table' => false], // Boolean value
['key' => 'cheapestPurchasePrice', 'text' => 'Einkauf', 'modal' => false, 'table' => ['class' => 'text-center', 'suffix' => ' €']],
['key' => 'cheapestSellPrice', 'text' => 'Verkauf', 'modal' => false, 'table' => ['class' => 'text-center', 'suffix' => ' €']],
['key' => 'warningAmount', 'text' => 'Warnmenge', 'required' => true,'modal' => ['type' => 'number'], 'table' => ['class' => 'text-center']], // Stock/inventory related
['key' => 'criticalAmount', 'text' => 'Kritische Menge', 'required' => true,'modal' => ['type' => 'number'], 'table' => ['class' => 'text-center']], // Stock/inventory related
['key' => 'isSerialDocumentation', 'text' => 'Seriennummern', 'required' => true,'modal' => ['type' => 'checkbox'], 'table' => false], // Boolean value
['key' => 'isEShop', 'text' => 'Ist E-Shop', 'required' => true,'modal' => ['type' => 'checkbox'], 'table' => false], // Boolean value
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 8]]
];
protected array $additionalActions = [
['key' => 'openHistory','title' => 'Historie','class' => 'fas fa-history text-secondary'],
['key' => 'editDistributorEntries','title' => 'Lieferanten','class' => 'fas fa-truck text-cyan'],
['key' => 'editThresholdEntries','title' => 'Schwellenwerte','class' => 'far fa-fw fa-box-full text-orange'],
['key' => 'editPricesEntries','title' => 'Preise','class' => 'fas fa-euro-sign text-green'],
];
// @formatter:on
protected array $infoMessages = ['create' => 'Artikel wurde erstellt',
'update' => 'Artikel wurde aktualisiert',
'delete' => 'Artikel wurde gelöscht',
'noChanges' => 'Keine Änderungen',];
protected function beforeUpdate($postData): bool {
(new WarehouseHistoryController)->create($postData, $this->mod);
return true;
}
protected function afterUpdate($postData) {
self::updateCheapestPurchasePrice($postData['id']);
}
public static function updateCheapestPurchasePrice($articleId) {
$cheapestPurchasePrice = WarehouseArticleDistributorModel::getAll(['articleId' => $articleId], 1, 0,
['key' => 'purchasePrice', 'order' => 'ASC'])[0]->purchasePrice;
$article = WarehouseArticleModel::get($articleId);
if (!$article instanceof WarehouseArticleModel) {
throw new Exception("Article is not an instance of WarehouseArticleModel");
}
//TODO: think of a new way as we have multiple sell prices now and article sellPriceOverride and sellPriceMultiplier do not exist anymore
// $cheapestSellPrice = $article->sellPriceOverride ?? $article->sellPriceMultiplier * $cheapestPurchasePrice;
if ($article->cheapestPurchasePrice != $cheapestPurchasePrice) {
try {
WarehouseArticleModel::update([...get_object_vars($article), // Unpack properties into an array
'cheapestPurchasePrice' => $cheapestPurchasePrice]);
} catch (Exception $e) {
print_r($article);
echo PHP_EOL;
die("WarehouseArticleController::updateCheapestPurchasePrice: " . $e->getMessage());
}
}
//TODO: start update cheapestSellPrice for each PriceType
$priceTypes = WarehouseArticlePriceTypeModel::getAll();
$articlePriceTypes = WarehouseArticlePriceModel::getAll(['articleId' => $articleId]);
//priceType has id, title
$cheapestSellPrices = [];
foreach ($priceTypes as $priceType) {
// check if priceType exists in articlePriceTypes else use $article->defaultSellMultiplier for price type
$articlePriceType = array_filter($articlePriceTypes, function ($articlePriceType) use ($priceType) {
return $articlePriceType->articlePriceTypeId == $priceType->id;
});
if (empty($articlePriceType)) {
$sellPrice = $article->defaultSellMultiplier * $cheapestPurchasePrice;
} else {
$articlePriceType = $articlePriceType[0];
if ($articlePriceType->priceOverride) {
$sellPrice = $articlePriceType->priceOverride;
} else {
$sellPrice = $articlePriceType->priceMultiplier * $cheapestPurchasePrice;
}
}
$cheapestSellPrices[] = [
'title' => $priceType->title,
'price' => $sellPrice,
];
}
// save cheapestSellPrices column on article
$article->cheapestSellPrice = json_encode($cheapestSellPrices);
WarehouseArticleModel::update([...get_object_vars($article)]);
}
protected function afterCreate() {
$last5Articles = WarehouseArticleModel::getAll([], 5, 0, ['key' => 'id', 'order' => 'DESC']);
foreach ($last5Articles as $article) {
self::updateCheapestPurchasePrice($article->id);
}
}
protected function updateAllCheapestPurchasePricesAction() {
$articles = WarehouseArticleModel::getAll();
foreach ($articles as $article) {
self::updateCheapestPurchasePrice($article->id);
}
}
protected function getHistoryAction() {
self::returnJson((new WarehouseHistoryController)->getHistory($this->request->id, $this->mod, $this->columns));
}
protected function importAction() {
error_reporting(E_ALL);
ini_set('display_errors', 1);
// read import.json from directory of this file
$json = fopen(dirname(__FILE__) . '/import.json', 'r') or die('Unable to open file!');
// read file content
$data = fread($json, filesize(dirname(__FILE__) . '/import.json'));
// decode json
$data = json_decode($data, true);
// close file
fclose($json);
// die with data length
// loop through data
echo 'Importing ' . count($data) . ' items' . PHP_EOL;
$count = 0;
foreach ($data as $item) {
// echo count + 1
echo ++$count . PHP_EOL;
// Check if Distributor exists
$distributor = WarehouseDistributorModel::getAll(['name' => $item['Lieferant']]);
if (empty($distributor)) {
$distributorId = WarehouseDistributorModel::create(['name' => $item['Lieferant'],
'address' => 'Missing',
'plz' => 'Missing',
'city' => 'Missing',
'countryId' => 1,
'email' => 'Missing',
'phone' => 'Missing',
'contactPerson' => 'Missing',]);
} else {
$distributorId = $distributor[0]->id;
}
// only continue if PRODUKT 1.ZEILE and PRODUKT 2.ZEILE and ARTIKEL GRUPPE and VK and EK and Lieferant/ Hersteller Artikelnr: are set
if (!isset($item['PRODUKT 1.ZEILE'])) {
echo 'Missing data for ' . $item['PRODUKT 1.ZEILE'] . PHP_EOL;
continue;
}
if (empty($item['VK'])) {
$item['VK'] = 0;
$calcSellPriceMultiplier = 0;
} else {
$item['VK'] = floatval(str_replace(',', '', $item['VK']));
}
if (empty($item['EK'])) {
$item['EK'] = 0;
$calcSellPriceMultiplier = 0;
$purchasePrice = 0;
} else {
$item['EK'] = floatval(str_replace(',', '', $item['EK']));
}
if (!empty($item['VK']) && !empty($item['EK'])) {
$calcSellPriceMultiplier = $item['VK'] / $item['EK'];
// if calcSellPriceMultiplier has more than 2 decimal places assign $calcSellPriceOverride
echo strlen(substr(strrchr($calcSellPriceMultiplier, "."), 1)) . PHP_EOL;
if (strlen(substr(strrchr($calcSellPriceMultiplier, "."), 1)) > 2) {
$calcSellPriceOverride = $item['VK'];
}
$purchasePrice = str_replace(',', '', $item['EK']);
}
if (!isset($calcSellPriceMultiplier) && !isset($calcSellPriceOverride) || !isset($purchasePrice)) {
echo 'Missing data for ' . $item['PRODUKT 1.ZEILE'] . PHP_EOL;
continue;
}
// Check if Article exists
$article = WarehouseArticleModel::getAll(['title' => ['exact' => $item['PRODUKT 1.ZEILE']]]);
if (empty($article)) {
$articleCreateData = ['title' => $item['PRODUKT 1.ZEILE'],
'description' => $item['PRODUKT 2. ZEILE'],
'category' => $item['ARTIKEL GRUPPE'],
'cheapestPurchasePrice' => 0,
'warningAmount' => 25,
'criticalAmount' => 10,
'isEShop' => 0,];
// if calcSellPriceOverride is set, add it to the $articleCreateData array
if (isset($calcSellPriceOverride)) {
$articleCreateData['sellPriceOverride'] = $calcSellPriceOverride;
} else if (isset($calcSellPriceMultiplier)) {
$articleCreateData['sellPriceMultiplier'] = $calcSellPriceMultiplier;
}
$articleId = WarehouseArticleModel::create($articleCreateData);
} else {
echo 'Article already exists with title ' . $item['PRODUKT 1.ZEILE'] . PHP_EOL;
$articleId = $article[0]->id;
}
// Check if ArticleDistributor exists
$articleDistributor = WarehouseArticleDistributorModel::getAll(['articleId' => $articleId,
'distributorId' => $distributorId]);
if (empty($articleDistributor)) {
WarehouseArticleDistributorModel::create(['articleId' => $articleId,
'distributorId' => $distributorId,
'purchasePrice' => $purchasePrice,
'externalArticleNumber' => $item['Lieferant/ Hersteller Artikelnr:'],]);
}
}
}
}