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 133 additions and 82 deletions
Showing only changes of commit ab20ec1738 - Show all commits

View File

@ -21,7 +21,7 @@ const props = defineProps({
},
template: {
type: String,
required: true,
required: false,
jsegarra marked this conversation as resolved
Review

Y si ponemos comillas simples como default reduciríamos la complejidad de usar ternario,no?

Y si ponemos comillas simples como default reduciríamos la complejidad de usar ternario,no?
Review

Sale un warning "Prop 'template' requires default value to be set." Lo digo por poner las comillas y nos evitamos un ternario

Sale un warning "Prop 'template' requires default value to be set." Lo digo por poner las comillas y nos evitamos un ternario
Review

Apliqué un string vacío '' como default de la prop template, pero sinceramente no se me ocurre como mejorar el ternary operator ese.

Pensé algo como: const key = props.template ? templates['${props.template}'] : props.template;.

Pero no se si tiene mucho sentido la verdad.

Commit: bafb938e23

Apliqué un string vacío `''` como default de la prop `template`, pero sinceramente no se me ocurre como mejorar el ternary operator ese. Pensé algo como: `const key = props.template ? `templates['${props.template}']` : props.template;`. Pero no se si tiene mucho sentido la verdad. Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/bafb938e231cbcd55236edf06b6c254f547d7ecb
},
locale: {
type: String,
@ -49,7 +49,7 @@ updateMessage();
function updateMessage() {
const params = props.data;
const key = `templates['${props.template}']`;
const key = props.template ? `templates['${props.template}']` : '';
message.value = t(key, params, { locale: locale.value });
}
@ -188,7 +188,7 @@ en:
templates:
pendingPayment: 'Your order is pending of payment.
Please, enter the website and make the payment with a credit card. Thank you.'
minAmount: 'A minimum amount of 50 (VAT excluded) is required for your order
minAmount: 'A minimum amount of 50 (VAT excluded) is required for your order
{ orderId } of { shipped } to receive it without additional shipping costs.'
orderChanges: 'Order {orderId} of { shipped }: { changes }'
en: English
@ -205,7 +205,7 @@ es:
templates:
pendingPayment: 'Su pedido está pendiente de pago.
Por favor, entre en la página web y efectue el pago con tarjeta. Muchas gracias.'
minAmount: 'Es necesario un importe mínimo de 50 (Sin IVA) en su pedido
minAmount: 'Es necesario un importe mínimo de 50 (Sin IVA) en su pedido
{ orderId } del día { shipped } para recibirlo sin portes adicionales.'
orderChanges: 'Pedido {orderId} día { shipped }: { changes }'
en: Inglés
@ -222,7 +222,7 @@ fr:
templates:
pendingPayment: 'Votre commande est en attente de paiement.
Veuillez vous connecter sur le site web et effectuer le paiement par carte. Merci beaucoup.'
minAmount: 'Un montant minimum de 50 (TVA non incluse) est requis pour votre commande
minAmount: 'Un montant minimum de 50 (TVA non incluse) est requis pour votre commande
{ orderId } du { shipped } afin de la recevoir sans frais de port supplémentaires.'
orderChanges: 'Commande { orderId } du { shipped }: { changes }'
en: Anglais
@ -239,7 +239,7 @@ pt:
templates:
pendingPayment: 'Seu pedido está pendente de pagamento.
Por favor, acesse o site e faça o pagamento com cartão. Muito obrigado.'
minAmount: 'É necessário um valor mínimo de 50 (sem IVA) em seu pedido
minAmount: 'É necessário um valor mínimo de 50 (sem IVA) em seu pedido
{ orderId } do dia { shipped } para recebê-lo sem custos de envio adicionais.'
orderChanges: 'Pedido { orderId } dia { shipped }: { changes }'
en: Inglês

View File

@ -64,6 +64,7 @@ export default {
markAll: 'Mark all',
noResults: 'No results',
system: 'System',
notificationSent: 'Notification sent',
},
errors: {
statusUnauthorized: 'Access denied',
@ -158,6 +159,7 @@ export default {
debt: 'Debt',
isDisabled: 'Customer is disabled',
isFrozen: 'Customer is frozen',
webAccountInactive: 'Web account inactive',
hasDebt: 'Customer has debt',
notChecked: 'Customer not checked',
noWebAccess: 'Web access is disabled',

View File

@ -64,6 +64,7 @@ export default {
markAll: 'Marcar todo',
noResults: 'Sin resultados',
system: 'Sistema',
notificationSent: 'Notificación enviada',
},
errors: {
statusUnauthorized: 'Acceso denegado',
@ -157,6 +158,7 @@ export default {
debt: 'Riesgo',
isDisabled: 'El cliente está desactivado',
isFrozen: 'El cliente está congelado',
webAccountInactive: 'Sin acceso web',
hasDebt: 'El cliente tiene riesgo',
notChecked: 'El cliente no está comprobado',
noWebAccess: 'El acceso web está desactivado',

View File

@ -12,7 +12,7 @@ const router = useRouter();
const provincesLocation = ref([]);
const consigneeFilter = {
const addressFilter = {
fields: [
'id',
'isDefaultAddress',
@ -51,16 +51,16 @@ const setProvince = (provinceFk) => {
return result[0]?.name || '';
};
const toCustomerConsigneeCreate = () => {
router.push({ name: 'CustomerConsigneeCreate' });
const toCustomerAddressCreate = () => {
router.push({ name: 'CustomerAddressCreate' });
};
const toCustomerConsigneeEdit = (consigneeId) => {
const toCustomerAddressEdit = (addressId) => {
router.push({
name: 'CustomerConsigneeEdit',
name: 'CustomerAddressEdit',
params: {
id: route.params.id,
consigneeId,
addressId,
},
});
};
@ -75,21 +75,21 @@ const toCustomerConsigneeEdit = (consigneeId) => {
<QCard class="q-pa-lg">
<VnPaginate
data-key="CustomerConsignees"
data-key="CustomerAddress"
:url="`Clients/${route.params.id}/addresses`"
order="id"
auto-load
:filter="consigneeFilter"
:filter="addressFilter"
>
<template #body="{ rows }">
<QCard
v-for="(item, index) in rows"
:key="index"
:class="{
'consignees-card': true,
'address-card': true,
'q-mb-md': index < rows.length - 1,
}"
@click="toCustomerConsigneeEdit(item.id)"
@click="toCustomerAddressEdit(item.id)"
>
<div class="q-ml-xs q-mr-md flex items-center">
<QIcon name="star" size="md" color="primary" />
@ -142,7 +142,7 @@ const toCustomerConsigneeEdit = (consigneeId) => {
</QCard>
<QPageSticky :offset="[18, 18]">
<QBtn @click.stop="toCustomerConsigneeCreate()" color="primary" fab icon="add" />
<QBtn @click.stop="toCustomerAddressCreate()" color="primary" fab icon="add" />
<QTooltip>
{{ t('New consignee') }}
</QTooltip>
@ -150,7 +150,7 @@ const toCustomerConsigneeEdit = (consigneeId) => {
</template>
<style lang="scss" scoped>
.consignees-card {
.address-card {
border: 2px solid var(--vn-light-gray);
border-radius: 10px;
padding: 10px;

View File

@ -66,6 +66,7 @@ const onSubmit = async () => {
try {
await axios.post('ClientContacts/crud', payload);
notes = [];
notify('globals.dataCreated', 'positive');
await getData();
} catch (error) {
notify('errors.create', 'negative');
@ -89,7 +90,12 @@ const onSubmit = async () => {
</div>
<div class="col">
jsegarra marked this conversation as resolved Outdated

No funciona si has dado a guardar.
Puedes eliminar la primera pero si añades una fila y le das a guardar, reaparece.

No funciona si has dado a guardar. Puedes eliminar la primera pero si añades una fila y le das a guardar, reaparece.

Corregido: d0e98010a5

Corregido: d0e98010a5
<VnInput :label="t('Phone')" clearable v-model="note.phone" />
<VnInput
:label="t('Phone')"
clearable
type="number"
v-model="note.phone"
/>
</div>
<div class="flex items-center">

View File

@ -10,6 +10,7 @@ import useCardDescription from 'src/composables/useCardDescription';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
const $props = defineProps({
id: {
@ -44,6 +45,9 @@ const setData = (entity) => (data.value = useCardDescription(entity.name, entity
:summary="$props.summary"
data-key="customerData"
>
<template #menu="{ entity }">
<CustomerDescriptorMenu :customer="entity" />
</template>
<template #body="{ entity }">
<VnLv v-if="entity.salesPersonUser" :label="t('customer.card.salesPerson')">
<template #value>
@ -79,6 +83,14 @@ const setData = (entity) => (data.value = useCardDescription(entity.name, entity
>
<QTooltip>{{ t('customer.card.isFrozen') }}</QTooltip>
</QIcon>
<QIcon
color="primary"
name="vn:noweb"
size="sm"
v-if="entity.account.active == false"
>
<QTooltip>{{ t('customer.card.webAccountInactive') }}</QTooltip>
</QIcon>
<QIcon
v-if="entity.debt > entity.credit"
name="vn:risk"
@ -98,9 +110,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.name, entity
</QCardActions>
</template>
<template #actions="{ entity }">
<div class="flex justify-center q-mb-md">
<QIcon color="primary" name="vn:noweb" size="sm" />
</div>
<QCardActions class="flex justify-center">
<QBtn
:to="{

View File

@ -0,0 +1,63 @@
<script setup>
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import axios from 'axios';
import { useQuasar } from 'quasar';
import useNotify from 'src/composables/useNotify';
import VnSmsDialog from 'src/components/common/VnSmsDialog.vue';
const $props = defineProps({
customer: {
type: Object,
required: true,
},
});
const { notify } = useNotify();
const { t } = useI18n();
const quasar = useQuasar();
const route = useRoute();
const showSmsDialog = () => {
console.log('showSmsDialog()');
quasar.dialog({
component: VnSmsDialog,
componentProps: {
phone: $props.customer.phone,
promise: sendSms,
},
});
};
const sendSms = async (payload) => {
payload.destinationFk = route.params.id;
try {
await axios.post(`Clients/${route.params.id}/sendSms`, payload);
notify('globals.notificationSent', 'positive');
} catch (error) {
notify(error.message, 'positive');
}
};
</script>
<template>
<QItem v-ripple clickable>
<QItemSection>
<RouterLink :to="{ name: 'TicketCreate' }" class="color-vn-text">
{{ t('Simple ticket') }}
</RouterLink>
</QItemSection>
</QItem>
<QItem v-ripple clickable>
<QItemSection @click="showSmsDialog()">{{ t('Send SMS') }}</QItemSection>
</QItem>
</template>
<i18n>
es:
Simple ticket: Ticket simple
Send SMS: Enviar SMS
</i18n>

View File

@ -162,14 +162,6 @@ const toCustomerGreugeCreate = () => {
</QPageSticky>
</template>
<style lang="scss">
.consignees-card {
border: 2px solid var(--vn-light-gray);
border-radius: 10px;
padding: 10px;
}
</style>
<i18n>
es:
Total: Total

View File

@ -59,18 +59,6 @@ const toCustomerNoteCreate = () => {
{{ t('globals.noResults') }}
</h5>
</div>
<QPageSticky :offset="[18, 18]">
<QBtn
@click.stop="toCustomerNoteCreate()"
color="primary"
fab
icon="add"
/>
<QTooltip>
{{ t('New consignee') }}
</QTooltip>
</QPageSticky>
</template>
</VnPaginate>
</QCard>
@ -78,7 +66,7 @@ const toCustomerNoteCreate = () => {
<QPageSticky :offset="[18, 18]">
<QBtn @click.stop="toCustomerNoteCreate()" color="primary" fab icon="add" />
<QTooltip>
{{ t('New consignee') }}
{{ t('New note') }}
</QTooltip>
</QPageSticky>
</template>
@ -90,3 +78,8 @@ const toCustomerNoteCreate = () => {
padding: 10px;
}
</style>
<i18n>
es:
New note: Nueva nota
</i18n>

View File

@ -118,14 +118,6 @@ const toCustomerRecoverieCreate = () => {
</QPageSticky>
</template>
<style lang="scss">
.consignees-card {
border: 2px solid var(--vn-light-gray);
border-radius: 10px;
padding: 10px;
}
</style>
<i18n>
es:
Since: Desde

View File

@ -128,14 +128,6 @@ const toCustomerSamplesCreate = () => {
</QPageSticky>
</template>
<style lang="scss">
.consignees-card {
border: 2px solid var(--vn-light-gray);
border-radius: 10px;
padding: 10px;
}
</style>
<i18n>
es:
Sent: Enviado

View File

@ -53,9 +53,9 @@ const refreshData = () => {
getCustomsAgents();
};
const toCustomerConsignees = () => {
const toCustomerAddress = () => {
router.push({
name: 'CustomerConsignees',
name: 'CustomerAddress',
params: {
id: route.params.id,
},
@ -92,7 +92,7 @@ const toCustomerConsignees = () => {
:form-initial-data="formInitialData"
:observe-form-changes="false"
:url-create="urlCreate"
@on-data-saved="toCustomerConsignees()"
@on-data-saved="toCustomerAddress()"
model="client"
>
<template #form="{ data, validate }">

View File

@ -31,7 +31,7 @@ const observationTypes = ref([]);
const notes = ref([]);
onBeforeMount(() => {
urlUpdate.value = `Clients/${route.params.id}/updateAddress/${route.params.consigneeId}`;
urlUpdate.value = `Clients/${route.params.id}/updateAddress/${route.params.addressId}`;
});
const onPostcodeCreated = async ({ code, provinceFk, townFk }, formData) => {
@ -48,7 +48,7 @@ const getData = async (observations) => {
if (observationTypes.value.length) {
const filter = {
fields: ['id', 'addressFk', 'observationTypeFk', 'description'],
where: { addressFk: `${route.params.consigneeId}` },
where: { addressFk: `${route.params.addressId}` },
};
const { data } = await axios.get('AddressObservations', {
params: { filter: JSON.stringify(filter) },
@ -65,7 +65,7 @@ const getData = async (observations) => {
$isNew: false,
$oldData: null,
$orgIndex: null,
addressFk: `${route.params.consigneeId}`,
addressFk: `${route.params.addressId}`,
description: observation.description,
observationTypeFk: type.id,
}
@ -81,7 +81,7 @@ const addNote = () => {
$isNew: true,
$oldData: null,
$orgIndex: null,
addressFk: `${route.params.consigneeId}`,
addressFk: `${route.params.addressId}`,
description: '',
observationTypeFk: '',
});
@ -133,7 +133,7 @@ const onDataSaved = () => {
<FormModel
:observe-form-changes="false"
:url-update="urlUpdate"
:url="`Addresses/${route.params.consigneeId}`"
:url="`Addresses/${route.params.addressId}`"
@on-data-saved="onDataSaved()"
auto-load
model="client"

View File

@ -21,7 +21,7 @@ export default {
'CustomerBasicData',
'CustomerFiscalData',
'CustomerBillingData',
'CustomerConsignees',
'CustomerAddress',
'CustomerNotes',
'CustomerCredits',
'CustomerGreuges',
@ -151,45 +151,45 @@ export default {
import('src/pages/Customer/Card/CustomerBillingData.vue'),
},
{
path: 'consignees',
name: 'ConsigneesCard',
redirect: { name: 'CustomerConsignees' },
path: 'address',
name: 'AddressCard',
redirect: { name: 'CustomerAddress' },
children: [
{
path: '',
name: 'CustomerConsignees',
name: 'CustomerAddress',
meta: {
icon: 'vn:delivery',
title: 'consignees',
},
component: () =>
import('src/pages/Customer/Card/CustomerConsignees.vue'),
import('src/pages/Customer/Card/CustomerAddress.vue'),
},
{
path: 'create',
name: 'CustomerConsigneeCreate',
name: 'CustomerAddressCreate',
meta: {
title: 'consignee-create',
title: 'address-create',
},
component: () =>
import(
'src/pages/Customer/components/CustomerConsigneeCreate.vue'
'src/pages/Customer/components/CustomerAddressCreate.vue'
),
},
{
path: ':consigneeId',
name: 'CustomerConsigneeEditCard',
redirect: { name: 'CustomerConsigneeEdit' },
path: ':addressId',
name: 'CustomerAddressEditCard',
redirect: { name: 'CustomerAddressEdit' },
children: [
{
path: 'edit',
name: 'CustomerConsigneeEdit',
name: 'CustomerAddressEdit',
meta: {
title: 'consignee-edit',
title: 'address-edit',
},
component: () =>
import(
'src/pages/Customer/components/CustomerConsigneeEdit.vue'
'src/pages/Customer/components/CustomerAddressEdit.vue'
),
},
],