feat: add obi order visualization
parent
c2d60ae2b3
commit
5419bb538e
|
|
@ -0,0 +1,63 @@
|
|||
# Dépendances avec les liens npm et GitHub
|
||||
|
||||
## Dépendances de développement
|
||||
- @antfu/eslint-config-vue : [npm](https://www.npmjs.com/package/@antfu/eslint-config-vue), [GitHub](https://github.com/antfu/eslint-config) - Configuration ESLint pour les projets Vue.js
|
||||
- @antfu/utils : [npm](https://www.npmjs.com/package/@antfu/utils), [GitHub](https://github.com/antfu/utils) - Utilitaires utiles pour le développement avec Vite
|
||||
- @fullcalendar/core : [npm](https://www.npmjs.com/package/@fullcalendar/core), [GitHub](https://github.com/fullcalendar/fullcalendar) - Bibliothèque de calendrier complète pour les applications web
|
||||
- @fullcalendar/daygrid : [npm](https://www.npmjs.com/package/@fullcalendar/daygrid), [GitHub](https://github.com/fullcalendar/daygrid) - Extension de grille de jours pour FullCalendar
|
||||
- @fullcalendar/interaction : [npm](https://www.npmjs.com/package/@fullcalendar/interaction), [GitHub](https://github.com/fullcalendar/interaction) - Prise en charge de l'interaction utilisateur pour FullCalendar
|
||||
- @fullcalendar/list : [npm](https://www.npmjs.com/package/@fullcalendar/list), [GitHub](https://github.com/fullcalendar/list) - Extension de liste pour FullCalendar
|
||||
- @fullcalendar/timegrid : [npm](https://www.npmjs.com/package/@fullcalendar/timegrid), [GitHub](https://github.com/fullcalendar/timegrid) - Extension de grille temporelle pour FullCalendar
|
||||
- @fullcalendar/vue3 : [npm](https://www.npmjs.com/package/@fullcalendar/vue3), [GitHub](https://github.com/fullcalendar/vue) - Intégration Vue 3 pour FullCalendar
|
||||
- @iconify-json/mdi : [npm](https://www.npmjs.com/package/@iconify-json/mdi), [GitHub](https://github.com/iconify/iconify-json) - Bibliothèque d'icônes Material Design pour Iconify
|
||||
- @iconify/tools : [npm](https://www.npmjs.com/package/@iconify/tools), [GitHub](https://github.com/iconify/iconify-tools) - Outils pour travailler avec Iconify
|
||||
- @iconify/utils : [npm](https://www.npmjs.com/package/@iconify/utils), [GitHub](https://github.com/iconify/iconify-utils) - Utilitaires pour Iconify
|
||||
- @iconify/vue : [npm](https://www.npmjs.com/package/@iconify/vue), [GitHub](https://github.com/iconify/iconify-vue) - Composant Vue pour Iconify
|
||||
- @intlify/unplugin-vue-i18n : [npm](https://www.npmjs.com/package/@intlify/unplugin-vue-i18n), [GitHub](https://github.com/intlify/unplugin) - Plugin Vue I18n pour Vite
|
||||
- @tabler/icons : [npm](https://www.npmjs.com/package/@tabler/icons), [GitHub](https://github.com/tabler/tabler-icons) - Bibliothèque d'icônes Tabler
|
||||
- @tiptap/extension-character-count : [npm](https://www.npmjs.com/package/@tiptap/extension-character-count), [GitHub](https://github.com/ueberdosis/tiptap) - Extension pour compter le nombre de caractères dans Tiptap
|
||||
- @tiptap/extension-placeholder : [npm](https://www.npmjs.com/package/@tiptap/extension-placeholder), [GitHub](https://github.com/ueberdosis/tiptap) - Extension de l'indicateur de position dans Tiptap
|
||||
- @tiptap/extension-subscript : [npm](https://www.npmjs.com/package/@tiptap/extension-subscript), [GitHub](https://github.com/ueberdosis/tiptap) - Extension pour le texte en indice dans Tiptap
|
||||
- @tiptap/extension-superscript : [npm](https://www.npmjs.com/package/@tiptap/extension-superscript), [GitHub](https://github.com/ueberdosis/tiptap) - Extension pour le texte en exposant dans Tiptap
|
||||
- @tiptap/extension-underline : [npm](https://www.npmjs.com/package/@tiptap/extension-underline), [GitHub](https://github.com/ueberdosis/tiptap) - Extension pour souligner le texte dans Tiptap
|
||||
- @types/mapbox-gl : [npm](https://www.npmjs.com/package/@types/mapbox-gl), [GitHub](https://github.com/DefinitelyTyped/DefinitelyTyped) - Types TypeScript pour Mapbox GL
|
||||
- @types/node : [npm](https://www.npmjs.com/package/@types/node), [GitHub](https://github.com/DefinitelyTyped/DefinitelyTyped) - Types TypeScript pour Node.js
|
||||
- @types/webfontloader : [npm](https://www.npmjs.com/package/@types/webfontloader), [GitHub](https://github.com/DefinitelyTyped/DefinitelyTyped) - Types TypeScript pour WebFontLoader
|
||||
- @typescript-eslint/eslint-plugin : [npm](https://www.npmjs.com/package/@typescript-eslint/eslint-plugin), [GitHub](https://github.com/typescript-eslint/typescript-eslint) - Plugin ESLint pour TypeScript
|
||||
- @typescript-eslint/parser : [npm](https://www.npmjs.com/package/@typescript-eslint/parser), [GitHub](https://github.com/typescript-eslint/typescript-eslint) - Analyseur ESLint pour TypeScript
|
||||
- @videojs-player/vue : [npm](https://www.npmjs.com/package/@videojs-player/vue), [GitHub](https://github.com/videojs/theater) - Composant Vue pour Video.js
|
||||
- @vitejs/plugin-vue : [npm](https://www.npmjs.com/package/@vitejs/plugin-vue), [GitHub](https://github.com/vitejs/vite)
|
||||
- @vitejs/plugin-vue-jsx : [npm](https://www.npmjs.com/package/@vitejs/plugin-vue-jsx), [GitHub](https://github.com/vitejs/vite)
|
||||
- date-fns : [npm](https://www.npmjs.com/package/date-fns), [GitHub](https://github.com/date-fns/date-fns) - Bibliothèque JavaScript moderne de manipulation de dates
|
||||
- eslint : [npm](https://www.npmjs.com/package/eslint), [GitHub](https://github.com/eslint/eslint) - Linter JavaScript/TypeScript
|
||||
- eslint-config-airbnb-base : [npm](https://www.npmjs.com/package/eslint-config-airbnb-base), [GitHub](https://github.com/airbnb/javascript) - Configuration ESLint pour les règles Airbnb (base)
|
||||
- eslint-import-resolver-typescript : [npm](https://www.npmjs.com/package/eslint-import-resolver-typescript), [GitHub](https://github.com/alexgorbatchev/eslint-import-resolver-typescript) - Résolveur d'importation ESLint pour TypeScript
|
||||
- eslint-plugin-case-police : [npm](https://www.npmjs.com/package/eslint-plugin-case-police), [GitHub](https://github.com/antfu/eslint-plugin-case-police) - Plugin ESLint pour l'ajustement de casse dans le code
|
||||
- eslint-plugin-import : [npm](https://www.npmjs.com/package/eslint-plugin-import), [GitHub](https://github.com/benmosher/eslint-plugin-import) - Plugin ESLint pour les règles d'importation
|
||||
- eslint-plugin-promise : [npm](https://www.npmjs.com/package/eslint-plugin-promise), [GitHub](https://github.com/xjamundx/eslint-plugin-promise) - Plugin ESLint pour les règles liées aux promesses
|
||||
- eslint-plugin-regex : [npm](https://www.npmjs.com/package/eslint-plugin-regex), [GitHub](https://github.com/ota-meshi/eslint-plugin-regex) - Plugin ESLint pour les règles de regex
|
||||
- eslint-plugin-sonarjs : [npm](https://www.npmjs.com/package/eslint-plugin-sonarjs), [GitHub](https://github.com/SonarSource/eslint-plugin-sonarjs) - Plugin ESLint pour les règles SonarJS
|
||||
- eslint-plugin-unicorn : [npm](https://www.npmjs.com/package/eslint-plugin-unicorn), [GitHub](https://github.com/sindresorhus/eslint-plugin-unicorn) - Plugin ESLint pour des règles diverses et utiles
|
||||
- eslint-plugin-vue : [npm](https://www.npmjs.com/package/eslint-plugin-vue), [GitHub](https://github.com/vuejs/eslint-plugin-vue) - Plugin ESLint pour les règles Vue.js
|
||||
- msw : [npm](https://www.npmjs.com/package/msw), [GitHub](https://github.com/mswjs/msw) - Outil de simulation de requêtes HTTP pour les tests
|
||||
- postcss-html : [npm](https://www.npmjs.com/package/postcss-html), [GitHub](https://github.com/yisar/postcss-html) - Plugin PostCSS pour traiter les fichiers HTML en CSS
|
||||
- postcss-scss : [npm](https://www.npmjs.com/package/postcss-scss), [GitHub](https://github.com/postcss/postcss-scss) - Plugin PostCSS pour la syntaxe SCSS
|
||||
- sass : [npm](https://www.npmjs.com/package/sass), [GitHub](https://github.com/sass/sass) - Préprocesseur CSS Sass
|
||||
- stylelint : [npm](https://www.npmjs.com/package/stylelint), [GitHub](https://github.com/stylelint/stylelint) - Linter pour les feuilles de style CSS/SCSS
|
||||
- stylelint-codeguide : [npm](https://www.npmjs.com/package/stylelint-codeguide), [GitHub](https://github.com/kristerkari/stylelint-codeguide) - Guide de style et configuration Stylelint
|
||||
- stylelint-config-idiomatic-order : [npm](https://www.npmjs.com/package/stylelint-config-idiomatic-order), [GitHub](https://github.com/ream88/stylelint-config-idiomatic-order) - Configuration Stylelint avec un ordre idiomatique
|
||||
- stylelint-config-standard-scss : [npm](https://www.npmjs.com/package/stylelint-config-standard-scss), [GitHub](https://github.com/kristerkari/stylelint-config-standard-scss) - Configuration Stylelint pour SCSS basée sur les règles standard
|
||||
- stylelint-use-logical-spec : [npm](https://www.npmjs.com/package/stylelint-use-logical-spec), [GitHub](https://github.com/iKettles/stylelint-use-logical-spec) - Plugin Stylelint pour promouvoir l'utilisation de spécifications logiques
|
||||
- tsx : [npm](https://www.npmjs.com/package/tsx), [GitHub](https://github.com/windicss/tsx) - Plugin WindiCSS pour la prise en charge de JSX/TSX
|
||||
- type-fest : [npm](https://www.npmjs.com/package/type-fest), [GitHub](https://github.com/sindresorhus/type-fest) - Collection de types TypeScript utiles
|
||||
- typescript : [npm](https://www.npmjs.com/package/typescript), [GitHub](https://github.com/microsoft/TypeScript) - Langage de programmation TypeScript
|
||||
- unplugin-auto-import : [npm](https://www.npmjs.com/package/unplugin-auto-import), [GitHub](https://github.com/antfu/unplugin-auto-import) - Plugin Vite pour l'importation automatique
|
||||
- unplugin-vue-components : [npm](https://www.npmjs.com/package/unplugin-vue-components), [GitHub](https://github.com/antfu/unplugin) - Plugin Vite pour la gestion des composants Vue
|
||||
- unplugin-vue-router : [npm](https://www.npmjs.com/package/unplugin-vue-router), [GitHub](https://github.com/antfu/unplugin-vue-router) - Plugin Vite pour Vue Router
|
||||
- video.js : [npm](https://www.npmjs.com/package/video.js), [GitHub](https://github.com/videojs/video.js) - Bibliothèque de lecteur vidéo JavaScript
|
||||
- vite : [npm](https://www.npmjs.com/package/vite), [GitHub](https://github.com/vitejs/vite) - Constructeur d'outils rapide pour le développement web moderne
|
||||
- vite-plugin-vue-devtools : [npm](https://www.npmjs.com/package/vite-plugin-vue-devtools), [GitHub](https://github.com/antfu/vite-plugin-vue-devtools) - Plugin Vite pour intégrer les outils de développement Vue.js
|
||||
- vite-plugin-vue-layouts : [npm](https://www.npmjs.com/package/vite-plugin-vue-layouts), [GitHub](https://github.com/JohnCampionJr/vite-plugin-vue-layouts) - Plugin Vite pour la gestion des mises en page Vue.js
|
||||
- vite-plugin-vuetify : [npm](https://www.npmjs.com/package/vite-plugin-vuetify), [GitHub](https://github.com/antfu/vite-plugin-vuetify) - Plugin Vite pour l'intégration de Vuetify
|
||||
- vue-shepherd : [npm](https://www.npmjs.com/package/vue-shepherd), [GitHub](https://github.com/hipstersmoothie/vue-shepherd) - Tour de guide pour les applications Vue.js
|
||||
- vue-tsc : [npm](https://www.npmjs.com/package/vue-tsc), [GitHub](https://github.com/johnsoncodehk/vue-tsc) - Plugin TypeScript pour la compilation de fichiers `.vue`
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
interface meta {
|
||||
id: number
|
||||
}
|
||||
|
||||
interface statusData {
|
||||
code: string
|
||||
title: string
|
||||
}
|
||||
|
||||
interface transaction {
|
||||
transactionTypeId: number
|
||||
transactionDate: Date
|
||||
transactionNo: string
|
||||
transactionTypeDescription: string
|
||||
transactionSubtotal: number
|
||||
transactionTax: number
|
||||
transactionTotal: number
|
||||
}
|
||||
|
||||
interface Common {
|
||||
orderId: string
|
||||
requestingLocationCd: string
|
||||
requestingSystemCd: string
|
||||
customerId: string
|
||||
customerFirstName: string
|
||||
customerLastName: string
|
||||
status: string
|
||||
submitOrdMsg: string
|
||||
fdateCreation: Date
|
||||
consumed: boolean
|
||||
shipforpickupLocationCd: string
|
||||
shipforpickupSystemCd: string
|
||||
statusData: statusData
|
||||
transaction: transaction
|
||||
}
|
||||
|
||||
interface Lines {
|
||||
lineOrderId: number
|
||||
lineItemNo: number
|
||||
orderId: string
|
||||
requestId: number
|
||||
lineItemOms: string
|
||||
itemId: string
|
||||
orderedLineQty: number
|
||||
status: string
|
||||
transactionDate: Date
|
||||
shippingAgent: string
|
||||
trackingNumber: string
|
||||
fulfillmentId: string
|
||||
cartonNumber: string
|
||||
fdateCreation: Date
|
||||
consumed: boolean
|
||||
}
|
||||
|
||||
interface History {
|
||||
statusId: number
|
||||
Id: number
|
||||
status: string
|
||||
transactionDate: Date
|
||||
fdateCreation: Date
|
||||
}
|
||||
|
||||
export interface Order {
|
||||
meta: meta
|
||||
common: Common
|
||||
lines: Lines[]
|
||||
history: History[]
|
||||
}
|
||||
|
|
@ -23,6 +23,13 @@ export default [
|
|||
{
|
||||
title: 'OBI',
|
||||
icon: { icon: 'tabler-shopping-bag-check' },
|
||||
children: [
|
||||
{
|
||||
title: 'Orders list',
|
||||
to: { name: 'obi-order-list' },
|
||||
icon: { icon: 'tabler-bug' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Dotsoft',
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@ export default [
|
|||
{
|
||||
title: 'OBI',
|
||||
icon: { icon: 'tabler-shopping-bag-check' },
|
||||
children: [
|
||||
{
|
||||
title: 'Orders',
|
||||
to: { name: 'obi-order-list' },
|
||||
icon: { icon: 'tabler-bug' },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Dotsoft',
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ const exportEXCEL = () => {
|
|||
:items-per-page="options.itemsPerPage"
|
||||
:page="options.page"
|
||||
:options="options"
|
||||
density="compact"
|
||||
/>
|
||||
</VCol>
|
||||
</Vcard>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
<script setup lang="ts">
|
||||
import type { Order } from '@/models/Order'
|
||||
import OrderPanel from '@/views/pages/order/view/OrderPanel.vue'
|
||||
import OrderTabGeneral from '@/views/pages/order/view/OrderTabGeneralH.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const route = useRoute('obi-order-details-id')
|
||||
const orderData = ref<Order>()
|
||||
const orderTab = ref(null)
|
||||
|
||||
const tabs = [
|
||||
{ title: 'General' },
|
||||
{ title: 'Preparation' },
|
||||
{ title: 'Receipt' },
|
||||
{ title: 'Flow' },
|
||||
]
|
||||
|
||||
const { data, error } = await useApi<Order>(`/obi/order/${route.params.id}`)
|
||||
|
||||
if (error.value)
|
||||
console.log(error.value)
|
||||
else if (data.value)
|
||||
orderData.value = data.value
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VBreadcrumbs
|
||||
class="px-0 py-2"
|
||||
:items="[
|
||||
{ title: t('Home'), to: { name: 'root' } },
|
||||
{ title: t('Order list'), to: { name: 'obi-order-list' } },
|
||||
{ title: `#${route.params.id}` },
|
||||
]"
|
||||
/>
|
||||
<div>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap gap-y-4 mb-6">
|
||||
<div>
|
||||
<div class="d-flex gap-2 align-center mb-0 flex-wrap">
|
||||
<h4 class="text-h3 font-weight-medium">
|
||||
Order Id: {{ orderData && orderData.common.orderId }}
|
||||
</h4>
|
||||
<div class="d-flex gap-2">
|
||||
<VChip
|
||||
label
|
||||
color="success"
|
||||
size="x-large"
|
||||
>
|
||||
{{ orderData && orderData.common.statusData.code }}
|
||||
</VChip>
|
||||
<VChip
|
||||
label
|
||||
size="x-large"
|
||||
:color="orderData && orderData.common.consumed ? 'success' : 'error'"
|
||||
>
|
||||
{{ orderData && orderData.common.consumed ? 'Consumed' : 'Not consumed' }}
|
||||
</VChip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex gap-4">
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
color="primary"
|
||||
>
|
||||
Reload
|
||||
</VBtn>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 👉 Order -->
|
||||
<VRow v-if="orderData">
|
||||
<VCol
|
||||
cols="12"
|
||||
md="5"
|
||||
lg="4"
|
||||
>
|
||||
<OrderPanel :order-data="orderData" />
|
||||
</VCol>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="7"
|
||||
lg="8"
|
||||
>
|
||||
<VTabs
|
||||
v-model="orderTab"
|
||||
class="v-tabs-pill mb-3 disable-tab-transition"
|
||||
>
|
||||
<VTab
|
||||
v-for="tab in tabs"
|
||||
:key="tab.title"
|
||||
>
|
||||
<span>{{ tab.title }}</span>
|
||||
</VTab>
|
||||
</VTabs>
|
||||
<VWindow
|
||||
v-model="orderTab"
|
||||
class="disable-tab-transition"
|
||||
:touch="false"
|
||||
>
|
||||
<!-- 👉 General -->
|
||||
<VWindowItem>
|
||||
<OrderTabGeneral :order-data="orderData" />
|
||||
</VWindowItem>
|
||||
</VWindow>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,244 @@
|
|||
<script setup lang="ts">
|
||||
import { VDataTableServer } from 'vuetify/labs/VDataTable'
|
||||
import { paginationMeta } from '@api-utils/paginationMeta'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const widgetData = ref([
|
||||
{ title: 'Pending Payment', value: 56, icon: 'tabler-calendar-stats' },
|
||||
{ title: 'Unfulfilled', value: 25, icon: 'tabler-circle-x' },
|
||||
{ title: 'Completed', value: 12689, icon: 'tabler-checks' },
|
||||
{ title: 'Refunded', value: 124, icon: 'tabler-wallet' },
|
||||
])
|
||||
|
||||
const searchQuery = ref('')
|
||||
|
||||
// Data table options
|
||||
const itemsPerPage = ref(10)
|
||||
const page = ref(1)
|
||||
const sortBy = ref()
|
||||
const orderBy = ref()
|
||||
|
||||
// Data table Headers
|
||||
const headers = [
|
||||
{ title: 'Id', key: 'meta.id' },
|
||||
{ title: 'Order', key: 'common.orderId' },
|
||||
{ title: 'Date', key: 'common.transaction.transactionDate' },
|
||||
{ title: 'Status', key: 'common.statusData.code' },
|
||||
{ title: 'Type', key: 'common.transaction.transactionTypeDescription' },
|
||||
]
|
||||
|
||||
// Update data table options
|
||||
const updateOptions = (options: any) => {
|
||||
page.value = options.page
|
||||
sortBy.value = options.sortBy[0]?.key
|
||||
orderBy.value = options.sortBy[0]?.order
|
||||
}
|
||||
|
||||
const resolveStatus = (status: string) => {
|
||||
if (status === 'fulfilled')
|
||||
return { text: 'fulfilled', color: 'success' }
|
||||
else if (status === 'received')
|
||||
return { text: 'received', color: 'primary' }
|
||||
else if (status === 'intransit polled')
|
||||
return { text: 'intransit polled', color: 'info' }
|
||||
else if (status === 'new_order')
|
||||
return { text: 'new_order', color: 'warning' }
|
||||
else
|
||||
return { text: status, color: 'error' }
|
||||
}
|
||||
|
||||
const { data: ordersData } = await useApi<any>(createUrl('/obi/order',
|
||||
{
|
||||
query: {
|
||||
q: searchQuery,
|
||||
page,
|
||||
itemsPerPage,
|
||||
sortBy,
|
||||
orderBy,
|
||||
},
|
||||
},
|
||||
))
|
||||
|
||||
const orders = computed(() => ordersData.value.orders)
|
||||
const totalOrder = computed(() => ordersData.value.total)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VBreadcrumbs
|
||||
class="px-0 py-2"
|
||||
:items="[
|
||||
{ title: t('Home'), to: { name: 'root' } },
|
||||
{ title: t('Order list') },
|
||||
]"
|
||||
/>
|
||||
<div>
|
||||
<VCard class="mb-6">
|
||||
<!-- 👉 Widgets -->
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<template
|
||||
v-for="(data, id) in widgetData"
|
||||
:key="id"
|
||||
>
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="6"
|
||||
md="3"
|
||||
class="px-6"
|
||||
>
|
||||
<div
|
||||
class="d-flex justify-space-between"
|
||||
:class="$vuetify.display.xs
|
||||
? 'product-widget'
|
||||
: $vuetify.display.sm
|
||||
? id < 2 ? 'product-widget' : ''
|
||||
: ''"
|
||||
>
|
||||
<div class="d-flex flex-column gap-y-1">
|
||||
<h4 class="text-h4">
|
||||
{{ data.value }}
|
||||
</h4>
|
||||
|
||||
<h6 class="text-h6">
|
||||
{{ data.title }}
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
<VAvatar
|
||||
variant="tonal"
|
||||
rounded
|
||||
size="38"
|
||||
>
|
||||
<VIcon
|
||||
:icon="data.icon"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
</div>
|
||||
</VCol>
|
||||
<VDivider
|
||||
v-if="$vuetify.display.mdAndUp ? id !== widgetData.length - 1
|
||||
: $vuetify.display.smAndUp ? id % 2 === 0
|
||||
: false"
|
||||
vertical
|
||||
inset
|
||||
length="55"
|
||||
/>
|
||||
</template>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
|
||||
<VCard>
|
||||
<!-- 👉 Filters -->
|
||||
<VCardText>
|
||||
<div class="d-flex justify-sm-space-between justify-start flex-wrap gap-4">
|
||||
<VTextField
|
||||
v-model="searchQuery"
|
||||
density="compact"
|
||||
placeholder="Search"
|
||||
style=" max-inline-size: 200px; min-inline-size: 200px;"
|
||||
/>
|
||||
|
||||
<div class="d-flex gap-x-4 align-center">
|
||||
<AppSelect
|
||||
v-model="itemsPerPage"
|
||||
style="min-inline-size: 6.25rem;"
|
||||
:items="[5, 10, 20, 50, 100]"
|
||||
/>
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
prepend-icon="tabler-screen-share"
|
||||
text="Export"
|
||||
append-icon="tabler-chevron-down"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</VCardText>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<!-- 👉 Order Table -->
|
||||
<VDataTableServer
|
||||
v-model:items-per-page="itemsPerPage"
|
||||
v-model:page="page"
|
||||
:headers="headers"
|
||||
:items="orders"
|
||||
:items-length="totalOrder"
|
||||
class="text-no-wrap"
|
||||
density="compact"
|
||||
@update:options="updateOptions"
|
||||
>
|
||||
<!-- Order ID -->
|
||||
<template #item.common.orderId="{ item }">
|
||||
<RouterLink
|
||||
:to="{ name: 'obi-order-details-id', params: { id: item.meta.id } }"
|
||||
class="font-weight-medium"
|
||||
>
|
||||
#{{ item.common.orderId }}
|
||||
</RouterLink>
|
||||
</template>
|
||||
|
||||
<!-- Status -->
|
||||
<template #item.common.statusData.code="{ item }">
|
||||
<VChip
|
||||
v-bind="resolveStatus(item.common.statusData.code)"
|
||||
label
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- pagination -->
|
||||
<template #bottom>
|
||||
<VDivider />
|
||||
|
||||
<div class="d-flex align-center justify-sm-space-between justify-center flex-wrap gap-3 pa-5 pt-3">
|
||||
<p class="text-sm text-disabled mb-0">
|
||||
{{ paginationMeta({ page, itemsPerPage }, totalOrder) }}
|
||||
</p>
|
||||
|
||||
<VPagination
|
||||
v-model="page"
|
||||
:length="Math.ceil(totalOrder / itemsPerPage)"
|
||||
:total-visible="$vuetify.display.xs ? 1 : Math.min(Math.ceil(totalOrder / itemsPerPage), 5)"
|
||||
>
|
||||
<template #prev="slotProps">
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
color="default"
|
||||
v-bind="slotProps"
|
||||
:icon="false"
|
||||
>
|
||||
Previous
|
||||
</VBtn>
|
||||
</template>
|
||||
|
||||
<template #next="slotProps">
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
color="default"
|
||||
v-bind="slotProps"
|
||||
:icon="false"
|
||||
>
|
||||
Next
|
||||
</VBtn>
|
||||
</template>
|
||||
</VPagination>
|
||||
</div>
|
||||
</template>
|
||||
</VDataTableServer>
|
||||
</VCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.customer-title:hover{
|
||||
color: rgba(var(--v-theme-primary)) !important;
|
||||
}
|
||||
|
||||
.product-widget{
|
||||
border-block-end: 1px solid rgba(var(--v-theme-on-surface), var(--v-border-opacity));
|
||||
padding-block-end: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -275,6 +275,7 @@ watch(route, (to, from) => {
|
|||
:items-per-page="stStoreList.itemsPerPage"
|
||||
:page="stStoreList.currentPage"
|
||||
:sort-by="stStoreList.getSortBy()"
|
||||
density="compact"
|
||||
@update:sort-by="sortBy => { stStoreList.setSortBy(sortBy[0]?.key) ; stStoreList.setSortOrder(sortBy[0]?.order) }"
|
||||
@update:items-per-page="itemsPerPage => { stStoreList.setItemsPerPage(itemsPerPage) }"
|
||||
@update:page="page => { stStoreList.setCurrentPage(page) }"
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
"Dates range error": "With a date range, a text of at least 5 characters must be specified",
|
||||
"Close": "Close",
|
||||
"Connect to invidual POS": "Connect to invidual POS",
|
||||
"Orders list": "Orders list",
|
||||
"---------------------------": "---------------------------",
|
||||
"UI Elements": "عناصر واجهة المستخدم",
|
||||
"Forms & Tables": "النماذج والجداول",
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
"Dates range error": "With a date range, a text of at least 5 characters must be specified",
|
||||
"Close": "Close",
|
||||
"Connect to invidual POS": "Connect to invidual POS",
|
||||
"Orders list": "Orders list",
|
||||
"---------------------------": "---------------------------",
|
||||
"UI Elements": "UI Elements",
|
||||
"Forms & Tables": "Forms & Tables",
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@
|
|||
"Dates range error": "Dans le cas d'une plage de dates, un texte d'au moins 5 caractères doit être spécifié.",
|
||||
"Close": "Fermer",
|
||||
"Connect to invidual POS": "Connexion à une caisse individuelle",
|
||||
"Orders list": "Liste des commandes",
|
||||
"---------------------------": "---------------------------",
|
||||
"UI Elements": "ÉLÉMENTS DE L'UI",
|
||||
"Forms & Tables": "Formulaires et tableaux",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
import { propsToCopy } from '@iconify/utils/lib/icon-set/get-icons';
|
||||
<script setup lang="ts">
|
||||
import { format } from 'date-fns'
|
||||
import type { Order } from '@/models/Order'
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const resolveConsumed = (consumed: boolean) => {
|
||||
if (consumed)
|
||||
return { text: 'Consumed', color: 'success' }
|
||||
else
|
||||
return { text: 'Not consumed', color: 'error' }
|
||||
}
|
||||
|
||||
interface Props {
|
||||
orderData: Order
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VRow>
|
||||
<!-- SECTION Order -->
|
||||
<VCol cols="12">
|
||||
<VCard v-if="props.orderData">
|
||||
<!-- 👉 Order Details -->
|
||||
<VCardText>
|
||||
<div class="text-disabled text-uppercase text-sm">
|
||||
Order Details
|
||||
</div>
|
||||
<VList class="card-list mt-2">
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">Origin request:</span>
|
||||
<span>
|
||||
{{ props.orderData.common.requestingLocationCd }} / {{ props.orderData.common.requestingSystemCd }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">Cust Id:</span>
|
||||
<span>
|
||||
{{ props.orderData.common.customerId }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">Cust. name:</span>
|
||||
<span>
|
||||
{{ props.orderData.common.customerLastName }} {{ props.orderData.common.customerFirstName }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">Date creation:</span>
|
||||
<span>
|
||||
{{ format(props.orderData.common.fdateCreation, "yyyy-MM-dd HH:mm:ss") }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">Ship for Pickup:</span>
|
||||
<span>
|
||||
{{ props.orderData.common.shipforpickupLocationCd }} / {{ props.orderData.common.shipforpickupSystemCd }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
</VList>
|
||||
<div class="text-disabled text-uppercase mt-4 text-sm">
|
||||
Transaction
|
||||
</div>
|
||||
<VList class="card-list mt-2">
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">No:</span>
|
||||
<span>
|
||||
{{ props.orderData.common.transaction.transactionNo }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">Date:</span>
|
||||
<span>
|
||||
{{ format(props.orderData.common.transaction.transactionDate, "yyyy-MM-dd HH:mm:ss") }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
<VListItem>
|
||||
<div class="text-body-1">
|
||||
<span class="font-weight-bold me-2">Type:</span>
|
||||
<span>
|
||||
{{ props.orderData.common.transaction.transactionTypeDescription }}
|
||||
</span>
|
||||
</div>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="text-center">
|
||||
<VBtn>
|
||||
Edit XML Details
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="text-center">
|
||||
<VBtn>
|
||||
Proximis
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
|
||||
<VCardText class="text-center">
|
||||
<VBtn>
|
||||
SQL Obi
|
||||
</VBtn>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</vrow>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 0.75rem;
|
||||
}
|
||||
|
||||
.text-capitalize {
|
||||
text-transform: capitalize !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
<script setup lang="ts">
|
||||
import { format } from 'date-fns'
|
||||
import { VDataTable } from 'vuetify/labs/VDataTable'
|
||||
import type { Order } from '@/models/Order'
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
interface Props {
|
||||
orderData: Order
|
||||
}
|
||||
|
||||
const headers = computed(() => [
|
||||
{ title: '', key: 'data-table-expand' },
|
||||
{ title: '#', key: 'lineItemNo' },
|
||||
{ title: t('Item'), key: 'itemId' },
|
||||
{ title: t('Qty'), key: 'orderedLineQty' },
|
||||
{ title: t('Date'), key: 'transactionDate' },
|
||||
{ title: t('Status'), key: 'status' },
|
||||
{ title: t('Created'), key: 'fdateCreation' },
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 👉 Order Details -->
|
||||
<VCard class="mb-6">
|
||||
<VCardItem>
|
||||
<template #title>
|
||||
<h5 class="text-h5">
|
||||
Order Lines
|
||||
</h5>
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<VDataTable
|
||||
:headers="headers"
|
||||
:items="props.orderData.lines"
|
||||
density="compact"
|
||||
class="text-no-wrap dt-row-striped"
|
||||
expand-on-click
|
||||
>
|
||||
<!-- Expanded Row Data -->
|
||||
<template #expanded-row="slotProps">
|
||||
<td :colspan="headers.length">
|
||||
<VTable
|
||||
density="compact"
|
||||
class="text-no-wrap"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-uppercase">
|
||||
Status history
|
||||
</th>
|
||||
<th class="text-uppercase">
|
||||
Transaction date history
|
||||
</th>
|
||||
<th class="text-uppercase">
|
||||
Creation date history
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="item in slotProps.item.history"
|
||||
:key="item.statusId"
|
||||
>
|
||||
<td>
|
||||
{{ item.status }}
|
||||
</td>
|
||||
<td>
|
||||
{{ format(item.transactionDate, "EEEE d MMMM yyyy HH:mm:ss") }}
|
||||
</td>
|
||||
<td>
|
||||
{{ format(item.fdateCreation, "EEEE d MMMM yyyy HH:mm:ss") }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
</td>
|
||||
</template>
|
||||
|
||||
<template #item.transactionDate="{ item }">
|
||||
{{ format(new Date(item.transactionDate), 'dd/MM/yyyy HH:mm:ss') }}
|
||||
</template>
|
||||
|
||||
<template #item.fdateCreation="{ item }">
|
||||
{{ format(new Date(item.fdateCreation), 'dd/MM/yyyy HH:mm:ss') }}
|
||||
</template>
|
||||
|
||||
<template #bottom />
|
||||
</VDataTable>
|
||||
|
||||
<VDivider />
|
||||
|
||||
<VCardText>
|
||||
<div class="d-flex align-end flex-column">
|
||||
<table class="text-high-emphasis">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-high-emphasis font-weight-medium">
|
||||
Tax:
|
||||
</td>
|
||||
<td style="text-align: end;">
|
||||
{{ parseFloat(orderData.common.transaction.transactionTax.toString()).toFixed(2) }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-high-emphasis font-weight-medium">
|
||||
Total:
|
||||
</td>
|
||||
<td style="text-align: end;">
|
||||
{{ parseFloat(orderData.common.transaction.transactionTotal.toString()).toFixed(2) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
<!-- 👉 Order History -->
|
||||
<VCard title="Order History">
|
||||
<VCardText>
|
||||
<VTimeline
|
||||
truncate-line="both"
|
||||
align="start"
|
||||
side="end"
|
||||
line-color="primary"
|
||||
density="compact"
|
||||
class="v-timeline-density-compact"
|
||||
>
|
||||
<template
|
||||
v-for="(historyItem, index) in props.orderData.history"
|
||||
:key="index"
|
||||
>
|
||||
<VTimelineItem
|
||||
dot-color="primary"
|
||||
size="x-small"
|
||||
>
|
||||
<div class="d-flex justify-space-between align-center">
|
||||
<div class="app-timeline-title">
|
||||
Order was {{ historyItem.status }} (Id: #{{ historyItem.statusId }})
|
||||
</div>
|
||||
<div class="app-timeline-meta">
|
||||
{{ format(historyItem.transactionDate, "EEEE d MMMM yyyy HH:mm:ss") }}
|
||||
</div>
|
||||
</div>
|
||||
<p class="app-timeline-text mb-0">
|
||||
Your order has been {{ historyItem.status }} successfully
|
||||
</p>
|
||||
</VTimelineItem>
|
||||
</template>
|
||||
</VTimeline>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
|
@ -43,6 +43,8 @@ declare module 'vue-router/auto/routes' {
|
|||
'$error': RouteRecordInfo<'$error', '/:error(.*)', { error: ParamValue<true> }, { error: ParamValue<false> }>,
|
||||
'flux-bl-not-sent': RouteRecordInfo<'flux-bl-not-sent', '/flux/bl/not_sent', Record<never, never>, Record<never, never>>,
|
||||
'login': RouteRecordInfo<'login', '/login', Record<never, never>, Record<never, never>>,
|
||||
'obi-order-details-id': RouteRecordInfo<'obi-order-details-id', '/obi/order/details/:id', { id: ParamValue<true> }, { id: ParamValue<false> }>,
|
||||
'obi-order-list': RouteRecordInfo<'obi-order-list', '/obi/order/list', Record<never, never>, Record<never, never>>,
|
||||
'store-details': RouteRecordInfo<'store-details', '/store/details', Record<never, never>, Record<never, never>>,
|
||||
'store-list': RouteRecordInfo<'store-list', '/store/list', Record<never, never>, Record<never, never>>,
|
||||
'xadmin-log': RouteRecordInfo<'xadmin-log', '/xadmin/log', Record<never, never>, Record<never, never>>,
|
||||
|
|
|
|||
Loading…
Reference in New Issue