Connect Orders database table with Payments and Addresses, visualize it in the frontend
This commit is contained in:
@@ -32,13 +32,15 @@ function confirmPressed() {
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
@click="showDialog = false"
|
||||
color="green"
|
||||
prepend-icon="mdi-close"
|
||||
color="orange"
|
||||
>
|
||||
{{ $t("dialog.cancel") }}
|
||||
</outlined-button>
|
||||
|
||||
<outlined-button
|
||||
@click="confirmPressed"
|
||||
prepend-icon="mdi-check"
|
||||
color="red"
|
||||
>
|
||||
{{ $t("dialog.confirm") }}
|
||||
|
||||
@@ -9,7 +9,12 @@ export async function getUserOrders(userId: number) {
|
||||
return axios.get(BASE_URL + "/" + userId)
|
||||
}
|
||||
|
||||
export async function addOrder(accountId: number, basketItems: Array<BasketItemModel>) {
|
||||
export async function addOrder(
|
||||
accountId: number,
|
||||
basketItems: Array<BasketItemModel>,
|
||||
paymentId: number,
|
||||
addressId: number
|
||||
) {
|
||||
let orderItems = []
|
||||
|
||||
for (let basketItem of basketItems) {
|
||||
@@ -22,6 +27,8 @@ export async function addOrder(accountId: number, basketItems: Array<BasketItemM
|
||||
|
||||
return axios.post(BASE_URL, {
|
||||
accountId: accountId,
|
||||
orderItems: orderItems
|
||||
orderItems: orderItems,
|
||||
paymentId: paymentId,
|
||||
addressId: addressId
|
||||
})
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import { AddressModel } from "./addressModel"
|
||||
import { OrderItemModel } from "./orderItemModel"
|
||||
import { PaymentModel } from "./paymentModel"
|
||||
|
||||
export class OrderModel {
|
||||
id: number
|
||||
@@ -6,4 +8,6 @@ export class OrderModel {
|
||||
shippingProgress: number
|
||||
orderItems: Array<OrderItemModel>
|
||||
orderedAt: string
|
||||
payment: PaymentModel
|
||||
address: AddressModel
|
||||
}
|
||||
@@ -8,10 +8,14 @@ import { addOrder } from "../api/orderApi";
|
||||
import { useAccountStore } from "./accountStore";
|
||||
import { ProductModel } from "../models/productModel";
|
||||
import { useProductStore } from "./productStore";
|
||||
import { AddressModel } from "../models/addressModel";
|
||||
import { PaymentModel } from "../models/paymentModel";
|
||||
|
||||
export const useBasketStore = defineStore('basketStore', {
|
||||
state: () => ({
|
||||
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("hackmycart/basketStore/productsInBasket", [])
|
||||
itemsInBasket: useLocalStorage<Array<BasketItemModel>>("hackmycart/basketStore/productsInBasket", []),
|
||||
usedAddress: useLocalStorage("hackmycart/basketStore/usedAddress", new AddressModel()),
|
||||
usedPayment: useLocalStorage("hackmycart/basketStore/usedPayment", new PaymentModel())
|
||||
}),
|
||||
|
||||
getters: {
|
||||
@@ -73,12 +77,20 @@ export const useBasketStore = defineStore('basketStore', {
|
||||
async takeOrder() {
|
||||
const accountStore = useAccountStore()
|
||||
const productStore = useProductStore()
|
||||
const feedbackStore = useFeedbackStore()
|
||||
|
||||
await addOrder(accountStore.userAccount.id, this.itemsInBasket)
|
||||
this.itemsInBasket = []
|
||||
await addOrder(accountStore.userAccount.id, this.itemsInBasket, this.usedPayment.id, this.usedAddress.id)
|
||||
.then(async result => {
|
||||
if (result.status == 201) {
|
||||
await accountStore.refreshOrders()
|
||||
await productStore.fetchAllProducts()
|
||||
|
||||
await accountStore.refreshOrders()
|
||||
await productStore.fetchAllProducts()
|
||||
this.itemsInBasket = []
|
||||
feedbackStore.changeBanner(BannerStateEnum.ORDERPLACESUCCESSFUL)
|
||||
} else {
|
||||
feedbackStore.changeBanner(BannerStateEnum.ERROR)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -20,6 +20,7 @@ export const useFeedbackStore = defineStore("feedbackStore", {
|
||||
|
||||
actions: {
|
||||
changeBanner(bannerState: BannerStateEnum) {
|
||||
// Banner message
|
||||
switch (bannerState) {
|
||||
////////// System feedback //////////
|
||||
|
||||
@@ -107,6 +108,8 @@ export const useFeedbackStore = defineStore("feedbackStore", {
|
||||
}
|
||||
}
|
||||
|
||||
// Banner color
|
||||
|
||||
switch (bannerState) {
|
||||
case BannerStateEnum.ERROR:
|
||||
case BannerStateEnum.ACCOUNTLOGINERROR:
|
||||
@@ -118,9 +121,9 @@ export const useFeedbackStore = defineStore("feedbackStore", {
|
||||
case BannerStateEnum.PRODUCTDELETESUCCESSFUL:
|
||||
case BannerStateEnum.PRODUCTDELETEERROR:
|
||||
this.color = "red"
|
||||
this.icon = "mdi-alert-circle"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.BASKETPRODUCTADDED:
|
||||
case BannerStateEnum.DATABASERESETSUCCESSFUL:
|
||||
case BannerStateEnum.ACCOUNTLOGINSUCCESSFUL:
|
||||
case BannerStateEnum.ACCOUNTREGISTERSUCCESSFUL:
|
||||
@@ -132,10 +135,74 @@ export const useFeedbackStore = defineStore("feedbackStore", {
|
||||
case BannerStateEnum.PRODUCTCREATESUCCESSFUL:
|
||||
case BannerStateEnum.PRODUCTCREATEERROR:
|
||||
this.color = "green"
|
||||
this.icon = "mdi-check-circle"
|
||||
break
|
||||
break;
|
||||
|
||||
case BannerStateEnum.BASKETPRODUCTREMOVED:
|
||||
this.color = "blue"
|
||||
}
|
||||
|
||||
|
||||
// Banner icon
|
||||
|
||||
switch (bannerState) {
|
||||
case BannerStateEnum.ERROR:
|
||||
this.icon = "mdi-alert-circle"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.ACCOUNTLOGINERROR:
|
||||
case BannerStateEnum.ACCOUNTLOGINWRONGLOGIN:
|
||||
case BannerStateEnum.ACCOUNTREGISTERERROR:
|
||||
case BannerStateEnum.ACCOUNTREGISTERUSERNAMEINUSE:
|
||||
this.icon = "mdi-account"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.CATEGORYCREATEERROR:
|
||||
case BannerStateEnum.CATEGORYDELETEERROR:
|
||||
case BannerStateEnum.CATEGORYCREATESUCCESSFUL:
|
||||
case BannerStateEnum.CATEGORYDELETESUCESSFUL:
|
||||
this.icon = "mdi-label"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.PRODUCTDELETESUCCESSFUL:
|
||||
case BannerStateEnum.PRODUCTDELETEERROR:
|
||||
case BannerStateEnum.PRODUCTCREATESUCCESSFUL:
|
||||
case BannerStateEnum.PRODUCTCREATEERROR:
|
||||
this.icon = "mdi-store"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.DATABASERESETSUCCESSFUL:
|
||||
this.icon = "mdi-database-refresh"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.BASKETPRODUCTADDED:
|
||||
case BannerStateEnum.BASKETPRODUCTREMOVED:
|
||||
this.icon = "mdi-basket"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.ORDERPLACESUCCESSFUL:
|
||||
this.icon = "mdi-basket-check"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.ACCOUNTLOGOUTSUCCESSFUL:
|
||||
this.icon = "mdi-logout"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.ACCOUNTLOGINSUCCESSFUL:
|
||||
this.icon = "mdi-login"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.ACCOUNTREGISTERSUCCESSFUL:
|
||||
this.icon = "mdi-account-plus"
|
||||
break;
|
||||
|
||||
case BannerStateEnum.ACCOUNTUPDATESUCCESSFUL:
|
||||
this.icon = "mdi-account-reactivate"
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this.showBanner = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
"backToLogin": "Zurück zum Login",
|
||||
"delete": "Account löschen",
|
||||
"managingAccount": "Account verwalten",
|
||||
"addresses": "Adressen",
|
||||
"payments": "Bezahlarten",
|
||||
"address": "Adresse | Addressen",
|
||||
"payment": "Bezahlart | Bezahlarten",
|
||||
"masterData": "Stammdaten",
|
||||
"noAddresses": "Keine Adressen gefunden",
|
||||
"noPayments": "Keine Bezahlarten gefunden",
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
"register": "Create Account",
|
||||
"delete": "Delete Account",
|
||||
"managingAccount": "Managing Account",
|
||||
"addresses": "Addresses",
|
||||
"payments": "Payments",
|
||||
"address": "Address | Addresses",
|
||||
"payment": "Payment | Payments",
|
||||
"masterData": "Master data",
|
||||
"noAddresses": "No Addresses found",
|
||||
"noPayments": "No payments found",
|
||||
|
||||
@@ -9,12 +9,28 @@ const basketStore = useBasketStore()
|
||||
const accountStore = useAccountStore()
|
||||
const showDialog: ModelRef<boolean> = defineModel()
|
||||
const orderingInProgress = ref(false)
|
||||
const addressError = ref(false)
|
||||
const paymentError = ref(false)
|
||||
|
||||
async function doOrder() {
|
||||
orderingInProgress.value = true
|
||||
await basketStore.takeOrder()
|
||||
addressError.value = false
|
||||
paymentError.value = false
|
||||
|
||||
if (basketStore.usedAddress == null) {
|
||||
addressError.value = true
|
||||
}
|
||||
|
||||
if (basketStore.usedPayment == null){
|
||||
paymentError.value = true
|
||||
}
|
||||
|
||||
if (basketStore.usedAddress != null && basketStore.usedPayment != null) {
|
||||
|
||||
await basketStore.takeOrder()
|
||||
showDialog.value = false
|
||||
}
|
||||
|
||||
showDialog.value = false
|
||||
orderingInProgress.value = false
|
||||
}
|
||||
</script>
|
||||
@@ -25,29 +41,65 @@ async function doOrder() {
|
||||
icon="mdi-basket-check"
|
||||
v-model="showDialog"
|
||||
max-width="800"
|
||||
persistent
|
||||
>
|
||||
<v-row>
|
||||
<v-col>
|
||||
Address
|
||||
{{ $t('account.address', accountStore.userAccount.addresses.length) }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-radio-group>
|
||||
<v-radio-group
|
||||
v-model="basketStore.usedAddress"
|
||||
:error="addressError"
|
||||
>
|
||||
<v-radio
|
||||
v-for="address in accountStore.userAccount.addresses"
|
||||
:value="address"
|
||||
:label="address.street + ' ' + address.houseNumber + ', ' + address.postalCode + ' ' + address.city"
|
||||
|
||||
/>
|
||||
</v-radio-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
{{ $t('account.payment', accountStore.userAccount.payments.length) }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-radio-group
|
||||
v-model="basketStore.usedPayment"
|
||||
>
|
||||
<v-radio
|
||||
v-for="payment in accountStore.userAccount.payments"
|
||||
:value="payment"
|
||||
:label="payment.bankName + ': ' + payment.iban"
|
||||
:error="paymentError"
|
||||
/>
|
||||
</v-radio-group>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<template #actions>
|
||||
<outlined-button
|
||||
@click="showDialog = false"
|
||||
prepend-icon="mdi-close"
|
||||
color="orange"
|
||||
>
|
||||
{{ $t('dialog.cancel') }}
|
||||
</outlined-button>
|
||||
|
||||
<outlined-button
|
||||
@click="doOrder"
|
||||
:loading="orderingInProgress"
|
||||
prepend-icon="mdi-send"
|
||||
color="green"
|
||||
>
|
||||
{{ $t('ordering.takeOrder') }}
|
||||
</outlined-button>
|
||||
|
||||
@@ -36,46 +36,81 @@ function formatDateTimeString(string: string) {
|
||||
:subtitle="$t('totalPrice') + ': ' + accountStore.getOrderTotalPrice(order.id) + ' €'"
|
||||
>
|
||||
<template #withoutContainer>
|
||||
<v-timeline direction="horizontal" side="start" size="x-large">
|
||||
<v-timeline-item :dot-color="getDotColor(order, 1)" icon="mdi-basket-check">
|
||||
{{ $t('orders.ordered') }}
|
||||
</v-timeline-item>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-timeline direction="horizontal" side="start" size="x-large">
|
||||
<v-timeline-item :dot-color="getDotColor(order, 1)" icon="mdi-basket-check">
|
||||
{{ $t('orders.ordered') }}
|
||||
</v-timeline-item>
|
||||
|
||||
<v-timeline-item :dot-color="getDotColor(order, 2)" icon="mdi-package-variant">
|
||||
{{ $t('orders.preparingForShipping') }}
|
||||
</v-timeline-item>
|
||||
<v-timeline-item :dot-color="getDotColor(order, 2)" icon="mdi-package-variant">
|
||||
{{ $t('orders.preparingForShipping') }}
|
||||
</v-timeline-item>
|
||||
|
||||
<v-timeline-item :dot-color="getDotColor(order, 3)" icon="mdi-send">
|
||||
{{ $t('orders.shipped') }}
|
||||
</v-timeline-item>
|
||||
<v-timeline-item :dot-color="getDotColor(order, 3)" icon="mdi-send">
|
||||
{{ $t('orders.shipped') }}
|
||||
</v-timeline-item>
|
||||
|
||||
<v-timeline-item :dot-color="getDotColor(order, 4)" icon="mdi-truck-fast">
|
||||
{{ $t('orders.inDelivery') }}
|
||||
</v-timeline-item>
|
||||
<v-timeline-item :dot-color="getDotColor(order, 4)" icon="mdi-truck-fast">
|
||||
{{ $t('orders.inDelivery') }}
|
||||
</v-timeline-item>
|
||||
|
||||
<v-timeline-item :dot-color="getDotColor(order, 5)" icon="mdi-package-check">
|
||||
{{ $t('orders.delivered') }}
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
<v-timeline-item :dot-color="getDotColor(order, 5)" icon="mdi-package-check">
|
||||
{{ $t('orders.delivered') }}
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-table class="bg-surface-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('quantity') }}</th>
|
||||
<th>{{ $t('product.brand') }}</th>
|
||||
<th>{{ $t('product.productName') }}</th>
|
||||
<th>{{ $t('product.productPrice') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="orderItem in order.orderItems">
|
||||
<td>{{ orderItem.quantity }}x</td>
|
||||
<td>{{ orderItem.product.brand.name }}</td>
|
||||
<td>{{ orderItem.product.name }}</td>
|
||||
<td>{{ orderItem.product.price }} €</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-table>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-card variant="outlined" class="ml-5 pa-3">
|
||||
<div class="text-h6">
|
||||
<v-icon icon="mdi-home" />
|
||||
{{ $t('account.address', 1) }}
|
||||
</div>
|
||||
|
||||
<div class="pl-9">{{ order.address.street }} {{ order.address.houseNumber }}</div>
|
||||
<div class="pl-9">{{ order.address.postalCode }} {{ order.address.city }}</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
<v-col>
|
||||
<v-card variant="outlined" class="mr-5 pa-3">
|
||||
<div class="text-h6">
|
||||
<v-icon icon="mdi-currency-usd" />
|
||||
{{ $t('account.payment', 1) }}
|
||||
</div>
|
||||
<div class="pl-9">{{ order.payment.bankName }}</div>
|
||||
<div class="pl-9">{{ order.payment.iban }}</div>
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-table class="bg-surface-light">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $t('quantity') }}</th>
|
||||
<th>{{ $t('product.brand') }}</th>
|
||||
<th>{{ $t('product.productName') }}</th>
|
||||
<th>{{ $t('product.productPrice') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="orderItem in order.orderItems">
|
||||
<td>{{ orderItem.quantity }}x</td>
|
||||
<td>{{ orderItem.product.brand.name }}</td>
|
||||
<td>{{ orderItem.product.name }}</td>
|
||||
<td>{{ orderItem.product.price }} €</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-table>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
</card-view>
|
||||
</template>
|
||||
@@ -142,7 +142,7 @@ watch(() => props.product.images, () => {
|
||||
v-model="nrOfArticles"
|
||||
variant="outlined"
|
||||
:min="1"
|
||||
:max="10"
|
||||
:max="product.inStock"
|
||||
density="comfortable"
|
||||
:hide-details="true"
|
||||
:disabled="product.inStock == 0"
|
||||
|
||||
Reference in New Issue
Block a user