Merge branch 'test' into 7356_ticketService
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
ba98816f93
|
@ -95,6 +95,10 @@ const $props = defineProps({
|
||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: '800px',
|
default: '800px',
|
||||||
},
|
},
|
||||||
|
onDataSaved: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
||||||
const modelValue = computed(
|
const modelValue = computed(
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, useAttrs, nextTick } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useState } from 'src/composables/useState';
|
||||||
|
|
||||||
import FormModel from 'components/FormModel.vue';
|
import FormModel from 'components/FormModel.vue';
|
||||||
|
|
||||||
const emit = defineEmits(['onDataSaved', 'onDataCanceled']);
|
const emit = defineEmits(['onDataSaved', 'onDataCanceled']);
|
||||||
|
|
||||||
defineProps({
|
const props = defineProps({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
|
@ -22,12 +23,21 @@ defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const attrs = useAttrs();
|
||||||
|
const state = useState();
|
||||||
const formModelRef = ref(null);
|
const formModelRef = ref(null);
|
||||||
const closeButton = ref(null);
|
const closeButton = ref(null);
|
||||||
const isSaveAndContinue = ref(false);
|
const isSaveAndContinue = ref(props.showSaveAndContinueBtn);
|
||||||
const onDataSaved = (formData, requestResponse) => {
|
const isLoading = computed(() => formModelRef.value?.isLoading);
|
||||||
if (closeButton.value && !isSaveAndContinue.value) closeButton.value.click();
|
const reset = computed(() => formModelRef.value?.reset);
|
||||||
|
|
||||||
|
const onDataSaved = async (formData, requestResponse) => {
|
||||||
|
if (!isSaveAndContinue.value) closeButton.value?.click();
|
||||||
|
if (isSaveAndContinue.value) {
|
||||||
|
await nextTick();
|
||||||
|
state.set(attrs.model, attrs.formInitialData);
|
||||||
|
}
|
||||||
|
isSaveAndContinue.value = props.showSaveAndContinueBtn;
|
||||||
emit('onDataSaved', formData, requestResponse);
|
emit('onDataSaved', formData, requestResponse);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,9 +46,6 @@ const onClick = async (saveAndContinue) => {
|
||||||
await formModelRef.value.save();
|
await formModelRef.value.save();
|
||||||
};
|
};
|
||||||
|
|
||||||
const isLoading = computed(() => formModelRef.value?.isLoading);
|
|
||||||
const reset = computed(() => formModelRef.value?.reset);
|
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
isLoading,
|
isLoading,
|
||||||
onDataSaved,
|
onDataSaved,
|
||||||
|
@ -74,10 +81,7 @@ defineExpose({
|
||||||
data-cy="FormModelPopup_cancel"
|
data-cy="FormModelPopup_cancel"
|
||||||
v-close-popup
|
v-close-popup
|
||||||
z-max
|
z-max
|
||||||
@click="
|
@click="emit('onDataCanceled')"
|
||||||
isSaveAndContinue = false;
|
|
||||||
emit('onDataCanceled');
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
:flat="showSaveAndContinueBtn"
|
:flat="showSaveAndContinueBtn"
|
||||||
|
|
|
@ -91,7 +91,6 @@ const components = {
|
||||||
event: updateEvent,
|
event: updateEvent,
|
||||||
attrs: {
|
attrs: {
|
||||||
...defaultAttrs,
|
...defaultAttrs,
|
||||||
style: 'min-width: 150px',
|
|
||||||
},
|
},
|
||||||
forceAttrs,
|
forceAttrs,
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,6 +31,7 @@ import VnLv from 'components/ui/VnLv.vue';
|
||||||
import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
|
import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
|
||||||
import VnTableFilter from './VnTableFilter.vue';
|
import VnTableFilter from './VnTableFilter.vue';
|
||||||
import { getColAlign } from 'src/composables/getColAlign';
|
import { getColAlign } from 'src/composables/getColAlign';
|
||||||
|
import RightMenu from '../common/RightMenu.vue';
|
||||||
|
|
||||||
const arrayData = useArrayData(useAttrs()['data-key']);
|
const arrayData = useArrayData(useAttrs()['data-key']);
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
|
@ -137,6 +138,10 @@ const $props = defineProps({
|
||||||
createComplement: {
|
createComplement: {
|
||||||
type: Object,
|
type: Object,
|
||||||
},
|
},
|
||||||
|
dataCy: {
|
||||||
|
type: String,
|
||||||
|
default: 'vn-table',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -165,7 +170,6 @@ const app = inject('app');
|
||||||
const editingRow = ref(null);
|
const editingRow = ref(null);
|
||||||
const editingField = ref(null);
|
const editingField = ref(null);
|
||||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||||
const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
|
|
||||||
const selectRegex = /select/;
|
const selectRegex = /select/;
|
||||||
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
||||||
const tableModes = [
|
const tableModes = [
|
||||||
|
@ -253,7 +257,9 @@ function splitColumns(columns) {
|
||||||
col.columnFilter = { inWhere: true, ...col.columnFilter };
|
col.columnFilter = { inWhere: true, ...col.columnFilter };
|
||||||
splittedColumns.value.columns.push(col);
|
splittedColumns.value.columns.push(col);
|
||||||
}
|
}
|
||||||
// Status column
|
|
||||||
|
splittedColumns.value.create = createOrderSort(splittedColumns.value.create);
|
||||||
|
|
||||||
if (splittedColumns.value.chips.length) {
|
if (splittedColumns.value.chips.length) {
|
||||||
splittedColumns.value.columnChips = splittedColumns.value.chips.filter(
|
splittedColumns.value.columnChips = splittedColumns.value.chips.filter(
|
||||||
(c) => !c.isId,
|
(c) => !c.isId,
|
||||||
|
@ -269,6 +275,24 @@ function splitColumns(columns) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createOrderSort(columns) {
|
||||||
|
const orderedColumn = columns
|
||||||
|
.map((column, index) =>
|
||||||
|
column.createOrder !== undefined ? { ...column, originalIndex: index } : null,
|
||||||
|
)
|
||||||
|
.filter((item) => item !== null);
|
||||||
|
|
||||||
|
orderedColumn.sort((a, b) => a.createOrder - b.createOrder);
|
||||||
|
|
||||||
|
const filteredColumns = columns.filter((col) => col.createOrder === undefined);
|
||||||
|
|
||||||
|
orderedColumn.forEach((col) => {
|
||||||
|
filteredColumns.splice(col.createOrder, 0, col);
|
||||||
|
});
|
||||||
|
|
||||||
|
return filteredColumns;
|
||||||
|
}
|
||||||
|
|
||||||
const rowClickFunction = computed(() => {
|
const rowClickFunction = computed(() => {
|
||||||
if ($props.rowClick != undefined) return $props.rowClick;
|
if ($props.rowClick != undefined) return $props.rowClick;
|
||||||
if ($props.redirect) return ({ id }) => redirectFn(id);
|
if ($props.redirect) return ({ id }) => redirectFn(id);
|
||||||
|
@ -314,8 +338,14 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
|
||||||
if (evt?.shiftKey && added) {
|
if (evt?.shiftKey && added) {
|
||||||
const rowIndex = selectedRows[0].$index;
|
const rowIndex = selectedRows[0].$index;
|
||||||
const selectedIndexes = new Set(selected.value.map((row) => row.$index));
|
const selectedIndexes = new Set(selected.value.map((row) => row.$index));
|
||||||
for (const row of rows) {
|
const minIndex = selectedIndexes.size
|
||||||
if (row.$index == rowIndex) break;
|
? Math.min(...selectedIndexes, rowIndex)
|
||||||
|
: 0;
|
||||||
|
const maxIndex = Math.max(...selectedIndexes, rowIndex);
|
||||||
|
|
||||||
|
for (let i = minIndex; i <= maxIndex; i++) {
|
||||||
|
const row = rows[i];
|
||||||
|
if (row.$index == rowIndex) continue;
|
||||||
if (!selectedIndexes.has(row.$index)) {
|
if (!selectedIndexes.has(row.$index)) {
|
||||||
selected.value.push(row);
|
selected.value.push(row);
|
||||||
selectedIndexes.add(row.$index);
|
selectedIndexes.add(row.$index);
|
||||||
|
@ -338,12 +368,11 @@ function hasEditableFormat(column) {
|
||||||
|
|
||||||
const clickHandler = async (event) => {
|
const clickHandler = async (event) => {
|
||||||
const clickedElement = event.target.closest('td');
|
const clickedElement = event.target.closest('td');
|
||||||
|
|
||||||
const isDateElement = event.target.closest('.q-date');
|
const isDateElement = event.target.closest('.q-date');
|
||||||
const isTimeElement = event.target.closest('.q-time');
|
const isTimeElement = event.target.closest('.q-time');
|
||||||
const isQselectDropDown = event.target.closest('.q-select__dropdown-icon');
|
const isQSelectDropDown = event.target.closest('.q-select__dropdown-icon');
|
||||||
|
|
||||||
if (isDateElement || isTimeElement || isQselectDropDown) return;
|
if (isDateElement || isTimeElement || isQSelectDropDown) return;
|
||||||
|
|
||||||
if (clickedElement === null) {
|
if (clickedElement === null) {
|
||||||
await destroyInput(editingRow.value, editingField.value);
|
await destroyInput(editingRow.value, editingField.value);
|
||||||
|
@ -414,20 +443,13 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
eventHandlers: {
|
eventHandlers: {
|
||||||
'update:modelValue': async (value) => {
|
'update:modelValue': async (value) => {
|
||||||
if (isSelect && value) {
|
if (isSelect && value) {
|
||||||
row[column.name] = value[column.attrs?.optionValue ?? 'id'];
|
await updateSelectValue(value, column, row, oldValue);
|
||||||
row[column?.name + 'TextValue'] =
|
|
||||||
value[column.attrs?.optionLabel ?? 'name'];
|
|
||||||
await column?.cellEvent?.['update:modelValue']?.(
|
|
||||||
value,
|
|
||||||
oldValue,
|
|
||||||
row,
|
|
||||||
);
|
|
||||||
} else row[column.name] = value;
|
} else row[column.name] = value;
|
||||||
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
||||||
},
|
},
|
||||||
keyup: async (event) => {
|
keyup: async (event) => {
|
||||||
if (event.key === 'Enter')
|
if (event.key === 'Enter')
|
||||||
await destroyInput(rowIndex, field, clickedElement);
|
await destroyInput(rowId, field, clickedElement);
|
||||||
},
|
},
|
||||||
keydown: async (event) => {
|
keydown: async (event) => {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
|
@ -458,6 +480,17 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
node.el?.querySelector('span > div > div').focus();
|
node.el?.querySelector('span > div > div').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function updateSelectValue(value, column, row, oldValue) {
|
||||||
|
row[column.name] = value[column.attrs?.optionValue ?? 'id'];
|
||||||
|
|
||||||
|
row[column?.name + 'VnTableTextValue'] = value[column.attrs?.optionLabel ?? 'name'];
|
||||||
|
|
||||||
|
if (column?.attrs?.find?.label)
|
||||||
|
row[column?.attrs?.find?.label] = value[column.attrs?.optionLabel ?? 'name'];
|
||||||
|
|
||||||
|
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
||||||
|
}
|
||||||
|
|
||||||
async function destroyInput(rowIndex, field, clickedElement) {
|
async function destroyInput(rowIndex, field, clickedElement) {
|
||||||
if (!clickedElement)
|
if (!clickedElement)
|
||||||
clickedElement = document.querySelector(
|
clickedElement = document.querySelector(
|
||||||
|
@ -520,9 +553,9 @@ function getToggleIcon(value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatColumnValue(col, row, dashIfEmpty) {
|
function formatColumnValue(col, row, dashIfEmpty) {
|
||||||
if (col?.format || row[col?.name + 'TextValue']) {
|
if (col?.format || row[col?.name + 'VnTableTextValue']) {
|
||||||
if (selectRegex.test(col?.component) && row[col?.name + 'TextValue']) {
|
if (selectRegex.test(col?.component) && row[col?.name + 'VnTableTextValue']) {
|
||||||
return dashIfEmpty(row[col?.name + 'TextValue']);
|
return dashIfEmpty(row[col?.name + 'VnTableTextValue']);
|
||||||
} else {
|
} else {
|
||||||
return col.format(row, dashIfEmpty);
|
return col.format(row, dashIfEmpty);
|
||||||
}
|
}
|
||||||
|
@ -555,19 +588,48 @@ function formatColumnValue(col, row, dashIfEmpty) {
|
||||||
}
|
}
|
||||||
return dashIfEmpty(row[col?.name]);
|
return dashIfEmpty(row[col?.name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cardClick(_, row) {
|
function cardClick(_, row) {
|
||||||
if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` });
|
if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeTextValue(data, getChanges) {
|
||||||
|
let changes = data.updates;
|
||||||
|
if (!changes) return data;
|
||||||
|
|
||||||
|
for (const change of changes) {
|
||||||
|
for (const key in change.data) {
|
||||||
|
if (key.endsWith('VnTableTextValue')) {
|
||||||
|
delete change.data[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.updates = changes.filter((change) => Object.keys(change.data).length > 0);
|
||||||
|
|
||||||
|
if ($attrs?.beforeSaveFn) data = $attrs.beforeSaveFn(data, getChanges);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRowClick(event, row) {
|
||||||
|
if (event.ctrlKey) return rowCtrlClickFunction.value(event, row);
|
||||||
|
if (rowClickFunction.value) rowClickFunction.value(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rowCtrlClickFunction = computed(() => {
|
||||||
|
if ($props.rowCtrlClick != undefined) return $props.rowCtrlClick;
|
||||||
|
if ($props.redirect)
|
||||||
|
return (evt, { id }) => {
|
||||||
|
stopEventPropagation(evt);
|
||||||
|
window.open(`/#/${$props.redirect}/${id}`, '_blank');
|
||||||
|
};
|
||||||
|
return () => {};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<QDrawer
|
<RightMenu v-if="$props.rightSearch" :overlay="overlay">
|
||||||
v-if="$props.rightSearch"
|
<template #right-panel>
|
||||||
v-model="stateStore.rightDrawer"
|
|
||||||
side="right"
|
|
||||||
:width="256"
|
|
||||||
:overlay="$props.overlay"
|
|
||||||
>
|
|
||||||
<QScrollArea class="fit">
|
|
||||||
<VnTableFilter
|
<VnTableFilter
|
||||||
:data-key="$attrs['data-key']"
|
:data-key="$attrs['data-key']"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
@ -581,8 +643,8 @@ function cardClick(_, row) {
|
||||||
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
|
<slot :name="slotName" v-bind="slotData ?? {}" :key="slotName" />
|
||||||
</template>
|
</template>
|
||||||
</VnTableFilter>
|
</VnTableFilter>
|
||||||
</QScrollArea>
|
</template>
|
||||||
</QDrawer>
|
</RightMenu>
|
||||||
<CrudModel
|
<CrudModel
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
:class="$attrs['class'] ?? 'q-px-md'"
|
:class="$attrs['class'] ?? 'q-px-md'"
|
||||||
|
@ -591,6 +653,7 @@ function cardClick(_, row) {
|
||||||
@on-fetch="(...args) => emit('onFetch', ...args)"
|
@on-fetch="(...args) => emit('onFetch', ...args)"
|
||||||
:search-url="searchUrl"
|
:search-url="searchUrl"
|
||||||
:disable-infinite-scroll="isTableMode"
|
:disable-infinite-scroll="isTableMode"
|
||||||
|
:before-save-fn="removeTextValue"
|
||||||
@save-changes="reload"
|
@save-changes="reload"
|
||||||
:has-sub-toolbar="$props.hasSubToolbar ?? isEditable"
|
:has-sub-toolbar="$props.hasSubToolbar ?? isEditable"
|
||||||
:auto-load="hasParams || $attrs['auto-load']"
|
:auto-load="hasParams || $attrs['auto-load']"
|
||||||
|
@ -618,7 +681,7 @@ function cardClick(_, row) {
|
||||||
:style="isTableMode && `max-height: ${tableHeight}`"
|
:style="isTableMode && `max-height: ${tableHeight}`"
|
||||||
:virtual-scroll="isTableMode"
|
:virtual-scroll="isTableMode"
|
||||||
@virtual-scroll="handleScroll"
|
@virtual-scroll="handleScroll"
|
||||||
@row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
|
@row-click="(event, row) => handleRowClick(event, row)"
|
||||||
@update:selected="emit('update:selected', $event)"
|
@update:selected="emit('update:selected', $event)"
|
||||||
@selection="(details) => handleSelection(details, rows)"
|
@selection="(details) => handleSelection(details, rows)"
|
||||||
:hide-selected-banner="true"
|
:hide-selected-banner="true"
|
||||||
|
@ -635,20 +698,13 @@ function cardClick(_, row) {
|
||||||
:skip="columnsVisibilitySkipped"
|
:skip="columnsVisibilitySkipped"
|
||||||
/>
|
/>
|
||||||
<QBtnToggle
|
<QBtnToggle
|
||||||
|
v-if="!tableModes.some((mode) => mode.disable)"
|
||||||
v-model="mode"
|
v-model="mode"
|
||||||
toggle-color="primary"
|
toggle-color="primary"
|
||||||
class="bg-vn-section-color"
|
class="bg-vn-section-color"
|
||||||
dense
|
dense
|
||||||
:options="tableModes.filter((mode) => !mode.disable)"
|
:options="tableModes.filter((mode) => !mode.disable)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<QBtn
|
|
||||||
v-if="showRightIcon"
|
|
||||||
icon="filter_alt"
|
|
||||||
class="bg-vn-section-color q-ml-sm"
|
|
||||||
dense
|
|
||||||
@click="stateStore.toggleRightDrawer()"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #header-cell="{ col }">
|
<template #header-cell="{ col }">
|
||||||
<QTh
|
<QTh
|
||||||
|
@ -961,14 +1017,6 @@ function cardClick(_, row) {
|
||||||
transition-show="scale"
|
transition-show="scale"
|
||||||
transition-hide="scale"
|
transition-hide="scale"
|
||||||
:full-width="createComplement?.isFullWidth ?? false"
|
:full-width="createComplement?.isFullWidth ?? false"
|
||||||
@before-hide="
|
|
||||||
() => {
|
|
||||||
if (createRef.isSaveAndContinue) {
|
|
||||||
showForm = true;
|
|
||||||
createForm.formInitialData = { ...create.formInitialData };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"
|
|
||||||
data-cy="vn-table-create-dialog"
|
data-cy="vn-table-create-dialog"
|
||||||
>
|
>
|
||||||
<FormModelPopup
|
<FormModelPopup
|
||||||
|
@ -979,7 +1027,10 @@ function cardClick(_, row) {
|
||||||
>
|
>
|
||||||
<template #form-inputs="{ data }">
|
<template #form-inputs="{ data }">
|
||||||
<div :style="createComplement?.containerStyle">
|
<div :style="createComplement?.containerStyle">
|
||||||
<div>
|
<div
|
||||||
|
:style="createComplement?.previousStyle"
|
||||||
|
v-if="!quasar.screen.xs"
|
||||||
|
>
|
||||||
<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">
|
||||||
|
@ -992,7 +1043,10 @@ function cardClick(_, row) {
|
||||||
:label="column.label"
|
:label="column.label"
|
||||||
>
|
>
|
||||||
<VnColumn
|
<VnColumn
|
||||||
:column="column"
|
:column="{
|
||||||
|
...column,
|
||||||
|
...{ disable: column?.createDisable ?? false },
|
||||||
|
}"
|
||||||
:row="{}"
|
:row="{}"
|
||||||
default="input"
|
default="input"
|
||||||
v-model="data[column.name]"
|
v-model="data[column.name]"
|
||||||
|
|
|
@ -27,30 +27,58 @@ describe('VnTable', () => {
|
||||||
beforeEach(() => (vm.selected = []));
|
beforeEach(() => (vm.selected = []));
|
||||||
|
|
||||||
describe('handleSelection()', () => {
|
describe('handleSelection()', () => {
|
||||||
const rows = [{ $index: 0 }, { $index: 1 }, { $index: 2 }];
|
const rows = [
|
||||||
const selectedRows = [{ $index: 1 }];
|
{ $index: 0 },
|
||||||
it('should add rows to selected when shift key is pressed and rows are added except last one', () => {
|
{ $index: 1 },
|
||||||
|
{ $index: 2 },
|
||||||
|
{ $index: 3 },
|
||||||
|
{ $index: 4 },
|
||||||
|
];
|
||||||
|
|
||||||
|
it('should add rows to selected when shift key is pressed and rows are added in ascending order', () => {
|
||||||
|
const selectedRows = [{ $index: 1 }];
|
||||||
vm.handleSelection(
|
vm.handleSelection(
|
||||||
{ evt: { shiftKey: true }, added: true, rows: selectedRows },
|
{ evt: { shiftKey: true }, added: true, rows: selectedRows },
|
||||||
rows
|
rows,
|
||||||
);
|
);
|
||||||
expect(vm.selected).toEqual([{ $index: 0 }]);
|
expect(vm.selected).toEqual([{ $index: 0 }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add rows to selected when shift key is pressed and rows are added in descending order', () => {
|
||||||
|
const selectedRows = [{ $index: 3 }];
|
||||||
|
vm.handleSelection(
|
||||||
|
{ evt: { shiftKey: true }, added: true, rows: selectedRows },
|
||||||
|
rows,
|
||||||
|
);
|
||||||
|
expect(vm.selected).toEqual([{ $index: 0 }, { $index: 1 }, { $index: 2 }]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should not add rows to selected when shift key is not pressed', () => {
|
it('should not add rows to selected when shift key is not pressed', () => {
|
||||||
|
const selectedRows = [{ $index: 1 }];
|
||||||
vm.handleSelection(
|
vm.handleSelection(
|
||||||
{ evt: { shiftKey: false }, added: true, rows: selectedRows },
|
{ evt: { shiftKey: false }, added: true, rows: selectedRows },
|
||||||
rows
|
rows,
|
||||||
);
|
);
|
||||||
expect(vm.selected).toEqual([]);
|
expect(vm.selected).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not add rows to selected when rows are not added', () => {
|
it('should not add rows to selected when rows are not added', () => {
|
||||||
|
const selectedRows = [{ $index: 1 }];
|
||||||
vm.handleSelection(
|
vm.handleSelection(
|
||||||
{ evt: { shiftKey: true }, added: false, rows: selectedRows },
|
{ evt: { shiftKey: true }, added: false, rows: selectedRows },
|
||||||
rows
|
rows,
|
||||||
);
|
);
|
||||||
expect(vm.selected).toEqual([]);
|
expect(vm.selected).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add all rows between the smallest and largest selected indexes', () => {
|
||||||
|
vm.selected = [{ $index: 1 }, { $index: 3 }];
|
||||||
|
const selectedRows = [{ $index: 4 }];
|
||||||
|
vm.handleSelection(
|
||||||
|
{ evt: { shiftKey: true }, added: true, rows: selectedRows },
|
||||||
|
rows,
|
||||||
|
);
|
||||||
|
expect(vm.selected).toEqual([{ $index: 1 }, { $index: 3 }, { $index: 2 }]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,13 @@ const stateStore = useStateStore();
|
||||||
const slots = useSlots();
|
const slots = useSlots();
|
||||||
const hasContent = useHasContent('#right-panel');
|
const hasContent = useHasContent('#right-panel');
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
overlay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if ((!slots['right-panel'] && !hasContent.value) || quasar.platform.is.mobile)
|
if ((!slots['right-panel'] && !hasContent.value) || quasar.platform.is.mobile)
|
||||||
stateStore.rightDrawer = false;
|
stateStore.rightDrawer = false;
|
||||||
|
@ -34,7 +41,12 @@ onMounted(() => {
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</div>
|
</div>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256">
|
<QDrawer
|
||||||
|
v-model="stateStore.rightDrawer"
|
||||||
|
side="right"
|
||||||
|
:width="256"
|
||||||
|
:overlay="overlay"
|
||||||
|
>
|
||||||
<QScrollArea class="fit">
|
<QScrollArea class="fit">
|
||||||
<div id="right-panel"></div>
|
<div id="right-panel"></div>
|
||||||
<slot v-if="!hasContent" name="right-panel" />
|
<slot v-if="!hasContent" name="right-panel" />
|
||||||
|
|
|
@ -27,7 +27,7 @@ const checkboxModel = computed({
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<QCheckbox v-bind="$attrs" v-on="$attrs" v-model="checkboxModel" />
|
<QCheckbox v-bind="$attrs" v-model="checkboxModel" />
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="info"
|
v-if="info"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
|
|
@ -302,8 +302,6 @@ defineExpose({ opts: myOptions, vnSelectRef });
|
||||||
|
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event) {
|
||||||
if (event.key === 'Tab' && !event.shiftKey) {
|
if (event.key === 'Tab' && !event.shiftKey) {
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const inputValue = vnSelectRef.value?.inputValue;
|
const inputValue = vnSelectRef.value?.inputValue;
|
||||||
|
|
||||||
if (inputValue) {
|
if (inputValue) {
|
||||||
|
|
|
@ -76,6 +76,15 @@ onBeforeMount(async () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const routeName = computed(() => {
|
||||||
|
const DESCRIPTOR_PROXY = 'DescriptorProxy';
|
||||||
|
|
||||||
|
let name = $props.dataKey;
|
||||||
|
if ($props.dataKey.includes(DESCRIPTOR_PROXY)) {
|
||||||
|
name = name.split(DESCRIPTOR_PROXY)[0];
|
||||||
|
}
|
||||||
|
return `${name}Summary`;
|
||||||
|
});
|
||||||
async function getData() {
|
async function getData() {
|
||||||
store.url = $props.url;
|
store.url = $props.url;
|
||||||
store.filter = $props.filter ?? {};
|
store.filter = $props.filter ?? {};
|
||||||
|
@ -154,9 +163,7 @@ const toModule = computed(() =>
|
||||||
{{ t('components.smartCard.openSummary') }}
|
{{ t('components.smartCard.openSummary') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<RouterLink
|
<RouterLink :to="{ name: routeName, params: { id: entity.id } }">
|
||||||
:to="{ name: `${dataKey}Summary`, params: { id: entity.id } }"
|
|
||||||
>
|
|
||||||
<QBtn
|
<QBtn
|
||||||
class="link"
|
class="link"
|
||||||
color="white"
|
color="white"
|
||||||
|
|
|
@ -204,8 +204,9 @@ async function search() {
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.q-field--focused) {
|
:deep(.q-field--focused) {
|
||||||
.q-icon {
|
.q-icon,
|
||||||
color: black;
|
.q-placeholder {
|
||||||
|
color: var(--vn-black-text-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ export async function checkEntryLock(entryFk, userFk) {
|
||||||
.dialog({
|
.dialog({
|
||||||
component: VnConfirm,
|
component: VnConfirm,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
'data-cy': 'entry-lock-confirm',
|
|
||||||
title: t('entry.lock.title'),
|
title: t('entry.lock.title'),
|
||||||
message: t('entry.lock.message', {
|
message: t('entry.lock.message', {
|
||||||
userName: data?.user?.nickname,
|
userName: data?.user?.nickname,
|
||||||
|
|
|
@ -153,6 +153,7 @@ globals:
|
||||||
maxTemperature: Max
|
maxTemperature: Max
|
||||||
minTemperature: Min
|
minTemperature: Min
|
||||||
changePass: Change password
|
changePass: Change password
|
||||||
|
setPass: Set password
|
||||||
deleteConfirmTitle: Delete selected elements
|
deleteConfirmTitle: Delete selected elements
|
||||||
changeState: Change state
|
changeState: Change state
|
||||||
raid: 'Raid {daysInForward} days'
|
raid: 'Raid {daysInForward} days'
|
||||||
|
@ -693,8 +694,10 @@ worker:
|
||||||
machine: Machine
|
machine: Machine
|
||||||
business:
|
business:
|
||||||
tableVisibleColumns:
|
tableVisibleColumns:
|
||||||
|
id: ID
|
||||||
started: Start Date
|
started: Start Date
|
||||||
ended: End Date
|
ended: End Date
|
||||||
|
hourlyLabor: Time sheet
|
||||||
company: Company
|
company: Company
|
||||||
reasonEnd: Reason for Termination
|
reasonEnd: Reason for Termination
|
||||||
department: Department
|
department: Department
|
||||||
|
@ -702,6 +705,7 @@ worker:
|
||||||
calendarType: Work Calendar
|
calendarType: Work Calendar
|
||||||
workCenter: Work Center
|
workCenter: Work Center
|
||||||
payrollCategories: Contract Category
|
payrollCategories: Contract Category
|
||||||
|
workerBusinessAgreementName: Agreement
|
||||||
occupationCode: Contribution Code
|
occupationCode: Contribution Code
|
||||||
rate: Rate
|
rate: Rate
|
||||||
businessType: Contract Type
|
businessType: Contract Type
|
||||||
|
|
|
@ -157,6 +157,7 @@ globals:
|
||||||
maxTemperature: Máx
|
maxTemperature: Máx
|
||||||
minTemperature: Mín
|
minTemperature: Mín
|
||||||
changePass: Cambiar contraseña
|
changePass: Cambiar contraseña
|
||||||
|
setPass: Establecer contraseña
|
||||||
deleteConfirmTitle: Eliminar los elementos seleccionados
|
deleteConfirmTitle: Eliminar los elementos seleccionados
|
||||||
changeState: Cambiar estado
|
changeState: Cambiar estado
|
||||||
raid: 'Redada {daysInForward} días'
|
raid: 'Redada {daysInForward} días'
|
||||||
|
@ -769,8 +770,10 @@ worker:
|
||||||
concept: Concepto
|
concept: Concepto
|
||||||
business:
|
business:
|
||||||
tableVisibleColumns:
|
tableVisibleColumns:
|
||||||
|
id: Id
|
||||||
started: Fecha inicio
|
started: Fecha inicio
|
||||||
ended: Fecha fin
|
ended: Fecha fin
|
||||||
|
hourlyLabor: Ficha
|
||||||
company: Empresa
|
company: Empresa
|
||||||
reasonEnd: Motivo finalización
|
reasonEnd: Motivo finalización
|
||||||
department: Departamento
|
department: Departamento
|
||||||
|
@ -781,6 +784,7 @@ worker:
|
||||||
occupationCode: Cotización
|
occupationCode: Cotización
|
||||||
rate: Tarifa
|
rate: Tarifa
|
||||||
businessType: Contrato
|
businessType: Contrato
|
||||||
|
workerBusinessAgreementName: Convenio
|
||||||
amount: Salario
|
amount: Salario
|
||||||
basicSalary: Salario transportistas
|
basicSalary: Salario transportistas
|
||||||
notes: Notas
|
notes: Notas
|
||||||
|
|
|
@ -25,12 +25,13 @@ const $props = defineProps({
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { hasAccount } = toRefs($props);
|
const { hasAccount } = toRefs($props);
|
||||||
const { openConfirmationModal } = useVnConfirm();
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
|
const arrayData = useArrayData('Account');
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const user = state.getUser();
|
const user = state.getUser();
|
||||||
const { notify } = useQuasar();
|
const { notify } = useQuasar();
|
||||||
const account = computed(() => useArrayData('Account').store.data[0]);
|
const account = computed(() => arrayData.store.data);
|
||||||
account.value.hasAccount = hasAccount.value;
|
account.value.hasAccount = hasAccount.value;
|
||||||
const entityId = computed(() => +route.params.id);
|
const entityId = computed(() => +route.params.id);
|
||||||
const hasitManagementAccess = ref();
|
const hasitManagementAccess = ref();
|
||||||
|
@ -39,7 +40,7 @@ const isHimself = computed(() => user.value.id === account.value.id);
|
||||||
const url = computed(() =>
|
const url = computed(() =>
|
||||||
isHimself.value
|
isHimself.value
|
||||||
? 'Accounts/change-password'
|
? 'Accounts/change-password'
|
||||||
: `Accounts/${entityId.value}/setPassword`
|
: `Accounts/${entityId.value}/setPassword`,
|
||||||
);
|
);
|
||||||
|
|
||||||
async function updateStatusAccount(active) {
|
async function updateStatusAccount(active) {
|
||||||
|
@ -153,6 +154,7 @@ onMounted(() => {
|
||||||
t('account.card.actions.disableAccount.title'),
|
t('account.card.actions.disableAccount.title'),
|
||||||
t('account.card.actions.disableAccount.subtitle'),
|
t('account.card.actions.disableAccount.subtitle'),
|
||||||
() => deleteAccount(),
|
() => deleteAccount(),
|
||||||
|
() => deleteAccount(),
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -172,6 +174,7 @@ onMounted(() => {
|
||||||
t('account.card.actions.enableAccount.title'),
|
t('account.card.actions.enableAccount.title'),
|
||||||
t('account.card.actions.enableAccount.subtitle'),
|
t('account.card.actions.enableAccount.subtitle'),
|
||||||
() => updateStatusAccount(true),
|
() => updateStatusAccount(true),
|
||||||
|
() => updateStatusAccount(true),
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -186,6 +189,7 @@ onMounted(() => {
|
||||||
t('account.card.actions.disableAccount.title'),
|
t('account.card.actions.disableAccount.title'),
|
||||||
t('account.card.actions.disableAccount.subtitle'),
|
t('account.card.actions.disableAccount.subtitle'),
|
||||||
() => updateStatusAccount(false),
|
() => updateStatusAccount(false),
|
||||||
|
() => updateStatusAccount(false),
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -201,6 +205,7 @@ onMounted(() => {
|
||||||
t('account.card.actions.activateUser.title'),
|
t('account.card.actions.activateUser.title'),
|
||||||
t('account.card.actions.activateUser.title'),
|
t('account.card.actions.activateUser.title'),
|
||||||
() => updateStatusUser(true),
|
() => updateStatusUser(true),
|
||||||
|
() => updateStatusUser(true),
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -215,6 +220,7 @@ onMounted(() => {
|
||||||
t('account.card.actions.deactivateUser.title'),
|
t('account.card.actions.deactivateUser.title'),
|
||||||
t('account.card.actions.deactivateUser.title'),
|
t('account.card.actions.deactivateUser.title'),
|
||||||
() => updateStatusUser(false),
|
() => updateStatusUser(false),
|
||||||
|
() => updateStatusUser(false),
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
|
|
@ -143,6 +143,7 @@ const exprBuilder = (param, value) => {
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
auto-load
|
auto-load
|
||||||
|
sortBy="name ASC"
|
||||||
/></QItemSection>
|
/></QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem class="q-mb-sm">
|
<QItem class="q-mb-sm">
|
||||||
|
|
|
@ -78,10 +78,20 @@ const columns = computed(() => [
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/activeWithInheritedRole',
|
url: 'Workers/activeWithInheritedRole',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name', 'firstName'],
|
||||||
where: { role: 'salesPerson' },
|
where: { role: 'salesPerson' },
|
||||||
optionFilter: 'firstName',
|
optionFilter: 'firstName',
|
||||||
},
|
},
|
||||||
|
columnFilter: {
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'Workers/activeWithInheritedRole',
|
||||||
|
fields: ['id', 'name', 'firstName'],
|
||||||
|
where: { role: 'salesPerson' },
|
||||||
|
optionLabel: 'firstName',
|
||||||
|
optionValue: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
create: false,
|
create: false,
|
||||||
columnField: {
|
columnField: {
|
||||||
component: null,
|
component: null,
|
||||||
|
|
|
@ -77,7 +77,6 @@ onBeforeMount(() => {
|
||||||
function setPaymentType(accounting) {
|
function setPaymentType(accounting) {
|
||||||
if (!accounting) return;
|
if (!accounting) return;
|
||||||
accountingType.value = accounting.accountingType;
|
accountingType.value = accounting.accountingType;
|
||||||
|
|
||||||
initialData.description = [];
|
initialData.description = [];
|
||||||
initialData.payed = Date.vnNew();
|
initialData.payed = Date.vnNew();
|
||||||
isCash.value = accountingType.value.code == 'cash';
|
isCash.value = accountingType.value.code == 'cash';
|
||||||
|
@ -87,14 +86,14 @@ function setPaymentType(accounting) {
|
||||||
initialData.payed.getDate() + accountingType.value.daysInFuture,
|
initialData.payed.getDate() + accountingType.value.daysInFuture,
|
||||||
);
|
);
|
||||||
maxAmount.value = accountingType.value && accountingType.value.maxAmount;
|
maxAmount.value = accountingType.value && accountingType.value.maxAmount;
|
||||||
|
|
||||||
if (accountingType.value.code == 'compensation')
|
if (accountingType.value.code == 'compensation')
|
||||||
return (initialData.description = '');
|
return (initialData.description = '');
|
||||||
if (accountingType.value.receiptDescription)
|
|
||||||
initialData.description.push(accountingType.value.receiptDescription);
|
|
||||||
if (initialData.description) initialData.description.push(initialData.description);
|
|
||||||
|
|
||||||
initialData.description = initialData.description.join(', ');
|
let descriptions = [];
|
||||||
|
if (accountingType.value.receiptDescription)
|
||||||
|
descriptions.push(accountingType.value.receiptDescription);
|
||||||
|
if (initialData.description) descriptions.push(initialData.description);
|
||||||
|
initialData.description = descriptions.join(', ');
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateFromAmount = (event) => {
|
const calculateFromAmount = (event) => {
|
||||||
|
|
|
@ -54,6 +54,7 @@ const columns = [
|
||||||
toggleIndeterminate: false,
|
toggleIndeterminate: false,
|
||||||
},
|
},
|
||||||
create: true,
|
create: true,
|
||||||
|
createOrder: 12,
|
||||||
width: '25px',
|
width: '25px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -61,9 +62,10 @@ const columns = [
|
||||||
name: 'workerFk',
|
name: 'workerFk',
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/search',
|
url: 'TicketRequests/getItemTypeWorker',
|
||||||
fields: ['id', 'nickname'],
|
fields: ['id', 'nickname'],
|
||||||
optionLabel: 'nickname',
|
optionLabel: 'nickname',
|
||||||
|
sortBy: 'nickname ASC',
|
||||||
optionValue: 'id',
|
optionValue: 'id',
|
||||||
},
|
},
|
||||||
visible: false,
|
visible: false,
|
||||||
|
@ -87,15 +89,6 @@ const columns = [
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'entryFk',
|
|
||||||
isId: true,
|
|
||||||
visible: false,
|
|
||||||
isEditable: false,
|
|
||||||
disable: true,
|
|
||||||
create: true,
|
|
||||||
columnFilter: false,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
label: 'Id',
|
label: 'Id',
|
||||||
|
@ -137,6 +130,7 @@ const columns = [
|
||||||
name: 'itemFk',
|
name: 'itemFk',
|
||||||
visible: false,
|
visible: false,
|
||||||
create: true,
|
create: true,
|
||||||
|
createOrder: 0,
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -160,6 +154,8 @@ const columns = [
|
||||||
name: 'stickers',
|
name: 'stickers',
|
||||||
component: 'input',
|
component: 'input',
|
||||||
create: true,
|
create: true,
|
||||||
|
|
||||||
|
createOrder: 1,
|
||||||
attrs: {
|
attrs: {
|
||||||
positive: false,
|
positive: false,
|
||||||
},
|
},
|
||||||
|
@ -271,6 +267,7 @@ const columns = [
|
||||||
},
|
},
|
||||||
width: '45px',
|
width: '45px',
|
||||||
create: true,
|
create: true,
|
||||||
|
createOrder: 3,
|
||||||
style: getQuantityStyle,
|
style: getQuantityStyle,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -280,6 +277,7 @@ const columns = [
|
||||||
toolTip: t('Buying value'),
|
toolTip: t('Buying value'),
|
||||||
name: 'buyingValue',
|
name: 'buyingValue',
|
||||||
create: true,
|
create: true,
|
||||||
|
createOrder: 2,
|
||||||
component: 'number',
|
component: 'number',
|
||||||
attrs: {
|
attrs: {
|
||||||
positive: false,
|
positive: false,
|
||||||
|
@ -312,6 +310,7 @@ const columns = [
|
||||||
toolTip: t('Package'),
|
toolTip: t('Package'),
|
||||||
name: 'price2',
|
name: 'price2',
|
||||||
component: 'number',
|
component: 'number',
|
||||||
|
createDisable: true,
|
||||||
width: '35px',
|
width: '35px',
|
||||||
create: true,
|
create: true,
|
||||||
format: (row) => parseFloat(row['price2']).toFixed(2),
|
format: (row) => parseFloat(row['price2']).toFixed(2),
|
||||||
|
@ -321,6 +320,7 @@ const columns = [
|
||||||
label: t('Box'),
|
label: t('Box'),
|
||||||
name: 'price3',
|
name: 'price3',
|
||||||
component: 'number',
|
component: 'number',
|
||||||
|
createDisable: 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);
|
||||||
|
@ -508,13 +508,14 @@ async function setBuyUltimate(itemFk, data) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const buyUltimateData = buyUltimate.data[0];
|
const buyUltimateData = buyUltimate.data[0];
|
||||||
|
if (!buyUltimateData) return;
|
||||||
|
|
||||||
const allowedKeys = columns
|
const allowedKeys = columns
|
||||||
.filter((col) => col.create === true)
|
.filter((col) => col.create === true)
|
||||||
.map((col) => col.name);
|
.map((col) => col.name);
|
||||||
|
|
||||||
allowedKeys.forEach((key) => {
|
allowedKeys.forEach((key) => {
|
||||||
if (buyUltimateData.hasOwnProperty(key) && key !== 'entryFk') {
|
if (buyUltimateData?.hasOwnProperty(key) && key !== 'entryFk') {
|
||||||
if (!['stickers', 'quantity'].includes(key)) data[key] = buyUltimateData[key];
|
if (!['stickers', 'quantity'].includes(key)) data[key] = buyUltimateData[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -607,6 +608,7 @@ onMounted(() => {
|
||||||
ref="entryBuysRef"
|
ref="entryBuysRef"
|
||||||
data-key="EntryBuys"
|
data-key="EntryBuys"
|
||||||
:url="`Entries/${entityId}/getBuyList`"
|
:url="`Entries/${entityId}/getBuyList`"
|
||||||
|
search-url="EntryBuys"
|
||||||
save-url="Buys/crud"
|
save-url="Buys/crud"
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
v-model:selected="selectedRows"
|
v-model:selected="selectedRows"
|
||||||
|
@ -636,21 +638,24 @@ onMounted(() => {
|
||||||
isFullWidth: true,
|
isFullWidth: true,
|
||||||
containerStyle: {
|
containerStyle: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
'flex-wrap': 'wrap',
|
|
||||||
gap: '16px',
|
gap: '16px',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
height: '450px',
|
|
||||||
},
|
},
|
||||||
columnGridStyle: {
|
columnGridStyle: {
|
||||||
'max-width': '50%',
|
'max-width': '50%',
|
||||||
flex: 1,
|
|
||||||
'margin-right': '30px',
|
'margin-right': '30px',
|
||||||
|
flex: 1,
|
||||||
},
|
},
|
||||||
|
previousStyle: {
|
||||||
|
'max-width': '30%',
|
||||||
|
height: '500px',
|
||||||
|
},
|
||||||
|
displayPrevious: true,
|
||||||
}"
|
}"
|
||||||
:is-editable="editableMode"
|
:is-editable="editableMode"
|
||||||
:without-header="!editableMode"
|
:without-header="!editableMode"
|
||||||
:with-filters="editableMode"
|
:with-filters="editableMode"
|
||||||
:right-search="true"
|
:right-search="editableMode"
|
||||||
:right-search-icon="true"
|
:right-search-icon="true"
|
||||||
:row-click="false"
|
:row-click="false"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
@ -660,6 +665,7 @@ onMounted(() => {
|
||||||
auto-load
|
auto-load
|
||||||
footer
|
footer
|
||||||
data-cy="entry-buys"
|
data-cy="entry-buys"
|
||||||
|
overlay
|
||||||
>
|
>
|
||||||
<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" />
|
||||||
|
|
|
@ -248,7 +248,7 @@ const entryFilterPanel = ref();
|
||||||
<i18n>
|
<i18n>
|
||||||
en:
|
en:
|
||||||
params:
|
params:
|
||||||
isExcludedFromAvailable: Inventory
|
isExcludedFromAvailable: Is excluded
|
||||||
isOrdered: Ordered
|
isOrdered: Ordered
|
||||||
isReceived: Received
|
isReceived: Received
|
||||||
isConfirmed: Confirmed
|
isConfirmed: Confirmed
|
||||||
|
|
|
@ -11,6 +11,8 @@ import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
|
import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
|
||||||
import { toDate } from 'src/filters';
|
import { toDate } from 'src/filters';
|
||||||
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
|
import EntrySummary from './Card/EntrySummary.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
@ -18,6 +20,7 @@ const defaultEntry = ref({});
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const user = state.getUser();
|
const user = state.getUser();
|
||||||
const dataKey = 'EntryList';
|
const dataKey = 'EntryList';
|
||||||
|
const { viewSummary } = useSummaryDialog();
|
||||||
|
|
||||||
const entryQueryFilter = {
|
const entryQueryFilter = {
|
||||||
include: [
|
include: [
|
||||||
|
@ -222,6 +225,19 @@ const columns = computed(() => [
|
||||||
visible: false,
|
visible: false,
|
||||||
create: true,
|
create: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
label: '',
|
||||||
|
name: 'tableActions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('components.smartCard.viewSummary'),
|
||||||
|
icon: 'preview',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => viewSummary(row.id, EntrySummary, 'xlg-width'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
function getBadgeAttrs(row) {
|
function getBadgeAttrs(row) {
|
||||||
const date = row.landed;
|
const date = row.landed;
|
||||||
|
@ -267,16 +283,7 @@ onBeforeMount(async () => {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSection
|
<VnSection :data-key="dataKey" prefix="entry">
|
||||||
:data-key="dataKey"
|
|
||||||
prefix="entry"
|
|
||||||
url="Entries/filter"
|
|
||||||
:array-data-props="{
|
|
||||||
url: 'Entries/filter',
|
|
||||||
order: 'landed DESC',
|
|
||||||
userFilter: EntryFilter,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<template #advanced-menu>
|
<template #advanced-menu>
|
||||||
<EntryFilter :data-key="dataKey" />
|
<EntryFilter :data-key="dataKey" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -285,6 +292,7 @@ onBeforeMount(async () => {
|
||||||
v-if="defaultEntry.defaultSupplierFk"
|
v-if="defaultEntry.defaultSupplierFk"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:data-key="dataKey"
|
:data-key="dataKey"
|
||||||
|
search-url="EntryList"
|
||||||
url="Entries/filter"
|
url="Entries/filter"
|
||||||
:filter="entryQueryFilter"
|
:filter="entryQueryFilter"
|
||||||
order="landed DESC"
|
order="landed DESC"
|
||||||
|
|
|
@ -19,6 +19,7 @@ const { t } = useI18n();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const user = state.getUser();
|
const user = state.getUser();
|
||||||
|
const footer = ref({ bought: 0, reserve: 0 });
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -38,16 +39,14 @@ const columns = computed(() => [
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Workers/activeWithInheritedRole',
|
url: 'TicketRequests/getItemTypeWorker',
|
||||||
fields: ['id', 'name', 'nickname'],
|
fields: ['id', 'nickname'],
|
||||||
where: { role: 'buyer' },
|
|
||||||
optionFilter: 'firstName',
|
|
||||||
optionLabel: 'nickname',
|
optionLabel: 'nickname',
|
||||||
|
sortBy: 'nickname ASC',
|
||||||
optionValue: 'id',
|
optionValue: 'id',
|
||||||
useLike: false,
|
|
||||||
},
|
},
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
width: '70px',
|
width: '50px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -58,6 +57,7 @@ const columns = computed(() => [
|
||||||
component: 'number',
|
component: 'number',
|
||||||
summation: true,
|
summation: true,
|
||||||
width: '50px',
|
width: '50px',
|
||||||
|
format: ({ reserve }, dashIfEmpty) => dashIfEmpty(round(reserve)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -65,6 +65,7 @@ const columns = computed(() => [
|
||||||
name: 'bought',
|
name: 'bought',
|
||||||
summation: true,
|
summation: true,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
style: ({ reserve, bought }) => boughtStyle(bought, reserve),
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -95,7 +96,6 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'data-cy': 'table-actions',
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -137,20 +137,20 @@ function openDialog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFooter(data) {
|
function setFooter(data) {
|
||||||
const footer = {
|
footer.value = { bought: 0, reserve: 0 };
|
||||||
bought: 0,
|
|
||||||
reserve: 0,
|
|
||||||
};
|
|
||||||
data.forEach((row) => {
|
data.forEach((row) => {
|
||||||
footer.bought += row?.bought;
|
footer.value.bought += row?.bought;
|
||||||
footer.reserve += row?.reserve;
|
footer.value.reserve += row?.reserve;
|
||||||
});
|
});
|
||||||
tableRef.value.footer = footer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function round(value) {
|
function round(value) {
|
||||||
return Math.round(value * 100) / 100;
|
return Math.round(value * 100) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function boughtStyle(bought, reserve) {
|
||||||
|
return reserve < bought ? { color: 'var(--q-negative)' } : '';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnSubToolbar>
|
<VnSubToolbar>
|
||||||
|
@ -253,24 +253,14 @@ function round(value) {
|
||||||
<WorkerDescriptorProxy :id="row?.workerFk" />
|
<WorkerDescriptorProxy :id="row?.workerFk" />
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-bought="{ row }">
|
|
||||||
<span :class="{ 'text-negative': row.reserve < row.bought }">
|
|
||||||
{{ row?.bought }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #column-footer-reserve>
|
<template #column-footer-reserve>
|
||||||
<span>
|
<span>
|
||||||
{{ round(tableRef.footer.reserve) }}
|
{{ round(footer.reserve) }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-footer-bought>
|
<template #column-footer-bought>
|
||||||
<span
|
<span :style="boughtStyle(footer?.bought, footer?.reserve)">
|
||||||
:class="{
|
{{ round(footer.bought) }}
|
||||||
'text-negative':
|
|
||||||
tableRef.footer.reserve < tableRef.footer.bought,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ round(tableRef.footer.bought) }}
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
@ -286,7 +276,7 @@ function round(value) {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.column {
|
.column {
|
||||||
min-width: 40%;
|
min-width: 35%;
|
||||||
margin-top: 5%;
|
margin-top: 5%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -14,7 +14,7 @@ const $props = defineProps({
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
dated: {
|
dated: {
|
||||||
type: Date,
|
type: [Date, String],
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -202,7 +202,7 @@ function setCursor(ref) {
|
||||||
:option-label="col.optionLabel"
|
:option-label="col.optionLabel"
|
||||||
:filter-options="['id', 'name']"
|
:filter-options="['id', 'name']"
|
||||||
:tooltip="t('Create a new expense')"
|
:tooltip="t('Create a new expense')"
|
||||||
@keydown.tab="
|
@keydown.tab.prevent="
|
||||||
autocompleteExpense(
|
autocompleteExpense(
|
||||||
$event,
|
$event,
|
||||||
row,
|
row,
|
||||||
|
|
|
@ -97,16 +97,19 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'isActive',
|
name: 'isActive',
|
||||||
label: t('invoiceOut.negativeBases.active'),
|
label: t('invoiceOut.negativeBases.active'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'hasToInvoice',
|
name: 'hasToInvoice',
|
||||||
label: t('invoiceOut.negativeBases.hasToInvoice'),
|
label: t('invoiceOut.negativeBases.hasToInvoice'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'hasVerifiedData',
|
name: 'isTaxDataChecked',
|
||||||
label: t('invoiceOut.negativeBases.verifiedData'),
|
label: t('invoiceOut.negativeBases.verifiedData'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -142,7 +145,7 @@ const downloadCSV = async () => {
|
||||||
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
||||||
userParams.from,
|
userParams.from,
|
||||||
userParams.to,
|
userParams.to,
|
||||||
filterParams
|
filterParams,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -120,22 +120,9 @@ const updateStock = async () => {
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv :label="t('globals.producer')" :value="dashIfEmpty(entity.subName)" />
|
<VnLv :label="t('globals.producer')" :value="dashIfEmpty(entity.subName)" />
|
||||||
<VnLv
|
<VnLv v-if="entity?.value5" :label="entity?.tag5" :value="entity.value5" />
|
||||||
v-if="entity.value5"
|
<VnLv v-if="entity?.value6" :label="entity?.tag6" :value="entity.value6" />
|
||||||
:label="t('item.descriptor.color')"
|
<VnLv v-if="entity?.value7" :label="entity?.tag7" :value="entity.value7" />
|
||||||
:value="entity.value5"
|
|
||||||
>
|
|
||||||
</VnLv>
|
|
||||||
<VnLv
|
|
||||||
v-if="entity.value6"
|
|
||||||
:label="t('item.descriptor.category')"
|
|
||||||
:value="entity.value6"
|
|
||||||
/>
|
|
||||||
<VnLv
|
|
||||||
v-if="entity.value7"
|
|
||||||
:label="t('item.list.stems')"
|
|
||||||
:value="entity.value7"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #icons="{ entity }">
|
<template #icons="{ entity }">
|
||||||
<QCardActions v-if="entity" class="q-gutter-x-md">
|
<QCardActions v-if="entity" class="q-gutter-x-md">
|
||||||
|
|
|
@ -12,7 +12,7 @@ import FetchData from 'components/FetchData.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
|
||||||
import { toDateFormat } from 'src/filters/date.js';
|
import { toDateTimeFormat } from 'src/filters/date.js';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
import { date } from 'quasar';
|
import { date } from 'quasar';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
|
@ -27,7 +27,7 @@ const user = state.getUser();
|
||||||
const today = Date.vnNew();
|
const today = Date.vnNew();
|
||||||
today.setHours(0, 0, 0, 0);
|
today.setHours(0, 0, 0, 0);
|
||||||
const warehousesOptions = ref([]);
|
const warehousesOptions = ref([]);
|
||||||
const itemBalances = computed(() => arrayDataItemBalances.store.data);
|
const itemBalances = computed(() => arrayDataItemBalances.store.data || []);
|
||||||
const where = computed(() => arrayDataItemBalances.store.filter.where || {});
|
const where = computed(() => arrayDataItemBalances.store.filter.where || {});
|
||||||
const showWhatsBeforeInventory = ref(false);
|
const showWhatsBeforeInventory = ref(false);
|
||||||
const inventoriedDate = ref(null);
|
const inventoriedDate = ref(null);
|
||||||
|
@ -143,7 +143,12 @@ onMounted(async () => {
|
||||||
const fetchItemBalances = async () => await arrayDataItemBalances.fetch({});
|
const fetchItemBalances = async () => await arrayDataItemBalances.fetch({});
|
||||||
|
|
||||||
const getBadgeAttrs = (_date) => {
|
const getBadgeAttrs = (_date) => {
|
||||||
const isSameDate = date.isSameDate(today, _date);
|
let today = Date.vnNew();
|
||||||
|
today.setHours(0, 0, 0, 0);
|
||||||
|
let timeTicket = new Date(_date);
|
||||||
|
timeTicket.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
const isSameDate = date.isSameDate(today, timeTicket);
|
||||||
const attrs = {
|
const attrs = {
|
||||||
'text-color': isSameDate ? 'black' : 'white',
|
'text-color': isSameDate ? 'black' : 'white',
|
||||||
color: isSameDate ? 'warning' : 'transparent',
|
color: isSameDate ? 'warning' : 'transparent',
|
||||||
|
@ -244,7 +249,7 @@ async function updateWarehouse(warehouseFk) {
|
||||||
dense
|
dense
|
||||||
style="font-size: 14px"
|
style="font-size: 14px"
|
||||||
>
|
>
|
||||||
{{ toDateFormat(row.shipped) }}
|
{{ toDateTimeFormat(row.shipped) }}
|
||||||
</QBadge>
|
</QBadge>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
|
@ -313,8 +318,8 @@ async function updateWarehouse(warehouseFk) {
|
||||||
row.lineFk == row.lastPreparedLineFk
|
row.lineFk == row.lastPreparedLineFk
|
||||||
? 'black'
|
? 'black'
|
||||||
: row.balance < 0
|
: row.balance < 0
|
||||||
? 'negative'
|
? 'negative'
|
||||||
: ''
|
: ''
|
||||||
"
|
"
|
||||||
dense
|
dense
|
||||||
style="font-size: 14px"
|
style="font-size: 14px"
|
||||||
|
|
|
@ -11,7 +11,6 @@ import { toCurrency } from 'filters/index';
|
||||||
import { useArrayData } from 'composables/useArrayData';
|
import { useArrayData } from 'composables/useArrayData';
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const from = ref();
|
const from = ref();
|
||||||
|
@ -41,7 +40,7 @@ const itemLastEntries = ref([]);
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
label: 'Nv',
|
label: 'NV',
|
||||||
name: 'ig',
|
name: 'ig',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
|
@ -70,6 +69,7 @@ const columns = computed(() => [
|
||||||
field: 'reference',
|
field: 'reference',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
format: (_, row) => toCurrency(row.price2) + ' / ' + toCurrency(row.price3),
|
format: (_, row) => toCurrency(row.price2) + ' / ' + toCurrency(row.price3),
|
||||||
|
style: (row) => highlightedRow(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('lastEntries.printedStickers'),
|
label: t('lastEntries.printedStickers'),
|
||||||
|
@ -84,6 +84,7 @@ const columns = computed(() => [
|
||||||
field: 'stickers',
|
field: 'stickers',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
format: (val) => dashIfEmpty(val),
|
format: (val) => dashIfEmpty(val),
|
||||||
|
style: (row) => highlightedRow(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Packing',
|
label: 'Packing',
|
||||||
|
@ -102,12 +103,14 @@ const columns = computed(() => [
|
||||||
name: 'stems',
|
name: 'stems',
|
||||||
field: 'stems',
|
field: 'stems',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
style: (row) => highlightedRow(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('lastEntries.quantity'),
|
label: t('lastEntries.quantity'),
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
field: 'quantity',
|
field: 'quantity',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
style: (row) => highlightedRow(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('lastEntries.cost'),
|
label: t('lastEntries.cost'),
|
||||||
|
@ -120,12 +123,14 @@ const columns = computed(() => [
|
||||||
name: 'weight',
|
name: 'weight',
|
||||||
field: 'weight',
|
field: 'weight',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
style: (row) => highlightedRow(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('lastEntries.cube'),
|
label: t('lastEntries.cube'),
|
||||||
name: 'cube',
|
name: 'cube',
|
||||||
field: 'packagingFk',
|
field: 'packagingFk',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
style: (row) => highlightedRow(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('lastEntries.supplier'),
|
label: t('lastEntries.supplier'),
|
||||||
|
@ -208,6 +213,14 @@ onMounted(async () => {
|
||||||
function getBadgeClass(groupingMode, expectedGrouping) {
|
function getBadgeClass(groupingMode, expectedGrouping) {
|
||||||
return groupingMode === expectedGrouping ? 'accent-badge' : 'simple-badge';
|
return groupingMode === expectedGrouping ? 'accent-badge' : 'simple-badge';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function highlightedRow(row) {
|
||||||
|
return row?.isInventorySupplier
|
||||||
|
? {
|
||||||
|
'background-color': 'var(--vn-section-hover-color)',
|
||||||
|
}
|
||||||
|
: '';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<VnSubToolbar>
|
<VnSubToolbar>
|
||||||
|
@ -236,7 +249,7 @@ function getBadgeClass(groupingMode, expectedGrouping) {
|
||||||
:no-data-label="t('globals.noResults')"
|
:no-data-label="t('globals.noResults')"
|
||||||
>
|
>
|
||||||
<template #body-cell-ig="{ row }">
|
<template #body-cell-ig="{ row }">
|
||||||
<QTd class="text-center">
|
<QTd class="text-center" :style="highlightedRow(row)">
|
||||||
<QIcon
|
<QIcon
|
||||||
:name="row.isIgnored ? 'check_box' : 'check_box_outline_blank'"
|
:name="row.isIgnored ? 'check_box' : 'check_box_outline_blank'"
|
||||||
style="color: var(--vn-label-color)"
|
style="color: var(--vn-label-color)"
|
||||||
|
@ -245,38 +258,38 @@ function getBadgeClass(groupingMode, expectedGrouping) {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-warehouse="{ row }">
|
<template #body-cell-warehouse="{ row }">
|
||||||
<QTd>
|
<QTd :style="highlightedRow(row)">
|
||||||
<span>{{ row.warehouse }}</span>
|
<span>{{ row.warehouse }}</span>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-date="{ row }">
|
<template #body-cell-date="{ row }">
|
||||||
<QTd class="text-center">
|
<QTd class="text-center" :style="highlightedRow(row)">
|
||||||
<VnDateBadge :date="row.landed" />
|
<VnDateBadge :date="row.landed" />
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-entry="{ row }">
|
<template #body-cell-entry="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd @click.stop :style="highlightedRow(row)">
|
||||||
<div class="full-width flex justify-center">
|
<div class="full-width flex justify-center">
|
||||||
<EntryDescriptorProxy :id="row.entryFk" class="q-ma-none" dense />
|
<EntryDescriptorProxy :id="row.entryFk" class="q-ma-none" dense />
|
||||||
<span class="link">{{ row.entryFk }}</span>
|
<span class="link">{{ row.entryFk }}</span>
|
||||||
</div>
|
</div>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-pvp="{ value }">
|
<template #body-cell-pvp="{ row, value }">
|
||||||
<QTd @click.stop class="text-center">
|
<QTd @click.stop class="text-center" :style="highlightedRow(row)">
|
||||||
<span> {{ value }}</span>
|
<span> {{ value }}</span>
|
||||||
<QTooltip> {{ t('lastEntries.grouping') }}/Packing </QTooltip></QTd
|
<QTooltip> {{ t('lastEntries.grouping') }}/Packing </QTooltip>
|
||||||
>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-printedStickers="{ row }">
|
<template #body-cell-printedStickers="{ row }">
|
||||||
<QTd @click.stop class="text-center">
|
<QTd @click.stop class="text-center" :style="highlightedRow(row)">
|
||||||
<span style="color: var(--vn-label-color)">
|
<span style="color: var(--vn-label-color)">
|
||||||
{{ row.printedStickers }}</span
|
{{ row.printedStickers }}</span
|
||||||
>
|
>
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-packing="{ row }">
|
<template #body-cell-packing="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd @click.stop :style="highlightedRow(row)">
|
||||||
<QBadge
|
<QBadge
|
||||||
class="center-content"
|
class="center-content"
|
||||||
:class="getBadgeClass(row.groupingMode, 'packing')"
|
:class="getBadgeClass(row.groupingMode, 'packing')"
|
||||||
|
@ -288,7 +301,7 @@ function getBadgeClass(groupingMode, expectedGrouping) {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-grouping="{ row }">
|
<template #body-cell-grouping="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd @click.stop :style="highlightedRow(row)">
|
||||||
<QBadge
|
<QBadge
|
||||||
class="center-content"
|
class="center-content"
|
||||||
:class="getBadgeClass(row.groupingMode, 'grouping')"
|
:class="getBadgeClass(row.groupingMode, 'grouping')"
|
||||||
|
@ -300,7 +313,7 @@ function getBadgeClass(groupingMode, expectedGrouping) {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-cost="{ row }">
|
<template #body-cell-cost="{ row }">
|
||||||
<QTd @click.stop class="text-center">
|
<QTd @click.stop class="text-center" :style="highlightedRow(row)">
|
||||||
<span>
|
<span>
|
||||||
{{ toCurrency(row.cost, 'EUR', 3) }}
|
{{ toCurrency(row.cost, 'EUR', 3) }}
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
|
@ -319,7 +332,7 @@ function getBadgeClass(groupingMode, expectedGrouping) {
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-supplier="{ row }">
|
<template #body-cell-supplier="{ row }">
|
||||||
<QTd @click.stop>
|
<QTd @click.stop :style="highlightedRow(row)">
|
||||||
<div class="full-width flex justify-left">
|
<div class="full-width flex justify-left">
|
||||||
<QBadge
|
<QBadge
|
||||||
:class="
|
:class="
|
||||||
|
@ -354,7 +367,6 @@ function getBadgeClass(groupingMode, expectedGrouping) {
|
||||||
.th :first-child {
|
.th :first-child {
|
||||||
.td {
|
.td {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: red;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.accent-badge {
|
.accent-badge {
|
||||||
|
|
|
@ -87,7 +87,7 @@ const insertTag = (rows) => {
|
||||||
tagFk: undefined,
|
tagFk: undefined,
|
||||||
}"
|
}"
|
||||||
:default-remove="false"
|
:default-remove="false"
|
||||||
:filter="{
|
:user-filter="{
|
||||||
fields: ['id', 'itemFk', 'tagFk', 'value', 'priority'],
|
fields: ['id', 'itemFk', 'tagFk', 'value', 'priority'],
|
||||||
where: { itemFk: route.params.id },
|
where: { itemFk: route.params.id },
|
||||||
include: {
|
include: {
|
||||||
|
@ -119,6 +119,7 @@ const insertTag = (rows) => {
|
||||||
"
|
"
|
||||||
:required="true"
|
:required="true"
|
||||||
:rules="validate('itemTag.tagFk')"
|
:rules="validate('itemTag.tagFk')"
|
||||||
|
:data-cy="`tag${row?.tag?.name}`"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-if="row.tag?.isFree === false"
|
v-if="row.tag?.isFree === false"
|
||||||
|
@ -145,6 +146,7 @@ const insertTag = (rows) => {
|
||||||
:label="t('itemTags.value')"
|
:label="t('itemTags.value')"
|
||||||
:is-clearable="false"
|
:is-clearable="false"
|
||||||
@keyup.enter.stop="(data) => itemTagsRef.onSubmit(data)"
|
@keyup.enter.stop="(data) => itemTagsRef.onSubmit(data)"
|
||||||
|
:data-cy="`tag${row?.tag?.name}Value`"
|
||||||
/>
|
/>
|
||||||
<VnInput
|
<VnInput
|
||||||
:label="t('itemBasicData.relevancy')"
|
:label="t('itemBasicData.relevancy')"
|
||||||
|
@ -162,6 +164,7 @@ const insertTag = (rows) => {
|
||||||
name="delete"
|
name="delete"
|
||||||
size="sm"
|
size="sm"
|
||||||
dense
|
dense
|
||||||
|
:data-cy="`deleteTag${row?.tag?.name}`"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('itemTags.removeTag') }}
|
{{ t('itemTags.removeTag') }}
|
||||||
|
@ -177,6 +180,7 @@ const insertTag = (rows) => {
|
||||||
icon="add"
|
icon="add"
|
||||||
v-shortcut="'+'"
|
v-shortcut="'+'"
|
||||||
fab
|
fab
|
||||||
|
data-cy="createNewTag"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ t('itemTags.addTag') }}
|
{{ t('itemTags.addTag') }}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { computed, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import { dashIfEmpty, toDate, toHour } from 'src/filters';
|
import { toDate, toHour } from 'src/filters';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { usePrintService } from 'src/composables/usePrintService';
|
import { usePrintService } from 'src/composables/usePrintService';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref, markRaw } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { toHour } from 'src/filters';
|
import { toHour } from 'src/filters';
|
||||||
|
@ -8,6 +8,7 @@ import RouteFilter from 'pages/Route/Card/RouteFilter.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 VnSection from 'src/components/common/VnSection.vue';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
|
@ -38,17 +39,7 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'workerFk',
|
name: 'workerFk',
|
||||||
label: t('route.Worker'),
|
label: t('route.Worker'),
|
||||||
component: 'select',
|
component: markRaw(VnSelectWorker),
|
||||||
attrs: {
|
|
||||||
url: 'Workers/activeWithInheritedRole',
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
useLike: false,
|
|
||||||
optionFilter: 'firstName',
|
|
||||||
find: {
|
|
||||||
value: 'workerFk',
|
|
||||||
label: 'workerUserName',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
create: true,
|
create: true,
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
|
format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
|
||||||
|
@ -59,6 +50,10 @@ const columns = computed(() => [
|
||||||
name: 'agencyName',
|
name: 'agencyName',
|
||||||
label: t('route.Agency'),
|
label: t('route.Agency'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('route.Agency'),
|
||||||
|
name: 'agencyModeFk',
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'agencyModes',
|
url: 'agencyModes',
|
||||||
|
@ -69,14 +64,19 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
create: true,
|
create: true,
|
||||||
columnClass: 'expand',
|
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
visible: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'vehiclePlateNumber',
|
name: 'vehiclePlateNumber',
|
||||||
label: t('route.Vehicle'),
|
label: t('route.Vehicle'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'vehicleFk',
|
||||||
|
label: t('route.Vehicle'),
|
||||||
|
cardVisible: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'vehicles',
|
url: 'vehicles',
|
||||||
|
@ -90,6 +90,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
create: true,
|
create: true,
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
visible: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -156,6 +157,7 @@ const columns = computed(() => [
|
||||||
<VnTable
|
<VnTable
|
||||||
:data-key
|
:data-key
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
|
ref="tableRef"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
redirect="route"
|
redirect="route"
|
||||||
:create="{
|
:create="{
|
||||||
|
|
|
@ -6,7 +6,10 @@ import VnSection from 'src/components/common/VnSection.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 FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
|
import SupplierSummary from './Card/SupplierSummary.vue';
|
||||||
|
|
||||||
|
const { viewSummary } = useSummaryDialog();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
const dataKey = 'SupplierList';
|
const dataKey = 'SupplierList';
|
||||||
|
@ -103,6 +106,19 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'right',
|
||||||
|
label: '',
|
||||||
|
name: 'tableActions',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
title: t('components.smartCard.viewSummary'),
|
||||||
|
icon: 'preview',
|
||||||
|
isPrimary: true,
|
||||||
|
action: (row) => viewSummary(row.id, SupplierSummary, 'md-width'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,32 +1,26 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import axios from 'axios';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
import { toCurrency } from 'src/filters';
|
import { toCurrency } from 'src/filters';
|
||||||
import VnUsesMana from 'components/ui/VnUsesMana.vue';
|
import VnUsesMana from 'components/ui/VnUsesMana.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
mana: {
|
|
||||||
type: Number,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
newPrice: {
|
newPrice: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
usesMana: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
manaCode: {
|
|
||||||
type: String,
|
|
||||||
default: 'mana',
|
|
||||||
},
|
|
||||||
sale: {
|
sale: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const mana = ref(null);
|
||||||
|
const usesMana = ref(false);
|
||||||
|
|
||||||
const emit = defineEmits(['save', 'cancel']);
|
const emit = defineEmits(['save', 'cancel']);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -38,32 +32,47 @@ const save = (sale = $props.sale) => {
|
||||||
QPopupProxyRef.value.hide();
|
QPopupProxyRef.value.hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getMana = async () => {
|
||||||
|
const { data } = await axios.get(`Tickets/${route.params.id}/getSalesPersonMana`);
|
||||||
|
mana.value = data;
|
||||||
|
await getUsesMana();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUsesMana = async () => {
|
||||||
|
const { data } = await axios.get('Sales/usesMana');
|
||||||
|
usesMana.value = data;
|
||||||
|
};
|
||||||
|
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
QPopupProxyRef.value.hide();
|
QPopupProxyRef.value.hide();
|
||||||
};
|
};
|
||||||
|
const hasMana = computed(() => typeof mana.value === 'number');
|
||||||
defineExpose({ save });
|
defineExpose({ save });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPopupProxy ref="QPopupProxyRef" data-cy="ticketEditManaProxy">
|
<QPopupProxy
|
||||||
|
ref="QPopupProxyRef"
|
||||||
|
@before-show="getMana"
|
||||||
|
data-cy="ticketEditManaProxy"
|
||||||
|
>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<QSpinner v-if="!mana" color="primary" size="md" />
|
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
||||||
<div v-else>
|
<QSpinner v-if="!hasMana" color="primary" size="md" />
|
||||||
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
<div class="q-pa-md" v-else>
|
||||||
<div class="q-pa-md">
|
<slot :popup="QPopupProxyRef" />
|
||||||
<slot :popup="QPopupProxyRef" />
|
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
||||||
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
<VnUsesMana :mana-code="manaCode" />
|
||||||
<VnUsesMana :mana-code="manaCode" />
|
</div>
|
||||||
</div>
|
<div v-if="newPrice" class="column items-center q-mt-lg">
|
||||||
<div v-if="newPrice" class="column items-center q-mt-lg">
|
<span class="text-primary">{{ t('New price') }}</span>
|
||||||
<span class="text-primary">{{ t('New price') }}</span>
|
<span class="text-subtitle1">
|
||||||
<span class="text-subtitle1">
|
{{ toCurrency($props.newPrice) }}
|
||||||
{{ toCurrency($props.newPrice) }}
|
</span>
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<QBtn
|
<QBtn
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
|
@ -45,7 +45,6 @@ const isTicketEditable = ref(false);
|
||||||
const sales = ref([]);
|
const sales = ref([]);
|
||||||
const editableStatesOptions = ref([]);
|
const editableStatesOptions = ref([]);
|
||||||
const selectedSales = ref([]);
|
const selectedSales = ref([]);
|
||||||
const mana = ref(null);
|
|
||||||
const manaCode = ref('mana');
|
const manaCode = ref('mana');
|
||||||
const ticketState = computed(() => store.data?.ticketState?.state?.code);
|
const ticketState = computed(() => store.data?.ticketState?.state?.code);
|
||||||
const transfer = ref({
|
const transfer = ref({
|
||||||
|
@ -175,17 +174,21 @@ const getSaleTotal = (sale) => {
|
||||||
return price - discount;
|
return price - discount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getRowUpdateInputEvents = (sale) => ({
|
||||||
|
'keyup.enter': () => {
|
||||||
|
changeQuantity(sale);
|
||||||
|
},
|
||||||
|
blur: () => {
|
||||||
|
changeQuantity(sale);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const resetChanges = async () => {
|
const resetChanges = async () => {
|
||||||
arrayData.fetch({ append: false });
|
arrayData.fetch({ append: false });
|
||||||
tableRef.value.reload();
|
tableRef.value.reload();
|
||||||
};
|
};
|
||||||
const rowToUpdate = ref(null);
|
|
||||||
const changeQuantity = async (sale) => {
|
const changeQuantity = async (sale) => {
|
||||||
if (
|
if (!sale.itemFk || sale.quantity == null || sale?.originalQuantity === sale.quantity)
|
||||||
!sale.itemFk ||
|
|
||||||
sale.quantity == null ||
|
|
||||||
edit.value?.oldQuantity === sale.quantity
|
|
||||||
)
|
|
||||||
return;
|
return;
|
||||||
if (!sale.id) return addSale(sale);
|
if (!sale.id) return addSale(sale);
|
||||||
|
|
||||||
|
@ -197,13 +200,10 @@ const changeQuantity = async (sale) => {
|
||||||
const updateQuantity = async (sale) => {
|
const updateQuantity = async (sale) => {
|
||||||
try {
|
try {
|
||||||
let { quantity, id } = sale;
|
let { quantity, id } = sale;
|
||||||
if (!rowToUpdate.value) return;
|
|
||||||
rowToUpdate.value = null;
|
|
||||||
sale.isNew = false;
|
sale.isNew = false;
|
||||||
const params = { quantity: quantity };
|
await axios.post(`Sales/${id}/updateQuantity`, { quantity });
|
||||||
await axios.post(`Sales/${id}/updateQuantity`, params);
|
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
tableRef.value.reload();
|
resetChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const { quantity } = tableRef.value.CrudModelRef.originalData.find(
|
const { quantity } = tableRef.value.CrudModelRef.originalData.find(
|
||||||
(s) => s.id === sale.id,
|
(s) => s.id === sale.id,
|
||||||
|
@ -247,7 +247,7 @@ const updateConcept = async (sale) => {
|
||||||
const data = { newConcept: sale.concept };
|
const data = { newConcept: sale.concept };
|
||||||
await axios.post(`Sales/${sale.id}/updateConcept`, data);
|
await axios.post(`Sales/${sale.id}/updateConcept`, data);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
tableRef.value.reload();
|
resetChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_EDIT = {
|
const DEFAULT_EDIT = {
|
||||||
|
@ -258,18 +258,6 @@ const DEFAULT_EDIT = {
|
||||||
oldQuantity: null,
|
oldQuantity: null,
|
||||||
};
|
};
|
||||||
const edit = ref({ ...DEFAULT_EDIT });
|
const edit = ref({ ...DEFAULT_EDIT });
|
||||||
const usesMana = ref(null);
|
|
||||||
|
|
||||||
const getUsesMana = async () => {
|
|
||||||
const { data } = await axios.get('Sales/usesMana');
|
|
||||||
usesMana.value = data;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getMana = async () => {
|
|
||||||
const { data } = await axios.get(`Tickets/${route.params.id}/getSalesPersonMana`);
|
|
||||||
mana.value = data;
|
|
||||||
await getUsesMana();
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectedValidSales = computed(() => {
|
const selectedValidSales = computed(() => {
|
||||||
if (!sales.value) return;
|
if (!sales.value) return;
|
||||||
|
@ -277,7 +265,6 @@ const selectedValidSales = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const onOpenEditPricePopover = async (sale) => {
|
const onOpenEditPricePopover = async (sale) => {
|
||||||
await getMana();
|
|
||||||
edit.value = {
|
edit.value = {
|
||||||
sale: JSON.parse(JSON.stringify(sale)),
|
sale: JSON.parse(JSON.stringify(sale)),
|
||||||
price: sale.price,
|
price: sale.price,
|
||||||
|
@ -285,7 +272,6 @@ const onOpenEditPricePopover = async (sale) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onOpenEditDiscountPopover = async (sale) => {
|
const onOpenEditDiscountPopover = async (sale) => {
|
||||||
await getMana();
|
|
||||||
if (isLocked.value) return;
|
if (isLocked.value) return;
|
||||||
if (sale) {
|
if (sale) {
|
||||||
edit.value = {
|
edit.value = {
|
||||||
|
@ -306,14 +292,13 @@ const changePrice = async (sale) => {
|
||||||
await confirmUpdate(() => updatePrice(sale, newPrice));
|
await confirmUpdate(() => updatePrice(sale, newPrice));
|
||||||
} else updatePrice(sale, newPrice);
|
} else updatePrice(sale, newPrice);
|
||||||
}
|
}
|
||||||
await getMana();
|
|
||||||
};
|
};
|
||||||
const updatePrice = async (sale, newPrice) => {
|
const updatePrice = async (sale, newPrice) => {
|
||||||
await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
|
await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
|
||||||
sale.price = newPrice;
|
sale.price = newPrice;
|
||||||
edit.value = { ...DEFAULT_EDIT };
|
edit.value = { ...DEFAULT_EDIT };
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
tableRef.value.reload();
|
resetChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeDiscount = async (sale) => {
|
const changeDiscount = async (sale) => {
|
||||||
|
@ -345,7 +330,7 @@ const updateDiscount = async (sales, newDiscount = null) => {
|
||||||
};
|
};
|
||||||
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
|
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
tableRef.value.reload();
|
resetChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNewPrice = computed(() => {
|
const getNewPrice = computed(() => {
|
||||||
|
@ -413,7 +398,7 @@ const removeSales = async () => {
|
||||||
await axios.post('Sales/deleteSales', params);
|
await axios.post('Sales/deleteSales', params);
|
||||||
removeSelectedSales();
|
removeSelectedSales();
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
window.location.reload();
|
resetChanges();
|
||||||
};
|
};
|
||||||
|
|
||||||
const setTransferParams = async () => {
|
const setTransferParams = async () => {
|
||||||
|
@ -599,9 +584,7 @@ watch(
|
||||||
:is-ticket-editable="isTicketEditable"
|
:is-ticket-editable="isTicketEditable"
|
||||||
:sales="selectedValidSales"
|
:sales="selectedValidSales"
|
||||||
:disable="!hasSelectedRows"
|
:disable="!hasSelectedRows"
|
||||||
:mana="mana"
|
|
||||||
:ticket-config="ticketConfig"
|
:ticket-config="ticketConfig"
|
||||||
@get-mana="getMana()"
|
|
||||||
@update-discounts="updateDiscounts"
|
@update-discounts="updateDiscounts"
|
||||||
@refresh-table="resetChanges"
|
@refresh-table="resetChanges"
|
||||||
/>
|
/>
|
||||||
|
@ -772,9 +755,7 @@ watch(
|
||||||
v-if="row.isNew || isTicketEditable"
|
v-if="row.isNew || isTicketEditable"
|
||||||
type="number"
|
type="number"
|
||||||
v-model.number="row.quantity"
|
v-model.number="row.quantity"
|
||||||
@blur="changeQuantity(row)"
|
v-on="getRowUpdateInputEvents(row)"
|
||||||
@keyup.enter.stop="changeQuantity(row)"
|
|
||||||
@update:model-value="() => (rowToUpdate = row)"
|
|
||||||
@focus="edit.oldQuantity = row.quantity"
|
@focus="edit.oldQuantity = row.quantity"
|
||||||
/>
|
/>
|
||||||
<span v-else>{{ row.quantity }}</span>
|
<span v-else>{{ row.quantity }}</span>
|
||||||
|
@ -786,7 +767,6 @@ watch(
|
||||||
</QBtn>
|
</QBtn>
|
||||||
<TicketEditManaProxy
|
<TicketEditManaProxy
|
||||||
ref="editPriceProxyRef"
|
ref="editPriceProxyRef"
|
||||||
:mana="mana"
|
|
||||||
:sale="row"
|
:sale="row"
|
||||||
:new-price="getNewPrice"
|
:new-price="getNewPrice"
|
||||||
@save="changePrice"
|
@save="changePrice"
|
||||||
|
@ -809,10 +789,8 @@ watch(
|
||||||
|
|
||||||
<TicketEditManaProxy
|
<TicketEditManaProxy
|
||||||
ref="editManaProxyRef"
|
ref="editManaProxyRef"
|
||||||
:mana="mana"
|
|
||||||
:sale="row"
|
:sale="row"
|
||||||
:new-price="getNewPrice"
|
:new-price="getNewPrice"
|
||||||
:uses-mana="usesMana"
|
|
||||||
:mana-code="manaCode"
|
:mana-code="manaCode"
|
||||||
@save="changeDiscount"
|
@save="changeDiscount"
|
||||||
>
|
>
|
||||||
|
|
|
@ -34,10 +34,6 @@ const props = defineProps({
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
mana: {
|
|
||||||
type: Number,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
ticketConfig: {
|
ticketConfig: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
|
@ -50,6 +46,7 @@ const { dialog } = useQuasar();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const acl = useAcl();
|
const acl = useAcl();
|
||||||
const btnDropdownRef = ref(null);
|
const btnDropdownRef = ref(null);
|
||||||
|
const editManaProxyRef = ref(null);
|
||||||
const { openConfirmationModal } = useVnConfirm();
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
|
|
||||||
const newDiscount = ref(null);
|
const newDiscount = ref(null);
|
||||||
|
@ -131,13 +128,13 @@ const createClaim = () => {
|
||||||
openConfirmationModal(
|
openConfirmationModal(
|
||||||
t('Claim out of time'),
|
t('Claim out of time'),
|
||||||
t('Do you want to continue?'),
|
t('Do you want to continue?'),
|
||||||
onCreateClaimAccepted
|
onCreateClaimAccepted,
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
openConfirmationModal(
|
openConfirmationModal(
|
||||||
t('Do you want to create a claim?'),
|
t('Do you want to create a claim?'),
|
||||||
false,
|
false,
|
||||||
onCreateClaimAccepted
|
onCreateClaimAccepted,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -216,8 +213,14 @@ const createRefund = async (withWarehouse) => {
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QItemLabel>{{ t('Update discount') }}</QItemLabel>
|
<QItemLabel>{{ t('Update discount') }}</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<TicketEditManaProxy :mana="props.mana" @save="changeMultipleDiscount()">
|
<TicketEditManaProxy
|
||||||
|
ref="editManaProxyRef"
|
||||||
|
:sale="row"
|
||||||
|
@save="changeMultipleDiscount"
|
||||||
|
>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
autofocus
|
||||||
|
@keyup.enter.stop="() => editManaProxyRef.save(row)"
|
||||||
v-model.number="newDiscount"
|
v-model.number="newDiscount"
|
||||||
:label="t('ticketSale.discount')"
|
:label="t('ticketSale.discount')"
|
||||||
type="number"
|
type="number"
|
||||||
|
|
|
@ -46,6 +46,15 @@ const descriptorData = useArrayData('Ticket');
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
ticketUrl.value = (await getUrl('ticket/')) + entityId.value + '/';
|
ticketUrl.value = (await getUrl('ticket/')) + entityId.value + '/';
|
||||||
});
|
});
|
||||||
|
const formattedAddress = computed(() => {
|
||||||
|
if (!ticket.value) return '';
|
||||||
|
|
||||||
|
const address = ticket.value.address;
|
||||||
|
const postcode = address.postalCode;
|
||||||
|
const province = address.province ? `(${address.province.name})` : '';
|
||||||
|
|
||||||
|
return `${address.street} - ${postcode} - ${address.city} ${province}`;
|
||||||
|
});
|
||||||
|
|
||||||
function isEditable() {
|
function isEditable() {
|
||||||
try {
|
try {
|
||||||
|
@ -238,7 +247,7 @@ onMounted(async () => {
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('ticket.summary.consigneeStreet')"
|
:label="t('ticket.summary.consigneeStreet')"
|
||||||
:value="entity.address?.street"
|
:value="formattedAddress"
|
||||||
/>
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-one" v-if="entity.notes.length">
|
<QCard class="vn-one" v-if="entity.notes.length">
|
||||||
|
|
|
@ -456,6 +456,7 @@ watch(
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
:pagination="{ rowsPerPage: 0 }"
|
||||||
:no-data-label="t('globals.noResults')"
|
:no-data-label="t('globals.noResults')"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
|
:order="['futureTotalWithVat ASC']"
|
||||||
auto-load
|
auto-load
|
||||||
:disable-option="{ card: true }"
|
:disable-option="{ card: true }"
|
||||||
>
|
>
|
||||||
|
|
|
@ -293,6 +293,7 @@ en:
|
||||||
clientFk: Customer
|
clientFk: Customer
|
||||||
orderFk: Order
|
orderFk: Order
|
||||||
from: From
|
from: From
|
||||||
|
shipped: Shipped
|
||||||
to: To
|
to: To
|
||||||
salesPersonFk: Salesperson
|
salesPersonFk: Salesperson
|
||||||
stateFk: State
|
stateFk: State
|
||||||
|
@ -320,6 +321,7 @@ es:
|
||||||
clientFk: Cliente
|
clientFk: Cliente
|
||||||
orderFk: Pedido
|
orderFk: Pedido
|
||||||
from: Desde
|
from: Desde
|
||||||
|
shipped: F. envío
|
||||||
to: Hasta
|
to: Hasta
|
||||||
salesPersonFk: Comercial
|
salesPersonFk: Comercial
|
||||||
stateFk: Estado
|
stateFk: Estado
|
||||||
|
|
|
@ -108,13 +108,11 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'shippedDate',
|
name: 'shipped',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
label: t('ticketList.shipped'),
|
label: t('ticketList.shipped'),
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
component: 'date',
|
component: 'date',
|
||||||
alias: 't',
|
|
||||||
inWhere: true,
|
|
||||||
},
|
},
|
||||||
format: ({ shippedDate }) => toDate(shippedDate),
|
format: ({ shippedDate }) => toDate(shippedDate),
|
||||||
},
|
},
|
||||||
|
@ -216,6 +214,7 @@ const columns = computed(() => [
|
||||||
{
|
{
|
||||||
title: t('components.smartCard.viewSummary'),
|
title: t('components.smartCard.viewSummary'),
|
||||||
icon: 'preview',
|
icon: 'preview',
|
||||||
|
isPrimary: true,
|
||||||
action: (row, evt) => {
|
action: (row, evt) => {
|
||||||
if (evt && evt.ctrlKey) {
|
if (evt && evt.ctrlKey) {
|
||||||
const url = router.resolve({
|
const url = router.resolve({
|
||||||
|
@ -253,7 +252,7 @@ const fetchAvailableAgencies = async (formData) => {
|
||||||
|
|
||||||
const { options, agency } = response;
|
const { options, agency } = response;
|
||||||
if (options) agenciesOptions.value = options;
|
if (options) agenciesOptions.value = options;
|
||||||
if (agency) formData.agencyModeId = agency;
|
if (agency) formData.agencyModeId = agency.agencyModeFk;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchClient = async (formData) => {
|
const fetchClient = async (formData) => {
|
||||||
|
|
|
@ -17,6 +17,12 @@ const maritalStatus = [
|
||||||
{ code: 'M', name: t('Married') },
|
{ code: 'M', name: t('Married') },
|
||||||
{ code: 'S', name: t('Single') },
|
{ code: 'S', name: t('Single') },
|
||||||
];
|
];
|
||||||
|
async function setAdvancedSummary(data) {
|
||||||
|
const advanced = (await useAdvancedSummary('Workers', data.id)) ?? {};
|
||||||
|
Object.assign(form.value.formData, advanced);
|
||||||
|
await nextTick();
|
||||||
|
if (form.value) form.value.hasChanges = false;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FetchData
|
||||||
|
@ -36,13 +42,7 @@ const maritalStatus = [
|
||||||
:url-update="`Workers/${$route.params.id}`"
|
:url-update="`Workers/${$route.params.id}`"
|
||||||
auto-load
|
auto-load
|
||||||
model="Worker"
|
model="Worker"
|
||||||
@on-fetch="
|
@on-fetch="setAdvancedSummary"
|
||||||
async (data) => {
|
|
||||||
Object.assign(data, (await useAdvancedSummary('Workers', data.id)) ?? {});
|
|
||||||
await $nextTick();
|
|
||||||
if (form) form.hasChanges = false;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<template #form="{ data }">
|
<template #form="{ data }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { ref, computed } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'components/VnTable/VnTable.vue';
|
||||||
import { toDate } from 'src/filters';
|
import { dashIfEmpty, toDate } from 'src/filters';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ const quasar = useQuasar();
|
||||||
|
|
||||||
async function reactivateWorker() {
|
async function reactivateWorker() {
|
||||||
const hasToReactive = tableRef.value.CrudModelRef.formData.find(
|
const hasToReactive = tableRef.value.CrudModelRef.formData.find(
|
||||||
(data) => !data.ended
|
(data) => !data.ended,
|
||||||
);
|
);
|
||||||
if (hasToReactive) {
|
if (hasToReactive) {
|
||||||
quasar
|
quasar
|
||||||
|
@ -35,28 +35,44 @@ async function reactivateWorker() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
label: t('Id'),
|
||||||
|
align: 'left',
|
||||||
|
isId: true,
|
||||||
|
cardVisible: true,
|
||||||
|
width: '40px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'isHourlyLabor',
|
||||||
|
label: t('worker.business.tableVisibleColumns.hourlyLabor'),
|
||||||
|
align: 'left',
|
||||||
|
component: 'checkbox',
|
||||||
|
cardVisible: true,
|
||||||
|
width: '60px',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'started',
|
name: 'started',
|
||||||
label: t('worker.business.tableVisibleColumns.started'),
|
label: t('worker.business.tableVisibleColumns.started'),
|
||||||
align: 'left',
|
|
||||||
format: ({ started }) => toDate(started),
|
format: ({ started }) => toDate(started),
|
||||||
component: 'date',
|
component: 'date',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '90px',
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'ended',
|
name: 'ended',
|
||||||
label: t('worker.business.tableVisibleColumns.ended'),
|
label: t('worker.business.tableVisibleColumns.ended'),
|
||||||
align: 'left',
|
|
||||||
format: ({ ended }) => toDate(ended),
|
format: ({ ended }) => toDate(ended),
|
||||||
component: 'date',
|
component: 'date',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '90px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('worker.business.tableVisibleColumns.company'),
|
label: t('worker.business.tableVisibleColumns.company'),
|
||||||
align: 'left',
|
toolTip: t('worker.business.tableVisibleColumns.company'),
|
||||||
name: 'companyCodeFk',
|
name: 'companyCodeFk',
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
|
@ -65,23 +81,23 @@ const columns = computed(() => [
|
||||||
optionLabel: 'code',
|
optionLabel: 'code',
|
||||||
optionValue: 'code',
|
optionValue: 'code',
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '60px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
name: 'reasonEndFk',
|
name: 'reasonEndFk',
|
||||||
component: 'select',
|
component: 'select',
|
||||||
label: t('worker.business.tableVisibleColumns.reasonEnd'),
|
label: t('worker.business.tableVisibleColumns.reasonEnd'),
|
||||||
|
toolTip: t('worker.business.tableVisibleColumns.reasonEnd'),
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'BusinessReasonEnds',
|
url: 'BusinessReasonEnds',
|
||||||
fields: ['id', 'reason'],
|
fields: ['id', 'reason'],
|
||||||
optionLabel: 'reason',
|
optionLabel: 'reason',
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
format: ({ reason }, dashIfEmpty) => dashIfEmpty(reason),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
name: 'departmentFk',
|
name: 'departmentFk',
|
||||||
component: 'select',
|
component: 'select',
|
||||||
label: t('worker.business.tableVisibleColumns.department'),
|
label: t('worker.business.tableVisibleColumns.department'),
|
||||||
|
@ -89,15 +105,19 @@ const columns = computed(() => [
|
||||||
url: 'Departments',
|
url: 'Departments',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
optionLabel: 'name',
|
optionLabel: 'name',
|
||||||
|
optionValue: 'id',
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '80px',
|
||||||
|
format: ({ departmentName }, dashIfEmpty) => dashIfEmpty(departmentName),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'workerBusinessProfessionalCategoryFk',
|
name: 'workerBusinessProfessionalCategoryFk',
|
||||||
component: 'select',
|
component: 'select',
|
||||||
label: t('worker.business.tableVisibleColumns.professionalCategory'),
|
label: t('worker.business.tableVisibleColumns.professionalCategory'),
|
||||||
|
toolTip: t('worker.business.tableVisibleColumns.professionalCategory'),
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'WorkerBusinessProfessionalCategories',
|
url: 'WorkerBusinessProfessionalCategories',
|
||||||
fields: ['id', 'description', 'code'],
|
fields: ['id', 'description', 'code'],
|
||||||
|
@ -105,6 +125,9 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '100px',
|
||||||
|
format: ({ professionalDescription }, dashIfEmpty) =>
|
||||||
|
dashIfEmpty(professionalDescription),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -118,6 +141,8 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
format: ({ calendarTypeDescription }, dashIfEmpty) =>
|
||||||
|
dashIfEmpty(calendarTypeDescription),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -131,6 +156,8 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '100px',
|
||||||
|
format: ({ workCenterName }, dashIfEmpty) => dashIfEmpty(workCenterName),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -144,6 +171,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
format: ({ payrollDescription }, dashIfEmpty) => dashIfEmpty(payrollDescription),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -157,6 +185,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
format: ({ occupationName }, dashIfEmpty) => dashIfEmpty(occupationName),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -165,6 +194,7 @@ const columns = computed(() => [
|
||||||
component: 'input',
|
component: 'input',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '50px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -177,6 +207,22 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
format: ({ workerBusinessTypeName }, dashIfEmpty) =>
|
||||||
|
dashIfEmpty(workerBusinessTypeName),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'workerBusinessAgreementFk',
|
||||||
|
label: t('worker.business.tableVisibleColumns.workerBusinessAgreementName'),
|
||||||
|
component: 'select',
|
||||||
|
attrs: {
|
||||||
|
url: 'WorkerBusinessAgreements',
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
cardVisible: true,
|
||||||
|
create: true,
|
||||||
|
format: ({ workerBusinessAgreementName }, dashIfEmpty) =>
|
||||||
|
dashIfEmpty(workerBusinessAgreementName),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -185,6 +231,7 @@ const columns = computed(() => [
|
||||||
component: 'input',
|
component: 'input',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '70px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -193,6 +240,7 @@ const columns = computed(() => [
|
||||||
component: 'input',
|
component: 'input',
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
|
width: '70px',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'notes',
|
name: 'notes',
|
||||||
|
@ -208,27 +256,27 @@ const columns = computed(() => [
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="WorkerBusiness"
|
data-key="WorkerBusiness"
|
||||||
:url="`Workers/${entityId}/Business`"
|
:url="`Workers/${entityId}/getWorkerBusiness`"
|
||||||
save-url="/Businesses/crud"
|
save-url="/Businesses/crud"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: `Workers/${entityId}/Business`,
|
urlCreate: `Workers/${entityId}/Business`,
|
||||||
title: 'Create business',
|
title: t('Create business'),
|
||||||
onDataSaved: () => tableRef.reload(),
|
onDataSaved: () => tableRef.reload(),
|
||||||
formInitialData: {},
|
formInitialData: {},
|
||||||
}"
|
}"
|
||||||
order="id DESC"
|
order="id DESC"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
default-mode="card"
|
|
||||||
auto-load
|
auto-load
|
||||||
:disable-option="{ table: true }"
|
:disable-option="{ card: true }"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
card-class="grid-two q-gutter-x-xl q-gutter-y-md q-pr-lg q-py-lg"
|
|
||||||
:is-editable="true"
|
:is-editable="true"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
|
:right-search-icon="false"
|
||||||
@save-changes="(data) => reactivateWorker(data)"
|
@save-changes="(data) => reactivateWorker(data)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<i18n>
|
<i18n>
|
||||||
es:
|
es:
|
||||||
Do you want to reactivate the user?: desea reactivar el usuario?
|
Do you want to reactivate the user?: desea reactivar el usuario?
|
||||||
|
Create business: Crear contrato
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -111,6 +111,7 @@ const handlePhotoUpdated = (evt = false) => {
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<VnLv :label="t('globals.user')" :value="entity.user?.name" />
|
<VnLv :label="t('globals.user')" :value="entity.user?.name" />
|
||||||
<VnLv
|
<VnLv
|
||||||
|
class="ellipsis-text"
|
||||||
:label="t('globals.params.email')"
|
:label="t('globals.params.email')"
|
||||||
:value="entity.user?.emailUser?.email"
|
:value="entity.user?.emailUser?.email"
|
||||||
copy
|
copy
|
||||||
|
@ -177,6 +178,12 @@ const handlePhotoUpdated = (evt = false) => {
|
||||||
.photo {
|
.photo {
|
||||||
height: 256px;
|
height: 256px;
|
||||||
}
|
}
|
||||||
|
.ellipsis-text {
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -12,6 +12,11 @@ const $props = defineProps({
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPopupProxy>
|
<QPopupProxy>
|
||||||
<WorkerDescriptor v-if="$props.id" :id="$props.id" :summary="WorkerSummary" />
|
<WorkerDescriptor
|
||||||
|
v-if="$props.id"
|
||||||
|
:id="$props.id"
|
||||||
|
:summary="WorkerSummary"
|
||||||
|
data-key="WorkerDescriptorProxy"
|
||||||
|
/>
|
||||||
</QPopupProxy>
|
</QPopupProxy>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
describe('ClaimNotes', () => {
|
||||||
|
const descriptorOptions = '[data-cy="descriptor-more-opts-menu"] > .q-list';
|
||||||
|
const url = '/#/account/1/summary';
|
||||||
|
|
||||||
|
it('should see all the account options', () => {
|
||||||
|
cy.login('itManagement');
|
||||||
|
cy.visit(url);
|
||||||
|
cy.dataCy('descriptor-more-opts').click();
|
||||||
|
cy.get(descriptorOptions)
|
||||||
|
.find('.q-item')
|
||||||
|
.its('length')
|
||||||
|
.then((count) => {
|
||||||
|
cy.log('Número de opciones:', count);
|
||||||
|
expect(count).to.equal(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not see any option', () => {
|
||||||
|
cy.login('salesPerson');
|
||||||
|
cy.visit(url);
|
||||||
|
cy.dataCy('descriptor-more-opts').click();
|
||||||
|
cy.get(descriptorOptions).should('not.be.visible');
|
||||||
|
});
|
||||||
|
});
|
|
@ -67,7 +67,7 @@ describe('Entry', () => {
|
||||||
|
|
||||||
it('Should notify when entry is lock by another user', () => {
|
it('Should notify when entry is lock by another user', () => {
|
||||||
const checkLockMessage = () => {
|
const checkLockMessage = () => {
|
||||||
cy.get('[data-cy="entry-lock-confirm"]').should('be.visible');
|
cy.get('[role="dialog"]').should('be.visible');
|
||||||
cy.get('[data-cy="VnConfirm_message"] > span').should(
|
cy.get('[data-cy="VnConfirm_message"] > span').should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
'This entry has been locked by buyerNick',
|
'This entry has been locked by buyerNick',
|
||||||
|
|
|
@ -1,36 +1,33 @@
|
||||||
/// <reference types="cypress" />
|
|
||||||
describe('Item tag', () => {
|
describe('Item tag', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1920, 1080);
|
cy.viewport(1920, 1080);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit(`/#/item/1/tags`);
|
cy.visit(`/#/item/1/tags`);
|
||||||
|
cy.get('.q-page').should('be.visible');
|
||||||
|
cy.waitForElement('[data-cy="itemTags"]');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const createNewTag = 'createNewTag';
|
||||||
|
const saveBtn = 'crudModelDefaultSaveBtn';
|
||||||
|
const newTag = 'tagundefined';
|
||||||
|
|
||||||
it('should throw an error adding an existent tag', () => {
|
it('should throw an error adding an existent tag', () => {
|
||||||
cy.get('.q-page').should('be.visible');
|
cy.dataCy(createNewTag).click();
|
||||||
cy.get('.q-page-sticky > div').click();
|
cy.dataCy(newTag).should('be.visible').click().type('Genero{enter}');
|
||||||
cy.get('.q-page-sticky > div').click();
|
cy.dataCy('tagGeneroValue').eq(1).should('be.visible');
|
||||||
cy.dataCy('Tag_select').eq(7).type('Tallos');
|
cy.dataCy(saveBtn).click();
|
||||||
cy.get('.q-menu .q-item').contains('Tallos').click();
|
|
||||||
cy.get(':nth-child(8) > [label="Value"]').type('1');
|
|
||||||
cy.dataCy('crudModelDefaultSaveBtn').click();
|
|
||||||
cy.checkNotification("The tag or priority can't be repeated for an item");
|
cy.checkNotification("The tag or priority can't be repeated for an item");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add a new tag', () => {
|
it('should add a new tag', () => {
|
||||||
cy.get('.q-page').should('be.visible');
|
cy.dataCy(createNewTag).click();
|
||||||
cy.get('.q-page-sticky > div').click();
|
cy.dataCy(newTag).should('be.visible').click().type('Forma{enter}');
|
||||||
cy.get('.q-page-sticky > div').click();
|
cy.dataCy('tagFormaValue').should('be.visible').type('50');
|
||||||
cy.dataCy('Tag_select').eq(7).click();
|
cy.dataCy(saveBtn).click();
|
||||||
cy.get('.q-menu .q-item').contains('Ancho de la base').type('{enter}');
|
|
||||||
cy.get(':nth-child(8) > [label="Value"]').type('50');
|
|
||||||
cy.dataCy('crudModelDefaultSaveBtn').click();
|
|
||||||
cy.checkNotification('Data saved');
|
cy.checkNotification('Data saved');
|
||||||
cy.dataCy('itemTags')
|
cy.dataCy('deleteTagForma').should('be.visible').click();
|
||||||
.children(':nth-child(8)')
|
cy.dataCy('VnConfirm_confirm').should('be.visible').click();
|
||||||
.find('.justify-center > .q-icon')
|
|
||||||
.click();
|
|
||||||
cy.dataCy('VnConfirm_confirm').click();
|
|
||||||
cy.checkNotification('Data saved');
|
cy.checkNotification('Data saved');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue