Table summary of orders
This commit is contained in:
20
src/App.vue
20
src/App.vue
@@ -1,10 +1,28 @@
|
||||
<template>
|
||||
<RouterView />
|
||||
<Suspense>
|
||||
<RouterView />
|
||||
</Suspense>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import './assets/style.scss'
|
||||
import { RouterView } from 'vue-router'
|
||||
import { watch } from 'vue'
|
||||
import { getActivePinia } from 'pinia'
|
||||
|
||||
const pinia = getActivePinia();
|
||||
|
||||
if(pinia != undefined) {
|
||||
watch(
|
||||
pinia.state,
|
||||
(state) => {
|
||||
// persist the whole state to the local storage whenever it changes
|
||||
localStorage.setItem('piniaState', JSON.stringify(state))
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -49,7 +49,3 @@ async function confirmOrder() {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -132,7 +132,3 @@ function cancelOrder(event: Event) {
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -10,7 +10,3 @@
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -44,7 +44,3 @@ function sendLogin() {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,12 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||
import { axiosInstance, type Category, type Contractor, type OrderProduct } from '@/main'
|
||||
import { axiosInstance, type Contractor, type OrderProduct } from '@/main'
|
||||
import { useCategoriesStore } from '@/stores/categories.store'
|
||||
import { useContractorsStore } from '@/stores/contractors.store'
|
||||
import { useOrdersStore } from '@/stores/orders.store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useSiteControlStore } from '@/stores/siteControl.store'
|
||||
import { ref } from 'vue'
|
||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
const categoriesStore = useCategoriesStore();
|
||||
const contractorsStore = useContractorsStore();
|
||||
@@ -17,26 +18,60 @@ const { contractor, contractors } = storeToRefs(contractorsStore);
|
||||
const { deliveryDate, uuid } = storeToRefs(ordersStore);
|
||||
const { categories } = storeToRefs(categoriesStore);
|
||||
const { showConfirmationModal, isDarkTheme } = storeToRefs(siteControlStore);
|
||||
|
||||
const contractorSearch = ref<string>();
|
||||
const filteredContractors = ref<Array<Contractor>>();
|
||||
const showContractorsDropdown = ref<boolean>(false);
|
||||
const contractorInput = ref(null);
|
||||
|
||||
const showErrorNotification = ref<boolean>(false);
|
||||
const errorNotificationMessage = ref<string>();
|
||||
const route = useRoute();
|
||||
|
||||
watch(contractor, (contractor) => {
|
||||
if(contractor == undefined) {
|
||||
contractorSearch.value = '';
|
||||
} else {
|
||||
contractorSearch.value = contractor.Knt_NipE + ', ' + contractor.Knt_Nazwa1 + contractor.Knt_Nazwa2 + contractor.Knt_Nazwa3;
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
function createJSON(event: Event) {
|
||||
event.preventDefault();
|
||||
console.log(route);
|
||||
const json = {
|
||||
MZN_UUID: uuid.value,
|
||||
MZN_DataZam: new Date(Date.now()).toISOString(),
|
||||
MZN_DataZam: new Date(Date.now()).toISOString().split('T')[0],
|
||||
MZN_DataDos: deliveryDate.value != undefined ? deliveryDate.value.toISOString() : null,
|
||||
MZN_PodID: contractor.value,
|
||||
MZN_PodID: contractor.value?.Knt_KntId,
|
||||
MZamElem: new Array<OrderProduct>
|
||||
};
|
||||
|
||||
if(categories.value == undefined) return;
|
||||
if(categories.value == undefined) {
|
||||
showErrorNotification.value=true;
|
||||
errorNotificationMessage.value = "Produkty nie zostały pobrane z bazy danych.";
|
||||
return;
|
||||
}
|
||||
|
||||
if(contractor.value == undefined) {
|
||||
showErrorNotification.value=true;
|
||||
errorNotificationMessage.value = "Klient nie został wybrany.";
|
||||
return;
|
||||
}
|
||||
|
||||
if(deliveryDate.value == undefined) {
|
||||
showErrorNotification.value=true;
|
||||
errorNotificationMessage.value = "Data dostawy nie została wybrana.";
|
||||
return;
|
||||
}
|
||||
|
||||
for (let category of categories.value) {
|
||||
for (let product of category.Towary) {
|
||||
if(product.Quantity != null && product.Quantity != '') {
|
||||
if(isNaN(Number(product.Quantity)) || isNaN(Number(product.Twr_CenaZ)) || isNaN(Number(product.Twr_Cena))) {
|
||||
showErrorNotification.value=true;
|
||||
return;
|
||||
errorNotificationMessage.value = "W zamówieniu znajdują się niepoprawne wartości.";
|
||||
return;
|
||||
}
|
||||
const productObject : OrderProduct = {
|
||||
MZE_TwrId: product.Twr_TwrId,
|
||||
@@ -54,10 +89,12 @@ function createJSON(event: Event) {
|
||||
}
|
||||
if(json.MZamElem.length == 0) {
|
||||
showErrorNotification.value=true;
|
||||
errorNotificationMessage.value = "Zamówienie jest puste.";
|
||||
return;
|
||||
}
|
||||
showErrorNotification.value=false;
|
||||
|
||||
console.log(json);
|
||||
console.log(JSON.stringify(json));
|
||||
axiosInstance.post('/zamowienie', JSON.stringify(json)).then( response => {
|
||||
uuid.value = response.data.MZN_UUID;
|
||||
});
|
||||
@@ -65,12 +102,64 @@ function createJSON(event: Event) {
|
||||
|
||||
function setConfirmationModal(event : Event) {
|
||||
event.preventDefault();
|
||||
if(uuid.value == undefined) {
|
||||
showErrorNotification.value=true;
|
||||
errorNotificationMessage.value = "Zamówienie nie zostało jeszcze zapisane w bazie danych.";
|
||||
return;
|
||||
}
|
||||
showConfirmationModal.value = true;
|
||||
}
|
||||
|
||||
function cancelOrder(event: Event) {
|
||||
event.preventDefault();
|
||||
axiosInstance.delete('/zamowienie/' + uuid.value);
|
||||
siteControlStore.newOrder();
|
||||
}
|
||||
|
||||
function filterContractors() {
|
||||
if (contractorSearch.value == "") {
|
||||
contractor.value = undefined;
|
||||
filteredContractors.value = contractors.value;
|
||||
return;
|
||||
}
|
||||
filteredContractors.value = contractors.value.filter(
|
||||
contractor =>
|
||||
(contractor.Knt_NipE + contractor.Knt_Nazwa1 + contractor.Knt_Nazwa2 + contractor.Knt_Nazwa3).toLowerCase().includes(contractorSearch.value as string)
|
||||
);
|
||||
}
|
||||
|
||||
function toggleContractorsDropdown() {
|
||||
if(!showContractorsDropdown.value) {
|
||||
showContractorsDropdown.value = true;
|
||||
if(contractorSearch.value == undefined || contractorSearch.value == '') {
|
||||
filteredContractors.value = contractors.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleClickOutsideDropdown(event : Event) {
|
||||
if(contractorInput.value != null && !contractorInput.value.contains(event.target)){
|
||||
showContractorsDropdown.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function selectContractorFromDropdown(selectedContractor : Contractor) {
|
||||
console.log(selectedContractor);
|
||||
contractor.value = selectedContractor;
|
||||
showContractorsDropdown.value = false;
|
||||
}
|
||||
|
||||
onMounted(function (){
|
||||
document.addEventListener('click', handleClickOutsideDropdown);
|
||||
});
|
||||
|
||||
onBeforeUnmount( function () {
|
||||
document.removeEventListener('click', handleClickOutsideDropdown);
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form class="box" @submit="createJSON">
|
||||
<form class="box" @submit.prevent="createJSON">
|
||||
<div class="mb-3">
|
||||
<div class="box">
|
||||
<div class="mb-3">
|
||||
@@ -78,12 +167,29 @@ function setConfirmationModal(event : Event) {
|
||||
<h1 class="subtitle is-5" v-if="uuid != undefined" ><b>{{ uuid }}</b></h1>
|
||||
</div>
|
||||
<div class="field mb-5">
|
||||
<label class="label is-small">NIP</label>
|
||||
<label class="label is-small">Klient</label>
|
||||
<div class="field">
|
||||
<div class="select is-small is-expanded" style="width: 100%">
|
||||
<select v-model="contractor" class="is-expanded" style="width: 100%" required>
|
||||
<option class="is-expanded" v-for="contractor in contractors" :key="contractor.Knt_KntId" :value="contractor">{{ contractor.Knt_NipE + ', ' + contractor.Knt_Miasto + ', ' + contractor.Knt_Nazwa1 + ' ' + contractor.Knt_Nazwa2 + ' ' + contractor.Knt_Nazwa3 }}</option>
|
||||
</select>
|
||||
<div ref="contractorInput" class="dropdown maxwidth"
|
||||
v-bind:class="{'is-active': showContractorsDropdown == true}">
|
||||
<div class="dropdown-trigger maxwidth" @click="toggleContractorsDropdown">
|
||||
<div class="field maxwidth" @onclick.prevent="toggleContractorsDropdown">
|
||||
<p class="control is-expanded has-icons-right is-small maxwidth" @onclick.prevent="toggleContractorsDropdown">
|
||||
<input class="input is-small is-expanded maxwidth" type="search"
|
||||
v-model="contractorSearch" @input="filterContractors" />
|
||||
<span class="icon is-small is-right"><i class="fas fa-search"></i></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown-menu is-clipped has-background-info-on-scheme-invert" id="dropdown-menu" role="menu" style="max-width: calc(100vw - 3rem); box-shadow: 0px 0px 6px -1px rgba(165, 165, 165, 0.8); border-radius: 10px 10px 10px 10px; overflow-x:auto">
|
||||
<div class="dropdown-content" style="max-height: 50vh; overflow-x: auto">
|
||||
<a v-if="filteredContractors != undefined && filteredContractors.length == 0" class="dropdown-item is-clipped">Brak wyników</a>
|
||||
<a v-for="dropdownContractor in filteredContractors" v-bind:key="dropdownContractor.Knt_KntId"
|
||||
class="dropdown-item is-clipped" @click = "selectContractorFromDropdown(dropdownContractor)"
|
||||
v-bind:class = "{'has-background-info' : dropdownContractor == contractor}">
|
||||
{{dropdownContractor.Knt_NipE + ', ' + dropdownContractor.Knt_Nazwa1 + dropdownContractor.Knt_Nazwa2 + dropdownContractor.Knt_Nazwa3}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -101,9 +207,10 @@ function setConfirmationModal(event : Event) {
|
||||
</div>
|
||||
<button class="button is-info mt-5">Zapisz</button>
|
||||
<button class="button is-success mt-5 ml-3" @click="setConfirmationModal">Potwierdź</button>
|
||||
<div v-if="showErrorNotification==true" class="notification is-danger is-light mt-5">
|
||||
<button class="button is-danger mt-5 ml-3" @click="cancelOrder" v-bind:disabled="uuid == undefined">Anuluj</button>
|
||||
<div v-if="showErrorNotification==true" class="notification is-danger is-bold mt-5">
|
||||
<button class="delete" @click.prevent="showErrorNotification = false"></button>
|
||||
W formularzu znajdują się pola, które nie są liczbami, lub wszystkie pola są puste.
|
||||
{{ errorNotificationMessage }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -120,7 +227,7 @@ function setConfirmationModal(event : Event) {
|
||||
type="text"
|
||||
placeholder="Kwota"
|
||||
v-model="product.Twr_Cena"
|
||||
v-bind:class="{ 'is-danger has-background-danger-90': product.Twr_Cena != undefined && isNaN(Number(product.Twr_Cena)),'is-success has-background-success-85': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"
|
||||
v-bind:class="{ 'is-danger has-background-danger-soft': product.Twr_Cena != undefined && isNaN(Number(product.Twr_Cena)),'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -131,7 +238,7 @@ function setConfirmationModal(event : Event) {
|
||||
type="text"
|
||||
placeholder="Kwota"
|
||||
v-model="product.Twr_CenaZ"
|
||||
v-bind:class="{ 'is-danger has-background-danger-90': product.Twr_CenaZ != undefined && isNaN(Number(product.Twr_CenaZ)), 'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))
|
||||
v-bind:class="{ 'is-danger has-background-danger-soft': product.Twr_CenaZ != undefined && isNaN(Number(product.Twr_CenaZ)), 'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
@@ -139,14 +246,14 @@ function setConfirmationModal(event : Event) {
|
||||
<div class="column">
|
||||
<div class="field has-addons">
|
||||
<p class="control">
|
||||
<span class="select is-small" v-bind:class="{ 'is-danger has-background-danger-90': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}">
|
||||
<select v-model="product.ChosenOption" v-bind:class="{ 'is-danger has-background-danger-90': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}">
|
||||
<span class="select is-small" v-bind:class="{ 'is-danger': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}">
|
||||
<select v-model="product.ChosenOption" v-bind:class="{ 'is-danger has-background-danger-soft': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}">
|
||||
<option v-for="option in product.Options" :key="option">{{ option }}</option>
|
||||
</select>
|
||||
</span>
|
||||
</p>
|
||||
<p class="control is-expanded">
|
||||
<input class="input is-small" type="text" placeholder="Ilość" v-model="product.Quantity" v-bind:class="{ 'is-danger has-background-danger-90': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-90': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}">
|
||||
<input class="input is-small" type="text" placeholder="Ilość" v-model="product.Quantity" v-bind:class="{ 'is-danger has-background-danger-soft': product.Quantity != undefined && isNaN(Number(product.Quantity)),'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -174,7 +281,8 @@ function setConfirmationModal(event : Event) {
|
||||
--dp-menu-border-color: var(--bulma-border);
|
||||
--dp-border-color-hover: var(--bulma-border);
|
||||
--dp-border-color-focus: var(--bulma-border);
|
||||
--dp-primary-color: var(--bulma-info-00);
|
||||
--dp-primary-color: var(--bulma-info);
|
||||
--dp-primary-text-color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,4 +296,8 @@ function setConfirmationModal(event : Event) {
|
||||
--dp-primary-text-color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.maxwidth {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -19,14 +19,13 @@ const userStore = useUserStore();
|
||||
|
||||
const { username } = storeToRefs(userStore);
|
||||
|
||||
|
||||
function makeBurger() {
|
||||
activator.value = !activator.value
|
||||
return activator
|
||||
}
|
||||
|
||||
function clickForm() {
|
||||
siteControlStore.switchToFrom();
|
||||
siteControlStore.switchToForm();
|
||||
if(activator.value) {
|
||||
activator.value = false;
|
||||
}
|
||||
@@ -39,27 +38,21 @@ function clickOrders() {
|
||||
}
|
||||
}
|
||||
|
||||
function clickTable() {
|
||||
siteControlStore.switchToTable();
|
||||
if(activator.value) {
|
||||
activator.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function routeLogin() {
|
||||
axiosInstance.post('/logout');
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
function newOrder() {
|
||||
const {order, uuid, deliveryDate, orderDate } = storeToRefs(ordersStore);
|
||||
const { contractor } = storeToRefs(contractorsStore);
|
||||
contractor.value = undefined;
|
||||
order.value = undefined;
|
||||
uuid.value = undefined;
|
||||
deliveryDate.value = undefined;
|
||||
orderDate.value = undefined;
|
||||
categoriesStore.fetchCategories();
|
||||
siteControlStore.switchToFrom();
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<nav class="navbar has-shadow" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item is-overflow-hidden" style="max-width: calc(100vw - 50px); white-space: nowrap; overflow: hidden">
|
||||
<h3 class="title is-4">Mleczarnia</h3>
|
||||
@@ -81,15 +74,17 @@ function newOrder() {
|
||||
<a class="navbar-item" @click="clickOrders">
|
||||
Zamówienia
|
||||
</a>
|
||||
<a class="navbar-item" @click="clickTable">
|
||||
Tabela
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<div class="buttons">
|
||||
<button class="button is-info" @click="newOrder">
|
||||
<button class="button is-info" @click="siteControlStore.newOrder">
|
||||
Nowe Zamówienie
|
||||
</button>
|
||||
<button class="button is-light" @click="routeLogin" >
|
||||
<button class="button is-info" @click="routeLogin" >
|
||||
Wyloguj
|
||||
</button>
|
||||
</div>
|
||||
@@ -98,7 +93,3 @@ function newOrder() {
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,17 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||
import { ref, watch } from 'vue'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useOrdersStore } from '@/stores/orders.store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useSiteControlStore } from '@/stores/siteControl.store'
|
||||
|
||||
const ordersStore = useOrdersStore();
|
||||
const siteControlStore = useSiteControlStore();
|
||||
const searchOrderDate = ref<Date>();
|
||||
const searchOrderDate = ref<Array<Date>>();
|
||||
const isOutOfBuffer = ref<boolean>(false);
|
||||
const isInBufor = ref<boolean>(false);
|
||||
const { orders } = storeToRefs(ordersStore);
|
||||
const areOrdersLoading = ref<boolean>(false);
|
||||
const { isDarkTheme } = storeToRefs(siteControlStore);
|
||||
|
||||
watch(isInBufor, (val) => {
|
||||
if(val && val == isOutOfBuffer.value) {
|
||||
@@ -29,6 +30,12 @@ watch(isOutOfBuffer, (val) => {
|
||||
immediate: true
|
||||
});
|
||||
|
||||
const buffer = computed(()=>{
|
||||
if (!isInBufor.value && !isOutOfBuffer.value) {
|
||||
return null;
|
||||
} else return !!isInBufor.value;
|
||||
});
|
||||
|
||||
function viewOrder(uuid : string) {
|
||||
siteControlStore.viewOrder(uuid);
|
||||
}
|
||||
@@ -36,10 +43,13 @@ function viewOrder(uuid : string) {
|
||||
async function fetchOrders(event : Event) {
|
||||
event.preventDefault();
|
||||
areOrdersLoading.value = true;
|
||||
if(isInBufor.value) {
|
||||
orders.value = await ordersStore.fetchOrdersInBuffer();
|
||||
} else if (isOutOfBuffer.value) {
|
||||
orders.value = await ordersStore.fetchOrdersOutOfBuffer();
|
||||
console.log(searchOrderDate.value);
|
||||
|
||||
if(searchOrderDate.value == undefined) {
|
||||
orders.value = await ordersStore.fetchOrdersByBuffer(buffer.value);
|
||||
}
|
||||
if(searchOrderDate.value != undefined) {
|
||||
orders.value = await ordersStore.fetchOrdersByDateStartAndEnd(searchOrderDate.value[0], searchOrderDate.value[1], buffer.value);
|
||||
}
|
||||
areOrdersLoading.value = false;
|
||||
}
|
||||
@@ -57,7 +67,10 @@ async function fetchOrders(event : Event) {
|
||||
<VueDatePicker v-model="searchOrderDate"
|
||||
:enable-time-picker="false"
|
||||
:clearable="true"
|
||||
input-class-name="input is-small"/>
|
||||
input-class-name="input is-small calendar-background"
|
||||
menu-class-name="calendar-background"
|
||||
v-bind:dark = "isDarkTheme"
|
||||
range/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field mb-5">
|
||||
@@ -73,15 +86,14 @@ async function fetchOrders(event : Event) {
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button class="button is-primary is-small is-expanded" @click="fetchOrders" :class="{ 'is-loading': areOrdersLoading }">Pobierz zamówienia</button>
|
||||
<button class="button is-info is-small is-expanded" @click="fetchOrders" :class="{ 'is-loading': areOrdersLoading }">Pobierz zamówienia</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="box">
|
||||
<h1 class="is-large mb-3"><b>ZAMÓWIENIA</b></h1>
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-4" v-for="order in orders" :key="order.MZN_UUID">
|
||||
<div class="box">
|
||||
<!-- <h1 class="mb-3 is-size-7"><b>{{ order.MZN_UUID }}</b></h1>-->
|
||||
<div class="box" :class="{'confirmed' : order.MZN_Bufor == 0 && order.MZN_Anulowane != 1, 'cancelled' : order.MZN_Anulowane == 1}">
|
||||
<label class="label is-small">Klient</label>
|
||||
<div class="field is-small mb-3">
|
||||
<input class="input is-small is-static"
|
||||
@@ -122,7 +134,7 @@ async function fetchOrders(event : Event) {
|
||||
value="Nie"
|
||||
readonly/>
|
||||
</div>
|
||||
<button class="button is-primary is-small is-expanded" @click="viewOrder(order.MZN_UUID)" :name="order.MZN_UUID">Podgląd</button>
|
||||
<button class="button is-info is-small is-expanded" @click="viewOrder(order.MZN_UUID)" :name="order.MZN_UUID">Podgląd</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -130,6 +142,34 @@ async function fetchOrders(event : Event) {
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style>
|
||||
@media (prefers-color-scheme: dark){
|
||||
.calendar-background {
|
||||
--dp-background-color: rgb(20, 22, 26);
|
||||
--dp-border-color: var(--bulma-border);
|
||||
--dp-menu-border-color: var(--bulma-border);
|
||||
--dp-border-color-hover: var(--bulma-border);
|
||||
--dp-border-color-focus: var(--bulma-border);
|
||||
--dp-primary-color: var(--bulma-info);
|
||||
--dp-primary-text-color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light){
|
||||
.calendar-background {
|
||||
--dp-border-color: var(--bulma-border);
|
||||
--dp-menu-border-color: var(--bulma-border);
|
||||
--dp-border-color-hover: var(--bulma-border);
|
||||
--dp-border-color-focus: var(--bulma-border);
|
||||
--dp-primary-color: var(--bulma-info);
|
||||
--dp-primary-text-color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.cancelled {
|
||||
--bulma-box-background-color: var(--bulma-danger-soft)
|
||||
}
|
||||
.confirmed {
|
||||
--bulma-box-background-color: var(--bulma-success-soft)
|
||||
}
|
||||
</style>
|
||||
19
src/main.ts
19
src/main.ts
@@ -1,4 +1,4 @@
|
||||
import { createApp } from 'vue';
|
||||
import { createApp, watch } from 'vue'
|
||||
import App from './App.vue';
|
||||
import VueDatePicker from '@vuepic/vue-datepicker';
|
||||
import '@vuepic/vue-datepicker/dist/main.css';
|
||||
@@ -24,10 +24,18 @@ const pinia = createPinia();
|
||||
app.use(pinia);
|
||||
app.use(VueCookies);
|
||||
app.use(router);
|
||||
useOrdersStore();
|
||||
useContractorsStore();
|
||||
useCategoriesStore();
|
||||
useSiteControlStore();
|
||||
|
||||
if(localStorage.getItem('piniaState')) {
|
||||
pinia.state.value = JSON.parse(localStorage.getItem('piniaState') as string);
|
||||
}
|
||||
|
||||
watch (
|
||||
() => pinia.state.value,
|
||||
(state) => {
|
||||
localStorage.setItem('piniaState', JSON.stringify(state));
|
||||
},
|
||||
{deep: true}
|
||||
)
|
||||
|
||||
|
||||
export const axiosInstance = axios.create({
|
||||
@@ -103,6 +111,7 @@ export interface Contractor {
|
||||
|
||||
export interface Order {
|
||||
MZN_Bufor: number,
|
||||
MZN_Anulowane: number,
|
||||
MZN_DataDos: string,
|
||||
MZN_DataZam: string,
|
||||
MZN_MZNID: number,
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
|
||||
import { MainView, LoginView } from '@/views';
|
||||
import { MainView, LoginView, SummedOrdersView } from '@/views';
|
||||
|
||||
export const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
linkActiveClass: 'active',
|
||||
routes: [
|
||||
{ path: '/', component: MainView },
|
||||
{ path: '/login', component: LoginView }
|
||||
{ path: '/login', component: LoginView },
|
||||
{ path: '/table', component: SummedOrdersView, },
|
||||
]
|
||||
});
|
||||
|
||||
router.beforeEach(async (to) => {
|
||||
// redirect to login page if not logged in and trying to access a restricted page
|
||||
const publicPages = ['/login'];
|
||||
const authRequired = !publicPages.includes(to.path);
|
||||
//
|
||||
// if (authRequired) {
|
||||
// return '/login';
|
||||
// }
|
||||
});
|
||||
|
||||
@@ -4,40 +4,52 @@ import { type Ref, ref } from 'vue'
|
||||
import { axiosInstance } from '@/main'
|
||||
|
||||
export const useOrdersStore = defineStore('orders', () => {
|
||||
const orders = ref<Array<Order>>([]);
|
||||
const orders = ref<Array<Order>>();
|
||||
const order = ref<Order>();
|
||||
const uuid = ref<string>();
|
||||
const deliveryDate = ref<Date>();
|
||||
const orderDate = ref<Date>();
|
||||
|
||||
async function fetchOrders() {
|
||||
orders.value=[];
|
||||
let ordersTemp : Array<Order> = await fetchOrdersInBuffer();
|
||||
orders.value.push(...ordersTemp);
|
||||
ordersTemp = await fetchOrdersOutOfBuffer();
|
||||
orders.value.push(...ordersTemp);
|
||||
}
|
||||
|
||||
async function fetchOrdersOutOfBuffer() : Promise<Array<Order>> {
|
||||
const response = await axiosInstance.get('/zamowienia', {withCredentials: true});
|
||||
const ordersTemp : Array<Order> = response.data;
|
||||
return ordersTemp;
|
||||
}
|
||||
|
||||
async function fetchOrdersInBuffer() : Promise<Array<Order>> {
|
||||
const response = await axiosInstance.get('/zamowienia/bufor', {withCredentials: true});
|
||||
async function fetchOrdersByBuffer(inBuffer : boolean | null) {
|
||||
let urlString = '/zamowienia';
|
||||
if(inBuffer != null) {
|
||||
urlString += '?bufor=' + Number(inBuffer).toString();
|
||||
}
|
||||
const response = await axiosInstance.get(urlString, {withCredentials: true});
|
||||
const ordersTemp : Array<Order> = response.data;
|
||||
return ordersTemp;
|
||||
}
|
||||
|
||||
async function fetchOrder(uuid : string) {
|
||||
async function fetchOrdersByDateStartAndEnd(dateStart : Date, dateEnd : Date, inBuffer : boolean | null) {
|
||||
let urlString = '/zamowienia?od=' + dateStart.toISOString().split('T')[0] + '&do=' + dateEnd.toISOString().split('T')[0]
|
||||
if(inBuffer != null) {
|
||||
urlString += '&bufor=' + Number(inBuffer).toString();
|
||||
}
|
||||
const response = await axiosInstance.get(urlString, {withCredentials: true});
|
||||
const ordersTemp : Array<Order> = response.data;
|
||||
return ordersTemp;
|
||||
}
|
||||
|
||||
async function fetchOrdersByDay(date : Date, inBuffer : boolean | null) {
|
||||
let urlString = "/zamowienia/" + date.toISOString().split("T")[0];
|
||||
console.log(urlString);
|
||||
if(inBuffer != null) {
|
||||
urlString += '?bufor=' + Number(inBuffer).toString();
|
||||
}
|
||||
const response = await axiosInstance.get(urlString, {withCredentials: true});
|
||||
const ordersTemp : Array<Order> = response.data;
|
||||
return ordersTemp;
|
||||
}
|
||||
|
||||
async function loadOrder(uuidString: string, confirmed: boolean, contractor: Ref<Contractor|undefined>, contractors: Ref<Array<Contractor>>, categories: Ref<Array<Category>>) {
|
||||
const response = await axiosInstance.get('/zamowienie/' + uuidString);
|
||||
const tempOrder = response.data;
|
||||
|
||||
console.log(tempOrder);
|
||||
|
||||
if(confirmed) {
|
||||
@@ -58,8 +70,14 @@ export const useOrdersStore = defineStore('orders', () => {
|
||||
for(const category of categories.value) {
|
||||
const product = category.Towary.find(product => (product.Twr_TwrId == orderProduct.MZE_TwrId));
|
||||
if(product != undefined && orderProduct.MZE_TwrCena != null) {
|
||||
product.Twr_Cena = orderProduct.MZE_TwrCena.slice(0, -2);
|
||||
console.log(product);
|
||||
if(orderProduct.MZE_TwrJm == product.Twr_JM) {
|
||||
product.Twr_Cena = orderProduct.MZE_TwrCena.slice(0, -2);
|
||||
} else if(orderProduct.Twr_Cena == product.Twr_JMZ) {
|
||||
product.Twr_CenaZ = orderProduct.MZE_TwrCena.slice(0, -2);
|
||||
}
|
||||
product.Quantity = orderProduct.MZE_TwrIlosc.slice(0, -2);
|
||||
product.ChosenOption = orderProduct.MZE_TwrJm;
|
||||
category.isVisible = true;
|
||||
break;
|
||||
}
|
||||
@@ -67,5 +85,5 @@ export const useOrdersStore = defineStore('orders', () => {
|
||||
}
|
||||
}
|
||||
|
||||
return {orders, order, uuid, deliveryDate, orderDate, fetchOrders, fetchOrdersInBuffer, fetchOrdersOutOfBuffer, loadOrder}
|
||||
return {orders, order, uuid, deliveryDate, orderDate, fetchOrders, loadOrder, fetchOrdersByDay, fetchOrdersByBuffer, fetchOrdersByDateStartAndEnd}
|
||||
})
|
||||
@@ -4,34 +4,42 @@ import { useOrdersStore } from '@/stores/orders.store'
|
||||
import type { Order } from '@/main'
|
||||
import { useContractorsStore } from '@/stores/contractors.store'
|
||||
import { useCategoriesStore } from '@/stores/categories.store'
|
||||
import { router } from '@/router/router'
|
||||
|
||||
export const useSiteControlStore = defineStore('siteControl', () => {
|
||||
const isForm = ref<boolean>(true);
|
||||
const isOrders = ref<boolean>(false);
|
||||
const shownComponent = ref<string>('mainForm');
|
||||
const showConfirmationModal = ref<boolean>(false);
|
||||
const isDarkTheme = ref<boolean>(false);
|
||||
const isLoading = ref<boolean>(true);
|
||||
|
||||
|
||||
function switchToFrom() {
|
||||
if(!isForm.value) {
|
||||
isForm.value = true;
|
||||
isOrders.value = false;
|
||||
function switchToForm() {
|
||||
shownComponent.value = "mainForm";
|
||||
if(router.currentRoute.value.fullPath != "/") {
|
||||
router.push("/");
|
||||
}
|
||||
}
|
||||
|
||||
async function switchToOrders() {
|
||||
if(!isOrders.value) {
|
||||
if(shownComponent.value != 'orderSelector') {
|
||||
const orderStore = useOrdersStore();
|
||||
const { orders } = storeToRefs(orderStore);
|
||||
isLoading.value = true;
|
||||
isForm.value = false;
|
||||
isOrders.value = true;
|
||||
shownComponent.value = "orderSelector"
|
||||
orders.value = new Array<Order>();
|
||||
orders.value.push(... await orderStore.fetchOrdersInBuffer());
|
||||
orders.value.push(... await orderStore.fetchOrdersOutOfBuffer());
|
||||
orders.value = await orderStore.fetchOrders();
|
||||
isLoading.value = false;
|
||||
}
|
||||
if(router.currentRoute.value.fullPath != "/") {
|
||||
router.push("/");
|
||||
}
|
||||
}
|
||||
|
||||
async function switchToTable() {
|
||||
if(router.currentRoute.value.fullPath != "/table") {
|
||||
shownComponent.value = "table"
|
||||
router.push("/table");
|
||||
}
|
||||
}
|
||||
|
||||
function checkTheme() {
|
||||
@@ -42,15 +50,31 @@ export const useSiteControlStore = defineStore('siteControl', () => {
|
||||
const orderStore = useOrdersStore();
|
||||
const contractorsStore = useContractorsStore();
|
||||
const categoriesStore = useCategoriesStore();
|
||||
isForm.value = true;
|
||||
isOrders.value = false;
|
||||
shownComponent.value = "mainForm";
|
||||
isLoading.value = true;
|
||||
window.scrollTo(0, 0);
|
||||
await categoriesStore.fetchCategories();
|
||||
const { contractor, contractors } = storeToRefs(contractorsStore);
|
||||
const { categories } = storeToRefs(categoriesStore);
|
||||
await orderStore.loadOrder(uuid, false, contractor, contractors, categories);
|
||||
isLoading.value=false;
|
||||
}
|
||||
|
||||
return {isForm, isOrders, isLoading, showConfirmationModal, isDarkTheme, switchToFrom, switchToOrders, checkTheme, viewOrder};
|
||||
function newOrder() {
|
||||
const ordersStore = useOrdersStore();
|
||||
const contractorsStore = useContractorsStore();
|
||||
const categoriesStore = useCategoriesStore();
|
||||
const { order, uuid, deliveryDate, orderDate } = storeToRefs(ordersStore);
|
||||
const { contractor } = storeToRefs(contractorsStore);
|
||||
contractor.value = undefined;
|
||||
order.value = undefined;
|
||||
uuid.value = undefined;
|
||||
deliveryDate.value = undefined;
|
||||
orderDate.value = undefined;
|
||||
categoriesStore.fetchCategories();
|
||||
switchToForm();
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
|
||||
return {isLoading, showConfirmationModal, isDarkTheme, shownComponent, switchToForm, switchToOrders, switchToTable, checkTheme, viewOrder, newOrder};
|
||||
})
|
||||
@@ -12,15 +12,12 @@ const schema = Yup.object().shape({
|
||||
});
|
||||
|
||||
async function onSubmit(values : any, { setErrors } : any) {
|
||||
const { username, password, errors } = values;
|
||||
|
||||
console.log(username + ' ' + password);
|
||||
const { username, password } = values;
|
||||
|
||||
const body = await axiosInstance.post('/login', {
|
||||
username: username,
|
||||
password: password
|
||||
}).catch ((error) => {
|
||||
console.log(error.response);
|
||||
if(error.response.status == 401) {
|
||||
setErrors({ apiError: "unauthorized" })
|
||||
}
|
||||
@@ -77,7 +74,3 @@ async function onSubmit(values : any, { setErrors } : any) {
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -4,23 +4,24 @@
|
||||
<div v-if="isLoading">
|
||||
<LoadingComponent/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="isForm">
|
||||
<div>
|
||||
<div v-if="shownComponent == 'mainForm'">
|
||||
<MainForm
|
||||
v-if="order == undefined || order.MZN_Bufor==1"
|
||||
/>
|
||||
<ConfirmedForm v-else-if="order.MZN_Bufor==0"/>
|
||||
</div>
|
||||
<OrdersSelector class="box is-shadowless" v-else-if="isOrders"
|
||||
<OrdersSelector class="box is-shadowless" v-else-if="shownComponent == 'orderSelector'"
|
||||
/>
|
||||
</div>
|
||||
<ConfirmationModal v-show="showConfirmationModal" @close="showConfirmationModal = false" @confirm="closeConfirmationModal" :order-uuid="uuid"></ConfirmationModal>
|
||||
<button class="button" @click="test">test</button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import '@/assets/base.css'
|
||||
import { useContractorsStore } from '@/stores/contractors.store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { getActivePinia, storeToRefs } from 'pinia'
|
||||
import { useCategoriesStore } from '@/stores/categories.store'
|
||||
import { useOrdersStore } from '@/stores/orders.store'
|
||||
import { useSiteControlStore } from '@/stores/siteControl.store'
|
||||
@@ -36,7 +37,7 @@ const contractor = storeToRefs(contractorsStore).contractor;
|
||||
const categories = storeToRefs(categoriesStore).categories;
|
||||
const { uuid, order } = storeToRefs(ordersStore);
|
||||
const { username } = storeToRefs(userStore);
|
||||
const { isForm, isOrders, showConfirmationModal, isLoading } = storeToRefs(siteControlStore);
|
||||
const { isForm, isOrders, showConfirmationModal, isLoading, shownComponent } = storeToRefs(siteControlStore);
|
||||
|
||||
|
||||
async function fetchData() {
|
||||
@@ -49,6 +50,10 @@ async function fetchData() {
|
||||
isLoading.value = false;
|
||||
}
|
||||
|
||||
function test() {
|
||||
console.log(getActivePinia());
|
||||
}
|
||||
|
||||
function closeConfirmationModal() {
|
||||
showConfirmationModal.value = false;
|
||||
if (uuid.value != undefined) {
|
||||
@@ -57,6 +62,7 @@ function closeConfirmationModal() {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(localStorage.getItem('piniaState'));
|
||||
siteControlStore.checkTheme();
|
||||
fetchData();
|
||||
</script>
|
||||
|
||||
90
src/views/SummedOrdersView.vue
Normal file
90
src/views/SummedOrdersView.vue
Normal file
@@ -0,0 +1,90 @@
|
||||
<script setup lang="ts">
|
||||
import { useOrdersStore } from '@/stores/orders.store'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useRoute } from 'vue-router'
|
||||
import NavBar from '@/components/NavBar.vue'
|
||||
import VueDatePicker from '@vuepic/vue-datepicker'
|
||||
import { useSiteControlStore } from '@/stores/siteControl.store'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const ordersStore = useOrdersStore();
|
||||
const siteControlStore = useSiteControlStore();
|
||||
|
||||
const { orders } = storeToRefs(ordersStore);
|
||||
const { isDarkTheme } = storeToRefs(siteControlStore);
|
||||
const searchDate = ref<Date>();
|
||||
const confirmedOrders = ref<boolean>();
|
||||
|
||||
|
||||
orders.value = await ordersStore.fetchOrdersByDay(new Date(Date.now()), null);
|
||||
|
||||
const route = useRoute();
|
||||
console.log(route);
|
||||
|
||||
async function fetchOrders() {
|
||||
console.log((confirmedOrders.value) ? true : null);
|
||||
orders.value = await ordersStore.fetchOrdersByDateStartAndEnd(searchDate.value != undefined ? searchDate.value : new Date(Date.now()),
|
||||
searchDate.value != undefined ? searchDate.value : new Date(Date.now()),
|
||||
(confirmedOrders.value) ? true : null);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NavBar/>
|
||||
<div class="columns box is-shadowless">
|
||||
<div class="column box mr-3">
|
||||
<h1 class="title is-4 mb-3">Opcje</h1>
|
||||
<label class="label is-small">Data dostawy</label>
|
||||
<VueDatePicker v-model="searchDate"
|
||||
:enable-time-picker="false"
|
||||
:clearable="true"
|
||||
input-class-name="input is-small calendar-background"
|
||||
menu-class-name="calendar-background"
|
||||
v-bind:dark = "isDarkTheme" />
|
||||
|
||||
<div class="control mt-3">
|
||||
<label class="checkbox mr-5">
|
||||
<input type="checkbox" v-model="confirmedOrders"/>
|
||||
Tylko potwierdzone zamówienia?
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<button class="button mt-3" @click="fetchOrders">Potwierdź</button>
|
||||
</div>
|
||||
<div class="column is-four-fifths is-flex is-align-content-center box is-justify-content-center">
|
||||
<table class="table blackBorder">
|
||||
<thead>
|
||||
<tr class="has-background-grey-light">
|
||||
<th>Nazwa produktu</th>
|
||||
<th>Ilość</th>
|
||||
<th>Jednostka miary</th>
|
||||
<th>Cena jednostkowa</th>
|
||||
<th>Cena całkowita</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-for="order in orders" :key="order.MZN_UUID">
|
||||
<tr class="has-background-grey-lighter">
|
||||
<th colspan="5">
|
||||
{{ order.MZN_PodNazwa1 + order.MZN_PodNazwa2 + order.MZN_PodNazwa3 + order.MZN_DataDos.toString()}}
|
||||
</th>
|
||||
</tr>
|
||||
<tr v-for="product in order.MZamElem" :key="product.MZE_MZEID">
|
||||
<th>{{ product.MZE_TwrNazwa }}</th>
|
||||
<th>{{ Number(product.MZE_TwrIlosc).toFixed(2) }}</th>
|
||||
<th>{{ product.MZE_TwrJm }}</th>
|
||||
<th>{{ Number(product.MZE_TwrCena).toFixed(2) }}</th>
|
||||
<th>{{ (Number(product.MZE_TwrCena) * Number(product.MZE_TwrIlosc)).toFixed(2) }}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.blackBorder {
|
||||
--bulma-table-cell-border-color : black;
|
||||
}
|
||||
</style>
|
||||
@@ -1,2 +1,3 @@
|
||||
export { default as LoginView } from "./LoginView.vue";
|
||||
export { default as MainView } from "./MainView.vue";
|
||||
export { default as SummedOrdersView } from "./SummedOrdersView.vue"
|
||||
|
||||
Reference in New Issue
Block a user