Merge branch 'feature/update-warehouse' into 'master'
update for warehouse See merge request fronk/thetool!654
This commit is contained in:
@@ -534,6 +534,7 @@ class AddressController extends mfBaseController {
|
||||
];
|
||||
$results[] = $result;
|
||||
$this->returnJson($results);
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class WarehouseAdministration extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
class WarehouseAdministrationController extends mfBaseController {
|
||||
private User $me;
|
||||
|
||||
protected function init(): void {
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
$this->layout()->set("me", $me);
|
||||
$this->me = $me;
|
||||
|
||||
if (!$this->me->isAdmin()) {
|
||||
$this->redirect("dashboard");
|
||||
}
|
||||
}
|
||||
|
||||
protected function indexAction(): void {
|
||||
$this->layout()->set('additionalJS', ['js/pages/WarehouseHistory/WarehouseHistoryModal.js']);
|
||||
|
||||
Helper::renderVue($this, 'WarehouseAdministration', 'Administration-Tools', ["CREATE_URL" => $this::getUrl($this->mod . "/create"),
|
||||
"TABLE_URL" => $this::getUrl($this->mod . "/get"),
|
||||
"UPDATE_URL" => $this::getUrl($this->mod . "/update"),
|
||||
"DELETE_URL" => $this::getUrl($this->mod . "/delete"),]);
|
||||
}
|
||||
|
||||
//TODO: this needs improvement as it is inefficient but it doesnt matter as it doesnt get called very often
|
||||
// and also maybe we should move it to WarehouseLocationController
|
||||
protected function createLocationsAction(): void {
|
||||
$existingLocations = WarehouseLocationModel::getAll();
|
||||
$companyCars = TimerecordingCarModel::getAll();
|
||||
|
||||
|
||||
$wantedCarLocations = [];
|
||||
foreach ($companyCars as $car) {
|
||||
// check if $car->brand includes "Anhänger" or "Anhaenger", if yes then continue
|
||||
if (strpos($car->brand, "Anhänger") !== false || strpos($car->brand, "Anhaenger") !== false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$carModelParts = explode(" ", $car->model);
|
||||
if (count($carModelParts) > 1) {
|
||||
$wantedCarLocations[] = "{$car->number_plate} {$car->brand} {$carModelParts[0]} {$carModelParts[1]}";
|
||||
} else {
|
||||
$wantedCarLocations[] = "{$car->number_plate} {$car->brand} {$carModelParts[0]}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// create a warehouse location for each wantedcar but check if $existingLocations[]->title already exists with the same title
|
||||
foreach ($wantedCarLocations as $wantedCarLocation) {
|
||||
$locationExists = false;
|
||||
foreach ($existingLocations as $existingLocation) {
|
||||
if ($existingLocation->title === $wantedCarLocation) {
|
||||
$locationExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$locationExists) {
|
||||
$numberPlate = explode(" ", $wantedCarLocation)[0];
|
||||
$assignedTo = 1;
|
||||
foreach ($companyCars as $car) {
|
||||
if ($car->number_plate === $numberPlate) {
|
||||
$assignedTo = $car->user_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($assignedTo === null) {
|
||||
$assignedTo = 6;
|
||||
}
|
||||
|
||||
WarehouseLocationModel::create([
|
||||
"title" => $wantedCarLocation,
|
||||
"description" => "Automatisch erstellt",
|
||||
"assignedTo" => $assignedTo,
|
||||
"createdBy" => $this->me->id,
|
||||
"create" => time()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$existingLocations = WarehouseLocationModel::getAll();
|
||||
$users = UserModel::search(['employee' => true]);
|
||||
|
||||
// now create a warehouse location for each user only if they dont already have one (for example if they have a company car)
|
||||
foreach ($users as $user) {
|
||||
$locationExists = false;
|
||||
foreach ($existingLocations as $existingLocation) {
|
||||
if (intval($existingLocation->assignedTo) === intval($user->id)) {
|
||||
$locationExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$locationExists) {
|
||||
WarehouseLocationModel::create([
|
||||
"title" => $user->name . "'s Lagerort",
|
||||
"description" => "Automatisch erstellt",
|
||||
"assignedTo" => $user->id,
|
||||
"createdBy" => $this->me->id,
|
||||
"create" => time()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
var_dump($existingLocations);
|
||||
die();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,12 @@ class WarehouseArticleController extends TTCrud {
|
||||
// @formatter:off
|
||||
protected array $columns = [
|
||||
['key' => 'title', 'text' => 'Titel', 'required' => true, 'table' => ['priority' => 9]],
|
||||
['key' => 'description', 'text' => 'Beschreibung', 'required' => true, 'table' => false],
|
||||
['key' => 'description', 'text' => 'Beschreibung', 'required' => true],
|
||||
['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' => 'select'], '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' => '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
|
||||
@@ -27,6 +28,7 @@ class WarehouseArticleController extends TTCrud {
|
||||
['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'],
|
||||
['key' => 'addToCart','title' => 'Zur Bestellung hinzufügen','class' => 'fas fa-shopping-cart text-primary'],
|
||||
];
|
||||
// @formatter:on
|
||||
|
||||
@@ -35,15 +37,6 @@ 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;
|
||||
@@ -77,6 +70,11 @@ class WarehouseArticleController extends TTCrud {
|
||||
WarehouseArticleModel::update(array_merge(get_object_vars($article), ['cheapestPurchasePrice' => $cheapestPurchasePrice]));
|
||||
}
|
||||
|
||||
protected function afterCreate($postData) {
|
||||
self::updateCheapestPurchasePrice($postData['id']);
|
||||
self::updateSellPrices($postData['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the sell prices for a given article.
|
||||
*
|
||||
@@ -96,33 +94,31 @@ class WarehouseArticleController extends TTCrud {
|
||||
$cheapestSellPrices = [];
|
||||
// Calculate sell prices for each price type, use default sell multiplier if no specific price is set
|
||||
foreach ($priceTypes as $priceType) {
|
||||
$articlePriceType = array_filter($articlePriceTypes, function ($apt) use ($priceType) {
|
||||
return $apt->articlePriceTypeId == $priceType->id;
|
||||
});
|
||||
$articlePriceType = null;
|
||||
foreach ($articlePriceTypes as $apt) {
|
||||
if ($apt->articlePriceTypeId == $priceType->id) {
|
||||
$articlePriceType = $apt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$sellPrice = $article->defaultSellMultiplier * $article->cheapestPurchasePrice;
|
||||
if (!empty($articlePriceType)) {
|
||||
$articlePriceType = $articlePriceType[0];
|
||||
$sellPrice = $priceType->defaultPriceFactor * $article->cheapestPurchasePrice;
|
||||
if ($articlePriceType !== null) {
|
||||
$sellPrice = $articlePriceType->priceOverride ?: $articlePriceType->priceMultiplier * $article->cheapestPurchasePrice;
|
||||
}
|
||||
$cheapestSellPrices[$priceType->id] = ['title' => $priceType->title, 'price' => $sellPrice];
|
||||
$cheapestSellPrices[$priceType->id] = ['title' => $priceType->title, 'price' => round($sellPrice, 2)];
|
||||
}
|
||||
|
||||
$article->cheapestSellPrice = json_encode($cheapestSellPrices);
|
||||
WarehouseArticleModel::update(get_object_vars($article));
|
||||
}
|
||||
|
||||
|
||||
protected function afterCreate($postData) {
|
||||
self::updateCheapestPurchasePrice($postData['id']);
|
||||
self::updateSellPrices($postData['id']);
|
||||
}
|
||||
|
||||
protected function updatePricesAction() {
|
||||
public function updatePricesAction() {
|
||||
foreach (WarehouseArticleModel::getAll() as $article) {
|
||||
self::updateCheapestPurchasePrice($article->id);
|
||||
self::updateSellPrices($article->id);
|
||||
}
|
||||
self::returnJson(['success' => true, 'message' => 'Preise wurden aktualisiert']);
|
||||
}
|
||||
|
||||
protected function getHistoryAction() {
|
||||
@@ -241,4 +237,52 @@ class WarehouseArticleController extends TTCrud {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareOrderAction() {
|
||||
// inside post json it will look like
|
||||
// [
|
||||
// {
|
||||
// "amount": "5",
|
||||
// "itemId": 441,
|
||||
// "title": "RT-FB-7590AX"
|
||||
// },
|
||||
// {
|
||||
// "amount": "5",
|
||||
// "itemId": 421,
|
||||
// "title": "RT-FB-7590"
|
||||
// }
|
||||
//]
|
||||
// get the json from the post request
|
||||
// then create a array containing each order we need to make, so search through WarehouseArticleDistributorModel to get the distributorId and purchasePrice (use lowest purchasePrice)
|
||||
// then get the WarehouseDistributorModel and then create a summary of the orders we need to make for each distributor
|
||||
|
||||
$postData = json_decode(file_get_contents('php://input'), true);
|
||||
$orders = [];
|
||||
foreach ($postData as $order) {
|
||||
$articleDistributors = WarehouseArticleDistributorModel::getAll(['articleId' => $order['itemId']]);
|
||||
$cheapestArticleDistributor = $articleDistributors[0];
|
||||
foreach ($articleDistributors as $articleDistributor) {
|
||||
if ($articleDistributor->purchasePrice < $cheapestArticleDistributor->purchasePrice) {
|
||||
$cheapestArticleDistributor = $articleDistributor;
|
||||
}
|
||||
}
|
||||
$distributor = WarehouseDistributorModel::get($cheapestArticleDistributor->distributorId);
|
||||
|
||||
if (!isset($orders[$distributor->id])) {
|
||||
$orders[$distributor->id] = ['distributor' => array($distributor),
|
||||
'orderAmount' => 0,
|
||||
'orders' => []];
|
||||
}
|
||||
|
||||
$orders[$distributor->id]['orders'][] = ['articleId' => $order['itemId'],
|
||||
'amount' => $order['amount'],
|
||||
'sum' => $order['amount'] * $cheapestArticleDistributor->purchasePrice,
|
||||
'purchasePrice' => $cheapestArticleDistributor->purchasePrice,
|
||||
'externalArticleNumber' => $cheapestArticleDistributor->externalArticleNumber,
|
||||
'title' => $order['title'],];
|
||||
$orders[$distributor->id]['orderAmount'] += $order['amount'] * $cheapestArticleDistributor->purchasePrice;
|
||||
}
|
||||
|
||||
self::returnJson($orders);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ class WarehouseArticleModel extends TTCrudBaseModel {
|
||||
public int $criticalAmount;
|
||||
public int $isEShop;
|
||||
public int $isEShopHide;
|
||||
public float $defaultSellMultiplier;
|
||||
public string $unit;
|
||||
public int $isSerialDocumentation;
|
||||
public int $revenueAccount;
|
||||
|
||||
@@ -7,6 +7,11 @@ class WarehouseArticlePriceTypeController extends TTCrud {
|
||||
// @formatter:off
|
||||
protected array $columns = [
|
||||
['key' => 'title', 'text' => 'Titel', 'required' => true],
|
||||
['key' => 'description', 'text' => 'Beschreibung', 'required' => false],
|
||||
['key' => 'defaultPriceFactor', 'text' => 'Standard Preisfaktor', 'required' => true, 'modal' => ['type' => 'number']],
|
||||
['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' => [], 'table' => ['class' => 'text-nowrap']], 'visible' => false],
|
||||
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center', 'priority' => 10]],
|
||||
];
|
||||
// @formatter:on
|
||||
@@ -16,47 +21,30 @@ class WarehouseArticlePriceTypeController extends TTCrud {
|
||||
'delete' => 'Artikel Verkaufspreis wurde gelöscht',
|
||||
'noChanges' => 'Keine Änderungen'];
|
||||
|
||||
protected function checkExistingDistributorEntry($postData): bool {
|
||||
// if postData id exists check if there is already an entry with the same articleId and locationId if postdata id and WarehouseLocationThresholdOverrideModel id are different return false
|
||||
if (isset($postData['id'])) {
|
||||
$count = WarehouseArticlePriceTypeModel::count(['title' => $postData['title'], 'id' => $postData['id']]);
|
||||
if ($count > 0) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
$count = WarehouseArticlePriceTypeModel::count(['title' => $postData['title']]);
|
||||
if ($count > 0) {
|
||||
self::returnJson(['success' => false,
|
||||
'message' => 'Es existiert bereits ein Preis Typ mit diesem Titel.']);
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function beforeCreate($postData): bool {
|
||||
return $this->checkExistingDistributorEntry($postData);
|
||||
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 {
|
||||
$existing = $this->checkExistingDistributorEntry($postData);
|
||||
|
||||
if (!$existing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(new WarehouseHistoryController)->create($postData, $this->mod);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function afterCreate($postData) {
|
||||
WarehouseArticleController::updateSellPrices($postData['articleId']);
|
||||
protected function afterUpdate($postData) {
|
||||
$WarehouseArticleController = new WarehouseArticleController;
|
||||
// set mod of WarehouseArticleController to WarehouseArticle
|
||||
$WarehouseArticleController->mod = 'WarehouseArticle';
|
||||
$WarehouseArticleController->updatePricesAction();
|
||||
}
|
||||
|
||||
public function afterUpdate($postData) {
|
||||
WarehouseArticleController::updateSellPrices($postData['articleId']);
|
||||
protected function afterCreate($postData) {
|
||||
$WarehouseArticleController = new WarehouseArticleController;
|
||||
// set mod of WarehouseArticleController to WarehouseArticle
|
||||
$WarehouseArticleController->mod = 'WarehouseArticle';
|
||||
$WarehouseArticleController->updatePricesAction();
|
||||
}
|
||||
|
||||
protected function getHistoryAction() {
|
||||
|
||||
@@ -3,4 +3,8 @@
|
||||
class WarehouseArticlePriceTypeModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public string $title;
|
||||
public ?string $description;
|
||||
public float $defaultPriceFactor;
|
||||
public int $create;
|
||||
public int $createBy;
|
||||
}
|
||||
@@ -153,6 +153,7 @@ class WarehouseEShopOrderController extends TTCrud {
|
||||
}
|
||||
// if it is still null, die with order id:
|
||||
if ($realOrderItems === null) {
|
||||
continue;
|
||||
self::returnJson(['success' => false, 'message' => 'Bestellung mit ID ' . $order['id'] . ' hat keine Artikel. Bitte überprüfen.']);
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
* @property int $orderId
|
||||
* @property int $articleId
|
||||
* @property int $quantity
|
||||
* @property int $price
|
||||
*/
|
||||
|
||||
class WarehouseEShopOrderItemModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public int $orderId;
|
||||
public ?int $articleId;
|
||||
public ?int $articlePacketId;
|
||||
public int $quantity;
|
||||
public ?int $articlePacketId;
|
||||
}
|
||||
@@ -9,6 +9,12 @@ class WarehouseHistoryController {
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
|
||||
foreach ($postData as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$postData[$key] = json_encode($value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_diff_assoc($postData, (array) $currentData) as $key => $value) {
|
||||
WarehouseHistoryModel::create(['table' => $mod,
|
||||
'row_id' => $postData['id'],
|
||||
|
||||
@@ -4,14 +4,25 @@ class WarehouseItemController extends TTCrud {
|
||||
protected string $headerTitle = 'Eintrag';
|
||||
protected string $createText = 'Eintrag erstellen';
|
||||
|
||||
// TODO: change articleId and warehouseLocationId to autocomplete
|
||||
// TODO: check if historyController is needed
|
||||
// TODO: check if apiUrl uses self::getUrl to get the correct URL
|
||||
|
||||
// @formatter:off
|
||||
protected array $columns = [
|
||||
['key' => 'articleId', 'text' => 'Artikel', 'required' => true, 'type' => 'select','table' => ['class' => 'text-nowrap'], 'modal' => ['items' => [], 'type' => 'select']],
|
||||
['key' => 'warehouseLocationId', 'text' => 'Lagerort', 'required' => true, 'type' => 'select', 'modal' => ['items' => [], 'type' => 'select']],
|
||||
['key' => 'quantity', 'text' => 'Menge', 'required' => true, 'type' => 'number'],
|
||||
['key' => 'serialNumber', 'text' => 'Seriennummer', 'required' => false],
|
||||
['key' => 'articleId', 'text' => 'Artikel', 'required' => true, 'type' => 'autocomplete','table' => ['class' => 'text-nowrap', 'filter' => 'autocomplete'],'modal' => [
|
||||
'apiUrl' => 'WarehouseArticle/autocomplete','items' => 'WarehouseArticle/autocomplete', 'type' => 'autocomplete']],
|
||||
['key' => 'warehouseLocationId', 'text' => 'Lagerort', 'required' => true, 'type' => 'autocomplete', 'table' => ['filter' => 'autocomplete'], 'modal' => [
|
||||
'items' => 'WarehouseLocation/autocomplete',
|
||||
'apiUrl' => 'WarehouseLocation/autocomplete', 'type' => 'autocomplete']],
|
||||
['key' => 'quantity', 'text' => 'Menge', 'required' => false, 'type' => 'number'
|
||||
// quantity is only visible in modal when warehouseArticle(articleId).serial is false, add modal config here to reference warehouseArticle
|
||||
, 'modal' => ['type' => 'number',
|
||||
'visible' => ['reference' => 'WarehouseArticle', 'use' => 'articleId=id', 'key' => 'isSerialDocumentation', 'value' => false]
|
||||
]
|
||||
],
|
||||
['key' => 'rack', 'text' => 'Regal', 'required' => false, 'modal' => ['type' => 'text']],
|
||||
['key' => 'shelf', 'text' => 'Fach', 'required' => false, 'modal' => ['type' => 'text'], 'table' => false],
|
||||
['key' => 'serialNumber', 'text' => 'Seriennummer', 'required' => false, 'modal' => ['type' => 'text', 'visible' => ['reference' => 'WarehouseArticle', 'use' => 'articleId=id', 'key' => 'isSerialDocumentation', 'value' => true]]],
|
||||
['key' => 'note', 'text' => 'Notiz', 'required' => false],
|
||||
['key' => 'actions', 'text' => 'Aktionen', 'table' => ['filter' => false], 'required' => false, 'modal' => false]
|
||||
];
|
||||
@@ -58,18 +69,6 @@ class WarehouseItemController extends TTCrud {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function prepareCrudConfig() {
|
||||
$articles = array_map(function($article) {
|
||||
return ['value' => $article->id, 'text' => $article->title];
|
||||
}, WarehouseArticleModel::getAll());
|
||||
$this->columns[0]['modal']['items'] = $articles;
|
||||
|
||||
$locations = array_map(function($location) {
|
||||
return ['value' => $location->id, 'text' => $location->title];
|
||||
}, WarehouseLocationModel::getAll());
|
||||
$this->columns[1]['modal']['items'] = $locations;
|
||||
}
|
||||
|
||||
protected function getHistoryAction() {
|
||||
self::returnJson((new WarehouseHistoryController)->getHistory($this->request->id, $this->mod, $this->columns));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ class WarehouseItemModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public int $articleId;
|
||||
public int $warehouseLocationId;
|
||||
public int $quantity;
|
||||
public ?string $rack;
|
||||
public ?string $shelf;
|
||||
public ?int $quantity;
|
||||
public ?string $serialNumber;
|
||||
public ?string $note;
|
||||
}
|
||||
@@ -6,7 +6,9 @@ class WarehouseLocationController extends TTCrud {
|
||||
|
||||
protected array $columns = [
|
||||
['key' => 'title', 'text' => 'Titel', 'required' => true],
|
||||
['key' => 'assignedTo', 'text' => 'Zugewiesen an', 'required' => true, 'modal' => ['type' => 'select', 'items' => []]],
|
||||
['key' => 'assignedTo', 'text' => 'Zugewiesen an', 'required' => true,
|
||||
'table' => ['filter' => 'select', 'items' => []],
|
||||
'modal' => ['type' => 'select', 'items' => []]],
|
||||
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
|
||||
];
|
||||
|
||||
|
||||
@@ -3,5 +3,8 @@
|
||||
class WarehouseLocationModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public string $title;
|
||||
public string $description;
|
||||
public int $assignedTo;
|
||||
public int $createdBy;
|
||||
public int $create;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class WarehouseOrder extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
//TODO: enable switching distributors in the order preview
|
||||
|
||||
class WarehouseOrderController extends TTCrud {
|
||||
protected string $headerTitle = 'Lieferantenbestellungen';
|
||||
protected bool $createText = false;
|
||||
|
||||
protected array $columns = [
|
||||
['key' => 'id', 'text' => 'ID', 'modal' => false],
|
||||
['key' => 'distributorId', 'text' => 'Lieferant', 'required' => true, 'type' => 'autocomplete','table' => ['class' => 'text-nowrap', 'filter' => 'autocomplete'],'modal' => [
|
||||
'apiUrl' => 'WarehouseDistributor/autocomplete','items' => 'WarehouseDistributor/autocomplete', 'type' => 'autocomplete']],
|
||||
['key' => 'extRef', 'text' => 'Externe Referenz', 'required' => false],
|
||||
['key' => 'intRef', 'text' => 'Interne Referenz', 'required' => false],
|
||||
['key' => 'status', 'text' => 'Status', 'required' => true, 'modal' => ['type' => 'select', 'items' => [
|
||||
['value' => 'new', 'text' => 'Neu'],
|
||||
['value' => 'accepted', 'text' => 'An Lieferant übergeben'],
|
||||
['value' => 'sent', 'text' => 'Gesendet'],
|
||||
['value' => 'done', 'text' => 'Erledigt'],
|
||||
]]],
|
||||
['key' => 'trackingNumber', 'text' => 'Trackingnummer', 'required' => false],
|
||||
['key' => 'sum', 'text' => 'Summe', 'required' => true, 'modal' => false, 'table' => ['filter' => 'numberRange']],
|
||||
['key' => 'create', 'text' => 'Erstellt', 'required' => true, 'modal' => false, 'filter' => 'datetime'],
|
||||
['key' => 'createBy', 'text' => 'Erstellt von', 'required' => true, 'table' => ['filter' => 'select'], 'modal' => ['type' => 'select', 'items' => []]],
|
||||
['key' => 'actions', 'text' => 'Aktionen', 'required' => false, 'modal' => false, 'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],
|
||||
];
|
||||
|
||||
protected array $additionalActions = [['key' => 'openHistory', 'title' => 'Historie', 'class' => 'fas fa-history text-primary']];
|
||||
|
||||
protected array $infoMessages = ['create' => 'Bestellung wurde erfolgreich erstellt.',
|
||||
'update' => 'Bestellung wurde aktualisiert.',
|
||||
'delete' => 'Bestellung wurde gelöscht',
|
||||
'noChanges' => 'Keine Änderungen',];
|
||||
|
||||
public function permissionCheck(): bool {
|
||||
return $this->user->can(["WarehouseEShop"]);
|
||||
}
|
||||
|
||||
protected function prepareCrudConfig() {
|
||||
// Fill Users in createBy column
|
||||
$column = array_search('createBy', array_column($this->columns, 'key'));
|
||||
$this->columns[$column]['modal']['items'] = array_map(function ($user) {
|
||||
return ['value' => intval($user->id), 'text' => $user->name];
|
||||
}, UserModel::search());
|
||||
|
||||
}
|
||||
|
||||
protected function createOrderAction() {
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$json = json_decode(file_get_contents('php://input'), true);
|
||||
$orders = $json;
|
||||
$orderIds = [];
|
||||
|
||||
foreach ($orders as $order) {
|
||||
$distributor = $order['distributor'][0];
|
||||
$orderAmount = $order['orderAmount'];
|
||||
$orders = $order['orders'];
|
||||
|
||||
$order = [
|
||||
'distributorId' => $distributor['id'],
|
||||
'extRef' => null,
|
||||
'status' => 'new',
|
||||
'trackingNumber' => null,
|
||||
'sum' => $orderAmount,
|
||||
'create' => time(),
|
||||
'createBy' => $this->user->id,
|
||||
];
|
||||
|
||||
$orderId = WarehouseOrderModel::create($order);
|
||||
$orderIds[] = $orderId;
|
||||
|
||||
foreach ($orders as $orderItem) {
|
||||
$article = WarehouseArticleModel::get($orderItem['articleId']);
|
||||
|
||||
WarehouseEShopOrderItemModel::create([
|
||||
'orderId' => $orderId,
|
||||
'articleId' => $orderItem['articleId'],
|
||||
'quantity' => $orderItem['amount'],
|
||||
'price' => $article->cheapestPurchasePrice,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
self::returnJson(['success' => true, 'message' => $this->infoMessages['create'], 'ids' => $orderIds]);
|
||||
}
|
||||
|
||||
protected function getOrderItemsAction() {
|
||||
$orderItems = WarehouseEShopOrderItemModel::getAll(['orderId' => $this->request->id]);
|
||||
|
||||
// also get the article name of the order items
|
||||
|
||||
foreach ($orderItems as $key => $orderItem) {
|
||||
$article = WarehouseArticleModel::get($orderItem->articleId);
|
||||
$orderItem->articleName = $article->title;
|
||||
}
|
||||
|
||||
self::returnJson($orderItems);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
//TODO: fix phpdoc
|
||||
/**
|
||||
* @property int $id
|
||||
* @property 'new'|'accepted'|'sent'|'done' $status
|
||||
* @property 'singleAddress'|'multipleAddresses' $deliveryMode
|
||||
* @property string $deliveryAddressName
|
||||
* @property string $deliveryAddressLine
|
||||
* @property string $deliveryAddressPLZ
|
||||
* @property string $deliveryAddressCity
|
||||
* @property int $create
|
||||
* @property int $createBy
|
||||
*/
|
||||
|
||||
// id, distributorId, intRef, extRef, status, trackingNumber, create, createBy
|
||||
class WarehouseOrderModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public int $distributorId;
|
||||
public ?string $intRef;
|
||||
public ?string $extRef;
|
||||
public float $sum;
|
||||
public string $status;
|
||||
public ?string $trackingNumber;
|
||||
public int $create;
|
||||
public int $createBy;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class WarehouseOrderItem extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* @property int $id
|
||||
* @property int $orderId
|
||||
* @property int $articleId
|
||||
* @property int $quantity
|
||||
* @property int $price
|
||||
*/
|
||||
|
||||
class WarehouseOrderItemModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public int $orderId;
|
||||
public int $articleId;
|
||||
public int $quantity;
|
||||
public float $price;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class WarehouseRevenueAccount extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
<?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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
class WarehouseRevenueAccountModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public int $revenueAccountNumber;
|
||||
public string $title;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class WarehouseShippingNote extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
class WarehouseShippingNoteController extends TTCrud {
|
||||
protected string $headerTitle = 'Lieferscheine';
|
||||
protected bool $createText = false;
|
||||
|
||||
protected array $columns = [['key' => 'id', 'text' => 'LS-Nr.', 'required' => false, 'modal' => false, 'table' => ['class' => 'text-nowrap']],
|
||||
['key' => 'billingAddressId',
|
||||
'text' => 'Rechnungsadresse',
|
||||
'required' => true,
|
||||
'type' => 'autocomplete',
|
||||
'table' => ['class' => 'text-nowrap', 'filter' => 'autocomplete'],
|
||||
'modal' => ['apiUrl' => 'Address/api?do=findAddress', 'items' => '/Address/Api?do=findAddress', 'type' => 'autocomplete']],
|
||||
['key' => 'deliveryAddressName', 'text' => 'L.-Adr. Name', 'required' => true],
|
||||
['key' => 'deliveryAddressLine', 'text' => 'L.-Adr.', 'required' => true],
|
||||
['key' => 'deliveryAddressPLZ', 'text' => 'L.-Adr. PLZ', 'required' => true],
|
||||
['key' => 'deliveryAddressCity', 'text' => 'L.-Adr. Ort', 'required' => true],
|
||||
['key' => 'status',
|
||||
'text' => 'Status',
|
||||
'required' => true,
|
||||
'table' => ['filter' => 'select'],
|
||||
'modal' => ['type' => 'select',
|
||||
'items' => [['value' => 'new', 'text' => 'Neu'],
|
||||
['value' => 'accepted', 'text' => 'Akzeptiert'],
|
||||
['value' => 'invoiced', 'text' => 'In Rechnung gestellt'],]]],
|
||||
['key' => 'positions', 'text' => 'Positionen', 'required' => true, 'table' => false, 'modal' => false],
|
||||
['key' => 'create', 'text' => 'Erstellt', 'required' => false, 'modal' => false, 'table' => ['filter' => 'date']],
|
||||
['key' => 'createBy',
|
||||
'text' => 'Erstellt von',
|
||||
'required' => true,
|
||||
'type' => 'autocomplete',
|
||||
'table' => ['class' => 'text-nowrap', 'filter' => 'select'],
|
||||
'modal' => ['items' => [], 'type' => 'select',]],
|
||||
|
||||
['key' => 'actions',
|
||||
'text' => 'Aktionen',
|
||||
'required' => false,
|
||||
'modal' => false,
|
||||
'table' => ['filter' => false, 'sortable' => false, 'class' => 'text-center']],];
|
||||
|
||||
protected array $additionalActions = [['key' => 'openHistory', 'title' => 'Historie', 'class' => 'fas fa-history text-primary'],
|
||||
['key' => 'print', 'title' => 'Drucken', 'class' => 'fas fa-print text-primary'],
|
||||
['key' => 'printWithPrice', 'title' => 'Drucken mit Preis', 'class' => 'fas fa-print text-success'],
|
||||
];
|
||||
|
||||
protected array $infoMessages = ['create' => 'Lieferschein wurde erstellt.',
|
||||
'update' => 'Lieferschein wurde aktualisiert',
|
||||
'delete' => 'Lieferschein wurde gelöscht',
|
||||
'noChanges' => 'Keine Änderungen vorgenommen'];
|
||||
|
||||
protected function prepareCrudConfig() {
|
||||
$users = array_map(function ($user) {
|
||||
return ['value' => intval($user->id), 'text' => $user->name];
|
||||
}, UserModel::search());
|
||||
|
||||
$this->columns[array_search('createBy', array_column($this->columns, 'key'))]['modal']['items'] = $users;
|
||||
}
|
||||
|
||||
protected function beforeCreate($postData): bool {
|
||||
// if postdata status is not new we return an error
|
||||
if ($postData['status'] !== 'new') {
|
||||
http_response_code(500);
|
||||
self::returnJson(['success' => false, 'message' => 'Status muss "Neu" sein']);
|
||||
die();
|
||||
}
|
||||
$postData['positions'] = json_encode($postData['positions']);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function customAutoCompleteBillingAddressId($id) {
|
||||
$address = new Address($id);
|
||||
if ($address->id) {
|
||||
$result = ['id' => $address->id,
|
||||
'title' => str_replace("'", "\\'", str_replace(["\n",
|
||||
"\r"], " ", $address->getCompanyOrName())) . " (" . $address->zip . " " . $address->city . ", " . $address->street . ")" . (($address->customer_number) ? " [" . $address->customer_number . "]" : "")];
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
protected function beforeUpdate($postData): bool {
|
||||
$postData['positions'] = json_encode($postData['positions']);
|
||||
(new WarehouseHistoryController)->create($postData, $this->mod);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getHistoryAction() {
|
||||
$historyEntries = [];
|
||||
|
||||
// remove all history elements where key is positions
|
||||
|
||||
foreach ((new WarehouseHistoryController)->getHistory($this->request->id, $this->mod, $this->columns) as $entry) {
|
||||
if ($entry['key'] !== 'positions') {
|
||||
$historyEntries[] = $entry;
|
||||
}
|
||||
}
|
||||
|
||||
// $historyEntries = array_filter($historyEntries, function ($entry) {
|
||||
// return $entry['key'] !== 'positions';
|
||||
// });
|
||||
|
||||
self::returnJson($historyEntries);
|
||||
}
|
||||
|
||||
protected function getArticleAddressPriceAction() {
|
||||
$articleId = $this->request->articleId;
|
||||
$addressId = $this->request->addressId;
|
||||
|
||||
if (strlen($articleId) < 1) {
|
||||
http_response_code(500);
|
||||
self::returnJson(['success' => false, 'message' => 'Keine Artikel ID gefunden']);
|
||||
}
|
||||
|
||||
if (strlen($addressId) < 1) {
|
||||
http_response_code(500);
|
||||
self::returnJson(['success' => false, 'message' => 'Keine Adress ID gefunden']);
|
||||
}
|
||||
|
||||
//TODO: implement a select to select price category for each address
|
||||
// for now we default with price with name "Verkauf"
|
||||
$prices = WarehouseArticlePriceTypeModel::getAll(['title' => 'Verkauf']);
|
||||
// if array is empty we return an error
|
||||
if (empty($prices)) {
|
||||
http_response_code(500);
|
||||
self::returnJson(['success' => false, 'message' => 'Keine Preiskategorie gefunden']);
|
||||
}
|
||||
$priceType = $prices[0]->title;
|
||||
|
||||
$article = WarehouseArticleModel::get($articleId);
|
||||
$sellPrices = json_decode($article->cheapestSellPrice, true);
|
||||
$sellPrice = array_search($priceType, array_column($sellPrices, 'title'));
|
||||
|
||||
if (empty($sellPrice)) {
|
||||
http_response_code(500);
|
||||
self::returnJson(['success' => false, 'message' => 'Kein Preis gefunden']);
|
||||
}
|
||||
|
||||
self::returnJson(['success' => true, 'price' => $sellPrices[$sellPrice]['price']]);
|
||||
}
|
||||
|
||||
protected function getDeliveryAddressesAction() {
|
||||
$billingAddressId = $this->request->billingAddressId;
|
||||
if (strlen($billingAddressId) < 1) {
|
||||
http_response_code(500);
|
||||
self::returnJson(['success' => false, 'message' => 'Keine Rechnungsadresse gefunden']);
|
||||
}
|
||||
|
||||
$deliveryAddresses = WarehouseShippingNoteModel::getAll(['billingAddressId' => $billingAddressId]);
|
||||
// TODO: maybe this should be improved as it is kinda hacky
|
||||
$result = [];
|
||||
foreach ($deliveryAddresses as $deliveryAddress) {
|
||||
$found = false;
|
||||
foreach ($result as $r) {
|
||||
if ($r->deliveryAddressName == $deliveryAddress->deliveryAddressName && $r->deliveryAddressLine == $deliveryAddress->deliveryAddressLine) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($found) {
|
||||
continue;
|
||||
}
|
||||
$result[] = $deliveryAddress;
|
||||
}
|
||||
|
||||
self::returnJson($result);
|
||||
}
|
||||
|
||||
protected function getAllTextElementsAction() {
|
||||
$textElements = WarehouseShippingNoteTextElementModel::getAll();
|
||||
self::returnJson($textElements);
|
||||
}
|
||||
|
||||
protected function createPDFAction() {
|
||||
$id = $this->request->id;
|
||||
if (strlen($id) < 1) {
|
||||
http_response_code(500);
|
||||
self::returnJson(['success' => false, 'message' => 'Lieferschein wurde nicht gefunden']);
|
||||
}
|
||||
|
||||
$shippingNote = WarehouseShippingNoteModel::get($id);
|
||||
$address = AddressModel::getOne($shippingNote->billingAddressId);
|
||||
$positions = [];
|
||||
|
||||
// loop through all positions and add articleTitle and articleDescription to each position entry
|
||||
foreach (json_decode($shippingNote->positions, true) as $position) {
|
||||
$article = WarehouseArticleModel::get($position['article']);
|
||||
$position['articleTitle'] = $article->title;
|
||||
$position['articleDescription'] = $article->description;
|
||||
$position['articleUnit'] = $article->unit;
|
||||
$positions[] = $position;
|
||||
}
|
||||
|
||||
$textElements = [];
|
||||
// parse shippingNote.textElements ({"1":true,"2":true}) to array, fetch each text element and put content into array
|
||||
$shippingNoteTextElements = json_decode($shippingNote->textElements, true);
|
||||
foreach ($shippingNoteTextElements as $key => $value) {
|
||||
if ($value) {
|
||||
$textElement = WarehouseShippingNoteTextElementModel::get($key);
|
||||
$textElements[] = $textElement->content;
|
||||
}
|
||||
}
|
||||
if (empty($textElements)) {
|
||||
$textElements = null;
|
||||
}
|
||||
|
||||
$pdf_vars = ["shippingNote" => $shippingNote,
|
||||
"positions" => $positions,
|
||||
"textElements" => $textElements,
|
||||
"showPrices" => isset($_GET['price']) && $_GET['price'] == "true",
|
||||
"bank_iban" => TT_INVOICE_BANK_IBAN,
|
||||
"bank_bic" => TT_INVOICE_BANK_BIC,
|
||||
"bank_bank" => TT_INVOICE_BANK_BANK,
|
||||
"bank_owner" => TT_INVOICE_BANK_OWNER];
|
||||
|
||||
// Replace placeholders in header
|
||||
// create shipping note in this format LS2024-X0001
|
||||
// pad number on the left side with zeros
|
||||
$shippingNoteNumber = "LS" . date("Y", $shippingNote->create) . "-" . str_pad($shippingNote->id, 4, "0", STR_PAD_LEFT);
|
||||
$headerHtml = file_get_contents(BASEDIR . "/Layout/default/WarehouseShippingNote/PDF_HEADER.html");
|
||||
$headerHtml = str_replace("{{ basedir }}", BASEDIR, $headerHtml);
|
||||
$headerHtml = str_replace("{{ addressLine_1 }}", $shippingNote->deliveryAddressName, $headerHtml);
|
||||
$headerHtml = str_replace("{{ addressLine_2 }}", $shippingNote->deliveryAddressLine, $headerHtml);
|
||||
$headerHtml = str_replace("{{ addressLine_3 }}", $shippingNote->deliveryAddressPLZ . " " . $shippingNote->deliveryAddressCity, $headerHtml);
|
||||
$headerHtml = str_replace("{{ addressLine_4 }}", "", $headerHtml);
|
||||
$headerHtml = str_replace("{{ addressLine_5 }}", "", $headerHtml);
|
||||
$headerHtml = str_replace("{{ customerNumber }}", $address->customer_number, $headerHtml);
|
||||
$headerHtml = str_replace("{{ shippingNoteNumber }}", $shippingNoteNumber, $headerHtml);
|
||||
$headerHtml = str_replace("{{ shippingNoteDate }}", date("d.m.Y", $shippingNote->create), $headerHtml);
|
||||
|
||||
$headerFile = BASEDIR . "/var/temp/shipping-note_header-" . date("U") . "-" . rand(1000, 9999) . ".html";
|
||||
file_put_contents($headerFile, $headerHtml);
|
||||
|
||||
|
||||
// Replace placeholders in header
|
||||
$footerHtml = file_get_contents(BASEDIR . "/Layout/default/WarehouseShippingNote/PDF_FOOTER.html");
|
||||
$footerHtml = str_replace("{{ bank_iban }}", TT_INVOICE_BANK_IBAN_FORMATTED, $footerHtml);
|
||||
$footerHtml = str_replace("{{ bank_bic }}", TT_INVOICE_BANK_BIC, $footerHtml);
|
||||
$footerHtml = str_replace("{{ bank_bank }}", TT_INVOICE_BANK_BANK, $footerHtml);
|
||||
$footerHtml = str_replace("{{ bank_owner }}", TT_INVOICE_BANK_OWNER, $footerHtml);
|
||||
|
||||
|
||||
$footerFile = BASEDIR . "/var/temp/shipping-note_header-" . date("U") . "-" . rand(1000, 9999) . ".html";
|
||||
file_put_contents($footerFile, $footerHtml);
|
||||
|
||||
|
||||
$pdf = new PdfForm("WarehouseShippingNote/PDF_MAIN", $pdf_vars);
|
||||
$wkhtmltopdfArgs = "--header-html $headerFile --footer-html $footerFile";
|
||||
$filename = $pdf->render($wkhtmltopdfArgs);
|
||||
|
||||
// return the pdf and die so the client sees the pdf not the filename
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
readfile($filename);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class WarehouseShippingNoteModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public int $billingAddressId;
|
||||
public string $deliveryAddressName;
|
||||
public string $deliveryAddressLine;
|
||||
public string $deliveryAddressPLZ;
|
||||
public string $deliveryAddressCity;
|
||||
public string $status; // 'new'|'accepted'|'invoiced'
|
||||
public string $positions;
|
||||
public string $textElements;
|
||||
public int $create;
|
||||
public int $createBy;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property mixed|null $name
|
||||
*/
|
||||
class WarehouseShippingNoteTextElement extends mfBaseModel
|
||||
{
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?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);
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class WarehouseShippingNoteTextElementModel extends TTCrudBaseModel {
|
||||
public int $id;
|
||||
public string $title;
|
||||
public string $content;
|
||||
public int $create;
|
||||
public int $createBy;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user