cafe-plaetschwiesle/web/src/views/Checkout.vue

195 lines
6 KiB
Vue

<template>
<BaseCard>
<ConfirmDialog></ConfirmDialog>
<Transition>
<WaveSpinner v-if="isLoading" />
<div v-else>
<BaseItem>
<div class="field-checkbox mt-1">
<Checkbox id="binary" v-model="checkAll" :binary="true" @click="checkAllClicked" />
<label for="binary">Alle Auswählen</label>
</div>
<hr style="color: var(--text-color)" class="my-3" />
<div v-for="order in orders" :key="order.id" class="field-checkbox">
<Checkbox :id="order.id" name="order" :value="order.id" v-model="orderFilter" />
<label :for="'' + order.id" class="w-full">
<span class="flex justify-content-between">
<span class="overflow-hidden text-overflow-ellipsis white-space-nowrap">{{ order.order_item.description }}</span>
<span>{{ convertToEur(order.order_item.price) }}</span>
</span>
</label>
</div>
</BaseItem>
<div class="h-4rem"></div>
<BottomNavigation>
<template #left>
<router-link :to="{ name: 'TableDetail' }" class="no-underline">
<Button :disabled="applyFilterLoading" icon="pi pi-arrow-left" class="p-button-rounded" />
</router-link>
</template>
<template #middle>
<div class="flex flex-column align-items-center">
<div class="text-sm">Tisch {{ table }}</div>
<div class="font-bold">{{ convertToEur(total) }}</div>
</div>
</template>
<template #right>
<Button
:disabled="total === 0"
:loading="applyFilterLoading"
icon="pi pi-money-bill"
class="p-button-danger p-button-rounded"
@click="generateBill"
/>
</template>
</BottomNavigation>
</div>
</Transition>
<Sidebar v-model:visible="billModal" :baseZIndex="10000" position="full" @hide="billModalClosed">
<BillModal :bill="bill" />
</Sidebar>
</BaseCard>
</template>
<script lang="ts">
import { computed, defineComponent, ref, watch } from "vue";
import { BillsService, OrdersService, controller_Bill, controller_Order } from "@/services/openapi";
import Checkbox from "primevue/checkbox";
import { convertToEur, emptyBill, errorToast } from "@/utils";
import Button from "primevue/button";
import WaveSpinner from "@/components/UI/WaveSpinner.vue";
import BaseCard from "@/components/UI/BaseCard.vue";
import BottomNavigation from "@/components/UI/BottomNavigation.vue";
import BaseItem from "@/components/UI/BaseItem.vue";
import ConfirmDialog from "primevue/confirmdialog";
import { useConfirm } from "primevue/useconfirm";
import { useToast } from "primevue/usetoast";
import Sidebar from "primevue/sidebar";
import BillModal from "@/components/Bills/BillModal.vue";
import { useRouter } from "vue-router";
export default defineComponent({
name: "CheckoutView",
// eslint-disable-next-line
components: { BaseItem, BaseCard, WaveSpinner, Checkbox, Button, BottomNavigation, ConfirmDialog, Sidebar, BillModal },
props: { id: { type: String, default: "0" } },
setup(props) {
const confirm = useConfirm();
const toast = useToast();
const router = useRouter();
const table = computed(() => parseInt(props.id));
const orders = ref<controller_Order[]>([]);
const orderFilter = ref<number[]>([]);
const isLoading = ref(false);
const applyFilterLoading = ref(false);
const checkAll = ref(false);
const total = ref(0);
const bill = ref<controller_Bill>({ ...emptyBill });
const billModal = ref(false);
function checkAllCheck() {
if (orderFilter.value) checkAll.value = orderFilter.value.length === orders.value.length;
}
function calculateTotal() {
let temp = 0;
orders.value.forEach((order) => {
if (order.id && orderFilter.value.includes(order.id)) temp += order.order_item.price;
});
total.value = temp;
}
watch(orderFilter, () => {
checkAllCheck();
calculateTotal();
});
getData();
function getData() {
isLoading.value = true;
OrdersService.getOrders(table.value, false)
.then((res) => {
orders.value = res;
setAllOrdersSelected();
checkAllCheck();
})
.finally(() => (isLoading.value = false));
}
function setAllOrdersSelected() {
const temp: number[] = [];
orders.value.forEach((order) => order.id && temp.push(order.id));
orderFilter.value = temp;
}
function checkAllClicked() {
if (orderFilter.value.length === orders.value.length) {
orderFilter.value = [];
} else {
setAllOrdersSelected();
}
}
function generateBill() {
applyFilterLoading.value = true;
confirm.require({
message: "Alle ausgewählte Bestellungen abrechnen?",
header: "Abrechnen",
icon: "pi pi-exclamation-triangle",
acceptClass: "p-button-danger",
rejectClass: "p-button-secondary",
accept: () => {
BillsService.postBills(table.value, orderFilter.value.toString())
.then((res) => {
bill.value = res;
billModal.value = true;
getData();
})
.catch((err) => errorToast(toast, err.body.error))
.finally(() => (applyFilterLoading.value = false));
},
reject: () => {
applyFilterLoading.value = false;
},
});
}
function billModalClosed() {
if (orderFilter.value.length === 0) {
router.push({ name: "Bills" });
}
}
return {
orders,
orderFilter,
checkAll,
checkAllClicked,
convertToEur,
generateBill,
isLoading,
applyFilterLoading,
total,
table,
bill,
billModal,
billModalClosed,
};
},
});
</script>
<style scoped>
.v-enter-active {
transition: opacity 0.2s ease-in;
}
.v-enter-from {
opacity: 0;
}
.field-checkbox:last-child {
margin-bottom: 0.25rem;
}
</style>