Merge branch 'dev' of https: refs #7869//gitea.verdnatura.es/verdnatura/salix-front into 7869-ModifyZones
gitea/salix-front/pipeline/pr-dev This commit is unstable Details

This commit is contained in:
Jon Elias 2025-03-17 08:04:00 +01:00
commit 89d9d75976
74 changed files with 9264 additions and 13040 deletions

2
Jenkinsfile vendored
View File

@ -120,6 +120,8 @@ pipeline {
def image = docker.build('lilium-dev', '-f docs/Dockerfile.dev docs')
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
sh "docker-compose ${env.COMPOSE_PARAMS} pull back"
sh "docker-compose ${env.COMPOSE_PARAMS} pull db"
sh "docker-compose ${env.COMPOSE_PARAMS} up -d"
image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") {

View File

@ -32,6 +32,18 @@ pnpm run test:front
pnpm run test:e2e
```
### Run e2e parallel
```bash
pnpm run test:e2e:parallel
```
### View e2e parallel report
```bash
pnpm run test:e2e:summary
```
### Build the app for production
```bash

View File

@ -13,7 +13,7 @@
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
"test:e2e": "cypress open",
"test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
"test:e2e:parallel": "bash ./test/cypress/cypressParallel.sh",
"test:e2e:parallel": "bash ./test/cypress/run.sh",
"test:e2e:summary": "bash ./test/cypress/summary.sh",
"test": "echo \"See package.json => scripts for available tests.\" && exit 0",
"test:front": "vitest",
@ -56,6 +56,7 @@
"eslint-plugin-cypress": "^4.1.0",
"eslint-plugin-vue": "^9.32.0",
"husky": "^8.0.0",
"junit-merge": "^2.0.0",
"mocha": "^11.1.0",
"postcss": "^8.4.23",
"prettier": "^3.4.2",

File diff suppressed because it is too large Load Diff

View File

@ -47,14 +47,6 @@ vi.mock('src/router/modules', () => ({
],
},
},
{
path: 'create',
name: 'CustomerCreate',
meta: {
title: 'createCustomer',
icon: 'vn:addperson',
},
},
],
},
],

View File

@ -99,7 +99,6 @@ globals:
file: File
selectFile: Select a file
copyClipboard: Copy on clipboard
salesPerson: SalesPerson
send: Send
code: Code
since: Since
@ -158,6 +157,7 @@ globals:
changeState: Change state
raid: 'Raid {daysInForward} days'
isVies: Vies
department: Department
noData: No data available
vehicle: Vehicle
pageTitles:
@ -347,7 +347,6 @@ globals:
params:
description: Description
clientFk: Client id
salesPersonFk: Sales person
warehouseFk: Warehouse
provinceFk: Province
stateFk: State
@ -605,7 +604,6 @@ worker:
balance: Balance
medical: Medical
list:
department: Department
schedule: Schedule
newWorker: New worker
summary:
@ -864,7 +862,6 @@ components:
mine: For me
hasMinPrice: Minimum price
# LatestBuysFilter
salesPersonFk: Buyer
supplierFk: Supplier
from: From
to: To

View File

@ -103,7 +103,6 @@ globals:
file: Fichero
selectFile: Seleccione un fichero
copyClipboard: Copiar en portapapeles
salesPerson: Comercial
send: Enviar
code: Código
since: Desde
@ -163,6 +162,7 @@ globals:
raid: 'Redada {daysInForward} días'
isVies: Vies
noData: Datos no disponibles
department: Departamento
vehicle: Vehículo
pageTitles:
logIn: Inicio de sesión
@ -350,7 +350,6 @@ globals:
params:
description: Descripción
clientFk: Id cliente
salesPersonFk: Comercial
warehouseFk: Almacén
provinceFk: Provincia
stateFk: Estado
@ -532,7 +531,6 @@ ticket:
state: Estado
shipped: Enviado
landed: Entregado
salesPerson: Comercial
total: Total
card:
customerId: ID cliente
@ -624,8 +622,6 @@ invoiceOut:
errors:
downloadCsvFailed: Error al descargar CSV
order:
field:
salesPersonFk: Comercial
form:
clientFk: Cliente
addressFk: Dirección
@ -693,7 +689,6 @@ worker:
formation: Formación
medical: Mutua
list:
department: Departamento
schedule: Horario
newWorker: Nuevo trabajador
summary:
@ -951,7 +946,6 @@ components:
hasMinPrice: Precio mínimo
wareHouseFk: Almacén
# LatestBuysFilter
salesPersonFk: Comprador
supplierFk: Proveedor
visible: Visible
active: Activo

View File

@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n';
import { toDateHourMinSec, toPercentage } from 'src/filters';
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
@ -65,12 +66,12 @@ onMounted(async () => {
</template>
</VnLv>
<VnLv :label="t('claim.created')" :value="toDateHourMinSec(entity.created)" />
<VnLv :label="t('claim.commercial')">
<VnLv :label="t('globals.department')">
<template #value>
<VnUserLink
:name="entity.client?.salesPersonUser?.name"
:worker-id="entity.client?.salesPersonFk"
/>
<span class="link">
{{ entity?.client?.department?.name || '-' }}
<DepartmentDescriptorProxy :id="entity?.client?.departmentFk" />
</span>
</template>
</VnLv>
<VnLv

View File

@ -14,7 +14,7 @@ export default {
relation: 'client',
scope: {
include: [
{ relation: 'salesPersonUser' },
{ relation: 'department' },
{
relation: 'claimsRatio',
scope: {

View File

@ -117,7 +117,7 @@ const selected = ref([]);
const mana = ref(0);
async function fetchMana() {
const ticketId = claim.value.ticketFk;
const response = await axios.get(`Tickets/${ticketId}/getSalesPersonMana`);
const response = await axios.get(`Tickets/${ticketId}/getDepartmentMana`);
mana.value = response.data;
}

View File

@ -19,6 +19,7 @@ import ClaimNotes from 'src/pages/Claim/Card/ClaimNotes.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import ClaimDescriptorMenu from './ClaimDescriptorMenu.vue';
const route = useRoute();
@ -252,13 +253,15 @@ function claimUrl(section) {
</VnLv>
<VnLv
v-if="$route.name != 'ClaimSummary'"
:label="t('globals.salesPerson')"
:label="t('customer.summary.team')"
>
<template #value>
<VnUserLink
:name="claim.client?.salesPersonUser?.name"
:worker-id="claim.client?.salesPersonFk"
/>
<span class="link">
{{ claim?.client?.department?.name || '-' }}
<DepartmentDescriptorProxy
:id="claim?.client?.departmentFk"
/>
</span>
</template>
</VnLv>
<VnLv v-if="$route.name != 'ClaimSummary'" :label="t('claim.attendedBy')">

View File

@ -44,15 +44,14 @@ const props = defineProps({
is-outlined
/>
<VnSelect
:label="t('Salesperson')"
v-model="params.salesPersonFk"
url="Workers/activeWithInheritedRole"
:filter="{ where: { role: 'salesPerson' } }"
:use-like="false"
option-filter="firstName"
dense
outlined
dense
rounded
:label="t('globals.params.departmentFk')"
v-model="params.departmentFk"
option-value="id"
option-label="name"
url="Departments"
/>
<VnSelect
:label="t('claim.attendedBy')"
@ -126,7 +125,6 @@ en:
search: Contains
clientFk: Customer
clientName: Customer
salesPersonFk: Salesperson
attenderFk: Attender
claimResponsibleFk: Responsible
claimStateFk: State
@ -139,7 +137,6 @@ es:
search: Contiene
clientFk: Cliente
clientName: Cliente
salesPersonFk: Comercial
attenderFk: Asistente
claimResponsibleFk: Responsable
claimStateFk: Estado
@ -148,6 +145,5 @@ es:
itemFk: Artículo
zoneFk: Zona
Client Name: Nombre del cliente
Salesperson: Comercial
Item: Artículo
</i18n>

View File

@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
import { toDate } from 'filters/index';
import ClaimFilter from './ClaimFilter.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import ClaimSummary from './Card/ClaimSummary.vue';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
@ -48,6 +49,20 @@ const columns = computed(() => [
},
columnClass: 'expand',
},
{
align: 'left',
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Departments',
},
create: true,
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'left',
label: t('claim.attendedBy'),
@ -152,6 +167,12 @@ const STATE_COLOR = {
<CustomerDescriptorProxy :id="row.clientFk" />
</span>
</template>
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ row.departmentName || '-' }}
<DepartmentDescriptorProxy :id="row?.departmentFk" />
</span>
</template>
<template #column-attendedBy="{ row }">
<span @click.stop>
<VnUserLink :name="row.workerName" :worker-id="row.workerFk" />

View File

@ -8,7 +8,6 @@ import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
import { getDifferences, getUpdatedValues } from 'src/filters';
const route = useRoute();
@ -37,7 +36,7 @@ const exprBuilder = (param, value) => {
function onBeforeSave(formData, originalData) {
return getUpdatedValues(
Object.keys(getDifferences(formData, originalData)),
formData
formData,
);
}
</script>
@ -119,16 +118,11 @@ function onBeforeSave(formData, originalData) {
/>
</VnRow>
<VnRow>
<VnSelectWorker
:label="t('customer.summary.salesPerson')"
v-model="data.salesPersonFk"
:params="{
departmentCodes: ['VT', 'shopping'],
}"
:has-avatar="true"
:rules="validate('client.salesPersonFk')"
:expr-builder="exprBuilder"
emit-value
<VnSelect
:label="t('globals.department')"
v-model="data.departmentFk"
url="Departments"
:fields="['id', 'name']"
/>
<VnSelect
v-model="data.contactChannelFk"
@ -160,7 +154,7 @@ function onBeforeSave(formData, originalData) {
<QIcon name="info" class="cursor-pointer">
<QTooltip>{{
t(
'In case of a company succession, specify the grantor company'
'In case of a company succession, specify the grantor company',
)
}}</QTooltip>
</QIcon>

View File

@ -3,14 +3,14 @@ import { onMounted, ref, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
import { toCurrency, toDate } from 'src/filters';
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';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import { useState } from 'src/composables/useState';
const state = useState();
@ -84,14 +84,10 @@ const debtWarning = computed(() => {
:value="toCurrency(entity.debt)"
:info="t('customer.summary.riskInfo')"
/>
<VnLv :label="t('customer.summary.salesPerson')">
<VnLv :label="t('globals.department')">
<template #value>
<VnUserLink
v-if="entity.salesPersonUser"
:name="entity.salesPersonUser.name"
:worker-id="entity.salesPersonFk"
/>
<span v-else>{{ dashIfEmpty(entity.salesPersonUser) }}</span>
<span class="link" v-text="entity.department?.name" />
<DepartmentDescriptorProxy :id="entity.department?.id" />
</template>
</VnLv>
<VnLv

View File

@ -2,7 +2,6 @@
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import { toCurrency, toPercentage, toDate, dashOrCurrency } from 'src/filters';
import CardSummary from 'components/ui/CardSummary.vue';
@ -13,6 +12,8 @@ import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryT
import VnTitle from 'src/components/common/VnTitle.vue';
import VnRow from 'src/components/ui/VnRow.vue';
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
const route = useRoute();
const { t } = useI18n();
const grafanaUrl = 'https://grafana.verdnatura.es';
@ -106,16 +107,12 @@ const sumRisk = ({ clientRisks }) => {
{{ t('globals.params.email') }}
<VnLinkMail email="entity.email"></VnLinkMail> </template
></VnLv>
<VnLv
:label="t('customer.summary.salesPerson')"
:value="entity?.salesPersonUser?.name"
>
<VnLv :label="t('globals.department')">
<template #value>
<VnUserLink
:name="entity.salesPersonUser?.name"
:worker-id="entity.salesPersonFk"
/> </template
></VnLv>
<span class="link" v-text="entity.department?.name" />
<DepartmentDescriptorProxy :id="entity?.department?.id" />
</template>
</VnLv>
<VnLv
:label="t('customer.summary.contactChannel')"
:value="entity?.contactChannel?.name"

View File

@ -1,146 +0,0 @@
<script setup>
import { reactive, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnLocation from 'src/components/common/VnLocation.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
const { t } = useI18n();
const initialData = reactive({
active: true,
isEqualizated: false,
});
const workersOptions = ref([]);
const businessTypesOptions = ref([]);
function handleLocation(data, location) {
const { town, code, provinceFk, countryFk } = location ?? {};
data.postcode = code;
data.city = town;
data.provinceFk = provinceFk;
data.countryFk = countryFk;
}
</script>
<template>
<FetchData
@on-fetch="(data) => (workersOptions = data)"
auto-load
url="Workers/search?departmentCodes"
/>
<FetchData
@on-fetch="(data) => (businessTypesOptions = data)"
auto-load
url="BusinessTypes"
/>
<QPage>
<VnSubToolbar />
<FormModel
:form-initial-data="initialData"
model="client"
url-create="Clients/createWithUser"
>
<template #form="{ data, validate }">
<VnRow>
<QInput :label="t('Comercial name')" v-model="data.name" />
<VnSelect
:label="t('Salesperson')"
:options="workersOptions"
hide-selected
option-label="name"
option-value="id"
v-model="data.salesPersonFk"
/>
</VnRow>
<VnRow>
<VnSelect
:label="t('Business type')"
:options="businessTypesOptions"
hide-selected
option-label="description"
option-value="code"
v-model="data.businessTypeFk"
/>
<QInput v-model="data.fi" :label="t('Tax number')" />
</VnRow>
<VnRow>
<QInput
:label="t('Business name')"
:rules="validate('client.socialName')"
v-model="data.socialName"
/>
</VnRow>
<VnRow>
<QInput
:label="t('Street')"
:rules="validate('client.street')"
v-model="data.street"
/>
</VnRow>
<VnRow>
<VnLocation
:rules="validate('Worker.postcode')"
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
v-model="data.location"
@update:model-value="(location) => handleLocation(data, location)"
>
</VnLocation>
</VnRow>
<VnRow>
<QInput v-model="data.userName" :label="t('Web user')" />
<QInput
:label="t('Email')"
:rules="validate('client.email')"
clearable
type="email"
v-model="data.email"
>
<template #append>
<QIcon name="info" class="cursor-info">
<QTooltip max-width="400px">{{
t('customer.basicData.youCanSaveMultipleEmails')
}}</QTooltip>
</QIcon>
</template>
</QInput>
</VnRow>
<QCheckbox
:label="t('Is equalizated')"
v-model="initialData.isEqualizated"
/>
</template>
</FormModel>
</QPage>
</template>
<style lang="scss" scoped>
.card {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-gap: 20px;
}
</style>
<i18n>
es:
Comercial name: Nombre comercial
Salesperson: Comercial
Business type: Tipo de negocio
Tax number: NIF / CIF
Business name: Razón social
Street: Dirección fiscal
Postcode: Código postal
City: Población
Province: Provincia
Country: País
Web user: Usuario web
Email: Email
Is equalizated: Recargo de equivalencia
</i18n>

View File

@ -3,7 +3,6 @@ import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
defineProps({
@ -65,22 +64,15 @@ const exprBuilder = (param, value) => {
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<VnSelectWorker
:label="t('Salesperson')"
v-model="params.salesPersonFk"
:params="{
departmentCodes: ['VT'],
}"
:expr-builder="exprBuilder"
@update:model-value="searchFn()"
emit-value
map-options
use-input
hide-selected
dense
<VnSelect
outlined
dense
rounded
:input-debounce="0"
:label="t('globals.params.departmentFk')"
v-model="params.departmentFk"
option-value="id"
option-label="name"
url="Departments"
/>
</QItemSection>
</QItem>
@ -164,7 +156,6 @@ en:
params:
search: Contains
fi: FI
salesPersonFk: Salesperson
provinceFk: Province
isActive: Is active
city: City
@ -191,7 +182,6 @@ es:
sageTaxTypeFk: Tipo de impuesto Sage
sageTransactionTypeFk: Tipo de impuesto Sage
payMethodFk: Forma de pago
salesPersonFk: Comercial
provinceFk: Provincia
city: Ciudad
phone: Teléfono
@ -201,7 +191,6 @@ es:
name: Nombre
postcode: CP
FI: NIF
Salesperson: Comercial
Province: Provincia
City: Ciudad
Phone: Teléfono

View File

@ -10,7 +10,6 @@ import CustomerFilter from './CustomerFilter.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import VnLocation from 'src/components/common/VnLocation.vue';
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { t } = useI18n();
@ -73,30 +72,17 @@ const columns = computed(() => [
},
{
align: 'left',
name: 'salesPersonFk',
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name', 'firstName'],
where: { role: 'salesPerson' },
optionFilter: 'firstName',
url: 'Departments',
},
columnFilter: {
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name', 'firstName'],
where: { role: 'salesPerson' },
optionLabel: 'firstName',
optionValue: 'id',
},
},
create: false,
create: true,
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'left',
@ -155,6 +141,9 @@ const columns = computed(() => [
inWhere: true,
},
columnClass: 'expand',
attrs: {
uppercase: true,
},
},
{
align: 'left',
@ -446,36 +435,6 @@ function handleLocation(data, location) {
redirect="customer"
>
<template #more-create-dialog="{ data }">
<VnSelectWorker
:label="t('customer.summary.salesPerson')"
v-model="data.salesPersonFk"
:params="{
departmentCodes: ['VT', 'shopping'],
}"
:has-avatar="true"
:id-value="data.salesPersonFk"
emit-value
auto-load
>
<template #prepend>
<VnAvatar
:worker-id="data.salesPersonFk"
color="primary"
:title="title"
/>
</template>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
<QItemLabel caption
>{{ scope.opt?.nickname }},
{{ scope.opt?.code }}</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelectWorker>
<VnLocation
:acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
v-model="data.location"

View File

@ -32,28 +32,6 @@ const columns = computed(() => [
},
},
},
{
align: 'left',
name: 'isWorker',
label: t('Is worker'),
},
{
align: 'left',
name: 'salesPersonFk',
label: t('Salesperson'),
columnFilter: {
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'salesPerson' },
useLike: false,
optionValue: 'id',
optionLabel: 'name',
optionFilter: 'firstName',
},
},
},
{
align: 'left',
name: 'departmentFk',
@ -153,6 +131,11 @@ const columns = computed(() => [
label: t('Has recovery'),
name: 'hasRecovery',
},
{
align: 'left',
name: 'isWorker',
label: t('customer.params.isWorker'),
},
]);
const viewAddObservation = (rowsSelected) => {
@ -167,7 +150,6 @@ const viewAddObservation = (rowsSelected) => {
function exprBuilder(param, value) {
switch (param) {
case 'salesPersonFk':
case 'creditInsurance':
case 'countryFk':
return { [`c.${param}`]: value };
@ -176,7 +158,7 @@ function exprBuilder(param, value) {
case 'workerFk':
return { [`co.${param}`]: value };
case 'departmentFk':
return { [`wd.${param}`]: value };
return { [`c.${param}`]: value };
case 'amount':
case 'clientFk':
return { [`d.${param}`]: value };
@ -241,12 +223,6 @@ function exprBuilder(param, value) {
<template #column-observation="{ row }">
<VnInput type="textarea" v-model="row.observation" readonly dense rows="2" />
</template>
<template #column-salesPersonFk="{ row }">
<span class="link" @click.stop>
{{ row.salesPersonName }}
<WorkerDescriptorProxy :id="row.salesPersonFk" />
</span>
</template>
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ row.departmentName }}
@ -265,8 +241,6 @@ function exprBuilder(param, value) {
es:
Add observation: Añadir observación
Client: Cliente
Is worker: Es trabajador
Salesperson: Comercial
Department: Departamento
Country: País
P. Method: F. Pago
@ -281,5 +255,5 @@ es:
Credit I.: Crédito A.
Credit insurance: Crédito asegurado
From: Desde
Has recovery: Tiene recobro
Has recovery: Recobro
</i18n>

View File

@ -15,19 +15,12 @@ const props = defineProps({
},
});
const salespersons = ref();
const countries = ref();
const authors = ref();
const departments = ref();
</script>
<template>
<FetchData
:filter="{ where: { role: 'salesPerson' } }"
@on-fetch="(data) => (salespersons = data)"
auto-load
url="Workers/activeWithInheritedRole"
/>
<FetchData @on-fetch="(data) => (countries = data)" auto-load url="Countries" />
<FetchData
@on-fetch="(data) => (authors = data)"
@ -62,29 +55,6 @@ const departments = ref();
@update:model-value="searchFn()"
/>
</QItem>
<QItem class="q-mb-sm">
<QItemSection v-if="salespersons">
<VnSelect
:input-debounce="0"
:label="t('Salesperson')"
:options="salespersons"
dense
emit-value
hide-selected
map-options
option-label="name"
option-value="id"
outlined
rounded
use-input
v-model="params.salesPersonFk"
@update:model-value="searchFn()"
/>
</QItemSection>
<QItemSection v-else>
<QSkeleton class="full-width" type="QInput" />
</QItemSection>
</QItem>
<QItem class="q-mb-sm">
<QItemSection v-if="departments">
<VnSelect
@ -219,7 +189,6 @@ const departments = ref();
en:
params:
clientFk: Client
salesPersonFk: Salesperson
countryFk: Country
paymentMethod: P. Method
balance: Balance D.
@ -230,7 +199,6 @@ en:
es:
params:
clientFk: Cliente
salesPersonFk: Comercial
countryFk: País
paymentMethod: F. Pago
balance: Saldo V.
@ -239,7 +207,6 @@ es:
credit: Crédito A.
defaulterSinced: Desde
Client: Cliente
Salesperson: Comercial
Departments: Departamentos
Country: País
P. Method: F. Pago

View File

@ -69,17 +69,16 @@ const columns = computed(() => [
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
name: 'salesPersonFk',
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'salesPerson' },
optionFilter: 'firstName',
useLike: false,
url: 'Departments',
},
visible: false,
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
]);
</script>
@ -96,7 +95,7 @@ const columns = computed(() => [
</VnSubToolbar>
<VnTable
:data-key="dataKey"
url="Clients"
url="Clients/filter"
:table="{
'row-key': 'id',
selection: 'multiple',
@ -127,7 +126,6 @@ const columns = computed(() => [
es:
Identifier: Identificador
Social name: Razón social
Salesperson: Comercial
Phone: Teléfono
City: Población
Email: Email

View File

@ -20,7 +20,7 @@ customer:
name: Name
contact: Contact
mobile: Mobile
salesPerson: Sales person
team: Team
contactChannel: Contact channel
socialName: Social name
fiscalId: Fiscal ID
@ -78,7 +78,6 @@ customer:
id: Identifier
socialName: Social name
fi: Tax number
salesPersonFk: Salesperson
creditInsurance: Credit insurance
phone: Phone
street: Street

View File

@ -20,7 +20,7 @@ customer:
name: Nombre
contact: Contacto
mobile: Móvil
salesPerson: Comercial
team: Equipo
contactChannel: Canal de contacto
socialName: Razón social
fiscalId: NIF/CIF
@ -78,7 +78,6 @@ customer:
id: Identificador
socialName: Razón social
fi: NIF / CIF
salesPersonFk: Comercial
creditInsurance: Crédito asegurado
phone: Teléfono
street: Dirección fiscal

View File

@ -20,14 +20,21 @@ const tagValues = ref([]);
</script>
<template>
<FetchData
url="TicketRequests/getItemTypeWorker"
auto-load
:filter="{ fields: ['id', 'nickname'], order: 'nickname ASC' }"
@on-fetch="(data) => (itemTypeWorkersOptions = data)"
/>
<ItemsFilterPanel :data-key="dataKey" :custom-tags="['tags']">
<template #body="{ params, searchFn }">
<QItem class="q-my-md">
<QItemSection>
<VnSelect
:label="t('components.itemsFilterPanel.salesPersonFk')"
v-model="params.salesPersonFk"
url="TicketRequests/getItemTypeWorker"
:label="t('components.itemsFilterPanel.buyerFk')"
v-model="params.buyerFk"
:options="itemTypeWorkersOptions"
option-value="id"
option-label="nickname"
:fields="['id', 'nickname']"
sort-by="nickname ASC"

View File

@ -46,6 +46,11 @@ function ticketFilter(invoice) {
<InvoiceOutDescriptorMenu :invoice-out-data="entity" :menu-ref="menuRef" />
</template>
<template #body="{ entity }">
<VnLv
v-if="entity.externalRef"
:label="t('invoiceOut.externalRef')"
:value="entity.externalRef"
/>
<VnLv :label="t('invoiceOut.card.issued')" :value="toDate(entity.issued)" />
<VnLv :label="t('globals.amount')" :value="toCurrency(entity.amount)" />
<VnLv v-if="entity.client" :label="t('globals.client')">

View File

@ -8,7 +8,7 @@ import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import { usePrintService } from 'src/composables/usePrintService';
import VnTable from 'src/components/VnTable/VnTable.vue';
import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
import { toCurrency, toDate } from 'src/filters/index';
import { toCurrency, toDate, dashIfEmpty } from 'src/filters/index';
import { QBtn } from 'quasar';
import axios from 'axios';
import InvoiceOutFilter from './InvoiceOutFilter.vue';
@ -16,7 +16,7 @@ import VnRow from 'src/components/ui/VnRow.vue';
import VnRadio from 'src/components/common/VnRadio.vue';
import VnInput from 'src/components/common/VnInput.vue';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import DepartmentDescriptorProxy from '../Worker/Department/Card/DepartmentDescriptorProxy.vue';
import VnSection from 'src/components/common/VnSection.vue';
const { t } = useI18n();
@ -55,6 +55,14 @@ const columns = computed(() => [
name: 'id',
},
},
{
align: 'left',
name: 'issued',
label: t('invoiceOut.summary.issued'),
component: 'date',
format: (row) => toDate(row.issued),
columnField: { component: null },
},
{
align: 'left',
name: 'ref',
@ -90,12 +98,12 @@ const columns = computed(() => [
{
align: 'left',
name: 'departmentFk',
label: t('globals.params.departmentFk'),
label: t('customer.summary.team'),
cardVisible: true,
component: 'select',
attrs: {
url: 'Departments',
},
create: true,
columnField: {
component: null,
},
@ -246,7 +254,7 @@ watchEffect(selectedRows);
</template>
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ row.departmentName || '-' }}
{{ dashIfEmpty(row.departmentName) }}
<DepartmentDescriptorProxy :id="row?.departmentFk" />
</span>
</template>

View File

@ -8,7 +8,7 @@ import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
import { useArrayData } from 'src/composables/useArrayData';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue';
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
import DepartmentDescriptorProxy from '../Worker/Department/Card/DepartmentDescriptorProxy.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import InvoiceOutNegativeBasesFilter from './InvoiceOutNegativeBasesFilter.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
@ -115,18 +115,16 @@ const columns = computed(() => [
},
{
align: 'left',
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
name: 'workerName',
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'salesPerson' },
url: 'Departments',
},
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.workerName),
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
]);
@ -198,10 +196,10 @@ const downloadCSV = async () => {
<TicketDescriptorProxy :id="row.ticketFk" />
</span>
</template>
<template #column-workerName="{ row }">
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ row.workerName }}
<WorkerDescriptorProxy :id="row.comercialId" />
{{ row.departmentName }}
<DepartmentDescriptorProxy :id="row.departmentFk" />
</span>
</template>
<template #moreFilterPanel="{ params }">

View File

@ -129,12 +129,15 @@ const props = defineProps({
</QItem>
<QItem>
<QItemSection>
<VnSelectWorker
:label="t('invoiceOut.negativeBases.comercial')"
v-model="params.workerName"
option-value="name"
is-outlined
@update:model-value="searchFn()"
<VnSelect
outlined
dense
rounded
:label="t('globals.params.departmentFk')"
v-model="params.departmentFk"
option-value="id"
option-label="name"
url="Departments"
/>
</QItemSection>
</QItem>

View File

@ -1,6 +1,7 @@
invoiceOut:
search: Search invoice
searchInfo: You can search by invoice reference
externalRef: External Ref.
params:
id: ID
company: Company
@ -12,7 +13,6 @@ invoiceOut:
isActive: Active
hasToInvoice: Has to invoice
hasVerifiedData: Verified data
workerName: Worker
isTaxDataChecked: Verified data
amount: Amount
clientFk: Client
@ -26,6 +26,7 @@ invoiceOut:
max: Max
hasPdf: Has PDF
search: Contains
departmentFk: Department
card:
issued: Issued
customerCard: Customer card

View File

@ -1,6 +1,7 @@
invoiceOut:
search: Buscar factura emitida
searchInfo: Puedes buscar por referencia de la factura
externalRef: Ref. externa
params:
id: ID
company: Empresa
@ -12,7 +13,6 @@ invoiceOut:
isActive: Activo
hasToInvoice: Debe facturar
hasVerifiedData: Datos verificados
workerName: Comercial
isTaxDataChecked: Datos comprobados
amount: Importe
clientFk: Cliente
@ -26,6 +26,7 @@ invoiceOut:
max: Max
hasPdf: Tiene PDF
search: Contiene
departmentFk: Departamento
card:
issued: Fecha emisión
customerCard: Ficha del cliente

View File

@ -3,6 +3,7 @@ import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'filters/index';
import useNotify from 'src/composables/useNotify.js';
@ -61,6 +62,7 @@ const columns = computed(() => [
columnClass: 'expand',
},
{
align: 'left',
label: t('item.buyRequest.requester'),
name: 'requesterName',
component: 'select',
@ -77,6 +79,19 @@ const columns = computed(() => [
},
columnClass: 'shrink',
},
{
align: 'left',
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Departments',
},
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
label: t('item.buyRequest.requested'),
name: 'quantity',
@ -107,6 +122,7 @@ const columns = computed(() => [
},
columnClass: 'shrink',
},
{
label: t('globals.item'),
name: 'item',
@ -262,6 +278,12 @@ const onDenyAccept = (_, responseData) => {
<WorkerDescriptorProxy :id="row.requesterFk" />
</span>
</template>
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ row.departmentName }}
<DepartmentDescriptorProxy :id="row.departmentFk" />
</span>
</template>
<template #column-item="{ row }">
<span>

View File

@ -31,7 +31,7 @@ function exprBuilder(param, value) {
switch (param) {
case 'clientFk':
return { [`c.id`]: value };
case 'salesPersonFk':
case 'departmentFk':
return { [`c.${param}`]: value };
}
}
@ -62,25 +62,17 @@ const columns = computed(() => [
columnFilter: false,
},
{
label: t('salesClientsTable.salesPerson'),
name: 'salesPersonFk',
field: 'salesPerson',
align: 'left',
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Departments',
},
columnField: {
component: null,
},
optionFilter: 'firstName',
columnFilter: {
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
sortBy: 'nickname ASC',
where: { role: 'salesPerson' },
useLike: false,
},
},
columnClass: 'no-padding',
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
label: t('salesClientsTable.client'),
@ -128,9 +120,9 @@ const columns = computed(() => [
<VnInputDate v-model="to" :label="$t('globals.to')" dense />
</VnRow>
</template>
<template #column-salesPersonFk="{ row }">
<span class="link" :title="row.salesPerson" v-text="row.salesPerson" />
<WorkerDescriptorProxy :id="row.salesPersonFk" dense />
<template #column-departmentFk="{ row }">
<span class="link" :title="row.department" v-text="row.department" />
<WorkerDescriptorProxy :id="row.departmentFk" dense />
</template>
<template #column-clientFk="{ row }">
<span class="link" :title="row.clientName" v-text="row.clientName" />

View File

@ -1,9 +1,9 @@
<script setup>
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import VnTable from 'components/VnTable/VnTable.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import { toDateFormat, toDateTimeFormat } from 'src/filters/date.js';
import { toCurrency } from 'src/filters';
@ -20,8 +20,8 @@ function exprBuilder(param, value) {
switch (param) {
case 'clientFk':
return { [`c.id`]: value };
case 'salesPersonFk':
return { [`c.salesPersonFk`]: value };
case 'departmentFk':
return { [`c.departmentFk`]: value };
}
}
@ -63,20 +63,18 @@ const columns = computed(() => [
columnFilter: false,
},
{
label: t('salesClientsTable.salesPerson'),
name: 'salesPersonFk',
align: 'left',
optionFilter: 'firstName',
columnFilter: {
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
sortBy: 'nickname ASC',
where: { role: 'salesPerson' },
useLike: false,
},
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Departments',
},
create: true,
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
label: t('salesOrdersTable.import'),
@ -184,11 +182,10 @@ const openTab = (id) =>
<CustomerDescriptorProxy :id="row.clientFk" />
</QTd>
</template>
<template #column-salesPersonFk="{ row }">
<template #column-departmentFk="{ row }">
<QTd @click.stop>
<span class="link" v-text="row.salesPerson" />
<WorkerDescriptorProxy :id="row.salesPersonFk" dense />
<span class="link" v-text="row.departmentName" />
<DepartmentDescriptorProxy :id="row.departmentFk" dense />
</QTd>
</template>
</VnTable>

View File

@ -9,7 +9,6 @@ import VnInput from 'src/components/common/VnInput.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import FetchData from 'src/components/FetchData.vue';
import { dateRange } from 'src/filters';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
defineProps({ dataKey: { type: String, required: true } });
const { t, te } = useI18n();
@ -113,16 +112,16 @@ const getLocale = (label) => {
</QItem>
<QItem>
<QItemSection>
<VnSelectWorker
<VnSelect
outlined
dense
rounded
:label="t('globals.params.salesPersonFk')"
v-model="params.salesPersonFk"
:params="{ departmentCodes: ['VT'] }"
:no-one="true"
>
</VnSelectWorker>
:label="t('globals.params.departmentFk')"
v-model="params.departmentFk"
option-value="id"
option-label="name"
url="Departments"
/>
</QItemSection>
</QItem>
<QItem>

View File

@ -2,7 +2,7 @@
import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
@ -49,8 +49,8 @@ function exprBuilder(param, value) {
switch (param) {
case 'stateFk':
return { 'ts.stateFk': value };
case 'salesPersonFk':
return { 'c.salesPersonFk': !value ? null : value };
case 'departmentFk':
return { 'c.departmentFk': !value ? null : value };
case 'provinceFk':
return { 'a.provinceFk': value };
case 'theoreticalHour':
@ -108,19 +108,18 @@ const columns = computed(() => [
},
},
{
label: t('salesClientsTable.salesPerson'),
name: 'salesPersonFk',
field: 'userName',
align: 'left',
columnFilter: {
component: 'select',
attrs: {
url: 'Workers/search?departmentCodes=["VT"]',
fields: ['id', 'name', 'nickname', 'code'],
sortBy: 'nickname ASC',
optionLabel: 'nickname',
},
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Departments',
},
create: true,
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
label: t('salesClientsTable.date'),
@ -437,10 +436,10 @@ const openTab = (id) => useOpenURL(`#/ticket/${id}/sale`);
<CustomerDescriptorProxy :id="row.clientFk" />
</div>
</template>
<template #column-salesPersonFk="{ row }">
<div @click.stop :title="row.userName">
<span class="link" v-text="dashIfEmpty(row.userName)" />
<WorkerDescriptorProxy :id="row.salesPersonFk" />
<template #column-departmentFk="{ row }">
<div @click.stop :title="row.departmentName">
<span class="link" v-text="dashIfEmpty(row.departmentName)" />
<DepartmentDescriptorProxy :id="row.departmentFk" />
</div>
</template>
<template #column-shippedDate="{ row }">

View File

@ -7,7 +7,6 @@ salesClientsTable:
to: To
date: Date
hour: Hour
salesPerson: Salesperson
client: Client
salesOrdersTable:
delete: Delete

View File

@ -7,7 +7,6 @@ salesClientsTable:
to: Hasta
date: Fecha
hour: Hora
salesPerson: Comercial
client: Cliente
salesOrdersTable:
delete: Eliminar

View File

@ -64,17 +64,7 @@ const orderFilter = {
{
relation: 'client',
scope: {
fields: [
'salesPersonFk',
'name',
'isActive',
'isFreezed',
'isTaxDataChecked',
],
include: {
relation: 'salesPersonUser',
scope: { fields: ['id', 'name'] },
},
fields: ['name', 'isActive', 'isFreezed', 'isTaxDataChecked'],
},
},
],
@ -167,7 +157,7 @@ const onClientChange = async (clientId) => {
!data.isConfirmed &&
agencyList?.length &&
agencyList.some(
(agency) => agency.agencyModeFk === data.agency_id
(agency) => agency.agencyModeFk === data.agency_id,
)
? data.agencyModeFk
: null

View File

@ -8,7 +8,7 @@ import filter from './OrderFilter.js';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import FetchData from 'components/FetchData.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
const DEFAULT_ITEMS = 0;
@ -66,11 +66,11 @@ const total = ref(0);
:label="t('globals.state')"
:value="getConfirmationValue(entity.isConfirmed)"
/>
<VnLv :label="t('order.field.salesPersonFk')">
<VnLv :label="t('customer.summary.team')">
<template #value>
<span class="link">
{{ entity?.client?.salesPersonUser?.name || '-' }}
<WorkerDescriptorProxy :id="entity?.client?.salesPersonFk" />
{{ entity?.client?.department?.name || '-' }}
<DepartmentDescriptorProxy :id="entity?.client?.departmentFk" />
</span>
</template>
</VnLv>

View File

@ -10,14 +10,14 @@ export default {
relation: 'client',
scope: {
fields: [
'salesPersonFk',
'departmentFk',
'name',
'isActive',
'isFreezed',
'isTaxDataChecked',
],
include: {
relation: 'salesPersonUser',
relation: 'department',
scope: { fields: ['id', 'name'] },
},
},

View File

@ -6,7 +6,6 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnInput from 'components/common/VnInput.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
const props = defineProps({
@ -62,15 +61,15 @@ const sourceList = ref([]);
outlined
rounded
/>
<VnSelectWorker
:label="t('globals.salesPerson')"
v-model="params.workerFk"
:params="{
departmentCodes: ['VT'],
}"
dense
<VnSelect
outlined
dense
rounded
:label="t('globals.params.departmentFk')"
v-model="params.departmentFk"
option-value="id"
option-label="name"
url="Departments"
/>
<VnInputDate
v-model="params.from"
@ -125,7 +124,6 @@ en:
search: Includes
clientFk: Client
agencyModeFk: Agency
salesPersonFk: Sales Person
from: From
to: To
orderFk: Order
@ -136,7 +134,6 @@ en:
showEmpty: Show Empty
customerId: Customer ID
agency: Agency
salesPerson: Sales Person
fromLanded: From Landed
toLanded: To Landed
orderId: Order ID
@ -149,7 +146,6 @@ es:
search: Búsqueda
clientFk: Cliente
agencyModeFk: Agencia
salesPersonFk: Comercial
from: Desde
to: Hasta
orderFk: Cesta
@ -160,7 +156,6 @@ es:
showEmpty: Mostrar vacías
customerId: ID Cliente
agency: Agencia
salesPerson: Comercial
fromLanded: Desde F. entrega
toLanded: Hasta F. entrega
orderId: ID Cesta

View File

@ -10,12 +10,12 @@ import axios from 'axios';
import OrderSummary from 'pages/Order/Card/OrderSummary.vue';
import OrderFilter from './Card/OrderFilter.vue';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
import VnTable from 'src/components/VnTable/VnTable.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnSection from 'src/components/common/VnSection.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import { getAddresses } from '../Customer/composables/getAddresses';
const { t } = useI18n();
@ -59,22 +59,17 @@ const columns = computed(() => [
},
{
align: 'left',
name: 'salesPersonFk',
label: t('module.salesPerson'),
columnFilter: {
component: 'select',
inWhere: true,
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'salesPerson' },
useLike: false,
optionValue: 'id',
optionLabel: 'name',
optionFilter: 'firstName',
},
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Departments',
},
format: (row) => row?.name,
create: true,
columnField: {
component: null,
},
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'center',
@ -264,10 +259,10 @@ const isDefaultAddress = (opt, data) => {
<CustomerDescriptorProxy :id="row?.clientFk" />
</span>
</template>
<template #column-salesPersonFk="{ row }">
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ row?.name }}
<WorkerDescriptorProxy :id="row?.salesPersonFk" />
{{ row?.departmentName }}
<DepartmentDescriptorProxy :id="row?.departmentFk" />
</span>
</template>
<template #column-landed="{ row }">

View File

@ -8,7 +8,6 @@ module:
hour: Hour
agency: Agency
total: Total
salesPerson: Sales Person
address: Address
cerateOrder: Create order
lines:
@ -22,8 +21,6 @@ lines:
params:
tagGroups: Tags
order:
field:
salesPersonFk: Sales Person
form:
clientFk: Client
addressFk: Address

View File

@ -8,7 +8,6 @@ module:
hour: Hora
agency: Agencia
total: Total
salesPerson: Comercial
address: Dirección
cerateOrder: Crear cesta
lines:
@ -22,8 +21,6 @@ lines:
params:
tagGroups: Tags
order:
field:
salesPersonFk: Comercial
form:
clientFk: Cliente
addressFk: Dirección

View File

@ -2,6 +2,7 @@
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'components/ui/VnFilterPanel.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
const { t } = useI18n();
const props = defineProps({
@ -46,19 +47,7 @@ const emit = defineEmits(['search']);
</QItem>
<QItem class="q-mb-sm">
<QItemSection>
<VnSelect
dense
outlined
rounded
:label="t('params.userFk')"
v-model="params.userFk"
url="Workers/activeWithInheritedRole"
option-value="id"
option-label="firstName"
:where="{ role: 'salesPerson' }"
sort-by="firstName ASC"
:use-like="false"
/>
<VnSelectWorker v-model="params.userFk" outlined rounded />
</QItemSection>
</QItem>
<QItem class="q-mb-md">

View File

@ -44,8 +44,8 @@ const getPriceDifference = async () => {
shipped: ticket.value.shipped,
};
const { data } = await axios.post(
`tickets/${ticket.value.id}/priceDifference`,
params
`tickets/${formData.value.id}/priceDifference`,
params,
);
ticket.value.sale = data;
};
@ -71,8 +71,8 @@ const submit = async () => {
};
const { data } = await axios.post(
`tickets/${ticket.value.id}/componentUpdate`,
params
`tickets/${formData.value.id}/componentUpdate`,
params,
);
if (!data) return;
@ -99,7 +99,7 @@ const onNextStep = async () => {
openConfirmationModal(
t('basicData.negativesConfirmTitle'),
t('basicData.negativesConfirmMessage'),
submitWithNegatives
submitWithNegatives,
);
else submit();
}

View File

@ -3,10 +3,10 @@ import { ref, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import { toDateTimeFormat } from 'src/filters/date';
import filter from './TicketFilter.js';
import FetchData from 'src/components/FetchData.vue';
@ -88,12 +88,12 @@ function getInfo() {
</QBadge>
</template>
</VnLv>
<VnLv :label="t('globals.salesPerson')">
<VnLv :label="t('customer.summary.team')">
<template #value>
<VnUserLink
:name="entity.client?.salesPersonUser?.name"
:worker-id="entity.client?.salesPersonFk"
/>
<span class="link">
{{ entity?.client?.department?.name || '-' }}
<DepartmentDescriptorProxy :id="entity?.client?.departmentFk" />
</span>
</template>
</VnLv>
<VnLv

View File

@ -33,7 +33,7 @@ const save = (sale = $props.sale) => {
};
const getMana = async () => {
const { data } = await axios.get(`Tickets/${route.params.id}/getSalesPersonMana`);
const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`);
mana.value = data;
await getUsesMana();
};

View File

@ -12,7 +12,7 @@ export default {
fields: [
'id',
'name',
'salesPersonFk',
'departmentFk',
'phone',
'mobile',
'email',
@ -29,7 +29,7 @@ export default {
fields: ['id', 'lang'],
},
},
{ relation: 'salesPersonUser' },
{ relation: 'department' },
],
},
},

View File

@ -176,12 +176,10 @@ const getSaleTotal = (sale) => {
const getRowUpdateInputEvents = (sale) => {
return {
'keyup.enter': (evt) => {
console.error(evt);
'keyup.enter': () => {
changeQuantity(sale);
},
blur: (evt) => {
console.error(evt);
blur: () => {
changeQuantity(sale);
},
};
@ -264,6 +262,18 @@ const DEFAULT_EDIT = {
oldQuantity: null,
};
const edit = ref({ ...DEFAULT_EDIT });
const usesMana = ref(null);
const getUsesMana = async () => {
const { data } = await axios.get('Sales/usesMana');
usesMana.value = data;
};
const getMana = async () => {
const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`);
mana.value = data;
await getUsesMana();
};
const selectedValidSales = computed(() => {
if (!sales.value) return;

View File

@ -62,8 +62,6 @@ const isClaimable = computed(() => {
}
return false;
});
const hasReserves = computed(() => props.sales.some((sale) => sale.reserved == true));
const sendSms = async (params) => {
await axios.post(`Tickets/${ticket.value.id}/sendSms`, params);
notify(t('SMS sent'), 'positive');
@ -144,14 +142,6 @@ const onCreateClaimAccepted = async () => {
push({ name: 'ClaimBasicData', params: { id: data.id } });
};
const setReserved = async (reserved) => {
const params = { ticketId: ticket.value.id, sales: props.sales, reserved: reserved };
await axios.post(`Sales/reserve`, params);
props.sales.forEach((sale) => {
sale.reserved = reserved;
});
};
const createRefund = async (withWarehouse) => {
if (!props.ticket) return;
@ -252,18 +242,6 @@ const createRefund = async (withWarehouse) => {
<QItemLabel>{{ t('Mark as reserved') }}</QItemLabel>
</QItemSection>
</QItem>
<QItem
v-if="isTicketEditable && hasReserves"
clickable
v-close-popup
v-ripple
@click="setReserved(false)"
data-cy="unmarkAsReservedItem"
>
<QItemSection>
<QItemLabel>{{ t('Unmark as reserved') }}</QItemLabel>
</QItemSection>
</QItem>
<QItem clickable v-ripple data-cy="ticketSaleRefundItem">
<QItemSection>
<QItemLabel>{{ t('Refund') }}</QItemLabel>

View File

@ -13,9 +13,9 @@ import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import { getUrl } from 'src/composables/getUrl';
import useNotify from 'src/composables/useNotify.js';
import { useArrayData } from 'composables/useArrayData';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import VnTitle from 'src/components/common/VnTitle.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnToSummary from 'src/components/ui/VnToSummary.vue';
@ -152,12 +152,14 @@ onMounted(async () => {
</QBadge>
</template>
</VnLv>
<VnLv :label="t('globals.salesPerson')">
<VnLv :label="t('customer.summary.team')">
<template #value>
<VnUserLink
:name="entity.client?.salesPersonUser?.name"
:worker-id="entity.client?.salesPersonFk"
/>
<span class="link">
{{ entity?.client?.department?.name || '-' }}
<DepartmentDescriptorProxy
:id="entity?.client?.departmentFk"
/>
</span>
</template>
</VnLv>
<VnLv :label="t('globals.agency')" :value="entity.agencyMode?.name" />

View File

@ -259,7 +259,7 @@ const moveTicketsAdvance = async () => {
destinationId: ticket.id,
originShipped: ticket.futureShipped,
destinationShipped: ticket.shipped,
salesPersonFk: ticket.workerFk,
departmentFk: ticket.departmentFk,
});
}
const params = { tickets: ticketsToMove };
@ -285,7 +285,7 @@ const progressAdd = () => {
t('advanceTickets.moveTicketSuccess', {
ticketsNumber: progressLength.value - splitErrors.value.length,
}),
'positive'
'positive',
);
}
};
@ -345,16 +345,16 @@ watch(
originElRef.value.setAttribute('colspan', '9');
destinationElRef.value.textContent = `${t(
'advanceTickets.destination'
'advanceTickets.destination',
)} ${toDateFormat(vnTableRef.value.params.dateToAdvance)}`;
originElRef.value.textContent = `${t('advanceTickets.origin')} ${toDateFormat(
vnTableRef.value.params.dateFuture
vnTableRef.value.params.dateFuture,
)}`;
newRow.append(destinationElRef.value, originElRef.value);
head.insertBefore(newRow, firstRow);
},
{ once: true, inmmediate: true }
{ once: true, inmmediate: true },
);
watch(
@ -362,14 +362,14 @@ watch(
() => {
if (originElRef.value && destinationElRef.value) {
destinationElRef.value.textContent = `${t(
'advanceTickets.destination'
'advanceTickets.destination',
)} ${toDateFormat(vnTableRef.value.params.dateToAdvance)}`;
originElRef.value.textContent = `${t('advanceTickets.origin')} ${toDateFormat(
vnTableRef.value.params.dateFuture
vnTableRef.value.params.dateFuture,
)}`;
}
},
{ deep: true }
{ deep: true },
);
</script>
<template>
@ -405,7 +405,7 @@ watch(
t(`advanceTickets.advanceTitleSubtitle`, {
selectedTickets: selectedTickets.length,
}),
moveTicketsAdvance
moveTicketsAdvance,
)
"
>
@ -423,7 +423,7 @@ watch(
t(`advanceTickets.advanceWithoutNegativeSubtitle`, {
selectedTickets: selectedTickets.length,
}),
splitTickets
splitTickets,
)
"
>

View File

@ -97,15 +97,15 @@ const getGroupedStates = (data) => {
</QItem>
<QItem>
<QItemSection>
<VnSelectWorker
:label="t('globals.salesPerson')"
v-model="params.salesPersonFk"
:params="{
departmentCodes: ['VT'],
}"
dense
<VnSelect
outlined
dense
rounded
:label="t('globals.params.departmentFk')"
v-model="params.departmentFk"
option-value="id"
option-label="name"
url="Departments"
/>
</QItemSection>
</QItem>
@ -308,7 +308,6 @@ en:
from: From
shipped: Shipped
to: To
salesPersonFk: Salesperson
stateFk: State
groupedStates: Grouped State
refFk: Invoice Ref.
@ -336,7 +335,6 @@ es:
from: Desde
shipped: F. envío
to: Hasta
salesPersonFk: Comercial
stateFk: Estado
groupedStates: Estado agrupado
refFk: Ref. Factura
@ -355,7 +353,6 @@ es:
Order ID: ID Pedido
From: Desde
To: Hasta
Salesperson: Comercial
State: Estado
Invoice Ref.: Ref. Factura
My team: Mi equipo

View File

@ -160,7 +160,7 @@ const moveTicketsFuture = async () => {
destinationId: ticket.futureId,
originShipped: ticket.shipped,
destinationShipped: ticket.futureShipped,
salesPersonFk: ticket.salesPersonFk,
departmentFk: ticket.departmentFk,
};
});

View File

@ -17,6 +17,7 @@ import TicketFilter from './TicketFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
import FetchData from 'src/components/FetchData.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
import { toTimeFormat } from 'src/filters/date';
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
@ -99,22 +100,16 @@ const columns = computed(() => [
},
{
align: 'left',
label: t('ticketList.salesPerson'),
name: 'salesPersonFk',
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'salesPerson' },
optionFilter: 'firstName',
useLike: false,
url: 'Departments',
},
columnField: {
component: null,
},
columnClass: 'expand',
cardVisible: true,
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'left',
@ -519,10 +514,10 @@ function setReference(data) {
<template #column-statusIcons="{ row }">
<TicketProblems :row="row" />
</template>
<template #column-salesPersonFk="{ row }">
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ dashIfEmpty(row.userName) }}
<CustomerDescriptorProxy :id="row.salesPersonFk" />
{{ dashIfEmpty(row.departmentName) }}
<DepartmentDescriptorProxy :id="row.departmentFk" />
</span>
</template>
<template #column-shippedDate="{ row }">

View File

@ -5,7 +5,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import VnSelectCache from 'src/components/common/VnSelectCache.vue';
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
import { useStateStore } from 'stores/useStateStore';
import { useVnConfirm } from 'composables/useVnConfirm';
@ -112,23 +112,17 @@ const columns = computed(() => [
},
{
align: 'left',
name: 'id',
label: t('weeklyTickets.salesperson'),
columnFilter: {
component: 'select',
alias: 'u',
attrs: {
url: 'Workers/activeWithInheritedRole',
fields: ['id', 'name'],
where: { role: 'salesperson' },
},
inWhere: true,
name: 'departmentFk',
label: t('customer.summary.team'),
component: 'select',
attrs: {
url: 'Departments',
},
create: true,
columnField: {
component: null,
},
cardVisible: true,
format: (row) => row.userName,
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
},
{
align: 'right',
@ -142,9 +136,9 @@ const columns = computed(() => [
openConfirmationModal(
t('You are going to delete this weekly ticket'),
t(
'This ticket will be removed from weekly tickets! Continue anyway?'
'This ticket will be removed from weekly tickets! Continue anyway?',
),
() => deleteWeekly(row.ticketFk)
() => deleteWeekly(row.ticketFk),
),
isPrimary: true,
},
@ -219,10 +213,10 @@ onMounted(async () => {
<CustomerDescriptorProxy :id="row.clientFk" />
</span>
</template>
<template #column-id="{ row }">
<template #column-departmentFk="{ row }">
<span class="link" @click.stop>
{{ row.userName }}
<WorkerDescriptorProxy :id="row.workerFk" />
{{ row.departmentName }}
<DepartmentDescriptorProxy :id="row.departmentFk" />
</span>
</template>
</VnTable>

View File

@ -136,7 +136,6 @@ purchaseRequest:
weeklyTickets:
id: Ticket ID
shipment: Shipment
salesperson: Salesperson
search: Search weekly tickets
searchInfo: Search weekly tickets by id or client id
ticketSaleTracking:
@ -172,7 +171,7 @@ tracking:
addState: Add state
package:
package: Package
added: Added
added: D. Added
addPackage: Add package
removePackage: Remove package
ticketList:
@ -181,7 +180,6 @@ ticketList:
state: State
shipped: Shipped
zone: Zone
salesPerson: Sales person
totalWithVat: Total with VAT
summary: Summary
client: Customer

View File

@ -58,7 +58,6 @@ basicData:
weeklyTickets:
id: ID Ticket
shipment: Salida
salesperson: Comercial
search: Buscar por tickets programados
searchInfo: Buscar tickets programados por el identificador o el identificador del cliente
advanceTickets:
@ -162,7 +161,7 @@ expedition:
removeExpedition: Eliminar expedición
package:
package: Embalaje
added: Añadido
added: F. Creacion
addPackage: Añadir embalaje
removePackage: Quitar embalaje
ticketSaleTracking:
@ -186,7 +185,6 @@ ticketList:
state: Estado
shipped: F. Envío
zone: Zona
salesPerson: Comercial
totalWithVat: Total con IVA
summary: Resumen
client: Cliente

View File

@ -121,7 +121,7 @@ const handlePhotoUpdated = (evt = false) => {
:value="entity.user?.emailUser?.email"
copy
/>
<VnLv :label="t('worker.list.department')">
<VnLv :label="t('globals.department')">
<template #value>
<span class="link" v-text="entity.department?.department?.name" />
<DepartmentDescriptorProxy :id="entity.department?.department?.id" />

View File

@ -50,7 +50,7 @@ onBeforeMount(async () => {
<QCard class="vn-one">
<VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" />
<VnLv :label="t('globals.name')" :value="worker.user?.nickname" />
<VnLv :label="t('worker.list.department')">
<VnLv :label="t('globals.department')">
<template #value>
<span class="link" v-text="worker.department?.department?.name" />
<DepartmentDescriptorProxy

View File

@ -4,8 +4,8 @@ const customerCard = {
name: 'CustomerCard',
path: ':id',
component: () => import('src/pages/Customer/Card/CustomerCard.vue'),
redirect: { name: 'CustomerSummary' },
meta: {
redirect: { name: 'CustomerSummary' },
meta: {
menu: [
'CustomerBasicData',
'CustomerFiscalData',
@ -40,8 +40,7 @@ const customerCard = {
title: 'basicData',
icon: 'vn:settings',
},
component: () =>
import('src/pages/Customer/Card/CustomerBasicData.vue'),
component: () => import('src/pages/Customer/Card/CustomerBasicData.vue'),
},
{
path: 'fiscal-data',
@ -50,8 +49,7 @@ const customerCard = {
title: 'fiscalData',
icon: 'vn:dfiscales',
},
component: () =>
import('src/pages/Customer/Card/CustomerFiscalData.vue'),
component: () => import('src/pages/Customer/Card/CustomerFiscalData.vue'),
},
{
path: 'billing-data',
@ -60,8 +58,7 @@ const customerCard = {
title: 'billingData',
icon: 'vn:payment',
},
component: () =>
import('src/pages/Customer/Card/CustomerBillingData.vue'),
component: () => import('src/pages/Customer/Card/CustomerBillingData.vue'),
},
{
path: 'address',
@ -85,9 +82,7 @@ const customerCard = {
title: 'address-create',
},
component: () =>
import(
'src/pages/Customer/components/CustomerAddressCreate.vue'
),
import('src/pages/Customer/components/CustomerAddressCreate.vue'),
},
{
path: ':addressId',
@ -125,8 +120,7 @@ const customerCard = {
title: 'credits',
icon: 'vn:credit',
},
component: () =>
import('src/pages/Customer/Card/CustomerCredits.vue'),
component: () => import('src/pages/Customer/Card/CustomerCredits.vue'),
},
{
path: 'greuges',
@ -135,8 +129,7 @@ const customerCard = {
title: 'greuges',
icon: 'vn:greuge',
},
component: () =>
import('src/pages/Customer/Card/CustomerGreuges.vue'),
component: () => import('src/pages/Customer/Card/CustomerGreuges.vue'),
},
{
path: 'balance',
@ -145,8 +138,7 @@ const customerCard = {
title: 'balance',
icon: 'balance',
},
component: () =>
import('src/pages/Customer/Card/CustomerBalance.vue'),
component: () => import('src/pages/Customer/Card/CustomerBalance.vue'),
},
{
path: 'recoveries',
@ -155,8 +147,7 @@ const customerCard = {
title: 'recoveries',
icon: 'vn:recovery',
},
component: () =>
import('src/pages/Customer/Card/CustomerRecoveries.vue'),
component: () => import('src/pages/Customer/Card/CustomerRecoveries.vue'),
},
{
path: 'web-access',
@ -165,8 +156,7 @@ const customerCard = {
title: 'webAccess',
icon: 'vn:web',
},
component: () =>
import('src/pages/Customer/Card/CustomerWebAccess.vue'),
component: () => import('src/pages/Customer/Card/CustomerWebAccess.vue'),
},
{
path: 'log',
@ -247,9 +237,7 @@ const customerCard = {
title: 'creditOpinion',
},
component: () =>
import(
'src/pages/Customer/Card/CustomerCreditOpinion.vue'
),
import('src/pages/Customer/Card/CustomerCreditOpinion.vue'),
},
],
},
@ -319,9 +307,7 @@ const customerCard = {
title: 'samples',
},
component: () =>
import(
'src/pages/Customer/Card/CustomerSamples.vue'
),
import('src/pages/Customer/Card/CustomerSamples.vue'),
},
{
path: 'create',
@ -376,9 +362,7 @@ const customerCard = {
title: 'fileManagement',
},
component: () =>
import(
'src/pages/Customer/Card/CustomerFileManagement.vue'
),
import('src/pages/Customer/Card/CustomerFileManagement.vue'),
},
{
path: 'file-management',
@ -420,8 +404,7 @@ const customerCard = {
meta: {
title: 'unpaid',
},
component: () =>
import('src/pages/Customer/Card/CustomerUnpaid.vue'),
component: () => import('src/pages/Customer/Card/CustomerUnpaid.vue'),
},
],
},
@ -429,7 +412,7 @@ const customerCard = {
};
export default {
name: 'Customer',
name: 'Customer',
path: '/customer',
meta: {
title: 'customers',
@ -469,15 +452,6 @@ export default {
customerCard,
],
},
{
path: 'create',
name: 'CustomerCreate',
meta: {
title: 'customerCreate',
icon: 'add',
},
component: () => import('src/pages/Customer/CustomerCreate.vue'),
},
{
path: 'payments',
name: 'CustomerPayments',

View File

@ -1,5 +1,5 @@
/// <reference types="cypress" />
describe('ClaimAction', () => {
describe.skip('ClaimAction', () => {
const claimId = 1;
const firstRow = 'tbody > :nth-child(1)';

View File

@ -1,5 +1,5 @@
/// <reference types="cypress" />
describe('ClaimPhoto', () => {
describe.skip('ClaimPhoto', () => {
const carrouselClose =
'.q-dialog__inner > .q-toolbar > .q-btn > .q-btn__content > .q-icon';
beforeEach(() => {

View File

@ -1,5 +1,5 @@
/// <reference types="cypress" />
describe('Client list', () => {
describe.skip('Client list', () => {
beforeEach(() => {
cy.login('developer');
cy.visit('/#/customer/list', {
@ -25,7 +25,7 @@ describe('Client list', () => {
'Web user': { val: `user_test_${randomInt}` },
Street: { val: `C/ STREET ${randomInt}` },
Email: { val: `user.test${randomInt}@cypress.com` },
'Sales person': { val: 'salesPerson', type: 'select' },
Team: { val: 'Informatica', type: 'select' },
Location: { val: '46000', type: 'select' },
'Business type': { val: 'others', type: 'select' },
};

View File

@ -16,9 +16,9 @@ describe('InvoiceOut negative bases', () => {
cy.get(getDescriptors('ticketFk')).click();
cy.get('.descriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('include.text', '23');
cy.get(getDescriptors('workerName')).click();
cy.get(getDescriptors('departmentFk')).click();
cy.get('.descriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('include.text', '18');
cy.get('.q-item > .q-item__label').should('include.text', '155');
});
it('should filter and download as CSV', () => {

View File

@ -12,7 +12,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
'Invalid username or password'
'Invalid username or password',
);
});
@ -23,7 +23,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
'Invalid username or password'
'Invalid username or password',
);
});
@ -33,7 +33,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
'You have successfully logged in'
'You have successfully logged in',
);
cy.url().should('contain', '/dashboard');
});
@ -44,7 +44,7 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.get('.q-notification__message').should(
'have.text',
'You have successfully logged in'
'You have successfully logged in',
);
cy.url().should('contain', '/dashboard');
cy.get('#user').click();
@ -61,14 +61,4 @@ describe('Login', () => {
cy.get('button[type="submit"]').click();
cy.url().should('contain', '/dashboard');
});
// ticket creation is not yet implemented, use this test once it is
// it(`should get redirected to ticket creation after login since salesPerson can do it`, () => {
// cy.visit('/#/ticket/create', { failOnStatusCode: false });
// cy.url().should('contain', '/#/login?redirect=/ticket/create');
// cy.get('input[aria-label="Username"]').type('salesPerson');
// cy.get('input[aria-label="Password"]').type('nightmare');
// cy.get('button[type="submit"]').click();
// cy.url().should('contain', '/#/ticket/create');
// })
});

View File

@ -24,12 +24,21 @@ describe('Logout', () => {
},
},
statusMessage: 'AUTHORIZATION_REQUIRED',
});
}).as('badRequest');
});
it('when token not exists', () => {
const exceptionHandler = (err) => {
if (err.code === 'AUTHORIZATION_REQUIRED') return;
};
Cypress.on('uncaught:exception', exceptionHandler);
cy.get('.q-list').first().should('be.visible').click();
cy.wait('@badRequest');
cy.checkNotification('Authorization Required');
Cypress.off('uncaught:exception', exceptionHandler);
});
});
});

View File

@ -1,4 +1,4 @@
describe('AgencyWorkCenter', () => {
describe.skip('AgencyWorkCenter', () => {
const selectors = {
workCenter: 'workCenter_select',
popupSave: 'FormModelPopup_save',

View File

@ -1,4 +1,4 @@
describe('RouteAutonomous', () => {
describe.skip('RouteAutonomous', () => {
const getLinkSelector = (colField) =>
`tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`;

View File

@ -23,7 +23,7 @@ describe('TicketSale', () => {
cy.get('[data-col-field="price"]')
.find('.q-btn > .q-btn__content')
.should('have.text', `${price}`);
.should('contain.text', `${price}`);
});
it('update discount', () => {
const discount = Math.floor(Math.random() * 100) + 1;
@ -152,22 +152,6 @@ describe('TicketSale', () => {
cy.checkNotification('Future ticket date not allowed');
});
it('marks row as reserved', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="markAsReservedItem"]');
cy.dataCy('markAsReservedItem').click();
cy.dataCy('ticketSaleReservedIcon').should('exist');
});
it('unmarks row as reserved', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="unmarkAsReservedItem"]');
cy.dataCy('unmarkAsReservedItem').click();
cy.dataCy('ticketSaleReservedIcon').should('not.exist');
});
it('refunds row with warehouse', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();

View File

@ -1,24 +1,39 @@
#!/bin/bash
salix_dir="${1:-$HOME/Projects/salix}"
salix_dir=$(eval echo "$salix_dir")
echo "$salix_dir"
current_dir=$(pwd)
cleanup() {
if [[ -z "$ended" ]]; then
ended=true
docker-compose -p e2e --project-directory . -f test/cypress/docker-compose.yml down -v
fi
docker-compose -p e2e --project-directory . -f test/cypress/docker-compose.yml down -v
}
trap cleanup SIGINT
#CLEAN
# CLEAN
rm -rf test/cypress/screenshots
rm -f test/cypress/results/*
rm -f test/cypress/reports/*
rm -f junit/e2e-*.xml
#RUN
# RUN
export CI=true
export TZ=Europe/Madrid
# IMAGES
docker build -t registry.verdnatura.es/salix-back:dev -f "$salix_dir/back/Dockerfile" "$salix_dir"
cd "$salix_dir" && npx myt run -t
docker exec vn-database sh -c "rm -rf /mysql-template"
docker exec vn-database sh -c "cp -a /var/lib/mysql /mysql-template"
docker commit vn-database registry.verdnatura.es/salix-db:dev
docker rm -f vn-database
cd "$current_dir"
docker build -f ./docs/Dockerfile.dev -t lilium-dev .
# END IMAGES
docker-compose -p e2e --project-directory . -f test/cypress/docker-compose.yml up -d
docker run -it --rm \

View File

@ -40,6 +40,11 @@ style.innerHTML = `
`;
document.head.appendChild(style);
// FIXME: https://redmine.verdnatura.es/issues/8771
Cypress.on('uncaught:exception', (err) => {
if (err.code === 'ERR_CANCELED') return false;
});
const waitForApiReady = (url, maxRetries = 20, delay = 1000) => {
let retries = 0;