Feature/add e shop

This commit is contained in:
Luca Haid
2024-07-24 13:25:49 +00:00
parent 1c8f1acf2a
commit 6c79a9302f
30 changed files with 588 additions and 53 deletions
+2 -3
View File
@@ -261,10 +261,9 @@ class User extends mfBaseModel {
if(!is_array($what)) {
$what = [$what];
}
//ob_end_clean();var_dump($what, $this->permissions);exit;
foreach($what as $w) {
$perm = ucfirst(strtolower($w));
$perm = ucfirst(($w));
if(is_object($this->permissions) && property_exists($this->permissions->data, "can$perm")) {
if($this->permissions->{"can$perm"} === "true") {
return true;
+3
View File
@@ -235,6 +235,9 @@ class UserController extends mfBaseController
$user->permissions->canBilling = "false";
$user->permissions->canFibu = "false";
$user->permissions->canStatistics = "false";
$user->permissions->canWarehouseAdmin = "false";
$user->permissions->canWarehouseEShop = "false";
$user->permissions->canWarehouseUser = "false";
if($r->get("can") && is_array($r->can)) {
foreach($r->can as $key => $can) {
@@ -9,11 +9,15 @@ class WarehouseArticleController extends TTCrud {
['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', 'modal' => ['type' => 'number'], 'table' => ['class' => 'text-center']], // Stock/inventory related
['key' => 'criticalAmount', 'text' => 'Kritische Menge', 'modal' => ['type' => 'number'], 'table' => ['class' => 'text-center']], // Stock/inventory related
['key' => 'isEShop', 'text' => 'Ist E-Shop', 'modal' => ['type' => 'checkbox'], 'table' => false], // Boolean value
['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]]
];
@@ -43,6 +47,7 @@ class WarehouseArticleController extends TTCrud {
$cheapestPurchasePrice = WarehouseArticleDistributorModel::getAll(['articleId' => $articleId], 1, 0,
['key' => 'purchasePrice', 'order' => 'ASC'])[0]->purchasePrice;
$article = WarehouseArticleModel::get($articleId);
if (!$article instanceof WarehouseArticleModel) {
@@ -53,13 +58,59 @@ class WarehouseArticleController extends TTCrud {
// $cheapestSellPrice = $article->sellPriceOverride ?? $article->sellPriceMultiplier * $cheapestPurchasePrice;
if ($article->cheapestPurchasePrice != $cheapestPurchasePrice) {
WarehouseArticleModel::update([...get_object_vars($article), // Unpack properties into an array
'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($postData) {
self::updateCheapestPurchasePrice($postData['id']);
protected function afterCreate() {
$last5Articles = WarehouseArticleModel::getAll([], 5, 0, ['key' => 'id', 'order' => 'DESC']);
foreach ($last5Articles as $article) {
self::updateCheapestPurchasePrice($article->id);
}
}
protected function updateAllCheapestPurchasePricesAction() {
@@ -6,10 +6,14 @@ class WarehouseArticleModel extends TTCrudBaseModel {
public string $description;
public string $category;
public ?float $cheapestPurchasePrice;
public ?float $cheapestSellPrice;
public ?string $cheapestSellPrice;
public int $warningAmount;
public int $criticalAmount;
public int $isEShop;
public float $defaultSellMultiplier;
public string $unit;
public int $isSerialDocumentation;
public int $revenueAccount;
}
@@ -20,8 +20,8 @@ class WarehouseArticleDistributorController extends TTCrud {
'delete' => 'Lieferanteintrag wurde gelöscht',
'noChanges' => 'Keine Änderungen',];
protected function checkExistingThresholdEntry($postData): bool {
$count = WarehouseLocationThresholdOverrideModel::count(['articleId' => $postData['articleId'],
protected function checkExistingDistributorEntry($postData): bool {
$count = WarehouseArticleDistributorModel::count(['articleId' => $postData['articleId'],
'distributorId' => $postData['distributorId']]);
if ($count > 0) {
@@ -34,7 +34,7 @@ class WarehouseArticleDistributorController extends TTCrud {
}
protected function beforeCreate($postData): bool {
return $this->checkExistingThresholdEntry($postData);
return $this->checkExistingDistributorEntry($postData);
}
protected function afterCreate($postData) {
@@ -42,7 +42,7 @@ class WarehouseArticleDistributorController extends TTCrud {
}
protected function beforeUpdate($postData): bool {
$existing = $this->checkExistingThresholdEntry($postData);
$existing = $this->checkExistingDistributorEntry($postData);
if (!$existing) {
return false;
@@ -0,0 +1,9 @@
<?php
/**
* @property mixed|null $name
*/
class WarehouseArticlePacket extends mfBaseModel
{
}
@@ -0,0 +1,94 @@
<?php
class WarehouseArticlePacketController extends TTCrud {
protected string $headerTitle = 'Artikel-Pakete';
protected string $createText = 'Artikel-Paket erstellen';
// @formatter:off
protected array $columns = [
['key' => 'title', 'text' => 'Titel', 'required' => true],
['key' => 'description', 'text' => 'Beschreibung', 'required' => true],
['key' => 'category', 'text' => 'Kategorie', 'required' => true],
['key' => 'overrideSellPrice', 'text' => 'Überschriebener Verkaufspreis', 'required' => false, 'modal' => ['type' => 'number'], 'table' => false],
['key' => 'calculatedSellPrice', 'text' => 'Verkaufspreis', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false]],
['key' => 'subItems', 'text' => 'Unterartikel', 'required' => true],
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 10]],
];
// @formatter:on
protected array $infoMessages = ['create' => 'Artikel-Paket wurde erstellt',
'update' => 'Artikel-Paket wurde aktualisiert',
'delete' => 'Artikel-Paket wurde gelöscht',
'noChanges' => 'Keine Änderungen'];
protected function prepareCrudConfig() {
$articles = array_map(function ($article) {
return ['value' => $article->id, 'text' => $article->title];
}, WarehouseArticleModel::getAll(
['isEShop' => 1],
));
$this->columns[5]['modal']['items'] = $articles;
}
//TODO: make this so it does not update all packets at the same time
protected function updatePacketPricesAction() {
$packets = WarehouseArticlePacketModel::getAll();
$articles = WarehouseArticleModel::getAll(['isEShop' => 1]);
// packet has $calculatedSellPrice for this but when overrideSellPrice is set, it should be used
foreach ($packets as $packet) {
if ($packet->overrideSellPrice) {
$calculatedSellPrice = $packet->overrideSellPrice;
} else {
$subItems = json_decode($packet->subItems);
$calculatedSellPrice = 0;
foreach ($subItems as $subItem) {
$article = WarehouseArticleModel::get($subItem->id);
$cheapestSellPrices = json_decode($article->cheapestSellPrice);
// find in array cheapestSellPrices by title === 'Energie Steiermark' and get the price
$articlePrice = array_values(array_filter($cheapestSellPrices, function ($cheapestSellPrice) {
return $cheapestSellPrice->title === 'Energie Steiermark';
}))[0]->price;
$calculatedSellPrice += $subItem->amount * $articlePrice;
}
}
WarehouseArticlePacketModel::update([...get_object_vars($packet), // Unpack properties into an array
'calculatedSellPrice' => $calculatedSellPrice]);
}
return true;
}
protected function afterUpdate(): bool {
return $this->updatePacketPricesAction();
}
protected function afterCreate(): bool {
return $this->updatePacketPricesAction();
}
protected function beforeUpdate($postData): bool {
(new WarehouseHistoryController)->create($postData, $this->mod);
return true;
}
protected function getHistoryAction() {
$history = WarehouseHistoryModel::getByRowId($this->request->id, $this->mod);
$history = array_map(function ($item) {
$item = (array) $item;
$item['columnHeader'] = $this->columns[array_search($item['key'], array_column($this->columns, 'key'))]['text'];
return $item;
}, $history);
self::returnJson($history);
}
}
@@ -0,0 +1,11 @@
<?php
class WarehouseArticlePacketModel extends TTCrudBaseModel {
public int $id;
public string $title;
public string $description;
public string $category;
public ?float $overrideSellPrice;
public ?float $calculatedSellPrice;
public string $subItems;
}
@@ -23,6 +23,14 @@ class WarehouseArticlePriceController extends TTCrud {
}
protected function validate($postData): bool {
// if either priceOverride or priceMultiplier is empty set it to null
if (isset($postData['priceOverride']) && $postData['priceOverride'] === '') {
$postData['priceOverride'] = null;
}
if (isset($postData['priceMultiplier']) && $postData['priceMultiplier'] === '') {
$postData['priceMultiplier'] = null;
}
// check if postData priceOverride or priceMultiplier is set but only one of them
if (isset($postData['priceOverride']) && isset($postData['priceMultiplier'])) {
self::returnJson(['success' => false,
@@ -51,6 +51,15 @@ class WarehouseArticlePriceTypeController extends TTCrud {
return true;
}
protected function afterUpdate($postData) {
WarehouseArticleController::updateCheapestPurchasePrice($postData['articleId']);
}
protected function afterCreate($postData) {
//TODO: fix this
WarehouseArticleController::updateCheapestPurchasePrice($postData['articleId']);
}
protected function getHistoryAction() {
$history = WarehouseHistoryModel::getByRowId($this->request->id, $this->mod);
@@ -5,8 +5,9 @@ class WarehouseEShopController extends TTCrud {
protected bool $createText = false;
protected array $columns = [
['key' => 'title', 'text' => 'Titel'],
['key' => 'category', 'text' => 'Kategorie'],
['key' => 'title', 'text' => 'Artikel'],
['key' => 'category', 'text' => 'Kategorie', 'table' => false],
['key' => 'price', 'text' => 'Preis', 'table' => ['filter' => false,'sortable' => false,'class' => 'text-right']],
['key' => 'amount', 'text' => 'Menge', 'table' => ['filter' => false,'sortable' => false,'class' => 'p-0 width-80']],
['key' => 'add', 'text' => 'Hinzufügen', 'table' => ['filter' => false,'sortable' => false, 'class' => 'width-120 text-center']]
];
@@ -18,6 +19,10 @@ class WarehouseEShopController extends TTCrud {
'noChanges' => 'Keine Änderungen',
];
public function permissionCheck(): bool {
return $this->user->can(["WarehouseEShop"]);
}
public function getAction() {
$filter = $this->postData['filters'] ?? [];
$order = $this->postData['order'] ?? ['key' => null, 'order' => 'ASC'];
@@ -30,6 +35,10 @@ class WarehouseEShopController extends TTCrud {
$filteredAvailable = WarehouseArticleModel::count($filter);
$totalRows = WarehouseArticleModel::count(['isEShop' => 1]);
$packetRows = WarehouseArticlePacketModel::getAll();
$rows = [...$rows, ...$packetRows];
self::returnJson(["rows" => $rows,
"pagination" => ["page" => $page,
"total_pages" => ceil($filteredAvailable / $perPage),
@@ -9,7 +9,7 @@ class WarehouseEShopOrderController extends TTCrud {
['key' => 'status', 'text' => 'Status', 'required' => true],
['key' => 'deliveryMode', 'text' => 'Liefermodus', 'required' => true, 'modal' => ['type' => 'select', 'items' => [
['value' => 'singleAddress', 'text' => 'Einzelne Adresse'],
['value' => 'multipleAddresses', 'text' => 'Mehrere Adressen'],
// ['value' => 'multipleAddresses', 'text' => 'Mehrere Adressen'],
]]],
['key' => 'deliveryAddressName', 'text' => 'Lieferadresse Name', 'required' => true, 'table' => false],
['key' => 'deliveryAddressLine', 'text' => 'Lieferadresse', 'required' => true, 'required_length' => 4],
@@ -31,6 +31,10 @@ class WarehouseEShopOrderController extends TTCrud {
'noChanges' => 'Keine Änderungen',
];
public function permissionCheck(): bool {
return $this->user->can(["WarehouseEShop"]);
}
protected function prepareCrudConfig() {
$users = array_map(function($user) {
return ['value' => intval($user->id), 'text' => $user->name];
@@ -67,11 +71,24 @@ class WarehouseEShopOrderController extends TTCrud {
// now create WarehouseEShopOrderItems for each item in the shopping cart
foreach ($shoppingCart as $item) {
WarehouseEShopOrderItemModel::create([
'orderId' => $id,
'articleId' => $item['itemId'],
'quantity' => intval($item['amount']),
]);
// itemId can either be P-[PACKETID] or I-[ARTICLEID]
// parse this and either fill articleId or articlePacketId for warehouseEShopOrderItem
if (strpos($item['itemId'], 'P-') === 0) {
WarehouseEShopOrderItemModel::create([
'orderId' => $id,
'articlePacketId' => intval(substr($item['itemId'], 2)),
'quantity' => intval($item['amount']),
]);
} else if (strpos($item['itemId'], 'I-') === 0) {
WarehouseEShopOrderItemModel::create([
'orderId' => $id,
'articleId' => intval(substr($item['itemId'], 2)),
'quantity' => intval($item['amount']),
]);
} else {
self::returnJson(['success' => false, 'message' => 'Invalid item id']);
die();
}
}
self::returnJson(['success' => true,
@@ -9,6 +9,7 @@
class WarehouseEShopOrderItemModel extends TTCrudBaseModel {
public int $id;
public int $orderId;
public int $articleId;
public ?int $articleId;
public ?int $articlePacketId;
public int $quantity;
}
@@ -0,0 +1,9 @@
<?php
/**
* @property mixed|null $name
*/
class WarehouseRevenueAccount extends mfBaseModel
{
}
@@ -0,0 +1,39 @@
<?php
class WarehouseRevenueAccountController extends TTCrud {
protected string $headerTitle = 'Erlöskontos';
protected string $createText = 'Erlöskonto erstellen';
// @formatter:off
protected array $columns = [
['key' => 'title', 'text' => 'Titel', 'required' => true],
['key' => 'revenueAccountNumber', 'text' => 'Erlöskonto Nummer', 'required' => true, 'modal' => ['type' => 'number']],
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 10]],
];
// @formatter:on
protected array $infoMessages = ['create' => 'Erlöskonto wurde erstellt',
'update' => 'Erlöskonto wurde aktualisiert',
'delete' => 'Erlöskonto wurde gelöscht',
'noChanges' => 'Keine Änderungen'];
protected function beforeUpdate($postData): bool {
(new WarehouseHistoryController)->create($postData, $this->mod);
return true;
}
protected function getHistoryAction() {
$history = WarehouseHistoryModel::getByRowId($this->request->id, $this->mod);
$history = array_map(function ($item) {
$item = (array) $item;
$item['columnHeader'] = $this->columns[array_search($item['key'], array_column($this->columns, 'key'))]['text'];
return $item;
}, $history);
self::returnJson($history);
}
}
@@ -0,0 +1,7 @@
<?php
class WarehouseRevenueAccountModel extends TTCrudBaseModel {
public int $id;
public int $revenueAccountNumber;
public string $title;
}