Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix-front into Warmfix-DepartmentIcon
gitea/salix-front/pipeline/pr-test There was a failure building this commit
Details
gitea/salix-front/pipeline/pr-test There was a failure building this commit
Details
This commit is contained in:
commit
fb912725b3
|
@ -31,6 +31,7 @@ yarn-error.log*
|
||||||
# Cypress directories and files
|
# Cypress directories and files
|
||||||
/test/cypress/videos
|
/test/cypress/videos
|
||||||
/test/cypress/screenshots
|
/test/cypress/screenshots
|
||||||
|
/junit
|
||||||
|
|
||||||
# VitePress directories and files
|
# VitePress directories and files
|
||||||
/docs/.vitepress/cache
|
/docs/.vitepress/cache
|
||||||
|
|
|
@ -114,15 +114,18 @@ pipeline {
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
script {
|
||||||
sh 'rm junit/e2e-*.xml || true'
|
sh 'rm -f junit/e2e-*.xml'
|
||||||
env.COMPOSE_TAG = PROTECTED_BRANCH.contains(env.CHANGE_TARGET) ? env.CHANGE_TARGET : 'dev'
|
env.COMPOSE_TAG = PROTECTED_BRANCH.contains(env.CHANGE_TARGET) ? env.CHANGE_TARGET : 'dev'
|
||||||
|
|
||||||
|
def image = docker.build('lilium-dev', '-f docs/Dockerfile.dev docs')
|
||||||
|
|
||||||
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
|
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"
|
sh "docker-compose ${env.COMPOSE_PARAMS} up -d"
|
||||||
|
|
||||||
def image = docker.build('lilium-dev', '-f docs/Dockerfile.dev docs')
|
|
||||||
image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") {
|
image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") {
|
||||||
sh 'cypress run --browser chromium || true'
|
sh 'sh test/cypress/cypressParallel.sh 2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
README.md
12
README.md
|
@ -32,6 +32,18 @@ pnpm run test:front
|
||||||
pnpm run test:e2e
|
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
|
### Build the app for production
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import { defineConfig } from 'cypress';
|
import { defineConfig } from 'cypress';
|
||||||
|
|
||||||
let urlHost, reporter, reporterOptions;
|
let urlHost, reporter, reporterOptions, timeouts;
|
||||||
|
|
||||||
if (process.env.CI) {
|
if (process.env.CI) {
|
||||||
urlHost = 'front';
|
urlHost = 'front';
|
||||||
reporter = 'junit';
|
reporter = 'junit';
|
||||||
reporterOptions = {
|
reporterOptions = {
|
||||||
mochaFile: 'junit/e2e-[hash].xml',
|
mochaFile: 'junit/e2e-[hash].xml',
|
||||||
toConsole: false,
|
};
|
||||||
|
timeouts = {
|
||||||
|
defaultCommandTimeout: 30000,
|
||||||
|
requestTimeout: 30000,
|
||||||
|
responseTimeout: 60000,
|
||||||
|
pageLoadTimeout: 60000,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
urlHost = 'localhost';
|
urlHost = 'localhost';
|
||||||
|
@ -20,17 +25,19 @@ if (process.env.CI) {
|
||||||
reportDir: 'test/cypress/reports',
|
reportDir: 'test/cypress/reports',
|
||||||
inlineAssets: true,
|
inlineAssets: true,
|
||||||
};
|
};
|
||||||
|
timeouts = {
|
||||||
|
defaultCommandTimeout: 10000,
|
||||||
|
requestTimeout: 10000,
|
||||||
|
responseTimeout: 30000,
|
||||||
|
pageLoadTimeout: 60000,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
e2e: {
|
e2e: {
|
||||||
baseUrl: `http://${urlHost}:9000`,
|
baseUrl: `http://${urlHost}:9000`,
|
||||||
experimentalStudio: false,
|
experimentalStudio: false,
|
||||||
defaultCommandTimeout: 10000,
|
|
||||||
trashAssetsBeforeRuns: false,
|
trashAssetsBeforeRuns: false,
|
||||||
requestTimeout: 10000,
|
|
||||||
responseTimeout: 30000,
|
|
||||||
pageLoadTimeout: 60000,
|
|
||||||
defaultBrowser: 'chromium',
|
defaultBrowser: 'chromium',
|
||||||
fixturesFolder: 'test/cypress/fixtures',
|
fixturesFolder: 'test/cypress/fixtures',
|
||||||
screenshotsFolder: 'test/cypress/screenshots',
|
screenshotsFolder: 'test/cypress/screenshots',
|
||||||
|
@ -50,8 +57,8 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
viewportWidth: 1280,
|
viewportWidth: 1280,
|
||||||
viewportHeight: 720,
|
viewportHeight: 720,
|
||||||
|
...timeouts,
|
||||||
|
includeShadowDom: true,
|
||||||
|
waitForAnimations: true,
|
||||||
},
|
},
|
||||||
experimentalMemoryManagement: true,
|
|
||||||
defaultCommandTimeout: 10000,
|
|
||||||
numTestsKeptInMemory: 2,
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "25.10.0",
|
"version": "25.12.0",
|
||||||
"description": "Salix frontend",
|
"description": "Salix frontend",
|
||||||
"productName": "Salix",
|
"productName": "Salix",
|
||||||
"author": "Verdnatura",
|
"author": "Verdnatura",
|
||||||
|
@ -13,6 +13,8 @@
|
||||||
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
||||||
"test:e2e": "cypress open",
|
"test:e2e": "cypress open",
|
||||||
"test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
|
"test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
|
||||||
|
"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": "echo \"See package.json => scripts for available tests.\" && exit 0",
|
||||||
"test:front": "vitest",
|
"test:front": "vitest",
|
||||||
"test:front:ci": "vitest run",
|
"test:front:ci": "vitest run",
|
||||||
|
@ -54,11 +56,14 @@
|
||||||
"eslint-plugin-cypress": "^4.1.0",
|
"eslint-plugin-cypress": "^4.1.0",
|
||||||
"eslint-plugin-vue": "^9.32.0",
|
"eslint-plugin-vue": "^9.32.0",
|
||||||
"husky": "^8.0.0",
|
"husky": "^8.0.0",
|
||||||
|
"junit-merge": "^2.0.0",
|
||||||
|
"mocha": "^11.1.0",
|
||||||
"postcss": "^8.4.23",
|
"postcss": "^8.4.23",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.4.2",
|
||||||
"sass": "^1.83.4",
|
"sass": "^1.83.4",
|
||||||
"vitepress": "^1.6.3",
|
"vitepress": "^1.6.3",
|
||||||
"vitest": "^0.34.0"
|
"vitest": "^0.34.0",
|
||||||
|
"xunit-viewer": "^10.6.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20 || ^18 || ^16",
|
"node": "^20 || ^18 || ^16",
|
||||||
|
|
2070
pnpm-lock.yaml
2070
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -181,9 +181,8 @@ async function saveChanges(data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let changes = data || getChanges();
|
let changes = data || getChanges();
|
||||||
if ($props.beforeSaveFn) {
|
if ($props.beforeSaveFn) changes = await $props.beforeSaveFn(changes, getChanges);
|
||||||
changes = await $props.beforeSaveFn(changes, getChanges);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (changes?.creates?.length === 0 && changes?.updates?.length === 0) {
|
if (changes?.creates?.length === 0 && changes?.updates?.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -194,7 +193,7 @@ async function saveChanges(data) {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
originalData.value = JSON.parse(JSON.stringify(formData.value));
|
||||||
if (changes.creates?.length) await vnPaginateRef.value.fetch();
|
if (changes?.creates?.length) await vnPaginateRef.value.fetch();
|
||||||
|
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
emit('saveChanges', data);
|
emit('saveChanges', data);
|
||||||
|
|
|
@ -188,7 +188,7 @@ const selectItem = ({ id }) => {
|
||||||
>
|
>
|
||||||
<template #body-cell-id="{ row }">
|
<template #body-cell-id="{ row }">
|
||||||
<QTd auto-width @click.stop>
|
<QTd auto-width @click.stop>
|
||||||
<QBtn flat color="blue">{{ row.id }}</QBtn>
|
<QBtn flat class="link">{{ row.id }}</QBtn>
|
||||||
<ItemDescriptorProxy :id="row.id" />
|
<ItemDescriptorProxy :id="row.id" />
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -196,7 +196,7 @@ const selectTravel = ({ id }) => {
|
||||||
>
|
>
|
||||||
<template #body-cell-id="{ row }">
|
<template #body-cell-id="{ row }">
|
||||||
<QTd auto-width @click.stop data-cy="travelFk-travel-form">
|
<QTd auto-width @click.stop data-cy="travelFk-travel-form">
|
||||||
<QBtn flat color="blue">{{ row.id }}</QBtn>
|
<QBtn flat class="link">{{ row.id }}</QBtn>
|
||||||
<TravelDescriptorProxy :id="row.id" />
|
<TravelDescriptorProxy :id="row.id" />
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -77,6 +77,7 @@ watch(
|
||||||
function findMatches(search, item) {
|
function findMatches(search, item) {
|
||||||
const matches = [];
|
const matches = [];
|
||||||
function findRoute(search, item) {
|
function findRoute(search, item) {
|
||||||
|
if (!item?.children) return;
|
||||||
for (const child of item.children) {
|
for (const child of item.children) {
|
||||||
if (search?.indexOf(child.name) > -1) {
|
if (search?.indexOf(child.name) > -1) {
|
||||||
matches.push(child);
|
matches.push(child);
|
||||||
|
@ -92,7 +93,7 @@ function findMatches(search, item) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addChildren(module, route, parent) {
|
function addChildren(module, route, parent) {
|
||||||
const menus = route?.meta?.menu ?? route?.menus?.[props.source]; //backwards compatible
|
const menus = route?.meta?.menu;
|
||||||
if (!menus) return;
|
if (!menus) return;
|
||||||
|
|
||||||
const matches = findMatches(menus, route);
|
const matches = findMatches(menus, route);
|
||||||
|
@ -107,11 +108,7 @@ function getRoutes() {
|
||||||
main: getMainRoutes,
|
main: getMainRoutes,
|
||||||
card: getCardRoutes,
|
card: getCardRoutes,
|
||||||
};
|
};
|
||||||
try {
|
|
||||||
handleRoutes[props.source]();
|
handleRoutes[props.source]();
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`Method is not defined`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function getMainRoutes() {
|
function getMainRoutes() {
|
||||||
const modules = Object.assign([], navigation.getModules().value);
|
const modules = Object.assign([], navigation.getModules().value);
|
||||||
|
@ -122,7 +119,6 @@ function getMainRoutes() {
|
||||||
);
|
);
|
||||||
if (!moduleDef) continue;
|
if (!moduleDef) continue;
|
||||||
item.children = [];
|
item.children = [];
|
||||||
|
|
||||||
addChildren(item.module, moduleDef, item.children);
|
addChildren(item.module, moduleDef, item.children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,21 +128,16 @@ function getMainRoutes() {
|
||||||
function getCardRoutes() {
|
function getCardRoutes() {
|
||||||
const currentRoute = route.matched[1];
|
const currentRoute = route.matched[1];
|
||||||
const currentModule = toLowerCamel(currentRoute.name);
|
const currentModule = toLowerCamel(currentRoute.name);
|
||||||
let moduleDef = routes.find((route) => toLowerCamel(route.name) === currentModule);
|
let moduleDef;
|
||||||
|
|
||||||
if (!moduleDef) return;
|
|
||||||
if (!moduleDef?.menus) moduleDef = betaGetRoutes();
|
|
||||||
addChildren(currentModule, moduleDef, items.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function betaGetRoutes() {
|
|
||||||
let menuRoute;
|
|
||||||
let index = route.matched.length - 1;
|
let index = route.matched.length - 1;
|
||||||
while (!menuRoute && index > 0) {
|
while (!moduleDef && index > 0) {
|
||||||
if (route.matched[index]?.meta?.menu) menuRoute = route.matched[index];
|
if (route.matched[index]?.meta?.menu) moduleDef = route.matched[index];
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
return menuRoute;
|
|
||||||
|
if (!moduleDef) return;
|
||||||
|
addChildren(currentModule, moduleDef, items.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function togglePinned(item, event) {
|
async function togglePinned(item, event) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ const refresh = () => window.location.reload();
|
||||||
:class="{
|
:class="{
|
||||||
'no-visible': !stateQuery.isLoading().value,
|
'no-visible': !stateQuery.isLoading().value,
|
||||||
}"
|
}"
|
||||||
size="xs"
|
size="sm"
|
||||||
data-cy="loading-spinner"
|
data-cy="loading-spinner"
|
||||||
/>
|
/>
|
||||||
<QSpace />
|
<QSpace />
|
||||||
|
|
|
@ -12,7 +12,7 @@ defineProps({ row: { type: Object, required: true } });
|
||||||
>
|
>
|
||||||
<QIcon name="vn:claims" size="xs">
|
<QIcon name="vn:claims" size="xs">
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('ticketSale.claim') }}:
|
{{ $t('ticketSale.claim') }}:
|
||||||
{{ row.claim?.claimFk }}
|
{{ row.claim?.claimFk }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
|
|
|
@ -87,7 +87,7 @@ const makeInvoice = async () => {
|
||||||
(data) => (
|
(data) => (
|
||||||
(rectificativeTypeOptions = data),
|
(rectificativeTypeOptions = data),
|
||||||
(transferInvoiceParams.cplusRectificationTypeFk = data.filter(
|
(transferInvoiceParams.cplusRectificationTypeFk = data.filter(
|
||||||
(type) => type.description == 'I – Por diferencias'
|
(type) => type.description == 'I – Por diferencias',
|
||||||
)[0].id)
|
)[0].id)
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
@ -100,7 +100,7 @@ const makeInvoice = async () => {
|
||||||
(data) => (
|
(data) => (
|
||||||
(siiTypeInvoiceOutsOptions = data),
|
(siiTypeInvoiceOutsOptions = data),
|
||||||
(transferInvoiceParams.siiTypeInvoiceOutFk = data.filter(
|
(transferInvoiceParams.siiTypeInvoiceOutFk = data.filter(
|
||||||
(type) => type.code == 'R4'
|
(type) => type.code == 'R4',
|
||||||
)[0].id)
|
)[0].id)
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
@ -122,7 +122,6 @@ const makeInvoice = async () => {
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Client')"
|
:label="t('Client')"
|
||||||
:options="clientsOptions"
|
|
||||||
hide-selected
|
hide-selected
|
||||||
option-label="name"
|
option-label="name"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
|
|
@ -595,8 +595,7 @@ function cardClick(_, row) {
|
||||||
|
|
||||||
function removeTextValue(data, getChanges) {
|
function removeTextValue(data, getChanges) {
|
||||||
let changes = data.updates;
|
let changes = data.updates;
|
||||||
if (!changes) return data;
|
if (changes) {
|
||||||
|
|
||||||
for (const change of changes) {
|
for (const change of changes) {
|
||||||
for (const key in change.data) {
|
for (const key in change.data) {
|
||||||
if (key.endsWith('VnTableTextValue')) {
|
if (key.endsWith('VnTableTextValue')) {
|
||||||
|
@ -606,7 +605,7 @@ function removeTextValue(data, getChanges) {
|
||||||
}
|
}
|
||||||
|
|
||||||
data.updates = changes.filter((change) => Object.keys(change.data).length > 0);
|
data.updates = changes.filter((change) => Object.keys(change.data).length > 0);
|
||||||
|
}
|
||||||
if ($attrs?.beforeSaveFn) data = $attrs.beforeSaveFn(data, getChanges);
|
if ($attrs?.beforeSaveFn) data = $attrs.beforeSaveFn(data, getChanges);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -776,7 +775,7 @@ const rowCtrlClickFunction = computed(() => {
|
||||||
:data-col-field="col?.name"
|
:data-col-field="col?.name"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="no-padding no-margin peter"
|
class="no-padding no-margin"
|
||||||
style="
|
style="
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -978,6 +977,8 @@ const rowCtrlClickFunction = computed(() => {
|
||||||
v-for="col of cols.filter((cols) => cols.visible ?? true)"
|
v-for="col of cols.filter((cols) => cols.visible ?? true)"
|
||||||
:key="col?.id"
|
:key="col?.id"
|
||||||
:class="getColAlign(col)"
|
:class="getColAlign(col)"
|
||||||
|
:style="col?.width ? `max-width: ${col?.width}` : ''"
|
||||||
|
style="font-size: small"
|
||||||
>
|
>
|
||||||
<slot
|
<slot
|
||||||
:name="`column-footer-${col.name}`"
|
:name="`column-footer-${col.name}`"
|
||||||
|
@ -1040,6 +1041,7 @@ const rowCtrlClickFunction = computed(() => {
|
||||||
@on-data-saved="(_, res) => createForm.onDataSaved(res)"
|
@on-data-saved="(_, res) => createForm.onDataSaved(res)"
|
||||||
>
|
>
|
||||||
<template #form-inputs="{ data }">
|
<template #form-inputs="{ data }">
|
||||||
|
<slot name="alter-create" :data="data">
|
||||||
<div :style="createComplement?.containerStyle">
|
<div :style="createComplement?.containerStyle">
|
||||||
<div
|
<div
|
||||||
:style="createComplement?.previousStyle"
|
:style="createComplement?.previousStyle"
|
||||||
|
@ -1047,7 +1049,10 @@ const rowCtrlClickFunction = computed(() => {
|
||||||
>
|
>
|
||||||
<slot name="previous-create-dialog" :data="data" />
|
<slot name="previous-create-dialog" :data="data" />
|
||||||
</div>
|
</div>
|
||||||
<div class="grid-create" :style="createComplement?.columnGridStyle">
|
<div
|
||||||
|
class="grid-create"
|
||||||
|
:style="createComplement?.columnGridStyle"
|
||||||
|
>
|
||||||
<slot
|
<slot
|
||||||
v-for="column of splittedColumns.create"
|
v-for="column of splittedColumns.create"
|
||||||
:key="column.name"
|
:key="column.name"
|
||||||
|
@ -1059,7 +1064,7 @@ const rowCtrlClickFunction = computed(() => {
|
||||||
<VnColumn
|
<VnColumn
|
||||||
:column="{
|
:column="{
|
||||||
...column,
|
...column,
|
||||||
...{ disable: column?.createDisable ?? false },
|
...column?.createAttrs,
|
||||||
}"
|
}"
|
||||||
:row="{}"
|
:row="{}"
|
||||||
default="input"
|
default="input"
|
||||||
|
@ -1072,6 +1077,7 @@ const rowCtrlClickFunction = computed(() => {
|
||||||
<slot name="more-create-dialog" :data="data" />
|
<slot name="more-create-dialog" :data="data" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
</FormModelPopup>
|
</FormModelPopup>
|
||||||
</QDialog>
|
</QDialog>
|
||||||
|
@ -1148,9 +1154,13 @@ es:
|
||||||
|
|
||||||
.grid-create {
|
.grid-create {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(150px, max-content));
|
grid-template-columns: 1fr 1fr;
|
||||||
|
max-width: 100%;
|
||||||
grid-gap: 20px;
|
grid-gap: 20px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
.col-span-2 {
|
||||||
|
grid-column: span 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-one {
|
.flex-one {
|
||||||
|
|
|
@ -15,10 +15,7 @@ vi.mock('src/router/modules', () => ({
|
||||||
meta: {
|
meta: {
|
||||||
title: 'customers',
|
title: 'customers',
|
||||||
icon: 'vn:client',
|
icon: 'vn:client',
|
||||||
},
|
menu: ['CustomerList', 'CustomerCreate'],
|
||||||
menus: {
|
|
||||||
main: ['CustomerList', 'CustomerCreate'],
|
|
||||||
card: ['CustomerBasicData'],
|
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -50,14 +47,6 @@ vi.mock('src/router/modules', () => ({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'createCustomer',
|
|
||||||
icon: 'vn:addperson',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -98,7 +87,7 @@ vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
|
||||||
icon: 'vn:client',
|
icon: 'vn:client',
|
||||||
moduleName: 'Customer',
|
moduleName: 'Customer',
|
||||||
keyBinding: 'c',
|
keyBinding: 'c',
|
||||||
menu: 'customer',
|
menu: ['customer'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -260,15 +249,6 @@ describe('Leftmenu as main', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a single matched route with a menu', () => {
|
|
||||||
const route = {
|
|
||||||
matched: [{ meta: { menu: 'customer' } }],
|
|
||||||
};
|
|
||||||
|
|
||||||
const result = vm.betaGetRoutes();
|
|
||||||
|
|
||||||
expect(result.meta.menu).toEqual(route.matched[0].meta.menu);
|
|
||||||
});
|
|
||||||
it('should get routes for main source', () => {
|
it('should get routes for main source', () => {
|
||||||
vm.props.source = 'main';
|
vm.props.source = 'main';
|
||||||
vm.getRoutes();
|
vm.getRoutes();
|
||||||
|
@ -351,8 +331,9 @@ describe('addChildren', () => {
|
||||||
|
|
||||||
it('should handle routes with no meta menu', () => {
|
it('should handle routes with no meta menu', () => {
|
||||||
const route = {
|
const route = {
|
||||||
meta: {},
|
meta: {
|
||||||
menus: {},
|
menu: [],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const parent = [];
|
const parent = [];
|
||||||
|
|
|
@ -56,7 +56,12 @@ async function confirm() {
|
||||||
{{ t('The notification will be sent to the following address') }}
|
{{ t('The notification will be sent to the following address') }}
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<QCardSection class="q-pt-none">
|
<QCardSection class="q-pt-none">
|
||||||
<VnInput v-model="address" is-outlined autofocus />
|
<VnInput
|
||||||
|
v-model="address"
|
||||||
|
is-outlined
|
||||||
|
autofocus
|
||||||
|
data-cy="SendEmailNotifiactionDialogInput"
|
||||||
|
/>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<QCardActions align="right">
|
<QCardActions align="right">
|
||||||
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
|
<QBtn :label="t('globals.cancel')" color="primary" flat v-close-popup />
|
||||||
|
|
|
@ -1,50 +1,56 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onBeforeMount, computed } from 'vue';
|
import { onBeforeMount } from 'vue';
|
||||||
import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
|
import { useRouter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import useCardSize from 'src/composables/useCardSize';
|
import useCardSize from 'src/composables/useCardSize';
|
||||||
import VnSubToolbar from '../ui/VnSubToolbar.vue';
|
import VnSubToolbar from '../ui/VnSubToolbar.vue';
|
||||||
import VnSearchbar from 'components/ui/VnSearchbar.vue';
|
|
||||||
import LeftMenu from 'components/LeftMenu.vue';
|
|
||||||
import RightMenu from 'components/common/RightMenu.vue';
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
dataKey: { type: String, required: true },
|
dataKey: { type: String, required: true },
|
||||||
url: { type: String, default: undefined },
|
url: { type: String, default: undefined },
|
||||||
|
idInWhere: { type: Boolean, default: false },
|
||||||
filter: { type: Object, default: () => {} },
|
filter: { type: Object, default: () => {} },
|
||||||
descriptor: { type: Object, required: true },
|
descriptor: { type: Object, required: true },
|
||||||
filterPanel: { type: Object, default: undefined },
|
filterPanel: { type: Object, default: undefined },
|
||||||
idInWhere: { type: Boolean, default: false },
|
|
||||||
searchDataKey: { type: String, default: undefined },
|
searchDataKey: { type: String, default: undefined },
|
||||||
searchbarProps: { type: Object, default: undefined },
|
searchbarProps: { type: Object, default: undefined },
|
||||||
redirectOnError: { type: Boolean, default: false },
|
redirectOnError: { type: Boolean, default: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchRightDataKey = computed(() => {
|
|
||||||
if (!props.searchDataKey) return route.name;
|
|
||||||
return props.searchDataKey;
|
|
||||||
});
|
|
||||||
|
|
||||||
const arrayData = useArrayData(props.dataKey, {
|
const arrayData = useArrayData(props.dataKey, {
|
||||||
url: props.url,
|
url: props.url,
|
||||||
userFilter: props.filter,
|
userFilter: props.filter,
|
||||||
oneRecord: true,
|
oneRecord: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onBeforeRouteLeave(() => {
|
||||||
|
stateStore.cardDescriptorChangeValue(null);
|
||||||
|
});
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
|
stateStore.cardDescriptorChangeValue(props.descriptor);
|
||||||
|
|
||||||
|
const route = router.currentRoute.value;
|
||||||
try {
|
try {
|
||||||
await fetch(route.params.id);
|
await fetch(route.params.id);
|
||||||
} catch {
|
} catch {
|
||||||
const { matched: matches } = router.currentRoute.value;
|
const { matched: matches } = route;
|
||||||
const { path } = matches.at(-1);
|
const { path } = matches.at(-1);
|
||||||
router.push({ path: path.replace(/:id.*/, '') });
|
router.push({ path: path.replace(/:id.*/, '') });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeRouteUpdate(async (to, from) => {
|
onBeforeRouteUpdate(async (to, from) => {
|
||||||
|
if (hasRouteParam(to.params)) {
|
||||||
|
const { matched } = router.currentRoute.value;
|
||||||
|
const { name } = matched.at(-3);
|
||||||
|
if (name) {
|
||||||
|
router.push({ name, params: to.params });
|
||||||
|
}
|
||||||
|
}
|
||||||
const id = to.params.id;
|
const id = to.params.id;
|
||||||
if (id !== from.params.id) await fetch(id, true);
|
if (id !== from.params.id) await fetch(id, true);
|
||||||
});
|
});
|
||||||
|
@ -56,34 +62,13 @@ async function fetch(id, append = false) {
|
||||||
else arrayData.store.url = props.url.replace(regex, `/${id}`);
|
else arrayData.store.url = props.url.replace(regex, `/${id}`);
|
||||||
await arrayData.fetch({ append, updateRouter: false });
|
await arrayData.fetch({ append, updateRouter: false });
|
||||||
}
|
}
|
||||||
|
function hasRouteParam(params, valueToCheck = ':addressId') {
|
||||||
|
return Object.values(params).includes(valueToCheck);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<QDrawer
|
|
||||||
v-model="stateStore.leftDrawer"
|
|
||||||
show-if-above
|
|
||||||
:width="256"
|
|
||||||
v-if="stateStore.isHeaderMounted()"
|
|
||||||
>
|
|
||||||
<QScrollArea class="fit">
|
|
||||||
<component :is="descriptor" />
|
|
||||||
<QSeparator />
|
|
||||||
<LeftMenu source="card" />
|
|
||||||
</QScrollArea>
|
|
||||||
</QDrawer>
|
|
||||||
<slot name="searchbar" v-if="props.searchDataKey">
|
|
||||||
<VnSearchbar :data-key="props.searchDataKey" v-bind="props.searchbarProps" />
|
|
||||||
</slot>
|
|
||||||
<RightMenu>
|
|
||||||
<template #right-panel v-if="props.filterPanel">
|
|
||||||
<component :is="props.filterPanel" :data-key="searchRightDataKey" />
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<QPageContainer>
|
|
||||||
<QPage>
|
|
||||||
<VnSubToolbar />
|
<VnSubToolbar />
|
||||||
<div :class="[useCardSize(), $attrs.class]">
|
<div :class="[useCardSize(), $attrs.class]">
|
||||||
<RouterView :key="$route.path" />
|
<RouterView :key="$route.path" />
|
||||||
</div>
|
</div>
|
||||||
</QPage>
|
|
||||||
</QPageContainer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { onBeforeMount } from 'vue';
|
|
||||||
import { useRouter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router';
|
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import useCardSize from 'src/composables/useCardSize';
|
|
||||||
import VnSubToolbar from '../ui/VnSubToolbar.vue';
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
dataKey: { type: String, required: true },
|
|
||||||
url: { type: String, default: undefined },
|
|
||||||
idInWhere: { type: Boolean, default: false },
|
|
||||||
filter: { type: Object, default: () => {} },
|
|
||||||
descriptor: { type: Object, required: true },
|
|
||||||
filterPanel: { type: Object, default: undefined },
|
|
||||||
searchDataKey: { type: String, default: undefined },
|
|
||||||
searchbarProps: { type: Object, default: undefined },
|
|
||||||
redirectOnError: { type: Boolean, default: false },
|
|
||||||
});
|
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
const router = useRouter();
|
|
||||||
const arrayData = useArrayData(props.dataKey, {
|
|
||||||
url: props.url,
|
|
||||||
userFilter: props.filter,
|
|
||||||
oneRecord: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeRouteLeave(() => {
|
|
||||||
stateStore.cardDescriptorChangeValue(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
|
||||||
stateStore.cardDescriptorChangeValue(props.descriptor);
|
|
||||||
|
|
||||||
const route = router.currentRoute.value;
|
|
||||||
try {
|
|
||||||
await fetch(route.params.id);
|
|
||||||
} catch {
|
|
||||||
const { matched: matches } = route;
|
|
||||||
const { path } = matches.at(-1);
|
|
||||||
router.push({ path: path.replace(/:id.*/, '') });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeRouteUpdate(async (to, from) => {
|
|
||||||
if (hasRouteParam(to.params)) {
|
|
||||||
const { matched } = router.currentRoute.value;
|
|
||||||
const { name } = matched.at(-3);
|
|
||||||
if (name) {
|
|
||||||
router.push({ name, params: to.params });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const id = to.params.id;
|
|
||||||
if (id !== from.params.id) await fetch(id, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function fetch(id, append = false) {
|
|
||||||
const regex = /\/(\d+)/;
|
|
||||||
if (props.idInWhere) arrayData.store.filter.where = { id };
|
|
||||||
else if (!regex.test(props.url)) arrayData.store.url = `${props.url}/${id}`;
|
|
||||||
else arrayData.store.url = props.url.replace(regex, `/${id}`);
|
|
||||||
await arrayData.fetch({ append, updateRouter: false });
|
|
||||||
}
|
|
||||||
function hasRouteParam(params, valueToCheck = ':addressId') {
|
|
||||||
return Object.values(params).includes(valueToCheck);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<div :class="[useCardSize(), $attrs.class]">
|
|
||||||
<RouterView :key="$route.path" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
|
@ -177,6 +177,7 @@ function addDefaultData(data) {
|
||||||
name="vn:attach"
|
name="vn:attach"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
@click="inputFileRef.pickFiles()"
|
@click="inputFileRef.pickFiles()"
|
||||||
|
data-cy="attachFile"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('globals.selectFile') }}</QTooltip>
|
<QTooltip>{{ t('globals.selectFile') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
|
|
|
@ -389,10 +389,7 @@ defineExpose({
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
<div
|
<div v-else class="info-row q-pa-md text-center">
|
||||||
v-else
|
|
||||||
class="info-row q-pa-md text-center"
|
|
||||||
>
|
|
||||||
<h5>
|
<h5>
|
||||||
{{ t('No data to display') }}
|
{{ t('No data to display') }}
|
||||||
</h5>
|
</h5>
|
||||||
|
@ -416,6 +413,7 @@ defineExpose({
|
||||||
v-shortcut
|
v-shortcut
|
||||||
@click="showFormDialog()"
|
@click="showFormDialog()"
|
||||||
class="fill-icon"
|
class="fill-icon"
|
||||||
|
data-cy="addButton"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('Upload file') }}
|
{{ t('Upload file') }}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { useArrayData } from 'composables/useArrayData';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useClipboard } from 'src/composables/useClipboard';
|
import { useClipboard } from 'src/composables/useClipboard';
|
||||||
import VnMoreOptions from './VnMoreOptions.vue';
|
import VnMoreOptions from './VnMoreOptions.vue';
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ const $props = defineProps({
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { copyText } = useClipboard();
|
const { copyText } = useClipboard();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
|
@ -58,6 +60,9 @@ const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
|
||||||
const DESCRIPTOR_PROXY = 'DescriptorProxy';
|
const DESCRIPTOR_PROXY = 'DescriptorProxy';
|
||||||
const moduleName = ref();
|
const moduleName = ref();
|
||||||
const isSameModuleName = route.matched[1].meta.moduleName !== moduleName.value;
|
const isSameModuleName = route.matched[1].meta.moduleName !== moduleName.value;
|
||||||
|
const DESCRIPTOR_PROXY = 'DescriptorProxy';
|
||||||
|
const moduleName = ref();
|
||||||
|
const isSameModuleName = route.matched[1].meta.moduleName !== moduleName.value;
|
||||||
defineExpose({ getData });
|
defineExpose({ getData });
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
|
@ -84,6 +89,7 @@ onBeforeMount(async () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function getName() {
|
||||||
function getName() {
|
function getName() {
|
||||||
let name = $props.dataKey;
|
let name = $props.dataKey;
|
||||||
if ($props.dataKey.includes(DESCRIPTOR_PROXY)) {
|
if ($props.dataKey.includes(DESCRIPTOR_PROXY)) {
|
||||||
|
@ -91,11 +97,17 @@ function getName() {
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
const routeName = computed(() => {
|
||||||
|
let routeName = getName();
|
||||||
|
return `${routeName}Summary`;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
const routeName = computed(() => {
|
const routeName = computed(() => {
|
||||||
let routeName = getName();
|
let routeName = getName();
|
||||||
return `${routeName}Summary`;
|
return `${routeName}Summary`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
async function getData() {
|
async function getData() {
|
||||||
store.url = $props.url;
|
store.url = $props.url;
|
||||||
store.filter = $props.filter ?? {};
|
store.filter = $props.filter ?? {};
|
||||||
|
@ -164,6 +176,8 @@ const toModule = computed(() => {
|
||||||
<div class="descriptor">
|
<div class="descriptor">
|
||||||
<template v-if="entity && !isLoading">
|
<template v-if="entity && !isLoading">
|
||||||
<div class="header bg-primary q-pa-sm justify-between">
|
<div class="header bg-primary q-pa-sm justify-between">
|
||||||
|
<slot name="header-extra-action">
|
||||||
|
<QBtn
|
||||||
<slot name="header-extra-action">
|
<slot name="header-extra-action">
|
||||||
<QBtn
|
<QBtn
|
||||||
round
|
round
|
||||||
|
@ -174,11 +188,14 @@ const toModule = computed(() => {
|
||||||
color="white"
|
color="white"
|
||||||
class="link"
|
class="link"
|
||||||
:to="toModule"
|
:to="toModule"
|
||||||
|
:to="toModule"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('globals.goToModuleIndex') }}
|
{{ t('globals.goToModuleIndex') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
</slot>
|
||||||
|
</QBtn>
|
||||||
</slot>
|
</slot>
|
||||||
<QBtn
|
<QBtn
|
||||||
@click.stop="viewSummary(entity.id, $props.summary, $props.width)"
|
@click.stop="viewSummary(entity.id, $props.summary, $props.width)"
|
||||||
|
@ -191,6 +208,7 @@ const toModule = computed(() => {
|
||||||
class="link"
|
class="link"
|
||||||
v-if="summary"
|
v-if="summary"
|
||||||
data-cy="openSummaryBtn"
|
data-cy="openSummaryBtn"
|
||||||
|
data-cy="openSummaryBtn"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('components.smartCard.openSummary') }}
|
{{ t('components.smartCard.openSummary') }}
|
||||||
|
@ -206,6 +224,7 @@ const toModule = computed(() => {
|
||||||
round
|
round
|
||||||
size="md"
|
size="md"
|
||||||
data-cy="goToSummaryBtn"
|
data-cy="goToSummaryBtn"
|
||||||
|
data-cy="goToSummaryBtn"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('components.cardDescriptor.summary') }}
|
{{ t('components.cardDescriptor.summary') }}
|
||||||
|
|
|
@ -81,6 +81,7 @@ async function fetch() {
|
||||||
name: `${moduleName ?? route.meta.moduleName}Summary`,
|
name: `${moduleName ?? route.meta.moduleName}Summary`,
|
||||||
params: { id: entityId || entity.id },
|
params: { id: entityId || entity.id },
|
||||||
}"
|
}"
|
||||||
|
data-cy="goToSummaryBtn"
|
||||||
>
|
>
|
||||||
<QIcon name="open_in_new" color="white" size="sm" />
|
<QIcon name="open_in_new" color="white" size="sm" />
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
|
@ -54,7 +54,7 @@ const $props = defineProps({
|
||||||
default: 'table',
|
default: 'table',
|
||||||
},
|
},
|
||||||
redirect: {
|
redirect: {
|
||||||
type: Boolean,
|
type: [String, Boolean],
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
arrayData: {
|
arrayData: {
|
||||||
|
|
|
@ -186,7 +186,7 @@ function fetchData([data]) {
|
||||||
ref="vnPaginateRef"
|
ref="vnPaginateRef"
|
||||||
class="show"
|
class="show"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
search-url="notes"
|
:search-url="false"
|
||||||
@on-fetch="
|
@on-fetch="
|
||||||
newNote.text = '';
|
newNote.text = '';
|
||||||
newNote.observationTypeFk = null;
|
newNote.observationTypeFk = null;
|
||||||
|
|
|
@ -33,6 +33,10 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
userFilter: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
filter: {
|
filter: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
|
|
|
@ -9,6 +9,8 @@ export function getColAlign(col) {
|
||||||
case 'number':
|
case 'number':
|
||||||
align = 'right';
|
align = 'right';
|
||||||
break;
|
break;
|
||||||
|
case 'time':
|
||||||
|
case 'date':
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
align = 'center';
|
align = 'center';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -148,8 +148,7 @@ export function useArrayData(key, userOptions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function applyFilter({ filter, params }, fetchOptions = {}) {
|
async function applyFilter({ filter, params }, fetchOptions = {}) {
|
||||||
if (filter) store.userFilter = filter;
|
if (filter) store.filter = filter;
|
||||||
store.filter = {};
|
|
||||||
if (params) store.userParams = { ...params };
|
if (params) store.userParams = { ...params };
|
||||||
|
|
||||||
const response = await fetch(fetchOptions);
|
const response = await fetch(fetchOptions);
|
||||||
|
|
|
@ -15,6 +15,7 @@ body.body--light {
|
||||||
--vn-empty-tag: #acacac;
|
--vn-empty-tag: #acacac;
|
||||||
--vn-black-text-color: black;
|
--vn-black-text-color: black;
|
||||||
--vn-text-color-contrast: white;
|
--vn-text-color-contrast: white;
|
||||||
|
--vn-link-color: #1e90ff;
|
||||||
|
|
||||||
background-color: var(--vn-page-color);
|
background-color: var(--vn-page-color);
|
||||||
|
|
||||||
|
@ -38,6 +39,7 @@ body.body--dark {
|
||||||
--vn-empty-tag: #2d2d2d;
|
--vn-empty-tag: #2d2d2d;
|
||||||
--vn-black-text-color: black;
|
--vn-black-text-color: black;
|
||||||
--vn-text-color-contrast: black;
|
--vn-text-color-contrast: black;
|
||||||
|
--vn-link-color: #66bfff;
|
||||||
|
|
||||||
background-color: var(--vn-page-color);
|
background-color: var(--vn-page-color);
|
||||||
|
|
||||||
|
@ -49,7 +51,7 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
color: $color-link;
|
color: var(--vn-link-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&--white {
|
&--white {
|
||||||
|
@ -58,14 +60,14 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tx-color-link {
|
.tx-color-link {
|
||||||
color: $color-link !important;
|
color: var(--vn-link-color) !important;
|
||||||
}
|
}
|
||||||
.tx-color-font {
|
.tx-color-font {
|
||||||
color: $color-link !important;
|
color: var(--vn-link-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-link {
|
.header-link {
|
||||||
color: $color-link !important;
|
color: var(--vn-link-color) !important;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-bottom: solid $primary;
|
border-bottom: solid $primary;
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
|
@ -337,5 +339,5 @@ input::-webkit-inner-spin-button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.containerShrinked {
|
.containerShrinked {
|
||||||
width: 80%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ $alert: $negative;
|
||||||
$white: #fff;
|
$white: #fff;
|
||||||
$dark: #3d3d3d;
|
$dark: #3d3d3d;
|
||||||
// custom
|
// custom
|
||||||
$color-link: #66bfff;
|
|
||||||
$color-spacer-light: #a3a3a31f;
|
$color-spacer-light: #a3a3a31f;
|
||||||
$color-spacer: #7979794d;
|
$color-spacer: #7979794d;
|
||||||
$border-thin-light: 1px solid $color-spacer-light;
|
$border-thin-light: 1px solid $color-spacer-light;
|
||||||
|
|
|
@ -99,7 +99,6 @@ globals:
|
||||||
file: File
|
file: File
|
||||||
selectFile: Select a file
|
selectFile: Select a file
|
||||||
copyClipboard: Copy on clipboard
|
copyClipboard: Copy on clipboard
|
||||||
salesPerson: SalesPerson
|
|
||||||
send: Send
|
send: Send
|
||||||
code: Code
|
code: Code
|
||||||
since: Since
|
since: Since
|
||||||
|
@ -158,7 +157,9 @@ globals:
|
||||||
changeState: Change state
|
changeState: Change state
|
||||||
raid: 'Raid {daysInForward} days'
|
raid: 'Raid {daysInForward} days'
|
||||||
isVies: Vies
|
isVies: Vies
|
||||||
|
department: Department
|
||||||
noData: No data available
|
noData: No data available
|
||||||
|
vehicle: Vehicle
|
||||||
pageTitles:
|
pageTitles:
|
||||||
logIn: Login
|
logIn: Login
|
||||||
addressEdit: Update address
|
addressEdit: Update address
|
||||||
|
@ -346,7 +347,6 @@ globals:
|
||||||
params:
|
params:
|
||||||
description: Description
|
description: Description
|
||||||
clientFk: Client id
|
clientFk: Client id
|
||||||
salesPersonFk: Sales person
|
|
||||||
warehouseFk: Warehouse
|
warehouseFk: Warehouse
|
||||||
provinceFk: Province
|
provinceFk: Province
|
||||||
stateFk: State
|
stateFk: State
|
||||||
|
@ -531,6 +531,7 @@ ticket:
|
||||||
customerCard: Customer card
|
customerCard: Customer card
|
||||||
ticketList: Ticket List
|
ticketList: Ticket List
|
||||||
newOrder: New Order
|
newOrder: New Order
|
||||||
|
ticketClaimed: Claimed ticket
|
||||||
boxing:
|
boxing:
|
||||||
expedition: Expedition
|
expedition: Expedition
|
||||||
created: Created
|
created: Created
|
||||||
|
@ -603,7 +604,6 @@ worker:
|
||||||
balance: Balance
|
balance: Balance
|
||||||
medical: Medical
|
medical: Medical
|
||||||
list:
|
list:
|
||||||
department: Department
|
|
||||||
schedule: Schedule
|
schedule: Schedule
|
||||||
newWorker: New worker
|
newWorker: New worker
|
||||||
summary:
|
summary:
|
||||||
|
@ -862,7 +862,6 @@ components:
|
||||||
mine: For me
|
mine: For me
|
||||||
hasMinPrice: Minimum price
|
hasMinPrice: Minimum price
|
||||||
# LatestBuysFilter
|
# LatestBuysFilter
|
||||||
salesPersonFk: Buyer
|
|
||||||
supplierFk: Supplier
|
supplierFk: Supplier
|
||||||
from: From
|
from: From
|
||||||
to: To
|
to: To
|
||||||
|
|
|
@ -103,7 +103,6 @@ globals:
|
||||||
file: Fichero
|
file: Fichero
|
||||||
selectFile: Seleccione un fichero
|
selectFile: Seleccione un fichero
|
||||||
copyClipboard: Copiar en portapapeles
|
copyClipboard: Copiar en portapapeles
|
||||||
salesPerson: Comercial
|
|
||||||
send: Enviar
|
send: Enviar
|
||||||
code: Código
|
code: Código
|
||||||
since: Desde
|
since: Desde
|
||||||
|
@ -163,6 +162,8 @@ globals:
|
||||||
raid: 'Redada {daysInForward} días'
|
raid: 'Redada {daysInForward} días'
|
||||||
isVies: Vies
|
isVies: Vies
|
||||||
noData: Datos no disponibles
|
noData: Datos no disponibles
|
||||||
|
department: Departamento
|
||||||
|
vehicle: Vehículo
|
||||||
pageTitles:
|
pageTitles:
|
||||||
logIn: Inicio de sesión
|
logIn: Inicio de sesión
|
||||||
addressEdit: Modificar consignatario
|
addressEdit: Modificar consignatario
|
||||||
|
@ -349,7 +350,6 @@ globals:
|
||||||
params:
|
params:
|
||||||
description: Descripción
|
description: Descripción
|
||||||
clientFk: Id cliente
|
clientFk: Id cliente
|
||||||
salesPersonFk: Comercial
|
|
||||||
warehouseFk: Almacén
|
warehouseFk: Almacén
|
||||||
provinceFk: Provincia
|
provinceFk: Provincia
|
||||||
stateFk: Estado
|
stateFk: Estado
|
||||||
|
@ -531,13 +531,13 @@ ticket:
|
||||||
state: Estado
|
state: Estado
|
||||||
shipped: Enviado
|
shipped: Enviado
|
||||||
landed: Entregado
|
landed: Entregado
|
||||||
salesPerson: Comercial
|
|
||||||
total: Total
|
total: Total
|
||||||
card:
|
card:
|
||||||
customerId: ID cliente
|
customerId: ID cliente
|
||||||
customerCard: Ficha del cliente
|
customerCard: Ficha del cliente
|
||||||
ticketList: Listado de tickets
|
ticketList: Listado de tickets
|
||||||
newOrder: Nuevo pedido
|
newOrder: Nuevo pedido
|
||||||
|
ticketClaimed: Ticket reclamado
|
||||||
boxing:
|
boxing:
|
||||||
expedition: Expedición
|
expedition: Expedición
|
||||||
created: Creado
|
created: Creado
|
||||||
|
@ -622,8 +622,6 @@ invoiceOut:
|
||||||
errors:
|
errors:
|
||||||
downloadCsvFailed: Error al descargar CSV
|
downloadCsvFailed: Error al descargar CSV
|
||||||
order:
|
order:
|
||||||
field:
|
|
||||||
salesPersonFk: Comercial
|
|
||||||
form:
|
form:
|
||||||
clientFk: Cliente
|
clientFk: Cliente
|
||||||
addressFk: Dirección
|
addressFk: Dirección
|
||||||
|
@ -691,7 +689,6 @@ worker:
|
||||||
formation: Formación
|
formation: Formación
|
||||||
medical: Mutua
|
medical: Mutua
|
||||||
list:
|
list:
|
||||||
department: Departamento
|
|
||||||
schedule: Horario
|
schedule: Horario
|
||||||
newWorker: Nuevo trabajador
|
newWorker: Nuevo trabajador
|
||||||
summary:
|
summary:
|
||||||
|
@ -949,7 +946,6 @@ components:
|
||||||
hasMinPrice: Precio mínimo
|
hasMinPrice: Precio mínimo
|
||||||
wareHouseFk: Almacén
|
wareHouseFk: Almacén
|
||||||
# LatestBuysFilter
|
# LatestBuysFilter
|
||||||
salesPersonFk: Comprador
|
|
||||||
supplierFk: Proveedor
|
supplierFk: Proveedor
|
||||||
visible: Visible
|
visible: Visible
|
||||||
active: Activo
|
active: Activo
|
||||||
|
|
|
@ -149,14 +149,12 @@ const columns = computed(() => [
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
>
|
>
|
||||||
<template #more-create-dialog="{ data }">
|
<template #more-create-dialog="{ data }">
|
||||||
<QCardSection>
|
|
||||||
<VnInputPassword
|
<VnInputPassword
|
||||||
:label="t('Password')"
|
:label="t('Password')"
|
||||||
v-model="data.password"
|
v-model="data.password"
|
||||||
:required="true"
|
:required="true"
|
||||||
autocomplete="new-password"
|
autocomplete="new-password"
|
||||||
/>
|
/>
|
||||||
</QCardSection>
|
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import AliasDescriptor from './AliasDescriptor.vue';
|
import AliasDescriptor from './AliasDescriptor.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="Alias"
|
data-key="Alias"
|
||||||
url="MailAliases"
|
url="MailAliases"
|
||||||
:descriptor="AliasDescriptor"
|
:descriptor="AliasDescriptor"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -27,13 +28,10 @@ const entityId = computed(() => $props.id || route.params.id);
|
||||||
<template #body="{ entity: alias }">
|
<template #body="{ entity: alias }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<QCardSection class="q-pa-none">
|
<QCardSection class="q-pa-none">
|
||||||
<router-link
|
<VnTitle
|
||||||
:to="{ name: 'AliasBasicData', params: { id: entityId } }"
|
:url="`#/account/alias/${entityId}/basic-data`"
|
||||||
class="header header-link"
|
:text="t('globals.summary.basicData')"
|
||||||
>
|
/>
|
||||||
{{ t('globals.summary.basicData') }}
|
|
||||||
<QIcon name="open_in_new" />
|
|
||||||
</router-link>
|
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<VnLv :label="t('role.id')" :value="alias.id" />
|
<VnLv :label="t('role.id')" :value="alias.id" />
|
||||||
<VnLv :label="t('role.description')" :value="alias.description" />
|
<VnLv :label="t('role.description')" :value="alias.description" />
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import AccountDescriptor from './AccountDescriptor.vue';
|
import AccountDescriptor from './AccountDescriptor.vue';
|
||||||
import filter from './AccountFilter.js';
|
import filter from './AccountFilter.js';
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
url="VnUsers/preview"
|
url="VnUsers/preview"
|
||||||
:id-in-where="true"
|
:id-in-where="true"
|
||||||
data-key="Account"
|
data-key="Account"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import filter from './AccountFilter.js';
|
import filter from './AccountFilter.js';
|
||||||
import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
|
import AccountDescriptorMenu from './AccountDescriptorMenu.vue';
|
||||||
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
|
||||||
const $props = defineProps({ id: { type: Number, default: 0 } });
|
const $props = defineProps({ id: { type: Number, default: 0 } });
|
||||||
|
|
||||||
|
@ -26,13 +27,10 @@ const entityId = computed(() => $props.id || route.params.id);
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<QCardSection class="q-pa-none">
|
<QCardSection class="q-pa-none">
|
||||||
<router-link
|
<VnTitle
|
||||||
:to="{ name: 'AccountBasicData', params: { id: entityId } }"
|
:url="`#/account/${entityId}/basic-data`"
|
||||||
class="header header-link"
|
:text="$t('globals.pageTitles.basicData')"
|
||||||
>
|
/>
|
||||||
{{ $t('globals.pageTitles.basicData') }}
|
|
||||||
<QIcon name="open_in_new" />
|
|
||||||
</router-link>
|
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<VnLv :label="$t('account.card.nickname')" :value="entity.name" />
|
<VnLv :label="$t('account.card.nickname')" :value="entity.name" />
|
||||||
<VnLv :label="$t('account.card.role')" :value="entity.role?.name" />
|
<VnLv :label="$t('account.card.role')" :value="entity.role?.name" />
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import RoleDescriptor from './RoleDescriptor.vue';
|
import RoleDescriptor from './RoleDescriptor.vue';
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
url="VnRoles"
|
url="VnRoles"
|
||||||
data-key="Role"
|
data-key="Role"
|
||||||
:id-in-where="true"
|
:id-in-where="true"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -29,13 +30,10 @@ const entityId = computed(() => $props.id || route.params.id);
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<QCardSection class="q-pa-none">
|
<QCardSection class="q-pa-none">
|
||||||
<a
|
<VnTitle
|
||||||
class="header header-link"
|
:url="`#/account/role/${entityId}/basic-data`"
|
||||||
:href="`#/VnUser/${entityId}/basic-data`"
|
:text="$t('globals.pageTitles.basicData')"
|
||||||
>
|
/>
|
||||||
{{ t('globals.pageTitles.basicData') }}
|
|
||||||
<QIcon name="open_in_new" />
|
|
||||||
</a>
|
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<VnLv :label="t('role.id')" :value="entity.id" />
|
<VnLv :label="t('role.id')" :value="entity.id" />
|
||||||
<VnLv :label="t('globals.name')" :value="entity.name" />
|
<VnLv :label="t('globals.name')" :value="entity.name" />
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import ClaimDescriptor from './ClaimDescriptor.vue';
|
import ClaimDescriptor from './ClaimDescriptor.vue';
|
||||||
import filter from './ClaimFilter.js';
|
import filter from './ClaimFilter.js';
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="Claim"
|
data-key="Claim"
|
||||||
url="Claims"
|
url="Claims"
|
||||||
:descriptor="ClaimDescriptor"
|
:descriptor="ClaimDescriptor"
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n';
|
||||||
import { toDateHourMinSec, toPercentage } from 'src/filters';
|
import { toDateHourMinSec, toPercentage } from 'src/filters';
|
||||||
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
|
import TicketDescriptorProxy from 'pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.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 CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
||||||
|
@ -65,12 +66,12 @@ onMounted(async () => {
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv :label="t('claim.created')" :value="toDateHourMinSec(entity.created)" />
|
<VnLv :label="t('claim.created')" :value="toDateHourMinSec(entity.created)" />
|
||||||
<VnLv :label="t('claim.commercial')">
|
<VnLv :label="t('globals.department')">
|
||||||
<template #value>
|
<template #value>
|
||||||
<VnUserLink
|
<span class="link">
|
||||||
:name="entity.client?.salesPersonUser?.name"
|
{{ entity?.client?.department?.name || '-' }}
|
||||||
:worker-id="entity.client?.salesPersonFk"
|
<DepartmentDescriptorProxy :id="entity?.client?.departmentFk" />
|
||||||
/>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv
|
<VnLv
|
||||||
|
|
|
@ -14,7 +14,7 @@ export default {
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
scope: {
|
scope: {
|
||||||
include: [
|
include: [
|
||||||
{ relation: 'salesPersonUser' },
|
{ relation: 'department' },
|
||||||
{
|
{
|
||||||
relation: 'claimsRatio',
|
relation: 'claimsRatio',
|
||||||
scope: {
|
scope: {
|
||||||
|
|
|
@ -117,7 +117,7 @@ const selected = ref([]);
|
||||||
const mana = ref(0);
|
const mana = ref(0);
|
||||||
async function fetchMana() {
|
async function fetchMana() {
|
||||||
const ticketId = claim.value.ticketFk;
|
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;
|
mana.value = response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,7 @@ function onDrag() {
|
||||||
class="all-pointer-events absolute delete-button zindex"
|
class="all-pointer-events absolute delete-button zindex"
|
||||||
@click.stop="viewDeleteDms(index)"
|
@click.stop="viewDeleteDms(index)"
|
||||||
round
|
round
|
||||||
|
:data-cy="`delete-button-${index+1}`"
|
||||||
/>
|
/>
|
||||||
<QIcon
|
<QIcon
|
||||||
name="play_circle"
|
name="play_circle"
|
||||||
|
@ -227,6 +228,7 @@ function onDrag() {
|
||||||
class="rounded-borders cursor-pointer fit"
|
class="rounded-borders cursor-pointer fit"
|
||||||
@click="openDialog(media.dmsFk)"
|
@click="openDialog(media.dmsFk)"
|
||||||
v-if="!media.isVideo"
|
v-if="!media.isVideo"
|
||||||
|
:data-cy="`file-${index+1}`"
|
||||||
>
|
>
|
||||||
</QImg>
|
</QImg>
|
||||||
<video
|
<video
|
||||||
|
@ -235,6 +237,7 @@ function onDrag() {
|
||||||
muted="muted"
|
muted="muted"
|
||||||
v-if="media.isVideo"
|
v-if="media.isVideo"
|
||||||
@click="openDialog(media.dmsFk)"
|
@click="openDialog(media.dmsFk)"
|
||||||
|
:data-cy="`file-${index+1}`"
|
||||||
/>
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,6 +19,7 @@ import ClaimNotes from 'src/pages/Claim/Card/ClaimNotes.vue';
|
||||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.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';
|
import ClaimDescriptorMenu from './ClaimDescriptorMenu.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -252,13 +253,15 @@ function claimUrl(section) {
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv
|
<VnLv
|
||||||
v-if="$route.name != 'ClaimSummary'"
|
v-if="$route.name != 'ClaimSummary'"
|
||||||
:label="t('globals.salesPerson')"
|
:label="t('customer.summary.team')"
|
||||||
>
|
>
|
||||||
<template #value>
|
<template #value>
|
||||||
<VnUserLink
|
<span class="link">
|
||||||
:name="claim.client?.salesPersonUser?.name"
|
{{ claim?.client?.department?.name || '-' }}
|
||||||
:worker-id="claim.client?.salesPersonFk"
|
<DepartmentDescriptorProxy
|
||||||
|
:id="claim?.client?.departmentFk"
|
||||||
/>
|
/>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv v-if="$route.name != 'ClaimSummary'" :label="t('claim.attendedBy')">
|
<VnLv v-if="$route.name != 'ClaimSummary'" :label="t('claim.attendedBy')">
|
||||||
|
@ -271,7 +274,7 @@ function claimUrl(section) {
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv v-if="$route.name != 'ClaimSummary'" :label="t('claim.customer')">
|
<VnLv v-if="$route.name != 'ClaimSummary'" :label="t('claim.customer')">
|
||||||
<template #value>
|
<template #value>
|
||||||
<span class="link cursor-pointer">
|
<span class="link">
|
||||||
{{ claim.client?.name }}
|
{{ claim.client?.name }}
|
||||||
<CustomerDescriptorProxy :id="claim.clientFk" />
|
<CustomerDescriptorProxy :id="claim.clientFk" />
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -80,7 +80,7 @@ const columns = [
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
:column-search="false"
|
:column-search="false"
|
||||||
:disable-option="{ card: true, table: true }"
|
:disable-option="{ card: true, table: true }"
|
||||||
search-url="actions"
|
:search-url="false"
|
||||||
:filter="{ where: { claimFk: $props.id } }"
|
:filter="{ where: { claimFk: $props.id } }"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:limit="0"
|
:limit="0"
|
||||||
|
|
|
@ -44,15 +44,14 @@ const props = defineProps({
|
||||||
is-outlined
|
is-outlined
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('Salesperson')"
|
|
||||||
v-model="params.salesPersonFk"
|
|
||||||
url="Workers/activeWithInheritedRole"
|
|
||||||
:filter="{ where: { role: 'salesPerson' } }"
|
|
||||||
:use-like="false"
|
|
||||||
option-filter="firstName"
|
|
||||||
dense
|
|
||||||
outlined
|
outlined
|
||||||
|
dense
|
||||||
rounded
|
rounded
|
||||||
|
:label="t('globals.params.departmentFk')"
|
||||||
|
v-model="params.departmentFk"
|
||||||
|
option-value="id"
|
||||||
|
option-label="name"
|
||||||
|
url="Departments"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('claim.attendedBy')"
|
:label="t('claim.attendedBy')"
|
||||||
|
@ -126,7 +125,6 @@ en:
|
||||||
search: Contains
|
search: Contains
|
||||||
clientFk: Customer
|
clientFk: Customer
|
||||||
clientName: Customer
|
clientName: Customer
|
||||||
salesPersonFk: Salesperson
|
|
||||||
attenderFk: Attender
|
attenderFk: Attender
|
||||||
claimResponsibleFk: Responsible
|
claimResponsibleFk: Responsible
|
||||||
claimStateFk: State
|
claimStateFk: State
|
||||||
|
@ -139,7 +137,6 @@ es:
|
||||||
search: Contiene
|
search: Contiene
|
||||||
clientFk: Cliente
|
clientFk: Cliente
|
||||||
clientName: Cliente
|
clientName: Cliente
|
||||||
salesPersonFk: Comercial
|
|
||||||
attenderFk: Asistente
|
attenderFk: Asistente
|
||||||
claimResponsibleFk: Responsable
|
claimResponsibleFk: Responsable
|
||||||
claimStateFk: Estado
|
claimStateFk: Estado
|
||||||
|
@ -148,6 +145,5 @@ es:
|
||||||
itemFk: Artículo
|
itemFk: Artículo
|
||||||
zoneFk: Zona
|
zoneFk: Zona
|
||||||
Client Name: Nombre del cliente
|
Client Name: Nombre del cliente
|
||||||
Salesperson: Comercial
|
|
||||||
Item: Artículo
|
Item: Artículo
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
|
||||||
import { toDate } from 'filters/index';
|
import { toDate } from 'filters/index';
|
||||||
import ClaimFilter from './ClaimFilter.vue';
|
import ClaimFilter from './ClaimFilter.vue';
|
||||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.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 VnUserLink from 'src/components/ui/VnUserLink.vue';
|
||||||
import ClaimSummary from './Card/ClaimSummary.vue';
|
import ClaimSummary from './Card/ClaimSummary.vue';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
|
@ -48,6 +49,20 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
columnClass: 'expand',
|
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',
|
align: 'left',
|
||||||
label: t('claim.attendedBy'),
|
label: t('claim.attendedBy'),
|
||||||
|
@ -152,6 +167,12 @@ const STATE_COLOR = {
|
||||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #column-departmentFk="{ row }">
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ row.departmentName || '-' }}
|
||||||
|
<DepartmentDescriptorProxy :id="row?.departmentFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
<template #column-attendedBy="{ row }">
|
<template #column-attendedBy="{ row }">
|
||||||
<span @click.stop>
|
<span @click.stop>
|
||||||
<VnUserLink :name="row.workerName" :worker-id="row.workerFk" />
|
<VnUserLink :name="row.workerName" :worker-id="row.workerFk" />
|
||||||
|
|
|
@ -8,7 +8,6 @@ import FormModel from 'components/FormModel.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
|
||||||
import { getDifferences, getUpdatedValues } from 'src/filters';
|
import { getDifferences, getUpdatedValues } from 'src/filters';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -37,7 +36,7 @@ const exprBuilder = (param, value) => {
|
||||||
function onBeforeSave(formData, originalData) {
|
function onBeforeSave(formData, originalData) {
|
||||||
return getUpdatedValues(
|
return getUpdatedValues(
|
||||||
Object.keys(getDifferences(formData, originalData)),
|
Object.keys(getDifferences(formData, originalData)),
|
||||||
formData
|
formData,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -119,16 +118,11 @@ function onBeforeSave(formData, originalData) {
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelectWorker
|
<VnSelect
|
||||||
:label="t('customer.summary.salesPerson')"
|
:label="t('globals.department')"
|
||||||
v-model="data.salesPersonFk"
|
v-model="data.departmentFk"
|
||||||
:params="{
|
url="Departments"
|
||||||
departmentCodes: ['VT', 'shopping'],
|
:fields="['id', 'name']"
|
||||||
}"
|
|
||||||
:has-avatar="true"
|
|
||||||
:rules="validate('client.salesPersonFk')"
|
|
||||||
:expr-builder="exprBuilder"
|
|
||||||
emit-value
|
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-model="data.contactChannelFk"
|
v-model="data.contactChannelFk"
|
||||||
|
@ -160,7 +154,7 @@ function onBeforeSave(formData, originalData) {
|
||||||
<QIcon name="info" class="cursor-pointer">
|
<QIcon name="info" class="cursor-pointer">
|
||||||
<QTooltip>{{
|
<QTooltip>{{
|
||||||
t(
|
t(
|
||||||
'In case of a company succession, specify the grantor company'
|
'In case of a company succession, specify the grantor company',
|
||||||
)
|
)
|
||||||
}}</QTooltip>
|
}}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import CustomerDescriptor from './CustomerDescriptor.vue';
|
import CustomerDescriptor from './CustomerDescriptor.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="Customer"
|
data-key="Customer"
|
||||||
:url="`Clients/${$route.params.id}/getCard`"
|
:url="`Clients/${$route.params.id}/getCard`"
|
||||||
:descriptor="CustomerDescriptor"
|
:descriptor="CustomerDescriptor"
|
||||||
|
|
|
@ -3,14 +3,14 @@ import { onMounted, ref, computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
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 useCardDescription from 'src/composables/useCardDescription';
|
||||||
|
|
||||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
|
||||||
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
|
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
|
||||||
|
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
const state = useState();
|
const state = useState();
|
||||||
|
|
||||||
|
@ -84,14 +84,10 @@ const debtWarning = computed(() => {
|
||||||
:value="toCurrency(entity.debt)"
|
:value="toCurrency(entity.debt)"
|
||||||
:info="t('customer.summary.riskInfo')"
|
:info="t('customer.summary.riskInfo')"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('customer.summary.salesPerson')">
|
<VnLv :label="t('globals.department')">
|
||||||
<template #value>
|
<template #value>
|
||||||
<VnUserLink
|
<span class="link" v-text="entity.department?.name" />
|
||||||
v-if="entity.salesPersonUser"
|
<DepartmentDescriptorProxy :id="entity.department?.id" />
|
||||||
:name="entity.salesPersonUser.name"
|
|
||||||
:worker-id="entity.salesPersonFk"
|
|
||||||
/>
|
|
||||||
<span v-else>{{ dashIfEmpty(entity.salesPersonUser) }}</span>
|
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv
|
<VnLv
|
||||||
|
|
|
@ -86,12 +86,12 @@ const tableColumnComponents = {
|
||||||
},
|
},
|
||||||
file: {
|
file: {
|
||||||
component: QBtn,
|
component: QBtn,
|
||||||
props: () => ({ flat: true, color: 'blue' }),
|
props: () => ({ flat: true }),
|
||||||
event: ({ row }) => downloadFile(row.dmsFk),
|
event: ({ row }) => downloadFile(row.dmsFk),
|
||||||
},
|
},
|
||||||
employee: {
|
employee: {
|
||||||
component: QBtn,
|
component: QBtn,
|
||||||
props: () => ({ flat: true, color: 'blue' }),
|
props: () => ({ flat: true }),
|
||||||
event: () => {},
|
event: () => {},
|
||||||
},
|
},
|
||||||
created: {
|
created: {
|
||||||
|
@ -214,8 +214,17 @@ const toCustomerFileManagementCreate = () => {
|
||||||
v-bind="tableColumnComponents[props.col.name].props(props)"
|
v-bind="tableColumnComponents[props.col.name].props(props)"
|
||||||
>
|
>
|
||||||
<template v-if="props.col.name !== 'original'">
|
<template v-if="props.col.name !== 'original'">
|
||||||
|
<span
|
||||||
|
:class="{
|
||||||
|
link:
|
||||||
|
props.col.name === 'employee' ||
|
||||||
|
props.col.name === 'file',
|
||||||
|
}"
|
||||||
|
>
|
||||||
{{ props.value }}
|
{{ props.value }}
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<WorkerDescriptorProxy
|
<WorkerDescriptorProxy
|
||||||
:id="props.row.dms.workerFk"
|
:id="props.row.dms.workerFk"
|
||||||
v-if="props.col.name === 'employee'"
|
v-if="props.col.name === 'employee'"
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import VnUserLink from 'src/components/ui/VnUserLink.vue';
|
|
||||||
|
|
||||||
import { toCurrency, toPercentage, toDate, dashOrCurrency } from 'src/filters';
|
import { toCurrency, toPercentage, toDate, dashOrCurrency } from 'src/filters';
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
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 VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
import VnRow from 'src/components/ui/VnRow.vue';
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
|
import CustomerDescriptorMenu from './CustomerDescriptorMenu.vue';
|
||||||
|
import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const grafanaUrl = 'https://grafana.verdnatura.es';
|
const grafanaUrl = 'https://grafana.verdnatura.es';
|
||||||
|
@ -106,16 +107,12 @@ const sumRisk = ({ clientRisks }) => {
|
||||||
{{ t('globals.params.email') }}
|
{{ t('globals.params.email') }}
|
||||||
<VnLinkMail email="entity.email"></VnLinkMail> </template
|
<VnLinkMail email="entity.email"></VnLinkMail> </template
|
||||||
></VnLv>
|
></VnLv>
|
||||||
<VnLv
|
<VnLv :label="t('globals.department')">
|
||||||
:label="t('customer.summary.salesPerson')"
|
|
||||||
:value="entity?.salesPersonUser?.name"
|
|
||||||
>
|
|
||||||
<template #value>
|
<template #value>
|
||||||
<VnUserLink
|
<span class="link" v-text="entity.department?.name" />
|
||||||
:name="entity.salesPersonUser?.name"
|
<DepartmentDescriptorProxy :id="entity?.department?.id" />
|
||||||
:worker-id="entity.salesPersonFk"
|
</template>
|
||||||
/> </template
|
</VnLv>
|
||||||
></VnLv>
|
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('customer.summary.contactChannel')"
|
:label="t('customer.summary.contactChannel')"
|
||||||
:value="entity?.contactChannel?.name"
|
:value="entity?.contactChannel?.name"
|
||||||
|
|
|
@ -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>
|
|
|
@ -3,7 +3,6 @@ import { useI18n } from 'vue-i18n';
|
||||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
defineProps({
|
defineProps({
|
||||||
|
@ -65,22 +64,15 @@ const exprBuilder = (param, value) => {
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem class="q-mb-sm">
|
<QItem class="q-mb-sm">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelectWorker
|
<VnSelect
|
||||||
: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
|
|
||||||
outlined
|
outlined
|
||||||
|
dense
|
||||||
rounded
|
rounded
|
||||||
:input-debounce="0"
|
:label="t('globals.params.departmentFk')"
|
||||||
|
v-model="params.departmentFk"
|
||||||
|
option-value="id"
|
||||||
|
option-label="name"
|
||||||
|
url="Departments"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
@ -164,7 +156,6 @@ en:
|
||||||
params:
|
params:
|
||||||
search: Contains
|
search: Contains
|
||||||
fi: FI
|
fi: FI
|
||||||
salesPersonFk: Salesperson
|
|
||||||
provinceFk: Province
|
provinceFk: Province
|
||||||
isActive: Is active
|
isActive: Is active
|
||||||
city: City
|
city: City
|
||||||
|
@ -191,7 +182,6 @@ es:
|
||||||
sageTaxTypeFk: Tipo de impuesto Sage
|
sageTaxTypeFk: Tipo de impuesto Sage
|
||||||
sageTransactionTypeFk: Tipo de impuesto Sage
|
sageTransactionTypeFk: Tipo de impuesto Sage
|
||||||
payMethodFk: Forma de pago
|
payMethodFk: Forma de pago
|
||||||
salesPersonFk: Comercial
|
|
||||||
provinceFk: Provincia
|
provinceFk: Provincia
|
||||||
city: Ciudad
|
city: Ciudad
|
||||||
phone: Teléfono
|
phone: Teléfono
|
||||||
|
@ -201,7 +191,6 @@ es:
|
||||||
name: Nombre
|
name: Nombre
|
||||||
postcode: CP
|
postcode: CP
|
||||||
FI: NIF
|
FI: NIF
|
||||||
Salesperson: Comercial
|
|
||||||
Province: Provincia
|
Province: Provincia
|
||||||
City: Ciudad
|
City: Ciudad
|
||||||
Phone: Teléfono
|
Phone: Teléfono
|
||||||
|
|
|
@ -10,7 +10,6 @@ import CustomerFilter from './CustomerFilter.vue';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||||
import VnLinkPhone from 'src/components/ui/VnLinkPhone.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';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -73,30 +72,17 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'salesPersonFk',
|
name: 'departmentFk',
|
||||||
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
|
label: t('customer.summary.team'),
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/activeWithInheritedRole',
|
url: 'Departments',
|
||||||
fields: ['id', 'name', 'firstName'],
|
|
||||||
where: { role: 'salesPerson' },
|
|
||||||
optionFilter: 'firstName',
|
|
||||||
},
|
},
|
||||||
columnFilter: {
|
create: true,
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
fields: ['id', 'name', 'firstName'],
|
|
||||||
where: { role: 'salesPerson' },
|
|
||||||
optionLabel: 'firstName',
|
|
||||||
optionValue: 'id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
create: false,
|
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson),
|
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -155,6 +141,9 @@ const columns = computed(() => [
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
},
|
},
|
||||||
columnClass: 'expand',
|
columnClass: 'expand',
|
||||||
|
attrs: {
|
||||||
|
uppercase: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -446,36 +435,6 @@ function handleLocation(data, location) {
|
||||||
redirect="customer"
|
redirect="customer"
|
||||||
>
|
>
|
||||||
<template #more-create-dialog="{ data }">
|
<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
|
<VnLocation
|
||||||
:acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
|
:acls="[{ model: 'Province', props: '*', accessType: 'WRITE' }]"
|
||||||
v-model="data.location"
|
v-model="data.location"
|
||||||
|
|
|
@ -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',
|
align: 'left',
|
||||||
name: 'departmentFk',
|
name: 'departmentFk',
|
||||||
|
@ -153,6 +131,11 @@ const columns = computed(() => [
|
||||||
label: t('Has recovery'),
|
label: t('Has recovery'),
|
||||||
name: 'hasRecovery',
|
name: 'hasRecovery',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'isWorker',
|
||||||
|
label: t('customer.params.isWorker'),
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const viewAddObservation = (rowsSelected) => {
|
const viewAddObservation = (rowsSelected) => {
|
||||||
|
@ -167,7 +150,6 @@ const viewAddObservation = (rowsSelected) => {
|
||||||
|
|
||||||
function exprBuilder(param, value) {
|
function exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'salesPersonFk':
|
|
||||||
case 'creditInsurance':
|
case 'creditInsurance':
|
||||||
case 'countryFk':
|
case 'countryFk':
|
||||||
return { [`c.${param}`]: value };
|
return { [`c.${param}`]: value };
|
||||||
|
@ -176,7 +158,7 @@ function exprBuilder(param, value) {
|
||||||
case 'workerFk':
|
case 'workerFk':
|
||||||
return { [`co.${param}`]: value };
|
return { [`co.${param}`]: value };
|
||||||
case 'departmentFk':
|
case 'departmentFk':
|
||||||
return { [`wd.${param}`]: value };
|
return { [`c.${param}`]: value };
|
||||||
case 'amount':
|
case 'amount':
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
return { [`d.${param}`]: value };
|
return { [`d.${param}`]: value };
|
||||||
|
@ -241,12 +223,6 @@ function exprBuilder(param, value) {
|
||||||
<template #column-observation="{ row }">
|
<template #column-observation="{ row }">
|
||||||
<VnInput type="textarea" v-model="row.observation" readonly dense rows="2" />
|
<VnInput type="textarea" v-model="row.observation" readonly dense rows="2" />
|
||||||
</template>
|
</template>
|
||||||
<template #column-salesPersonFk="{ row }">
|
|
||||||
<span class="link" @click.stop>
|
|
||||||
{{ row.salesPersonName }}
|
|
||||||
<WorkerDescriptorProxy :id="row.salesPersonFk" />
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #column-departmentFk="{ row }">
|
<template #column-departmentFk="{ row }">
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
{{ row.departmentName }}
|
{{ row.departmentName }}
|
||||||
|
@ -265,8 +241,6 @@ function exprBuilder(param, value) {
|
||||||
es:
|
es:
|
||||||
Add observation: Añadir observación
|
Add observation: Añadir observación
|
||||||
Client: Cliente
|
Client: Cliente
|
||||||
Is worker: Es trabajador
|
|
||||||
Salesperson: Comercial
|
|
||||||
Department: Departamento
|
Department: Departamento
|
||||||
Country: País
|
Country: País
|
||||||
P. Method: F. Pago
|
P. Method: F. Pago
|
||||||
|
@ -281,5 +255,5 @@ es:
|
||||||
Credit I.: Crédito A.
|
Credit I.: Crédito A.
|
||||||
Credit insurance: Crédito asegurado
|
Credit insurance: Crédito asegurado
|
||||||
From: Desde
|
From: Desde
|
||||||
Has recovery: Tiene recobro
|
Has recovery: Recobro
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -15,19 +15,12 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const salespersons = ref();
|
|
||||||
const countries = ref();
|
const countries = ref();
|
||||||
const authors = ref();
|
const authors = ref();
|
||||||
const departments = ref();
|
const departments = ref();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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) => (countries = data)" auto-load url="Countries" />
|
||||||
<FetchData
|
<FetchData
|
||||||
@on-fetch="(data) => (authors = data)"
|
@on-fetch="(data) => (authors = data)"
|
||||||
|
@ -62,29 +55,6 @@ const departments = ref();
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
/>
|
/>
|
||||||
</QItem>
|
</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">
|
<QItem class="q-mb-sm">
|
||||||
<QItemSection v-if="departments">
|
<QItemSection v-if="departments">
|
||||||
<VnSelect
|
<VnSelect
|
||||||
|
@ -219,7 +189,6 @@ const departments = ref();
|
||||||
en:
|
en:
|
||||||
params:
|
params:
|
||||||
clientFk: Client
|
clientFk: Client
|
||||||
salesPersonFk: Salesperson
|
|
||||||
countryFk: Country
|
countryFk: Country
|
||||||
paymentMethod: P. Method
|
paymentMethod: P. Method
|
||||||
balance: Balance D.
|
balance: Balance D.
|
||||||
|
@ -230,7 +199,6 @@ en:
|
||||||
es:
|
es:
|
||||||
params:
|
params:
|
||||||
clientFk: Cliente
|
clientFk: Cliente
|
||||||
salesPersonFk: Comercial
|
|
||||||
countryFk: País
|
countryFk: País
|
||||||
paymentMethod: F. Pago
|
paymentMethod: F. Pago
|
||||||
balance: Saldo V.
|
balance: Saldo V.
|
||||||
|
@ -239,7 +207,6 @@ es:
|
||||||
credit: Crédito A.
|
credit: Crédito A.
|
||||||
defaulterSinced: Desde
|
defaulterSinced: Desde
|
||||||
Client: Cliente
|
Client: Cliente
|
||||||
Salesperson: Comercial
|
|
||||||
Departments: Departamentos
|
Departments: Departamentos
|
||||||
Country: País
|
Country: País
|
||||||
P. Method: F. Pago
|
P. Method: F. Pago
|
||||||
|
|
|
@ -69,17 +69,16 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
|
name: 'departmentFk',
|
||||||
name: 'salesPersonFk',
|
label: t('customer.summary.team'),
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/activeWithInheritedRole',
|
url: 'Departments',
|
||||||
fields: ['id', 'name'],
|
|
||||||
where: { role: 'salesPerson' },
|
|
||||||
optionFilter: 'firstName',
|
|
||||||
useLike: false,
|
|
||||||
},
|
},
|
||||||
visible: false,
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
@ -96,7 +95,7 @@ const columns = computed(() => [
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
<VnTable
|
<VnTable
|
||||||
:data-key="dataKey"
|
:data-key="dataKey"
|
||||||
url="Clients"
|
url="Clients/filter"
|
||||||
:table="{
|
:table="{
|
||||||
'row-key': 'id',
|
'row-key': 'id',
|
||||||
selection: 'multiple',
|
selection: 'multiple',
|
||||||
|
@ -127,7 +126,6 @@ const columns = computed(() => [
|
||||||
es:
|
es:
|
||||||
Identifier: Identificador
|
Identifier: Identificador
|
||||||
Social name: Razón social
|
Social name: Razón social
|
||||||
Salesperson: Comercial
|
|
||||||
Phone: Teléfono
|
Phone: Teléfono
|
||||||
City: Población
|
City: Población
|
||||||
Email: Email
|
Email: Email
|
||||||
|
|
|
@ -20,7 +20,7 @@ customer:
|
||||||
name: Name
|
name: Name
|
||||||
contact: Contact
|
contact: Contact
|
||||||
mobile: Mobile
|
mobile: Mobile
|
||||||
salesPerson: Sales person
|
team: Team
|
||||||
contactChannel: Contact channel
|
contactChannel: Contact channel
|
||||||
socialName: Social name
|
socialName: Social name
|
||||||
fiscalId: Fiscal ID
|
fiscalId: Fiscal ID
|
||||||
|
@ -78,7 +78,6 @@ customer:
|
||||||
id: Identifier
|
id: Identifier
|
||||||
socialName: Social name
|
socialName: Social name
|
||||||
fi: Tax number
|
fi: Tax number
|
||||||
salesPersonFk: Salesperson
|
|
||||||
creditInsurance: Credit insurance
|
creditInsurance: Credit insurance
|
||||||
phone: Phone
|
phone: Phone
|
||||||
street: Street
|
street: Street
|
||||||
|
|
|
@ -20,7 +20,7 @@ customer:
|
||||||
name: Nombre
|
name: Nombre
|
||||||
contact: Contacto
|
contact: Contacto
|
||||||
mobile: Móvil
|
mobile: Móvil
|
||||||
salesPerson: Comercial
|
team: Equipo
|
||||||
contactChannel: Canal de contacto
|
contactChannel: Canal de contacto
|
||||||
socialName: Razón social
|
socialName: Razón social
|
||||||
fiscalId: NIF/CIF
|
fiscalId: NIF/CIF
|
||||||
|
@ -78,7 +78,6 @@ customer:
|
||||||
id: Identificador
|
id: Identificador
|
||||||
socialName: Razón social
|
socialName: Razón social
|
||||||
fi: NIF / CIF
|
fi: NIF / CIF
|
||||||
salesPersonFk: Comercial
|
|
||||||
creditInsurance: Crédito asegurado
|
creditInsurance: Crédito asegurado
|
||||||
phone: Teléfono
|
phone: Teléfono
|
||||||
street: Dirección fiscal
|
street: Dirección fiscal
|
||||||
|
|
|
@ -13,6 +13,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
|
import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
|
||||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||||
|
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -53,7 +54,7 @@ onMounted(() => {
|
||||||
:clear-store-on-unmount="false"
|
:clear-store-on-unmount="false"
|
||||||
>
|
>
|
||||||
<template #form="{ data }">
|
<template #form="{ data }">
|
||||||
<VnRow>
|
<VnRow class="q-py-sm">
|
||||||
<VnSelectTravelExtended
|
<VnSelectTravelExtended
|
||||||
:data="data"
|
:data="data"
|
||||||
v-model="data.travelFk"
|
v-model="data.travelFk"
|
||||||
|
@ -65,7 +66,7 @@ onMounted(() => {
|
||||||
:required="true"
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow class="q-py-sm">
|
||||||
<VnInput v-model="data.reference" :label="t('globals.reference')" />
|
<VnInput v-model="data.reference" :label="t('globals.reference')" />
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
v-model="data.invoiceAmount"
|
v-model="data.invoiceAmount"
|
||||||
|
@ -73,7 +74,7 @@ onMounted(() => {
|
||||||
:positive="false"
|
:positive="false"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow class="q-py-sm">
|
||||||
<VnInput
|
<VnInput
|
||||||
v-model="data.invoiceNumber"
|
v-model="data.invoiceNumber"
|
||||||
:label="t('entry.summary.invoiceNumber')"
|
:label="t('entry.summary.invoiceNumber')"
|
||||||
|
@ -84,12 +85,13 @@ onMounted(() => {
|
||||||
:options="companiesOptions"
|
:options="companiesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="code"
|
option-label="code"
|
||||||
|
sort-by="code"
|
||||||
map-options
|
map-options
|
||||||
hide-selected
|
hide-selected
|
||||||
:required="true"
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow class="q-py-sm">
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
:label="t('entry.summary.commission')"
|
:label="t('entry.summary.commission')"
|
||||||
v-model="data.commission"
|
v-model="data.commission"
|
||||||
|
@ -102,9 +104,10 @@ onMounted(() => {
|
||||||
:options="currenciesOptions"
|
:options="currenciesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="code"
|
option-label="code"
|
||||||
|
sort-by="code"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow class="q-py-sm">
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
v-model="data.initialTemperature"
|
v-model="data.initialTemperature"
|
||||||
name="initialTemperature"
|
name="initialTemperature"
|
||||||
|
@ -121,8 +124,16 @@ onMounted(() => {
|
||||||
:decimal-places="2"
|
:decimal-places="2"
|
||||||
:positive="false"
|
:positive="false"
|
||||||
/>
|
/>
|
||||||
|
<VnSelect
|
||||||
|
v-model="data.typeFk"
|
||||||
|
url="entryTypes"
|
||||||
|
:fields="['code', 'description']"
|
||||||
|
option-value="code"
|
||||||
|
optionLabel="description"
|
||||||
|
sortBy="description"
|
||||||
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow class="q-py-sm">
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('entry.basicData.observation')"
|
:label="t('entry.basicData.observation')"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
|
@ -132,14 +143,20 @@ onMounted(() => {
|
||||||
fill-input
|
fill-input
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow class="q-py-sm">
|
||||||
<QCheckbox v-model="data.isOrdered" :label="t('entry.summary.ordered')" />
|
<VnCheckbox
|
||||||
<QCheckbox v-model="data.isConfirmed" :label="t('globals.confirmed')" />
|
v-model="data.isOrdered"
|
||||||
<QCheckbox
|
:label="t('entry.list.tableVisibleColumns.isOrdered')"
|
||||||
v-model="data.isExcludedFromAvailable"
|
|
||||||
:label="t('entry.summary.excludedFromAvailable')"
|
|
||||||
/>
|
/>
|
||||||
<QCheckbox
|
<VnCheckbox
|
||||||
|
v-model="data.isConfirmed"
|
||||||
|
:label="t('entry.list.tableVisibleColumns.isConfirmed')"
|
||||||
|
/>
|
||||||
|
<VnCheckbox
|
||||||
|
v-model="data.isExcludedFromAvailable"
|
||||||
|
:label="t('entry.list.tableVisibleColumns.isExcludedFromAvailable')"
|
||||||
|
/>
|
||||||
|
<VnCheckbox
|
||||||
:disable="!isAdministrative()"
|
:disable="!isAdministrative()"
|
||||||
v-model="data.isBooked"
|
v-model="data.isBooked"
|
||||||
:label="t('entry.basicData.booked')"
|
:label="t('entry.basicData.booked')"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref, computed } from 'vue';
|
||||||
|
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ import ItemDescriptor from 'src/pages/Item/Card/ItemDescriptor.vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import VnSelectEnum from 'src/components/common/VnSelectEnum.vue';
|
import VnSelectEnum from 'src/components/common/VnSelectEnum.vue';
|
||||||
import { checkEntryLock } from 'src/composables/checkEntryLock';
|
import { checkEntryLock } from 'src/composables/checkEntryLock';
|
||||||
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -57,31 +59,6 @@ const columns = [
|
||||||
createOrder: 12,
|
createOrder: 12,
|
||||||
width: '25px',
|
width: '25px',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: t('Buyer'),
|
|
||||||
name: 'workerFk',
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'TicketRequests/getItemTypeWorker',
|
|
||||||
fields: ['id', 'nickname'],
|
|
||||||
optionLabel: 'nickname',
|
|
||||||
sortBy: 'nickname ASC',
|
|
||||||
optionValue: 'id',
|
|
||||||
},
|
|
||||||
visible: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Family'),
|
|
||||||
name: 'itemTypeFk',
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'itemTypes',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
optionLabel: 'name',
|
|
||||||
optionValue: 'id',
|
|
||||||
},
|
|
||||||
visible: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'id',
|
name: 'id',
|
||||||
isId: true,
|
isId: true,
|
||||||
|
@ -111,16 +88,10 @@ const columns = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'left',
|
||||||
label: t('Article'),
|
label: t('Article'),
|
||||||
|
component: 'input',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'Items',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
optionLabel: 'name',
|
|
||||||
optionValue: 'id',
|
|
||||||
},
|
|
||||||
width: '85px',
|
width: '85px',
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
},
|
},
|
||||||
|
@ -212,7 +183,6 @@ const columns = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
|
||||||
labelAbbreviation: 'GM',
|
labelAbbreviation: 'GM',
|
||||||
label: t('Grouping selector'),
|
label: t('Grouping selector'),
|
||||||
toolTip: t('Grouping selector'),
|
toolTip: t('Grouping selector'),
|
||||||
|
@ -240,7 +210,6 @@ const columns = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
|
||||||
labelAbbreviation: 'G',
|
labelAbbreviation: 'G',
|
||||||
label: 'Grouping',
|
label: 'Grouping',
|
||||||
toolTip: 'Grouping',
|
toolTip: 'Grouping',
|
||||||
|
@ -294,7 +263,7 @@ const columns = [
|
||||||
align: 'center',
|
align: 'center',
|
||||||
label: t('Amount'),
|
label: t('Amount'),
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
width: '45px',
|
width: '75px',
|
||||||
component: 'number',
|
component: 'number',
|
||||||
attrs: {
|
attrs: {
|
||||||
positive: false,
|
positive: false,
|
||||||
|
@ -310,7 +279,9 @@ const columns = [
|
||||||
toolTip: t('Package'),
|
toolTip: t('Package'),
|
||||||
name: 'price2',
|
name: 'price2',
|
||||||
component: 'number',
|
component: 'number',
|
||||||
createDisable: true,
|
createAttrs: {
|
||||||
|
disable: true,
|
||||||
|
},
|
||||||
width: '35px',
|
width: '35px',
|
||||||
create: true,
|
create: true,
|
||||||
format: (row) => parseFloat(row['price2']).toFixed(2),
|
format: (row) => parseFloat(row['price2']).toFixed(2),
|
||||||
|
@ -320,7 +291,9 @@ const columns = [
|
||||||
label: t('Box'),
|
label: t('Box'),
|
||||||
name: 'price3',
|
name: 'price3',
|
||||||
component: 'number',
|
component: 'number',
|
||||||
createDisable: true,
|
createAttrs: {
|
||||||
|
disable: true,
|
||||||
|
},
|
||||||
cellEvent: {
|
cellEvent: {
|
||||||
'update:modelValue': async (value, oldValue, row) => {
|
'update:modelValue': async (value, oldValue, row) => {
|
||||||
row['price2'] = row['price2'] * (value / oldValue);
|
row['price2'] = row['price2'] * (value / oldValue);
|
||||||
|
@ -340,13 +313,6 @@ const columns = [
|
||||||
toggleIndeterminate: false,
|
toggleIndeterminate: false,
|
||||||
},
|
},
|
||||||
component: 'checkbox',
|
component: 'checkbox',
|
||||||
cellEvent: {
|
|
||||||
'update:modelValue': async (value, oldValue, row) => {
|
|
||||||
await axios.patch(`Items/${row['itemFk']}`, {
|
|
||||||
hasMinPrice: value,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
width: '25px',
|
width: '25px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -356,13 +322,6 @@ const columns = [
|
||||||
toolTip: t('Minimum price'),
|
toolTip: t('Minimum price'),
|
||||||
name: 'minPrice',
|
name: 'minPrice',
|
||||||
component: 'number',
|
component: 'number',
|
||||||
cellEvent: {
|
|
||||||
'update:modelValue': async (value, oldValue, row) => {
|
|
||||||
await axios.patch(`Items/${row['itemFk']}`, {
|
|
||||||
minPrice: value,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
width: '35px',
|
width: '35px',
|
||||||
style: (row) => {
|
style: (row) => {
|
||||||
if (!row?.hasMinPrice) return { color: 'var(--vn-label-color)' };
|
if (!row?.hasMinPrice) return { color: 'var(--vn-label-color)' };
|
||||||
|
@ -425,6 +384,23 @@ const columns = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
const buyerFk = ref(null);
|
||||||
|
const itemTypeFk = ref(null);
|
||||||
|
const inkFk = ref(null);
|
||||||
|
const tag1 = ref(null);
|
||||||
|
const tag2 = ref(null);
|
||||||
|
const tag1Filter = ref(null);
|
||||||
|
const tag2Filter = ref(null);
|
||||||
|
const filter = computed(() => {
|
||||||
|
const where = {};
|
||||||
|
where.workerFk = buyerFk.value;
|
||||||
|
where.itemTypeFk = itemTypeFk.value;
|
||||||
|
where.inkFk = inkFk.value;
|
||||||
|
where.tag1 = tag1.value;
|
||||||
|
where.tag2 = tag2.value;
|
||||||
|
|
||||||
|
return { where };
|
||||||
|
});
|
||||||
|
|
||||||
function getQuantityStyle(row) {
|
function getQuantityStyle(row) {
|
||||||
if (row?.quantity !== row?.stickers * row?.packing)
|
if (row?.quantity !== row?.stickers * row?.packing)
|
||||||
|
@ -610,6 +586,7 @@ onMounted(() => {
|
||||||
:url="`Entries/${entityId}/getBuyList`"
|
:url="`Entries/${entityId}/getBuyList`"
|
||||||
search-url="EntryBuys"
|
search-url="EntryBuys"
|
||||||
save-url="Buys/crud"
|
save-url="Buys/crud"
|
||||||
|
:filter="filter"
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
v-model:selected="selectedRows"
|
v-model:selected="selectedRows"
|
||||||
@on-fetch="() => footerFetchDataRef.fetch()"
|
@on-fetch="() => footerFetchDataRef.fetch()"
|
||||||
|
@ -655,7 +632,7 @@ onMounted(() => {
|
||||||
:is-editable="editableMode"
|
:is-editable="editableMode"
|
||||||
:without-header="!editableMode"
|
:without-header="!editableMode"
|
||||||
:with-filters="editableMode"
|
:with-filters="editableMode"
|
||||||
:right-search="editableMode"
|
:right-search="false"
|
||||||
:row-click="false"
|
:row-click="false"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:beforeSaveFn="beforeSave"
|
:beforeSaveFn="beforeSave"
|
||||||
|
@ -666,6 +643,46 @@ onMounted(() => {
|
||||||
data-cy="entry-buys"
|
data-cy="entry-buys"
|
||||||
overlay
|
overlay
|
||||||
>
|
>
|
||||||
|
<template #top-left>
|
||||||
|
<VnRow>
|
||||||
|
<VnSelect
|
||||||
|
:label="t('Buyer')"
|
||||||
|
v-model="buyerFk"
|
||||||
|
url="TicketRequests/getItemTypeWorker"
|
||||||
|
:fields="['id', 'nickname']"
|
||||||
|
option-label="nickname"
|
||||||
|
sort-by="nickname ASC"
|
||||||
|
/>
|
||||||
|
<VnSelect
|
||||||
|
:label="t('Family')"
|
||||||
|
v-model="itemTypeFk"
|
||||||
|
url="ItemTypes"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
option-label="name"
|
||||||
|
sort-by="name ASC"
|
||||||
|
/>
|
||||||
|
<VnSelect
|
||||||
|
:label="t('Color')"
|
||||||
|
v-model="inkFk"
|
||||||
|
url="Inks"
|
||||||
|
:fields="['id', 'name']"
|
||||||
|
option-label="name"
|
||||||
|
sort-by="name ASC"
|
||||||
|
/>
|
||||||
|
<VnInput
|
||||||
|
v-model="tag1Filter"
|
||||||
|
:label="t('Tag')"
|
||||||
|
@keyup.enter="tag1 = tag1Filter"
|
||||||
|
@remove="tag1 = null"
|
||||||
|
/>
|
||||||
|
<VnInput
|
||||||
|
v-model="tag2Filter"
|
||||||
|
:label="t('Tag')"
|
||||||
|
@keyup.enter="tag2 = tag2Filter"
|
||||||
|
@remove="tag2 = null"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
</template>
|
||||||
<template #column-hex="{ row }">
|
<template #column-hex="{ row }">
|
||||||
<VnColor :colors="row?.hexJson" style="height: 100%; min-width: 2000px" />
|
<VnColor :colors="row?.hexJson" style="height: 100%; min-width: 2000px" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -696,7 +713,7 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #column-footer-weight>
|
<template #column-footer-weight>
|
||||||
{{ footer?.weight }}
|
<span class="q-pr-xs">{{ footer?.weight }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-footer-quantity>
|
<template #column-footer-quantity>
|
||||||
<span :style="getQuantityStyle(footer)" data-cy="footer-quantity">
|
<span :style="getQuantityStyle(footer)" data-cy="footer-quantity">
|
||||||
|
@ -704,9 +721,8 @@ onMounted(() => {
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-footer-amount>
|
<template #column-footer-amount>
|
||||||
<span :style="getAmountStyle(footer)" data-cy="footer-amount">
|
<span data-cy="footer-amount">{{ footer?.amount }} / </span>
|
||||||
{{ footer?.amount }}
|
<span style="color: var(--q-positive)">{{ footer?.checkedAmount }}</span>
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
<template #column-create-itemFk="{ data }">
|
<template #column-create-itemFk="{ data }">
|
||||||
<VnSelect
|
<VnSelect
|
||||||
|
@ -767,6 +783,8 @@ onMounted(() => {
|
||||||
</template>
|
</template>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
|
Buyer: Comprador
|
||||||
|
Family: Familia
|
||||||
Article: Artículo
|
Article: Artículo
|
||||||
Siz.: Med.
|
Siz.: Med.
|
||||||
Size: Medida
|
Size: Medida
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import EntryDescriptor from './EntryDescriptor.vue';
|
import EntryDescriptor from './EntryDescriptor.vue';
|
||||||
import filter from './EntryFilter.js';
|
import filter from './EntryFilter.js';
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="Entry"
|
data-key="Entry"
|
||||||
url="Entries"
|
url="Entries"
|
||||||
:descriptor="EntryDescriptor"
|
:descriptor="EntryDescriptor"
|
||||||
|
|
|
@ -2,153 +2,82 @@
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import CrudModel from 'components/CrudModel.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
|
|
||||||
const { params } = useRoute();
|
const { params } = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const selectedRows = ref([]);
|
||||||
const entryObservationsRef = ref(null);
|
const entryObservationsRef = ref(null);
|
||||||
const entryObservationsOptions = ref([]);
|
const entityId = ref(params.id);
|
||||||
const selected = ref([]);
|
|
||||||
|
|
||||||
const sortEntryObservationOptions = (data) => {
|
|
||||||
entryObservationsOptions.value = [...data].sort((a, b) =>
|
|
||||||
a.description.localeCompare(b.description),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
name: 'observationType',
|
name: 'id',
|
||||||
label: t('entry.notes.observationType'),
|
isId: true,
|
||||||
field: (row) => row.observationTypeFk,
|
visible: false,
|
||||||
sortable: true,
|
isEditable: false,
|
||||||
options: entryObservationsOptions.value,
|
columnFilter: false,
|
||||||
required: true,
|
|
||||||
model: 'observationTypeFk',
|
|
||||||
optionValue: 'id',
|
|
||||||
optionLabel: 'description',
|
|
||||||
tabIndex: 1,
|
|
||||||
align: 'left',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
name: 'observationTypeFk',
|
||||||
|
label: t('entry.notes.observationType'),
|
||||||
|
component: 'select',
|
||||||
|
columnFilter: { inWhere: true },
|
||||||
|
attrs: {
|
||||||
|
inWhere: true,
|
||||||
|
url: 'ObservationTypes',
|
||||||
|
fields: ['id', 'description'],
|
||||||
|
optionValue: 'id',
|
||||||
|
optionLabel: 'description',
|
||||||
|
sortBy: 'description',
|
||||||
|
},
|
||||||
|
width: '30px',
|
||||||
|
create: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
name: 'description',
|
name: 'description',
|
||||||
label: t('globals.description'),
|
label: t('globals.description'),
|
||||||
field: (row) => row.description,
|
component: 'input',
|
||||||
tabIndex: 2,
|
columnFilter: false,
|
||||||
align: 'left',
|
attrs: { autogrow: true },
|
||||||
|
create: true,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const filter = computed(() => ({
|
||||||
|
fields: ['id', 'entryFk', 'observationTypeFk', 'description'],
|
||||||
|
include: ['observationType'],
|
||||||
|
where: { entryFk: entityId },
|
||||||
|
}));
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<VnTable
|
||||||
url="ObservationTypes"
|
|
||||||
@on-fetch="(data) => sortEntryObservationOptions(data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<CrudModel
|
|
||||||
data-key="EntryAccount"
|
|
||||||
url="EntryObservations"
|
|
||||||
model="EntryAccount"
|
|
||||||
:filter="{
|
|
||||||
fields: ['id', 'entryFk', 'observationTypeFk', 'description'],
|
|
||||||
where: { entryFk: params.id },
|
|
||||||
}"
|
|
||||||
ref="entryObservationsRef"
|
ref="entryObservationsRef"
|
||||||
:data-required="{ entryFk: params.id }"
|
data-key="EntryObservations"
|
||||||
v-model:selected="selected"
|
|
||||||
auto-load
|
|
||||||
>
|
|
||||||
<template #body="{ rows, validate }">
|
|
||||||
<QTable
|
|
||||||
v-model:selected="selected"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:rows="rows"
|
url="EntryObservations"
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
:user-filter="filter"
|
||||||
row-key="$index"
|
order="id ASC"
|
||||||
selection="multiple"
|
:disable-option="{ card: true }"
|
||||||
hide-pagination
|
:is-editable="true"
|
||||||
:grid="$q.screen.lt.md"
|
:right-search="true"
|
||||||
table-header-class="text-left"
|
v-model:selected="selectedRows"
|
||||||
>
|
:create="{
|
||||||
<template #body-cell-observationType="{ row, col }">
|
urlCreate: 'EntryObservations',
|
||||||
<QTd>
|
title: t('Create note'),
|
||||||
<VnSelect
|
onDataSaved: () => {
|
||||||
v-model="row[col.model]"
|
entryObservationsRef.reload();
|
||||||
:options="col.options"
|
},
|
||||||
:option-value="col.optionValue"
|
formInitialData: { entryFk: entityId },
|
||||||
:option-label="col.optionLabel"
|
}"
|
||||||
:autofocus="col.tabIndex == 1"
|
:table="{
|
||||||
input-debounce="0"
|
'row-key': 'id',
|
||||||
hide-selected
|
selection: 'multiple',
|
||||||
:required="true"
|
}"
|
||||||
|
auto-load
|
||||||
/>
|
/>
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #body-cell-description="{ row, col }">
|
|
||||||
<QTd>
|
|
||||||
<VnInput
|
|
||||||
:label="t('globals.description')"
|
|
||||||
v-model="row[col.name]"
|
|
||||||
:rules="validate('EntryObservation.description')"
|
|
||||||
/>
|
|
||||||
</QTd>
|
|
||||||
</template>
|
|
||||||
<template #item="props">
|
|
||||||
<div class="q-pa-xs col-xs-12 col-sm-6 grid-style-transition">
|
|
||||||
<QCard bordered flat>
|
|
||||||
<QCardSection>
|
|
||||||
<QCheckbox v-model="props.selected" dense />
|
|
||||||
</QCardSection>
|
|
||||||
<QSeparator />
|
|
||||||
<QList dense>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnSelect
|
|
||||||
v-model="props.row.observationTypeFk"
|
|
||||||
:options="entryObservationsOptions"
|
|
||||||
option-value="id"
|
|
||||||
option-label="description"
|
|
||||||
input-debounce="0"
|
|
||||||
hide-selected
|
|
||||||
:required="true"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
:label="t('globals.description')"
|
|
||||||
v-model="props.row.description"
|
|
||||||
:rules="
|
|
||||||
validate('EntryObservation.description')
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</QList>
|
|
||||||
</QCard>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</QTable>
|
|
||||||
</template>
|
|
||||||
</CrudModel>
|
|
||||||
<QPageSticky position="bottom-right" :offset="[25, 25]">
|
|
||||||
<QBtn
|
|
||||||
fab
|
|
||||||
color="primary"
|
|
||||||
icon="add"
|
|
||||||
v-shortcut="'+'"
|
|
||||||
@click="entryObservationsRef.insert()"
|
|
||||||
/>
|
|
||||||
</QPageSticky>
|
|
||||||
</template>
|
</template>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Add note: Añadir nota
|
Create note: Crear nota
|
||||||
Remove note: Quitar nota
|
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -92,13 +92,13 @@ onMounted(async () => {
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<VnCheckbox
|
<VnCheckbox
|
||||||
:label="t('entry.summary.ordered')"
|
:label="t('entry.list.tableVisibleColumns.isOrdered')"
|
||||||
v-model="entry.isOrdered"
|
v-model="entry.isOrdered"
|
||||||
:disable="true"
|
:disable="true"
|
||||||
size="xs"
|
size="xs"
|
||||||
/>
|
/>
|
||||||
<VnCheckbox
|
<VnCheckbox
|
||||||
:label="t('globals.confirmed')"
|
:label="t('entry.list.tableVisibleColumns.isConfirmed')"
|
||||||
v-model="entry.isConfirmed"
|
v-model="entry.isConfirmed"
|
||||||
:disable="true"
|
:disable="true"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
@ -110,7 +110,11 @@ onMounted(async () => {
|
||||||
size="xs"
|
size="xs"
|
||||||
/>
|
/>
|
||||||
<VnCheckbox
|
<VnCheckbox
|
||||||
:label="t('entry.summary.excludedFromAvailable')"
|
:label="
|
||||||
|
t(
|
||||||
|
'entry.list.tableVisibleColumns.isExcludedFromAvailable',
|
||||||
|
)
|
||||||
|
"
|
||||||
v-model="entry.isExcludedFromAvailable"
|
v-model="entry.isExcludedFromAvailable"
|
||||||
:disable="true"
|
:disable="true"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
|
|
@ -85,7 +85,7 @@ const entryFilterPanel = ref();
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
:label="t('entry.list.tableVisibleColumns.isConfirmed')"
|
label="LE"
|
||||||
v-model="params.isConfirmed"
|
v-model="params.isConfirmed"
|
||||||
toggle-indeterminate
|
toggle-indeterminate
|
||||||
>
|
>
|
||||||
|
@ -102,6 +102,7 @@ const entryFilterPanel = ref();
|
||||||
v-model="params.landed"
|
v-model="params.landed"
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
data-cy="landed"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
@ -121,13 +122,6 @@ const entryFilterPanel = ref();
|
||||||
rounded
|
rounded
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
v-model="params.invoiceNumber"
|
|
||||||
:label="t('params.invoiceNumber')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
|
@ -171,6 +165,7 @@ const entryFilterPanel = ref();
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
url="Warehouses"
|
url="Warehouses"
|
||||||
:fields="['id', 'name']"
|
:fields="['id', 'name']"
|
||||||
|
sort-by="name ASC"
|
||||||
hide-selected
|
hide-selected
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
|
@ -186,6 +181,7 @@ const entryFilterPanel = ref();
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
url="Warehouses"
|
url="Warehouses"
|
||||||
:fields="['id', 'name']"
|
:fields="['id', 'name']"
|
||||||
|
sort-by="name ASC"
|
||||||
hide-selected
|
hide-selected
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
|
@ -233,15 +229,6 @@ const entryFilterPanel = ref();
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
v-model="params.evaNotes"
|
|
||||||
:label="t('params.evaNotes')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
</template>
|
||||||
</VnFilterPanel>
|
</VnFilterPanel>
|
||||||
</template>
|
</template>
|
||||||
|
@ -267,7 +254,7 @@ en:
|
||||||
hasToShowDeletedEntries: Show deleted entries
|
hasToShowDeletedEntries: Show deleted entries
|
||||||
es:
|
es:
|
||||||
params:
|
params:
|
||||||
isExcludedFromAvailable: Inventario
|
isExcludedFromAvailable: Excluida
|
||||||
isOrdered: Pedida
|
isOrdered: Pedida
|
||||||
isConfirmed: Confirmado
|
isConfirmed: Confirmado
|
||||||
isReceived: Recibida
|
isReceived: Recibida
|
||||||
|
|
|
@ -1,264 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { onMounted, onUnmounted, ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
import { toDate } from 'src/filters';
|
|
||||||
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import EntryLatestBuysFilter from './EntryLatestBuysFilter.vue';
|
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
|
||||||
import VnImg from 'src/components/ui/VnImg.vue';
|
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
const { t } = useI18n();
|
|
||||||
const tableRef = ref();
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
align: 'center',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.image'),
|
|
||||||
name: 'itemFk',
|
|
||||||
columnField: {
|
|
||||||
component: VnImg,
|
|
||||||
attrs: ({ row }) => {
|
|
||||||
return {
|
|
||||||
id: row.id,
|
|
||||||
size: '50x50',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
columnFilter: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.itemFk'),
|
|
||||||
name: 'itemFk',
|
|
||||||
isTitle: true,
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.summary.packing'),
|
|
||||||
name: 'packing',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.summary.grouping'),
|
|
||||||
name: 'grouping',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.quantity'),
|
|
||||||
name: 'quantity',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.description'),
|
|
||||||
name: 'description',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.size'),
|
|
||||||
name: 'size',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.tags'),
|
|
||||||
name: 'tags',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.type'),
|
|
||||||
name: 'type',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.intrastat'),
|
|
||||||
name: 'intrastat',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.origin'),
|
|
||||||
name: 'origin',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.weightByPiece'),
|
|
||||||
name: 'weightByPiece',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.isActive'),
|
|
||||||
name: 'isActive',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.family'),
|
|
||||||
name: 'family',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.entryFk'),
|
|
||||||
name: 'entryFk',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.summary.buyingValue'),
|
|
||||||
name: 'buyingValue',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.freightValue'),
|
|
||||||
name: 'freightValue',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.comissionValue'),
|
|
||||||
name: 'comissionValue',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.packageValue'),
|
|
||||||
name: 'packageValue',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.isIgnored'),
|
|
||||||
name: 'isIgnored',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.price2'),
|
|
||||||
name: 'price2',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.price3'),
|
|
||||||
name: 'price3',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.minPrice'),
|
|
||||||
name: 'minPrice',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.ektFk'),
|
|
||||||
name: 'ektFk',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('globals.weight'),
|
|
||||||
name: 'weight',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.buys.packagingFk'),
|
|
||||||
name: 'packagingFk',
|
|
||||||
columnFilter: {
|
|
||||||
component: 'number',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.packingOut'),
|
|
||||||
name: 'packingOut',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.landing'),
|
|
||||||
name: 'landing',
|
|
||||||
component: 'date',
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landing)),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
stateStore.rightDrawer = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => (stateStore.rightDrawer = false));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<RightMenu>
|
|
||||||
<template #right-panel>
|
|
||||||
<EntryLatestBuysFilter data-key="LatestBuys" />
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<VnSubToolbar />
|
|
||||||
<VnTable
|
|
||||||
ref="tableRef"
|
|
||||||
data-key="LatestBuys"
|
|
||||||
url="Buys/latestBuysFilter"
|
|
||||||
order="id DESC"
|
|
||||||
:columns="columns"
|
|
||||||
redirect="entry"
|
|
||||||
:row-click="({ entryFk }) => tableRef.redirect(entryFk)"
|
|
||||||
auto-load
|
|
||||||
:right-search="false"
|
|
||||||
/>
|
|
||||||
</template>
|
|
|
@ -1,161 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|
||||||
import VnInput from 'components/common/VnInput.vue';
|
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
|
||||||
import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue';
|
|
||||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
|
|
||||||
defineProps({
|
|
||||||
dataKey: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const tagValues = ref([]);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<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"
|
|
||||||
option-label="nickname"
|
|
||||||
:fields="['id', 'nickname']"
|
|
||||||
sort-by="nickname ASC"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
rounded
|
|
||||||
use-input
|
|
||||||
@update:model-value="searchFn()"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem class="q-my-md">
|
|
||||||
<QItemSection>
|
|
||||||
<VnSelectSupplier
|
|
||||||
v-model="params.supplierFk"
|
|
||||||
url="Suppliers"
|
|
||||||
:fields="['id', 'name', 'nickname']"
|
|
||||||
sort-by="name ASC"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
rounded
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem class="q-my-md">
|
|
||||||
<QItemSection>
|
|
||||||
<VnInputDate
|
|
||||||
:label="t('components.itemsFilterPanel.started')"
|
|
||||||
v-model="params.from"
|
|
||||||
is-outlined
|
|
||||||
@update:model-value="searchFn()"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem class="q-my-md">
|
|
||||||
<QItemSection>
|
|
||||||
<VnInputDate
|
|
||||||
:label="t('components.itemsFilterPanel.ended')"
|
|
||||||
v-model="params.to"
|
|
||||||
is-outlined
|
|
||||||
@update:model-value="searchFn()"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('components.itemsFilterPanel.active')"
|
|
||||||
v-model="params.active"
|
|
||||||
toggle-indeterminate
|
|
||||||
@update:model-value="searchFn()"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
<QItemSection>
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('globals.visible')"
|
|
||||||
v-model="params.visible"
|
|
||||||
toggle-indeterminate
|
|
||||||
@update:model-value="searchFn()"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<QCheckbox
|
|
||||||
:label="t('components.itemsFilterPanel.floramondo')"
|
|
||||||
v-model="params.floramondo"
|
|
||||||
toggle-indeterminate
|
|
||||||
@update:model-value="searchFn()"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
|
|
||||||
<QItem
|
|
||||||
v-for="(value, index) in tagValues"
|
|
||||||
:key="value"
|
|
||||||
class="q-mt-md filter-value"
|
|
||||||
>
|
|
||||||
<QItemSection class="col">
|
|
||||||
<VnSelect
|
|
||||||
:label="t('params.tag')"
|
|
||||||
v-model="value.selectedTag"
|
|
||||||
:options="tagOptions"
|
|
||||||
option-label="name"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
rounded
|
|
||||||
:emit-value="false"
|
|
||||||
use-input
|
|
||||||
:is-clearable="false"
|
|
||||||
@update:model-value="getSelectedTagValues(value)"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
<QItemSection class="col">
|
|
||||||
<VnSelect
|
|
||||||
v-if="!value?.selectedTag?.isFree && value.valueOptions"
|
|
||||||
:label="t('params.value')"
|
|
||||||
v-model="value.value"
|
|
||||||
:options="value.valueOptions || []"
|
|
||||||
option-value="value"
|
|
||||||
option-label="value"
|
|
||||||
dense
|
|
||||||
outlined
|
|
||||||
rounded
|
|
||||||
emit-value
|
|
||||||
use-input
|
|
||||||
:disable="!value"
|
|
||||||
:is-clearable="false"
|
|
||||||
class="filter-input"
|
|
||||||
@update:model-value="applyTags(params, searchFn)"
|
|
||||||
/>
|
|
||||||
<VnInput
|
|
||||||
v-else
|
|
||||||
v-model="value.value"
|
|
||||||
:label="t('params.value')"
|
|
||||||
:disable="!value"
|
|
||||||
is-outlined
|
|
||||||
class="filter-input"
|
|
||||||
:is-clearable="false"
|
|
||||||
@keyup.enter="applyTags(params, searchFn)"
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
<QIcon
|
|
||||||
name="delete"
|
|
||||||
class="filter-icon"
|
|
||||||
@click="removeTag(index, params, searchFn)"
|
|
||||||
/>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</ItemsFilterPanel>
|
|
||||||
</template>
|
|
|
@ -107,9 +107,8 @@ const columns = computed(() => [
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'suppliers',
|
url: 'suppliers',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
where: { order: 'name DESC' },
|
sortBy: 'name ASC',
|
||||||
},
|
},
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
|
|
||||||
width: '110px',
|
width: '110px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -145,6 +144,7 @@ const columns = computed(() => [
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'agencyModes',
|
url: 'agencyModes',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
|
sortBy: 'name ASC',
|
||||||
},
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
|
@ -158,7 +158,6 @@ const columns = computed(() => [
|
||||||
component: 'input',
|
component: 'input',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
label: t('entry.list.tableVisibleColumns.warehouseOutFk'),
|
label: t('entry.list.tableVisibleColumns.warehouseOutFk'),
|
||||||
name: 'warehouseOutFk',
|
name: 'warehouseOutFk',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
@ -166,6 +165,7 @@ const columns = computed(() => [
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'warehouses',
|
url: 'warehouses',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
|
sortBy: 'name ASC',
|
||||||
},
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
|
@ -174,7 +174,6 @@ const columns = computed(() => [
|
||||||
width: '65px',
|
width: '65px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
label: t('entry.list.tableVisibleColumns.warehouseInFk'),
|
label: t('entry.list.tableVisibleColumns.warehouseInFk'),
|
||||||
name: 'warehouseInFk',
|
name: 'warehouseInFk',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
@ -182,6 +181,7 @@ const columns = computed(() => [
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'warehouses',
|
url: 'warehouses',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
|
sortBy: 'name ASC',
|
||||||
},
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
|
@ -190,7 +190,6 @@ const columns = computed(() => [
|
||||||
width: '65px',
|
width: '65px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
labelAbbreviation: t('Type'),
|
labelAbbreviation: t('Type'),
|
||||||
label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
||||||
toolTip: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
toolTip: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
||||||
|
@ -201,6 +200,7 @@ const columns = computed(() => [
|
||||||
fields: ['code', 'description'],
|
fields: ['code', 'description'],
|
||||||
optionValue: 'code',
|
optionValue: 'code',
|
||||||
optionLabel: 'description',
|
optionLabel: 'description',
|
||||||
|
sortBy: 'description',
|
||||||
},
|
},
|
||||||
width: '65px',
|
width: '65px',
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.entryTypeDescription),
|
format: (row, dashIfEmpty) => dashIfEmpty(row.entryTypeDescription),
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useQuasar, date } from 'quasar';
|
||||||
import { useQuasar } from 'quasar';
|
|
||||||
|
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import FormModelPopup from 'components/FormModelPopup.vue';
|
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
|
||||||
import EntryStockBoughtFilter from './EntryStockBoughtFilter.vue';
|
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import EntryStockBoughtDetail from 'src/pages/Entry/EntryStockBoughtDetail.vue';
|
import EntryStockBoughtDetail from 'src/pages/Entry/EntryStockBoughtDetail.vue';
|
||||||
|
import TravelDescriptorProxy from '../Travel/Card/TravelDescriptorProxy.vue';
|
||||||
|
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const state = useState();
|
const filterDate = ref(useFilterParams('StockBoughts').params);
|
||||||
const user = state.getUser();
|
|
||||||
const footer = ref({ bought: 0, reserve: 0 });
|
const footer = ref({ bought: 0, reserve: 0 });
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
|
@ -46,7 +45,7 @@ const columns = computed(() => [
|
||||||
optionValue: 'id',
|
optionValue: 'id',
|
||||||
},
|
},
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
width: '50px',
|
width: '60%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -56,20 +55,20 @@ const columns = computed(() => [
|
||||||
create: true,
|
create: true,
|
||||||
component: 'number',
|
component: 'number',
|
||||||
summation: true,
|
summation: true,
|
||||||
width: '50px',
|
|
||||||
format: ({ reserve }, dashIfEmpty) => dashIfEmpty(round(reserve)),
|
format: ({ reserve }, dashIfEmpty) => dashIfEmpty(round(reserve)),
|
||||||
|
width: '20%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'right',
|
||||||
label: t('entryStockBought.bought'),
|
label: t('entryStockBought.bought'),
|
||||||
name: 'bought',
|
name: 'bought',
|
||||||
summation: true,
|
summation: true,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
style: ({ reserve, bought }) => boughtStyle(bought, reserve),
|
style: ({ reserve, bought }) => boughtStyle(bought, reserve),
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
width: '20%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
label: t('entryStockBought.date'),
|
label: t('entryStockBought.date'),
|
||||||
name: 'dated',
|
name: 'dated',
|
||||||
component: 'date',
|
component: 'date',
|
||||||
|
@ -77,7 +76,7 @@ const columns = computed(() => [
|
||||||
create: true,
|
create: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'center',
|
||||||
name: 'tableActions',
|
name: 'tableActions',
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
|
@ -90,7 +89,7 @@ const columns = computed(() => [
|
||||||
component: EntryStockBoughtDetail,
|
component: EntryStockBoughtDetail,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
workerFk: row.workerFk,
|
workerFk: row.workerFk,
|
||||||
dated: userParams.value.dated,
|
dated: filterDate.value.dated,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -98,39 +97,29 @@ const columns = computed(() => [
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const fetchDataRef = ref();
|
const fetchDataRef = ref();
|
||||||
const travelDialogRef = ref(false);
|
const travelDialogRef = ref(false);
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const travel = ref(null);
|
const travel = ref(null);
|
||||||
const userParams = ref({
|
const filter = computed(() => ({
|
||||||
dated: Date.vnNew().toJSON(),
|
fields: ['id', 'm3', 'ref', 'warehouseInFk'],
|
||||||
});
|
|
||||||
|
|
||||||
const filter = ref({
|
|
||||||
fields: ['id', 'm3', 'warehouseInFk'],
|
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
relation: 'warehouseIn',
|
relation: 'warehouseIn',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['code'],
|
fields: ['code', 'name'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
where: {
|
where: {
|
||||||
shipped: (userParams.value.dated
|
shipped: date.adjustDate(filterDate.value.dated, {
|
||||||
? new Date(userParams.value.dated)
|
hour: 0,
|
||||||
: Date.vnNew()
|
minute: 0,
|
||||||
).setHours(0, 0, 0, 0),
|
second: 0,
|
||||||
|
}),
|
||||||
m3: { neq: null },
|
m3: { neq: null },
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
|
|
||||||
const setUserParams = async ({ dated }) => {
|
|
||||||
const shipped = (dated ? new Date(dated) : Date.vnNew()).setHours(0, 0, 0, 0);
|
|
||||||
filter.value.where.shipped = shipped;
|
|
||||||
fetchDataRef.value?.fetch();
|
|
||||||
};
|
|
||||||
|
|
||||||
function openDialog() {
|
function openDialog() {
|
||||||
travelDialogRef.value = true;
|
travelDialogRef.value = true;
|
||||||
|
@ -151,6 +140,31 @@ function round(value) {
|
||||||
function boughtStyle(bought, reserve) {
|
function boughtStyle(bought, reserve) {
|
||||||
return reserve < bought ? { color: 'var(--q-negative)' } : '';
|
return reserve < bought ? { color: 'var(--q-negative)' } : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function beforeSave(data, getChanges) {
|
||||||
|
const changes = data.creates;
|
||||||
|
if (!changes) return data;
|
||||||
|
const patchPromises = [];
|
||||||
|
|
||||||
|
for (const change of changes) {
|
||||||
|
if (change?.isReal === false && change?.reserve > 0) {
|
||||||
|
const postData = {
|
||||||
|
workerFk: change.workerFk,
|
||||||
|
reserve: change.reserve,
|
||||||
|
dated: filterDate.value.dated,
|
||||||
|
};
|
||||||
|
const promise = axios.post('StockBoughts', postData).catch((error) => {
|
||||||
|
console.error('Error processing change: ', change, error);
|
||||||
|
});
|
||||||
|
|
||||||
|
patchPromises.push(promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all(patchPromises);
|
||||||
|
const filteredChanges = changes.filter((change) => change?.isReal !== false);
|
||||||
|
data.creates = filteredChanges;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnSubToolbar>
|
<VnSubToolbar>
|
||||||
|
@ -158,18 +172,17 @@ function boughtStyle(bought, reserve) {
|
||||||
<FetchData
|
<FetchData
|
||||||
ref="fetchDataRef"
|
ref="fetchDataRef"
|
||||||
url="Travels"
|
url="Travels"
|
||||||
auto-load
|
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
@on-fetch="
|
@on-fetch="
|
||||||
(data) => {
|
(data) => {
|
||||||
travel = data.find(
|
travel = data.find(
|
||||||
(data) => data.warehouseIn?.code.toLowerCase() === 'vnh',
|
(data) => data.warehouseIn?.code?.toLowerCase() === 'vnh',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<VnRow class="travel">
|
<VnRow class="travel">
|
||||||
<div v-if="travel">
|
<div v-show="travel">
|
||||||
<span style="color: var(--vn-label-color)">
|
<span style="color: var(--vn-label-color)">
|
||||||
{{ t('entryStockBought.purchaseSpaces') }}:
|
{{ t('entryStockBought.purchaseSpaces') }}:
|
||||||
</span>
|
</span>
|
||||||
|
@ -180,7 +193,7 @@ function boughtStyle(bought, reserve) {
|
||||||
v-if="travel?.m3"
|
v-if="travel?.m3"
|
||||||
style="max-width: 20%"
|
style="max-width: 20%"
|
||||||
flat
|
flat
|
||||||
icon="edit"
|
icon="search"
|
||||||
@click="openDialog()"
|
@click="openDialog()"
|
||||||
:title="t('entryStockBought.editTravel')"
|
:title="t('entryStockBought.editTravel')"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -195,57 +208,42 @@ function boughtStyle(bought, reserve) {
|
||||||
:url-update="`Travels/${travel?.id}`"
|
:url-update="`Travels/${travel?.id}`"
|
||||||
model="travel"
|
model="travel"
|
||||||
:title="t('Travel m3')"
|
:title="t('Travel m3')"
|
||||||
:form-initial-data="{ id: travel?.id, m3: travel?.m3 }"
|
:form-initial-data="travel"
|
||||||
@on-data-saved="fetchDataRef.fetch()"
|
@on-data-saved="fetchDataRef.fetch()"
|
||||||
>
|
>
|
||||||
<template #form-inputs="{ data }">
|
<template #form-inputs="{ data }">
|
||||||
<VnInput
|
<span class="link">
|
||||||
v-model="data.id"
|
{{ data.ref }}
|
||||||
:label="t('id')"
|
<TravelDescriptorProxy :id="data.id" />
|
||||||
type="number"
|
</span>
|
||||||
disable
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
<VnInput v-model="data.m3" :label="t('m3')" type="number" />
|
<VnInput v-model="data.m3" :label="t('m3')" type="number" />
|
||||||
</template>
|
</template>
|
||||||
</FormModelPopup>
|
</FormModelPopup>
|
||||||
</QDialog>
|
</QDialog>
|
||||||
<RightMenu>
|
|
||||||
<template #right-panel>
|
|
||||||
<EntryStockBoughtFilter
|
|
||||||
data-key="StockBoughts"
|
|
||||||
@set-user-params="setUserParams"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</RightMenu>
|
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<div class="column items-center">
|
<div class="column items-center">
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="StockBoughts"
|
data-key="StockBoughts"
|
||||||
url="StockBoughts/getStockBought"
|
url="StockBoughts/getStockBought"
|
||||||
|
:beforeSaveFn="beforeSave"
|
||||||
save-url="StockBoughts/crud"
|
save-url="StockBoughts/crud"
|
||||||
search-url="StockBoughts"
|
search-url="StockBoughts"
|
||||||
order="reserve DESC"
|
order="bought DESC"
|
||||||
:right-search="false"
|
|
||||||
:is-editable="true"
|
:is-editable="true"
|
||||||
@on-fetch="(data) => setFooter(data)"
|
@on-fetch="
|
||||||
:create="{
|
async (data) => {
|
||||||
urlCreate: 'StockBoughts',
|
setFooter(data);
|
||||||
title: t('entryStockBought.reserveSomeSpace'),
|
await fetchDataRef.fetch();
|
||||||
onDataSaved: () => tableRef.reload(),
|
}
|
||||||
formInitialData: {
|
"
|
||||||
workerFk: user.id,
|
|
||||||
dated: Date.vnNow(),
|
|
||||||
},
|
|
||||||
}"
|
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:user-params="userParams"
|
|
||||||
:footer="true"
|
:footer="true"
|
||||||
table-height="80vh"
|
table-height="80vh"
|
||||||
auto-load
|
|
||||||
:column-search="false"
|
:column-search="false"
|
||||||
:without-header="true"
|
:without-header="true"
|
||||||
|
:user-params="{ dated: Date.vnNew() }"
|
||||||
|
auto-load
|
||||||
>
|
>
|
||||||
<template #column-workerFk="{ row }">
|
<template #column-workerFk="{ row }">
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
|
@ -278,9 +276,6 @@ function boughtStyle(bought, reserve) {
|
||||||
.column {
|
.column {
|
||||||
min-width: 35%;
|
min-width: 35%;
|
||||||
margin-top: 5%;
|
margin-top: 5%;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
.text-negative {
|
.text-negative {
|
||||||
color: $negative !important;
|
color: $negative !important;
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { onMounted } from 'vue';
|
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
|
||||||
|
|
||||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const props = defineProps({
|
|
||||||
dataKey: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const stateStore = useStateStore();
|
|
||||||
const emit = defineEmits(['set-user-params']);
|
|
||||||
const setUserParams = (params) => {
|
|
||||||
emit('set-user-params', params);
|
|
||||||
};
|
|
||||||
onMounted(async () => {
|
|
||||||
stateStore.rightDrawer = true;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<VnFilterPanel
|
|
||||||
:data-key="props.dataKey"
|
|
||||||
:search-button="true"
|
|
||||||
search-url="StockBoughts"
|
|
||||||
@set-user-params="setUserParams"
|
|
||||||
>
|
|
||||||
<template #tags="{ tag, formatFn }">
|
|
||||||
<div class="q-gutter-x-xs">
|
|
||||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #body="{ params, searchFn }">
|
|
||||||
<QItem class="q-my-sm">
|
|
||||||
<QItemSection>
|
|
||||||
<VnInputDate
|
|
||||||
id="date"
|
|
||||||
v-model="params.dated"
|
|
||||||
@update:model-value="
|
|
||||||
(value) => {
|
|
||||||
params.dated = value;
|
|
||||||
setUserParams(params);
|
|
||||||
searchFn();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:label="t('Date')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</VnFilterPanel>
|
|
||||||
</template>
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
params:
|
|
||||||
dated: Date
|
|
||||||
workerFk: Worker
|
|
||||||
es:
|
|
||||||
Date: Fecha
|
|
||||||
params:
|
|
||||||
dated: Fecha
|
|
||||||
workerFk: Trabajador
|
|
||||||
</i18n>
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||||
import { toDate } from 'src/filters/index';
|
import { toDate } from 'src/filters/index';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import EntryBuysTableDialog from './EntryBuysTableDialog.vue';
|
import EntrySupplierlDetail from './EntrySupplierlDetail.vue';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -18,18 +18,28 @@ const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'id',
|
name: 'id',
|
||||||
label: t('myEntries.id'),
|
label: t('entrySupplier.id'),
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
isId: true,
|
||||||
|
chip: {
|
||||||
|
condition: () => true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'supplierName',
|
||||||
|
label: t('entrySupplier.supplierName'),
|
||||||
|
cardVisible: true,
|
||||||
isTitle: true,
|
isTitle: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
visible: false,
|
visible: false,
|
||||||
align: 'right',
|
align: 'right',
|
||||||
label: t('myEntries.shipped'),
|
label: t('entrySupplier.shipped'),
|
||||||
name: 'shipped',
|
name: 'shipped',
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
name: 'fromShipped',
|
name: 'fromShipped',
|
||||||
label: t('myEntries.fromShipped'),
|
label: t('entrySupplier.fromShipped'),
|
||||||
component: 'date',
|
component: 'date',
|
||||||
},
|
},
|
||||||
format: ({ shipped }) => toDate(shipped),
|
format: ({ shipped }) => toDate(shipped),
|
||||||
|
@ -37,26 +47,26 @@ const columns = computed(() => [
|
||||||
{
|
{
|
||||||
visible: false,
|
visible: false,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('myEntries.shipped'),
|
label: t('entrySupplier.shipped'),
|
||||||
name: 'shipped',
|
name: 'shipped',
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
name: 'toShipped',
|
name: 'toShipped',
|
||||||
label: t('myEntries.toShipped'),
|
label: t('entrySupplier.toShipped'),
|
||||||
component: 'date',
|
component: 'date',
|
||||||
},
|
},
|
||||||
format: ({ shipped }) => toDate(shipped),
|
format: ({ shipped }) => toDate(shipped),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'left',
|
||||||
label: t('myEntries.shipped'),
|
label: t('entrySupplier.shipped'),
|
||||||
name: 'shipped',
|
name: 'shipped',
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
format: ({ shipped }) => toDate(shipped),
|
format: ({ shipped }) => toDate(shipped),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'left',
|
||||||
label: t('myEntries.landed'),
|
label: t('entrySupplier.landed'),
|
||||||
name: 'landed',
|
name: 'landed',
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
format: ({ landed }) => toDate(landed),
|
format: ({ landed }) => toDate(landed),
|
||||||
|
@ -64,15 +74,13 @@ const columns = computed(() => [
|
||||||
|
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'right',
|
||||||
label: t('myEntries.wareHouseIn'),
|
label: t('entrySupplier.wareHouseIn'),
|
||||||
name: 'warehouseInFk',
|
name: 'warehouseInFk',
|
||||||
format: (row) => {
|
format: ({ warehouseInName }) => warehouseInName,
|
||||||
row.warehouseInName;
|
|
||||||
},
|
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
name: 'warehouseInFk',
|
name: 'warehouseInFk',
|
||||||
label: t('myEntries.warehouseInFk'),
|
label: t('entrySupplier.warehouseInFk'),
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'warehouses',
|
url: 'warehouses',
|
||||||
|
@ -86,13 +94,13 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('myEntries.daysOnward'),
|
label: t('entrySupplier.daysOnward'),
|
||||||
name: 'daysOnward',
|
name: 'daysOnward',
|
||||||
visible: false,
|
visible: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('myEntries.daysAgo'),
|
label: t('entrySupplier.daysAgo'),
|
||||||
name: 'daysAgo',
|
name: 'daysAgo',
|
||||||
visible: false,
|
visible: false,
|
||||||
},
|
},
|
||||||
|
@ -101,8 +109,8 @@ const columns = computed(() => [
|
||||||
name: 'tableActions',
|
name: 'tableActions',
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
title: t('myEntries.printLabels'),
|
title: t('entrySupplier.printLabels'),
|
||||||
icon: 'move_item',
|
icon: 'search',
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
action: (row) => printBuys(row.id),
|
action: (row) => printBuys(row.id),
|
||||||
},
|
},
|
||||||
|
@ -112,7 +120,7 @@ const columns = computed(() => [
|
||||||
|
|
||||||
const printBuys = (rowId) => {
|
const printBuys = (rowId) => {
|
||||||
quasar.dialog({
|
quasar.dialog({
|
||||||
component: EntryBuysTableDialog,
|
component: EntrySupplierlDetail,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
id: rowId,
|
id: rowId,
|
||||||
},
|
},
|
||||||
|
@ -121,19 +129,18 @@ const printBuys = (rowId) => {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
<VnSearchbar
|
||||||
data-key="myEntriesList"
|
data-key="entrySupplierList"
|
||||||
url="Entries/filter"
|
url="Entries/filter"
|
||||||
:label="t('myEntries.search')"
|
:label="t('entrySupplier.search')"
|
||||||
:info="t('myEntries.searchInfo')"
|
:info="t('entrySupplier.searchInfo')"
|
||||||
/>
|
/>
|
||||||
<VnTable
|
<VnTable
|
||||||
data-key="myEntriesList"
|
data-key="entrySupplierList"
|
||||||
url="Entries/filter"
|
url="Entries/filter"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:user-params="params"
|
:user-params="params"
|
||||||
default-mode="card"
|
default-mode="card"
|
||||||
order="shipped DESC"
|
order="shipped DESC"
|
||||||
auto-load
|
auto-load
|
||||||
chip-locale="myEntries"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
|
@ -30,7 +30,7 @@ const entriesTableColumns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'itemFk',
|
name: 'itemFk',
|
||||||
field: 'itemFk',
|
field: 'itemFk',
|
||||||
label: t('entry.latestBuys.tableVisibleColumns.itemFk'),
|
label: t('entrySupplier.itemId'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -65,7 +65,15 @@ const entriesTableColumns = computed(() => [
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function downloadCSV(rows) {
|
function downloadCSV(rows) {
|
||||||
const headers = ['id', 'itemFk', 'name', 'stickers', 'packing', 'grouping', 'comment'];
|
const headers = [
|
||||||
|
'id',
|
||||||
|
'itemFk',
|
||||||
|
'name',
|
||||||
|
'stickers',
|
||||||
|
'packing',
|
||||||
|
'grouping',
|
||||||
|
'comment',
|
||||||
|
];
|
||||||
|
|
||||||
const csvRows = rows.map((row) => {
|
const csvRows = rows.map((row) => {
|
||||||
const buy = row;
|
const buy = row;
|
||||||
|
@ -119,17 +127,18 @@ function downloadCSV(rows) {
|
||||||
>
|
>
|
||||||
<template #top-left>
|
<template #top-left>
|
||||||
<QBtn
|
<QBtn
|
||||||
:label="t('myEntries.downloadCsv')"
|
:label="t('entrySupplier.downloadCsv')"
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="csv"
|
icon="csv"
|
||||||
@click="downloadCSV(rows)"
|
@click="downloadCSV(rows)"
|
||||||
unelevated
|
unelevated
|
||||||
|
data-cy="downloadCsvBtn"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #top-right>
|
<template #top-right>
|
||||||
<QBtn
|
<QBtn
|
||||||
class="q-mr-lg"
|
class="q-mr-lg"
|
||||||
:label="t('myEntries.printLabels')"
|
:label="t('entrySupplier.printLabels')"
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="print"
|
icon="print"
|
||||||
@click="
|
@click="
|
||||||
|
@ -148,13 +157,18 @@ function downloadCSV(rows) {
|
||||||
v-if="props.row.stickers > 0"
|
v-if="props.row.stickers > 0"
|
||||||
@click="
|
@click="
|
||||||
openReport(
|
openReport(
|
||||||
`Entries/${props.row.id}/buy-label-supplier`
|
`Entries/${props.row.id}/buy-label-supplier`,
|
||||||
|
{},
|
||||||
|
true,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
unelevated
|
unelevated
|
||||||
|
color="primary"
|
||||||
|
flat
|
||||||
|
data-cy="seeLabelBtn"
|
||||||
>
|
>
|
||||||
<QTooltip>{{
|
<QTooltip>{{
|
||||||
t('myEntries.viewLabel')
|
t('entrySupplier.viewLabel')
|
||||||
}}</QTooltip>
|
}}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QTr>
|
</QTr>
|
|
@ -38,7 +38,7 @@ const recalc = async () => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="q-pa-lg row justify-center">
|
<div class="q-pa-lg row justify-center">
|
||||||
<QCard class="bg-light" style="width: 300px">
|
<QCard class="bg-light" style="width: 300px" data-cy="wasteRecalc">
|
||||||
<QCardSection>
|
<QCardSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
class="q-mb-lg"
|
class="q-mb-lg"
|
||||||
|
@ -46,6 +46,7 @@ const recalc = async () => {
|
||||||
:label="$t('globals.from')"
|
:label="$t('globals.from')"
|
||||||
rounded
|
rounded
|
||||||
dense
|
dense
|
||||||
|
data-cy="dateFrom"
|
||||||
/>
|
/>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
class="q-mb-lg"
|
class="q-mb-lg"
|
||||||
|
@ -55,6 +56,7 @@ const recalc = async () => {
|
||||||
:disable="!dateFrom"
|
:disable="!dateFrom"
|
||||||
rounded
|
rounded
|
||||||
dense
|
dense
|
||||||
|
data-cy="dateTo"
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
color="primary"
|
color="primary"
|
||||||
|
@ -63,6 +65,7 @@ const recalc = async () => {
|
||||||
:loading="isLoading"
|
:loading="isLoading"
|
||||||
:disable="isLoading || !(dateFrom && dateTo)"
|
:disable="isLoading || !(dateFrom && dateTo)"
|
||||||
@click="recalc()"
|
@click="recalc()"
|
||||||
|
data-cy="recalc"
|
||||||
/>
|
/>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
</QCard>
|
</QCard>
|
||||||
|
|
|
@ -6,7 +6,7 @@ entry:
|
||||||
list:
|
list:
|
||||||
newEntry: New entry
|
newEntry: New entry
|
||||||
tableVisibleColumns:
|
tableVisibleColumns:
|
||||||
isExcludedFromAvailable: Exclude from inventory
|
isExcludedFromAvailable: Excluded from available
|
||||||
isOrdered: Ordered
|
isOrdered: Ordered
|
||||||
isConfirmed: Ready to label
|
isConfirmed: Ready to label
|
||||||
isReceived: Received
|
isReceived: Received
|
||||||
|
@ -33,7 +33,7 @@ entry:
|
||||||
invoiceAmount: Invoice amount
|
invoiceAmount: Invoice amount
|
||||||
ordered: Ordered
|
ordered: Ordered
|
||||||
booked: Booked
|
booked: Booked
|
||||||
excludedFromAvailable: Inventory
|
excludedFromAvailable: Excluded
|
||||||
travelReference: Reference
|
travelReference: Reference
|
||||||
travelAgency: Agency
|
travelAgency: Agency
|
||||||
travelShipped: Shipped
|
travelShipped: Shipped
|
||||||
|
@ -55,7 +55,7 @@ entry:
|
||||||
commission: Commission
|
commission: Commission
|
||||||
observation: Observation
|
observation: Observation
|
||||||
booked: Booked
|
booked: Booked
|
||||||
excludedFromAvailable: Inventory
|
excludedFromAvailable: Excluded
|
||||||
initialTemperature: Ini °C
|
initialTemperature: Ini °C
|
||||||
finalTemperature: Fin °C
|
finalTemperature: Fin °C
|
||||||
buys:
|
buys:
|
||||||
|
@ -65,27 +65,10 @@ entry:
|
||||||
printedStickers: Printed stickers
|
printedStickers: Printed stickers
|
||||||
notes:
|
notes:
|
||||||
observationType: Observation type
|
observationType: Observation type
|
||||||
latestBuys:
|
|
||||||
tableVisibleColumns:
|
|
||||||
image: Picture
|
|
||||||
itemFk: Item ID
|
|
||||||
weightByPiece: Weight/Piece
|
|
||||||
isActive: Active
|
|
||||||
family: Family
|
|
||||||
entryFk: Entry
|
|
||||||
freightValue: Freight value
|
|
||||||
comissionValue: Commission value
|
|
||||||
packageValue: Package value
|
|
||||||
isIgnored: Is ignored
|
|
||||||
price2: Grouping
|
|
||||||
price3: Packing
|
|
||||||
minPrice: Min
|
|
||||||
ektFk: Ekt
|
|
||||||
packingOut: Package out
|
|
||||||
landing: Landing
|
|
||||||
isExcludedFromAvailable: Es inventory
|
|
||||||
params:
|
params:
|
||||||
isExcludedFromAvailable: Exclude from inventory
|
entryFk: Entry
|
||||||
|
observationTypeFk: Observation type
|
||||||
|
isExcludedFromAvailable: Excluded from available
|
||||||
isOrdered: Ordered
|
isOrdered: Ordered
|
||||||
isConfirmed: Ready to label
|
isConfirmed: Ready to label
|
||||||
isReceived: Received
|
isReceived: Received
|
||||||
|
@ -127,13 +110,17 @@ entry:
|
||||||
company_name: Company name
|
company_name: Company name
|
||||||
itemTypeFk: Item type
|
itemTypeFk: Item type
|
||||||
workerFk: Worker id
|
workerFk: Worker id
|
||||||
|
daysAgo: Days ago
|
||||||
|
toShipped: T. shipped
|
||||||
|
fromShipped: F. shipped
|
||||||
|
supplierName: Supplier
|
||||||
search: Search entries
|
search: Search entries
|
||||||
searchInfo: You can search by entry reference
|
searchInfo: You can search by entry reference
|
||||||
descriptorMenu:
|
descriptorMenu:
|
||||||
showEntryReport: Show entry report
|
showEntryReport: Show entry report
|
||||||
entryFilter:
|
entryFilter:
|
||||||
params:
|
params:
|
||||||
isExcludedFromAvailable: Exclude from inventory
|
isExcludedFromAvailable: Excluded from available
|
||||||
invoiceNumber: Invoice number
|
invoiceNumber: Invoice number
|
||||||
travelFk: Travel
|
travelFk: Travel
|
||||||
companyFk: Company
|
companyFk: Company
|
||||||
|
@ -155,7 +142,7 @@ entryFilter:
|
||||||
warehouseOutFk: Origin
|
warehouseOutFk: Origin
|
||||||
warehouseInFk: Destiny
|
warehouseInFk: Destiny
|
||||||
entryTypeCode: Entry type
|
entryTypeCode: Entry type
|
||||||
myEntries:
|
entrySupplier:
|
||||||
id: ID
|
id: ID
|
||||||
landed: Landed
|
landed: Landed
|
||||||
shipped: Shipped
|
shipped: Shipped
|
||||||
|
@ -170,6 +157,8 @@ myEntries:
|
||||||
downloadCsv: Download CSV
|
downloadCsv: Download CSV
|
||||||
search: Search entries
|
search: Search entries
|
||||||
searchInfo: You can search by entry reference
|
searchInfo: You can search by entry reference
|
||||||
|
supplierName: Supplier
|
||||||
|
itemId: Item id
|
||||||
entryStockBought:
|
entryStockBought:
|
||||||
travel: Travel
|
travel: Travel
|
||||||
editTravel: Edit travel
|
editTravel: Edit travel
|
||||||
|
|
|
@ -6,7 +6,7 @@ entry:
|
||||||
list:
|
list:
|
||||||
newEntry: Nueva entrada
|
newEntry: Nueva entrada
|
||||||
tableVisibleColumns:
|
tableVisibleColumns:
|
||||||
isExcludedFromAvailable: Excluir del inventario
|
isExcludedFromAvailable: Excluir del disponible
|
||||||
isOrdered: Pedida
|
isOrdered: Pedida
|
||||||
isConfirmed: Lista para etiquetar
|
isConfirmed: Lista para etiquetar
|
||||||
isReceived: Recibida
|
isReceived: Recibida
|
||||||
|
@ -33,7 +33,7 @@ entry:
|
||||||
invoiceAmount: Importe
|
invoiceAmount: Importe
|
||||||
ordered: Pedida
|
ordered: Pedida
|
||||||
booked: Contabilizada
|
booked: Contabilizada
|
||||||
excludedFromAvailable: Inventario
|
excludedFromAvailable: Excluido
|
||||||
travelReference: Referencia
|
travelReference: Referencia
|
||||||
travelAgency: Agencia
|
travelAgency: Agencia
|
||||||
travelShipped: F. envio
|
travelShipped: F. envio
|
||||||
|
@ -56,7 +56,7 @@ entry:
|
||||||
observation: Observación
|
observation: Observación
|
||||||
commission: Comisión
|
commission: Comisión
|
||||||
booked: Contabilizada
|
booked: Contabilizada
|
||||||
excludedFromAvailable: Inventario
|
excludedFromAvailable: Excluido
|
||||||
initialTemperature: Ini °C
|
initialTemperature: Ini °C
|
||||||
finalTemperature: Fin °C
|
finalTemperature: Fin °C
|
||||||
buys:
|
buys:
|
||||||
|
@ -66,30 +66,12 @@ entry:
|
||||||
printedStickers: Etiquetas impresas
|
printedStickers: Etiquetas impresas
|
||||||
notes:
|
notes:
|
||||||
observationType: Tipo de observación
|
observationType: Tipo de observación
|
||||||
latestBuys:
|
|
||||||
tableVisibleColumns:
|
|
||||||
image: Foto
|
|
||||||
itemFk: Id Artículo
|
|
||||||
weightByPiece: Peso (gramos)/tallo
|
|
||||||
isActive: Activo
|
|
||||||
family: Familia
|
|
||||||
entryFk: Entrada
|
|
||||||
freightValue: Porte
|
|
||||||
comissionValue: Comisión
|
|
||||||
packageValue: Embalaje
|
|
||||||
isIgnored: Ignorado
|
|
||||||
price2: Grouping
|
|
||||||
price3: Packing
|
|
||||||
minPrice: Min
|
|
||||||
ektFk: Ekt
|
|
||||||
packingOut: Embalaje envíos
|
|
||||||
landing: Llegada
|
|
||||||
isExcludedFromAvailable: Es inventario
|
|
||||||
|
|
||||||
search: Buscar entradas
|
search: Buscar entradas
|
||||||
searchInfo: Puedes buscar por referencia de entrada
|
searchInfo: Puedes buscar por referencia de entrada
|
||||||
params:
|
params:
|
||||||
isExcludedFromAvailable: Excluir del inventario
|
entryFk: Entrada
|
||||||
|
observationTypeFk: Tipo de observación
|
||||||
|
isExcludedFromAvailable: Excluir del disponible
|
||||||
isOrdered: Pedida
|
isOrdered: Pedida
|
||||||
isConfirmed: Lista para etiquetar
|
isConfirmed: Lista para etiquetar
|
||||||
isReceived: Recibida
|
isReceived: Recibida
|
||||||
|
@ -131,9 +113,13 @@ entry:
|
||||||
company_name: Nombre empresa
|
company_name: Nombre empresa
|
||||||
itemTypeFk: Familia
|
itemTypeFk: Familia
|
||||||
workerFk: Comprador
|
workerFk: Comprador
|
||||||
|
daysAgo: Días atras
|
||||||
|
toShipped: F. salida(hasta)
|
||||||
|
fromShipped: F. salida(desde)
|
||||||
|
supplierName: Proveedor
|
||||||
entryFilter:
|
entryFilter:
|
||||||
params:
|
params:
|
||||||
isExcludedFromAvailable: Inventario
|
isExcludedFromAvailable: Excluido
|
||||||
isOrdered: Pedida
|
isOrdered: Pedida
|
||||||
isConfirmed: Confirmado
|
isConfirmed: Confirmado
|
||||||
isReceived: Recibida
|
isReceived: Recibida
|
||||||
|
@ -149,7 +135,7 @@ entryFilter:
|
||||||
warehouseInFk: Destino
|
warehouseInFk: Destino
|
||||||
entryTypeCode: Tipo de entrada
|
entryTypeCode: Tipo de entrada
|
||||||
hasToShowDeletedEntries: Mostrar entradas eliminadas
|
hasToShowDeletedEntries: Mostrar entradas eliminadas
|
||||||
myEntries:
|
entrySupplier:
|
||||||
id: ID
|
id: ID
|
||||||
landed: F. llegada
|
landed: F. llegada
|
||||||
shipped: F. salida
|
shipped: F. salida
|
||||||
|
@ -164,10 +150,12 @@ myEntries:
|
||||||
downloadCsv: Descargar CSV
|
downloadCsv: Descargar CSV
|
||||||
search: Buscar entradas
|
search: Buscar entradas
|
||||||
searchInfo: Puedes buscar por referencia de la entrada
|
searchInfo: Puedes buscar por referencia de la entrada
|
||||||
|
supplierName: Proveedor
|
||||||
|
itemId: Id artículo
|
||||||
entryStockBought:
|
entryStockBought:
|
||||||
travel: Envío
|
travel: Envío
|
||||||
editTravel: Editar envío
|
editTravel: Editar envío
|
||||||
purchaseSpaces: Espacios de compra
|
purchaseSpaces: Camiones reservados
|
||||||
buyer: Comprador
|
buyer: Comprador
|
||||||
reserve: Reservado
|
reserve: Reservado
|
||||||
bought: Comprado
|
bought: Comprado
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import InvoiceInDescriptor from './InvoiceInDescriptor.vue';
|
import InvoiceInDescriptor from './InvoiceInDescriptor.vue';
|
||||||
import { onBeforeRouteUpdate } from 'vue-router';
|
import { onBeforeRouteUpdate } from 'vue-router';
|
||||||
import { setRectificative } from '../composables/setRectificative';
|
import { setRectificative } from '../composables/setRectificative';
|
||||||
|
@ -9,7 +9,7 @@ onBeforeRouteUpdate(async (to) => await setRectificative(to));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="InvoiceIn"
|
data-key="InvoiceIn"
|
||||||
url="InvoiceIns"
|
url="InvoiceIns"
|
||||||
:descriptor="InvoiceInDescriptor"
|
:descriptor="InvoiceInDescriptor"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import InvoiceOutDescriptor from './InvoiceOutDescriptor.vue';
|
import InvoiceOutDescriptor from './InvoiceOutDescriptor.vue';
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import filter from './InvoiceOutFilter.js';
|
import filter from './InvoiceOutFilter.js';
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="InvoiceOut"
|
data-key="InvoiceOut"
|
||||||
url="InvoiceOuts"
|
url="InvoiceOuts"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
|
|
|
@ -75,6 +75,7 @@ function ticketFilter(invoice) {
|
||||||
icon="vn:client"
|
icon="vn:client"
|
||||||
color="primary"
|
color="primary"
|
||||||
:to="{ name: 'CustomerCard', params: { id: entity.client.id } }"
|
:to="{ name: 'CustomerCard', params: { id: entity.client.id } }"
|
||||||
|
data-cy="invoiceOutDescriptorCustomerCard"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('invoiceOut.card.customerCard') }}</QTooltip>
|
<QTooltip>{{ t('invoiceOut.card.customerCard') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
@ -86,6 +87,7 @@ function ticketFilter(invoice) {
|
||||||
name: 'TicketList',
|
name: 'TicketList',
|
||||||
query: { table: ticketFilter(entity) },
|
query: { table: ticketFilter(entity) },
|
||||||
}"
|
}"
|
||||||
|
data-cy="invoiceOutDescriptorTicketList"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('invoiceOut.card.ticketList') }}</QTooltip>
|
<QTooltip>{{ t('invoiceOut.card.ticketList') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -30,7 +31,7 @@ const states = ref();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnInput
|
||||||
:label="t('Customer ID')"
|
:label="t('globals.params.clientFk')"
|
||||||
v-model="params.clientFk"
|
v-model="params.clientFk"
|
||||||
is-outlined
|
is-outlined
|
||||||
/>
|
/>
|
||||||
|
@ -38,13 +39,17 @@ const states = ref();
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput v-model="params.fi" :label="t('FI')" is-outlined />
|
<VnInput
|
||||||
|
v-model="params.fi"
|
||||||
|
:label="t('globals.params.fi')"
|
||||||
|
is-outlined
|
||||||
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
:label="t('Amount')"
|
:label="t('globals.amount')"
|
||||||
v-model="params.amount"
|
v-model="params.amount"
|
||||||
is-outlined
|
is-outlined
|
||||||
data-cy="InvoiceOutFilterAmountBtn"
|
data-cy="InvoiceOutFilterAmountBtn"
|
||||||
|
@ -54,7 +59,7 @@ const states = ref();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('Min')"
|
:label="t('invoiceOut.params.min')"
|
||||||
dense
|
dense
|
||||||
lazy-rules
|
lazy-rules
|
||||||
outlined
|
outlined
|
||||||
|
@ -65,7 +70,7 @@ const states = ref();
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QInput
|
<QInput
|
||||||
:label="t('Max')"
|
:label="t('invoiceOut.params.max')"
|
||||||
dense
|
dense
|
||||||
lazy-rules
|
lazy-rules
|
||||||
outlined
|
outlined
|
||||||
|
@ -78,7 +83,7 @@ const states = ref();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
:label="t('Has PDF')"
|
:label="t('invoiceOut.params.hasPdf')"
|
||||||
toggle-indeterminate
|
toggle-indeterminate
|
||||||
v-model="params.hasPdf"
|
v-model="params.hasPdf"
|
||||||
/>
|
/>
|
||||||
|
@ -88,14 +93,31 @@ const states = ref();
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
v-model="params.created"
|
v-model="params.created"
|
||||||
:label="t('Created')"
|
:label="t('invoiceOut.params.created')"
|
||||||
is-outlined
|
is-outlined
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate v-model="params.dued" :label="t('Dued')" is-outlined />
|
<VnInputDate
|
||||||
|
v-model="params.dued"
|
||||||
|
:label="t('invoiceOut.params.dued')"
|
||||||
|
is-outlined
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnSelect
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
:label="t('globals.params.departmentFk')"
|
||||||
|
v-model="params.departmentFk"
|
||||||
|
option-value="id"
|
||||||
|
option-label="name"
|
||||||
|
url="Departments"
|
||||||
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { usePrintService } from 'src/composables/usePrintService';
|
import { usePrintService } from 'src/composables/usePrintService';
|
||||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
import InvoiceOutSummary from './Card/InvoiceOutSummary.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 { QBtn } from 'quasar';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
||||||
|
@ -16,6 +16,7 @@ import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
import VnRadio from 'src/components/common/VnRadio.vue';
|
import VnRadio from 'src/components/common/VnRadio.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
|
import DepartmentDescriptorProxy from '../Worker/Department/Card/DepartmentDescriptorProxy.vue';
|
||||||
import VnSection from 'src/components/common/VnSection.vue';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -94,6 +95,20 @@ const columns = computed(() => [
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'departmentFk',
|
||||||
|
label: t('customer.summary.team'),
|
||||||
|
cardVisible: true,
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Departments',
|
||||||
|
},
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'companyFk',
|
name: 'companyFk',
|
||||||
|
@ -193,7 +208,7 @@ watchEffect(selectedRows);
|
||||||
prefix="invoiceOut"
|
prefix="invoiceOut"
|
||||||
:array-data-props="{
|
:array-data-props="{
|
||||||
url: 'InvoiceOuts/filter',
|
url: 'InvoiceOuts/filter',
|
||||||
order: ['id DESC'],
|
order: 'id DESC',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<template #advanced-menu>
|
<template #advanced-menu>
|
||||||
|
@ -237,8 +252,14 @@ watchEffect(selectedRows);
|
||||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #column-departmentFk="{ row }">
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ dashIfEmpty(row.departmentName) }}
|
||||||
|
<DepartmentDescriptorProxy :id="row?.departmentFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
<template #more-create-dialog="{ data }">
|
<template #more-create-dialog="{ data }">
|
||||||
<div class="row q-col-gutter-xs">
|
<div class="row q-col-gutter-xs col-span-2">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="q-col-gutter-xs">
|
<div class="q-col-gutter-xs">
|
||||||
<VnRow fixed>
|
<VnRow fixed>
|
||||||
|
@ -404,7 +425,6 @@ watchEffect(selectedRows);
|
||||||
:label="
|
:label="
|
||||||
t('invoiceOutList.tableVisibleColumns.taxArea')
|
t('invoiceOutList.tableVisibleColumns.taxArea')
|
||||||
"
|
"
|
||||||
:options="taxAreasOptions"
|
|
||||||
option-label="code"
|
option-label="code"
|
||||||
option-value="code"
|
option-value="code"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.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 VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import InvoiceOutNegativeBasesFilter from './InvoiceOutNegativeBasesFilter.vue';
|
import InvoiceOutNegativeBasesFilter from './InvoiceOutNegativeBasesFilter.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
|
@ -115,18 +115,16 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'),
|
name: 'departmentFk',
|
||||||
name: 'workerName',
|
label: t('customer.summary.team'),
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/activeWithInheritedRole',
|
url: 'Departments',
|
||||||
fields: ['id', 'name'],
|
|
||||||
where: { role: 'salesPerson' },
|
|
||||||
},
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
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" />
|
<TicketDescriptorProxy :id="row.ticketFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-workerName="{ row }">
|
<template #column-departmentFk="{ row }">
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
{{ row.workerName }}
|
{{ row.departmentName }}
|
||||||
<WorkerDescriptorProxy :id="row.comercialId" />
|
<DepartmentDescriptorProxy :id="row.departmentFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #moreFilterPanel="{ params }">
|
<template #moreFilterPanel="{ params }">
|
||||||
|
|
|
@ -20,7 +20,7 @@ const props = defineProps({
|
||||||
<VnFilterPanel
|
<VnFilterPanel
|
||||||
:data-key="props.dataKey"
|
:data-key="props.dataKey"
|
||||||
:search-button="true"
|
:search-button="true"
|
||||||
:un-removable-params="['from', 'to']"
|
:unremovable-params="['from', 'to']"
|
||||||
:hidden-tags="['from', 'to']"
|
:hidden-tags="['from', 'to']"
|
||||||
>
|
>
|
||||||
<template #tags="{ tag, formatFn }">
|
<template #tags="{ tag, formatFn }">
|
||||||
|
@ -129,12 +129,15 @@ const props = defineProps({
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelectWorker
|
<VnSelect
|
||||||
:label="t('invoiceOut.negativeBases.comercial')"
|
outlined
|
||||||
v-model="params.workerName"
|
dense
|
||||||
option-value="name"
|
rounded
|
||||||
is-outlined
|
:label="t('globals.params.departmentFk')"
|
||||||
@update:model-value="searchFn()"
|
v-model="params.departmentFk"
|
||||||
|
option-value="id"
|
||||||
|
option-label="name"
|
||||||
|
url="Departments"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
|
|
@ -13,7 +13,6 @@ invoiceOut:
|
||||||
isActive: Active
|
isActive: Active
|
||||||
hasToInvoice: Has to invoice
|
hasToInvoice: Has to invoice
|
||||||
hasVerifiedData: Verified data
|
hasVerifiedData: Verified data
|
||||||
workerName: Worker
|
|
||||||
isTaxDataChecked: Verified data
|
isTaxDataChecked: Verified data
|
||||||
amount: Amount
|
amount: Amount
|
||||||
clientFk: Client
|
clientFk: Client
|
||||||
|
@ -27,6 +26,7 @@ invoiceOut:
|
||||||
max: Max
|
max: Max
|
||||||
hasPdf: Has PDF
|
hasPdf: Has PDF
|
||||||
search: Contains
|
search: Contains
|
||||||
|
departmentFk: Department
|
||||||
card:
|
card:
|
||||||
issued: Issued
|
issued: Issued
|
||||||
customerCard: Customer card
|
customerCard: Customer card
|
||||||
|
|
|
@ -13,7 +13,6 @@ invoiceOut:
|
||||||
isActive: Activo
|
isActive: Activo
|
||||||
hasToInvoice: Debe facturar
|
hasToInvoice: Debe facturar
|
||||||
hasVerifiedData: Datos verificados
|
hasVerifiedData: Datos verificados
|
||||||
workerName: Comercial
|
|
||||||
isTaxDataChecked: Datos comprobados
|
isTaxDataChecked: Datos comprobados
|
||||||
amount: Importe
|
amount: Importe
|
||||||
clientFk: Cliente
|
clientFk: Cliente
|
||||||
|
@ -27,6 +26,7 @@ invoiceOut:
|
||||||
max: Max
|
max: Max
|
||||||
hasPdf: Tiene PDF
|
hasPdf: Tiene PDF
|
||||||
search: Contiene
|
search: Contiene
|
||||||
|
departmentFk: Departamento
|
||||||
card:
|
card:
|
||||||
issued: Fecha emisión
|
issued: Fecha emisión
|
||||||
customerCard: Ficha del cliente
|
customerCard: Ficha del cliente
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import ItemDescriptor from './ItemDescriptor.vue';
|
import ItemDescriptor from './ItemDescriptor.vue';
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="Item"
|
data-key="Item"
|
||||||
:url="`Items/${$route.params.id}/getCard`"
|
:url="`Items/${$route.params.id}/getCard`"
|
||||||
:descriptor="ItemDescriptor"
|
:descriptor="ItemDescriptor"
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { ref, computed, onMounted } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.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 { useStateStore } from 'stores/useStateStore';
|
||||||
import { toCurrency } from 'filters/index';
|
import { toCurrency } from 'filters/index';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
|
@ -61,6 +62,7 @@ const columns = computed(() => [
|
||||||
columnClass: 'expand',
|
columnClass: 'expand',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
align: 'left',
|
||||||
label: t('item.buyRequest.requester'),
|
label: t('item.buyRequest.requester'),
|
||||||
name: 'requesterName',
|
name: 'requesterName',
|
||||||
component: 'select',
|
component: 'select',
|
||||||
|
@ -77,6 +79,19 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
columnClass: 'shrink',
|
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'),
|
label: t('item.buyRequest.requested'),
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
|
@ -107,6 +122,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
columnClass: 'shrink',
|
columnClass: 'shrink',
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: t('globals.item'),
|
label: t('globals.item'),
|
||||||
name: 'item',
|
name: 'item',
|
||||||
|
@ -262,6 +278,12 @@ const onDenyAccept = (_, responseData) => {
|
||||||
<WorkerDescriptorProxy :id="row.requesterFk" />
|
<WorkerDescriptorProxy :id="row.requesterFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
<template #column-departmentFk="{ row }">
|
||||||
|
<span class="link" @click.stop>
|
||||||
|
{{ row.departmentName }}
|
||||||
|
<DepartmentDescriptorProxy :id="row.departmentFk" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #column-item="{ row }">
|
<template #column-item="{ row }">
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -221,7 +221,7 @@ en:
|
||||||
attenderFk: Atender
|
attenderFk: Atender
|
||||||
clientFk: Client id
|
clientFk: Client id
|
||||||
warehouseFk: Warehouse
|
warehouseFk: Warehouse
|
||||||
requesterFk: Salesperson
|
requesterFk: Requester
|
||||||
from: From
|
from: From
|
||||||
to: To
|
to: To
|
||||||
mine: For me
|
mine: For me
|
||||||
|
@ -239,7 +239,7 @@ es:
|
||||||
attenderFk: Comprador
|
attenderFk: Comprador
|
||||||
clientFk: Id cliente
|
clientFk: Id cliente
|
||||||
warehouseFk: Almacén
|
warehouseFk: Almacén
|
||||||
requesterFk: Comercial
|
requesterFk: Solicitante
|
||||||
from: Desde
|
from: Desde
|
||||||
to: Hasta
|
to: Hasta
|
||||||
mine: Para mi
|
mine: Para mi
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import ItemTypeDescriptor from 'src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue';
|
import ItemTypeDescriptor from 'src/pages/Item/ItemType/Card/ItemTypeDescriptor.vue';
|
||||||
import filter from './ItemTypeFilter.js';
|
import filter from './ItemTypeFilter.js';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="ItemType"
|
data-key="ItemType"
|
||||||
url="ItemTypes"
|
url="ItemTypes"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
|
|
|
@ -7,6 +7,7 @@ import filter from './ItemTypeFilter.js';
|
||||||
import CardSummary from 'components/ui/CardSummary.vue';
|
import CardSummary from 'components/ui/CardSummary.vue';
|
||||||
import VnLv from 'src/components/ui/VnLv.vue';
|
import VnLv from 'src/components/ui/VnLv.vue';
|
||||||
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
||||||
|
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||||
|
|
||||||
onUpdated(() => summaryRef.value.fetch());
|
onUpdated(() => summaryRef.value.fetch());
|
||||||
|
|
||||||
|
@ -62,13 +63,10 @@ async function setItemTypeData(data) {
|
||||||
</template>
|
</template>
|
||||||
<template #body>
|
<template #body>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-one">
|
||||||
<router-link
|
<VnTitle
|
||||||
:to="{ name: 'ItemTypeBasicData', params: { id: entityId } }"
|
:url="`#/item/item-type/${entityId}/basic-data`"
|
||||||
class="header header-link"
|
:text="$t('globals.summary.basicData')"
|
||||||
>
|
/>
|
||||||
{{ t('globals.summary.basicData') }}
|
|
||||||
<QIcon name="open_in_new" />
|
|
||||||
</router-link>
|
|
||||||
<VnLv :label="t('itemType.summary.id')" :value="itemType.id" />
|
<VnLv :label="t('itemType.summary.id')" :value="itemType.id" />
|
||||||
<VnLv :label="t('itemType.shared.code')" :value="itemType.code" />
|
<VnLv :label="t('itemType.shared.code')" :value="itemType.code" />
|
||||||
<VnLv :label="t('itemType.shared.name')" :value="itemType.name" />
|
<VnLv :label="t('itemType.shared.name')" :value="itemType.name" />
|
||||||
|
|
|
@ -84,7 +84,7 @@ item:
|
||||||
attenderFk: Atender
|
attenderFk: Atender
|
||||||
clientFk: Client id
|
clientFk: Client id
|
||||||
warehouseFk: Warehouse
|
warehouseFk: Warehouse
|
||||||
requesterFk: Salesperson
|
requesterFk: Requester
|
||||||
from: From
|
from: From
|
||||||
to: To
|
to: To
|
||||||
mine: For me
|
mine: For me
|
||||||
|
|
|
@ -93,7 +93,7 @@ item:
|
||||||
attenderFk: Comprador
|
attenderFk: Comprador
|
||||||
clientFk: Id cliente
|
clientFk: Id cliente
|
||||||
warehouseFk: Almacén
|
warehouseFk: Almacén
|
||||||
requesterFk: Comercial
|
requesterFk: Solicitante
|
||||||
from: Desde
|
from: Desde
|
||||||
to: Hasta
|
to: Hasta
|
||||||
mine: Para mi
|
mine: Para mi
|
||||||
|
|
|
@ -31,7 +31,7 @@ function exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
return { [`c.id`]: value };
|
return { [`c.id`]: value };
|
||||||
case 'salesPersonFk':
|
case 'departmentFk':
|
||||||
return { [`c.${param}`]: value };
|
return { [`c.${param}`]: value };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,25 +62,17 @@ const columns = computed(() => [
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('salesClientsTable.salesPerson'),
|
|
||||||
name: 'salesPersonFk',
|
|
||||||
field: 'salesPerson',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
name: 'departmentFk',
|
||||||
|
label: t('customer.summary.team'),
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Departments',
|
||||||
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
},
|
},
|
||||||
optionFilter: 'firstName',
|
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
|
||||||
columnFilter: {
|
|
||||||
component: 'select',
|
|
||||||
attrs: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
sortBy: 'nickname ASC',
|
|
||||||
where: { role: 'salesPerson' },
|
|
||||||
useLike: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
columnClass: 'no-padding',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('salesClientsTable.client'),
|
label: t('salesClientsTable.client'),
|
||||||
|
@ -128,9 +120,9 @@ const columns = computed(() => [
|
||||||
<VnInputDate v-model="to" :label="$t('globals.to')" dense />
|
<VnInputDate v-model="to" :label="$t('globals.to')" dense />
|
||||||
</VnRow>
|
</VnRow>
|
||||||
</template>
|
</template>
|
||||||
<template #column-salesPersonFk="{ row }">
|
<template #column-departmentFk="{ row }">
|
||||||
<span class="link" :title="row.salesPerson" v-text="row.salesPerson" />
|
<span class="link" :title="row.department" v-text="row.department" />
|
||||||
<WorkerDescriptorProxy :id="row.salesPersonFk" dense />
|
<WorkerDescriptorProxy :id="row.departmentFk" dense />
|
||||||
</template>
|
</template>
|
||||||
<template #column-clientFk="{ row }">
|
<template #column-clientFk="{ row }">
|
||||||
<span class="link" :title="row.clientName" v-text="row.clientName" />
|
<span class="link" :title="row.clientName" v-text="row.clientName" />
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
|
|
||||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import VnTable from 'components/VnTable/VnTable.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 { toDateFormat, toDateTimeFormat } from 'src/filters/date.js';
|
||||||
import { toCurrency } from 'src/filters';
|
import { toCurrency } from 'src/filters';
|
||||||
|
@ -20,8 +20,8 @@ function exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
return { [`c.id`]: value };
|
return { [`c.id`]: value };
|
||||||
case 'salesPersonFk':
|
case 'departmentFk':
|
||||||
return { [`c.salesPersonFk`]: value };
|
return { [`c.departmentFk`]: value };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,20 +63,18 @@ const columns = computed(() => [
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('salesClientsTable.salesPerson'),
|
|
||||||
name: 'salesPersonFk',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
optionFilter: 'firstName',
|
name: 'departmentFk',
|
||||||
columnFilter: {
|
label: t('customer.summary.team'),
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/activeWithInheritedRole',
|
url: 'Departments',
|
||||||
fields: ['id', 'name'],
|
|
||||||
sortBy: 'nickname ASC',
|
|
||||||
where: { role: 'salesPerson' },
|
|
||||||
useLike: false,
|
|
||||||
},
|
},
|
||||||
|
create: true,
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
},
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('salesOrdersTable.import'),
|
label: t('salesOrdersTable.import'),
|
||||||
|
@ -184,11 +182,10 @@ const openTab = (id) =>
|
||||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
<template #column-departmentFk="{ row }">
|
||||||
<template #column-salesPersonFk="{ row }">
|
|
||||||
<QTd @click.stop>
|
<QTd @click.stop>
|
||||||
<span class="link" v-text="row.salesPerson" />
|
<span class="link" v-text="row.departmentName" />
|
||||||
<WorkerDescriptorProxy :id="row.salesPersonFk" dense />
|
<DepartmentDescriptorProxy :id="row.departmentFk" dense />
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
|
|
@ -9,7 +9,6 @@ import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import { dateRange } from 'src/filters';
|
import { dateRange } from 'src/filters';
|
||||||
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
|
||||||
|
|
||||||
defineProps({ dataKey: { type: String, required: true } });
|
defineProps({ dataKey: { type: String, required: true } });
|
||||||
const { t, te } = useI18n();
|
const { t, te } = useI18n();
|
||||||
|
@ -113,16 +112,16 @@ const getLocale = (label) => {
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelectWorker
|
<VnSelect
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
rounded
|
rounded
|
||||||
:label="t('globals.params.salesPersonFk')"
|
:label="t('globals.params.departmentFk')"
|
||||||
v-model="params.salesPersonFk"
|
v-model="params.departmentFk"
|
||||||
:params="{ departmentCodes: ['VT'] }"
|
option-value="id"
|
||||||
:no-one="true"
|
option-label="name"
|
||||||
>
|
url="Departments"
|
||||||
</VnSelectWorker>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import FetchData from 'components/FetchData.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';
|
||||||
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||||
|
@ -49,8 +49,8 @@ function exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'stateFk':
|
case 'stateFk':
|
||||||
return { 'ts.stateFk': value };
|
return { 'ts.stateFk': value };
|
||||||
case 'salesPersonFk':
|
case 'departmentFk':
|
||||||
return { 'c.salesPersonFk': !value ? null : value };
|
return { 'c.departmentFk': !value ? null : value };
|
||||||
case 'provinceFk':
|
case 'provinceFk':
|
||||||
return { 'a.provinceFk': value };
|
return { 'a.provinceFk': value };
|
||||||
case 'theoreticalHour':
|
case 'theoreticalHour':
|
||||||
|
@ -108,19 +108,18 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('salesClientsTable.salesPerson'),
|
|
||||||
name: 'salesPersonFk',
|
|
||||||
field: 'userName',
|
|
||||||
align: 'left',
|
align: 'left',
|
||||||
columnFilter: {
|
name: 'departmentFk',
|
||||||
|
label: t('customer.summary.team'),
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/search?departmentCodes=["VT"]',
|
url: 'Departments',
|
||||||
fields: ['id', 'name', 'nickname', 'code'],
|
|
||||||
sortBy: 'nickname ASC',
|
|
||||||
optionLabel: 'nickname',
|
|
||||||
},
|
},
|
||||||
|
create: true,
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
},
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(row.departmentName),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('salesClientsTable.date'),
|
label: t('salesClientsTable.date'),
|
||||||
|
@ -437,10 +436,10 @@ const openTab = (id) => useOpenURL(`#/ticket/${id}/sale`);
|
||||||
<CustomerDescriptorProxy :id="row.clientFk" />
|
<CustomerDescriptorProxy :id="row.clientFk" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #column-salesPersonFk="{ row }">
|
<template #column-departmentFk="{ row }">
|
||||||
<div @click.stop :title="row.userName">
|
<div @click.stop :title="row.departmentName">
|
||||||
<span class="link" v-text="dashIfEmpty(row.userName)" />
|
<span class="link" v-text="dashIfEmpty(row.departmentName)" />
|
||||||
<WorkerDescriptorProxy :id="row.salesPersonFk" />
|
<DepartmentDescriptorProxy :id="row.departmentFk" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #column-shippedDate="{ row }">
|
<template #column-shippedDate="{ row }">
|
||||||
|
|
|
@ -7,7 +7,6 @@ salesClientsTable:
|
||||||
to: To
|
to: To
|
||||||
date: Date
|
date: Date
|
||||||
hour: Hour
|
hour: Hour
|
||||||
salesPerson: Salesperson
|
|
||||||
client: Client
|
client: Client
|
||||||
salesOrdersTable:
|
salesOrdersTable:
|
||||||
delete: Delete
|
delete: Delete
|
||||||
|
|
|
@ -7,7 +7,6 @@ salesClientsTable:
|
||||||
to: Hasta
|
to: Hasta
|
||||||
date: Fecha
|
date: Fecha
|
||||||
hour: Hora
|
hour: Hora
|
||||||
salesPerson: Comercial
|
|
||||||
client: Cliente
|
client: Cliente
|
||||||
salesOrdersTable:
|
salesOrdersTable:
|
||||||
delete: Eliminar
|
delete: Eliminar
|
||||||
|
|
|
@ -64,17 +64,7 @@ const orderFilter = {
|
||||||
{
|
{
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
scope: {
|
scope: {
|
||||||
fields: [
|
fields: ['name', 'isActive', 'isFreezed', 'isTaxDataChecked'],
|
||||||
'salesPersonFk',
|
|
||||||
'name',
|
|
||||||
'isActive',
|
|
||||||
'isFreezed',
|
|
||||||
'isTaxDataChecked',
|
|
||||||
],
|
|
||||||
include: {
|
|
||||||
relation: 'salesPersonUser',
|
|
||||||
scope: { fields: ['id', 'name'] },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -167,7 +157,7 @@ const onClientChange = async (clientId) => {
|
||||||
!data.isConfirmed &&
|
!data.isConfirmed &&
|
||||||
agencyList?.length &&
|
agencyList?.length &&
|
||||||
agencyList.some(
|
agencyList.some(
|
||||||
(agency) => agency.agencyModeFk === data.agency_id
|
(agency) => agency.agencyModeFk === data.agency_id,
|
||||||
)
|
)
|
||||||
? data.agencyModeFk
|
? data.agencyModeFk
|
||||||
: null
|
: null
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import VnCardBeta from 'components/common/VnCardBeta.vue';
|
import VnCard from 'components/common/VnCard.vue';
|
||||||
import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
|
import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
|
||||||
import filter from './OrderFilter.js';
|
import filter from './OrderFilter.js';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnCardBeta
|
<VnCard
|
||||||
data-key="Order"
|
data-key="Order"
|
||||||
url="Orders"
|
url="Orders"
|
||||||
:filter="filter"
|
:filter="filter"
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue