PR-CUSTOMER #186

Merged
jsegarra merged 105 commits from :PR-CUSTOMER into dev 2024-04-19 15:55:53 +00:00
14 changed files with 1017 additions and 37 deletions
Showing only changes of commit 01ffe3adb7 - Show all commits

View File

@ -109,14 +109,18 @@ function tMobile(...args) {
}
async function fetch() {
const { data } = await axios.get($props.url, {
params: { filter: JSON.stringify($props.filter) },
});
try {
const { data } = await axios.get($props.url, {
params: { filter: JSON.stringify($props.filter) },
});
state.set($props.model, data);
originalData.value = data && JSON.parse(JSON.stringify(data));
state.set($props.model, data);
originalData.value = data && JSON.parse(JSON.stringify(data));
emit('onFetch', state.get($props.model));
emit('onFetch', state.get($props.model));
} catch (error) {
state.set($props.model, {});
originalData.value = {};
}
}
async function save() {

View File

@ -37,7 +37,7 @@ const params = {
};
const filter = {
include: { relation: 'company', scope: { fields: ['code'] } },
where: { clientFk: `${route.params.id}`, companyFk: user.value.companyFk },
where: { clientFk: route.params.id, companyFk: user.value.companyFk },
};
const tableColumnComponents = {

View File

@ -23,7 +23,7 @@ const filter = {
},
},
],
where: { clientFk: `${route.params.id}` },
where: { clientFk: route.params.id },
order: ['created DESC'],
limit: 20,
};

View File

@ -1,5 +1,5 @@
<script setup>
import { ref, computed } from 'vue';
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
@ -27,7 +27,7 @@ const filter = {
},
},
],
where: { clientFk: `${route.params.id}` },
where: { clientFk: route.params.id },
order: ['created DESC'],
limit: 20,
};
@ -93,6 +93,7 @@ const toCustomerCreditCreate = () => {
:rows="rows"
class="full-width q-mt-md"
row-key="id"
v-if="rows?.length"
>
<template #body-cell="props">
<QTd :props="props">
@ -110,6 +111,10 @@ const toCustomerCreditCreate = () => {
</QTd>
</template>
</QTable>
<h5 class="flex justify-center label-color" v-else>
{{ t('globals.noResults') }}
</h5>
</QPage>
<QPageSticky :offset="[18, 18]">
@ -120,6 +125,12 @@ const toCustomerCreditCreate = () => {
</QPageSticky>
</template>
<style lang="scss">
.label-color {
color: var(--vn-label);
}
</style>
<i18n>
es:
Since: Desde

View File

@ -1,3 +1,268 @@
<script setup>
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import { date, QBadge, QBtn, QCheckbox } from 'quasar';
import { downloadFile } from 'src/composables/downloadFile';
import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import CustomerFileManagementActions from 'src/pages/Customer/components/CustomerFileManagementActions.vue';
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const ClientDmsRef = ref(null);
const rows = ref([]);
const workerId = ref(null);
const filter = {
include: {
relation: 'dms',
scope: {
fields: [
'dmsTypeFk',
'reference',
'hardCopyNumber',
'workerFk',
'description',
'hasFile',
'file',
'created',
],
include: [
{ relation: 'dmsType', scope: { fields: ['name'] } },
{
relation: 'worker',
scope: {
fields: ['id'],
include: { relation: 'user', scope: { fields: ['name'] } },
},
},
],
},
},
where: { clientFk: route.params.id },
order: ['dmsFk DESC'],
limit: 20,
};
const tableColumnComponents = {
id: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
type: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
order: {
component: QBadge,
props: () => {},
event: () => (workerId.value = null),
},
reference: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
description: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
original: {
component: QCheckbox,
props: (prop) => ({
disable: true,
'model-value': Boolean(prop.value),
}),
event: () => (workerId.value = null),
},
file: {
component: QBtn,
props: () => ({ flat: true, color: 'blue' }),
event: ({ row }) => {
setDownloadFile(row);
},
},
employee: {
component: QBtn,
props: () => ({ flat: true, color: 'blue' }),
event: ({ row }) => (workerId.value = row.clientFk),
},
created: {
component: 'span',
props: () => {},
event: () => (workerId.value = null),
},
actions: {
component: CustomerFileManagementActions,
props: (prop) => ({
id: prop.row.dmsFk,
promise: setData,
}),
event: () => (workerId.value = null),
},
};
const columns = computed(() => [
{
align: 'left',
field: ({ dms }) => dms.id,
label: t('Id'),
name: 'id',
},
{
align: 'left',
field: ({ dms }) => dms.dmsType.name,
label: t('Type'),
name: 'type',
},
{
align: 'left',
field: ({ dms }) => dms.hardCopyNumber,
label: t('Order'),
name: 'order',
},
{
align: 'left',
field: ({ dms }) => dms.reference,
label: t('Reference'),
name: 'reference',
},
{
align: 'left',
field: ({ dms }) => dms.description,
label: t('Description'),
name: 'description',
},
{
align: 'left',
field: ({ dms }) => dms.hasFile,
label: t('Original'),
name: 'original',
},
{
align: 'left',
field: ({ dms }) => dms.file,
label: t('File'),
name: 'file',
},
{
align: 'left',
field: ({ dms }) => dms.worker.user.name,
label: t('Employee'),
name: 'employee',
},
{
align: 'left',
field: (value) => value.dms.created,
label: t('Created'),
name: 'created',
jsegarra marked this conversation as resolved Outdated

Duda, cuando actualicemos con dev no tendremos conflicto?

Duda, cuando actualicemos con dev no tendremos conflicto?

Se reemplazo toDateHourMinSec por las nuevas utils ubicadas en date.js

Commit: 3cb045936b

Se reemplazo `toDateHourMinSec` por las nuevas utils ubicadas en `date.js` Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/3cb045936b2d17001fedd87219c904162d29fba4
format: (value) => date.formatDate(value, 'DD/MM/YYYY hh:mm'),
},
{
align: 'right',
field: 'actions',
label: '',
name: 'actions',
},
]);
const setDownloadFile = (row) => {
downloadFile(row.dmsFk);
workerId.value = null;
};
const setData = () => {
ClientDmsRef.value.fetch();
};
const toCustomerFileManagementCreate = () => {
router.push({ name: 'CustomerFileManagementCreate' });
};
</script>
<template>
<div class="flex justify-center">Customer file management</div>
<FetchData
ref="ClientDmsRef"
:filter="filter"
@on-fetch="(data) => (rows = data)"
auto-load
url="ClientDms"
/>
<QPage class="column items-center q-pa-md">
<QTable
:columns="columns"
:pagination="{ rowsPerPage: 12 }"
:rows="rows"
class="full-width q-mt-md"
row-key="id"
v-if="rows?.length"
>
<template #body-cell="props">
<QTd :props="props">
<QTr :props="props" class="cursor-pointer">
<component
:is="
props.col.name === 'order' && !props.value
? 'span'
: tableColumnComponents[props.col.name].component
"
@click="tableColumnComponents[props.col.name].event(props)"
class="col-content"
v-bind="tableColumnComponents[props.col.name].props(props)"
>
<template v-if="props.col.name !== 'original'">
{{ props.value }}
</template>
<WorkerDescriptorProxy :id="workerId" />
</component>
</QTr>
</QTd>
</template>
</QTable>
<h5 class="flex justify-center label-color" v-else>
{{ t('globals.noResults') }}
jsegarra marked this conversation as resolved
Review

El icono de fichero es diferente a otras partes de la aplicación. Unificar criterios. Puesto que este es el último módulo que quiere integrarse, lo reemplazaría por los que ya están.

El icono de fichero es diferente a otras partes de la aplicación. Unificar criterios. Puesto que este es el último módulo que quiere integrarse, lo reemplazaría por los que ya están.
Review

Corregido: 3cf3687b84

Corregido: 3cf3687b84
</h5>
</QPage>
<QPageSticky :offset="[18, 18]">
<QBtn
@click.stop="toCustomerFileManagementCreate()"
color="primary"
fab
icon="add"
/>
<QTooltip>
{{ t('Upload file') }}
</QTooltip>
</QPageSticky>
</template>
<style lang="scss">
.label-color {
color: var(--vn-label);
}
</style>
<i18n>
es:
Id: Id
Type: Tipo
Order: Orden
Reference: Referencia
Description: Descripción
Original: Original
File: Fichero
Employee: Empleado
Created: Fecha creación
Upload file: Subir fichero
</i18n>

View File

@ -15,7 +15,7 @@ const router = useRouter();
const rows = ref([]);
const filter = {
where: { clientFk: `${route.params.id}` },
where: { clientFk: route.params.id },
order: ['started DESC'],
limit: 20,
};

View File

@ -71,7 +71,7 @@ const columns = computed(() => [
},
{
align: 'left',
field: (value) => value.company.code,
field: (value) => value.company?.code,
label: t('Company'),
name: 'company',
},

View File

@ -1,3 +1,57 @@
<script setup>
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import FormModel from 'components/FormModel.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const route = useRoute();
const unpaidClient = ref(false);
const initialData = reactive({
dated: '2001-01-01T11:00:00.000Z',
clientFk: 1,
});
jsegarra marked this conversation as resolved Outdated

TODO, revisar si hay otra opción

TODO, revisar si hay otra opción

Modificado

Commit: 998561badd

Modificado Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/998561badd40ba7f32a0265c9865a44dae284586
const onFetch = () => {
unpaidClient.value = true;
};
</script>
<template>
<div class="flex justify-center">Customer unpaid</div>
<FormModel
:form-initial-data="initialData"
:observe-form-changes="true"
:url="`ClientUnpaids/${route.params.id}`"
@on-fetch="onFetch"
url-create="ClientUnpaids"
auto-load
>
<template #form="{ data }">
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<QCheckbox :label="t('Unpaid client')" v-model="unpaidClient" />
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md" v-if="unpaidClient">
<div class="col">
<VnInputDate :label="t('Date')" v-model="data.dated" />

salix pone una fecha por defecto, emular comportamiento

salix pone una fecha por defecto, emular comportamiento

Corregido: 90ee50eab5

Corregido: 90ee50eab5

Lo veo OK

Lo veo OK
</div>
<div class="col">
<VnInput :label="t('Amount')" type="number" v-model="data.amount" />
</div>
</VnRow>
</template>
</FormModel>
</template>
jsegarra marked this conversation as resolved Outdated

Porque haces un find por id, si ya lo has hecho en la query/filter? Te devoilverá el resultado
Si filtras por 1101, te llegará [1101]

Porque haces un find por id, si ya lo has hecho en la query/filter? Te devoilverá el resultado Si filtras por 1101, te llegará [1101]

Corregido: 93015d9f98

Corregido: 93015d9f98
<i18n>
jsegarra marked this conversation as resolved Outdated

Mi propuesta es si data.length>0

Mi propuesta es si data.length>0

Corregido: 93015d9f98

Corregido: 93015d9f98
es:
Unpaid client: Cliente impagado
Date: Fecha
Amount: Importe
</i18n>

View File

@ -3,7 +3,7 @@ import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import { useQuasar } from 'quasar';
import { useDialogPluginComponent, useQuasar } from 'quasar';
import VnRow from 'components/ui/VnRow.vue';
@ -18,6 +18,7 @@ const $props = defineProps({
},
});
const { dialogRef } = useDialogPluginComponent();
const { t } = useI18n();
const quasar = useQuasar();

View File

@ -0,0 +1,96 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import { useQuasar } from 'quasar';
import { downloadFile } from 'src/composables/downloadFile';
import CustomerFileManagementDelete from 'src/pages/Customer/components/CustomerFileManagementDelete.vue';
const { t } = useI18n();
const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const $props = defineProps({
id: {
type: Number,
required: true,
},
promise: {
type: Function,
required: true,
},
});
const setDownloadFile = () => downloadFile($props.id);
const toCustomerFileManagementEdit = () => {
router.push({
name: 'CustomerFileManagementEdit',
params: {
id: route.params.id,
dmsId: $props.id,
},
});
};
const showCustomerFileManagementDeleteDialog = () => {
quasar.dialog({
component: CustomerFileManagementDelete,
componentProps: {
id: $props.id,
promise: setData,
},
});
};
const setData = () => {
$props.promise();
};
</script>
<template>
<div>
<QIcon
@click.stop="setDownloadFile"
color="primary"
name="cloud_download"
size="sm"
>
<QTooltip>
{{ t('Download file') }}
</QTooltip>
</QIcon>
<QIcon
@click.stop="toCustomerFileManagementEdit"
class="q-ml-md"
color="primary"
name="edit"
size="sm"
>
<QTooltip>
{{ t('Edit file') }}
</QTooltip>
</QIcon>
<QIcon
@click.stop="showCustomerFileManagementDeleteDialog"
class="q-ml-md"
color="primary"
name="delete"
size="sm"
>
<QTooltip>
{{ t('Remove file') }}
</QTooltip>
</QIcon>
</div>
</template>
<i18n>
es:
jsegarra marked this conversation as resolved Outdated

TIP: quizás usando traducciones con argumentos nos podemos ahorrar 2 líneas

TIP: quizás usando traducciones con argumentos nos podemos ahorrar 2 líneas

Corregido: 1e9b3f8f0e

Corregido: 1e9b3f8f0e
Download file: Descargar fichero
Edit file: Editar fichero
Remove file: Eliminar fichero
</i18n>

View File

@ -0,0 +1,247 @@
<script setup>
import { onBeforeMount, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { useQuasar } from 'quasar';
import { useState } from 'src/composables/useState';
import FetchData from 'components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const state = useState();
const user = state.getUser();
const filterFindOne = { where: { code: 'paymentsLaw' } };
const filterCompanies = { order: ['code'] };
const filterWarehouses = { order: ['name'] };
const client = ref({});
const findOne = ref([]);
const allowedContentTypes = ref([]);
const optionsCompanies = ref([]);
const optionsWarehouses = ref([]);
const optionsDmsTypes = ref([]);
const isLoading = ref(false);
const dms = ref({
hasFile: false,
});
onBeforeMount(() => {
const { companyFk, warehouseFk } = user.value;
dms.value.reference = route.params.id;
dms.value.companyId = companyFk;
dms.value.warehouseId = warehouseFk;
});
watch([client, findOne], ([newClient, newFindOne]) => {
dms.value.description = t('clientFileDescription', {
dmsTypeName: newFindOne.name?.toUpperCase(),
clientName: newClient.name?.toUpperCase(),
clientId: newClient.id,
});
dms.value.dmsTypeId = newFindOne.id;
});
const saveData = async () => {
try {
const formData = new FormData();
if (dms.value.files) {
for (let i = 0; i < dms.value.files.length; i++)
formData.append(dms.value.files[i].name, dms.value.files[i]);
dms.value.hasFileAttached = true;
}
jsegarra marked this conversation as resolved Outdated

Comentario, no es nuestro estilo, hay otras instrucciones para hacer lo mismo pero con menos código.

Comentario, no es nuestro estilo, hay otras instrucciones para hacer lo mismo pero con menos código.

Aunque no es su estilo, la repetición de código en varios archivos me intrigó. Viendo espacio para mejora, investigué su origen y hallé varias instancias. Curioso para ser 'no característico' de su enfoque, ¿no?

Corregido: 38d3d49ecb

Aunque no es su estilo, la repetición de código en varios archivos me intrigó. Viendo espacio para mejora, investigué su origen y hallé varias instancias. Curioso para ser 'no característico' de su enfoque, ¿no? Corregido: 38d3d49ecb

Fantástico Carlos, tomaré tu commit como ejemplo para nuevos casos y cuando surja la oportunidad cambiar las otras ocurrencias!

Fantástico Carlos, tomaré tu commit como ejemplo para nuevos casos y cuando surja la oportunidad cambiar las otras ocurrencias!
const url = `clients/${route.params.id}/uploadFile`;
await axios.post(url, formData, {
params: dms.value,
});
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
router.push({ name: 'CustomerFileManagement' });
} catch (error) {
quasar.notify({
message: t(`${error.message}`),
type: 'negative',
});
}
};
const inputFileRef = ref();
</script>
<template>
<fetch-data
@on-fetch="(data) => (client = data)"
auto-load
:url="`Clients/${route.params.id}/getCard`"
/>
<fetch-data
:filter="filterFindOne"
@on-fetch="(data) => (findOne = data)"
auto-load
url="DmsTypes/findOne"
/>
<fetch-data
@on-fetch="(data) => (allowedContentTypes = data)"
auto-load
url="DmsContainers/allowedContentTypes"
/>
<fetch-data
:filter="filterCompanies"
@on-fetch="(data) => (optionsCompanies = data)"
auto-load
url="Companies"
/>
<fetch-data
:filter="filterWarehouses"
@on-fetch="(data) => (optionsWarehouses = data)"
auto-load
url="Warehouses"
/>
<fetch-data
:filter="filterWarehouses"
@on-fetch="(data) => (optionsDmsTypes = data)"
auto-load
url="DmsTypes"
/>
<QForm>
<QCard class="q-pa-lg">
<QCardSection>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput :label="t('Reference')" v-model="dms.reference" />
</div>
<div class="col">
<VnSelectFilter
:label="t('Company')"
:options="optionsCompanies"
option-label="code"
option-value="id"
v-model="dms.companyId"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnSelectFilter
:label="t('Warehouse')"
:options="optionsWarehouses"
option-label="name"
option-value="id"
v-model="dms.warehouseId"
/>
</div>
<div class="col">
<VnSelectFilter
:label="t('Type')"
:options="optionsDmsTypes"
option-label="name"
option-value="id"
v-model="dms.dmsTypeId"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput
:label="t('Description')"
type="textarea"
v-model="dms.description"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<QFile
ref="inputFileRef"
class="required"
:label="t('File')"
v-model="dms.files"
multiple
:accept="allowedContentTypes.join(',')"
clearable
clear-icon="close"
>
<template #append>
<QBtn
icon="attach_file_add"
flat
round
padding="xs"
@click="inputFileRef.pickFiles()"
>
<QTooltip>
{{ t('Select a file') }}
</QTooltip>
</QBtn>
<QBtn icon="info" flat round padding="xs">
<QTooltip max-width="30rem">
{{
`${t(
'Allowed content types'
)}: ${allowedContentTypes.join(', ')}`
}}
</QTooltip>
</QBtn>
</template>
</QFile>
</div>
</VnRow>
<QCheckbox
:label="t('Generate identifier for original file')"
v-model="dms.hasFile"
/>
</QCardSection>
<QCardActions class="flex justify-end">
<QBtn
:disabled="isLoading"
:label="t('globals.cancel')"
:loading="isLoading"
class="q-mr-xl"
color="primary"
flat
/>
<QBtn
:disabled="isLoading"
:label="t('globals.save')"
:loading="isLoading"
color="primary"
@click.stop="saveData"
/>
</QCardActions>
</QCard>
</QForm>
</template>
<i18n>
en:
clientFileDescription: '{dmsTypeName} FROM CLIENT {clientName} ID {clientId}'
es:
Reference: Referencia
Company: Empresa
Warehouse: Almacén
Type: Tipo
Description: Descripción
clientFileDescription: '{dmsTypeName} DEL CLIENTE {clientName} ID {clientId}'
File: Fichero
Select a file: Selecciona un fichero
Allowed content types: Tipos de archivo permitidos
Generate identifier for original file: Generar identificador para archivo original
</i18n>

View File

@ -0,0 +1,81 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useDialogPluginComponent, useQuasar } from 'quasar';
import axios from 'axios';
const $props = defineProps({
id: {
type: Number,
required: true,
},
promise: {
type: Function,
required: true,
},
});
const { dialogRef } = useDialogPluginComponent();
const { t } = useI18n();
const quasar = useQuasar();
const closeButton = ref(null);
const isLoading = ref(false);
const deleteDms = async () => {
isLoading.value = true;
try {
await axios.post(`ClientDms/${$props.id}/removeFile`);
if ($props.promise) await $props.promise();
} catch (error) {
quasar.notify({
message: t(`${error.message}`),
type: 'negative',
});
} finally {
closeButton.value.click();
isLoading.value = false;
}
};
</script>
<template>
<QDialog ref="dialogRef">
<QCard class="q-pa-md q-mb-md">
<span ref="closeButton" class="row justify-end close-icon" v-close-popup>
<QIcon name="close" size="sm" />
</span>
<QCardSection>
<div class="mt-1 text-h6">{{ t('This file will be deleted') }}</div>
<div>{{ t('Are you sure you want to continue?') }}</div>
</QCardSection>
<QCardActions class="flex justify-end">
<QBtn
:disabled="isLoading"
:label="t('globals.cancel')"
:loading="isLoading"
class="q-mr-xl"
color="primary"
flat
v-close-popup
/>
<QBtn
:disabled="isLoading"
:label="t('globals.save')"
:loading="isLoading"
@click.stop="deleteDms"
color="primary"
/>
</QCardActions>
</QCard>
</QDialog>
</template>
<i18n>
es:
This file will be deleted: Este fichero va a ser borrado
Are you sure you want to continue?: ¿Seguro que quieres continuar?
</i18n>

View File

@ -0,0 +1,225 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { useQuasar } from 'quasar';
import FetchData from 'components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
const { t } = useI18n();
const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const filterCompanies = { order: ['code'] };
const filterWarehouses = { order: ['name'] };
const allowedContentTypes = ref([]);
const optionsCompanies = ref([]);
const optionsWarehouses = ref([]);
const optionsDmsTypes = ref([]);
const isLoading = ref(false);
const dms = ref({
hasFile: true,
});
const setCurrentDms = (data) => {
dms.value.reference = data.reference;
dms.value.companyId = data.companyFk;
dms.value.warehouseId = data.warehouseFk;
dms.value.dmsTypeId = data.dmsTypeFk;
dms.value.description = data.description;
};
const saveData = async () => {
try {
const formData = new FormData();
if (dms.value.files) {
for (let i = 0; i < dms.value.files.length; i++)
formData.append(dms.value.files[i].name, dms.value.files[i]);
dms.value.hasFileAttached = true;
}
const url = `dms/${route.params.dmsId}/updateFile`;
await axios.post(url, formData, {
params: dms.value,
});
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
router.push({ name: 'CustomerFileManagement' });
} catch (error) {
quasar.notify({
message: t(`${error.message}`),
type: 'negative',
});
}
};
const inputFileRef = ref();
</script>
<template>
<fetch-data :url="`Dms/${route.params.dmsId}`" @on-fetch="setCurrentDms" auto-load />
<fetch-data
@on-fetch="(data) => (allowedContentTypes = data)"
auto-load
url="DmsContainers/allowedContentTypes"
/>
<fetch-data
:filter="filterCompanies"
@on-fetch="(data) => (optionsCompanies = data)"
auto-load
url="Companies"
/>
<fetch-data
:filter="filterWarehouses"
@on-fetch="(data) => (optionsWarehouses = data)"
auto-load
url="Warehouses"
/>
<fetch-data
:filter="filterWarehouses"
@on-fetch="(data) => (optionsDmsTypes = data)"
auto-load
url="DmsTypes"
/>
<QForm>
<QCard class="q-pa-lg">
<QCardSection>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput :label="t('Reference')" v-model="dms.reference" />
</div>
<div class="col">
<VnSelectFilter
:label="t('Company')"
:options="optionsCompanies"
option-label="code"
option-value="id"
v-model="dms.companyId"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnSelectFilter
:label="t('Warehouse')"
:options="optionsWarehouses"
option-label="name"
option-value="id"
v-model="dms.warehouseId"
/>
</div>
<div class="col">
<VnSelectFilter
:label="t('Type')"
:options="optionsDmsTypes"
option-label="name"
option-value="id"
v-model="dms.dmsTypeId"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<VnInput
:label="t('Description')"
type="textarea"
v-model="dms.description"
/>
</div>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md">
<div class="col">
<QFile
ref="inputFileRef"
class="required"
:label="t('File')"
v-model="dms.files"
multiple
:accept="allowedContentTypes.join(',')"
clearable
clear-icon="close"
>
<template #append>
<QBtn
icon="attach_file_add"
flat
round
padding="xs"
@click="inputFileRef.pickFiles()"
>
<QTooltip>
{{ t('Select a file') }}
</QTooltip>
</QBtn>
<QBtn icon="info" flat round padding="xs">
<QTooltip max-width="30rem">
{{
`${t(
'Allowed content types'
)}: ${allowedContentTypes.join(', ')}`
}}
</QTooltip>
</QBtn>
</template>
</QFile>
</div>
</VnRow>
<QCheckbox
:label="t('Generate identifier for original file')"
v-model="dms.hasFile"
disable
/>
</QCardSection>
<QCardActions class="flex justify-end">
<QBtn
:disabled="isLoading"
:label="t('globals.cancel')"
:loading="isLoading"
class="q-mr-xl"
color="primary"
flat
/>
<QBtn
:disabled="isLoading"
:label="t('globals.save')"
:loading="isLoading"
color="primary"
@click.stop="saveData"
/>
</QCardActions>
</QCard>
</QForm>
</template>
<i18n>
en:
clientFileDescription: '{dmsTypeName} FROM CLIENT {clientName} ID {clientId}'
es:
Reference: Referencia
Company: Empresa
Warehouse: Almacén
Type: Tipo
Description: Descripción
clientFileDescription: '{dmsTypeName} DEL CLIENTE {clientName} ID {clientId}'
File: Fichero
Select a file: Selecciona un fichero
Allowed content types: Tipos de archivo permitidos
Generate identifier for original file: Generar identificador para archivo original
</i18n>

View File

@ -356,12 +356,12 @@ export default {
{
name: 'CustomerCreditContracts',
title: 'creditContracts',
icon: 'paid',
icon: 'vn:solunion',
},
{
name: 'CustomerCreditOpinion',
title: 'creditOpinion',
icon: 'paid',
icon: 'vn:linesprepaired',
},
],
},
@ -371,7 +371,6 @@ export default {
name: 'CustomerCreditContracts',
meta: {
title: 'creditContracts',
icon: 'paid',
},
component: () =>
import(
@ -388,7 +387,6 @@ export default {
name: 'CustomerCreditContracts',
meta: {
title: 'creditContracts',
icon: 'paid',
},
component: () =>
import(
@ -418,7 +416,6 @@ export default {
name: 'CustomerCreditOpinion',
meta: {
title: 'creditOpinion',
icon: 'paid',
},
component: () =>
import(
@ -437,37 +434,37 @@ export default {
{
name: 'CustomerSamples',
title: 'samples',
icon: 'pending',
icon: 'vn:notes',
},
{
name: 'CustomerConsumption',
title: 'consumption',
icon: 'pending',
icon: 'vn:lines',

salix tiene otro icono

salix tiene otro icono

Corregido: 3bcd4984f5

Corregido: 3bcd4984f5

Yo lo veo OK

Yo lo veo OK
},
{
name: 'CustomerMandates',
title: 'mandates',
icon: 'pending',
icon: 'vn:mandatory',
},
{
name: 'CustomerContacts',
title: 'contacts',
icon: 'pending',
icon: 'contact_phone',
},
{
name: 'CustomerWebPayment',
title: 'webPayment',
icon: 'pending',
icon: 'vn:onlinepayment',
},
{
name: 'CustomerFileManagement',
title: 'fileManagement',
icon: 'pending',
icon: 'Upload',
},
{
name: 'CustomerUnpaid',
title: 'unpaid',
icon: 'pending',
icon: 'vn:supplierfalse',

salix tiene otro icono

salix tiene otro icono

Corregido: 9ae0874ccf

Corregido: 9ae0874ccf

Lo veo OK

Lo veo OK
},
],
},
@ -477,7 +474,6 @@ export default {
name: 'CustomerSamples',
meta: {
title: 'samples',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerSamples.vue'),
@ -492,7 +488,6 @@ export default {
name: 'CustomerSamples',
meta: {
title: 'samples',
icon: 'paid',
},
component: () =>
import(
@ -514,7 +509,6 @@ export default {
name: 'CustomerConsumption',
meta: {
title: 'consumption',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerConsumption.vue'),
@ -524,7 +518,6 @@ export default {
name: 'CustomerMandates',
meta: {
title: 'mandates',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerMandates.vue'),
@ -534,7 +527,6 @@ export default {
name: 'CustomerContacts',
meta: {
title: 'contacts',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerContacts.vue'),
@ -544,7 +536,6 @@ export default {
name: 'CustomerWebPayment',
meta: {
title: 'webPayment',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerWebPayment.vue'),
Review

si estoy en el cliente 1110 que no tiene pagos web, y en el buscador superior me muevo al 1101 que sí los tiene en salix me aparecen en lilium tengo que hacer f5 para que acceda a la información, no pasa en esta seccion solamente, tal vez alguien de vuestro o nuestro equipo esto ya lo haya solucionado en algun otro formulario..preguntar a ver.

si estoy en el cliente 1110 que no tiene pagos web, y en el buscador superior me muevo al 1101 que sí los tiene en salix me aparecen en lilium tengo que hacer f5 para que acceda a la información, no pasa en esta seccion solamente, tal vez alguien de vuestro o nuestro equipo esto ya lo haya solucionado en algun otro formulario..preguntar a ver.
Review

Corregido: b12968f982

Corregido: b12968f982
Review

@jgallego Tenemos un comportamiento similar en el resto de la aplicación.
Ya tenemos un redmine abierto
La solución de Carlos es similar a la que se ha aplicado en el redmine

@jgallego Tenemos un comportamiento similar en el resto de la aplicación. Ya tenemos un redmine abierto https://gitea.verdnatura.es/verdnatura/salix-front/pulls/186#issuecomment-43382 La solución de Carlos es similar a la que se ha aplicado en el redmine
@ -554,7 +545,6 @@ export default {
name: 'CustomerFileManagement',
meta: {
title: 'fileManagement',
icon: 'paid',
},
component: () =>
import(
@ -571,7 +561,6 @@ export default {
name: 'CustomerFileManagement',
meta: {
title: 'fileManagement',
icon: 'paid',
},
component: () =>
import(
@ -586,6 +575,14 @@ export default {
'src/pages/Customer/components/CustomerFileManagementCreate.vue'
),
},
{
path: ':dmsId/edit',
name: 'CustomerFileManagementEdit',
component: () =>
import(
'src/pages/Customer/components/CustomerFileManagementEdit.vue'
),
},
],
},
{
@ -593,7 +590,6 @@ export default {
name: 'CustomerUnpaid',
meta: {
title: 'unpaid',
icon: 'paid',
},
component: () =>
import('src/pages/Customer/Card/CustomerUnpaid.vue'),
jsegarra marked this conversation as resolved Outdated

esta seccion da fallo simplemente al entrar

esta seccion da fallo simplemente al entrar

Corregido: 3bcd4984f5

Corregido: 3bcd4984f5

@jgallego Este método también falla en Salix, lo que pasa es que no se muestra mensaje de error
URL=> http://localhost:5000/api/ClientUnpaids/1112?filter=%7B%7D

@jgallego Este método también falla en Salix, lo que pasa es que no se muestra mensaje de error URL=> http://localhost:5000/api/ClientUnpaids/1112?filter=%7B%7D

Lo arregla verdnatura

Lo arregla verdnatura

Negativo!
@cfonseca, la manera correcta de hacer uso de esta tabla no es mediante el path "/ClientUnpaid/:id", sino pasándole el clientFk como filter
Ten en cuenta que tendrás que añadir registros a la tabla vn.clientUnpaid. bien lo puedes hacer desde la extensión de vscode que comentamos, desde DBeaver o desde fixtures.before.sql...si ves que no, apúntatelo para verlo en la daily

Negativo! @cfonseca, la manera correcta de hacer uso de esta tabla no es mediante el path "/ClientUnpaid/:id", sino pasándole el clientFk como filter Ten en cuenta que tendrás que añadir registros a la tabla vn.clientUnpaid. bien lo puedes hacer desde la extensión de vscode que comentamos, desde DBeaver o desde fixtures.before.sql...si ves que no, apúntatelo para verlo en la daily

Corregido: e56aa6587f

Corregido: e56aa6587f

He añadido un comentario a este código.
Tras llamada, Carlos va a hacer unos cambios ya que la implementación estaba bien orientada pero la ejecución no era la correcta,

He añadido un comentario a este código. Tras llamada, Carlos va a hacer unos cambios ya que la implementación estaba bien orientada pero la ejecución no era la correcta,