added confirmation email for eshop
This commit is contained in:
@@ -27,6 +27,7 @@ class WarehouseEShopOrderController extends TTCrud {
|
||||
|
||||
protected array $additionalActions = [
|
||||
['key' => 'openHistory', 'title' => 'Historie', 'class' => 'fas fa-history text-primary'],
|
||||
['key' => 'openSingleOrderEmail', 'title' => 'Bestellbestätigung', 'class' => 'fas fa-envelope text-primary'],
|
||||
];
|
||||
|
||||
protected array $infoMessages = [
|
||||
@@ -48,6 +49,50 @@ class WarehouseEShopOrderController extends TTCrud {
|
||||
$this->columns[8]['modal']['items'] = $users;
|
||||
}
|
||||
|
||||
protected function singleOrderEmailAction() {
|
||||
// this has dryRun and id in get parameter create a E-Mail Body like the things below
|
||||
$isDryRun = $this->request->dryRun ?? false;
|
||||
$id = $this->request->id;
|
||||
|
||||
$order = WarehouseEShopOrderModel::get($id);
|
||||
$orderItems = WarehouseEShopOrderItemModel::getAll(['orderId' => $id]);
|
||||
$articles = WarehouseArticleModel::getAll();
|
||||
$articlePackets = WarehouseArticlePacketModel::getAll();
|
||||
|
||||
$paddedId = str_pad($id, 3, '0', STR_PAD_LEFT);
|
||||
$body = "Bestellung #$paddedId\n\n";
|
||||
$body .= "Lieferadresse:\n";
|
||||
$body .= $order->deliveryAddressName . "\n";
|
||||
$body .= $order->deliveryAddressLine . "\n";
|
||||
$body .= $order->deliveryAddressPLZ . ' ' . $order->deliveryAddressCity . "\n\n";
|
||||
$body .= "Bestellte Artikel:\n";
|
||||
foreach ($orderItems as $item) {
|
||||
$article = $item->articleId ? array_search($item->articleId, array_column($articles, 'id')) : null;
|
||||
$articlePacket = $item->articlePacketId ? array_search($item->articlePacketId, array_column($articlePackets, 'id')) : null;
|
||||
|
||||
$articleTitle = $item->articleId ? $articles[$article]->title : $articlePackets[$articlePacket]->title;
|
||||
$quantity = $item->quantity;
|
||||
$body .= "$quantity x $articleTitle\n";
|
||||
}
|
||||
$body .= "\n\n";
|
||||
$body .= "CSV der Bestellung ist im Anhang.\n\n";
|
||||
$body .= "XINON GmbH\nFladnitz im Raabtal 150\n8322 Studenzen\n";
|
||||
|
||||
if ($isDryRun) {
|
||||
self::returnJson(['success' => true, 'message' => 'E-Mail Body wurde erstellt', 'body' => $body]);
|
||||
} else {
|
||||
$email = new Emailnotification();
|
||||
$email->setSubject("Bestellbestätigung Bestellung #$paddedId");
|
||||
$email->setBody($body);
|
||||
$email->setFrom(TT_OUTGOING_EMAIL_2FA, TT_OUTGOING_EMAIL_2FA);
|
||||
// $email->setTo('ftth-versand@triotronik.com');
|
||||
$email->setTo('luca.haid@xinon.eu');
|
||||
$csvContent = $this->CSVExportNewOrdersMarkAcceptedAction(true, [$id]);
|
||||
$email->addAttachment(null, $csvContent, "Bestellung_$paddedId.csv", "text/csv");
|
||||
self::returnJson(['success' => true, 'message' => 'E-Mail wurde versendet']);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getAllOrderItemsPerOrder(): array {
|
||||
$items = WarehouseEShopOrderItemModel::getAll();
|
||||
$articles = WarehouseArticleModel::getAll();
|
||||
@@ -146,13 +191,14 @@ class WarehouseEShopOrderController extends TTCrud {
|
||||
|
||||
$user = UserModel::getOne($json['createBy']);
|
||||
|
||||
|
||||
$email = new Emailnotification();
|
||||
$email->setSubject("Bestellbestätigung Bestellung #$subjectId");
|
||||
$email->setBody($body);
|
||||
$email->setFrom(TT_OUTGOING_EMAIL_2FA, TT_OUTGOING_EMAIL_2FA);
|
||||
$email->setTo($user->email);
|
||||
$email->send();
|
||||
foreach (["office@xinon.at", $user->email] as $emailAddr) {
|
||||
$email = new Emailnotification();
|
||||
$email->setSubject("Bestellbestätigung Bestellung #$subjectId");
|
||||
$email->setBody($body);
|
||||
$email->setFrom(TT_OUTGOING_EMAIL_2FA, TT_OUTGOING_EMAIL_2FA);
|
||||
$email->setTo($emailAddr);
|
||||
$email->send();
|
||||
}
|
||||
|
||||
self::returnJson(['success' => true,
|
||||
'message' => $this->infoMessages['create'],
|
||||
@@ -162,12 +208,18 @@ class WarehouseEShopOrderController extends TTCrud {
|
||||
die(json_encode($json));
|
||||
}
|
||||
|
||||
protected function CSVExportNewOrdersMarkAcceptedAction() {
|
||||
protected function CSVExportNewOrdersMarkAcceptedAction($returnCSV = false, $orderIds = []) {
|
||||
$orders = WarehouseEShopOrderModel::getAll(['status' => 'new']);
|
||||
$orders = array_map(function($order) {
|
||||
return (array) $order;
|
||||
}, $orders);
|
||||
|
||||
if (!empty($orderIds)) {
|
||||
$orders = array_filter($orders, function($order) use ($orderIds) {
|
||||
return in_array($order['id'], $orderIds);
|
||||
});
|
||||
}
|
||||
|
||||
if (empty($orders)) {
|
||||
self::returnJson(['success' => false, 'message' => 'Keine neuen Bestellungen']);
|
||||
die();
|
||||
@@ -210,6 +262,10 @@ class WarehouseEShopOrderController extends TTCrud {
|
||||
WarehouseEShopOrderModel::update($order);
|
||||
}
|
||||
|
||||
if ($returnCSV) {
|
||||
return Helper::arrayToCsv($rows);
|
||||
}
|
||||
|
||||
self::returnJson($rows);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,5 +135,26 @@ class Helper {
|
||||
$controller->layout()->setTemplate("VueViews/Vue");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of objects to a CSV file.
|
||||
* @param array $rows The array of objects to convert to CSV.
|
||||
* @return string The CSV file content.
|
||||
*/
|
||||
public static function arrayToCsv(array $rows): string {
|
||||
$output = fopen('php://temp', 'w');
|
||||
|
||||
// Add headers
|
||||
fputcsv($output, array_keys((array) $rows[0]));
|
||||
|
||||
// Add rows
|
||||
foreach ($rows as $row) {
|
||||
fputcsv($output, (array) $row);
|
||||
}
|
||||
|
||||
rewind($output);
|
||||
$csv = stream_get_contents($output);
|
||||
fclose($output);
|
||||
|
||||
return $csv;
|
||||
}
|
||||
}
|
||||
@@ -103,10 +103,10 @@ Vue.component('warehouse-e-shop', {
|
||||
const response = await axios.post(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/createOrder`, {
|
||||
shoppingCart: this.shoppingCart,
|
||||
deliveryMode: this.createOrderDialogData.deliveryMode,
|
||||
deliveryAddressName: this.createOrderDialogData.deliveryAddressName,
|
||||
deliveryAddressLine: this.createOrderDialogData.deliveryAddressLine,
|
||||
deliveryAddressPLZ: this.createOrderDialogData.deliveryAddressPLZ,
|
||||
deliveryAddressCity: this.createOrderDialogData.deliveryAddressCity,
|
||||
deliveryAddressName: this.createOrderDialogData.deliveryAddressName.trim(),
|
||||
deliveryAddressLine: this.createOrderDialogData.deliveryAddressLine.trim(),
|
||||
deliveryAddressPLZ: this.createOrderDialogData.deliveryAddressPLZ.trim(),
|
||||
deliveryAddressCity: this.createOrderDialogData.deliveryAddressCity.trim(),
|
||||
});
|
||||
if (response.data.success) {
|
||||
this.window.notify('success', response.data.message || 'Erfolgreich gespeichert');
|
||||
|
||||
@@ -3,7 +3,9 @@ Vue.component('warehouse-e-shop-order', {
|
||||
//language=Vue
|
||||
template: `
|
||||
<tt-card>
|
||||
<tt-table-crud @openHistory="historyModal = true; historyModalId = $event.id" ref="table">
|
||||
<tt-table-crud @openHistory="historyModal = true; historyModalId = $event.id"
|
||||
@openSingleOrderEmail="openSingleOrderEmailModal = true; singleOrderEmailModalId = $event.id"
|
||||
ref="table">
|
||||
|
||||
<template v-slot:table-top-buttons>
|
||||
<button @click="createCSVExportAndMarkAsAccepted" type="button" class="btn btn-outline-success">
|
||||
@@ -28,10 +30,29 @@ Vue.component('warehouse-e-shop-order', {
|
||||
|
||||
</tt-table-crud>
|
||||
<warehouse-history-modal :show.sync="historyModal" :id="historyModalId"/>
|
||||
|
||||
<!-- add a tt-modal which just shows some text from the api to show a email for a single order-->
|
||||
<tt-modal :show.sync="openSingleOrderEmailModal"
|
||||
:title="'Email für Bestellung ' + singleOrderEmailModalId"
|
||||
@close="openSingleOrderEmailModal = false"
|
||||
save-text="E-Mail senden"
|
||||
@submit="sendSingleOrderEmail"
|
||||
:delete="false"
|
||||
>
|
||||
<div v-if="singleOrderEmailModalId && singleOrderEmailModalText">
|
||||
<p v-html="singleOrderEmailModalText.body.replaceAll('\\n', '<br>')"></p>
|
||||
</div>
|
||||
<!-- else show loader-->
|
||||
<div v-else>
|
||||
<tt-loader/>
|
||||
</div>
|
||||
</tt-modal>
|
||||
|
||||
|
||||
</tt-card>
|
||||
`, data() {
|
||||
return {
|
||||
window: window, historyModal: false, historyModalId: null, articleItems: null
|
||||
window: window, historyModal: false, historyModalId: null, articleItems: null, openSingleOrderEmailModal: false, singleOrderEmailModalId: null, singleOrderEmailModalText: null
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
@@ -40,11 +61,20 @@ Vue.component('warehouse-e-shop-order', {
|
||||
this.articleItems = response.data;
|
||||
},
|
||||
methods: {
|
||||
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);
|
||||
this.openSingleOrderEmailModal = false;
|
||||
} else {
|
||||
window.notify('error', 'Ein Fehler ist aufgetreten');
|
||||
}
|
||||
},
|
||||
async createCSVExportAndMarkAsAccepted() {
|
||||
const response = await axios.post(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/CSVExportNewOrdersMarkAccepted`);
|
||||
|
||||
if (response.data.message) {
|
||||
window.notify('info', response.data.message);
|
||||
window.notify('success', response.data.message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,5 +107,16 @@ Vue.component('warehouse-e-shop-order', {
|
||||
|
||||
await this.$refs.table.$refs.table.fetchData();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
singleOrderEmailModalId() {
|
||||
this.openSingleOrderEmailModal = !!this.singleOrderEmailModalId;
|
||||
this.singleOrderEmailModalText = null;
|
||||
if (this.singleOrderEmailModalId) {
|
||||
axios.get(`${window['TT_CONFIG']['BASE_PATH']}/WarehouseEShopOrder/singleOrderEmail?id=${this.singleOrderEmailModalId}&dryRun=true`)
|
||||
.then(response => this.singleOrderEmailModalText = response.data)
|
||||
.catch(error => window.notify('error', error.response?.data?.message || 'Ein Fehler ist aufgetreten'));
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,7 +3,9 @@ Vue.component('tt-modal', {
|
||||
show: { type: Boolean, default: false },
|
||||
title: { type: String, default: 'Modal Title' },
|
||||
delete: { type: Boolean, default: true },
|
||||
deleteText: { type: String, default: 'Delete' },
|
||||
save: { type: Boolean, default: true },
|
||||
saveText: { type: String, default: 'Save' },
|
||||
},
|
||||
watch: {
|
||||
show(newVal) {
|
||||
@@ -35,8 +37,8 @@ Vue.component('tt-modal', {
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<slot name="footer">
|
||||
<button v-if="save" class="btn btn-primary" @click="$emit('submit')">Save</button>
|
||||
<button v-if="$props.delete" class="btn btn-danger" @click="$emit('delete')">Delete</button>
|
||||
<button v-if="save" class="btn btn-primary" @click="$emit('submit')">{{saveText}}</button>
|
||||
<button v-if="$props.delete" class="btn btn-danger" @click="$emit('delete')">{{deleteText}}</button>
|
||||
<button class="btn btn-secondary" @click="$emit('update:show', false)">Close</button>
|
||||
</slot>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user