fixed some price handling aswell as tt-autocomplete and tt-table excel export always showing
This commit is contained in:
@@ -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:'],]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user