#init
This commit is contained in:
38
src/App.vue
38
src/App.vue
@@ -4,33 +4,25 @@ import Header from "./components/TemplateParts/Header.vue";
|
||||
|
||||
<template>
|
||||
|
||||
<Header></Header>
|
||||
<div v-if="$route.path === '/login'">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
||||
<main id="main" class="main">
|
||||
<Header></Header>
|
||||
|
||||
<!--
|
||||
<div class="pagetitle">
|
||||
<h1>Dashboard</h1>
|
||||
<nav>
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="index.html">Home</a></li>
|
||||
<li class="breadcrumb-item active">Dashboard</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
-->
|
||||
<!-- End Page Title -->
|
||||
<main id="main" class="main">
|
||||
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition :name="route.meta.transition || 'fade'" mode="out-in">
|
||||
<div :key="route.path">
|
||||
<component :is="Component"/>
|
||||
</div>
|
||||
</transition>
|
||||
</router-view>
|
||||
</main>
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition :name="route.meta.transition || 'fade'" mode="out-in">
|
||||
<div :key="route.path">
|
||||
<component :is="Component"/>
|
||||
</div>
|
||||
</transition>
|
||||
</router-view>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div class="search-form d-flex align-items-center">
|
||||
<input type="text" name="query" placeholder="Scanner un bon de livraison" v-model="query" @input="searchDeliveries"
|
||||
autofocus>
|
||||
<input type="text" name="query" placeholder="Scanner un bon de livraison" v-model="query" @input="searchDeliveries" autofocus>
|
||||
<button type="submit" title="Valider"><i class="fa-solid fa-barcode fa-fw"></i></button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,8 +29,9 @@ export default {
|
||||
|
||||
const apiResult = await ShipmentApi.getDeliveriesByOrder(this.query)
|
||||
|
||||
this.shipmentStore.setOrderNumber(this.query)
|
||||
this.shipmentStore.setIdOrder(this.query)
|
||||
this.shipmentStore.setDeliveryLines(apiResult.data)
|
||||
this.query = null
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,13 @@ const routes = [
|
||||
name: 'home',
|
||||
component: () => import('/src/views/index.vue'),
|
||||
meta: { transition: 'slide-right' },
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('/src/views/login.vue'),
|
||||
meta: { transition: 'slide-right' },
|
||||
}
|
||||
|
||||
]
|
||||
const router = createRouter({
|
||||
history: createWebHistory('/vue-admin'),
|
||||
|
||||
@@ -1,39 +1,8 @@
|
||||
import {defineStore} from 'pinia'
|
||||
|
||||
|
||||
const shipmentStatus = [
|
||||
{
|
||||
code: "30",
|
||||
label: 'Colisage',
|
||||
allowStatus: [3, 80, 39, 37]
|
||||
|
||||
},
|
||||
{
|
||||
code: "3",
|
||||
label: 'A livrer',
|
||||
allowStatus: []
|
||||
},
|
||||
{
|
||||
code: "31",
|
||||
label: 'A livrer Dépôt',
|
||||
allowStatus: [3, 80, 39, 37]
|
||||
},
|
||||
{
|
||||
code: "80",
|
||||
label: 'Manquant à rembourser',
|
||||
allowStatus: []
|
||||
},
|
||||
{
|
||||
code: "39",
|
||||
label: 'Produit en commande',
|
||||
allowStatus: [30, 3, 80, 39, 37]
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
export const useShipmentStore = defineStore('shipment', {
|
||||
state: () => ({
|
||||
orderNumber: '',
|
||||
idOrder: null,
|
||||
deliveryLines: []
|
||||
}),
|
||||
getters: {
|
||||
@@ -41,14 +10,13 @@ export const useShipmentStore = defineStore('shipment', {
|
||||
},
|
||||
actions: {
|
||||
setDeliveryLines(lines) {
|
||||
// for (const line of lines) {
|
||||
// let labelFinder = shipmentStatus.filter(status => status.code === line.status)
|
||||
// line.labelStatus = (labelFinder.length > 0) ? labelFinder.code : 'Unknown'
|
||||
// }
|
||||
for (const line of lines) {
|
||||
line.scan = false
|
||||
}
|
||||
this.deliveryLines = lines
|
||||
},
|
||||
setOrderNumber(orderNumber) {
|
||||
this.orderNumber = orderNumber
|
||||
setIdOrder(idOrder) {
|
||||
this.idOrder = idOrder
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -442,7 +442,7 @@ h6 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header .search-form input {
|
||||
.search-form input {
|
||||
border: 0;
|
||||
font-size: 14px;
|
||||
color: #012970;
|
||||
@@ -453,21 +453,21 @@ h6 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.header .search-form input:focus,
|
||||
.header .search-form input:hover {
|
||||
.search-form input:focus,
|
||||
.search-form input:hover {
|
||||
outline: none;
|
||||
box-shadow: 0 0 10px 0 rgba(1, 41, 112, 0.15);
|
||||
border: 1px solid rgba(1, 41, 112, 0.3);
|
||||
}
|
||||
|
||||
.header .search-form button {
|
||||
.search-form button {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
margin-left: -30px;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.header .search-form button i {
|
||||
.search-form button i {
|
||||
color: #012970;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +1,80 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<div class="table-responsive mb-4" v-if="store.deliveriesCounter >0">
|
||||
<table class="table table-striped table-hover align-middle">
|
||||
<thead style="font-size:.8em">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Désignation</th>
|
||||
<th>EAN</th>
|
||||
<th>EAN Colisé <i class="fa-solid fa-circle-question" data-bs-toggle="tooltip"
|
||||
data-bs-title="Article qui sera envoyé à Winpharma. Pourra être différent du EAN lorsque la boîte mise dans le colis ne correspond pas."></i>
|
||||
</th>
|
||||
<!--<th>Réf.</th>
|
||||
<th>Localisation</th>
|
||||
<th>Type</th>-->
|
||||
<th>Statut</th>
|
||||
<!--<th title="N° expédition transporteur"><small>N° exp. transporteur</small></th>-->
|
||||
<th><span class="text-nowrap">N° tracking</span></th>
|
||||
<th>Informations</th>
|
||||
<th>Historique</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-for="location in locationGroup">
|
||||
<tr class="table-group-divider table-secondary">
|
||||
<th></th>
|
||||
<th colspan="7"
|
||||
class="text-uppercase"><i class="fa-solid fa-location-dot"></i> {{ location }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr v-for="line in store.deliveryLines.filter(obj => obj.physical_location === location)">
|
||||
<td class="text-center"><input class="form-check-input" type="checkbox" role="switch"
|
||||
name="id_product_to_deliver[]"></td>
|
||||
<td>{{ line.product_name }}</td>
|
||||
<td>{{ line.product_ref }}</td>
|
||||
<td class="text-nowrap">
|
||||
<div class="input-group input-group-sm flex-nowrap">
|
||||
<button type="button" name="ean_winpharma_btn" class="btn btn-primary to_edit" data-bs-toggle="tooltip"
|
||||
data-bs-title="Scanner le code barre à coliser" disabled="" aria-label="Editer"
|
||||
data-bs-original-title="Editer"><i class="fa-solid fa-barcode fa-sm"></i></button>
|
||||
<input class="form-control to_edit" type="text" name="line_1_ean_winpharma" value="" disabled=""
|
||||
required="required"></div>
|
||||
</td>
|
||||
<td><span class="text-nowrap badge bg-info label_status_initial">{{ line.labelStatus }}</span><select
|
||||
<div class="modal fade" ref="modal" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">EAN {{ eanScan }} not found</h5>
|
||||
<button type="button" class="btn-close" aria-label="Close" @click="modal.hide()"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
TODO : liaison manuelle
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive mb-4" v-if="store.deliveriesCounter >0">
|
||||
<div class="pagetitle">
|
||||
<h1>Commande n°{{ store.idOrder }}</h1>
|
||||
</div>
|
||||
|
||||
<div class=" d-flex align-items-center">
|
||||
<div class="search-form" style="width: 360px">
|
||||
<input type="text" placeholder="Scanner un article" ref="productScan" v-model="eanScan"
|
||||
@input="searchEanInDeliveries">
|
||||
<button type="submit" title="Valider"><i class="fa-solid fa-barcode fa-fw"></i></button>
|
||||
</div>
|
||||
|
||||
<div class="ps-4" v-if="store.deliveriesCounter === deliveryLines.filter(line=>line.scan).length">
|
||||
<button class="btn btn-primary ms-10">Valider</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<table class="table table-striped table-hover align-middle mt-4">
|
||||
<thead style="font-size:.8em">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Désignation</th>
|
||||
<th>EAN</th>
|
||||
<th>EAN Colisé <i class="fa-solid fa-circle-question" data-bs-toggle="tooltip"
|
||||
data-bs-title="Article qui sera envoyé à Winpharma. Pourra être différent du EAN lorsque la boîte mise dans le colis ne correspond pas."></i>
|
||||
</th>
|
||||
<!--<th>Réf.</th>
|
||||
<th>Localisation</th>
|
||||
<th>Type</th>-->
|
||||
<th>Statut</th>
|
||||
<!--<th title="N° expédition transporteur"><small>N° exp. transporteur</small></th>-->
|
||||
<th><span class="text-nowrap">N° tracking</span></th>
|
||||
<th>Informations</th>
|
||||
<th>Historique</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-for="location in locationGroup">
|
||||
<tr class="table-group-divider table-secondary"
|
||||
v-if="store.deliveryLines.filter(obj => obj.physical_location === location).length >0">
|
||||
<th></th>
|
||||
<th colspan="7"
|
||||
class="text-uppercase"><i class="fa-solid fa-location-dot"></i> {{ location }}
|
||||
</th>
|
||||
</tr>
|
||||
<tr v-for="line in store.deliveryLines.filter(obj => obj.physical_location === location)"
|
||||
:class="(line.scan) ? 'table-primary' : null">
|
||||
<td class="text-center"><input class="form-check-input" type="checkbox" role="switch" :checked="line.scan">
|
||||
</td>
|
||||
<td>{{ line.product_name }}</td>
|
||||
<td>{{ line.ean }}</td>
|
||||
<td class="text-nowrap">
|
||||
<div class="input-group input-group-sm flex-nowrap">
|
||||
<button type="button" name="ean_winpharma_btn" class="btn btn-primary to_edit" data-bs-toggle="tooltip"
|
||||
data-bs-title="Scanner le code barre à coliser" disabled="" aria-label="Editer"
|
||||
data-bs-original-title="Editer"><i class="fa-solid fa-barcode fa-sm"></i></button>
|
||||
<input class="form-control to_edit" type="text" name="line_1_ean_winpharma" value="" disabled=""
|
||||
required="required"></div>
|
||||
</td>
|
||||
<td><span :class="getStatusInfo(line.status).hasOwnProperty('color') ? 'bg-'+getStatusInfo(line.status).color : 'bg-info'" class="text-nowrap badge label_status_initial">{{ getStatusInfo(line.status).label }}</span>
|
||||
|
||||
<select
|
||||
class="form-select form-select-sm to_edit d-none" name="line_1_new_status" required="required" disabled=""
|
||||
data-type="new_status_select">
|
||||
<option value=""></option>
|
||||
@@ -52,37 +85,120 @@
|
||||
<option value="37">Produit manquant</option>
|
||||
<option value="38">Reliquat</option>
|
||||
</select></td>
|
||||
<td></td>
|
||||
<td class="lh-sm"><small>CIP : 2106369<br>G5E / R23A<br>PARAPHARMACIE</small></td>
|
||||
<td class="text-center">
|
||||
<button type="button" class="btn btn-light btn-sm" title="Historique des statuts"><i
|
||||
class="fa-solid fa-list-check"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
<td></td>
|
||||
<td class="lh-sm"><small>CIP :
|
||||
{{ line.product_ref }}<br>{{ line.localization }}<br>{{ line.product_content_type }}</small></td>
|
||||
<td class="text-center">
|
||||
<button type="button" class="btn btn-light btn-sm" title="Historique des statuts"><i
|
||||
class="fa-solid fa-list-check"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {useShipmentStore} from '@/stores/shipment.js'
|
||||
import {reactive, ref} from "vue";
|
||||
import {nextTick, onMounted, reactive, ref, watch} from "vue";
|
||||
import {storeToRefs} from "pinia";
|
||||
import {Modal} from 'bootstrap'
|
||||
|
||||
const shipmentStatus = [
|
||||
{
|
||||
code: "0",
|
||||
label: 'En attente',
|
||||
allowStatus: [3, 80, 39, 37],
|
||||
color: 'danger'
|
||||
|
||||
},
|
||||
{
|
||||
code: "30",
|
||||
label: 'Colisage',
|
||||
allowStatus: [3, 80, 39, 37]
|
||||
|
||||
},
|
||||
{
|
||||
code: "3",
|
||||
label: 'A livrer',
|
||||
allowStatus: []
|
||||
},
|
||||
{
|
||||
code: "31",
|
||||
label: 'A livrer Dépôt',
|
||||
allowStatus: [3, 80, 39, 37]
|
||||
},
|
||||
{
|
||||
code: "80",
|
||||
label: 'Manquant à rembourser',
|
||||
allowStatus: []
|
||||
},
|
||||
{
|
||||
code: "39",
|
||||
label: 'Produit en commande',
|
||||
allowStatus: [30, 3, 80, 39, 37]
|
||||
},
|
||||
]
|
||||
|
||||
export default {
|
||||
name: "index",
|
||||
setup() {
|
||||
const store = useShipmentStore()
|
||||
const {idOrder, deliveryLines} = storeToRefs(store)
|
||||
const eanScan = ref();
|
||||
|
||||
const locationGroup = ['pharmacy', 'warehouse']
|
||||
|
||||
const productScan = ref(null)
|
||||
|
||||
watch(idOrder, async (to, from) => {
|
||||
if (from === null && to !== null) {
|
||||
await nextTick()
|
||||
productScan.value.focus()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return {
|
||||
store,
|
||||
locationGroup,
|
||||
deliveryLines,
|
||||
productScan,
|
||||
eanScan
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modal: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
searchEanInDeliveries() {
|
||||
|
||||
if (this.eanScan.length === 13) {
|
||||
const findLine = this.deliveryLines.filter(line => line.ean === this.eanScan)
|
||||
if (findLine.length > 0) {
|
||||
findLine[0].scan = true
|
||||
findLine[0].status = "3"
|
||||
findLine[0].labelStatus = "A livrer"
|
||||
this.eanScan = null
|
||||
} else {
|
||||
this.modal.show()
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
getStatusInfo(code) {
|
||||
let labelFinder = shipmentStatus.filter(status => status.code === code)
|
||||
return (labelFinder.length > 0) ? labelFinder[0] : {label: 'unknow'}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.modal = new Modal(this.$refs['modal'], {backdrop: true})
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
10853
src/views/login.vue
10853
src/views/login.vue
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user