239 lines
12 KiB
PHP
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' => 'isEShopHide', 'text' => 'E-Shop Versteckt', '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(array_merge(get_object_vars($article), ['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:'],]);
|
|
}
|
|
|
|
}
|
|
}
|
|
} |