Merge branch 'Warehouse/improve2' into 'master'

new update

See merge request fronk/thetool!1252
This commit is contained in:
Luca Haid
2025-04-24 11:39:43 +00:00
22 changed files with 992 additions and 337 deletions
@@ -10,22 +10,20 @@ class WarehouseArticleController extends TTCrud {
['key' => 'title', 'text' => 'Titel', 'required' => true, 'table' => ['priority' => 9]],
['key' => 'articleNumber', 'text' => 'Nr.', 'required' => true],
['key' => 'description', 'text' => 'Beschreibung', 'required' => true],
['key' => 'category', 'text' => 'Kategorie', 'required' => true],
['key' => 'unit', 'text' => 'Einheit', 'required' => true,'table' => false], // Boolean value
['key' => 'revenueAccount', 'text' => 'Erlöskonto', 'required' => true,'modal' =>
['type' => 'select', 'items' => [['value' => 0, 'text' => 'Dienstleistungen'], ['value' => 1, 'text' => 'Handelswaren']]
], 'table' => false], // Boolean value
['key' => 'category_id', 'text' => 'Kategorie', 'required' => true, 'modal' => ['type' => 'select', 'items' => []], 'table' => ['filter' => 'select']],
['key' => 'unit', 'text' => 'Einheit', 'required' => true,'table' => false],
['key' => 'revenueAccount', 'text' => 'Erlöskonto', 'required' => true,'modal' => ['type' => 'select', 'items' => [['value' => 0, 'text' => 'Dienstleistungen'], ['value' => 1, 'text' => 'Handelswaren']]], 'table' => false],
['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' => false], // Stock/inventory related
['key' => 'criticalAmount', 'text' => 'Kritische Menge', 'required' => true,'modal' => ['type' => 'number'], 'table' => false], // Stock/inventory related
['key' => 'isSerialDocumentation', 'text' => 'Seriennummern', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false], // Boolean value
['key' => 'isEShop', 'text' => 'Ist E-Shop', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false], // Boolean value
['key' => 'isEShopHide', 'text' => 'E-Shop Versteckt', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false], // Boolean value
['key' => 'warningAmount', 'text' => 'Warnmenge', 'required' => true,'modal' => ['type' => 'number'], 'table' => false],
['key' => 'criticalAmount', 'text' => 'Kritische Menge', 'required' => true,'modal' => ['type' => 'number'], 'table' => false],
['key' => 'isSerialDocumentation', 'text' => 'Seriennummern', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false],
['key' => 'isEShop', 'text' => 'Ist E-Shop', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false],
['key' => 'isEShopHide', 'text' => 'E-Shop Versteckt', 'required' => false,'modal' => ['type' => 'checkbox'], 'table' => false],
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 8]]
];
protected array $autocompleteColumns = ['articleNumber', 'title', 'description', 'category'];
protected array $autocompleteColumns = ['articleNumber', 'title', 'description'];
protected array $additionalActions = [['key' => 'openHistory','title' => 'Historie','class' => 'fas fa-history text-secondary']];
// @formatter:on
@@ -33,8 +31,12 @@ class WarehouseArticleController extends TTCrud {
protected array $additionalJSVariables = ['WAREHOUSE_ADMIN' => true];
protected function prepareCrudConfig() {
$categories = array_map(fn($category) => ['value' => $category->id, 'text' => $category->name], WarehouseCategory::getAll());
$this->columns[array_search('category_id', array_column($this->columns, 'key'))]['modal']['items'] = $categories;
if ($this->user->can('WarehouseAdmin')) return;
array_walk($this->columns, fn(&$col) => in_array($col['key'], ['actions', 'cheapestPurchasePrice', 'warningAmount', 'criticalAmount']) && $col['table'] = false);
$this->createText = false;
@@ -5,7 +5,7 @@ class WarehouseArticleModel extends TTCrudBaseModel {
public string $title;
public string $articleNumber;
public string $description;
public string $category;
public ?int $category_id;
public ?float $cheapestPurchasePrice;
public ?string $cheapestSellPrice;
public int $warningAmount;
@@ -95,4 +95,8 @@ class WarehouseArticlePriceController extends TTCrud {
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
public function afterDelete($postData) {
WarehouseArticleController::updateSellPrices($postData['articleId']);
}
}
@@ -0,0 +1,23 @@
<?php
class WarehouseCategory extends TTCrudBaseModel {
public int $id;
public string $name;
public string $description;
public int $create;
public int $create_by;
public ?int $edit;
public ?int $edit_by;
}
// SQL:
// CREATE TABLE `WarehouseCategory` (
// `id` INT NOT NULL AUTO_INCREMENT,
// `name` VARCHAR(255) NOT NULL,
// `description` TEXT NOT NULL,
// `create` INT NOT NULL,
// `create_by` INT NOT NULL,
// `edit` INT DEFAULT NULL,
// `edit_by` INT DEFAULT NULL,
// PRIMARY KEY (`id`)
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
@@ -0,0 +1,30 @@
<?php
class WarehouseCategoryController extends TTCrud {
protected string $headerTitle = 'Kategorien';
protected string $createText = 'Kategorie erstellen';
protected string $singleText = 'Kategorie';
// @formatter:off
protected array $columns = [
['key' => 'title', 'text' => 'Titel', 'required' => true,],
['key' => 'description', 'text' => 'Beschreibung', 'required' => true],
['key' => 'create', 'text' => 'Erstellt am', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
['key' => 'create_by', 'text' => 'Erstellt von', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
['key' => 'edit', 'text' => 'Bearbeitet am', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
['key' => 'edit_by', 'text' => 'Bearbeitet von', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 10]],
];
// @formatter:on
protected array $additionalActions = [['key' => 'openHistory', 'title' => 'Historie', 'class' => 'fas fa-history text-primary']];
protected function beforeUpdate($postData): bool {
(new WarehouseHistoryController)->create($postData, $this->mod);
return true;
}
protected function getHistoryAction() {
self::returnJson((new WarehouseHistoryController)->getHistory($this->request->id, $this->mod, $this->columns));
}
}
@@ -23,15 +23,16 @@ class WarehouseOfferController extends TTCrud {
'modal' => false,
'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
];
protected array $additionalJSVariables = ['WAREHOUSE_ADMIN' => true];
protected array $permissionCheck = ['WarehouseAdmin'];
protected array $additionalActions = [['key' => 'openHistory', 'title' => 'Historie', 'class' => 'fas fa-history text-primary']];
protected array $additionalActions = [['key' => 'openpdf', 'title' => 'PDF öffnen', 'class' => 'fas fa-file-pdf', 'color' => 'primary']];
protected function prepareCrudConfig(): void {
$editorColumnIndex = array_search('editor', array_column($this->columns, 'key'));
$this->columns[$editorColumnIndex]['modal']['items'] = array_map(function ($user) {
return ['value' => intval($user->id), 'text' => $user->name];
}, UserModel::search(['employee' => true]));
if (!$this->user->can('WarehouseAdmin')) $this->additionalJSVariables['WAREHOUSE_ADMIN'] = false;
}
protected function beforeCreate(): bool {
@@ -52,6 +53,7 @@ class WarehouseOfferController extends TTCrud {
}
protected function createTemplateAction() {
if (!$this->user->can('WarehouseAdmin')) self::sendError("Keine Berechtigung");
$_POST = json_decode(file_get_contents('php://input'), true);
$templateId = WarehouseOfferTemplateModel::create([
@@ -67,7 +69,68 @@ class WarehouseOfferController extends TTCrud {
self::returnJson(['success' => true, 'id' => $templateId]);
}
protected function deleteTemplateAction() {
if (!$this->user->can('WarehouseAdmin')) self::sendError("Keine Berechtigung");
WarehouseOfferTemplateModel::delete($this->request->id);
self::returnJson(['success' => true]);
}
protected function getTemplatesAction() {
self::returnJson(WarehouseOfferTemplateModel::getAll());
}
public function createPDFAction($returnFilename = false, $idOverride = null) {
//display errors
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$id = $idOverride ?? $this->request->id;
if (strlen($id) < 1) self::sendError('ID fehlt');
$offer = WarehouseOfferModel::get($id);
if (!$offer->id) self::sendError('Angebot nicht gefunden');
$positions = json_decode($offer->positions, true);
$entries = [];
foreach ($positions as $position) {
if (!isset($position['article'])) continue;
$article = WarehouseArticleModel::get($position['article']);
$position['articleText'] = WarehouseArticleModel::get($position['article'])->title;
$position['articleDescription'] = $article->description === $article->title ? "" : $article->description;
$position['articleUnit'] = $position['unit'] ?? $article->unit ?? 'Stk.';
if (isset($position['_group'])) {
$entries[$position['_group']][] = $position;
} else {
$entries[''][] = $position;
}
}
$pdf_vars = [
"offer" => $offer,
"entries" => $entries,
"bank_iban" => TT_INVOICE_BANK_IBAN,
"bank_bic" => TT_INVOICE_BANK_BIC,
"bank_bank" => TT_INVOICE_BANK_BANK,
"bank_owner" => TT_INVOICE_BANK_OWNER
];
$headerHtml = file_get_contents(BASEDIR . "/Layout/default/WarehouseOffer/PDF_HEADER.html");
$headerHtml = str_replace("{{ addressLine_header }}",
// {{ addressLine_1 }} {{ addressLine_2 }} {{ addressLine_3 }} {{ addressLine_4 }} {{ externalReference }}
$headerHtml = str_replace("{{ addressLine_1 }}", $offer->customerName, $headerHtml));
$headerHtml = str_replace("{{ addressLine_2 }}", $offer->customerStreet, $headerHtml);
$headerHtml = str_replace("{{ addressLine_3 }}", $offer->customerZip . ' ' . $offer->customerCity, $headerHtml);
$headerHtml = str_replace("{{ addressLine_5 }}", $offer->customerVAT, $headerHtml);
$headerHtml = str_replace("{{ externalReference }}", $offer->customerReference, $headerHtml);
exit;
}
}
@@ -5,6 +5,7 @@
*
* Represents a warehouse offer template with key details.
*
* @property int $id Unique identifier for the template
* @property string $templateName Name of the template
* @property string $positions Details about positions in the offer
* @property float $totalDiscount Total discount applied to the offer
@@ -15,6 +16,7 @@
*/
class WarehouseOfferTemplateModel extends TTCrudBaseModel
{
public int $id;
public string $templateName;
public string $positions;
public float $totalDiscount;
@@ -529,9 +529,6 @@ class WarehouseShippingNoteController extends TTCrud {
return $distance * 2;
}
$fromData = geocode($from);
$toData = geocode($to);
$distance = route($from, $to);
$roundedDistanceKm = round($distance / 1000, 0);
@@ -1,9 +0,0 @@
<?php
/**
* @property mixed|null $name
*/
class WarehouseShippingNoteTextElement extends mfBaseModel
{
}
@@ -1,48 +0,0 @@
<?php
class WarehouseShippingNoteTextElementController extends TTCrud {
protected string $headerTitle = 'Lieferschein Textelemente';
protected string $createText = 'Lieferschein Textelement erstellen';
// @formatter:off
protected array $columns = [
['key' => 'title', 'text' => 'Titel', 'required' => true],
['key' => 'content', 'text' => 'Text', 'required' => true, 'modal' => []],
['key' => 'create', 'text' => 'Erstellt', 'required' => false, 'modal' => false, 'table' => ['filter' => 'datetime', 'class' => 'text-nowrap']],
['key' => 'createBy', 'text' => 'Erstellt von', 'required' => false, 'modal' => [
'type' => 'select', 'items' => [],'visible' => false], ],
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 10]],
];
// @formatter:on
protected array $infoMessages = ['create' => 'Lieferschein Textelement wurde erstellt',
'update' => 'Lieferschein Textelement wurde aktualisiert',
'delete' => 'Lieferschein Textelement wurde gelöscht',
'noChanges' => 'Keine Änderungen'];
protected function prepareCrudConfig() {
// add all users to createBy column
$this->columns[array_search('createBy', array_column($this->columns, 'key'))]['modal']['items'] = array_map(function ($user) {
return ['value' => $user->id, 'text' => $user->name];
}, UserModel::getAll());
}
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);
}
}
@@ -1,10 +0,0 @@
<?php
class WarehouseShippingNoteTextElementModel extends TTCrudBaseModel {
public int $id;
public string $title;
public string $content;
public int $create;
public int $createBy;
}