diff --git a/application/WarehouseEShopOrder/WarehouseEShopOrderController.php b/application/WarehouseEShopOrder/WarehouseEShopOrderController.php index b7e8dca91..e5701ae97 100644 --- a/application/WarehouseEShopOrder/WarehouseEShopOrderController.php +++ b/application/WarehouseEShopOrder/WarehouseEShopOrderController.php @@ -16,6 +16,7 @@ class WarehouseEShopOrderController extends TTCrud { ['key' => 'deliveryAddressPLZ', 'text' => 'PLZ', 'required' => true, 'regex' => '/^\d{4}$/'], ['key' => 'deliveryAddressCity', 'text' => 'Stadt', 'required' => true, 'required_length' => 3], ['key' => 'trackingNumber', 'text' => 'Trackingnummer', 'required' => false, 'modal' => false], + ['key' => 'positions', 'text' => 'Positionen', 'required' => false, 'table' => false], ['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']] @@ -65,7 +66,8 @@ class WarehouseEShopOrderController extends TTCrud { return ['value' => intval($user->id), 'text' => $user->name]; }, UserModel::search()); - $this->columns[11]['modal']['items'] = $users; + $createByIndex = array_search('createBy', array_column($this->columns, 'key')); + $this->columns[$createByIndex]['modal']['items'] = $users; } protected function createShippingNote() { @@ -77,7 +79,9 @@ class WarehouseEShopOrderController extends TTCrud { $existingShippingNote = WarehouseShippingNoteModel::getAll(['eShopOrderId' => $id]); if (!empty($existingShippingNote)) { - self::returnJson(['success' => false, 'message' => 'Für diese Bestellung existiert bereits ein Lieferschein', 'shippingNoteId' => $existingShippingNote[0]->id]); + self::returnJson(['success' => false, + 'message' => 'Für diese Bestellung existiert bereits ein Lieferschein', + 'shippingNoteId' => $existingShippingNote[0]->id]); die(); } @@ -286,7 +290,8 @@ class WarehouseEShopOrderController extends TTCrud { } protected function getAllOrderItemsPerOrder(): array { - $items = WarehouseEShopOrderItemModel::getAll(); + if (isset($_GET['orderId'])) return WarehouseEShopOrderItemModel::getAll(['orderId' => $_GET['orderId']]); + else $items = WarehouseEShopOrderItemModel::getAll(); $articles = WarehouseArticleModel::getAll(); $articlePackets = WarehouseArticlePacketModel::getAll(); @@ -397,6 +402,7 @@ class WarehouseEShopOrderController extends TTCrud { unset($this->postData['shippingNoteStatus']); return true; } + protected function beforeUpdate($postData): bool { unset($this->postData['shippingNoteStatus']); (new WarehouseHistoryController)->create($postData, $this->mod); @@ -444,17 +450,17 @@ class WarehouseEShopOrderController extends TTCrud { } protected function readGLSEmailAction() { - function decode_utf8($str){ + function decode_utf8($str) { # paterns - $err="(=\?.{10,13}q\?_?|\?\=)"; + $err = "(=\?.{10,13}q\?_?|\?\=)"; $pat = "/=([0-9A-F]{2})/"; - $cha="'.chr(hexdec("; + $cha = "'.chr(hexdec("; # erase null signs in string $str = str_replace("\x00", "", $str); # to decode with eval and replace - eval("\$str='". - preg_replace($pat,$cha."'$1')).'",$str) - ."';"); + eval("\$str='" . + preg_replace($pat, $cha . "'$1')).'", $str) + . "';"); # return return $str; } @@ -585,4 +591,71 @@ class WarehouseEShopOrderController extends TTCrud { $result = []; } + + protected function updatePositionAction() { + $json = json_decode(file_get_contents('php://input'), true); + $id = intval($json['id']); + $articleId = $json['articleId'] ? intval($json['articleId']) : null; + $articlePacketId = $json['articlePacketId'] ? intval($json['articlePacketId']) : null; + $quantity = intval($json['quantity']); + + if (!$id || !$quantity) { + self::returnJson(['success' => false, 'message' => 'Ungültige Daten']); + die(); + } + + $position = (array) WarehouseEShopOrderItemModel::get($id); + if (!$position) { + self::returnJson(['success' => false, 'message' => 'Position nicht gefunden']); + die(); + } + + $position['articleId'] = $articleId; + $position['articlePacketId'] = $articlePacketId; + $position['quantity'] = $quantity; + WarehouseEShopOrderItemModel::update($position); + + self::returnJson(['success' => true, 'position' => $position]); + } + + protected function deletePositionAction() { + $json = json_decode(file_get_contents('php://input'), true); + $id = intval($json['id']); + + if (!$id) { + self::returnJson(['success' => false, 'message' => 'Keine ID angegeben']); + die(); + } + + $position = WarehouseEShopOrderItemModel::get($id); + if (!$position) { + self::returnJson(['success' => false, 'message' => 'Position nicht gefunden']); + die(); + } + + WarehouseEShopOrderItemModel::delete($id); + self::returnJson(['success' => true, 'message' => 'Position gelöscht']); + } + + protected function addPositionAction() { + $json = json_decode(file_get_contents('php://input'), true); + $orderId = intval($json['orderId']); + $articleId = $json['articleId'] ? intval($json['articleId']) : null; + $articlePacketId = $json['articlePacketId'] ? intval($json['articlePacketId']) : null; + $quantity = intval($json['quantity']); + + if (!$orderId || !$quantity) { + self::returnJson(['success' => false, 'message' => 'Ungültige Daten']); + die(); + } + + $position = WarehouseEShopOrderItemModel::create(['orderId' => $orderId, + 'articleId' => $articleId, + 'articlePacketId' => $articlePacketId, + 'quantity' => $quantity]); + + $position = (array) WarehouseEShopOrderItemModel::get($position); + + self::returnJson(['success' => true, 'position' => $position]); + } } diff --git a/public/js/pages/WarehouseEShopOrder/WarehouseEShopOrder.js b/public/js/pages/WarehouseEShopOrder/WarehouseEShopOrder.js index b8ae92fcd..d6cd8c89e 100644 --- a/public/js/pages/WarehouseEShopOrder/WarehouseEShopOrder.js +++ b/public/js/pages/WarehouseEShopOrder/WarehouseEShopOrder.js @@ -1,74 +1,235 @@ // noinspection JSUnusedLocalSymbols + +const articleAPIUrl = `${window['TT_CONFIG']['BASE_PATH']}/WarehouseArticle/autocomplete`; +const articlePacketAPIUrl = `${window['TT_CONFIG']['BASE_PATH']}/WarehouseArticlePacket/autocomplete`; + +Vue.component('warehouse-e-shop-order-modal-positions-mgmt', { + props: { + id: {type: [String, Number], required: true}, + }, data() { + return { + window: window, + positions: [], + articleAPIUrl: articleAPIUrl, + articlePacketAPIUrl: articlePacketAPIUrl, + articleNames: {}, + articlePacketNames: {}, + articleId: null, + articlePacketId: null, + amount: null, + editIndex: null, + } + }, async mounted() { + // get all positions by /WarehouseEShopOrder/getAllItemsPerOrder?orderId=ID + const response = await axios.get(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/getAllItemsPerOrder?orderId=${this.id}`); + this.positions = response.data; + }, methods: { + async fetchNames() { + console.log("hallohallo"); + // TODO: there must be a better way to do this + for (const position of this.positions) { + if (position.articleId) this.$set(this.articleNames, position.articleId, 'Loading...'); + if (position.articlePacketId) this.$set(this.articlePacketNames, position.articlePacketId, 'Loading...'); + } + + const articlePromises = this.positions.filter(position => position.articleId) + .map(position => axios.get(window.TT_CONFIG["BASE_PATH"] + '/WarehouseArticle/autoComplete?searchedID=' + position.articleId)); + const articlePacketPromises = this.positions.filter(position => position.articlePacketId) + .map(position => axios.get(window.TT_CONFIG["BASE_PATH"] + '/WarehouseArticlePacket/autoComplete?searchedID=' + position.articlePacketId)); + + const articleResponses = await Promise.all(articlePromises); + const articlePacketResponses = await Promise.all(articlePacketPromises); + + for (const response of articleResponses) { + this.$set(this.articleNames, response.data[0].value, response.data[0].text); + } + + for (const response of articlePacketResponses) { + this.$set(this.articlePacketNames, response.data[0].value, response.data[0].text); + } + + }, + async addPosition() { + if (!this.articleId && !this.articlePacketId) return window.notify('error', 'Bitte wählen Sie einen Artikel oder ein Artikel Packet aus.'); + if (this.editIndex !== null) return this.updatePosition(); + + const response = await axios.post(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/addPosition`, { + orderId: this.id, + articleId: this.articleId, + articlePacketId: this.articlePacketId, + quantity: this.amount, + }); + + if (response.data.success) { + this.positions.push(response.data.position); + this.articleId = null; + this.articlePacketId = null; + this.amount = null; + window.notify('success', 'Position hinzugefügt'); + } else { + window.notify('error', response.data.message); + } + }, + async updatePosition() { + const position = this.positions[this.editIndex]; + const response = await axios.post(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/updatePosition`, { + id: position.id, + articleId: this.articleId, + articlePacketId: this.articlePacketId, + quantity: this.amount, + }); + + if (response.data.success) { + this.positions[this.editIndex] = response.data.position; + this.articleId = null; + this.articlePacketId = null; + this.amount = null; + this.editIndex = null; + window.notify('success', response.data.message); + } else { + window.notify('error', response.data.message); + } + }, + async deletePosition(id) { + const response = await axios.post(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/deletePosition`, {id}); + + if (response.data.success) { + this.positions = this.positions.filter(position => position.id !== id); + window.notify('success', response.data.message); + } else { + window.notify('error', response.data.message); + } + }, + async editPosition(id) { + const position = this.positions.find(position => position.id === id); + this.articleId = position.articleId; + this.articlePacketId = position.articlePacketId; + this.amount = position.quantity; + this.editIndex = this.positions.indexOf(position); + }, + }, watch: {positions: {handler: 'fetchNames', immediate: true}}, //language=Vue + template: ` +
| Artikel | +Menge | +Aktionen | +|
|---|---|---|---|
| Keine Einträge | +|||
| {{ position.articleId ? articleNames[position.articleId] : position.articlePacketId ? articlePacketNames[position.articlePacketId] : + 'Loading...' }} + | +{{ position.quantity }} | ++ + + | +|