Compare commits
	
		
			41 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d6750c015f | |||
| 7a00b146bd | |||
| 424aae99a0 | |||
| 0ccb091125 | |||
| 1c9e824459 | |||
| cd92389110 | |||
| 2fcf4fa9f2 | |||
| df969e35a7 | |||
| 42f101b505 | |||
| d6384abed3 | |||
| 8be432c150 | |||
| 51ef4b0691 | |||
| a073e88632 | |||
| 4234c1dd80 | |||
| 41c13f208c | |||
| 4be55d4a4a | |||
| f636540034 | |||
| df0bbe8e3f | |||
| 2689f227b7 | |||
| 81d7b1f832 | |||
| 9a060b8464 | |||
| 406cfebb93 | |||
| ba5e4a5376 | |||
| 2d0d27b502 | |||
| eeac03235b | |||
| 8140233e3a | |||
| d7e28cd926 | |||
| ce89b79074 | |||
| feee47f464 | |||
| ff3b22fb1b | |||
| bbec759b08 | |||
| 200242252c | |||
| 673eb10b7b | |||
| 15271a873b | |||
| dce8e294c5 | |||
| 2a06bb27ab | |||
| 87c8579e9e | |||
| 93c015fcb7 | |||
| 2fecc061e2 | |||
| a289c8dd0f | |||
| a3ec0fa06d | 
							
								
								
									
										31
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | /* eslint-disable */ | ||||||
|  | // @ts-nocheck | ||||||
|  | // Generated by unplugin-vue-components | ||||||
|  | // Read more: https://github.com/vuejs/core/pull/3399 | ||||||
|  | export {} | ||||||
|  |  | ||||||
|  | /* prettier-ignore */ | ||||||
|  | declare module 'vue' { | ||||||
|  |   export interface GlobalComponents { | ||||||
|  |     CancelationModal: typeof import('./src/components/CancelationModal.vue')['default'] | ||||||
|  |     Column: typeof import('primevue/column')['default'] | ||||||
|  |     ColumnGroup: typeof import('primevue/columngroup')['default'] | ||||||
|  |     ConfirmationModal: typeof import('./src/components/ConfirmationModal.vue')['default'] | ||||||
|  |     ConfirmedForm: typeof import('./src/components/ConfirmedForm.vue')['default'] | ||||||
|  |     DataTable: typeof import('primevue/datatable')['default'] | ||||||
|  |     IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default'] | ||||||
|  |     IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default'] | ||||||
|  |     IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default'] | ||||||
|  |     IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default'] | ||||||
|  |     IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default'] | ||||||
|  |     LoadingComponent: typeof import('./src/components/LoadingComponent.vue')['default'] | ||||||
|  |     LoginModal: typeof import('./src/components/LoginModal.vue')['default'] | ||||||
|  |     MainForm: typeof import('./src/components/MainForm.vue')['default'] | ||||||
|  |     NavBar: typeof import('./src/components/NavBar.vue')['default'] | ||||||
|  |     OrdersSelector: typeof import('./src/components/OrdersSelector.vue')['default'] | ||||||
|  |     RouterLink: typeof import('vue-router')['RouterLink'] | ||||||
|  |     RouterView: typeof import('vue-router')['RouterView'] | ||||||
|  |     Row: typeof import('primevue/row')['default'] | ||||||
|  |     SummaryComponent: typeof import('./src/components/SummaryComponent.vue')['default'] | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -4,9 +4,9 @@ | |||||||
|     <meta charset="UTF-8"> |     <meta charset="UTF-8"> | ||||||
|     <link rel="icon" href="/favicon.ico"> |     <link rel="icon" href="/favicon.ico"> | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|     <title>Vite App</title> |     <title>Mleczarnia Kuzma</title> | ||||||
|   </head> |   </head> | ||||||
|   <body> |   <body class="has-navbar-fixed-top"> | ||||||
|     <div id="app"></div> |     <div id="app"></div> | ||||||
|     <script type="module" src="/src/main.ts"></script> |     <script type="module" src="/src/main.ts"></script> | ||||||
|   </body> |   </body> | ||||||
|   | |||||||
							
								
								
									
										1326
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1326
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								package.json
									
									
									
									
									
								
							| @@ -13,13 +13,23 @@ | |||||||
|     "format": "prettier --write src/" |     "format": "prettier --write src/" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "@fortawesome/fontawesome-svg-core": "^6.6.0", | ||||||
|  |     "@primevue/themes": "^4.0.4", | ||||||
|     "@vuepic/vue-datepicker": "^8.7.0", |     "@vuepic/vue-datepicker": "^8.7.0", | ||||||
|     "bulma": "^1.0.1", |     "axios": "^1.7.2", | ||||||
|  |     "bulma": "^1.0.3", | ||||||
|     "cors": "^2.8.5", |     "cors": "^2.8.5", | ||||||
|  |     "pinia": "^2.1.7", | ||||||
|  |     "primevue": "^4.0.4", | ||||||
|  |     "vee-validate": "^4.13.1", | ||||||
|     "vue": "^3.4.21", |     "vue": "^3.4.21", | ||||||
|     "vue-router": "^4.3.0" |     "vue-router": "^4.3.3", | ||||||
|  |     "vue3-cookies": "^1.0.6", | ||||||
|  |     "vue3-print-nb": "^0.1.4", | ||||||
|  |     "yup": "^1.4.0" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|  |     "@primevue/auto-import-resolver": "^4.0.4", | ||||||
|     "@rushstack/eslint-patch": "^1.8.0", |     "@rushstack/eslint-patch": "^1.8.0", | ||||||
|     "@tsconfig/node20": "^20.1.4", |     "@tsconfig/node20": "^20.1.4", | ||||||
|     "@types/node": "^20.12.5", |     "@types/node": "^20.12.5", | ||||||
| @@ -31,9 +41,10 @@ | |||||||
|     "eslint-plugin-vue": "^9.23.0", |     "eslint-plugin-vue": "^9.23.0", | ||||||
|     "npm-run-all2": "^6.1.2", |     "npm-run-all2": "^6.1.2", | ||||||
|     "prettier": "^3.2.5", |     "prettier": "^3.2.5", | ||||||
|     "sass": "^1.77.2", |     "sass": "^1.83.1", | ||||||
|     "typescript": "~5.4.0", |     "typescript": "~5.4.0", | ||||||
|     "vite": "^5.2.8", |     "unplugin-vue-components": "^0.27.3", | ||||||
|     "vue-tsc": "^2.0.11" |     "vite": "^5.4.11", | ||||||
|  |     "vue-tsc": "2.0.11" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										381
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										381
									
								
								src/App.vue
									
									
									
									
									
								
							| @@ -1,376 +1,27 @@ | |||||||
| <template> | <template> | ||||||
|   <nav class="navbar" role="navigation" aria-label="main navigation"> |   <RouterView class="has-navbar-fixed-top"/> | ||||||
|     <div class="navbar-brand"> |  | ||||||
|       <a class="navbar-item"> |  | ||||||
|         <h3 class="title is-3">Mleczarnia</h3> |  | ||||||
|       </a> |  | ||||||
|       <button @click="makeBurger" class="button navbar-burger" data-target="navMenu" v-bind:class="{ 'is-active': activator }"> |  | ||||||
|         <span aria-hidden="true"></span> |  | ||||||
|         <span aria-hidden="true"></span> |  | ||||||
|         <span aria-hidden="true"></span> |  | ||||||
|         <span aria-hidden="true"></span> |  | ||||||
|       </button> |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
|     <div class="navbar-menu" id="navMenu" v-bind:class="{ 'is-active': activator }"> |  | ||||||
|       <div class="navbar-start"> |  | ||||||
|         <a class="navbar-item" @click="switchToFrom"> |  | ||||||
|           Formularz |  | ||||||
|         </a> |  | ||||||
|  |  | ||||||
|         <a class="navbar-item" @click="switchToOrders"> |  | ||||||
|           Zamówienia |  | ||||||
|         </a> |  | ||||||
|       </div> |  | ||||||
|  |  | ||||||
|       <div class="navbar-end"> |  | ||||||
|         <div class="navbar-item"> |  | ||||||
|           <div class="buttons"> |  | ||||||
|             <a class="button is-light"> |  | ||||||
|               Log in |  | ||||||
|             </a> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   </nav> |  | ||||||
|   <div v-if="isForm"> |  | ||||||
|     <form class="box" @submit="createJSON"> |  | ||||||
|       <div class="mb-3"> |  | ||||||
|         <div class="box"> |  | ||||||
|           <h1 class="is-large mb-3"><b>ZAMÓWIENIE</b></h1> |  | ||||||
|           <h1 class="is-large mb-3" v-if="uuid != null" ><b>{{ uuid }}</b></h1> |  | ||||||
|           <div class="field mb-5"> |  | ||||||
|             <label class="label is-small">NIP</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" :value=contractor.Knt_KntId>{{ contractor.Knt_NipE + ', ' + contractor.Knt_Miasto + ', ' + contractor.Knt_Nazwa1 + ' ' + contractor.Knt_Nazwa2 + ' ' + contractor.Knt_Nazwa3 }}</option> |  | ||||||
|                 </select> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|           <div class="field"> |  | ||||||
|             <label class="label is-small">Data dostawy</label> |  | ||||||
|             <div class="field is-small"> |  | ||||||
|               <VueDatePicker class ="bulma-is-small" |  | ||||||
|                              v-model="deliveryDate" |  | ||||||
|                              :enable-time-picker="false" |  | ||||||
|                              :clearable="true" |  | ||||||
|                              input-class-name="input is-small" |  | ||||||
|                               required/> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|           <button class="button is-primary mt-5">Submit</button> |  | ||||||
|           <button class="button is-primary mt-5 ml-3" @click="showModal = true">Potwierdź</button> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div v-for="(kategoria, index) in wares" :key="kategoria.Kod"> |  | ||||||
|         <div class="box" > |  | ||||||
|           <h1 class="is-large mb-3"><b>{{ kategoria.Kod }}</b></h1> |  | ||||||
|           <div class="field" v-for="(ware, index) in kategoria.Towary" :key="ware.Twr_Nazwa"> |  | ||||||
|             <label class="label is-small">{{ ware.Twr_Nazwa }}</label> |  | ||||||
|             <div class="columns is-mobile"> |  | ||||||
|               <div class="column" v-if="ware.chosenOption == ware.Twr_JM"> |  | ||||||
|                 <div class="field"> |  | ||||||
|                   <input |  | ||||||
|                     class="input is-small" |  | ||||||
|                     type="text" |  | ||||||
|                     placeholder="Kwota" |  | ||||||
|                     v-model="ware.Twr_Cena" |  | ||||||
|                   /> |  | ||||||
|                 </div> |  | ||||||
|               </div> |  | ||||||
|               <div class="column" v-else-if="ware.chosenOption == ware.Twr_JMZ"> |  | ||||||
|                 <div class="field"> |  | ||||||
|                   <input |  | ||||||
|                     class="input is-small" |  | ||||||
|                     type="text" |  | ||||||
|                     placeholder="Kwota" |  | ||||||
|                     v-model="ware.Twr_CenaZ" |  | ||||||
|                   /> |  | ||||||
|                 </div> |  | ||||||
|               </div> |  | ||||||
|               <div class="column"> |  | ||||||
|                 <div class="field has-addons"> |  | ||||||
|                   <p class="control"> |  | ||||||
|                   <span class="select is-small"> |  | ||||||
|                     <select v-model="ware.chosenOption" readonly> |  | ||||||
|                       <option v-for="option in ware.Options" :key="option">{{ option }}</option> |  | ||||||
|                     </select> |  | ||||||
|                   </span> |  | ||||||
|                   </p> |  | ||||||
|                   <p class="control is-expanded"> |  | ||||||
|                     <input class="input is-small" type="text" placeholder="Ilość" v-model="ware.Quantity"> |  | ||||||
|                   </p> |  | ||||||
|                 </div> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|             <div v-if="!(index == kategoria.Towary.length - 1)"></div> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|         <div class="mb-3" v-if="!(index == wares.length - 1)"></div> |  | ||||||
|       </div> |  | ||||||
|       <button class="button is-primary mt-3 is-large is-fullwidth">Submit</button> |  | ||||||
|     </form> |  | ||||||
|   </div> |  | ||||||
|   <div class="box is-shadowless" v-else-if="isOrders"> |  | ||||||
|     <form class="mb-3"> |  | ||||||
|         <div class="box"> |  | ||||||
|           <h1 class="is-large mb-3"><b>FILTR ZAMÓWIEŃ</b></h1> |  | ||||||
|           <div class="field mb-5"> |  | ||||||
|             <label class="label is-small">Data zamówienia</label> |  | ||||||
|             <div class="field is-small"> |  | ||||||
|               <VueDatePicker v-model="searchOrderDate" |  | ||||||
|                              :enable-time-picker="false" |  | ||||||
|                              :clearable="true" |  | ||||||
|                              input-class-name="input is-small"/> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|           <div class="field mb-5"> |  | ||||||
|             <label class="label is-small">Zamówienie potwierdzone?</label> |  | ||||||
|             <div class="control"> |  | ||||||
|               <label class="checkbox mr-5"> |  | ||||||
|                 <input type="checkbox" v-model="isOutOfBufor"/> |  | ||||||
|                 Tak |  | ||||||
|               </label> |  | ||||||
|               <label class="checkbox"> |  | ||||||
|                 <input type="checkbox" v-model="isInBufor"/> |  | ||||||
|                 Nie |  | ||||||
|               </label> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|           <button class="button is-primary is-small is-expanded" @click="createJSON">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> |  | ||||||
|               <label class="label is-small">Klient</label> |  | ||||||
|               <div class="field is-small mb-3"> |  | ||||||
|                 <input class="input is-small is-static" |  | ||||||
|                        type="text" |  | ||||||
|                        :value="order.MZN_PodNazwa1 + order.MZN_PodNazwa2 + order.MZN_PodNazwa3" |  | ||||||
|                         readonly/> |  | ||||||
|               </div> |  | ||||||
|               <div class="columns is-mobile field is-small mb-0"> |  | ||||||
|                 <div class="column is-6"> |  | ||||||
|                   <label class="label is-small">Data dostawy</label> |  | ||||||
|                   <div class="field is-small"> |  | ||||||
|                     <input class="input is-small is-static" |  | ||||||
|                            type="text" |  | ||||||
|                            v-model="order.MZN_DataDos" |  | ||||||
|                            readonly/> |  | ||||||
|                   </div> |  | ||||||
|                 </div> |  | ||||||
|                 <div class="column is-6"> |  | ||||||
|                   <label class="label is-small">Data zamówienia</label> |  | ||||||
|                   <div class="field is-small"> |  | ||||||
|                     <input class="input is-small is-static" |  | ||||||
|                            type="text" |  | ||||||
|                            v-model="order.MZN_DataZam.split('T')[0]" |  | ||||||
|                            readonly/> |  | ||||||
|                   </div> |  | ||||||
|                 </div> |  | ||||||
|               </div> |  | ||||||
|               <label class="label is-small">Zamówienie potwierdzone?</label> |  | ||||||
|               <div class="field is-small mb-3" v-if="order.MZN_Bufor==0"> |  | ||||||
|                 <input class="input is-small is-static" |  | ||||||
|                        type="text" |  | ||||||
|                        value="Tak" |  | ||||||
|                        readonly/> |  | ||||||
|               </div> |  | ||||||
|               <div class="field is-small mb-3" v-else> |  | ||||||
|                 <input class="input is-small is-static" |  | ||||||
|                        type="text" |  | ||||||
|                        value="Nie" |  | ||||||
|                        readonly/> |  | ||||||
|               </div> |  | ||||||
|               <button class="button is-primary is-small is-expanded" @click="viewOrder" :name="order.MZN_UUID">Podgląd</button> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
|   </div> |  | ||||||
|   <ConfirmationModal v-show="showModal" @close="showModal = false" :order-uuid="uuid"></ConfirmationModal> |  | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script lang="ts"> | <script setup lang="ts"> | ||||||
| import './assets/style.scss'; | import './assets/style.scss' | ||||||
| import { ref } from 'vue'; | import './assets/print.css' | ||||||
| import ConfirmationModal from '@/components/ConfirmationModal.vue'; | import { RouterView } from 'vue-router' | ||||||
|  | import { useContractorsStore } from '@/stores/contractors.store' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  |  | ||||||
| export default { | // const categoriesStore = useCategoriesStore(); | ||||||
|   components: { ConfirmationModal }, | // await categoriesStore.fetchCategories(); | ||||||
|   data() { |  | ||||||
|     return { |  | ||||||
|       contractors: [], |  | ||||||
|       contractor: {}, |  | ||||||
|       wares: [], |  | ||||||
|       orders: ref(new Array<Object>), |  | ||||||
|       order: ref(), |  | ||||||
|       deliveryDate: ref(), |  | ||||||
|       searchOrderDate: ref(null), |  | ||||||
|       isInBufor: ref(false), |  | ||||||
|       isOutOfBufor: ref(false), |  | ||||||
|       uuid: ref(), |  | ||||||
|       activator: ref(false), |  | ||||||
|       isForm: ref(true), |  | ||||||
|       isOrders: ref(false), |  | ||||||
|       showModal: ref(false) |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   watch: { |  | ||||||
|     isInBufor(val) { |  | ||||||
|       if(val == true && val == this.isOutOfBufor) { |  | ||||||
|         this.isOutOfBufor = false; |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     isOutOfBufor(val) { |  | ||||||
|       if(val == true && val == this.isInBufor) { |  | ||||||
|         this.isInBufor = false; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     async fetchData() { |  | ||||||
|       const response1 = await fetch('https://zamowienia.mleczarnia-kuzma.pl/api/kontrahenci'); |  | ||||||
|       this.contractors = await response1.json(); |  | ||||||
|       console.log(this.contractors); |  | ||||||
|       const response2 = await fetch('https://zamowienia.mleczarnia-kuzma.pl/api/towary'); |  | ||||||
|       this.wares = await response2.json(); |  | ||||||
|       console.log(this.wares); |  | ||||||
|       for (let kategoria of this.wares) { |  | ||||||
|         for (let ware of kategoria.Towary) { |  | ||||||
|           ware.Options = new Array(ware.Twr_JM); |  | ||||||
|           ware.chosenOption = ware.Twr_JM; |  | ||||||
|           if (ware.Twr_JMZ != null) { |  | ||||||
|             ware.Options.push(ware.Twr_JMZ); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       const response3 = await fetch('https://zamowienia.mleczarnia-kuzma.pl/api/zamowienia/bufor'); |  | ||||||
|       let ordersTemp : Array<Object> = await response3.json(); |  | ||||||
|       this.orders.push(...ordersTemp); |  | ||||||
|       const response4 = await fetch('https://zamowienia.mleczarnia-kuzma.pl/api/zamowienia'); |  | ||||||
|       ordersTemp = await response4.json(); |  | ||||||
|       this.orders.push(...ordersTemp); |  | ||||||
|       console.log(this.orders); |  | ||||||
|     }, |  | ||||||
|     createJSON(event: Event) { |  | ||||||
|       event.preventDefault(); |  | ||||||
|       console.log(this.contractor); |  | ||||||
|       const json = { |  | ||||||
|         MZN_UUID: this.uuid, |  | ||||||
|         MZN_DataZam: new Date(Date.now()).toISOString(), |  | ||||||
|         MZN_DataDos: this.deliveryDate != null ? this.deliveryDate.toISOString() : null, |  | ||||||
|         MZN_PodID: this.contractor, |  | ||||||
|         MZamElem: new Array() |  | ||||||
|       }; |  | ||||||
|       for (let category of this.wares) { |  | ||||||
|         for (let ware of category.Towary) { |  | ||||||
|           if(ware.Quantity != null) { |  | ||||||
|             ware.Options = new Array(ware.Twr_JM); |  | ||||||
|             ware.chosenOption = ware.Twr_JM; |  | ||||||
|             if (ware.Twr_JMZ != null) { |  | ||||||
|               ware.Options.push(ware.Twr_JMZ); |  | ||||||
|             } |  | ||||||
|             const wareObject = { |  | ||||||
|               MZE_TwrId: ware.Twr_TwrId, |  | ||||||
|               MZE_TwrJM: ware.chosenOption, |  | ||||||
|               MZE_TwrCena: ware.chosenOption == ware.Twr_JMZ ? ware.Twr_CenaZ : ware.Twr_Cena, |  | ||||||
|               MZE_TwrIlosc: ware.Quantity |  | ||||||
|             } |  | ||||||
|             json.MZamElem.push(wareObject); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       console.log(JSON.stringify(json)); |  | ||||||
|       fetch('https://zamowienia.mleczarnia-kuzma.pl/api/zamowienie', { |  | ||||||
|         method: 'POST', |  | ||||||
|         headers: { |  | ||||||
|           'Accept': 'application/json', |  | ||||||
|           'Content-Type': 'application/json' |  | ||||||
|         }, |  | ||||||
|         body: JSON.stringify(json) |  | ||||||
|       }) |  | ||||||
|         .then(response => response.json()) |  | ||||||
|         .then(response => this.uuid = response.MZN_UUID) |  | ||||||
|     }, |  | ||||||
|     parseOrderJSON(event: Event) { |  | ||||||
|       event.preventDefault(); |  | ||||||
|       const json = "{\"MZN_UUID\":\"55ca3087-38c0-445f-ab7e-7e566c68c0d4\",\"MZN_DataZam\":1704063600000,\"MZN_DataDos\":1717493437880,\"MZN_PodID\":194,\"MZamElem\":[{\"MZE_TwrId\":1833,\"MZE_TwrJM\":\"kg\",\"MZE_TwrCena\":\"16.00\",\"MZN_TwrIlosc\":2},{\"MZE_TwrId\":1837,\"MZE_TwrJM\":\"kg\",\"MZE_TwrCena\":\"16.10\",\"MZN_TwrIlosc\":4}]}"; |  | ||||||
|       const parsedJson = JSON.parse(json); |  | ||||||
|       console.log(this.deliveryDate.toJSON()); |  | ||||||
|       console.log(this.contractor); |  | ||||||
|       fetch('https://zamowienia.mleczarnia-kuzma.pl/api/zamowienie/' + this.uuid, { |  | ||||||
|         method: 'PUT' |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     async viewOrder(event: Event) { |  | ||||||
|       console.log(event.target.name); |  | ||||||
|       let tempOrder = this.orders.find(order => (order.MZN_UUID == event.target.name)); |  | ||||||
|       console.log(tempOrder); |  | ||||||
|       const response = await fetch('https://zamowienia.mleczarnia-kuzma.pl/api/zamowienie/' + tempOrder.MZN_UUID); |  | ||||||
|       let order = await response.json(); |  | ||||||
|       this.uuid = order.MZN_UUID; |  | ||||||
|       this.contractor = order.MZN_PodID; |  | ||||||
|       this.deliveryDate = new Date(order.MZN_DataDos); |  | ||||||
|       console.log(order); |  | ||||||
|       for(let product of order.MZamElem){ |  | ||||||
|         for(let kategoria of this.wares) { |  | ||||||
|           let towar = kategoria.Towary.find(ware => (ware.Twr_TwrId == product.MZE_TwrId)); |  | ||||||
|           if(towar != null) { |  | ||||||
|             console.log('ten towar ' + towar); |  | ||||||
|             towar.Twr_Cena = product.MZE_TwrCena.slice(0, -2); |  | ||||||
|             towar.Quantity = product.MZE_TwrIlosc.slice(0, -2); |  | ||||||
|             break; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       this.isForm = true; |  | ||||||
|       this.isOrders = false; |  | ||||||
|       window.scrollTo(0, 0); |  | ||||||
|     }, |  | ||||||
|     makeBurger () { |  | ||||||
|       this.activator = !this.activator |  | ||||||
|       return this.activator |  | ||||||
|     }, |  | ||||||
|     switchToFrom() { |  | ||||||
|       if(!this.isForm) { |  | ||||||
|         this.isForm = true; |  | ||||||
|         this.isOrders = false; |  | ||||||
|         if(this.activator) { |  | ||||||
|           this.activator = false; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     switchToOrders() { |  | ||||||
|       if(!this.isOrders) { |  | ||||||
|         this.isForm = false; |  | ||||||
|         this.isOrders = true; |  | ||||||
|         if(this.activator) { |  | ||||||
|           this.activator = false; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   created() { |  | ||||||
|     this.fetchData() |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style> | <style> | ||||||
| @media (prefers-color-scheme: light) { | @media screen and (min-width: 500px) { | ||||||
|   :root { |   .box { | ||||||
|     min-height: 100vh; |     --bulma-box-padding: 1.5rem; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| body { | @media screen and (max-width: 500px) { | ||||||
|   min-height: 100vh; |   .box { | ||||||
|  |     --bulma-box-padding: 0.75rem; | ||||||
|  |   } | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
|   | |||||||
| @@ -59,7 +59,6 @@ | |||||||
| } | } | ||||||
|  |  | ||||||
| body { | body { | ||||||
|   min-height: 100vh; |  | ||||||
|   color: var(--color-text); |   color: var(--color-text); | ||||||
|   background: var(--color-background); |   background: var(--color-background); | ||||||
|   transition: |   transition: | ||||||
|   | |||||||
| @@ -7,6 +7,15 @@ | |||||||
|   font-weight: normal; |   font-weight: normal; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .blackBorder { | ||||||
|  |   --bulma-table-cell-border-color : black; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tableOverflow { | ||||||
|  |   overflow-x: scroll; | ||||||
|  |   display: block; | ||||||
|  | } | ||||||
|  |  | ||||||
| a, | a, | ||||||
| .green { | .green { | ||||||
|   text-decoration: none; |   text-decoration: none; | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								src/assets/print.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/assets/print.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | .blackBorder { | ||||||
|  |     --bulma-table-cell-border-color : black; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .tableOverflow { | ||||||
|  |     overflow-x: scroll; | ||||||
|  |     display: block; | ||||||
|  | } | ||||||
| @@ -1,3 +1,22 @@ | |||||||
| @import 'node_modules/bulma/bulma.scss'; | @import 'node_modules/bulma/bulma.scss'; | ||||||
|  | @import 'node_modules/bulma/sass/utilities/mixins'; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | .element { | ||||||
|  |   &.is-loading { | ||||||
|  |     position: relative; | ||||||
|  |     pointer-events: none; | ||||||
|  |     opacity: 1; | ||||||
|  |     &:after { | ||||||
|  |       @include loader; | ||||||
|  |       position: absolute; | ||||||
|  |       top: calc(50% - 1em); | ||||||
|  |       left: calc(50% - 1em); | ||||||
|  |       width: 2em; | ||||||
|  |       height: 2em; | ||||||
|  |       border-width: 0.25em; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| $primary-color: #111111; | $primary-color: #111111; | ||||||
							
								
								
									
										57
									
								
								src/components/CancelationModal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/components/CancelationModal.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import { useOrdersStore } from '@/stores/orders.store' | ||||||
|  | import { storeToRefs } from 'pinia' | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  | import { useContractorsStore } from '@/stores/contractors.store' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  | import { ref } from 'vue' | ||||||
|  |  | ||||||
|  | const ordersStore = useOrdersStore(); | ||||||
|  | const siteControlStore = useSiteControlStore(); | ||||||
|  | const contractorStore = useContractorsStore(); | ||||||
|  | const categoriesStore = useCategoriesStore(); | ||||||
|  |  | ||||||
|  | const { uuid } = storeToRefs(ordersStore); | ||||||
|  | const { showCancellationModal, isLoading } = storeToRefs(siteControlStore); | ||||||
|  | const cancellationReason = ref<string>(""); | ||||||
|  |  | ||||||
|  | async function cancelOrder() { | ||||||
|  |   showCancellationModal.value = false; | ||||||
|  |   // console.log(cancellationReason.value); | ||||||
|  |   axiosInstance.delete('/zamowienie/' + uuid.value, { | ||||||
|  |     data: { | ||||||
|  |       MZN_AnulowanePowod: cancellationReason.value | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  |   siteControlStore.newOrder("/orders"); | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <div class="modal is-active"> | ||||||
|  |       <div class="modal-background"></div> | ||||||
|  |       <div class="modal-card p-3"> | ||||||
|  |         <header class="modal-card-head"> | ||||||
|  |           <p class="modal-card-title">Uwaga</p> | ||||||
|  |           <button class="delete" aria-label="close" @click="$emit('close')"></button> | ||||||
|  |         </header> | ||||||
|  |         <section class="modal-card-body"> | ||||||
|  |           <div>Czy napewno chcesz anulować zamówienie? Czynności tej nie można odwrócić.</div> | ||||||
|  |           <p class="control is-expanded" style="margin-top: 20px"> | ||||||
|  |             <input class="input is-small" type="text" v-model="cancellationReason"  placeholder="Powód anulowania" > | ||||||
|  |           </p> | ||||||
|  |         </section> | ||||||
|  |         <footer class="modal-card-foot"> | ||||||
|  |  | ||||||
|  |           <div class="buttons"> | ||||||
|  | <!--            <button class="button is-success" @click="cancelOrder" v-bind:disabled="cancellationReason == undefined || cancellationReason == ''">Tak</button>--> | ||||||
|  |             <button class="button is-success" :disabled="cancellationReason.length<3" @click="cancelOrder">Tak</button> | ||||||
|  |             <button class="button" @click="$emit('close')">Nie</button> | ||||||
|  |           </div> | ||||||
|  |         </footer> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
| @@ -1,17 +1,38 @@ | |||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| const emit = defineEmits(['close']); | import { useOrdersStore } from '@/stores/orders.store' | ||||||
|  | import { storeToRefs } from 'pinia' | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  | import { useContractorsStore } from '@/stores/contractors.store' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  | import { useRoute } from 'vue-router' | ||||||
|  | import { useRoutesStore } from '@/stores/routes.store' | ||||||
|  | import {  ref } from 'vue' | ||||||
|  |  | ||||||
| const props = defineProps( | const ordersStore = useOrdersStore(); | ||||||
|   { | const siteControlStore = useSiteControlStore(); | ||||||
|     orderUuid : String | const contractorStore = useContractorsStore(); | ||||||
|  | const categoriesStore = useCategoriesStore(); | ||||||
|  | const routeStore = useRoutesStore(); | ||||||
|  |  | ||||||
|  | const { contractor, contractors } = storeToRefs(contractorStore); | ||||||
|  | const { categories } = storeToRefs(categoriesStore); | ||||||
|  | const { uuid } = storeToRefs(ordersStore); | ||||||
|  | const { showConfirmationModal, isLoading} = storeToRefs(siteControlStore); | ||||||
|  | const { route, routes } = storeToRefs(routeStore); | ||||||
|  | const isOrderConfirmed = ref(true) | ||||||
|  |  | ||||||
|  | async function confirmOrder() { | ||||||
|  |   isOrderConfirmed.value = false; | ||||||
|  |   await axiosInstance.put('/zamowienie/' + uuid.value); | ||||||
|  |   showConfirmationModal.value = false; | ||||||
|  |   if (uuid.value != undefined && route.value != undefined) { | ||||||
|  |     isLoading.value = true; | ||||||
|  |     await ordersStore.loadOrder(uuid.value, true, contractor, contractors, categories, route, routes); | ||||||
|  |     ordersStore.orderToClone = false | ||||||
|  |     isLoading.value = false; | ||||||
|   } |   } | ||||||
| ); |   isOrderConfirmed.value = true; | ||||||
|  |  | ||||||
| function confirmOrder() { |  | ||||||
|   emit('close'); |  | ||||||
|   fetch('https://zamowienia.mleczarnia-kuzma.pl/api/zamowienie/' + props.orderUuid, { |  | ||||||
|     method: 'PUT' |  | ||||||
|   }); |  | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| @@ -29,15 +50,11 @@ function confirmOrder() { | |||||||
|         </section> |         </section> | ||||||
|         <footer class="modal-card-foot"> |         <footer class="modal-card-foot"> | ||||||
|           <div class="buttons"> |           <div class="buttons"> | ||||||
|             <button class="button is-success" @click="confirmOrder">Tak</button> |             <button class="button is-success" @click="confirmOrder"  :disabled="!isOrderConfirmed">Tak</button> | ||||||
|             <button class="button" @click="$emit('close')">Nie</button> |             <button class="button" @click="$emit('close')">Nie</button> | ||||||
|           </div> |           </div> | ||||||
|         </footer> |         </footer> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <style scoped> |  | ||||||
|  |  | ||||||
| </style> |  | ||||||
							
								
								
									
										147
									
								
								src/components/ConfirmedForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/components/ConfirmedForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import VueDatePicker from '@vuepic/vue-datepicker' | ||||||
|  | import { useOrdersStore } from '@/stores/orders.store' | ||||||
|  | import { storeToRefs } from 'pinia' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  | import { useContractorsStore } from '@/stores/contractors.store' | ||||||
|  | import { useRoutesStore } from '@/stores/routes.store' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  |  | ||||||
|  | const ordersStore = useOrdersStore(); | ||||||
|  | const categoriesStore = useCategoriesStore(); | ||||||
|  | const contractorsStore = useContractorsStore(); | ||||||
|  | const routeStore = useRoutesStore(); | ||||||
|  | const siteControlStore = useSiteControlStore(); | ||||||
|  |  | ||||||
|  | const { order, uuid} = storeToRefs(ordersStore); | ||||||
|  |  | ||||||
|  | const { categories } = storeToRefs(categoriesStore); | ||||||
|  |  | ||||||
|  | const { contractor } = storeToRefs(contractorsStore); | ||||||
|  |  | ||||||
|  | const { route } = storeToRefs(routeStore); | ||||||
|  |  | ||||||
|  | const { showCancellationModal } = storeToRefs(siteControlStore); | ||||||
|  |  | ||||||
|  | function cancelOrder(event: Event) { | ||||||
|  |   event.preventDefault(); | ||||||
|  |   // axiosInstance.delete('/zamowienie/' + uuid.value); | ||||||
|  |   showCancellationModal.value = true; | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <form class="box  is-shadowless"> | ||||||
|  |     <div class="mb-3  "> | ||||||
|  |       <div class="box" :class="{'cancelled' : order.MZN_Anulowane == 1}"> | ||||||
|  |         <div class="mb-3"> | ||||||
|  |           <h1 class="title is-5" v-if="order != undefined"><b>ZAMÓWIENIE NR {{ order.MZN_MZNID }}</b><b | ||||||
|  |             v-if="order.MZN_Anulowane == 1">, ZAMÓWIENIE ANULOWANE</b></h1> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3" v-if="contractor != undefined"> | ||||||
|  |           <label class="label is-small">Klient</label> | ||||||
|  |           <div class="field is-small mb-3"> | ||||||
|  |             <p class="mb-3 is-size-7"> | ||||||
|  |               {{ contractor.Knt_Nazwa1 + contractor.Knt_Nazwa2 + contractor.Knt_Nazwa3 }} | ||||||
|  |             </p> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3" v-if="order != undefined"> | ||||||
|  |           <label class="label is-small">Data dostawy</label> | ||||||
|  |           <div class="field is-small"> | ||||||
|  |             <VueDatePicker | ||||||
|  |               v-model="order.MZN_DataDos" | ||||||
|  |               :enable-time-picker="false" | ||||||
|  |               :clearable="true" | ||||||
|  |               input-class-name="input is-small calendar-background is-static" | ||||||
|  |               menu-class-name="calendar-background" | ||||||
|  |               readonly | ||||||
|  |               hide-input-icon/> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3" v-if="order != undefined"> | ||||||
|  |           <label class="label is-small">Data zamówienia</label> | ||||||
|  |           <div class="field is-small"> | ||||||
|  |            <VueDatePicker | ||||||
|  |               v-model="order.MZN_DataZam" | ||||||
|  |               :enable-time-picker="false" | ||||||
|  |               :clearable="true" | ||||||
|  |               input-class-name="input is-small calendar-background is-static" | ||||||
|  |               menu-class-name="calendar-background" | ||||||
|  |               readonly | ||||||
|  |               hide-input-icon/> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3" v-if="route != undefined"> | ||||||
|  |           <label class="label is-small">Trasa</label> | ||||||
|  |           <div class="field is-small mb-3"> | ||||||
|  |             <p class="mb-3 is-size-7"> | ||||||
|  |               {{route.MZT_Nazwa1}} | ||||||
|  |             </p> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3" v-if="order != undefined && order.MZN_Uwagi != undefined"> | ||||||
|  |           <label class="label is-small">Uwagi do zamówienia</label> | ||||||
|  |           <p  class="mb-3 is-size-7"> | ||||||
|  |             {{ order.MZN_Uwagi }} | ||||||
|  |           </p> | ||||||
|  |         </div> | ||||||
|  |         <button v-if="order.MZN_Anulowane==0" class="button is-danger" @click="cancelOrder">Anuluj zamówienie</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div v-for="category in categories" :key="category.Kod"> | ||||||
|  |       <div class="box mb-3 " :class="{'cancelled' : order.MZN_Anulowane == 1}" v-if="category.isVisible"> | ||||||
|  |         <h1 class="title mb-3 is-6"><b>{{ category.Kod }}</b></h1> | ||||||
|  |         <div class="field" v-for="(product) in category.Towary" :key="product.Twr_Nazwa"> | ||||||
|  |           <div v-if="Number(product.Quantity) > 0" class="mb-3"> | ||||||
|  |             <label class="label is-small">{{ product.Twr_Nazwa }}</label> | ||||||
|  |             <div class="columns is-mobile"> | ||||||
|  |               <div class="column"> | ||||||
|  |                 <div class="field"> | ||||||
|  |                   <p class="control is-expanded is-size-7"> | ||||||
|  |                     {{ product.Quantity + ' ' + product.ChosenOption }} | ||||||
|  |                   </p> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |               <div class="column" v-if="product.ChosenOption == product.Twr_JM"> | ||||||
|  |                 <div class="field"> | ||||||
|  |                   <p class="mb-3 is-size-7"> | ||||||
|  |                     {{ product.Twr_Cena }} PLN | ||||||
|  |                   </p> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |               <div class="column" v-else-if="product.ChosenOption == product.Twr_JMZ"> | ||||||
|  |                 <div class="field"> | ||||||
|  |                   <p class="mb-3 is-size-7"> | ||||||
|  |                     {{ product.Twr_CenaZ }} PLN | ||||||
|  |                   </p> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |               <div class="column" v-if="product.ChosenOption == product.Twr_JM"> | ||||||
|  |                 <div class="field"> | ||||||
|  |                   <p class="mb-3 is-size-7"> | ||||||
|  |                     {{ (Number(product.Twr_Cena) * Number(product.Quantity)).toFixed(2) }} PLN | ||||||
|  |                   </p> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |               <div class="column" v-else-if="product.ChosenOption == product.Twr_JMZ"> | ||||||
|  |                 <div class="field"> | ||||||
|  |                   <p class="mb-3 is-size-7"> | ||||||
|  |                     {{ (Number(product.Twr_CenaZ) * Number(product.Quantity)).toFixed(2) }} PLN | ||||||
|  |                   </p> | ||||||
|  |  | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |  | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </form> | ||||||
|  | </template> | ||||||
|  | <style> | ||||||
|  | .cancelled { | ||||||
|  |   --bulma-box-background-color: var(--bulma-danger-soft) | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										12
									
								
								src/components/LoadingComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/components/LoadingComponent.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  |  | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <div class="box"> | ||||||
|  |     <div class="box is-skeleton m-3" style="height: 40vh"></div> | ||||||
|  |     <div class="box is-skeleton mb-3 mx-3" style="height: 20vh"></div> | ||||||
|  |     <div class="box is-skeleton mb-3 mx-3" style="height: 20vh"></div> | ||||||
|  |   </div> | ||||||
|  |  | ||||||
|  | </template> | ||||||
							
								
								
									
										46
									
								
								src/components/LoginModal.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/components/LoginModal.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  | import type { VueCookies } from 'vue3-cookies/dist/interfaces' | ||||||
|  | import { inject } from 'vue' | ||||||
|  |  | ||||||
|  | const emit = defineEmits(['close']); | ||||||
|  |  | ||||||
|  | function sendLogin() { | ||||||
|  |   emit('close'); | ||||||
|  |   axiosInstance.post('/login', { | ||||||
|  |     username: 'testowyj', | ||||||
|  |     password: 'beihiegei5Fied0b' | ||||||
|  |   }, { | ||||||
|  |     withCredentials: true | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   const $cookies = inject<VueCookies>('$cookies'); | ||||||
|  |   console.log($cookies); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <div> | ||||||
|  |     <div class="modal is-active"> | ||||||
|  |       <div class="modal-background"></div> | ||||||
|  |       <div class="modal-card p-3"> | ||||||
|  |         <header class="modal-card-head"> | ||||||
|  |           <p class="modal-card-title">Logowanie</p> | ||||||
|  |           <button class="delete" aria-label="close" @click="$emit('close')"></button> | ||||||
|  |         </header> | ||||||
|  |         <section class="modal-card-body"> | ||||||
|  |           <form> | ||||||
|  |  | ||||||
|  |           </form> | ||||||
|  |         </section> | ||||||
|  |         <footer class="modal-card-foot"> | ||||||
|  |           <div class="buttons"> | ||||||
|  |             <button class="button is-success" @click="sendLogin">Zaloguj się</button> | ||||||
|  |             <button class="button" @click="$emit('close')">Anuluj</button> | ||||||
|  |           </div> | ||||||
|  |         </footer> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
							
								
								
									
										475
									
								
								src/components/MainForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										475
									
								
								src/components/MainForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,475 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import VueDatePicker from '@vuepic/vue-datepicker' | ||||||
|  | import { axiosInstance, type Contractor, type Order, type OrderProduct, type Route } 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 { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue' | ||||||
|  | import { useRoutesStore } from '@/stores/routes.store' | ||||||
|  |  | ||||||
|  | const categoriesStore = useCategoriesStore(); | ||||||
|  | const contractorsStore = useContractorsStore(); | ||||||
|  | const ordersStore = useOrdersStore(); | ||||||
|  | const siteControlStore = useSiteControlStore(); | ||||||
|  | const routesStore = useRoutesStore(); | ||||||
|  |  | ||||||
|  | const { contractor, contractors } = storeToRefs(contractorsStore); | ||||||
|  | const { deliveryDate, uuid, order, additionalNotes } = storeToRefs(ordersStore); | ||||||
|  | const { categories } = storeToRefs(categoriesStore); | ||||||
|  | const { showConfirmationModal, showCancellationModal, isDarkTheme } = storeToRefs(siteControlStore); | ||||||
|  | const { route, routes } = storeToRefs(routesStore); | ||||||
|  |  | ||||||
|  | const contractorSearch = ref<string>(); | ||||||
|  | const filteredContractors = ref<Array<Contractor>>(); | ||||||
|  | const showContractorsDropdown = ref<boolean>(false); | ||||||
|  | const contractorInput = ref(null); | ||||||
|  |  | ||||||
|  | const routeSearch = ref<string>(); | ||||||
|  | const filteredRoutes = ref<Array<Route>>(); | ||||||
|  | const showRoutesDropdown = ref<boolean>(false); | ||||||
|  | const routeInput = ref(null); | ||||||
|  | const invoices = ref(); | ||||||
|  | const documentType = ref<number>() | ||||||
|  |  | ||||||
|  | const showErrorNotification = ref<boolean>(false); | ||||||
|  | const showSuccessNotification = ref<boolean>(false); | ||||||
|  | const errorNotificationMessage = ref<string>(); | ||||||
|  | const successNotificationMessage = ref<string>(); | ||||||
|  |  | ||||||
|  | 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 }); | ||||||
|  |  | ||||||
|  | watch(route, (route) => { | ||||||
|  |   if(route == undefined) { | ||||||
|  |     routeSearch.value = ''; | ||||||
|  |   } else { | ||||||
|  |     routeSearch.value = route.MZT_Nazwa1; | ||||||
|  |   } | ||||||
|  | }, { immediate: true }); | ||||||
|  |  | ||||||
|  | const totalAmountUnpaid = computed(() => { | ||||||
|  |   let total = 0; | ||||||
|  |   let totalPaid = 0; | ||||||
|  |   for(let invoice of invoices.value) { | ||||||
|  |     total += Number(invoice.BZd_KwotaSys); | ||||||
|  |     totalPaid += Number(invoice.BZd_KwotaRozSys); | ||||||
|  |   } | ||||||
|  |   return (total - totalPaid).toFixed(2); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | function createJSON(event: Event) { | ||||||
|  |   event.preventDefault(); | ||||||
|  |   console.log(deliveryDate.value); | ||||||
|  |   if(typeof deliveryDate.value != typeof Date) { | ||||||
|  |     deliveryDate.value = new Date(deliveryDate.value as unknown as string); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const json = { | ||||||
|  |     MZN_UUID: uuid.value, | ||||||
|  |     MZN_DataZam: new Date(Date.now()).toISOString(), | ||||||
|  |     MZN_DataDos: deliveryDate.value != undefined ? deliveryDate.value.toISOString().split('T')[0] : null, | ||||||
|  |     MZN_PodID: contractor.value?.Knt_KntId, | ||||||
|  |     MZN_MZTID: route.value?.MZT_MZTID, | ||||||
|  |     MZN_Uwagi: additionalNotes.value, | ||||||
|  |     MZN_TypDokumentu: documentType.value, | ||||||
|  |     MZamElem: new Array<OrderProduct>, | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   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)) | ||||||
|  |           || product.Twr_Cena == "" || product.Twr_CenaZ == "") { | ||||||
|  |           showErrorNotification.value=true; | ||||||
|  |           errorNotificationMessage.value = "W zamówieniu znajdują się niepoprawne wartości."; | ||||||
|  |           return; | ||||||
|  |         } | ||||||
|  |         product.Twr_Cena = product.Twr_Cena == "" || product.Twr_Cena == null ? product.BasePrice : product.Twr_Cena; | ||||||
|  |         product.Twr_CenaZ = product.Twr_CenaZ == "" || product.Twr_CenaZ == null ? product.BasePriceZ : product.Twr_CenaZ; | ||||||
|  |         const productObject : OrderProduct = { | ||||||
|  |           MZE_TwrId: product.Twr_TwrId, | ||||||
|  |           MZE_TwrJm: product.ChosenOption, | ||||||
|  |           MZE_TwrCena: product.ChosenOption == product.Twr_JMZ ? product.Twr_CenaZ : product.Twr_Cena, | ||||||
|  |           MZE_TwrIlosc: product.Quantity, | ||||||
|  |           MZE_TwrNazwa: product.Twr_Nazwa, | ||||||
|  |           MZE_TwrKod: product.Twr_Kod, | ||||||
|  |           MZE_MZNID: undefined, | ||||||
|  |           MZE_MZEID: undefined, | ||||||
|  |           MZE_TwrStawka: undefined | ||||||
|  |         }; | ||||||
|  |         json.MZamElem.push(productObject); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   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; | ||||||
|  |     order.value = {} as Order; | ||||||
|  |     order.value.MZN_MZNID = response.data.MZN_MZNID; | ||||||
|  |     order.value.MZN_Bufor = 1; | ||||||
|  |     showSuccessNotification.value = true; | ||||||
|  |     successNotificationMessage.value = "Zamówienie zostało zapisane do bazy danych." | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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(); | ||||||
|  |   showCancellationModal.value = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 selectContractorFromDropdown(selectedContractor : Contractor) { | ||||||
|  |   console.log(selectedContractor); | ||||||
|  |   contractor.value = selectedContractor; | ||||||
|  |   showContractorsDropdown.value = false; | ||||||
|  |   fetchInvoices(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function filterRoutes() { | ||||||
|  |   if (routeSearch.value == "") { | ||||||
|  |     route.value = undefined; | ||||||
|  |     filteredRoutes.value = routes.value; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   if(routes.value != undefined) { | ||||||
|  |     filteredRoutes.value = routes.value.filter( | ||||||
|  |       route => | ||||||
|  |         route.MZT_Nazwa1.toLowerCase().includes(routeSearch.value?.toLowerCase() as string) | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function toggleRoutesDropdown() { | ||||||
|  |   if(!showRoutesDropdown.value) { | ||||||
|  |     showRoutesDropdown.value = true; | ||||||
|  |     if(routeSearch.value == undefined || routeSearch.value == '') { | ||||||
|  |       filteredRoutes.value = routes.value; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function selectRouteFromDropdown(selectedRoute : Route) { | ||||||
|  |   route.value = selectedRoute; | ||||||
|  |   showRoutesDropdown.value = false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function handleClickOutsideDropdown(event : Event) { | ||||||
|  |   if(contractorInput.value != null && !contractorInput.value.contains(event.target)){ | ||||||
|  |     showContractorsDropdown.value = false; | ||||||
|  |   } | ||||||
|  |   if(routeInput.value != null && !routeInput.value.contains(event.target)){ | ||||||
|  |     showRoutesDropdown.value = false; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function fetchInvoices() { | ||||||
|  |   const response = await axiosInstance.get('/zaleglosci/' + contractor.value?.Knt_KntId); | ||||||
|  |   invoices.value = response.data; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | onMounted(function (){ | ||||||
|  |   document.addEventListener('click', handleClickOutsideDropdown); | ||||||
|  |   console.log(order) | ||||||
|  |   if(contractor.value != undefined) { | ||||||
|  |     fetchInvoices(); | ||||||
|  |   } | ||||||
|  |   if(order.value != undefined) { | ||||||
|  |     documentType.value = order.value.MZN_TypDokumentu === 306 ? 306 : 301 | ||||||
|  |   }else documentType.value = 301 | ||||||
|  |    console.log(documentType.value) | ||||||
|  |  | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | onBeforeUnmount( function () { | ||||||
|  |   document.removeEventListener('click', handleClickOutsideDropdown); | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <form class="box is-shadowless" @submit.prevent="createJSON"> | ||||||
|  |     <div> | ||||||
|  |       <div class="box mb-5"> | ||||||
|  |         <div class="mb-3"> | ||||||
|  |           <h1 class="title is-5" v-if="order == undefined"><b>NOWE ZAMÓWIENIE</b></h1> | ||||||
|  |           <h1 class="title is-5" v-else-if="!ordersStore.orderToClone"><b>ZAMÓWIENIE NR {{order.MZN_MZNID}}</b></h1> | ||||||
|  |           <h1 class="title is-5" v-else-if="ordersStore.orderToClone"><b>DUPLIKACJA ZAMÓWIENIA NR {{order.MZN_MZNID}}</b></h1> | ||||||
|  |  | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3"> | ||||||
|  |           <label class="label is-small">Klient</label> | ||||||
|  |           <div class="field"> | ||||||
|  |             <div ref="contractorInput" class="dropdown maxwidth" | ||||||
|  |                  v-bind:class="{'is-active': showContractorsDropdown == true}"> | ||||||
|  |               <div class="dropdown-trigger maxwidth" @click="toggleContractorsDropdown"> | ||||||
|  |                 <div class="field maxwidth"> | ||||||
|  |                   <p class="control is-expanded has-icons-right is-small maxwidth"> | ||||||
|  |                     <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> | ||||||
|  |         <div class="field mb-3"> | ||||||
|  |           <DataTable :value="invoices" scrollable v-if="invoices != undefined && invoices.length > 0"> | ||||||
|  |             <Column field="BZd_NumerPelny" header="Numer faktury" frozen/> | ||||||
|  |             <Column field="BZd_DataDok" header="Data"/> | ||||||
|  |             <Column field="BZd_Termin" header="Termin zapłaty"/> | ||||||
|  |             <Column field="BZd_KwotaSys" header="Kwota faktury"/> | ||||||
|  |             <Column field="BZd_KwotaRozSys" header="Kwota rozliczona"/> | ||||||
|  |             <ColumnGroup type="footer"> | ||||||
|  |               <Row> | ||||||
|  |                 <Column footer="Kwota zadłużenia" :colspan="4" footerStyle="text-align:right" /> | ||||||
|  |                 <Column :footer="totalAmountUnpaid" /> | ||||||
|  |               </Row> | ||||||
|  |             </ColumnGroup> | ||||||
|  |           </DataTable> | ||||||
|  |           <span v-else>Brak nierozliczonych faktur</span> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3"> | ||||||
|  |           <div> | ||||||
|  |             <label class="label is-small">Dokument WZ</label> | ||||||
|  |             <input | ||||||
|  |               v-model="documentType" | ||||||
|  |               type="checkbox" | ||||||
|  |               :true-value="306" | ||||||
|  |               :false-value="301"> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3"> | ||||||
|  |           <label class="label is-small">Data dostawy</label> | ||||||
|  |           <div class="field is-small"> | ||||||
|  |             <VueDatePicker class ="bulma-is-small" | ||||||
|  |                            v-model="deliveryDate" | ||||||
|  |                            :enable-time-picker="false" | ||||||
|  |                            :clearable="true" | ||||||
|  |                            input-class-name="input is-small calendar-background" | ||||||
|  |                            menu-class-name="calendar-background" | ||||||
|  |                            v-bind:dark = "!!window?.matchMedia?.('(prefers-color-scheme:dark)')?.matches" | ||||||
|  |             /> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-3"> | ||||||
|  |           <label class="label is-small">Trasa</label> | ||||||
|  |           <div class="field"> | ||||||
|  |             <div ref="routeInput" class="dropdown maxwidth" | ||||||
|  |                  v-bind:class="{'is-active': showRoutesDropdown == true}"> | ||||||
|  |               <div class="dropdown-trigger maxwidth" @click="toggleRoutesDropdown"> | ||||||
|  |                 <div class="field maxwidth"> | ||||||
|  |                   <p class="control is-expanded has-icons-right is-small maxwidth"> | ||||||
|  |                     <input class="input is-small is-expanded maxwidth" type="search" | ||||||
|  |                            v-model="routeSearch" @input="filterRoutes" /> | ||||||
|  |                     <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="filteredRoutes != undefined && filteredRoutes.length == 0" class="dropdown-item is-clipped">Brak wyników</a> | ||||||
|  |                   <a class="dropdown-item is-clipped" @click = "selectRouteFromDropdown(null)" | ||||||
|  |                      v-bind:class = "{'has-background-info' : route == null}">Brak</a> | ||||||
|  |                   <a v-for="dropdownRoute in filteredRoutes" v-bind:key="dropdownRoute.MZT_MZTID" | ||||||
|  |                      class="dropdown-item is-clipped" @click = "selectRouteFromDropdown(dropdownRoute)" | ||||||
|  |                      v-bind:class = "{'has-background-info' : dropdownRoute == route}"> | ||||||
|  |                     {{dropdownRoute.MZT_Nazwa1}} | ||||||
|  |                   </a> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field"> | ||||||
|  |           <label class="label is-small">Uwagi do zamówienia</label> | ||||||
|  |           <textarea | ||||||
|  |             v-model="additionalNotes" | ||||||
|  |             class="textarea" | ||||||
|  |             placeholder="Uwagi do zamówienia" | ||||||
|  |             rows="5" | ||||||
|  |           ></textarea> | ||||||
|  |         </div> | ||||||
|  |         <button class="button is-info mt-3">Zapisz</button> | ||||||
|  |         <button class="button is-success mt-3 ml-3" @click="setConfirmationModal" v-bind:disabled="uuid == undefined">Potwierdź</button> | ||||||
|  |         <button class="button is-danger mt-3 ml-3" @click="cancelOrder" v-bind:disabled="uuid == undefined">Anuluj</button> | ||||||
|  |         <div v-if="showErrorNotification" class="notification is-danger is-bold mt-3"> | ||||||
|  |           <button  class="delete" @click.prevent="showErrorNotification = false"></button> | ||||||
|  |           {{ errorNotificationMessage }} | ||||||
|  |         </div> | ||||||
|  |         <div v-if="showSuccessNotification" class="notification is-success is-bold mt-3"> | ||||||
|  |           <button  class="delete" @click.prevent="showSuccessNotification = false"></button> | ||||||
|  |           {{ successNotificationMessage }} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div v-for="category in categories" :key="category.Kod"> | ||||||
|  |       <div class="box mb-3" > | ||||||
|  |         <h1 class="title is-5 mb-3 mb-3"><b>{{ category.Kod }}</b></h1> | ||||||
|  |         <div class="field" v-for="(product, index) in category.Towary" :key="product.Twr_Nazwa"> | ||||||
|  |           <label class="label is-small">{{ product.Twr_Nazwa }}</label> | ||||||
|  |           <div class="columns is-mobile"> | ||||||
|  |             <div class="column" v-if="product.ChosenOption == product.Twr_JM"> | ||||||
|  |               <div class="field has-addons"> | ||||||
|  |                 <p class="control is-expanded"> | ||||||
|  |                   <input | ||||||
|  |                     class="input is-small is-fullwidth" | ||||||
|  |                     type="text" | ||||||
|  |                     placeholder="Kwota" | ||||||
|  |                     v-model="product.Twr_Cena" | ||||||
|  |                     v-bind:class="{ 'is-danger has-background-danger-soft': product.Twr_Cena != undefined && (isNaN(Number(product.Twr_Cena)) || product.Twr_Cena == ''),'is-success has-background-success-soft': product.Quantity != undefined && product.Quantity as unknown as string != '' && !isNaN(Number(product.Quantity))}" | ||||||
|  |                   /> | ||||||
|  |                 </p> | ||||||
|  |                 <p class="control"> | ||||||
|  |                   <button class="button is-small is-danger is-outlined" @click.prevent="product.Twr_Cena = product.BasePrice">X</button> | ||||||
|  |                 </p> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="column" v-else-if="product.ChosenOption == product.Twr_JMZ"> | ||||||
|  |               <div class="field has-addons"> | ||||||
|  |                 <p class="control is-expanded"> | ||||||
|  |                   <input | ||||||
|  |                     class="input is-small" | ||||||
|  |                     type="text" | ||||||
|  |                     placeholder="Kwota" | ||||||
|  |                     v-model="product.Twr_CenaZ" | ||||||
|  |                     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)) | ||||||
|  |                                     }" | ||||||
|  |                   /> | ||||||
|  |                 </p> | ||||||
|  |                 <p class="control"> | ||||||
|  |                   <button class="button is-small is-danger is-outlined" @click.prevent="product.Twr_CenaZ = product.BasePriceZ">X</button> | ||||||
|  |                 </p> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |             <div class="column"> | ||||||
|  |               <div class="field has-addons"> | ||||||
|  |                 <p class="control"> | ||||||
|  |                   <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> | ||||||
|  | <!--TODO intesting part                 --> | ||||||
|  |                 <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-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> | ||||||
|  |           </div> | ||||||
|  |           <div v-if="!(index == category.Towary.length - 1)"></div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="columns mt-1 is-variable is-mobile"> | ||||||
|  |       <div class = "column is-6"> | ||||||
|  |         <button class="button is-info is-fullwidth is-large">Zapisz</button> | ||||||
|  |       </div> | ||||||
|  |       <div class = "is-large column is-6 ml-3"> | ||||||
|  |         <button class="button is-success is-fullwidth is-large" @click="showConfirmationModal = true">Potwierdź</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </form> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <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; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .maxwidth { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										94
									
								
								src/components/NavBar.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/components/NavBar.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  | import { router } from '@/router/router' | ||||||
|  | import { useOrdersStore } from '@/stores/orders.store' | ||||||
|  | import { useContractorsStore } from '@/stores/contractors.store' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  | import { storeToRefs } from 'pinia' | ||||||
|  | import { useUserStore } from '@/stores/user.store' | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  |  | ||||||
|  | const activator =  ref(false); | ||||||
|  |  | ||||||
|  | const siteControlStore = useSiteControlStore(); | ||||||
|  | const ordersStore = useOrdersStore(); | ||||||
|  | const contractorsStore = useContractorsStore(); | ||||||
|  | const categoriesStore = useCategoriesStore(); | ||||||
|  | const userStore = useUserStore(); | ||||||
|  |  | ||||||
|  | const { username } = storeToRefs(userStore); | ||||||
|  |  | ||||||
|  | function makeBurger() { | ||||||
|  |   activator.value = !activator.value | ||||||
|  |   return activator | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function clickForm() { | ||||||
|  |   siteControlStore.switchToForm(); | ||||||
|  |   if(activator.value) { | ||||||
|  |     activator.value = false; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function clickOrders() { | ||||||
|  |   siteControlStore.switchToOrders(); | ||||||
|  |   if(activator.value) { | ||||||
|  |     activator.value = false; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function clickTable() { | ||||||
|  |   siteControlStore.switchToTable(); | ||||||
|  |   if(activator.value) { | ||||||
|  |     activator.value = false; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function routeLogin() { | ||||||
|  |   axiosInstance.post('/logout'); | ||||||
|  |   router.push("/login"); | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <nav class="navbar has-shadow is-fixed-top" role="navigation" aria-label="main navigation"> | ||||||
|  |     <div class="navbar-brand"> | ||||||
|  |       <div class="navbar-item is-overflow-hidden" style="max-width: calc(100vw - 50px); white-space: nowrap; overflow: hidden"> | ||||||
|  |         <h3 class="title is-4">Mleczarnia</h3> | ||||||
|  |         <h4 v-if="username != undefined" class="subtitle is-4"> {{'- ' + username}}</h4> | ||||||
|  |       </div> | ||||||
|  |       <button @click="makeBurger" class="button navbar-burger is-pulled-right" data-target="navMenu" v-bind:class="{ 'is-active': activator }"> | ||||||
|  |         <span aria-hidden="true"></span> | ||||||
|  |         <span aria-hidden="true"></span> | ||||||
|  |         <span aria-hidden="true"></span> | ||||||
|  |         <span aria-hidden="true"></span> | ||||||
|  |       </button> | ||||||
|  |     </div> | ||||||
|  |     <div class="navbar-menu" id="navMenu" v-bind:class="{ 'is-active': activator }"> | ||||||
|  |       <div class="navbar-start"> | ||||||
|  |         <a class="navbar-item" @click="clickForm"> | ||||||
|  |           Formularz | ||||||
|  |         </a> | ||||||
|  |         <a class="navbar-item" @click="clickOrders"> | ||||||
|  |           Zamówienia | ||||||
|  |         </a> | ||||||
|  |         <a class="navbar-item" @click="clickTable"> | ||||||
|  |           Zestawienie | ||||||
|  |         </a> | ||||||
|  |       </div> | ||||||
|  |       <div class="navbar-end"> | ||||||
|  |         <div class="navbar-item"> | ||||||
|  |           <div class="buttons"> | ||||||
|  |             <button class="button is-info" @click="() => siteControlStore.newOrder('/')"> | ||||||
|  |               Nowe Zamówienie | ||||||
|  |             </button> | ||||||
|  |             <button class="button is-info" @click="routeLogin" > | ||||||
|  |               Wyloguj | ||||||
|  |             </button> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </nav> | ||||||
|  | </template> | ||||||
							
								
								
									
										227
									
								
								src/components/OrdersSelector.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								src/components/OrdersSelector.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,227 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import VueDatePicker from '@vuepic/vue-datepicker'; | ||||||
|  | import { computed, ref, watch } from 'vue' | ||||||
|  | import { useOrdersStore } from '@/stores/orders.store' | ||||||
|  | import { storeToRefs } from 'pinia' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  | import { addDays, type Order } from '@/main' | ||||||
|  |  | ||||||
|  | const ordersStore = useOrdersStore(); | ||||||
|  | const siteControlStore = useSiteControlStore(); | ||||||
|  | const searchOrderDate = ref<Array<Date>>([]); | ||||||
|  | const isOutOfBuffer = ref<boolean>(false); | ||||||
|  | const isInBufor = ref<boolean>(false); | ||||||
|  | const { orders, dates } = storeToRefs(ordersStore); | ||||||
|  | const areOrdersLoading = ref<boolean>(false); | ||||||
|  | const { isDarkTheme, isLoading } = storeToRefs(siteControlStore); | ||||||
|  |  | ||||||
|  | const date = new Date(Date.now()); | ||||||
|  | const startDate = new Date(date.getFullYear(), date.getMonth(), (date.getDate())); | ||||||
|  | const endDate = new Date(date.getFullYear(), date.getMonth()+1, date.getDate()); | ||||||
|  | searchOrderDate.value?.push(startDate, endDate); | ||||||
|  |  | ||||||
|  | watch(isInBufor, (val) => { | ||||||
|  |   if(val && val == isOutOfBuffer.value) { | ||||||
|  |     isOutOfBuffer.value = false; | ||||||
|  |   } | ||||||
|  | },{ | ||||||
|  |   immediate: true | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | watch(isOutOfBuffer, (val) => { | ||||||
|  |   if(val && val == isInBufor.value) { | ||||||
|  |     isInBufor.value = false; | ||||||
|  |   } | ||||||
|  | }, { | ||||||
|  |   immediate: true | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | const buffer = computed(()=>{ | ||||||
|  |     if (!isInBufor.value && !isOutOfBuffer.value) { | ||||||
|  |       return null; | ||||||
|  |     } else return !!isInBufor.value; | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  | const datesWithOrders = computed( ()=>{ | ||||||
|  |   const datesWithOrders = new Map<Date, Array<Order>>(); | ||||||
|  |   if (dates.value == undefined || orders.value == undefined) { | ||||||
|  |     return datesWithOrders; | ||||||
|  |   } | ||||||
|  |   for (const date of dates.value) { | ||||||
|  |     datesWithOrders.set(date, []); | ||||||
|  |     for (const order of orders.value) { | ||||||
|  |       if (order.MZN_DataDos == date.toString()) { | ||||||
|  |         datesWithOrders.get(date)?.push(order); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return datesWithOrders; | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | function viewOrder(order : Order, clone: boolean) { | ||||||
|  |   order.loading = true; | ||||||
|  |   siteControlStore.viewOrder(order.MZN_UUID, clone); | ||||||
|  | } | ||||||
|  | function documnetType(order : Order):string { | ||||||
|  |   if(order.MZN_TypDokumentu == 306) return ". Dokument WZ" | ||||||
|  |   else return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function fetchOrders(event : Event | null) { | ||||||
|  |   event?.preventDefault(); | ||||||
|  |   areOrdersLoading.value = true; | ||||||
|  |   console.log(searchOrderDate.value); | ||||||
|  |  | ||||||
|  |   if(searchOrderDate.value == undefined) { | ||||||
|  |     orders.value = await ordersStore.fetchOrdersByBuffer(buffer.value); | ||||||
|  |   } | ||||||
|  |   if(searchOrderDate.value != undefined) { | ||||||
|  |     orders.value = await ordersStore.fetchOrdersByDateStartAndEnd(addDays(searchOrderDate.value[0], 1), addDays(searchOrderDate.value[1], 1), buffer.value); | ||||||
|  |   } | ||||||
|  |   areOrdersLoading.value = false; | ||||||
|  |   console.log("orders"); | ||||||
|  |   console.log(orders.value); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fetchOrders(null); | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <div class="box is-shadowless"> | ||||||
|  |     <form class="mb-3"> | ||||||
|  |       <div class="box"> | ||||||
|  |         <h1 class="mb-3 title is-5"><b>FILTR ZAMÓWIEŃ</b></h1> | ||||||
|  |         <div class="field mb-5"> | ||||||
|  |           <label class="label is-small">Data zamówienia</label> | ||||||
|  |           <div class="field is-small"> | ||||||
|  |             <VueDatePicker v-model="searchOrderDate" | ||||||
|  |                            :enable-time-picker="false" | ||||||
|  |                            :clearable="true" | ||||||
|  |                            :highlight="dates" | ||||||
|  |                            input-class-name="input is-small calendar-background" | ||||||
|  |                            menu-class-name="calendar-background" | ||||||
|  |                            format="dd/MM/yyyy" | ||||||
|  |                             range/> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <div class="field mb-5"> | ||||||
|  |           <label class="label is-small">Zamówienie potwierdzone?</label> | ||||||
|  |           <div class="control"> | ||||||
|  |             <label class="checkbox mr-5"> | ||||||
|  |               <input type="checkbox" v-model="isOutOfBuffer"/> | ||||||
|  |               Tak | ||||||
|  |             </label> | ||||||
|  |             <label class="checkbox"> | ||||||
|  |               <input type="checkbox" v-model="isInBufor"/> | ||||||
|  |               Nie | ||||||
|  |             </label> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <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="mb-3 title is-5"><b>ZAMÓWIENIA</b></h1> | ||||||
|  |       <div v-for="date in datesWithOrders.keys()" :key="String(date)"> | ||||||
|  |         <div v-if="datesWithOrders.get(date)?.length != 0"> | ||||||
|  |           <h1 class="mb-3 subtitle is-6" :class="{'is-skeleton' : areOrdersLoading}">{{ date }}</h1> | ||||||
|  |           <div class="columns is-multiline"> | ||||||
|  |             <template v-for="order in datesWithOrders.get(date)" :key="order.MZN_UUID"> | ||||||
|  |               <div class="column is-4 mb-3" v-if="order.MZN_DataDos == date.toString()"> | ||||||
|  |                 <div class="box" | ||||||
|  |                      :class="{'confirmed' : order.MZN_Bufor == 0 && order.MZN_Anulowane != 1, | ||||||
|  |                       'cancelled' : order.MZN_Anulowane == 1, | ||||||
|  |                       'is-skeleton' : areOrdersLoading}"> | ||||||
|  |                   <label class="label" :class="{'is-invisible': areOrdersLoading}">Zamówienie nr {{order.MZN_MZNID}}{{documnetType(order)}}  </label> | ||||||
|  |                   <label class="label is-small" :class="{'is-invisible': areOrdersLoading}">Klient</label> | ||||||
|  |                   <div class="field is-small mb-3" :class="{'is-invisible': areOrdersLoading}"> | ||||||
|  |                     <input class="input is-small is-static" | ||||||
|  |                            type="text" | ||||||
|  |                            :value="order.MZN_PodNazwa1 + order.MZN_PodNazwa2 + order.MZN_PodNazwa3" | ||||||
|  |                            readonly/> | ||||||
|  |                   </div> | ||||||
|  |                   <div class="columns is-mobile field is-small mb-0"> | ||||||
|  |                     <div class="column is-6" :class="{'is-invisible': areOrdersLoading}"> | ||||||
|  |                       <label class="label is-small">Data dostawy</label> | ||||||
|  |                       <div class="field is-small"> | ||||||
|  |                         <input class="input is-small is-static" | ||||||
|  |                                type="text" | ||||||
|  |                                v-model="order.MZN_DataDos" | ||||||
|  |                                readonly/> | ||||||
|  |                       </div> | ||||||
|  |                     </div> | ||||||
|  |                     <div class="column is-6"> | ||||||
|  |                       <label class="label is-small" :class="{'is-invisible': areOrdersLoading}">Zamówienie potwierdzone?</label> | ||||||
|  |                       <div class="field is-small" :class="{'is-invisible': areOrdersLoading}" v-if="order.MZN_Bufor==0"> | ||||||
|  |                         <input class="input is-small is-static" | ||||||
|  |                                type="text" | ||||||
|  |                                value="Tak" | ||||||
|  |                                readonly/> | ||||||
|  |                       </div> | ||||||
|  |                       <div class="field is-small" :class="{'is-invisible': areOrdersLoading}" v-else> | ||||||
|  |                         <input class="input is-small is-static" | ||||||
|  |                                type="text" | ||||||
|  |                                value="Nie" | ||||||
|  |                                readonly/> | ||||||
|  |                       </div> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                   <div v-if=" order.MZN_Uwagi != null && order.MZN_Uwagi != ''"> | ||||||
|  |                     <label class="label is-small" :class="{'is-invisible': areOrdersLoading} ">Uwagi</label> | ||||||
|  |                     <div class="field is-small mb-3" :class="{'is-invisible': areOrdersLoading}"> | ||||||
|  |                     <span v-if=" order.MZN_Uwagi != null && order.MZN_Uwagi != ''"> | ||||||
|  |                       {{ order.MZN_Uwagi }} | ||||||
|  |                     </span> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                   <label class="label is-small mb-4" :class="{'is-invisible': areOrdersLoading}">Produkty</label> | ||||||
|  |                   <div class="field columns is-multiline is-mobile"> | ||||||
|  |                     <template v-for="product in order.MZamElem" :key="product.MZE_TwrKod"> | ||||||
|  |                       <div class="column is-6 py-0">{{ product.MZE_TwrKod }}</div> | ||||||
|  |                       <div class="column is-6 py-0">{{Number(product.MZE_TwrIlosc).toFixed(2) + " " + product.MZE_TwrJm}}</div> | ||||||
|  |                     </template> | ||||||
|  |                   </div> | ||||||
|  |                   <button class="button is-info is-small is-expanded mr-2" :class="{'is-invisible': areOrdersLoading, 'is-loading': order.loading}" @click="viewOrder(order, false)">Podgląd</button> | ||||||
|  |                   <button class="button is-info is-small is-expanded mr-2" :class="{'is-invisible': areOrdersLoading}" @click="viewOrder(order, true)">Duplikuj</button> | ||||||
|  |  | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |             </template> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <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> | ||||||
							
								
								
									
										412
									
								
								src/components/SummaryComponent.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										412
									
								
								src/components/SummaryComponent.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,412 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import { useOrdersStore } from '@/stores/orders.store' | ||||||
|  | import { storeToRefs } from 'pinia' | ||||||
|  | import VueDatePicker from '@vuepic/vue-datepicker' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  | import { onBeforeUnmount, onMounted, ref, watch } from 'vue' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  | import type { Order, OrderProduct, Product } from '@/main' | ||||||
|  | import { useRoutesStore } from '@/stores/routes.store' | ||||||
|  | import { bool } from 'yup' | ||||||
|  |  | ||||||
|  | const ordersStore = useOrdersStore() | ||||||
|  | const categoriesStore = useCategoriesStore() | ||||||
|  | const routeStore = useRoutesStore() | ||||||
|  |  | ||||||
|  | const { orders, dates } = storeToRefs(ordersStore) | ||||||
|  | const { routes } = storeToRefs(routeStore) | ||||||
|  | const searchDate = ref<Date>(new Date(Date.now())) | ||||||
|  | const confirmedOrders = ref<boolean>() | ||||||
|  | const isSummed = ref<boolean>(true) | ||||||
|  | const nipGrouped = ref(false) | ||||||
|  | const isLoading = ref<boolean>(true) | ||||||
|  | const summedProducts = ref<Array<Product>>([]) | ||||||
|  | const products = ref<Array<Object>>() | ||||||
|  | const ordersByRoute = ref<Map<string, Array<Order>>>(new Map<string, Array<Order>>()) | ||||||
|  | const orderByRouteAndNipRef = ref<Map<string, Map<number, { | ||||||
|  |   orders: Order[]; | ||||||
|  |   products: OrderProduct[] | ||||||
|  | }>>>(new Map<string, Map<number, { orders: Order[]; products: OrderProduct[] }>>) | ||||||
|  | const activeButton = ref(null) | ||||||
|  |  | ||||||
|  | const watchSearchDate = watch(searchDate, async (oldSearchDate, newSeatchDate) => { | ||||||
|  |   if (oldSearchDate != newSeatchDate) { | ||||||
|  |     await fetchOrders() | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | const watchConfirmedOrders = watch(confirmedOrders, async (oldConfirmedOrders, newConfirmedOrders) => { | ||||||
|  |   if (oldConfirmedOrders != newConfirmedOrders) { | ||||||
|  |     await fetchOrders() | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | const setActive = (button) => { | ||||||
|  |   activeButton.value = button; | ||||||
|  |  | ||||||
|  |   if (button === 'separate') { | ||||||
|  |     isSummed.value = false; | ||||||
|  |     nipGrouped.value = false; | ||||||
|  |   } else if (button === 'grouped') { | ||||||
|  |     isSummed.value = false; | ||||||
|  |     nipGrouped.value = true; | ||||||
|  |   } else if (button === 'summed') { | ||||||
|  |     isSummed.value = true; | ||||||
|  |     nipGrouped.value = false; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | async function fetchOrders() { | ||||||
|  |   isLoading.value = true | ||||||
|  |   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) ? false : null) | ||||||
|  |   const productsMap = await categoriesStore.sumProductsFromOrders(orders.value) | ||||||
|  |   summedProducts.value = [] | ||||||
|  |   for (const product of productsMap.values()) { | ||||||
|  |     if (product.SummedQuantity > 0) { | ||||||
|  |       summedProducts.value.push(product) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   await prepareProductsFromOrders() | ||||||
|  |  | ||||||
|  |   isLoading.value = false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function addRoutes() { | ||||||
|  |   for (const route of routes.value) { | ||||||
|  |     ordersByRoute.value.set(route.MZT_Nazwa1, []) | ||||||
|  |     } | ||||||
|  |   ordersByRoute.value.set('brak', []) | ||||||
|  | } | ||||||
|  | function updateProducts(order: UnwrapRefSimple<Order> | UnwrapRefSimple<UnwrapRefSimple<Order>>) { | ||||||
|  |   for (const product of order.MZamElem) { | ||||||
|  |     const newProduct = { | ||||||
|  |       'kod': product.MZE_TwrKod, | ||||||
|  |       'nazwa': product.MZE_TwrNazwa, | ||||||
|  |       'ilosc': Number(product.MZE_TwrIlosc).toFixed(2), | ||||||
|  |       'jm': product.MZE_TwrJm, | ||||||
|  |       'cena': Number(product.MZE_TwrCena).toFixed(2), | ||||||
|  |       'suma': Number(Number(product.MZE_TwrCena) * Number(product.MZE_TwrIlosc)).toFixed(2) | ||||||
|  |     } | ||||||
|  |     order.products.push(newProduct) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | function prepareProductsFromOrders() { | ||||||
|  |   products.value = [] | ||||||
|  |   if (orders.value == undefined || routes.value == undefined) { | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |   addRoutes() | ||||||
|  |   for (const order of orders.value) { | ||||||
|  |     order.products = [] | ||||||
|  |     updateProducts(order) | ||||||
|  |       const routeName = routes.value.find( route => { | ||||||
|  |         return route.MZT_MZTID == order.MZN_MZTID | ||||||
|  |       })?.MZT_Nazwa1; | ||||||
|  |  | ||||||
|  |       ordersByRoute.value.get(routeName != undefined ? routeName : "brak")?.push(order); | ||||||
|  |   } | ||||||
|  |   console.log(orders.value) | ||||||
|  |   console.log(ordersByRoute.value) | ||||||
|  |   groupByNip() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function groupByNip() { | ||||||
|  |   const orderByRouteAndNip = new Map<string, Map<number, { orders: Order[]; products: OrderProduct[] }>>() | ||||||
|  |  | ||||||
|  |   for (const [route, orders] of ordersByRoute.value) { | ||||||
|  |     const ordersByNip = new Map<number, { orders: Order[]; products: OrderProduct[] }>() | ||||||
|  |  | ||||||
|  |     for (const order of orders) { | ||||||
|  |       if (!ordersByNip.has(order.MZN_PodNipE)) { | ||||||
|  |         ordersByNip.set(order.MZN_PodNipE, { orders: [], products: [] }) | ||||||
|  |       } | ||||||
|  |       const entry = ordersByNip.get(order.MZN_PodNipE) | ||||||
|  |       entry.orders.push(order) | ||||||
|  |  | ||||||
|  |       for (const element of order.MZamElem) { | ||||||
|  |         const existingProduct = entry.products.find(p => p.MZE_TwrId === element.MZE_TwrId) | ||||||
|  |         if (existingProduct) { | ||||||
|  |           existingProduct.MZE_TwrCena =String(Number(existingProduct.MZE_TwrCena).toFixed(2)) | ||||||
|  |           existingProduct.MZE_TwrIlosc = String( | ||||||
|  |             Number(Number(existingProduct.MZE_TwrIlosc) + Number(element.MZE_TwrIlosc)).toFixed(2) | ||||||
|  |           ) | ||||||
|  |           existingProduct.suma = Number(Number(existingProduct.MZE_TwrIlosc) * Number(existingProduct.MZE_TwrCena)).toFixed(2) | ||||||
|  |         } else { | ||||||
|  |           element.MZE_TwrCena = String(Number(element.MZE_TwrCena).toFixed(2)) | ||||||
|  |           element.MZE_TwrIlosc = String(Number(element.MZE_TwrIlosc).toFixed(2)) | ||||||
|  |           element.suma = Number(Number(element.MZE_TwrIlosc )*Number(element.MZE_TwrCena)).toFixed(2) | ||||||
|  |           entry.products.push(element) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     orderByRouteAndNip.set(route, ordersByNip) | ||||||
|  |   } | ||||||
|  |   orderByRouteAndNipRef.value = orderByRouteAndNip | ||||||
|  |   console.log(orderByRouteAndNip) | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | onMounted(async () => { | ||||||
|  |     orders.value = await ordersStore.fetchOrdersByDay(searchDate.value, null); | ||||||
|  |     const productsMap = await categoriesStore.sumProductsFromOrders(orders.value); | ||||||
|  |     summedProducts.value = []; | ||||||
|  |     for(const product of productsMap.values()) { | ||||||
|  |       if(product.SummedQuantity > 0) { | ||||||
|  |         summedProducts.value.push(product); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     console.log(summedProducts.value); | ||||||
|  |     await prepareProductsFromOrders(); | ||||||
|  |     console.log(products.value); | ||||||
|  |     isLoading.value=false; | ||||||
|  |  | ||||||
|  |   console.log(ordersByRoute.value) | ||||||
|  | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | onBeforeUnmount(async function() { | ||||||
|  |     const siteControlStore = useSiteControlStore(); | ||||||
|  |     await siteControlStore.newOrder(null); | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | function documnetType(order : Order):string { | ||||||
|  |   if(order.MZN_TypDokumentu == 306) return ". Dokument WZ" | ||||||
|  |   else return "" | ||||||
|  | } | ||||||
|  |  function ifOneWZExists(orders: Array<UnwrapRefSimple<Order>> ):string { | ||||||
|  |    for (const order of orders) { | ||||||
|  |      console.log(order.MZN_TypDokumentu); | ||||||
|  |      if (order.MZN_TypDokumentu === 306) return ". Dokument WZ"; // ❗ PRZERYWA funkcję natychmiast | ||||||
|  |    } | ||||||
|  |    return "" | ||||||
|  |  } | ||||||
|  |  | ||||||
|  | function hasNonEmptyUwagi(item: any): boolean { | ||||||
|  |   let found = false; | ||||||
|  |   item.orders.forEach(order => { | ||||||
|  |     if(order.MZN_Uwagi) { | ||||||
|  |       found = true; | ||||||
|  |     } | ||||||
|  |   }) | ||||||
|  |  | ||||||
|  |   return found; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <div class="columns box is-shadowless" style="margin: 0.5rem 0 0; padding: 0; min-height: 100%"> | ||||||
|  |     <div class="column"> | ||||||
|  |       <div class="box"> | ||||||
|  |         <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" | ||||||
|  |                        :highlight = "dates" | ||||||
|  |         /> | ||||||
|  |  | ||||||
|  |         <div class="control mt-3"> | ||||||
|  |           <label class="checkbox mr-5"> | ||||||
|  |             <input type="checkbox" v-model="confirmedOrders"/> | ||||||
|  |             Tylko potwierdzone zamówienia? | ||||||
|  |           </label> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="box mt-3"> | ||||||
|  |  | ||||||
|  |         <button | ||||||
|  |           class="button is-fullwidth mb-3" | ||||||
|  |           :class="{ 'is-active': activeButton === 'grouped' }" | ||||||
|  |           @click="setActive('grouped')" | ||||||
|  |         > | ||||||
|  |           Zamówienia pogrupowane po NIP | ||||||
|  |         </button> | ||||||
|  |  | ||||||
|  |         <button | ||||||
|  |           class="button is-fullwidth mb-3" | ||||||
|  |           :class="{ 'is-active': activeButton === 'separate' }" | ||||||
|  |           @click="setActive('separate')" | ||||||
|  |         > | ||||||
|  |           Rozdzielone zamówienia | ||||||
|  |         </button> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         <button | ||||||
|  |           class="button is-fullwidth mb-3" | ||||||
|  |           :class="{ 'is-active': activeButton === 'summed' }" | ||||||
|  |           @click="setActive('summed')" | ||||||
|  |         > | ||||||
|  |           Zsumowane zamówienia | ||||||
|  |         </button> | ||||||
|  |         <button class="button is-fullwidth" v-print="'#printMe'">Drukuj</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |     <div class="column is-four-fifths"> | ||||||
|  |       <div class="box" style="width: 100%; height: 100%; padding: 0"> | ||||||
|  |         <div style="width: 100%; height: 100%"> | ||||||
|  |           <div v-if="isLoading == true" class="is-flex is-justify-content-center is-flex-direction-row" style="height: 100%; align-content:space-evenly"> | ||||||
|  |             <div class="title is-1 has-text-centered element is-loading" style="min-height: 150px; align-self: center;"></div> | ||||||
|  |           </div> | ||||||
|  |           <div v-else-if="orders != undefined && orders.length != 0 && !isSummed" id="printMe"> | ||||||
|  |             <div v-for="route in routes" :key="route.MZT_MZTID"> | ||||||
|  |               <div v-if="route.MZT_Nazwa1 != undefined && ordersByRoute != undefined && ordersByRoute.has(route.MZT_Nazwa1)"> | ||||||
|  |                 <div v-if=" | ||||||
|  |                 //@ts-ignore | ||||||
|  |                 ordersByRoute.has(route.MZT_Nazwa1) && ordersByRoute?.get(route.MZT_Nazwa1) != undefined && ordersByRoute?.get(route.MZT_Nazwa1).length > 0" | ||||||
|  |                      style="page-break-after: always;"> | ||||||
|  |                   <h1 class="is-size-2 is-fullwidth has-text-centered">{{ | ||||||
|  |                     //@ts-ignore | ||||||
|  |                       route.MZT_Nazwa1 + ' ' + ordersByRoute?.get(route.MZT_Nazwa1)[0].MZN_DataDos | ||||||
|  |                     }}</h1> | ||||||
|  |  | ||||||
|  |                   <div v-if="!nipGrouped" v-for="order of ordersByRoute.get(route.MZT_Nazwa1)" :key="order.MZN_MZNID" | ||||||
|  |                        class="pb-4" style="display: block; page-break-inside: avoid;"> | ||||||
|  |                     <p class="is-size-6 px-2">NIP {{order.MZN_PodNipE}}</p> | ||||||
|  |                     <p class="is-size-6 px-2">{{order.MZN_PodNazwa1 + order.MZN_PodNazwa2 + order.MZN_PodNazwa3}}</p> | ||||||
|  |                     <p class="is-size-5 px-2">ZAMÓWIENIE NR {{order.MZN_MZNID}}{{documnetType(order)}}</p> | ||||||
|  |                     <DataTable :value="order.products" class="mb-3" style="padding:0" scrollable> | ||||||
|  |                       <Column field="kod" header="Indeks" frozen></Column> | ||||||
|  |                       <Column field="nazwa" header="Nazwa"/> | ||||||
|  |                       <Column field="ilosc" header="Ilość"/> | ||||||
|  |                       <Column field="jm" header="JM"/> | ||||||
|  |                       <Column field="cena" header="Cena"/> | ||||||
|  |                       <Column field="suma" header="Suma"/> | ||||||
|  |                     </DataTable> | ||||||
|  |                     <div v-if="order.MZN_Uwagi != undefined"> | ||||||
|  |                       <p class="is-size-6 px-2">Uwagi</p> | ||||||
|  |                       <p class="is-size-6 px-2">{{order.MZN_Uwagi}}</p> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                   <div v-else-if="nipGrouped" | ||||||
|  |                        v-for="[nip, item] in Array.from(orderByRouteAndNipRef.get(route.MZT_Nazwa1) || new Map())" | ||||||
|  |                        :key="nip" class="pb-4" style="display: block; page-break-inside: avoid;"> | ||||||
|  |  | ||||||
|  |                     <p class="is-size-5 px-2">NIP: {{ nip }}</p> | ||||||
|  |  | ||||||
|  |                     <p class="is-size-6 px-2"> | ||||||
|  |                       {{ item.orders[0].MZN_PodNazwa1 + item.orders[0].MZN_PodNazwa2 + item.orders[0].MZN_PodNazwa3 | ||||||
|  |                       }}</p> | ||||||
|  |                     <p class="is-size-5 px-2" | ||||||
|  |                        v-if="orderByRouteAndNipRef.get(route.MZT_Nazwa1)?.get(nip)?.orders?.length > 1 "> | ||||||
|  |                       ZAMÓWIENIA NR | ||||||
|  |                       <span | ||||||
|  |                         v-for="(orderByNip, index) in orderByRouteAndNipRef.get(route.MZT_Nazwa1).get(nip).orders">{{ orderByNip.MZN_MZNID }}<span | ||||||
|  |                           v-if="index !== orderByRouteAndNipRef.get(route.MZT_Nazwa1).get(nip).orders.length - 1">, </span> | ||||||
|  |                       </span> | ||||||
|  |                       <span>{{ifOneWZExists(orderByRouteAndNipRef.get(route.MZT_Nazwa1).get(nip).orders)}}</span> | ||||||
|  |                     </p> | ||||||
|  |                     <p class="is-size-5 px-2" | ||||||
|  |                        v-else> | ||||||
|  |                       ZAMÓWIENIE NR | ||||||
|  |                       <span | ||||||
|  |                         v-for="(orderByNip, index) in orderByRouteAndNipRef.get(route.MZT_Nazwa1).get(nip).orders">{{orderByNip.MZN_MZNID}}<span | ||||||
|  |                           v-if="index !== orderByRouteAndNipRef.get(route.MZT_Nazwa1).get(nip).orders.length - 1">, </span> | ||||||
|  |                       </span><span>{{ifOneWZExists(orderByRouteAndNipRef.get(route.MZT_Nazwa1).get(nip).orders)}}</span> | ||||||
|  |  | ||||||
|  |                     </p> | ||||||
|  |                     <DataTable :value="orderByRouteAndNipRef.get(route.MZT_Nazwa1).get(nip).products" | ||||||
|  |                                class="mb-3" style="padding:0" scrollable> | ||||||
|  |                       <Column field="MZE_TwrKod" header="Indeks" frozen></Column> | ||||||
|  |                       <Column field="MZE_TwrNazwa" header="Nazwa" /> | ||||||
|  |                       <Column field="MZE_TwrIlosc" header="Ilość" /> | ||||||
|  |                       <Column field="MZE_TwrJm" header="JM" /> | ||||||
|  |                       <Column field="MZE_TwrCena" header="Cena" /> | ||||||
|  |                       <Column field="suma" header="Suma" /> | ||||||
|  |                     </DataTable> | ||||||
|  |                     <div > | ||||||
|  |                       <p v-if="hasNonEmptyUwagi(item)"  class="is-size-6 px-2">Uwagi</p> | ||||||
|  |                       <p v-for="order in item.orders" class="is-size-6 px-2">{{ order.MZN_Uwagi }}</p> | ||||||
|  |                     </div> | ||||||
|  |                   </div> | ||||||
|  |                   </div> | ||||||
|  |                 </div> | ||||||
|  |               </div> | ||||||
|  |           </div> | ||||||
|  |           <DataTable :value="summedProducts" class="mb-3" style="padding:0" scrollable id="printMe" v-else-if="orders != undefined && orders.length != 0 && isSummed"> | ||||||
|  |             <Column field="Twr_Kod" header="Indeks" frozen></Column> | ||||||
|  |             <Column field="Twr_Nazwa" header="Nazwa"/> | ||||||
|  |             <Column field="SummedQuantity" header="Ilość"> | ||||||
|  |               <template #body="slotProps"> | ||||||
|  |                 <span>{{ slotProps.data.SummedQuantity.toFixed(2)}}</span> | ||||||
|  |               </template> | ||||||
|  |             </Column> | ||||||
|  |             <Column field="Twr_JM" header="JM"> | ||||||
|  |             </Column> | ||||||
|  |             <Column field="SummedPrice" header="Suma"> | ||||||
|  |               <template #body="slotProps"> | ||||||
|  |                 <span>{{ slotProps.data.SummedPrice.toFixed(2)}}</span> | ||||||
|  |               </template> | ||||||
|  |             </Column> | ||||||
|  |           </DataTable> | ||||||
|  |           <div v-else class="is-flex is-justify-content-center is-flex-direction-row" style="height: 100%"> | ||||||
|  |             <p class="title is-1 has-text-centered" style="height: min-content; align-self: center;">Brak zamówień</p> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <style scoped> | ||||||
|  |   @media screen and (min-width: 500px) { | ||||||
|  |     .box { | ||||||
|  |       --bulma-box-padding: 1.5rem; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   @media screen and (max-width: 500px) { | ||||||
|  |     .box { | ||||||
|  |       --bulma-box-padding: 0.75rem; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   .is-active { | ||||||
|  |     background-color: #66d1ff; | ||||||
|  |     color: white; | ||||||
|  |   } | ||||||
|  |   .blackBorder { | ||||||
|  |     --bulma-table-cell-border-color : black; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .tableOverflow { | ||||||
|  |     overflow-x: scroll; | ||||||
|  |     display: block; | ||||||
|  |     padding: 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .test { | ||||||
|  |     padding: 0.75rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   tr th:first-child{ | ||||||
|  |     border-top-left-radius: 0.75rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   tr th:last-child{ | ||||||
|  |     border-top-right-radius: 0.75rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .p-datatable-scrollable { | ||||||
|  |     border-top-right-radius: 0.75rem; | ||||||
|  |     border-top-left-radius: 0.75rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .p-datatable-table-container { | ||||||
|  |     border-top-right-radius: 0.75rem; | ||||||
|  |     border-top-left-radius: 0.75rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   table { | ||||||
|  |     border-top-right-radius: 0.75rem; | ||||||
|  |     border-top-left-radius: 0.75rem; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   @media print { | ||||||
|  |     .dashedBorder{ | ||||||
|  |       border-style: dotted; | ||||||
|  |       border-color: lightgray; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | </style> | ||||||
							
								
								
									
										212
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										212
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,8 +1,210 @@ | |||||||
| import { createApp } from 'vue' | import { createApp, watch } from 'vue' | ||||||
| import App from './App.vue' | import App from './App.vue'; | ||||||
| import VueDatePicker from '@vuepic/vue-datepicker'; | import VueDatePicker from '@vuepic/vue-datepicker'; | ||||||
| import '@vuepic/vue-datepicker/dist/main.css' | import '@vuepic/vue-datepicker/dist/main.css'; | ||||||
|  | import ConfirmationModal from '@/components/ConfirmationModal.vue'; | ||||||
|  | import NavBar from '@/components/NavBar.vue'; | ||||||
|  | import MainForm from '@/components/MainForm.vue'; | ||||||
|  | import OrdersSelector from '@/components/OrdersSelector.vue' | ||||||
|  | import ConfirmedForm from '@/components/ConfirmedForm.vue' | ||||||
|  | import LoadingComponent from '@/components/LoadingComponent.vue' | ||||||
|  | import axios from 'axios' | ||||||
|  | import LoginModal from '@/components/LoginModal.vue' | ||||||
|  | import { createPinia, storeToRefs } from 'pinia' | ||||||
|  | import VueCookies from 'vue3-cookies' | ||||||
|  | import { router } from '@/router/router' | ||||||
|  | import { useUserStore } from '@/stores/user.store' | ||||||
|  | import print from 'vue3-print-nb' | ||||||
|  | import CancelationModal from '@/components/CancelationModal.vue' | ||||||
|  | import SummaryComponent from '@/components/SummaryComponent.vue' | ||||||
|  | import PrimeVue from "primevue/config"; | ||||||
|  | import Lara from '@primevue/themes/lara'; | ||||||
|  |  | ||||||
|  | const app = createApp(App); | ||||||
|  | const pinia = createPinia(); | ||||||
|  | app.use(pinia); | ||||||
|  | app.use(VueCookies); | ||||||
|  | app.use(router); | ||||||
|  | app.use(print); | ||||||
|  | app.use(PrimeVue, { | ||||||
|  |   // Default theme configuration | ||||||
|  |   theme: { | ||||||
|  |     preset: Lara, | ||||||
|  |     options: { | ||||||
|  |       prefix: 'p', | ||||||
|  |       darkModeSelector: 'system', | ||||||
|  |       cssLayer: false | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | 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} | ||||||
|  | ) | ||||||
|  | const currentUrl = window.location.href | ||||||
|  |  | ||||||
|  | export const baseURL = currentUrl.includes("localhost") | ||||||
|  |   ? "https://zamowienia-test.mleczarnia-kuzma.pl/api" | ||||||
|  |   : currentUrl.substring(0, currentUrl.lastIndexOf("/") ) + "/api" ; | ||||||
|  |  | ||||||
|  | export const axiosInstance = axios.create({ | ||||||
|  |   baseURL: baseURL, | ||||||
|  |   withCredentials: true | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | axiosInstance.interceptors.response.use( (response) => { | ||||||
|  |   return response; | ||||||
|  | }, (error) => { | ||||||
|  |   if (error.response.status == 401) { | ||||||
|  |     const userStore = useUserStore(); | ||||||
|  |     storeToRefs(userStore).username.value = undefined; | ||||||
|  |     router.push('/login'); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
| const app = createApp(App) |  | ||||||
| app.component('VueDatePicker', VueDatePicker); | app.component('VueDatePicker', VueDatePicker); | ||||||
| app.mount('#app') | app.component('ConfirmationModal', ConfirmationModal); | ||||||
|  | app.component('LoginModal', LoginModal); | ||||||
|  | app.component('NavBar', NavBar); | ||||||
|  | app.component('MainForm', MainForm); | ||||||
|  | app.component('OrdersSelector', OrdersSelector); | ||||||
|  | app.component('ConfirmedForm', ConfirmedForm); | ||||||
|  | app.component('LoadingComponent', LoadingComponent); | ||||||
|  | app.component('CancelationModal', CancelationModal); | ||||||
|  | app.component('SummaryComponent', SummaryComponent); | ||||||
|  | app.mount('#app'); | ||||||
|  |  | ||||||
|  | export interface Category { | ||||||
|  |   GIDNumer: number, | ||||||
|  |   GrONumer: number, | ||||||
|  |   Kod: string, | ||||||
|  |   Nazwa: string, | ||||||
|  |   Poziom: number, | ||||||
|  |   Sciezka: string, | ||||||
|  |   Towary: Array<Product> | ||||||
|  |   isVisible: boolean | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface Product { | ||||||
|  |   Twr_Cena: string, | ||||||
|  |   Twr_CenaZ: string, | ||||||
|  |   Twr_JM: string, | ||||||
|  |   Twr_JMPrzelicznikL: string, | ||||||
|  |   Twr_JMPrzelicznikM: string, | ||||||
|  |   Twr_JMZ: string, | ||||||
|  |   Twr_Kod: string, | ||||||
|  |   Twr_Nazwa: string, | ||||||
|  |   Twr_NieAktywny: number, | ||||||
|  |   Twr_Stawka: string, | ||||||
|  |   Twr_TwGGIDNumer: number, | ||||||
|  |   Twr_TwrId: number, | ||||||
|  |   Options: Array<string>, | ||||||
|  |   ChosenOption: string, | ||||||
|  |   Quantity: string, | ||||||
|  |   BasePrice: string, | ||||||
|  |   BasePriceZ: string, | ||||||
|  |   SummedQuantity: number, | ||||||
|  |   SummedPrice: number | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface Contractor { | ||||||
|  |   Knt_Email: string, | ||||||
|  |   Knt_KntId: number, | ||||||
|  |   Knt_KodPocztowy: string, | ||||||
|  |   Knt_Miasto: string, | ||||||
|  |   Knt_Nazwa1: string, | ||||||
|  |   Knt_Nazwa2: string, | ||||||
|  |   Knt_Nazwa3: string, | ||||||
|  |   Knt_Nieaktywny: number, | ||||||
|  |   Knt_NipE: string, | ||||||
|  |   Knt_NrDomu: string, | ||||||
|  |   Knt_OpiekunId: number, | ||||||
|  |   Knt_OpiekunTyp: number, | ||||||
|  |   Knt_Ulica: string, | ||||||
|  |   Knt_Wojewodztwo: string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface Order { | ||||||
|  |   loading: boolean | ||||||
|  |   MZN_Bufor: number, | ||||||
|  |   MZN_Anulowane: number, | ||||||
|  |   MZN_DataDos: string, | ||||||
|  |   MZN_DataZam: string, | ||||||
|  |   MZN_MZNID: number, | ||||||
|  |   MZN_OpeID: number, | ||||||
|  |   MZN_PodID: number, | ||||||
|  |   MZN_PodKodPocztowy: string, | ||||||
|  |   MZN_PodMiasto: string, | ||||||
|  |   MZN_PodNazwa1: string, | ||||||
|  |   MZN_PodNazwa2: string, | ||||||
|  |   MZN_PodNazwa3: string, | ||||||
|  |   MZN_PodNipE: string, | ||||||
|  |   MZN_PodNrDomu: string, | ||||||
|  |   MZN_PodUlica: string, | ||||||
|  |   MZN_PodWojewodztwo: string, | ||||||
|  |   MZN_TypDokumentu: number, | ||||||
|  |   MZN_UUID: string, | ||||||
|  |   MZN_Uwagi: string, | ||||||
|  |   MZN_MZTID: number, | ||||||
|  |   MZamElem: Array<OrderProduct>, | ||||||
|  |   products: any | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface Order { | ||||||
|  |   loading: boolean | ||||||
|  |   MZN_Bufor: number, | ||||||
|  |   MZN_Anulowane: number, | ||||||
|  |   MZN_DataDos: string, | ||||||
|  |   MZN_DataZam: string, | ||||||
|  |   MZN_MZNID: number, | ||||||
|  |   MZN_OpeID: number, | ||||||
|  |   MZN_PodID: number, | ||||||
|  |   MZN_PodKodPocztowy: string, | ||||||
|  |   MZN_PodMiasto: string, | ||||||
|  |   MZN_PodNazwa1: string, | ||||||
|  |   MZN_PodNazwa2: string, | ||||||
|  |   MZN_PodNazwa3: string, | ||||||
|  |   MZN_PodNipE: string, | ||||||
|  |   MZN_PodNrDomu: string, | ||||||
|  |   MZN_PodUlica: string, | ||||||
|  |   MZN_PodWojewodztwo: string, | ||||||
|  |   MZN_TypDokumentu: number, | ||||||
|  |   MZN_UUID: string, | ||||||
|  |   MZN_Uwagi: string, | ||||||
|  |   MZN_MZTID: number, | ||||||
|  |   MZamElem: Array<OrderProduct>, | ||||||
|  |   products: any | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface OrderProduct { | ||||||
|  |   MZE_MZEID: number | undefined, | ||||||
|  |   MZE_MZNID: number | undefined, | ||||||
|  |   MZE_TwrCena: string, | ||||||
|  |   MZE_TwrId: number, | ||||||
|  |   MZE_TwrIlosc: string, | ||||||
|  |   MZE_TwrJm: string, | ||||||
|  |   MZE_TwrNazwa: string, | ||||||
|  |   MZE_TwrKod: string, | ||||||
|  |   MZE_TwrStawka: string | undefined, | ||||||
|  |   suma?: number | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export interface Route { | ||||||
|  |   MZT_MZTID: number, | ||||||
|  |   MZT_Nazwa1: string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export function addDays(date : Date, days : number) { | ||||||
|  |   const result = new Date(date); | ||||||
|  |   result.setDate(result.getDate() + days); | ||||||
|  |   return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								src/router/router.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/router/router.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | import { createRouter, createWebHistory } from 'vue-router'; | ||||||
|  |  | ||||||
|  | import { MainView, LoginView, SummaryView, OrdersView } from '@/views' | ||||||
|  |  | ||||||
|  | export const router = createRouter({ | ||||||
|  |   history: createWebHistory(import.meta.env.BASE_URL), | ||||||
|  |   linkActiveClass: 'active', | ||||||
|  |   routes: [ | ||||||
|  |     { path: '/', component: MainView }, | ||||||
|  |     { path: '/login', component: LoginView }, | ||||||
|  |     { path: '/summary', component: SummaryView}, | ||||||
|  |     { path: '/orders', component: OrdersView}, | ||||||
|  |   ] | ||||||
|  | }); | ||||||
|  |  | ||||||
							
								
								
									
										63
									
								
								src/stores/categories.store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/stores/categories.store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | import { defineStore } from 'pinia' | ||||||
|  | import type { Category, Order, Product } from '@/main' | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  |  | ||||||
|  | export const useCategoriesStore = defineStore('categories', () => { | ||||||
|  |   const categories = ref<Array<Category>>([]); | ||||||
|  |  | ||||||
|  |   async function fetchCategories() { | ||||||
|  |     const response = await axiosInstance.get('/towary', {withCredentials: true}); | ||||||
|  |     categories.value = response.data; | ||||||
|  |  | ||||||
|  |     if(categories.value != undefined) { | ||||||
|  |       for (const category of categories.value) { | ||||||
|  |         for (const product of category.Towary) { | ||||||
|  |           product.Options = new Array(product.Twr_JM); | ||||||
|  |           product.ChosenOption = product.Twr_JM; | ||||||
|  |           product.BasePrice = product.Twr_Cena; | ||||||
|  |           product.BasePriceZ = product.Twr_CenaZ; | ||||||
|  |           product.SummedQuantity = 0; | ||||||
|  |           product.SummedPrice = 0; | ||||||
|  |           if (product.Twr_JMZ != null) { | ||||||
|  |             product.Options.push(product.Twr_JMZ); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function sumProductsFromOrders(orders : Array<Order>) { | ||||||
|  |     const productsMap = new Map<string, Product>(); | ||||||
|  |  | ||||||
|  |     await fetchCategories(); | ||||||
|  |  | ||||||
|  |     if(categories.value != undefined) { | ||||||
|  |       for (const category of categories.value) { | ||||||
|  |         for (const product of category.Towary) { | ||||||
|  |           productsMap.set(product.Twr_TwrId.toString(), product); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if(orders != undefined) { | ||||||
|  |       for (const order of orders) { | ||||||
|  |         for (const product of order.MZamElem) { | ||||||
|  |           const mapProduct = productsMap.get(String(product.MZE_TwrId)); | ||||||
|  |           if (product.MZE_TwrJm == mapProduct?.Twr_JM) { | ||||||
|  |             mapProduct.SummedQuantity += Number(product.MZE_TwrIlosc); | ||||||
|  |             mapProduct.SummedPrice += (Number(product.MZE_TwrCena) * Number(product.MZE_TwrIlosc)); | ||||||
|  |           } | ||||||
|  |           else if (product.MZE_TwrJm == mapProduct?.Twr_JMZ) { | ||||||
|  |             mapProduct.SummedQuantity += (Number(product.MZE_TwrIlosc) * Number(mapProduct.Twr_JMPrzelicznikL)/Number(mapProduct.Twr_JMPrzelicznikM)); | ||||||
|  |  | ||||||
|  |             mapProduct.SummedPrice += (Number(product.MZE_TwrCena) * Number(product.MZE_TwrIlosc)); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return productsMap; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return {categories, fetchCategories, sumProductsFromOrders} | ||||||
|  | }) | ||||||
							
								
								
									
										21
									
								
								src/stores/contractors.store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/stores/contractors.store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | import { defineStore } from 'pinia' | ||||||
|  | import type { Contractor } from '@/main' | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export const useContractorsStore = defineStore('contractors', () => { | ||||||
|  |   const contractors = ref<Array<Contractor>>([]); | ||||||
|  |   contractors.value=[]; | ||||||
|  |   const contractor = ref<Contractor>(); | ||||||
|  |  | ||||||
|  |   async function fetchContractors() { | ||||||
|  |     const response = await axiosInstance.get('/kontrahenci', {withCredentials: true}); | ||||||
|  |     console.log(response); | ||||||
|  |     console.log(contractors.value); | ||||||
|  |     contractors.value = []; | ||||||
|  |     contractors.value.push(...response.data); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return {contractors, contractor, fetchContractors} | ||||||
|  | }) | ||||||
							
								
								
									
										122
									
								
								src/stores/orders.store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								src/stores/orders.store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | |||||||
|  | import { defineStore } from 'pinia' | ||||||
|  | import type { Category, Contractor, Order, Route } from '@/main' | ||||||
|  | import { type Ref, ref } from 'vue' | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  |  | ||||||
|  | export const useOrdersStore = defineStore('orders', () => { | ||||||
|  |   const orders = ref<Array<Order>>(); | ||||||
|  |   const dates = ref<Date[]>(); | ||||||
|  |   const order = ref<Order>(); | ||||||
|  |   const uuid = ref<string>(); | ||||||
|  |   const deliveryDate = ref<Date>(); | ||||||
|  |   const orderDate = ref<Date>(); | ||||||
|  |   const additionalNotes = ref<string>(); | ||||||
|  |   const orderToClone = ref<boolean>(); | ||||||
|  |  | ||||||
|  |   async function fetchOrders() { | ||||||
|  |     const response = await axiosInstance.get('/zamowienia', {withCredentials: true}); | ||||||
|  |     const ordersTemp : Array<Order> = response.data; | ||||||
|  |     await getOrderDates(); | ||||||
|  |     return ordersTemp; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   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; | ||||||
|  |     await getOrderDates(); | ||||||
|  |     return ordersTemp; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   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]; | ||||||
|  |     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; | ||||||
|  |     await getOrderDates(); | ||||||
|  |     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; | ||||||
|  |     await getOrderDates(); | ||||||
|  |     return ordersTemp; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function getOrderDates() { | ||||||
|  |     const tempDates = new Array<Date>(); | ||||||
|  |     for (let i = 0; i <= 11; i++) { | ||||||
|  |       tempDates.push(...await fetchDates(i)); | ||||||
|  |     } | ||||||
|  |     dates.value = tempDates; | ||||||
|  |     console.log(dates.value); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function fetchDates(offset : number) { | ||||||
|  |     const date = new Date(Date.now()); | ||||||
|  |     date.setMonth(offset ); | ||||||
|  |     const urlString = "/kalendarz/" + Number(date.getFullYear()) + "-" + Number(date.getMonth()+1); | ||||||
|  |     const response = await axiosInstance.get(urlString, {withCredentials: true}); | ||||||
|  |     const datesTemp :Array<Date> = response.data; | ||||||
|  |     return datesTemp; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   function updateStores(contractor: Ref<Contractor | undefined>, contractors: Ref<Array<Contractor>>, tempOrder, route: Ref<Route | undefined>, routes: Ref<Array<Route> | undefined>, uuidString: string) { | ||||||
|  |     contractor.value = <Contractor>contractors.value?.find((contractor) => contractor.Knt_KntId == tempOrder.MZN_PodID) | ||||||
|  |     route.value = <Route>routes.value?.find((route) => route.MZT_MZTID == tempOrder.MZN_MZTID) | ||||||
|  |     deliveryDate.value = new Date(tempOrder.MZN_DataDos) | ||||||
|  |     orderDate.value = new Date(tempOrder.MZN_DataZam) | ||||||
|  |     if(!orderToClone.value) { | ||||||
|  |       uuid.value = uuidString | ||||||
|  |     }else { | ||||||
|  |       uuid.value = undefined | ||||||
|  |     } | ||||||
|  |     order.value = tempOrder | ||||||
|  |     additionalNotes.value = tempOrder.MZN_Uwagi | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function setOrderQuantities(tempOrder, categories: Ref<Array<Category>>) { | ||||||
|  |     for (const orderProduct of tempOrder.MZamElem) { | ||||||
|  |       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) { | ||||||
|  |           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 | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function loadOrder(uuidString: string, confirmed: boolean, contractor: Ref<Contractor|undefined>, contractors: Ref<Array<Contractor>>, categories: Ref<Array<Category>>, route: Ref<Route|undefined>, routes: Ref<Array<Route>|undefined>) { | ||||||
|  |     const response = await axiosInstance.get('/zamowienie/' + uuidString); | ||||||
|  |     const tempOrder = response.data; | ||||||
|  |     console.log(tempOrder); | ||||||
|  |     if(confirmed)tempOrder.MZN_Bufor = 0; | ||||||
|  |     updateStores(contractor, contractors, tempOrder, route, routes, uuidString) | ||||||
|  |     if(categories.value == undefined) return; | ||||||
|  |     setOrderQuantities(tempOrder, categories) | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return {orders,orderToClone, order, uuid, deliveryDate, orderDate, dates, additionalNotes, fetchOrders, loadOrder, fetchOrdersByDay, fetchOrdersByBuffer, fetchOrdersByDateStartAndEnd, fetchDates, getOrderDates} | ||||||
|  | }) | ||||||
							
								
								
									
										17
									
								
								src/stores/routes.store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/stores/routes.store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | import { defineStore } from 'pinia' | ||||||
|  | import type { Route } from '@/main' | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  |  | ||||||
|  | export const useRoutesStore = defineStore('routes', () => { | ||||||
|  |   const routes = ref<Array<Route>>(); | ||||||
|  |   const route = ref<Route>(); | ||||||
|  |  | ||||||
|  |   async function fetchRoutes() { | ||||||
|  |     const response = await axiosInstance.get('/trasy', {withCredentials: true}); | ||||||
|  |     routes.value = []; | ||||||
|  |     routes.value.push(...response.data); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return {routes, route, fetchRoutes}; | ||||||
|  | }); | ||||||
							
								
								
									
										72
									
								
								src/stores/siteControl.store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/stores/siteControl.store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | import { defineStore, storeToRefs } from 'pinia' | ||||||
|  | import { ref } from 'vue' | ||||||
|  | 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' | ||||||
|  | import { useRoutesStore } from '@/stores/routes.store' | ||||||
|  |  | ||||||
|  | export const useSiteControlStore = defineStore('siteControl', () => { | ||||||
|  |   const shownComponent = ref<string>("mainForm"); | ||||||
|  |   const showConfirmationModal = ref<boolean>(false); | ||||||
|  |   const showCancellationModal = ref<boolean>(false); | ||||||
|  |   const isDarkTheme = ref<boolean>(false); | ||||||
|  |   const isLoading = ref<boolean>(true); | ||||||
|  |  | ||||||
|  |   const orderStore = useOrdersStore(); | ||||||
|  |   const contractorsStore = useContractorsStore(); | ||||||
|  |   const categoriesStore = useCategoriesStore(); | ||||||
|  |   const routeStore = useRoutesStore(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   async function switchToForm() { | ||||||
|  |     await router.push("/"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function switchToOrders() { | ||||||
|  |     await router.push("/orders"); | ||||||
|  |      } | ||||||
|  |  | ||||||
|  |   async function switchToTable() { | ||||||
|  |     await router.push("/summary"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   function checkTheme() { | ||||||
|  |     isDarkTheme.value = !!window?.matchMedia?.('(prefers-color-scheme:dark)')?.matches; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function viewOrder(uuid : string, clone:boolean ) { | ||||||
|  |     shownComponent.value = "mainForm"; | ||||||
|  |     isLoading.value = true; | ||||||
|  |     await categoriesStore.fetchCategories(); | ||||||
|  |     const { contractor, contractors } = storeToRefs(contractorsStore); | ||||||
|  |     const { categories } = storeToRefs(categoriesStore); | ||||||
|  |     const { route, routes } = storeToRefs( routeStore ); | ||||||
|  |     orderStore.orderToClone = clone; | ||||||
|  |     await orderStore.loadOrder(uuid, false, contractor, contractors, categories, route, routes); | ||||||
|  |     isLoading.value=false; | ||||||
|  |     await router.push("/"); | ||||||
|  |     window.scrollTo(0,0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   async function newOrder(redirect : string) { | ||||||
|  |     const { order, uuid, deliveryDate, orderDate, additionalNotes } = storeToRefs(orderStore); | ||||||
|  |     const { contractor } = storeToRefs(contractorsStore); | ||||||
|  |     const { route } = storeToRefs(routeStore); | ||||||
|  |     contractor.value = undefined; | ||||||
|  |     order.value = undefined; | ||||||
|  |     uuid.value = undefined; | ||||||
|  |     deliveryDate.value = undefined; | ||||||
|  |     orderDate.value = undefined; | ||||||
|  |     route.value = undefined; | ||||||
|  |     additionalNotes.value = undefined; | ||||||
|  |     await categoriesStore.fetchCategories(); | ||||||
|  |     if (redirect) | ||||||
|  |     { | ||||||
|  |       await router.push(redirect); | ||||||
|  |       window.scrollTo(0,0); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return {isLoading, showConfirmationModal, showCancellationModal, isDarkTheme, shownComponent, switchToForm, switchToOrders, switchToTable, checkTheme, viewOrder ,newOrder}; | ||||||
|  | }) | ||||||
							
								
								
									
										10
									
								
								src/stores/user.store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/stores/user.store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | import { defineStore } from 'pinia' | ||||||
|  | import { ref } from 'vue' | ||||||
|  |  | ||||||
|  |  | ||||||
|  | export const useUserStore = defineStore('user', () => { | ||||||
|  |   const username = ref<string>(); | ||||||
|  |   const logoutButtonText = ref<string>(); | ||||||
|  |  | ||||||
|  |   return {username, logoutButtonText}; | ||||||
|  | }) | ||||||
							
								
								
									
										78
									
								
								src/views/LoginView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/views/LoginView.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import { Form, Field } from 'vee-validate'; | ||||||
|  | import * as Yup from 'yup'; | ||||||
|  | import { axiosInstance } from '@/main' | ||||||
|  | import { router } from '@/router/router' | ||||||
|  | import { useUserStore } from '@/stores/user.store' | ||||||
|  | import { getActivePinia, storeToRefs } from 'pinia' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  |  | ||||||
|  | const schema = Yup.object().shape({ | ||||||
|  |   username: Yup.string().required('Nazwa użytkownika jest wymagana'), | ||||||
|  |   password: Yup.string().required('Hasło jest wymagane') | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | async function onSubmit(values : any, { setErrors } : any) { | ||||||
|  |   const { username, password } = values; | ||||||
|  |  | ||||||
|  |   const body = await axiosInstance.post('/login', { | ||||||
|  |     username: username, | ||||||
|  |     password: password | ||||||
|  |   }).catch ((error) => { | ||||||
|  |     if(error.response.status == 401) { | ||||||
|  |       setErrors({ apiError: "unauthorized" }) | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  |   if(body != undefined && body.status == 200) { | ||||||
|  |     const userStore = useUserStore(); | ||||||
|  |     const siteControlStore = useSiteControlStore(); | ||||||
|  |     const { username } = storeToRefs(userStore); | ||||||
|  |     username.value = body.data.displayName; | ||||||
|  |     await siteControlStore.newOrder("/"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <div class="container is-flex is-justify-content-space-evenly is-align-items-center" style="min-height: calc(100vh - 3.5rem)"> | ||||||
|  |     <div class="box" style="width: 75%"> | ||||||
|  |       <h1 class="title is-3 mb-3">Login</h1> | ||||||
|  |       <Form @submit="onSubmit" :validation-schema="schema" v-slot="{ errors, isSubmitting }"> | ||||||
|  |         <div class="form-group"> | ||||||
|  |           <div class="field mb-3"> | ||||||
|  |             <label class="label is-small">Nazwa użytkownika</label> | ||||||
|  |             <div class="field is-small mb-3"> | ||||||
|  |               <Field class="input is-small" | ||||||
|  |                      type="text" | ||||||
|  |                     name="username" | ||||||
|  |                      :class="{ 'is-danger': errors.username }"/> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div class="has-text-danger">{{errors.username}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div class="form-group"> | ||||||
|  |           <div class="field mb-3"> | ||||||
|  |             <label class="label is-small">Hasło</label> | ||||||
|  |             <div class="field is-small mb-3"> | ||||||
|  |               <Field class="input is-small" | ||||||
|  |                      type="password" | ||||||
|  |                      name="password" | ||||||
|  |                      :class="{ 'is-danger': errors.password }"/> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div class="has-text-danger">{{errors.password}}</div> | ||||||
|  |         </div> | ||||||
|  |         <div class="form-group"> | ||||||
|  |           <button class="button is-info" :disabled="isSubmitting"> | ||||||
|  |             <span v-show="isSubmitting" class="spinner-border spinner-border-sm mr-1"></span> | ||||||
|  |             Login | ||||||
|  |           </button> | ||||||
|  |         </div> | ||||||
|  |         <div v-if="errors.apiError" class="has-text-danger mt-3 mb-3">Hasło lub nazwa użytkownika jest niepoprawna.</div> | ||||||
|  |       </Form> | ||||||
|  |     </div> | ||||||
|  |  | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
							
								
								
									
										63
									
								
								src/views/MainView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/views/MainView.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | |||||||
|  | <template class="has-navbar-fixed-top"> | ||||||
|  |   <NavBar/> | ||||||
|  |   <div v-if="isLoading"> | ||||||
|  |     <LoadingComponent/> | ||||||
|  |   </div> | ||||||
|  |   <div v-else> | ||||||
|  |     <MainForm | ||||||
|  |         v-if="order == undefined || order.MZN_Bufor==1 || ordersStore.orderToClone" | ||||||
|  |       /> | ||||||
|  |       <ConfirmedForm v-else-if="order.MZN_Bufor==0"/> | ||||||
|  |   </div> | ||||||
|  |   <ConfirmationModal v-show="showConfirmationModal" @close="showConfirmationModal = false"></ConfirmationModal> | ||||||
|  |   <CancelationModal v-show="showCancellationModal" @close="showCancellationModal = false"></CancelationModal> | ||||||
|  | <!--  <button class="button" @click="test">test</button>--> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import '@/assets/base.css' | ||||||
|  | import { useContractorsStore } from '@/stores/contractors.store' | ||||||
|  | import { getActivePinia, storeToRefs } from 'pinia' | ||||||
|  | import { useCategoriesStore } from '@/stores/categories.store' | ||||||
|  | import { useOrdersStore } from '@/stores/orders.store' | ||||||
|  | import { useSiteControlStore } from '@/stores/siteControl.store' | ||||||
|  | import { useUserStore } from '@/stores/user.store' | ||||||
|  | import { useRoutesStore } from '@/stores/routes.store' | ||||||
|  |  | ||||||
|  | const contractorsStore = useContractorsStore(); | ||||||
|  | const categoriesStore = useCategoriesStore(); | ||||||
|  | const ordersStore = useOrdersStore(); | ||||||
|  | const siteControlStore = useSiteControlStore(); | ||||||
|  | const userStore = useUserStore(); | ||||||
|  | const routesStore = useRoutesStore(); | ||||||
|  | const contractors = storeToRefs(contractorsStore).contractors; | ||||||
|  | const contractor = storeToRefs(contractorsStore).contractor; | ||||||
|  | const categories = storeToRefs(categoriesStore).categories; | ||||||
|  | const { uuid, order } = storeToRefs(ordersStore); | ||||||
|  | const { username } = storeToRefs(userStore); | ||||||
|  | const { showConfirmationModal, showCancellationModal, isLoading, shownComponent } = storeToRefs(siteControlStore); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | async function  fetchData() { | ||||||
|  |   //await categoriesStore.fetchCategories(); | ||||||
|  |   await contractorsStore.fetchContractors(); | ||||||
|  |   await routesStore.fetchRoutes(); | ||||||
|  |   //siteControlStore.newOrder(false); | ||||||
|  |   isLoading.value = false; | ||||||
|  | } | ||||||
|  | siteControlStore.checkTheme(); | ||||||
|  | fetchData(); | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style> | ||||||
|  | @media screen and (min-width: 500px) { | ||||||
|  |   .box { | ||||||
|  |     --bulma-box-padding: 1.5rem; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @media screen and (max-width: 500px) { | ||||||
|  |   .box { | ||||||
|  |     --bulma-box-padding: 0.75rem; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										12
									
								
								src/views/OrdersView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/views/OrdersView.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  |  | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <NavBar/> | ||||||
|  |   <OrdersSelector class="box is-shadowless"/> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <style scoped> | ||||||
|  |  | ||||||
|  | </style> | ||||||
							
								
								
									
										8
									
								
								src/views/SummaryView.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/views/SummaryView.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | <script setup lang="ts"> | ||||||
|  | import SummaryComponent from '@/components/SummaryComponent.vue' | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <template> | ||||||
|  |   <NavBar/> | ||||||
|  |   <SummaryComponent/> | ||||||
|  | </template> | ||||||
							
								
								
									
										4
									
								
								src/views/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/views/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | export { default as LoginView } from "./LoginView.vue"; | ||||||
|  | export { default as MainView } from "./MainView.vue"; | ||||||
|  | export { default as SummaryView } from "./SummaryView.vue" | ||||||
|  | export { default as OrdersView } from "./OrdersView.vue" | ||||||
							
								
								
									
										30
									
								
								srg
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								srg
									
									
									
									
									
								
							| @@ -1,30 +0,0 @@ | |||||||
| <div class="columns is-mobile"> |  | ||||||
|             <div class="column"> |  | ||||||
|               <div class="field"> |  | ||||||
|               <input |  | ||||||
|                 class="input is-normal" |  | ||||||
|                 type="text" |  | ||||||
|                 placeholder="Kwota" |  | ||||||
|               /> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|             <div class="column"> |  | ||||||
|               <div class="field has-addons"> |  | ||||||
|                 <p class="control"> |  | ||||||
|                   <span class="select is-small"> |  | ||||||
|                                         <select> |  | ||||||
|                                           <option v-for="option in towar.Options" :key="option">{{option}}</option> |  | ||||||
|                                         </select> |  | ||||||
|                                       </span> |  | ||||||
|                 </p> |  | ||||||
|                 <p class="control is-expanded"> |  | ||||||
|                   <input class="input" type="text" placeholder="Amount of money"> |  | ||||||
|                 </p> |  | ||||||
|                 <p class="control"> |  | ||||||
|                   <button class="button"> |  | ||||||
|                     Transfer |  | ||||||
|                   </button> |  | ||||||
|                 </p> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
| @@ -7,5 +7,8 @@ | |||||||
|     { |     { | ||||||
|       "path": "./tsconfig.app.json" |       "path": "./tsconfig.app.json" | ||||||
|     } |     } | ||||||
|   ] |   ], | ||||||
|  |   "compilerOptions": { | ||||||
|  |     "allowJs": true | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,11 +2,18 @@ import { fileURLToPath, URL } from 'node:url' | |||||||
|  |  | ||||||
| import { defineConfig } from 'vite' | import { defineConfig } from 'vite' | ||||||
| import vue from '@vitejs/plugin-vue' | import vue from '@vitejs/plugin-vue' | ||||||
|  | import Components from 'unplugin-vue-components/vite'; | ||||||
|  | import {PrimeVueResolver} from '@primevue/auto-import-resolver'; | ||||||
|  |  | ||||||
| // https://vitejs.dev/config/ | // https://vitejs.dev/config/ | ||||||
| export default defineConfig({ | export default defineConfig({ | ||||||
|   plugins: [ |   plugins: [ | ||||||
|     vue(), |     vue(), | ||||||
|  |     Components({ | ||||||
|  |       resolvers: [ | ||||||
|  |         PrimeVueResolver() | ||||||
|  |       ] | ||||||
|  |     }) | ||||||
|   ], |   ], | ||||||
|   resolve: { |   resolve: { | ||||||
|     alias: { |     alias: { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user