fixed some price handling aswell as tt-autocomplete and tt-table excel export always showing

This commit is contained in:
2024-07-25 08:59:41 +02:00
parent 813b0b4524
commit e4427c9eac
8 changed files with 106 additions and 74 deletions

View File

@@ -11,7 +11,7 @@ class WarehouseArticleController extends TTCrud {
['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' => 'revenueAccount', 'text' => 'Erlöskonto', 'required' => true,'modal' => ['type' => 'select'], '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
@@ -35,6 +35,15 @@ class WarehouseArticleController extends TTCrud {
'delete' => 'Artikel wurde gelöscht',
'noChanges' => 'Keine Änderungen',];
public function prepareCrudConfig() {
$revenueAccounts = WarehouseRevenueAccountModel::getAll();
$revenueAccounts = array_map(function ($revenueAccount) {
return ['value' => $revenueAccount->id, 'text' => $revenueAccount->title];
}, $revenueAccounts);
$this->columns[5]['modal']['items'] = $revenueAccounts;
}
protected function beforeUpdate($postData): bool {
(new WarehouseHistoryController)->create($postData, $this->mod);
return true;
@@ -44,79 +53,75 @@ class WarehouseArticleController extends TTCrud {
self::updateCheapestPurchasePrice($postData['id']);
}
public static function updateCheapestPurchasePrice($articleId) {
$cheapestPurchasePrice = WarehouseArticleDistributorModel::getAll(['articleId' => $articleId], 1, 0,
['key' => 'purchasePrice', 'order' => 'ASC'])[0]->purchasePrice;
/**
* Updates the cheapest purchase price for a given article from WarehouseArticleDistributorModel prices.
*
* @param int $articleId The ID of the article to update.
* @return void
* @throws Exception If the article is not an instance of WarehouseArticleModel.
*/
public static function updateCheapestPurchasePrice(int $articleId): void {
$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;
$order = ['key' => 'purchasePrice', 'order' => 'ASC'];
$cheapestDistributorEntry = WarehouseArticleDistributorModel::getAll(['articleId' => $articleId], 1, 0, $order);
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());
}
if (empty($cheapestDistributorEntry)) return;
$cheapestPurchasePrice = $cheapestDistributorEntry[0]->purchasePrice;
if ($article->cheapestPurchasePrice == $cheapestPurchasePrice) return;
WarehouseArticleModel::update(array_merge(get_object_vars($article), ['cheapestPurchasePrice' => $cheapestPurchasePrice]));
}
/**
* Updates the sell prices for a given article.
*
* @param int $articleId The ID of the article to update.
* @return void
* @throws Exception If the article is not an instance of WarehouseArticleModel.
*/
public static function updateSellPrices(int $articleId) {
$article = WarehouseArticleModel::get($articleId);
if (!$article instanceof WarehouseArticleModel) {
throw new Exception("Article is not an instance of WarehouseArticleModel");
}
//TODO: start update cheapestSellPrice for each PriceType
$priceTypes = WarehouseArticlePriceTypeModel::getAll();
$priceTypes = WarehouseArticlePriceTypeModel::getAll();
$articlePriceTypes = WarehouseArticlePriceModel::getAll(['articleId' => $articleId]);
//priceType has id, title
$cheapestSellPrices = [];
// Calculate sell prices for each price type, use default sell multiplier if no specific price is set
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;
$articlePriceType = array_filter($articlePriceTypes, function ($apt) use ($priceType) {
return $apt->articlePriceTypeId == $priceType->id;
});
if (empty($articlePriceType)) {
$sellPrice = $article->defaultSellMultiplier * $cheapestPurchasePrice;
} else {
$sellPrice = $article->defaultSellMultiplier * $article->cheapestPurchasePrice;
if (!empty($articlePriceType)) {
$articlePriceType = $articlePriceType[0];
if ($articlePriceType->priceOverride) {
$sellPrice = $articlePriceType->priceOverride;
} else {
$sellPrice = $articlePriceType->priceMultiplier * $cheapestPurchasePrice;
}
$sellPrice = $articlePriceType->priceOverride ?: $articlePriceType->priceMultiplier * $article->cheapestPurchasePrice;
}
$cheapestSellPrices[] = [
'title' => $priceType->title,
'price' => $sellPrice,
];
$cheapestSellPrices[$priceType->id] = ['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 afterCreate($postData) {
self::updateCheapestPurchasePrice($postData['id']);
self::updateSellPrices($postData['id']);
}
protected function updateAllCheapestPurchasePricesAction() {
$articles = WarehouseArticleModel::getAll();
foreach ($articles as $article) {
protected function updatePricesAction() {
foreach (WarehouseArticleModel::getAll() as $article) {
self::updateCheapestPurchasePrice($article->id);
self::updateSellPrices($article->id);
}
}
@@ -226,12 +231,12 @@ class WarehouseArticleController extends TTCrud {
// Check if ArticleDistributor exists
$articleDistributor = WarehouseArticleDistributorModel::getAll(['articleId' => $articleId,
'distributorId' => $distributorId]);
'distributorId' => $distributorId]);
if (empty($articleDistributor)) {
WarehouseArticleDistributorModel::create(['articleId' => $articleId,
'distributorId' => $distributorId,
'purchasePrice' => $purchasePrice,
'externalArticleNumber' => $item['Lieferant/ Hersteller Artikelnr:'],]);
'distributorId' => $distributorId,
'purchasePrice' => $purchasePrice,
'externalArticleNumber' => $item['Lieferant/ Hersteller Artikelnr:'],]);
}
}

View File

@@ -20,25 +20,33 @@ class WarehouseArticleDistributorController extends TTCrud {
'delete' => 'Lieferanteintrag wurde gelöscht',
'noChanges' => 'Keine Änderungen',];
protected function checkExistingDistributorEntry($postData): bool {
$count = WarehouseArticleDistributorModel::count(['articleId' => $postData['articleId'],
'distributorId' => $postData['distributorId']]);
if ($count > 0) {
self::returnJson(['success' => false,
'message' => 'Es existiert bereits ein Eintrag mit dieser Artikelnummer und diesem Lieferanten.']);
return false;
}
return true;
}
protected function beforeCreate($postData): bool {
return $this->checkExistingDistributorEntry($postData);
}
protected function checkExistingDistributorEntry($postData): bool {
if (isset($postData['id'])) {
$count = WarehouseArticleDistributorModel::count(['articleId' => $postData['articleId'],
'distributorId' => $postData['articlePriceTypeId'],
'id' => $postData['id']]);
if ($count > 0) return true;
} else {
$count = WarehouseArticleDistributorModel::count(['articleId' => $postData['articleId'],
'distributorId' => $postData['distributorId']]);
if ($count > 0) {
self::returnJson(['success' => false,
'message' => 'Es existiert bereits ein Eintrag mit dieser Artikelnummer und diesem Lieferanten.']);
return false;
}
}
return true;
}
protected function afterCreate($postData) {
WarehouseArticleController::updateCheapestPurchasePrice($postData['articleId']);
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
protected function beforeUpdate($postData): bool {
@@ -55,6 +63,7 @@ class WarehouseArticleDistributorController extends TTCrud {
protected function afterUpdate($postData) {
WarehouseArticleController::updateCheapestPurchasePrice($postData['articleId']);
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
protected function getHistoryAction() {

View File

@@ -22,6 +22,7 @@ class WarehouseArticlePriceController extends TTCrud {
return $this->validate($postData);
}
//TODO: phpdoc and simplify
protected function validate($postData): bool {
// if either priceOverride or priceMultiplier is empty set it to null
if (isset($postData['priceOverride']) && $postData['priceOverride'] === '') {
@@ -42,11 +43,11 @@ class WarehouseArticlePriceController extends TTCrud {
return false;
}
if (isset($postData['id'])) {
$count = WarehouseArticlePriceModel::count(['articleId' => $postData['articleId'],
'articlePriceTypeId' => $postData['articlePriceTypeId'],
'id' => $postData['id']]);
if ($count > 0) return true;
} else {
$count = WarehouseArticlePriceModel::count(['articleId' => $postData['articleId'],
@@ -86,4 +87,12 @@ class WarehouseArticlePriceController extends TTCrud {
self::returnJson($history);
}
public function afterCreate($postData) {
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
public function afterUpdate($postData) {
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
}

View File

@@ -51,13 +51,12 @@ class WarehouseArticlePriceTypeController extends TTCrud {
return true;
}
protected function afterUpdate($postData) {
WarehouseArticleController::updateCheapestPurchasePrice($postData['articleId']);
public function afterCreate($postData) {
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
protected function afterCreate($postData) {
//TODO: fix this
WarehouseArticleController::updateCheapestPurchasePrice($postData['articleId']);
public function afterUpdate($postData) {
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
protected function getHistoryAction() {

View File

@@ -123,7 +123,7 @@ class TTCrud extends mfBaseController {
$id = $this->model::create($this->postData);
if (method_exists($this, 'afterCreate')) {
$this->afterCreate($this->postData);
$this->afterCreate(array_merge($this->postData, ['id' => $id]));
}
self::returnJson(['success' => true,

View File

@@ -37,7 +37,7 @@ Vue.component('warehouse-distributor-modal', {
this.rows = response.data.rows
}, addRow() {
this.rows.push({distributor: null, price: null, externalArticleNumber: null});
this.rows.push({distributorId: undefined, price: null, externalArticleNumber: null});
}, async saveRow(index) {
// post to /WarehouseArticleDistributor/save with rows data and articleId
const row = this.rows[index];

View File

@@ -25,7 +25,12 @@ Vue.component('tt-autocomplete', {
<ul v-show="showSuggestions && displayValue.length > 0 || isLoading"
class="dropdown-menu show dropdown-shadow">
<div v-show="isLoading" class="loader"></div>
<li class="dropdown-item" v-show="isLoading">
<div class="spinner-border spinner-border-sm text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
Einträge werden geladen...
</li>
<template v-show="showSuggestions && displayingItems.length > 0 && isLoading !== true">
<li
@@ -73,6 +78,7 @@ Vue.component('tt-autocomplete', {
const selectedItem = this.items.find(item => item.value === this.value);
this.displayValue = selectedItem ? selectedItem.text : '';
} else {
this.$emit('input', '');
this.displayValue = '';
}
@@ -98,8 +104,12 @@ Vue.component('tt-autocomplete', {
},
methods: {
onInput(event) {
console.log('input', event.target.value);
this.displayValue = event.target.value;
console.log('displayValue', this.displayValue);
this.$emit('input', '');
console.log('value', this.value);
console.log('displayValue', this.displayValue);
this.fetchSuggestions();
},
onFocus() {

View File

@@ -253,7 +253,7 @@ Vue.component('tt-table', {
<i class="fas fa-filter"></i>
Filter zurücksetzen
</button>
<button v-if="!excelExport" title="EXCEL Export" @click="exportToExcel" class="btn btn-outline-success">
<button v-if="excelExport" title="EXCEL Export" @click="exportToExcel" class="btn btn-outline-success">
<i class="fa fa-file-excel" style="color: var(--success)"></i>
Excel Export
</button>