feat: chat-rct

feat/issue-23/chat-rct
Frédérik Benoist 2024-02-20 00:13:23 +01:00
parent c4f87d7b14
commit fe0d48703b
5 changed files with 268 additions and 91 deletions

View File

@ -126,6 +126,21 @@
"Note: Click on the button below to access DOTSOFT Back-office": "Note: Click on the button below to access DOTSOFT Back-office",
"Open Back-office": "Open Back-office",
"Mount drive": "Mount drive",
"Chat RCT": "Chat RCT",
"Your RCT Item": "Your RCT Item",
"Store Distributor": "Store Distributor",
"Possible actions to realize": "Possible actions to realize",
"Store where item is required": "Store where item is required",
"Specify an RCT": "Specify an RCT",
"Previous": "Previous",
"Next": "Next",
"Select distributor": "Select distributor",
"Select store": "Select store",
"Yes": "Yes",
"No": "No",
"Resend RCT": "Resend RCT ?",
"Summary": "Summary",
"The request has been processed successfully": "The request has been processed successfully",
"---------------------------": "---------------------------",
"UI Elements": "عناصر واجهة المستخدم",
"Forms & Tables": "النماذج والجداول",

View File

@ -126,6 +126,21 @@
"Note: Click on the button below to access DOTSOFT Back-office": "Note: Click on the button below to access DOTSOFT Back-office",
"Open Back-office": "Open Back-office",
"Mount drive": "Mount drive",
"Chat RCT": "Chat RCT",
"Your RCT Item": "Your RCT Item",
"Store Distributor": "Store Distributor",
"Store where item is required": "Store where item is required",
"Possible actions to realize": "Possible actions to realize",
"Specify an RCT": "Specify an RCT",
"Previous": "Previous",
"Next": "Next",
"Select distributor": "Select distributor",
"Select store": "Select store",
"Yes": "Yes",
"No": "No",
"Resend RCT": "Resend RCT ?",
"Summary": "Summary",
"The request has been processed successfully": "The request has been processed successfully",
"---------------------------": "---------------------------",
"UI Elements": "UI Elements",
"Forms & Tables": "Forms & Tables",

View File

@ -127,6 +127,21 @@
"Note: Click on the button below to access DOTSOFT Back-office": "Note: Cliquez sur le bouton ci-dessous pour accéder au Back-office DOTSOFT",
"Open Back-office": "Ouvrir DOTSOFT",
"Mount drive": "Monter lecteur",
"Chat RCT": "Chat RCT",
"Your RCT Item": "RCT recherchée",
"Store Distributor": "Sélection distributeur",
"Store where item is required": "Sélection Boutique",
"Possible actions to realize": "Actions possibles à effectuer",
"Specify an RCT": "Saisissez la RCT",
"Previous": "Précédent",
"Next": "Suivant",
"Select distributor": "Selectionner un distributeur",
"Select store": "Selectionner une boutique",
"Yes": "Oui",
"No": "Non",
"Resend RCT": "Renvoyer RCT ?",
"Summary": "Résumé",
"The request has been processed successfully": "La demande a été traitée avec succès",
"---------------------------": "---------------------------",
"UI Elements": "ÉLÉMENTS DE L'UI",
"Forms & Tables": "Formulaires et tableaux",

View File

@ -1,13 +1,21 @@
export const useChatRctStore = defineStore('chatrct', {
state: () => ({
rct: 'XY10000-08-3A',
ref_rct: null,
ref_r: null,
id_produit: 0,
distributor: null,
store: 4,
distributor_list: [],
store: null,
store_list: [],
prompt_rct: '### Bonjour,\n Indiquez-moi la RCT sur laquelle vous souhaitez faire des recherches ...',
prompt_distributor: '',
prompt_store: '',
output_actions: '',
loading: false,
actions_lib: [],
actions_flag: false,
actions_proc: 'cache',
resend_data: 'No',
prompt_gen() {
return `${this.prompt_rct}\n${this.prompt_distributor}\n${this.prompt_store}`
},
@ -16,11 +24,16 @@ export const useChatRctStore = defineStore('chatrct', {
async validateRct() {
this.loading = true
const { data } = await useApi<any>(`/chatrct/rct/${this.rct}`)
const { data } = await useApi<any>(`/chatrct/rct?itemId=${this.ref_rct}`)
if (data.value) {
const jsonData = JSON.parse(data.value)
if (jsonData.response.id_produit) {
this.id_produit = jsonData.response.id_produit
this.ref_r = jsonData.response.ref_r
this.distributor_list = jsonData.response.distributor_list
}
else { this.id_produit = 0 }
this.prompt_store = ''
this.prompt_distributor = ''
@ -29,43 +42,103 @@ export const useChatRctStore = defineStore('chatrct', {
this.loading = false
return true // TODO A VERIFIER SI REF N'EXISTE PAS
return (this.id_produit > 0)
},
async validateDistributor() {
this.loading = true
const { data } = await useApi<any>(`/chatrct/distributor/${this.distributor}?itemId=${this.rct}&produitId=${this.id_produit}`)
const { data } = await useApi<any>(`/chatrct/distributor/${this.distributor}?itemId=${this.ref_rct}&produitId=${this.id_produit}`)
if (data.value) {
const jsonData = JSON.parse(data.value)
this.prompt_distributor = jsonData.response.lines.join('\n')
this.store = null
this.store_list = jsonData.response.store_list
}
this.loading = false
return true
},
setRct(rct: string) {
this.rct = rct
async validateStore() {
this.loading = true
const { data } = await useApi<any>(`/chatrct/store/${this.store}?distributorId=${this.distributor}&itemId=${this.ref_rct}&produitId=${this.id_produit}`)
if (data.value) {
const jsonData = JSON.parse(data.value)
this.prompt_store = jsonData.response.lines.join('\n')
this.actions_lib = jsonData.response.actions
this.actions_flag = jsonData.response.actions_flag
this.actions_proc = jsonData.response.actions_proc
}
this.loading = false
return true
},
async validateActions() {
this.loading = true
if (this.actions_proc === 'cache') {
const currentDate = new Date().toISOString().slice(0, 10).replace(/-/g, '')
const requestBodyCache = {
itemId: this.ref_r,
comment: `HDPOS Force Cache ${currentDate}`,
proc: this.actions_proc,
}
const { data } = await useApi<any>('/chatrct/rct/forceCache', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBodyCache),
})
if (data.value)
this.output_actions = data.value.output
}
else if (this.actions_proc === 'exception') {
const tomorrowDate = new Date(Date.now() + 86400000).toISOString().slice(0, 10).replace(/-/g, '')
const requestBodyException = {
id_produit: this.id_produit,
id_distrib: this.distributor,
fdate: tomorrowDate,
forcer_cache: 1,
modul_trait: 'HDPOS',
}
const { data } = await useApi<any>('/chatrct/rct/forceException', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBodyException),
})
if (data.value)
this.output_actions = data.value.output
}
this.loading = false
// Check for "ERREUR" at the beginning of the string
return !this.output_actions.startsWith('ERREUR')
},
clearState() {
this.rct = ''
this.ref_rct = null
this.distributor = null
this.store = null
this.resend_data = 'No'
},
getRct() {
return this.rct
},
getDistrib() {
return this.distributor
},
getStore() {
return this.store
},
ClearPrompts() {
clearPrompts() {
this.prompt_rct = '### Bonjour,\n Indiquez-moi la RCT sur laquelle vous souhaitez faire des recherches ...'
this.prompt_distributor = ''
this.prompt_store = ''
this.output_actions = ''
},
},
})

View File

@ -2,33 +2,24 @@
import { VForm } from 'vuetify/components/VForm'
import { useChatRctStore } from '@stores/chatrct.store'
const { t } = useI18n()
const numberedSteps = [
{
title: 'Item',
subtitle: 'Your RCT Item',
title: t('Item'),
subtitle: t('Your RCT Item'),
},
{
title: 'Distributor',
subtitle: 'Store Distributor',
title: t('Distributor'),
subtitle: t('Store Distributor'),
},
{
title: 'Store',
subtitle: 'Store where item is sold',
title: t('Store'),
subtitle: t('Store where item is required'),
},
{
title: 'Actions',
subtitle: 'Possible actions to realize',
},
]
const distributors = [
{
name: 'IKKS',
id: 1,
},
{
name: 'XO',
id: 6,
title: t('Actions'),
subtitle: t('Possible actions to realize'),
},
]
@ -40,8 +31,13 @@ const refDistributorForm = ref<VForm>()
const refStoreForm = ref<VForm>()
const refActionsForm = ref<VForm>()
const isSnackbarActions = ref(false)
const store = useChatRctStore()
store.clearState()
store.clearPrompts()
const validateRctForm = async () => {
const validRctForm = await refRctForm.value?.validate()
if (validRctForm && validRctForm.valid) {
@ -51,9 +47,7 @@ const validateRctForm = async () => {
currentStep.value++
isCurrentStepValid.value = true
}
else {
isCurrentStepValid.value = false
}
else { isCurrentStepValid.value = false }
}
}
@ -66,41 +60,57 @@ const validateDistributorForm = async () => {
currentStep.value++
isCurrentStepValid.value = true
}
else {
isCurrentStepValid.value = false
}
else { isCurrentStepValid.value = false }
}
}
const validateStoreForm = () => {
refStoreForm.value?.validate().then(valid => {
if (valid) {
const validateStoreForm = async () => {
const validStoreForm = await refStoreForm.value?.validate()
if (validStoreForm && validStoreForm.valid) {
if (store.store_list && Array.isArray(store.store_list) && store.store_list.length > 0) {
const valid = store.store_list.some((s: { id: any }) => s.id === store.store)
const validStore = await store.validateStore()
if (valid && validStore) {
currentStep.value++
isCurrentStepValid.value = true
}
else {
isCurrentStepValid.value = false
else { isCurrentStepValid.value = false }
}
else { isCurrentStepValid.value = false }
}
})
}
const validateActionsForm = () => {
isCurrentStepValid.value = true
const validateActionsForm = async () => {
const validActionsForm = await refActionsForm.value?.validate()
if (validActionsForm && validActionsForm.valid) {
if (store.resend_data === 'Yes') {
const valid = await store.validateActions()
// refActionsForm.value?.validate().then(valid => {
// if (valid.valid)
// isCurrentStepValid.value = true
// else isCurrentStepValid.value = false
// })
if (valid) {
currentStep.value++
isCurrentStepValid.value = true
isSnackbarActions.value = true
}
else { isCurrentStepValid.value = false }
}
else { isCurrentStepValid.value = false }
}
}
const decrementStep = () => {
currentStep.value--
if (currentStep.value === 0)
store.ClearPrompts()
else if (currentStep.value === 1)
if (currentStep.value === 0) {
store.clearPrompts()
}
else if (currentStep.value === 1) {
store.prompt_distributor = ''
}
else if (currentStep.value === 2) {
store.prompt_store = ''
store.output_actions = ''
}
}
</script>
@ -132,10 +142,10 @@ const decrementStep = () => {
<VRow>
<VCol cols="12">
<h6 class="text-h6 font-weight-medium">
Item
{{ $t('Item') }}
</h6>
<p class="mb-0">
Your RCT Item
{{ $t('Your RCT Item') }}
</p>
</VCol>
@ -144,8 +154,8 @@ const decrementStep = () => {
md="6"
>
<AppTextField
v-model="store.rct"
placeholder="BX10100"
v-model="store.ref_rct"
:placeholder="$t('Specify an RCT')"
:rules="[requiredValidator]"
label="RCT"
/>
@ -163,11 +173,11 @@ const decrementStep = () => {
start
class="flip-in-rtl"
/>
Previous
{{ $t('Previous') }}
</VBtn>
<VBtn type="submit">
Next
{{ $t('Next') }}
<VIcon
icon="tabler-arrow-right"
end
@ -189,10 +199,10 @@ const decrementStep = () => {
<VRow>
<VCol cols="12">
<h6 class="text-h6 font-weight-medium">
Distributor
{{ $t('Distributor') }}
</h6>
<p class="mb-0">
Distributor where item are sold
{{ $t('Store Distributor') }}
</p>
</VCol>
@ -202,12 +212,13 @@ const decrementStep = () => {
>
<AppSelect
v-model="store.distributor"
:items="distributors"
placeholder="Select Distributor"
:items="store.distributor_list"
:placeholder="$t('Select distributor')"
:rules="[requiredValidator]"
item-title="name"
item-value="id"
label="Distributor"
:label="$t('Distributor')"
:return-object="false"
/>
</VCol>
<VCol cols="12">
@ -222,11 +233,11 @@ const decrementStep = () => {
start
class="flip-in-rtl"
/>
Previous
{{ $t('Previous') }}
</VBtn>
<VBtn type="submit">
Next
{{ $t('Next') }}
<VIcon
icon="tabler-arrow-right"
end
@ -248,10 +259,10 @@ const decrementStep = () => {
<VRow>
<VCol cols="12">
<h6 class="text-h6 font-weight-medium">
Store search
{{ $t('Store') }}
</h6>
<p class="mb-0">
Possible store to search data on ...
{{ $t('Store where item is required') }}
</p>
</VCol>
@ -259,11 +270,15 @@ const decrementStep = () => {
cols="12"
md="6"
>
<AppTextField
<AppCombobox
v-model="store.store"
placeholder="Store ID"
:items="store.store_list"
:placeholder="$t('Select store')"
:rules="[requiredValidator]"
label="Store ID"
item-title="name"
item-value="id"
:label="$t('Store')"
:return-object="false"
/>
</VCol>
@ -279,11 +294,11 @@ const decrementStep = () => {
start
class="flip-in-rtl"
/>
Previous
{{ $t('Previous') }}
</VBtn>
<VBtn type="submit">
Next
{{ $t('Next') }}
<VIcon
icon="tabler-arrow-right"
end
@ -304,15 +319,42 @@ const decrementStep = () => {
>
<VRow>
<VCol cols="12">
<h6 class="text-h6 font-weight-medium">
List of Actions
</h6>
<p
v-for="(action, index) in store.actions_lib"
:key="index"
class="mb-0"
>
{{ action }}
</p>
</VCol>
<VCol
v-if="store.actions_flag"
cols="12"
md="6"
sm="8"
>
<VRadioGroup
v-model="store.resend_data"
class="mb-3"
>
<template #label>
<div class="text-high-emphasis">
{{ $t('Resend RCT') }}
</div>
</template>
<VRadio
value="Yes"
:label="$t('Yes')"
class="ms-2"
/>
<VRadio
value="No"
:label="$t('No')"
class="ms-2"
/>
</VRadioGroup>
{{ store.output_actions }}
</VCol>
<VCol cols="12">
<div class="d-flex flex-wrap gap-4 justify-sm-space-between justify-center mt-8">
@ -326,19 +368,36 @@ const decrementStep = () => {
start
class="flip-in-rtl"
/>
Previous
{{ $t('Previous') }}
</VBtn>
<VBtn
v-if="store.actions_flag"
color="success"
type="submit"
>
submit
{{ $t('Submit') }}
</VBtn>
</div>
</VCol>
</VRow>
</VForm>
<!-- Snackbar Export -->
<VSnackbar
v-model="isSnackbarActions"
location="center"
>
{{ $t('The request has been processed successfully') }}
<template #actions>
<VBtn
color="error"
@click="isSnackbarActions = false"
>
{{ $t("Close") }}
</VBtn>
</template>
</VSnackbar>
</VWindowItem>
</VWindow>
</VCardText>