From 35251c5ee5da3fd6844553e8b7bb7d804764e3c5 Mon Sep 17 00:00:00 2001 From: Luca Haid Date: Fri, 13 Dec 2024 07:25:55 +0000 Subject: [PATCH] Shipping note add direct url create --- .../WarehouseEShopOrderController.php | 91 +++++- .../WarehouseEShopOrder.js | 290 ++++++++++++++---- .../WarehouseShippingNote.js | 7 +- .../WarehouseShippingNoteModal.js | 11 + 4 files changed, 324 insertions(+), 75 deletions(-) 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: ` +
+ +
+ + + +
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + +
ArtikelMengeAktionen
Keine Einträge
{{ position.articleId ? articleNames[position.articleId] : position.articlePacketId ? articlePacketNames[position.articlePacketId] : + 'Loading...' }} + {{ position.quantity }} + + +
+
+ + +
+ `, + + +}) + Vue.component('warehouse-e-shop-order', { //language=Vue - template: ` - - + template: ` + + - + - + - - - - - - -
-

-
- -
- -
-
- - -
-
    -
  • - {{ entry.date }} {{ entry.time }} - {{ entry.evtDscr }} -
  • -
-
- -
+ -
- `, data() { +
+ `, data() { return { window: window, historyModal: false, @@ -79,7 +240,10 @@ Vue.component('warehouse-e-shop-order', { singleOrderEmailModalText: null, openTrackingHistoryModal: false, trackingHistoryModalId: null, - trackingHistoryModalData: null, + trackingHistoryModalData: null, // modal + positionsEntryArticleId: null, + positionsEntryArticlePacketId: null, + positionsEntryAmount: null, } }, async mounted() { const response = await axios.get(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/getAllItemsPerOrder`); @@ -92,8 +256,7 @@ Vue.component('warehouse-e-shop-order', { if (response.data.shippingNoteId) { window.open(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseShippingNote/createPDF?id=${response.data.shippingNoteId}&price=true`, '_blank'); } - }, - async sendSingleOrderEmail() { + }, async sendSingleOrderEmail() { const response = await axios.get(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/singleOrderEmail?id=${this.singleOrderEmailModalId}`); if (response.data.message) { window.notify(response.data.success === true ? 'success' : 'error', response.data.message); @@ -148,8 +311,7 @@ Vue.component('warehouse-e-shop-order', { .then(response => this.singleOrderEmailModalText = response.data) .catch(error => window.notify('error', error.response?.data?.message || 'Ein Fehler ist aufgetreten')); } - }, - async trackingHistoryModalId() { + }, async trackingHistoryModalId() { this.openTrackingHistoryModal = !!this.trackingHistoryModalId; this.trackingHistoryModalData = null; if (this.trackingHistoryModalId) { diff --git a/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js b/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js index a81c70e4f..25f6e2309 100644 --- a/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js +++ b/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js @@ -80,7 +80,10 @@ Vue.component('warehouse-shipping-note', { signingShippingNoteId: null } }, - methods: { - + mounted() { + // check if get parameter doAction = createNew is set, if so open the modal with 'create' as id + if (window.location.search.includes('doAction=createNew')) { + this.shippingNoteModalId = 'create'; + } } }) diff --git a/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js b/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js index 206f0b15c..e74ee9566 100644 --- a/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js +++ b/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js @@ -543,6 +543,17 @@ Vue.component('warehouse-shipping-note-modal', { this.textElements = []; } } + } else { + const knr = new URLSearchParams(window.location.search).get('knr'); + if (knr) { + const response = await axios.get(window.TT_CONFIG["BASE_PATH"] + '/Address/Api?do=findAddress&fibu_primary_account=1&autocomplete=1&q=' + knr); + for (const address of response.data) { + if (address.text.endsWith(`[${knr}]`)) { + this.billAddrId = address.value; + break; + } + } + } } }, methods: {