8627-devToTest #1421
|
@ -51,7 +51,5 @@ export default boot(({ app }) => {
|
|||
|
||||
await useCau(response, message);
|
||||
};
|
||||
app.directive('shortcut', keyShortcut);
|
||||
app.mixin(qFormMixin);
|
||||
app.mixin(mainShortcutMixin);
|
||||
app.provide('app', app);
|
||||
});
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
colors: {
|
||||
type: Array,
|
||||
required: true,
|
||||
validator: (value) => value.length <= 3,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="color-div">
|
||||
<div
|
||||
v-for="(color, index) in colors"
|
||||
:key="index"
|
||||
:style="{
|
||||
backgroundColor: color,
|
||||
height: '10px',
|
||||
}"
|
||||
>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.color-div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { markRaw, computed } from 'vue';
|
||||
import { QIcon, QCheckbox } from 'quasar';
|
||||
import { QIcon, QCheckbox, QToggle } from 'quasar';
|
||||
import { dashIfEmpty } from 'src/filters';
|
||||
|
||||
/* basic input */
|
||||
|
@ -48,6 +48,10 @@ const $props = defineProps({
|
|||
type: Boolean,
|
||||
default: null,
|
||||
},
|
||||
eventHandlers: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const defaultSelect = {
|
||||
|
@ -141,6 +145,9 @@ const defaultComponents = {
|
|||
userLink: {
|
||||
component: markRaw(VnUserLink),
|
||||
},
|
||||
toggle: {
|
||||
component: markRaw(QToggle),
|
||||
},
|
||||
};
|
||||
|
||||
const value = computed(() => {
|
||||
|
@ -187,6 +194,7 @@ const components = computed(() => {
|
|||
...(component.attrs || {}),
|
||||
autofocus: $props.autofocus,
|
||||
},
|
||||
event: { ...component?.event, ...$props?.eventHandlers },
|
||||
};
|
||||
return acc;
|
||||
}, {});
|
||||
|
@ -200,7 +208,6 @@ const components = computed(() => {
|
|||
:components="components"
|
||||
:value="{ row, model }"
|
||||
v-model="model"
|
||||
@blur="emit('blur')"
|
||||
/>
|
||||
<VnComponent
|
||||
v-if="col.component"
|
||||
|
@ -208,7 +215,6 @@ const components = computed(() => {
|
|||
:components="components"
|
||||
:value="{ row, model }"
|
||||
v-model="model"
|
||||
@blur="emit('blur')"
|
||||
/>
|
||||
<span :title="value" v-else>{{ value }}</span>
|
||||
<VnComponent
|
||||
|
@ -217,7 +223,7 @@ const components = computed(() => {
|
|||
:components="components"
|
||||
:value="{ row, model }"
|
||||
v-model="model"
|
||||
@blur="emit('blur')"
|
||||
/>
|
||||
<slot name="append" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -58,7 +58,7 @@ const selectComponent = {
|
|||
component: markRaw(VnSelect),
|
||||
event: updateEvent,
|
||||
attrs: {
|
||||
class: 'q-px-sm q-pb-xs q-pt-none fit',
|
||||
class: 'q-pt-none fit test',
|
||||
dense: true,
|
||||
filled: !$props.showTitle,
|
||||
},
|
||||
|
@ -120,6 +120,7 @@ const components = {
|
|||
};
|
||||
|
||||
async function addFilter(value, name) {
|
||||
console.log('test');
|
||||
value ??= undefined;
|
||||
if (value && typeof value === 'object') value = model.value;
|
||||
value = value === '' ? undefined : value;
|
||||
|
@ -168,3 +169,12 @@ const onTabPressed = async () => {
|
|||
/>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
/* label.test {
|
||||
padding-bottom: 0px !important;
|
||||
background-color: red;
|
||||
} */
|
||||
label.test > .q-field__inner > .q-field__control {
|
||||
padding: inherit;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,23 +1,36 @@
|
|||
<script setup>
|
||||
import { ref, onBeforeMount, onMounted, computed, watch, useAttrs, nextTick } from 'vue';
|
||||
import {
|
||||
ref,
|
||||
onBeforeMount,
|
||||
onMounted,
|
||||
computed,
|
||||
watch,
|
||||
h,
|
||||
render,
|
||||
inject,
|
||||
useAttrs,
|
||||
} from 'vue';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||
import { dashIfEmpty } from 'src/filters';
|
||||
|
||||
import CrudModel from 'src/components/CrudModel.vue';
|
||||
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||
|
||||
import VnTableColumn from 'components/VnTable/VnColumn.vue';
|
||||
import VnColumn from 'components/VnTable/VnColumn.vue';
|
||||
import VnFilter from 'components/VnTable/VnFilter.vue';
|
||||
import VnTableChip from 'components/VnTable/VnChip.vue';
|
||||
import VnVisibleColumn from 'src/components/VnTable/VnVisibleColumn.vue';
|
||||
import VnLv from 'components/ui/VnLv.vue';
|
||||
import VnTableOrder from 'src/components/VnTable/VnOrder.vue';
|
||||
import VnTableFilter from './VnTableFilter.vue';
|
||||
import { dashIfEmpty } from 'src/filters';
|
||||
|
||||
const arrayData = useArrayData(useAttrs()['data-key']);
|
||||
const $props = defineProps({
|
||||
columns: {
|
||||
type: Array,
|
||||
|
@ -115,6 +128,10 @@ const $props = defineProps({
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
withFilters: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const stateStore = useStateStore();
|
||||
|
@ -136,7 +153,12 @@ const createForm = ref();
|
|||
const tableRef = ref();
|
||||
const params = ref(useFilterParams($attrs['data-key']).params);
|
||||
const orders = ref(useFilterParams($attrs['data-key']).orders);
|
||||
const app = inject('app');
|
||||
|
||||
const editingRow = ref(null);
|
||||
const editingField = ref(null);
|
||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||
const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
|
||||
const tableModes = [
|
||||
{
|
||||
icon: 'view_column',
|
||||
|
@ -156,7 +178,6 @@ onBeforeMount(() => {
|
|||
const urlParams = route.query[$props.searchUrl];
|
||||
hasParams.value = urlParams && Object.keys(urlParams).length !== 0;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
mode.value =
|
||||
quasar.platform.is.mobile && !$props.disableOption?.card
|
||||
|
@ -185,9 +206,6 @@ watch(
|
|||
{ immediate: true }
|
||||
);
|
||||
|
||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||
const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
|
||||
|
||||
function splitColumns(columns) {
|
||||
splittedColumns.value = {
|
||||
columns: [],
|
||||
|
@ -306,99 +324,210 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
|
|||
}
|
||||
}
|
||||
|
||||
const editingRow = ref(null);
|
||||
const editingField = ref(null);
|
||||
function isEditableColumn(column) {
|
||||
const isEditableCol = column?.isEditable ?? true;
|
||||
const isVisible = column?.visible ?? true;
|
||||
const hasComponent = column?.component;
|
||||
|
||||
const handleClick = (event) => {
|
||||
return $props.isEditable && isVisible && hasComponent && isEditableCol;
|
||||
}
|
||||
|
||||
function hasEditableFormat(column) {
|
||||
if (isEditableColumn(column)) return 'editable-text';
|
||||
}
|
||||
|
||||
const handleClick = async (event) => {
|
||||
const clickedElement = event.target.closest('td');
|
||||
|
||||
if (!clickedElement) return;
|
||||
|
||||
const rowIndex = clickedElement.getAttribute('data-row-index');
|
||||
console.log('HandleRowIndex: ', rowIndex);
|
||||
const colField = clickedElement.getAttribute('data-col-field');
|
||||
console.log('HandleColField: ', colField);
|
||||
|
||||
if (rowIndex !== null && colField) {
|
||||
startEditing(Number(rowIndex), colField);
|
||||
}
|
||||
};
|
||||
const vnEditableCell = ref(null);
|
||||
const startEditing = async (rowId, field) => {
|
||||
const col = $props.columns.find((col) => col.name === field);
|
||||
if (col?.isEditable === false) return;
|
||||
editingRow.value = rowId;
|
||||
editingField.value = field;
|
||||
if (col.component === 'checkbox') {
|
||||
await nextTick();
|
||||
const inputElement = vnEditableCell.value?.$el?.querySelector('span > div');
|
||||
inputElement.focus();
|
||||
console.log('handleClick STARTEDEDITING');
|
||||
const column = $props.columns.find((col) => col.name === colField);
|
||||
console.log('isEditableColumn(column): ', isEditableColumn(column));
|
||||
if (!isEditableColumn(column)) return;
|
||||
await startEditing(Number(rowIndex), colField, clickedElement);
|
||||
if (column.component !== 'checkbox') console.log();
|
||||
}
|
||||
};
|
||||
|
||||
const stopEditing = (rowIndex, field) => {
|
||||
async function startEditing(rowId, field, clickedElement) {
|
||||
console.log('startEditing: ', field);
|
||||
if (rowId === editingRow.value && field === editingField.value) return;
|
||||
editingRow.value = rowId;
|
||||
editingField.value = field;
|
||||
|
||||
const column = $props.columns.find((col) => col.name === field);
|
||||
console.log('LaVerdaderacolumn: ', column);
|
||||
const row = CrudModelRef.value.formData[rowId];
|
||||
const oldValue = CrudModelRef.value.formData[rowId][column?.name];
|
||||
console.log('changes: ', CrudModelRef.value.getChanges());
|
||||
|
||||
if (!clickedElement)
|
||||
clickedElement = document.querySelector(
|
||||
`[data-row-index="${rowId}"][data-col-field="${field}"]`
|
||||
);
|
||||
|
||||
Array.from(clickedElement.childNodes).forEach((child) => {
|
||||
child.style.visibility = 'hidden';
|
||||
child.style.position = 'absolute';
|
||||
});
|
||||
|
||||
console.log('row[column.name]: ', row[column.name]);
|
||||
const node = h(VnColumn, {
|
||||
row: row,
|
||||
column: column,
|
||||
modelValue: row[column.name],
|
||||
componentProp: 'columnField',
|
||||
autofocus: true,
|
||||
focusOnMount: true,
|
||||
eventHandlers: {
|
||||
'update:modelValue': (value) => {
|
||||
console.log('update:modelValue: ', value);
|
||||
row[column.name] = value;
|
||||
|
||||
column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
||||
},
|
||||
onMouseDown: (event) => {
|
||||
console.log('mouseDown: ', field);
|
||||
if (column.component === 'checkbox') event.stopPropagation();
|
||||
},
|
||||
blur: () => {
|
||||
/* const focusElement = document.activeElement;
|
||||
const rowIndex = focusElement.getAttribute('data-row-index');
|
||||
const colField = focusElement.getAttribute('data-col-field');
|
||||
console.log('rowIndex: ', rowIndex);
|
||||
console.log('colField: ', colField);
|
||||
console.log('editingField.value: ', editingField.value);
|
||||
console.log('editingRow.value: ', editingRow.value);
|
||||
|
||||
handleBlur(rowId, field, clickedElement);
|
||||
column?.cellEvent?.blur?.(row); */
|
||||
},
|
||||
keyup: async (event) => {
|
||||
console.log('keyup: ', field);
|
||||
if (event.key === 'Enter') handleBlur(rowId, field, clickedElement);
|
||||
},
|
||||
keydown: async (event) => {
|
||||
switch (event.key) {
|
||||
case 'Tab':
|
||||
console.log('TabTest: ', field);
|
||||
await handleTabKey(event, rowId, field);
|
||||
event.stopPropagation();
|
||||
if (column.component === 'checkbox')
|
||||
handleBlur(rowId, field, clickedElement);
|
||||
break;
|
||||
case 'Escape':
|
||||
console.log('Escape: ', field);
|
||||
stopEditing(rowId, field, clickedElement);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
click: (event) => {
|
||||
/* event.stopPropagation();
|
||||
console.log('click: ', field);
|
||||
|
||||
if (column.component === 'checkbox') {
|
||||
const allowNull = column?.toggleIndeterminate ?? true;
|
||||
const currentValue = row[column.name];
|
||||
|
||||
let newValue;
|
||||
|
||||
if (allowNull) {
|
||||
if (currentValue === null) {
|
||||
newValue = true;
|
||||
} else if (currentValue) {
|
||||
newValue = false;
|
||||
} else {
|
||||
newValue = null;
|
||||
}
|
||||
} else {
|
||||
newValue = !currentValue;
|
||||
}
|
||||
row[column.name] = newValue;
|
||||
|
||||
column?.cellEvent?.['update:modelValue']?.(newValue, row);
|
||||
}
|
||||
column?.cellEvent?.['click']?.(event, row); */
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
node.appContext = app._context;
|
||||
render(node, clickedElement);
|
||||
|
||||
if (column.component === 'checkbox') node.el?.querySelector('span > div').focus();
|
||||
}
|
||||
|
||||
function stopEditing(rowIndex, field, clickedElement) {
|
||||
console.log('stopEditing: ', field);
|
||||
if (clickedElement) {
|
||||
render(null, clickedElement);
|
||||
Array.from(clickedElement.childNodes).forEach((child) => {
|
||||
child.style.visibility = 'visible';
|
||||
child.style.position = '';
|
||||
});
|
||||
}
|
||||
if (editingRow.value !== rowIndex || editingField.value !== field) return;
|
||||
editingRow.value = null;
|
||||
editingField.value = null;
|
||||
};
|
||||
}
|
||||
|
||||
const handleTab = async (rowIndex, colName) => {
|
||||
function handleBlur(rowIndex, field, clickedElement) {
|
||||
console.log('handleBlur: ', field);
|
||||
stopEditing(rowIndex, field, clickedElement);
|
||||
}
|
||||
|
||||
async function handleTabNavigation(rowIndex, colName, direction) {
|
||||
const columns = $props.columns;
|
||||
|
||||
const totalColumns = columns.length;
|
||||
let currentColumnIndex = columns.findIndex((col) => col.name === colName);
|
||||
let newColumnIndex = currentColumnIndex + 1;
|
||||
while (
|
||||
columns[newColumnIndex]?.visible === false ||
|
||||
columns[newColumnIndex]?.isEditable === false ||
|
||||
!columns[newColumnIndex]?.component
|
||||
) {
|
||||
newColumnIndex++;
|
||||
if (newColumnIndex >= columns.length) newColumnIndex = 0;
|
||||
}
|
||||
|
||||
if (currentColumnIndex >= newColumnIndex) rowIndex++;
|
||||
let iterations = 0;
|
||||
let newColumnIndex = currentColumnIndex;
|
||||
|
||||
await startEditing(rowIndex, columns[newColumnIndex].name);
|
||||
};
|
||||
do {
|
||||
iterations++;
|
||||
newColumnIndex = (newColumnIndex + direction + totalColumns) % totalColumns;
|
||||
|
||||
const handleShiftTab = async (rowIndex, colName) => {
|
||||
console.log('handleShiftTab: ');
|
||||
const columns = $props.columns;
|
||||
const currentColumnIndex = columns.findIndex((col) => col.name === colName);
|
||||
if (isEditableColumn(columns[newColumnIndex])) break;
|
||||
} while (iterations < totalColumns);
|
||||
|
||||
if (currentColumnIndex === -1) return;
|
||||
|
||||
let prevColumnIndex = currentColumnIndex - 1;
|
||||
let prevRowIndex = rowIndex;
|
||||
|
||||
while (prevColumnIndex >= 0 && columns[prevColumnIndex]?.isEditable === false) {
|
||||
prevColumnIndex--;
|
||||
}
|
||||
|
||||
if (prevColumnIndex < 0) {
|
||||
prevColumnIndex = columns.length - 1;
|
||||
prevRowIndex -= 1;
|
||||
|
||||
while (prevRowIndex >= 0 && columns[prevColumnIndex]?.isEditable === false) {
|
||||
prevColumnIndex--;
|
||||
if (prevColumnIndex < 0) {
|
||||
prevColumnIndex = columns.length - 1;
|
||||
prevRowIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prevRowIndex < 0) {
|
||||
stopEditing(rowIndex, colName);
|
||||
if (iterations >= totalColumns) {
|
||||
console.warn('No editable columns found.');
|
||||
return;
|
||||
}
|
||||
|
||||
await startEditing(prevRowIndex, columns[prevColumnIndex]?.name);
|
||||
console.log('finishHandleShiftTab');
|
||||
};
|
||||
if (direction === 1 && newColumnIndex <= currentColumnIndex) {
|
||||
rowIndex++;
|
||||
} else if (direction === -1 && newColumnIndex >= currentColumnIndex) {
|
||||
rowIndex--;
|
||||
}
|
||||
console.log('next: ', columns[newColumnIndex].name, 'rowIndex: ', rowIndex);
|
||||
return { nextRowIndex: rowIndex, nextColumnName: columns[newColumnIndex].name };
|
||||
}
|
||||
|
||||
async function handleTabKey(event, rowIndex, colName) {
|
||||
const direction = event.shiftKey ? -1 : 1;
|
||||
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
|
||||
rowIndex,
|
||||
colName,
|
||||
direction
|
||||
);
|
||||
|
||||
if (nextRowIndex < 0 || nextRowIndex >= arrayData.store.data.length) return;
|
||||
|
||||
event.preventDefault();
|
||||
await startEditing(nextRowIndex, nextColumnName, null);
|
||||
}
|
||||
|
||||
const handleTabKey = async (event, rowIndex, colName) => {
|
||||
if (event.shiftKey) await handleShiftTab(rowIndex, colName);
|
||||
else await handleTab(rowIndex, colName);
|
||||
};
|
||||
function getCheckboxIcon(value) {
|
||||
switch (typeof value) {
|
||||
case 'boolean':
|
||||
|
@ -408,25 +537,35 @@ function getCheckboxIcon(value) {
|
|||
? 'indeterminate_check_box'
|
||||
: 'unknown_med';
|
||||
case 'number':
|
||||
return value > 0 ? 'check' : 'close';
|
||||
return value === 0 ? 'close' : 'check';
|
||||
case 'object':
|
||||
return value === null ? 'help_outline' : 'unknown_med';
|
||||
case 'undefined':
|
||||
return 'help_outline';
|
||||
default:
|
||||
return 'unknown_med';
|
||||
return 'indeterminate_check_box';
|
||||
}
|
||||
}
|
||||
|
||||
function shouldDisplayReadonly(col, rowIndex) {
|
||||
return (
|
||||
!col?.component ||
|
||||
editingRow.value !== rowIndex ||
|
||||
editingField.value !== col?.name
|
||||
);
|
||||
}
|
||||
/* function getCheckboxIcon(value) {
|
||||
switch (typeof value) {
|
||||
case 'boolean':
|
||||
return value ? 'check_box' : 'check_box_outline_blank';
|
||||
case 'string':
|
||||
return value.toLowerCase() === 'partial'
|
||||
? 'indeterminate_check_box'
|
||||
: 'unknown_med';
|
||||
case 'number':
|
||||
return value === 0 ? 'check_box_outline_blank' : 'check_box';
|
||||
case 'object':
|
||||
return value === null ? 'help_outline' : 'unknown_med';
|
||||
case 'undefined':
|
||||
return 'help_outline';
|
||||
default:
|
||||
return 'indeterminate_check_box';
|
||||
}
|
||||
} */
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QDrawer
|
||||
v-if="$props.rightSearch"
|
||||
|
@ -477,7 +616,7 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
@row-click="(_, row) => rowClickFunction && rowClickFunction(row)"
|
||||
@update:selected="emit('update:selected', $event)"
|
||||
@selection="(details) => handleSelection(details, rows)"
|
||||
@click="handleClick"
|
||||
v-on="isEditable ? { click: handleClick } : {}"
|
||||
>
|
||||
<template #top-left v-if="!$props.withoutHeader">
|
||||
<slot name="top-left"> </slot>
|
||||
|
@ -496,13 +635,6 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
dense
|
||||
: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 #header-cell="{ col }">
|
||||
<QTh
|
||||
|
@ -512,7 +644,9 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
>
|
||||
<div
|
||||
class="no-padding"
|
||||
:style="$props.columnSearch ? 'height: 75px' : ''"
|
||||
:style="
|
||||
withFilters && $props.columnSearch ? 'height: 75px' : ''
|
||||
"
|
||||
>
|
||||
<div class="text-center" style="height: 30px">
|
||||
<QTooltip v-if="col.toolTip">{{ col.toolTip }}</QTooltip>
|
||||
|
@ -525,13 +659,17 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
/>
|
||||
</div>
|
||||
<VnFilter
|
||||
v-if="$props.columnSearch && col.columnSearch !== false"
|
||||
v-if="
|
||||
$props.columnSearch &&
|
||||
col.columnSearch !== false &&
|
||||
withFilters
|
||||
"
|
||||
:column="col"
|
||||
:show-title="true"
|
||||
:data-key="$attrs['data-key']"
|
||||
v-model="params[columnName(col)]"
|
||||
:search-url="searchUrl"
|
||||
class="full-width"
|
||||
class="full-width test"
|
||||
/>
|
||||
</div>
|
||||
</QTh>
|
||||
|
@ -550,7 +688,6 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
</template>
|
||||
<template #body-cell="{ col, row, rowIndex }">
|
||||
<QTd
|
||||
auto-width
|
||||
class="no-margin q-px-xs"
|
||||
v-if="col.visible ?? true"
|
||||
:style="{
|
||||
|
@ -566,7 +703,6 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
:data-col-field="col?.name"
|
||||
>
|
||||
<div
|
||||
v-if="shouldDisplayReadonly(col, rowIndex)"
|
||||
class="no-padding no-margin"
|
||||
style="
|
||||
overflow: hidden;
|
||||
|
@ -584,18 +720,12 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
v-if="col?.component === 'checkbox'"
|
||||
:name="getCheckboxIcon(row[col?.name])"
|
||||
style="color: var(--vn-text-color)"
|
||||
size="var(--font-size)"
|
||||
:class="
|
||||
isEditable &&
|
||||
(col?.component ? 'editable-text' : '')
|
||||
"
|
||||
:class="hasEditableFormat(col)"
|
||||
size="17px"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
:class="
|
||||
isEditable &&
|
||||
(col?.component ? 'editable-text' : '')
|
||||
"
|
||||
:class="hasEditableFormat(col)"
|
||||
:style="col?.style ? col.style(row) : null"
|
||||
style="bottom: 0"
|
||||
>
|
||||
|
@ -607,27 +737,6 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
</span>
|
||||
</slot>
|
||||
</div>
|
||||
<div v-else>
|
||||
<VnTableColumn
|
||||
ref="vnEditableCell"
|
||||
:column="col"
|
||||
:row="row"
|
||||
:is-editable="col.isEditable ?? isEditable"
|
||||
v-model="row[col.name]"
|
||||
component-prop="columnField"
|
||||
class="cell-input q-px-xs"
|
||||
@blur="stopEditing(rowIndex, col?.name)"
|
||||
@keyup.enter="stopEditing(rowIndex, col?.name)"
|
||||
@keydown.tab.prevent="
|
||||
handleTabKey($event, rowIndex, col?.name)
|
||||
"
|
||||
@keydown.shift.tab.prevent="
|
||||
handleShiftTab(rowIndex, col?.name)
|
||||
"
|
||||
@keydown.escape="stopEditing(rowIndex, col?.name)"
|
||||
:autofocus="true"
|
||||
/>
|
||||
</div>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-tableActions="{ col, row }">
|
||||
|
@ -751,7 +860,7 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
:row="row"
|
||||
:row-index="index"
|
||||
>
|
||||
<VnTableColumn
|
||||
<VnColumn
|
||||
:column="col"
|
||||
:row="row"
|
||||
:is-editable="false"
|
||||
|
@ -792,7 +901,8 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
</component>
|
||||
</template>
|
||||
<template #bottom-row="{ cols }" v-if="$props.footer">
|
||||
<QTr v-if="rows.length" style="height: 30px">
|
||||
<QTr v-if="rows.length" style="height: 45px">
|
||||
<QTh v-if="table.selection" />
|
||||
<QTh
|
||||
v-for="col of cols.filter((cols) => cols.visible ?? true)"
|
||||
:key="col?.id"
|
||||
|
@ -838,7 +948,7 @@ function shouldDisplayReadonly(col, rowIndex) {
|
|||
:column-name="column.name"
|
||||
:label="column.label"
|
||||
>
|
||||
<VnTableColumn
|
||||
<VnColumn
|
||||
:column="column"
|
||||
:row="{}"
|
||||
default="input"
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<script setup>
|
||||
const $props = defineProps({
|
||||
colors: {
|
||||
type: String,
|
||||
default: '{"value":[]}',
|
||||
},
|
||||
});
|
||||
|
||||
const colorArray = JSON.parse($props.colors)?.value;
|
||||
const maxHeight = 30;
|
||||
const colorHeight = maxHeight / colorArray?.length;
|
||||
</script>
|
||||
<template>
|
||||
<div class="color-div" :style="{ height: `${maxHeight}px` }">
|
||||
<div
|
||||
v-for="(color, index) in colorArray"
|
||||
:key="index"
|
||||
:style="{
|
||||
backgroundColor: `#${color}`,
|
||||
height: `${colorHeight}px`,
|
||||
}"
|
||||
>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.color-div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
|
@ -45,6 +45,7 @@ function toValueAttrs(attrs) {
|
|||
}
|
||||
</script>
|
||||
<template>
|
||||
<slot name="test" />
|
||||
<span
|
||||
v-for="toComponent of componentArray"
|
||||
:key="toComponent.name"
|
||||
|
@ -57,6 +58,7 @@ function toValueAttrs(attrs) {
|
|||
v-on="mix(toComponent).event ?? {}"
|
||||
v-model="model"
|
||||
@blur="emit('blur')"
|
||||
@mouse-down="() => console.log('mouse-down')"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
@ -70,10 +70,6 @@ const focus = () => {
|
|||
vnInputRef.value.focus();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
focus,
|
||||
});
|
||||
|
||||
const mixinRules = [
|
||||
requiredFieldRule,
|
||||
...($attrs.rules ?? []),
|
||||
|
|
|
@ -6,7 +6,7 @@ import { useRequired } from 'src/composables/useRequired';
|
|||
import dataByOrder from 'src/utils/dataByOrder';
|
||||
import { QItemLabel } from 'quasar';
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'update:options', 'remove', 'blur']);
|
||||
const emit = defineEmits(['update:modelValue', 'update:options', 'remove']);
|
||||
const $attrs = useAttrs();
|
||||
const { t } = useI18n();
|
||||
|
||||
|
@ -327,7 +327,6 @@ function handleKeyDown(event) {
|
|||
:option-value="optionValue"
|
||||
v-bind="{ ...$attrs, ...styleAttrs }"
|
||||
@filter="filterHandler"
|
||||
@blur="() => emit('blur')"
|
||||
:emit-value="nullishToTrue($attrs['emit-value'])"
|
||||
:map-options="nullishToTrue($attrs['map-options'])"
|
||||
:use-input="nullishToTrue($attrs['use-input'])"
|
||||
|
|
|
@ -34,7 +34,6 @@ const isAllowedToCreate = computed(() => {
|
|||
return role.hasAny($props.rolesAllowedToCreate);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VnSelect
|
||||
v-model="value"
|
||||
|
@ -63,7 +62,6 @@ const isAllowedToCreate = computed(() => {
|
|||
</template>
|
||||
</VnSelect>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.default-icon {
|
||||
cursor: pointer;
|
||||
|
|
|
@ -76,7 +76,6 @@ a {
|
|||
text-decoration: underline;
|
||||
}
|
||||
|
||||
// Removes chrome autofill background
|
||||
input:-webkit-autofill,
|
||||
select:-webkit-autofill {
|
||||
color: var(--vn-text-color);
|
||||
|
|
|
@ -392,16 +392,26 @@ entry:
|
|||
list:
|
||||
newEntry: New entry
|
||||
tableVisibleColumns:
|
||||
created: Creation
|
||||
supplierFk: Supplier
|
||||
isBooked: Booked
|
||||
isConfirmed: Confirmed
|
||||
isExcludedFromAvailable: Exclude from inventory
|
||||
isOrdered: Ordered
|
||||
isConfirmed: Ready to label
|
||||
isReceived: Received
|
||||
isRaid: Raid
|
||||
landed: Date
|
||||
supplierFk: Supplier
|
||||
reference: Ref/Alb/Guide
|
||||
invoiceNumber: Invoice
|
||||
agencyModeId: Agency
|
||||
isBooked: Booked
|
||||
companyFk: Company
|
||||
travelFk: Travel
|
||||
isExcludedFromAvailable: Inventory
|
||||
evaNotes: Notes
|
||||
warehouseOutFk: Origin
|
||||
warehouseInFk: Destiny
|
||||
entryTypeDescription: Entry type
|
||||
invoiceAmount: Import
|
||||
travelFk: Travel
|
||||
summary:
|
||||
invoiceAmount: Amount
|
||||
commission: Commission
|
||||
currency: Currency
|
||||
invoiceNumber: Invoice number
|
||||
|
@ -454,7 +464,10 @@ entry:
|
|||
ektFk: Ekt
|
||||
packingOut: Package out
|
||||
landing: Landing
|
||||
isExcludedFromAvailable: Es inventory
|
||||
isExcludedFromAvailable: Exclude from inventory
|
||||
isRaid: Raid
|
||||
invoiceNumber: Invoice
|
||||
reference: Ref/Alb/Guide
|
||||
ticket:
|
||||
card:
|
||||
customerId: Customer ID
|
||||
|
|
|
@ -392,16 +392,26 @@ entry:
|
|||
list:
|
||||
newEntry: Nueva entrada
|
||||
tableVisibleColumns:
|
||||
created: Creación
|
||||
supplierFk: Proveedor
|
||||
isBooked: Asentado
|
||||
isConfirmed: Confirmado
|
||||
isExcludedFromAvailable: Excluir del inventario
|
||||
isOrdered: Pedida
|
||||
isConfirmed: Lista para etiquetar
|
||||
isReceived: Recibida
|
||||
isRaid: Redada
|
||||
landed: Fecha
|
||||
supplierFk: Proveedor
|
||||
invoiceNumber: Nº Factura
|
||||
reference: Ref/Alb/Guía
|
||||
agencyModeId: Agencia
|
||||
isBooked: Asentado
|
||||
companyFk: Empresa
|
||||
travelFk: Envio
|
||||
isExcludedFromAvailable: Inventario
|
||||
evaNotes: Notas
|
||||
warehouseOutFk: Origen
|
||||
warehouseInFk: Destino
|
||||
entryTypeDescription: Tipo entrada
|
||||
invoiceAmount: Importe
|
||||
summary:
|
||||
invoiceAmount: Importe
|
||||
commission: Comisión
|
||||
currency: Moneda
|
||||
invoiceNumber: Núm. factura
|
||||
|
@ -455,7 +465,10 @@ entry:
|
|||
ektFk: Ekt
|
||||
packingOut: Embalaje envíos
|
||||
landing: Llegada
|
||||
isExcludedFromAvailable: Es inventario
|
||||
isExcludedFromAvailable: Excluir del inventario
|
||||
isRaid: Redada
|
||||
invoiceNumber: Nº Factura
|
||||
reference: Ref/Alb/Guía
|
||||
ticket:
|
||||
card:
|
||||
customerId: ID cliente
|
||||
|
|
|
@ -100,17 +100,6 @@ const columns = computed(() => [
|
|||
columnFilter: {
|
||||
component: 'number',
|
||||
},
|
||||
columnField: {
|
||||
component: null,
|
||||
after: {
|
||||
component: markRaw(VnLinkPhone),
|
||||
attrs: ({ model }) => {
|
||||
return {
|
||||
'phone-number': model,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
|
|
|
@ -247,8 +247,14 @@ function handleLocation(data, location) {
|
|||
:label="t('Longitude')"
|
||||
clearable
|
||||
v-model="data.longitude"
|
||||
:decimal-places="6"
|
||||
/>
|
||||
<VnInputNumber
|
||||
:label="t('Latitude')"
|
||||
clearable
|
||||
v-model="data.latitude"
|
||||
:decimal-places="6"
|
||||
/>
|
||||
<VnInputNumber :label="t('Latitude')" clearable v-model="data.latitude" />
|
||||
</VnRow>
|
||||
<h4 class="q-mb-xs">{{ t('Notes') }}</h4>
|
||||
<VnRow
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Checkbox Focus with Button</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.checkbox-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
input[type='checkbox'] {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
label {
|
||||
margin-left: 10px;
|
||||
}
|
||||
/* Estilos para el foco */
|
||||
input[type='checkbox']:focus {
|
||||
outline: 2px solid blue;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="checkbox-container">
|
||||
<input type="checkbox" id="myCheckbox" />
|
||||
<label for="myCheckbox">Acepto los términos y condiciones</label>
|
||||
</div>
|
||||
|
||||
<!-- Botón para enfocar el checkbox -->
|
||||
<button id="focusButton">Dar foco al checkbox</button>
|
||||
|
||||
<script>
|
||||
const checkbox = document.getElementById('myCheckbox');
|
||||
const focusButton = document.getElementById('focusButton');
|
||||
|
||||
// Manejador de eventos para cuando el checkbox recibe el foco
|
||||
checkbox.addEventListener('focus', () => {
|
||||
console.log('El checkbox tiene el foco');
|
||||
});
|
||||
|
||||
// Manejador de eventos para cuando el checkbox pierde el foco
|
||||
checkbox.addEventListener('blur', () => {
|
||||
console.log('El checkbox perdió el foco');
|
||||
});
|
||||
|
||||
// Manejador de eventos para cuando se cambia el estado del checkbox
|
||||
checkbox.addEventListener('change', (event) => {
|
||||
if (event.target.checked) {
|
||||
console.log('El checkbox está marcado');
|
||||
} else {
|
||||
console.log('El checkbox no está marcado');
|
||||
}
|
||||
});
|
||||
|
||||
// Dar foco al checkbox cuando se presiona el botón
|
||||
focusButton.addEventListener('click', () => {
|
||||
checkbox.focus();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -9,6 +9,7 @@ import FormModel from 'components/FormModel.vue';
|
|||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
||||
import FilterTravelForm from 'src/components/FilterTravelForm.vue';
|
||||
|
||||
|
@ -51,28 +52,6 @@ const onFilterTravelSelected = (formData, id) => {
|
|||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow>
|
||||
<VnSelect
|
||||
:label="t('globals.supplier')"
|
||||
v-model="data.supplierFk"
|
||||
url="Suppliers"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
:fields="['id', 'nickname']"
|
||||
hide-selected
|
||||
:required="true"
|
||||
map-options
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ scope.opt?.nickname }}, {{ scope.opt?.id }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
<VnSelectDialog
|
||||
:label="t('entry.basicData.travel')"
|
||||
v-model="data.travelFk"
|
||||
|
@ -105,9 +84,36 @@ const onFilterTravelSelected = (formData, id) => {
|
|||
</QItem>
|
||||
</template>
|
||||
</VnSelectDialog>
|
||||
<VnSelect
|
||||
:label="t('globals.supplier')"
|
||||
v-model="data.supplierFk"
|
||||
url="Suppliers"
|
||||
option-value="id"
|
||||
option-label="nickname"
|
||||
:fields="['id', 'nickname']"
|
||||
hide-selected
|
||||
:required="true"
|
||||
map-options
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt?.name }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ scope.opt?.nickname }}, {{ scope.opt?.id }}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelect>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnInput v-model="data.reference" :label="t('globals.reference')" />
|
||||
<VnInputNumber
|
||||
v-model="data.invoiceAmount"
|
||||
:label="t('entry.summary.invoiceAmount')"
|
||||
:positive="false"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnInput
|
||||
|
|
|
@ -2,21 +2,36 @@
|
|||
import { useStateStore } from 'stores/useStateStore';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { h, onMounted, ref } from 'vue';
|
||||
|
||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
|
||||
import FetchedTags from 'components/ui/FetchedTags.vue';
|
||||
import VnColor from 'src/components/VnColor.vue';
|
||||
import FetchedTags from 'src/components/ui/FetchedTags.vue';
|
||||
import VnColor from 'src/components/common/VnColor.vue';
|
||||
import { QCheckbox } from 'quasar';
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
editableMode: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
const stateStore = useStateStore();
|
||||
const route = useRoute();
|
||||
const selectedRows = ref([]);
|
||||
const entityId = ref($props.id ?? route.params.id);
|
||||
console.log('entityId: ', entityId.value);
|
||||
|
||||
const footer = ref({});
|
||||
const columns = [
|
||||
{
|
||||
name: 'buyFk',
|
||||
name: 'id',
|
||||
isId: true,
|
||||
visible: false,
|
||||
isEditable: false,
|
||||
|
@ -26,6 +41,7 @@ const columns = [
|
|||
label: 'Nv',
|
||||
name: 'isIgnored',
|
||||
component: 'checkbox',
|
||||
toggleIndeterminate: false,
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
|
@ -33,6 +49,7 @@ const columns = [
|
|||
label: 'Id',
|
||||
name: 'itemFk',
|
||||
component: 'input',
|
||||
isEditable: false,
|
||||
create: true,
|
||||
width: '45px',
|
||||
},
|
||||
|
@ -52,7 +69,8 @@ const columns = [
|
|||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('Size'),
|
||||
label: t('Siz.'),
|
||||
toolTip: t('Size'),
|
||||
name: 'size',
|
||||
width: '35px',
|
||||
isEditable: false,
|
||||
|
@ -63,8 +81,18 @@ const columns = [
|
|||
{
|
||||
align: 'center',
|
||||
label: t('Sti.'),
|
||||
toolTip: t('Printed Stickers/Stickers'),
|
||||
name: 'stickers',
|
||||
component: 'number',
|
||||
attrs: {
|
||||
positive: false,
|
||||
},
|
||||
cellEvent: {
|
||||
'update:modelValue': (value, oldValue, row) => {
|
||||
row['quantity'] = value * row['packing'];
|
||||
row['amount'] = row['quantity'] * row['buyingValue'];
|
||||
},
|
||||
},
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
|
@ -92,11 +120,49 @@ const columns = [
|
|||
label: 'Pack',
|
||||
name: 'packing',
|
||||
component: 'number',
|
||||
cellEvent: {
|
||||
'update:modelValue': (value, oldValue, row) => {
|
||||
console.log('oldValue: ', oldValue);
|
||||
const oldPacking = oldValue === 1 || oldValue === null ? 1 : oldValue;
|
||||
row['weight'] = (row['weight'] * value) / oldPacking;
|
||||
row['quantity'] = row['stickers'] * value;
|
||||
row['amount'] = row['quantity'] * row['buyingValue'];
|
||||
},
|
||||
},
|
||||
width: '35px',
|
||||
style: (row) => {
|
||||
if (row.groupingMode === 'grouping')
|
||||
return { color: 'var(--vn-label-color)' };
|
||||
},
|
||||
/* append: {
|
||||
name: 'groupingMode',
|
||||
h: (row) =>
|
||||
h(QCheckbox, {
|
||||
'data-name': 'groupingMode',
|
||||
modelValue: row['groupingMode'] === 'packing',
|
||||
size: 'sm',
|
||||
'onUpdate:modelValue': (value) => {
|
||||
console.log('entra');
|
||||
if (value) row['groupingMode'] = 'packing';
|
||||
else row['groupingMode'] = 'grouping';
|
||||
},
|
||||
onClick: (event) => {
|
||||
console.log('eventOnClick: ', event);
|
||||
},
|
||||
}),
|
||||
}, */
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Group',
|
||||
name: 'groupingMode',
|
||||
component: 'toggle',
|
||||
attrs: {
|
||||
trueValue: 'grouping',
|
||||
falseValue: 'packing',
|
||||
indeterminateValue: null,
|
||||
},
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
|
@ -113,17 +179,31 @@ const columns = [
|
|||
label: t('Quantity'),
|
||||
name: 'quantity',
|
||||
component: 'number',
|
||||
width: '50px',
|
||||
style: (row) => {
|
||||
if (row?.quantity !== row?.stickers * row?.packing)
|
||||
return { color: 'var(--q-negative)' };
|
||||
attrs: {
|
||||
positive: false,
|
||||
},
|
||||
cellEvent: {
|
||||
'update:modelValue': (value, oldValue, row) => {
|
||||
row['amount'] = value * row['buyingValue'];
|
||||
},
|
||||
},
|
||||
width: '50px',
|
||||
style: getQuantityStyle,
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Cost.',
|
||||
label: t('Cost'),
|
||||
toolTip: t('Buying value'),
|
||||
name: 'buyingValue',
|
||||
component: 'number',
|
||||
attrs: {
|
||||
positive: false,
|
||||
},
|
||||
cellEvent: {
|
||||
'update:modelValue': (value, oldValue, row) => {
|
||||
row['amount'] = row['quantity'] * value;
|
||||
},
|
||||
},
|
||||
width: '50px',
|
||||
},
|
||||
{
|
||||
|
@ -131,13 +211,17 @@ const columns = [
|
|||
label: t('Amount'),
|
||||
name: 'amount',
|
||||
width: '50px',
|
||||
style: () => {
|
||||
return { color: 'var(--vn-label-color)' };
|
||||
component: 'number',
|
||||
attrs: {
|
||||
positive: false,
|
||||
},
|
||||
isEditable: false,
|
||||
style: getAmountStyle,
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('Package'),
|
||||
label: t('Pack.'),
|
||||
toolTip: t('Package'),
|
||||
name: 'price2',
|
||||
component: 'number',
|
||||
width: '35px',
|
||||
|
@ -147,13 +231,40 @@ const columns = [
|
|||
label: t('Box'),
|
||||
name: 'price3',
|
||||
component: 'number',
|
||||
cellEvent: {
|
||||
'update:modelValue': (value, row) => {
|
||||
/*
|
||||
Call db.execV("UPDATE vn.item SET " & _
|
||||
"typeFk = # " & _
|
||||
",producerFk = # " & _
|
||||
",minPrice = # " & _
|
||||
",box = # " & _
|
||||
",hasMinPrice = # " & _
|
||||
",comment = # " & _
|
||||
"WHERE id = # " _
|
||||
, Me.tipo_id _
|
||||
, Me.producer_id _
|
||||
, Me.PVP _
|
||||
, Me.caja _
|
||||
, Me.Min _
|
||||
, Nz(Me.reference, 0) _
|
||||
, Me.Id_Article _
|
||||
)
|
||||
Me.Tarifa2 = Me.Tarifa2 * (Me.Tarifa3 / Me.Tarifa3.OldValue)
|
||||
Call actualizar_compra
|
||||
Me.sincro = True
|
||||
*/
|
||||
},
|
||||
},
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Min.',
|
||||
toolTip: t('Minimum price'),
|
||||
name: 'minPrice',
|
||||
component: 'number',
|
||||
isEditable: false,
|
||||
width: '35px',
|
||||
style: (row) => {
|
||||
if (row?.hasMinPrice)
|
||||
|
@ -163,21 +274,27 @@ const columns = [
|
|||
{
|
||||
align: 'center',
|
||||
label: t('P.Sen'),
|
||||
toolTip: t('Packing sent'),
|
||||
name: 'packingOut',
|
||||
component: 'number',
|
||||
isEditable: false,
|
||||
width: '40px',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('Com.'),
|
||||
toolTip: t('Comment'),
|
||||
name: 'comment',
|
||||
component: 'input',
|
||||
isEditable: false,
|
||||
width: '55px',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Prod.',
|
||||
toolTip: t('Producer'),
|
||||
name: 'subName',
|
||||
isEditable: false,
|
||||
width: '45px',
|
||||
style: () => {
|
||||
return { color: 'var(--vn-label-color)' };
|
||||
|
@ -185,43 +302,148 @@ const columns = [
|
|||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Tags',
|
||||
label: t('Tags'),
|
||||
name: 'tags',
|
||||
width: '120px',
|
||||
width: '125px',
|
||||
columnSearch: false,
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Comp.',
|
||||
toolTip: t('Company'),
|
||||
name: 'company_name',
|
||||
component: 'input',
|
||||
isEditable: false,
|
||||
width: '35px',
|
||||
},
|
||||
];
|
||||
|
||||
function getQuantityStyle(row) {
|
||||
if (row?.quantity !== row?.stickers * row?.packing)
|
||||
return { color: 'var(--q-negative)' };
|
||||
}
|
||||
function getAmountStyle(row) {
|
||||
if (row?.isChecked) return { color: 'var(--q-positive)' };
|
||||
return { color: 'var(--vn-label-color)' };
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log('viewMode: ', $props.editableMode);
|
||||
stateStore.rightDrawer = false;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<VnSubToolbar />
|
||||
<QToggle
|
||||
toggle-indeterminate
|
||||
toggle-order="ft"
|
||||
v-model="cyan"
|
||||
label="'ft' order + toggle-indeterminate"
|
||||
color="cyan"
|
||||
/>
|
||||
<Teleport to="#st-data" v-if="stateStore?.isSubToolbarShown() && editableMode">
|
||||
<QBtnGroup push style="column-gap: 1px">
|
||||
<QBtn icon="calculate" color="primary" flat @click="console.log('calculate')">
|
||||
<QTooltip>{{ t('tableActions.openBucketCalculator') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtnDropdown
|
||||
icon="box_edit"
|
||||
color="primary"
|
||||
flat
|
||||
tool-tip="test"
|
||||
@click="console.log('request_quote')"
|
||||
:title="t('tableActions.setSaleMode')"
|
||||
>
|
||||
<div>
|
||||
<QList>
|
||||
<QItem clickable v-close-popup @click="setSaleMode('packing')">
|
||||
<QItemSection>
|
||||
<QItemLabel>Packing</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem clickable v-close-popup @click="setSaleMode('packing')">
|
||||
<QItemSection>
|
||||
<QItemLabel>Grouping</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem label="Grouping" />
|
||||
</QList>
|
||||
</div>
|
||||
</QBtnDropdown>
|
||||
<QBtn
|
||||
icon="invert_colors"
|
||||
color="primary"
|
||||
flat
|
||||
@click="console.log('price_check')"
|
||||
>
|
||||
<QTooltip>{{ t('tableActions.openCalculator') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
icon="exposure_neg_1"
|
||||
color="primary"
|
||||
flat
|
||||
@click="console.log('request_quote')"
|
||||
title="test"
|
||||
>
|
||||
<QTooltip>{{ t('tableActions.invertQuantitySign') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
icon="price_check"
|
||||
color="primary"
|
||||
flat
|
||||
@click="console.log('request_quote')"
|
||||
>
|
||||
<QTooltip>{{ t('tableActions.checkAmount') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
icon="price_check"
|
||||
color="primary"
|
||||
flat
|
||||
@click="console.log('request_quote')"
|
||||
>
|
||||
<QTooltip>{{ t('tableActions.setMinPrice') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QBtnGroup>
|
||||
</Teleport>
|
||||
<FetchData
|
||||
ref="footerFetchDataRef"
|
||||
:url="`Entries/${entityId}/getBuyList`"
|
||||
:params="{ groupBy: 'GROUP BY b.entryFk' }"
|
||||
@on-fetch="
|
||||
(data) => {
|
||||
console.log('data: ', data);
|
||||
footer = data[0];
|
||||
}
|
||||
"
|
||||
auto-load
|
||||
/>
|
||||
<VnTable
|
||||
ref="tableRef"
|
||||
data-key="EntryBuys"
|
||||
:url="`Entries/${route.params.id}/getBuys`"
|
||||
:url="`Entries/${entityId}/getBuyList`"
|
||||
save-url="Buys/crud"
|
||||
:disable-option="{ card: true }"
|
||||
v-model:selected="selectedRows"
|
||||
:table="{
|
||||
'row-key': 'id',
|
||||
selection: 'multiple',
|
||||
}"
|
||||
:table="
|
||||
editableMode
|
||||
? {
|
||||
'row-key': 'id',
|
||||
selection: 'multiple',
|
||||
}
|
||||
: {}
|
||||
"
|
||||
:is-editable="editableMode"
|
||||
:without-header="!editableMode"
|
||||
:with-filters="editableMode"
|
||||
:right-search="false"
|
||||
:row-click="false"
|
||||
:columns="columns"
|
||||
class="buyList"
|
||||
is-editable
|
||||
table-height="84vh"
|
||||
auto-load
|
||||
footer
|
||||
>
|
||||
<template #column-hex>
|
||||
<VnColor :colors="['#ff0000', '#ffff00', '#ff0000']" style="height: 100%" />
|
||||
<template #column-hex="{ row }">
|
||||
<VnColor :colors="row?.hexJson" style="height: 100%" />
|
||||
</template>
|
||||
<template #column-name="{ row }">
|
||||
<span class="link">
|
||||
|
@ -233,29 +455,57 @@ onMounted(() => {
|
|||
<FetchedTags :item="row" :columns="3" />
|
||||
</template>
|
||||
<template #column-stickers="{ row }">
|
||||
<span style="color: var(--vn-label-color)">{{ row.printedStickers }}</span>
|
||||
<span>/{{ row.stickers }}</span>
|
||||
<span :class="editableMode ? 'editable-text' : ''">
|
||||
<span style="color: var(--vn-label-color)">{{
|
||||
row.printedStickers
|
||||
}}</span>
|
||||
<span>/{{ row.stickers }}</span>
|
||||
</span>
|
||||
</template>
|
||||
<template #column-footer-stickers>
|
||||
<div>
|
||||
<span style="color: var(--vn-label-color)">{{
|
||||
footer?.printedStickers
|
||||
}}</span>
|
||||
<span>/{{ footer?.stickers }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #column-footer-weight>
|
||||
{{ footer?.weight }}
|
||||
</template>
|
||||
<template #column-footer-quantity>
|
||||
<span :style="getQuantityStyle(footer)">
|
||||
{{ footer?.quantity }}
|
||||
</span>
|
||||
</template>
|
||||
<template #column-footer-amount>
|
||||
<span :style="getAmountStyle(footer)">
|
||||
{{ footer?.amount }}
|
||||
</span>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.q-checkbox__inner--dark {
|
||||
&__inner {
|
||||
border-radius: 0% !important;
|
||||
background-color: rosybrown;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<i18n>
|
||||
es:
|
||||
Article: Artículo3
|
||||
Size: Med.
|
||||
Article: Artículo
|
||||
Siz.: Med.
|
||||
Size: Medida
|
||||
Sti.: Eti.
|
||||
Bucket: Cubo
|
||||
Quantity: Cantidad
|
||||
Amount: Importe
|
||||
Pack.: Paq.
|
||||
Package: Paquete
|
||||
Box: Caja
|
||||
P.Sen: P.Env
|
||||
Packing sent: Packing envíos
|
||||
Com.: Ref.
|
||||
Comment: Referencia
|
||||
Minimum price: Precio mínimo
|
||||
Printed Stickers/Stickers: Etiquetas impresas/Etiquetas
|
||||
Cost: Cost.
|
||||
Buying value: Coste
|
||||
Producer: Productor
|
||||
Company: Compañia
|
||||
Tags: Etiquetas
|
||||
</i18n>
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import CardDescriptor from 'components/ui/CardDescriptor.vue';
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
||||
|
||||
import { toDate } from 'src/filters';
|
||||
import { usePrintService } from 'composables/usePrintService';
|
||||
import { getUrl } from 'src/composables/getUrl';
|
||||
import filter from './EntryFilter.js';
|
||||
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
||||
import axios from 'axios';
|
||||
import { useRouter } from 'vue-router';
|
||||
const { push } = useRouter();
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -55,9 +55,22 @@ const getEntryRedirectionFilter = (entry) => {
|
|||
});
|
||||
};
|
||||
|
||||
const showEntryReport = () => {
|
||||
openReport(`Entries/${route.params.id}/entry-order-pdf`);
|
||||
};
|
||||
function showEntryReport() {
|
||||
openReport(`Entries/${entityId.value}/entry-order-pdf`);
|
||||
}
|
||||
function recalculateRates() {
|
||||
console.log('recalculateRates');
|
||||
}
|
||||
async function cloneEntry() {
|
||||
console.log('cloneEntry');
|
||||
await axios
|
||||
.post(`Entries/${entityId.value}/cloneEntry`)
|
||||
.then((response) => push(`/entry/${response.data[0].vNewEntryFk}`));
|
||||
}
|
||||
async function deleteEntry() {
|
||||
console.log('deleteEntry');
|
||||
await axios.post(`Entries/${entityId.value}/deleteEntry`).then(() => push(`/entry/`));
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -73,14 +86,39 @@ const showEntryReport = () => {
|
|||
<QItem v-ripple clickable @click="showEntryReport(entity)">
|
||||
<QItemSection>{{ t('Show entry report') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-ripple clickable @click="recalculateRates(entity)">
|
||||
<QItemSection>{{ t('Recalculate rates') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-ripple clickable @click="cloneEntry(entity)">
|
||||
<QItemSection>{{ t('Clone') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-ripple clickable @click="deleteEntry(entity)">
|
||||
<QItemSection>{{ t('Delete') }}</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
<template #body="{ entity }">
|
||||
<VnLv :label="t('globals.agency')" :value="entity.travel?.agency?.name" />
|
||||
<VnLv :label="t('shipped')" :value="toDate(entity.travel?.shipped)" />
|
||||
<VnLv :label="t('landed')" :value="toDate(entity.travel?.landed)" />
|
||||
<VnLv :label="t('Travel')">
|
||||
<template #value>
|
||||
<span class="link" v-if="entity?.travelFk">
|
||||
{{ entity.travel?.agency?.name }}
|
||||
{{ entity.travel?.warehouseOut?.code }} →
|
||||
{{ entity.travel?.warehouseIn?.code }}
|
||||
<TravelDescriptorProxy :id="entity?.travelFk" />
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv
|
||||
:label="t('globals.warehouseOut')"
|
||||
:value="entity.travel?.warehouseOut?.name"
|
||||
:label="t('entry.summary.travelShipped')"
|
||||
:value="toDate(entity.travel?.shipped)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelLanded')"
|
||||
:value="toDate(entity.travel?.landed)"
|
||||
/>
|
||||
<VnLv :label="t('entry.summary.currency')" :value="entity?.currency?.code" />
|
||||
<VnLv
|
||||
:label="t('entry.summary.invoiceAmount')"
|
||||
:value="entity?.invoiceAmount"
|
||||
/>
|
||||
</template>
|
||||
<template #icons="{ entity }">
|
||||
|
@ -107,6 +145,14 @@ const showEntryReport = () => {
|
|||
}}</QTooltip
|
||||
>
|
||||
</QIcon>
|
||||
<QIcon
|
||||
v-if="!entity?.travelFk"
|
||||
name="vn:deletedTicket"
|
||||
size="xs"
|
||||
color="primary"
|
||||
>
|
||||
<QTooltip>{{ t('This entry is deleted') }}</QTooltip>
|
||||
</QIcon>
|
||||
</QCardActions>
|
||||
</template>
|
||||
<template #actions="{ entity }">
|
||||
|
@ -153,6 +199,7 @@ const showEntryReport = () => {
|
|||
</template>
|
||||
<i18n>
|
||||
es:
|
||||
Travel: Envío
|
||||
Supplier card: Ficha del proveedor
|
||||
All travels with current agency: Todos los envíos con la agencia actual
|
||||
All entries with current supplier: Todas las entradas con el proveedor actual
|
||||
|
@ -162,4 +209,5 @@ es:
|
|||
Virtual entry: Es una redada
|
||||
shipped: Enviado
|
||||
landed: Recibido
|
||||
This entry is deleted: Esta entrada está eliminada
|
||||
</i18n>
|
||||
|
|
|
@ -9,6 +9,7 @@ export default {
|
|||
'shipped',
|
||||
'agencyModeFk',
|
||||
'warehouseOutFk',
|
||||
'warehouseInFk',
|
||||
'daysInForward',
|
||||
],
|
||||
include: [
|
||||
|
@ -21,13 +22,13 @@ export default {
|
|||
{
|
||||
relation: 'warehouseOut',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
fields: ['name', 'code'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'warehouseIn',
|
||||
scope: {
|
||||
fields: ['name'],
|
||||
fields: ['name', 'code'],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -39,5 +40,11 @@ export default {
|
|||
fields: ['id', 'nickname'],
|
||||
},
|
||||
},
|
||||
{
|
||||
relation: 'currency',
|
||||
scope: {
|
||||
fields: ['id', 'code'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
import { onMounted, ref, computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { toDate } from 'src/filters';
|
||||
import { getUrl } from 'src/composables/getUrl';
|
||||
import axios from 'axios';
|
||||
|
||||
import CardSummary from 'components/ui/CardSummary.vue';
|
||||
import VnLv from 'src/components/ui/VnLv.vue';
|
||||
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
||||
|
||||
import { toDate, toCurrency } from 'src/filters';
|
||||
import { getUrl } from 'src/composables/getUrl';
|
||||
import axios from 'axios';
|
||||
import FetchedTags from 'src/components/ui/FetchedTags.vue';
|
||||
import EntryBuys from './EntryBuys.vue';
|
||||
import VnTitle from 'src/components/common/VnTitle.vue';
|
||||
import VnToSummary from 'src/components/ui/VnToSummary.vue';
|
||||
|
||||
const route = useRoute();
|
||||
|
@ -30,117 +30,6 @@ const entry = ref();
|
|||
const entryBuys = ref([]);
|
||||
const entryUrl = ref();
|
||||
|
||||
onMounted(async () => {
|
||||
entryUrl.value = (await getUrl('entry/')) + entityId.value;
|
||||
});
|
||||
|
||||
const tableColumnComponents = {
|
||||
quantity: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
},
|
||||
stickers: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
packagingFk: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
weight: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
packing: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
grouping: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
buyingValue: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
amount: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
pvp: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
};
|
||||
|
||||
const entriesTableColumns = computed(() => {
|
||||
return [
|
||||
{
|
||||
label: t('globals.quantity'),
|
||||
field: 'quantity',
|
||||
name: 'quantity',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
label: t('entry.summary.stickers'),
|
||||
field: 'stickers',
|
||||
name: 'stickers',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
label: t('entry.summary.package'),
|
||||
field: 'packagingFk',
|
||||
name: 'packagingFk',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
label: t('globals.weight'),
|
||||
field: 'weight',
|
||||
name: 'weight',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
label: t('entry.summary.packing'),
|
||||
field: 'packing',
|
||||
name: 'packing',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
label: t('entry.summary.grouping'),
|
||||
field: 'grouping',
|
||||
name: 'grouping',
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
label: t('entry.summary.buyingValue'),
|
||||
field: 'buyingValue',
|
||||
name: 'buyingValue',
|
||||
align: 'left',
|
||||
format: (value) => toCurrency(value),
|
||||
},
|
||||
{
|
||||
label: t('entry.summary.import'),
|
||||
name: 'amount',
|
||||
align: 'left',
|
||||
format: (_, row) => toCurrency(row.buyingValue * row.quantity),
|
||||
},
|
||||
{
|
||||
label: t('entry.summary.pvp'),
|
||||
name: 'pvp',
|
||||
align: 'left',
|
||||
format: (_, row) => toCurrency(row.price2) + ' / ' + toCurrency(row.price3),
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
async function setEntryData(data) {
|
||||
if (data) entry.value = data;
|
||||
await fetchEntryBuys();
|
||||
|
@ -150,8 +39,11 @@ const fetchEntryBuys = async () => {
|
|||
const { data } = await axios.get(`Entries/${entry.value.id}/getBuys`);
|
||||
if (data) entryBuys.value = data;
|
||||
};
|
||||
</script>
|
||||
|
||||
onMounted(async () => {
|
||||
entryUrl.value = (await getUrl('entry/')) + entityId.value;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<CardSummary
|
||||
ref="summaryRef"
|
||||
|
@ -168,34 +60,64 @@ const fetchEntryBuys = async () => {
|
|||
/>
|
||||
</template>
|
||||
<template #header>
|
||||
<span>{{ entry.id }} - {{ entry.supplier.nickname }}</span>
|
||||
<span>{{ entry.id }} - {{ entry?.supplier?.nickname }}</span>
|
||||
</template>
|
||||
<template #body>
|
||||
<QCard class="vn-one">
|
||||
<router-link
|
||||
:to="{ name: 'EntryBasicData', params: { id: entityId } }"
|
||||
class="header header-link"
|
||||
>
|
||||
{{ t('globals.summary.basicData') }}
|
||||
<QIcon name="open_in_new" />
|
||||
</router-link>
|
||||
<VnTitle
|
||||
:url="`#/entry/{{ entityId }}/basicData`"
|
||||
:text="t('globals.summary.basicData')"
|
||||
/>
|
||||
<div class="card-group">
|
||||
<div class="card-content">
|
||||
<VnLv
|
||||
:label="t('entry.summary.commission')"
|
||||
:value="entry.commission"
|
||||
:value="entry?.commission"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('entry.summary.currency')"
|
||||
:value="entry.currency?.name"
|
||||
:value="entry?.currency?.name"
|
||||
/>
|
||||
<VnLv :label="t('globals.company')" :value="entry.company.code" />
|
||||
<VnLv :label="t('globals.reference')" :value="entry.reference" />
|
||||
<VnLv
|
||||
:label="t('globals.company')"
|
||||
:value="entry?.company?.code"
|
||||
/>
|
||||
<VnLv :label="t('globals.reference')" :value="entry?.reference" />
|
||||
<VnLv
|
||||
:label="t('entry.summary.invoiceNumber')"
|
||||
:value="entry.invoiceNumber"
|
||||
:value="entry?.invoiceNumber"
|
||||
/>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<QCheckbox
|
||||
:label="t('entry.summary.ordered')"
|
||||
v-model="entry.isOrdered"
|
||||
:disable="true"
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('globals.confirmed')"
|
||||
v-model="entry.isConfirmed"
|
||||
:disable="true"
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('entry.summary.booked')"
|
||||
v-model="entry.isBooked"
|
||||
:disable="true"
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('entry.summary.excludedFromAvailable')"
|
||||
v-model="entry.isExcludedFromAvailable"
|
||||
:disable="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</QCard>
|
||||
<QCard class="vn-one" v-if="entry?.travelFk">
|
||||
<VnTitle
|
||||
:url="`#/travel/{{ entry.travel.id }}/summary`"
|
||||
:text="t('globals.summary.basicData')"
|
||||
/>
|
||||
<div class="card-group">
|
||||
<div class="card-content">
|
||||
<VnLv :label="t('entry.summary.travelReference')">
|
||||
<template #value>
|
||||
|
@ -210,18 +132,23 @@ const fetchEntryBuys = async () => {
|
|||
:value="entry.travel.agency?.name"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('shipped')"
|
||||
:label="t('entry.summary.travelShipped')"
|
||||
:value="toDate(entry.travel.shipped)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('globals.warehouseOut')"
|
||||
:value="entry.travel.warehouseOut?.name"
|
||||
/>
|
||||
<VnLv :label="t('landed')" :value="toDate(entry.travel.landed)" />
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelLanded')"
|
||||
:value="toDate(entry.travel.landed)"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('globals.warehouseIn')"
|
||||
:value="entry.travel.warehouseIn?.name"
|
||||
/>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<QCheckbox
|
||||
:label="t('entry.summary.travelDelivered')"
|
||||
v-model="entry.travel.isDelivered"
|
||||
|
@ -235,59 +162,35 @@ const fetchEntryBuys = async () => {
|
|||
</div>
|
||||
</div>
|
||||
</QCard>
|
||||
<QCard class="vn-one">
|
||||
<router-link
|
||||
:to="{ name: 'TravelSummary', params: { id: entry.travel.id } }"
|
||||
class="header header-link"
|
||||
>
|
||||
{{ t('Travel data') }}
|
||||
<QIcon name="open_in_new" />
|
||||
</router-link>
|
||||
<QCheckbox
|
||||
:label="t('entry.summary.ordered')"
|
||||
v-model="entry.isOrdered"
|
||||
:disable="true"
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('globals.confirmed')"
|
||||
v-model="entry.isConfirmed"
|
||||
:disable="true"
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('entry.summary.booked')"
|
||||
v-model="entry.isBooked"
|
||||
:disable="true"
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('entry.summary.excludedFromAvailable')"
|
||||
v-model="entry.isExcludedFromAvailable"
|
||||
:disable="true"
|
||||
<QCard class="vn-max">
|
||||
<VnTitle
|
||||
:url="`#/entry/{{ entityId }}/buys`"
|
||||
:text="t('entry.summary.buys')"
|
||||
/>
|
||||
<EntryBuys v-if="entityId" :id="entityId" :editable-mode="false" />
|
||||
</QCard>
|
||||
</template>
|
||||
</CardSummary>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.separation-row {
|
||||
background-color: var(--vn-section-color) !important;
|
||||
}
|
||||
.card-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
margin-bottom: 16px; /* Para dar espacio entre las secciones */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (min-width: 1010px) {
|
||||
.card-group {
|
||||
flex-direction: row; /* Coloca los contenidos en fila cuando el ancho es mayor a 600px */
|
||||
flex-direction: row;
|
||||
}
|
||||
.card-content {
|
||||
flex: 1; /* Haz que las secciones ocupen el mismo espacio */
|
||||
margin-right: 16px; /* Espaciado entre las dos primeras tarjetas */
|
||||
flex: 1;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -295,4 +198,5 @@ const fetchEntryBuys = async () => {
|
|||
<i18n>
|
||||
es:
|
||||
Travel data: Datos envío
|
||||
InvoiceIn data: Datos factura
|
||||
</i18n>
|
||||
|
|
|
@ -18,6 +18,7 @@ const props = defineProps({
|
|||
|
||||
const currenciesOptions = ref([]);
|
||||
const companiesOptions = ref([]);
|
||||
const entryFilterPanel = ref();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -37,7 +38,7 @@ const companiesOptions = ref([]);
|
|||
@on-fetch="(data) => (currenciesOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
||||
<VnFilterPanel ref="entryFilterPanel" :data-key="props.dataKey" :search-button="true">
|
||||
<template #tags="{ tag, formatFn }">
|
||||
<div class="q-gutter-x-xs">
|
||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
||||
|
@ -47,70 +48,82 @@ const companiesOptions = ref([]);
|
|||
<template #body="{ params, searchFn }">
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.search"
|
||||
:label="t('entryFilter.filter.search')"
|
||||
is-outlined
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('params.isExcludedFromAvailable')"
|
||||
v-model="params.isExcludedFromAvailable"
|
||||
toggle-indeterminate
|
||||
>
|
||||
<QTooltip>
|
||||
{{
|
||||
t(
|
||||
'entry.list.tableVisibleColumns.isExcludedFromAvailable'
|
||||
)
|
||||
}}
|
||||
</QTooltip>
|
||||
</QCheckbox>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
:label="t('params.isOrdered')"
|
||||
v-model="params.isOrdered"
|
||||
toggle-indeterminate
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('entry.list.tableVisibleColumns.isOrdered') }}
|
||||
</QTooltip>
|
||||
</QCheckbox>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.reference"
|
||||
:label="t('entryFilter.filter.reference')"
|
||||
is-outlined
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('params.isReceived')"
|
||||
v-model="params.isReceived"
|
||||
toggle-indeterminate
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('entry.list.tableVisibleColumns.isReceived') }}
|
||||
</QTooltip>
|
||||
</QCheckbox>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
:label="t('params.isRaid')"
|
||||
v-model="params.isRaid"
|
||||
toggle-indeterminate
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('entry.list.tableVisibleColumns.isRaid') }}
|
||||
</QTooltip>
|
||||
</QCheckbox>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.invoiceNumber"
|
||||
:label="t('params.invoiceNumber')"
|
||||
is-outlined
|
||||
/>
|
||||
<QCheckbox
|
||||
:label="t('entry.list.tableVisibleColumns.isConfirmed')"
|
||||
v-model="params.isConfirmed"
|
||||
toggle-indeterminate
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('entry.list.tableVisibleColumns.isConfirmed') }}
|
||||
</QTooltip>
|
||||
</QCheckbox>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.travelFk"
|
||||
:label="t('params.travelFk')"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('params.companyFk')"
|
||||
v-model="params.companyFk"
|
||||
<VnInputDate
|
||||
:label="t('params.landed')"
|
||||
v-model="params.landed"
|
||||
@update:model-value="searchFn()"
|
||||
:options="companiesOptions"
|
||||
option-value="id"
|
||||
option-label="code"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('params.currencyFk')"
|
||||
v-model="params.currencyFk"
|
||||
@update:model-value="searchFn()"
|
||||
:options="currenciesOptions"
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
<VnInput v-model="params.id" label="Id" is-outlined />
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
|
@ -143,56 +156,90 @@ const companiesOptions = ref([]);
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate
|
||||
:label="t('params.created')"
|
||||
v-model="params.created"
|
||||
@update:model-value="searchFn()"
|
||||
<VnInput
|
||||
v-model="params.invoiceNumber"
|
||||
:label="t('params.invoiceNumber')"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate
|
||||
:label="t('params.from')"
|
||||
v-model="params.from"
|
||||
@update:model-value="searchFn()"
|
||||
<VnInput
|
||||
v-model="params.reference"
|
||||
:label="t('entryFilter.filter.reference')"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate
|
||||
:label="t('params.to')"
|
||||
v-model="params.to"
|
||||
<VnSelect
|
||||
:label="t('params.agencyModeId')"
|
||||
v-model="params.agencyModeId"
|
||||
@update:model-value="searchFn()"
|
||||
url="AgencyModes"
|
||||
:fields="['id', 'name']"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
v-model="params.evaNotes"
|
||||
:label="t('params.evaNotes')"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
:label="t('params.isBooked')"
|
||||
v-model="params.isBooked"
|
||||
toggle-indeterminate
|
||||
/>
|
||||
</QItemSection>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
:label="t('params.isConfirmed')"
|
||||
v-model="params.isConfirmed"
|
||||
toggle-indeterminate
|
||||
<VnSelect
|
||||
:label="t('params.warehouseOutFk')"
|
||||
v-model="params.warehouseOutFk"
|
||||
@update:model-value="searchFn()"
|
||||
url="Warehouses"
|
||||
:fields="['id', 'name']"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
:label="t('params.isOrdered')"
|
||||
v-model="params.isOrdered"
|
||||
toggle-indeterminate
|
||||
<VnSelect
|
||||
:label="t('params.warehouseInFk')"
|
||||
v-model="params.warehouseInFk"
|
||||
@update:model-value="searchFn()"
|
||||
url="Warehouses"
|
||||
:fields="['id', 'name']"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
:label="t('params.entryTypeCode')"
|
||||
v-model="params.entryTypeCode"
|
||||
@update:model-value="searchFn()"
|
||||
url="EntryTypes"
|
||||
:fields="['code', 'description']"
|
||||
option-value="code"
|
||||
option-label="description"
|
||||
hide-selected
|
||||
dense
|
||||
outlined
|
||||
rounded
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
@ -203,30 +250,38 @@ const companiesOptions = ref([]);
|
|||
<i18n>
|
||||
en:
|
||||
params:
|
||||
|
||||
invoiceNumber: Invoice number
|
||||
travelFk: Travel
|
||||
companyFk: Company
|
||||
currencyFk: Currency
|
||||
supplierFk: Supplier
|
||||
from: From
|
||||
to: To
|
||||
created: Created
|
||||
isBooked: Booked
|
||||
isConfirmed: Confirmed
|
||||
isExcludedFromAvailable: Inventory
|
||||
isOrdered: Ordered
|
||||
isReceived: Received
|
||||
isConfirmed: Confirmed
|
||||
isRaid: Raid
|
||||
landed: Date
|
||||
id: Id
|
||||
supplierFk: Supplier
|
||||
invoiceNumber: Invoice number
|
||||
reference: Ref/Alb/Guide
|
||||
agencyModeId: Agency mode
|
||||
evaNotes: Notes
|
||||
warehouseOutFk: Origin
|
||||
warehouseInFk: Destiny
|
||||
entryTypeCode: Entry type
|
||||
hasToShowDeletedEntries: Show deleted entries
|
||||
es:
|
||||
params:
|
||||
|
||||
invoiceNumber: Núm. factura
|
||||
travelFk: Envío
|
||||
companyFk: Empresa
|
||||
currencyFk: Moneda
|
||||
supplierFk: Proveedor
|
||||
from: Desde
|
||||
to: Hasta
|
||||
created: Fecha creación
|
||||
isBooked: Asentado
|
||||
isConfirmed: Confirmado
|
||||
isExcludedFromAvailable: Inventario
|
||||
isOrdered: Pedida
|
||||
isConfirmed: Confirmado
|
||||
isReceived: Recibida
|
||||
isRaid: Raid
|
||||
landed: Fecha
|
||||
id: Id
|
||||
supplierFk: Proveedor
|
||||
invoiceNumber: Núm. factura
|
||||
reference: Ref/Alb/Guía
|
||||
agencyModeId: Modo agencia
|
||||
evaNotes: Notas
|
||||
warehouseOutFk: Origen
|
||||
warehouseInFk: Destino
|
||||
entryTypeCode: Tipo de entrada
|
||||
hasToShowDeletedEntries: Mostrar entradas eliminadas
|
||||
</i18n>
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
<script setup>
|
||||
import { onMounted, ref, computed } from 'vue';
|
||||
import axios from 'axios';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { onBeforeMount } from 'vue';
|
||||
|
||||
import EntryFilter from './EntryFilter.vue';
|
||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||
import { useStateStore } from 'stores/useStateStore';
|
||||
import VnTable from 'components/VnTable/VnTable.vue';
|
||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||
import { toDate } from 'src/filters';
|
||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||
import EntrySummary from './Card/EntrySummary.vue';
|
||||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
||||
|
||||
const stateStore = useStateStore();
|
||||
const { t } = useI18n();
|
||||
const tableRef = ref();
|
||||
const defaultEntry = ref({});
|
||||
const state = useState();
|
||||
const user = state.getUser();
|
||||
|
||||
const { viewSummary } = useSummaryDialog();
|
||||
const entryFilter = {
|
||||
const entryQueryFilter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'suppliers',
|
||||
|
@ -42,11 +43,50 @@ const entryFilter = {
|
|||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
name: 'status',
|
||||
columnFilter: false,
|
||||
align: 'center',
|
||||
label: 'Ex',
|
||||
toolTip: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
|
||||
name: 'isExcludedFromAvailable',
|
||||
component: 'checkbox',
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
align: 'center',
|
||||
label: 'Pe',
|
||||
toolTip: t('entry.list.tableVisibleColumns.isOrdered'),
|
||||
name: 'isOrdered',
|
||||
component: 'checkbox',
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Le',
|
||||
toolTip: t('entry.list.tableVisibleColumns.isConfirmed'),
|
||||
name: 'isConfirmed',
|
||||
component: 'checkbox',
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: 'Re',
|
||||
toolTip: t('entry.list.tableVisibleColumns.isReceived'),
|
||||
name: 'isReceived',
|
||||
component: 'checkbox',
|
||||
width: '35px',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('entry.list.tableVisibleColumns.landed'),
|
||||
name: 'landed',
|
||||
component: 'date',
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landed)),
|
||||
width: '105px',
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
label: t('globals.id'),
|
||||
name: 'id',
|
||||
isId: true,
|
||||
|
@ -54,30 +94,6 @@ const columns = computed(() => [
|
|||
condition: () => true,
|
||||
},
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('globals.reference'),
|
||||
name: 'reference',
|
||||
isTitle: true,
|
||||
component: 'input',
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
create: true,
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.created'),
|
||||
name: 'created',
|
||||
create: true,
|
||||
cardVisible: true,
|
||||
component: 'date',
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.created)),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.supplierFk'),
|
||||
|
@ -89,117 +105,168 @@ const columns = computed(() => [
|
|||
url: 'suppliers',
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(row.supplierName),
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('entry.list.tableVisibleColumns.isBooked'),
|
||||
name: 'isBooked',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
component: 'checkbox',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('entry.list.tableVisibleColumns.isConfirmed'),
|
||||
name: 'isConfirmed',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
component: 'checkbox',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('entry.list.tableVisibleColumns.isOrdered'),
|
||||
name: 'isOrdered',
|
||||
cardVisible: true,
|
||||
create: true,
|
||||
component: 'checkbox',
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.invoiceNumber'),
|
||||
name: 'invoiceNumber',
|
||||
component: 'input',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.companyFk'),
|
||||
name: 'companyFk',
|
||||
label: t('entry.list.tableVisibleColumns.reference'),
|
||||
name: 'reference',
|
||||
isTitle: true,
|
||||
component: 'input',
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
cardVisible: true,
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: 'AWB',
|
||||
name: 'awbCode',
|
||||
component: 'input',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.agencyModeId'),
|
||||
name: 'agencyModeId',
|
||||
cardVisible: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
url: 'companies',
|
||||
fields: ['id', 'code'],
|
||||
optionLabel: 'code',
|
||||
optionValue: 'id',
|
||||
url: 'agencyModes',
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
create: true,
|
||||
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(row.companyCode),
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(row.agencyModeName),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.travelFk'),
|
||||
name: 'travelFk',
|
||||
label: t('entry.list.tableVisibleColumns.evaNotes'),
|
||||
name: 'evaNotes',
|
||||
component: 'input',
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.warehouseOutFk'),
|
||||
name: 'warehouseOutFk',
|
||||
cardVisible: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
url: 'travels',
|
||||
fields: ['id', 'ref'],
|
||||
optionLabel: 'ref',
|
||||
optionValue: 'id',
|
||||
url: 'warehouses',
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
create: true,
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseOutName),
|
||||
},
|
||||
{
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.invoiceAmount'),
|
||||
name: 'invoiceAmount',
|
||||
label: t('entry.list.tableVisibleColumns.warehouseInFk'),
|
||||
name: 'warehouseInFk',
|
||||
cardVisible: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
url: 'warehouses',
|
||||
fields: ['id', 'name'],
|
||||
},
|
||||
columnField: {
|
||||
component: null,
|
||||
},
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseInName),
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('entry.list.tableVisibleColumns.isExcludedFromAvailable'),
|
||||
name: 'isExcludedFromAvailable',
|
||||
chip: {
|
||||
color: null,
|
||||
condition: (value) => value,
|
||||
icon: 'vn:inventory',
|
||||
},
|
||||
align: 'left',
|
||||
label: t('entry.list.tableVisibleColumns.entryTypeDescription'),
|
||||
name: 'entryTypeCode',
|
||||
cardVisible: true,
|
||||
columnFilter: {
|
||||
inWhere: true,
|
||||
},
|
||||
component: 'checkbox',
|
||||
},
|
||||
{
|
||||
align: 'center',
|
||||
label: t('entry.list.tableVisibleColumns.isRaid'),
|
||||
name: 'isRaid',
|
||||
chip: {
|
||||
color: null,
|
||||
condition: (value) => value,
|
||||
icon: 'vn:net',
|
||||
},
|
||||
columnFilter: {
|
||||
inWhere: true,
|
||||
},
|
||||
component: 'checkbox',
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
name: 'tableActions',
|
||||
actions: [
|
||||
{
|
||||
title: t('components.smartCard.viewSummary'),
|
||||
icon: 'preview',
|
||||
action: (row) => viewSummary(row.id, EntrySummary),
|
||||
isPrimary: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
optionValue: 'code',
|
||||
optionLabel: 'description',
|
||||
url: 'entryTypes',
|
||||
fields: ['code', 'description'],
|
||||
},
|
||||
],
|
||||
},
|
||||
format: (row, dashIfEmpty) => dashIfEmpty(row.entryTypeDescription),
|
||||
},
|
||||
{
|
||||
name: 'dated',
|
||||
label: t('entry.list.tableVisibleColumns.dated'),
|
||||
component: 'date',
|
||||
cardVisible: false,
|
||||
visible: false,
|
||||
create: true,
|
||||
},
|
||||
{
|
||||
name: 'companyFk',
|
||||
label: t('entry.list.tableVisibleColumns.companyFk'),
|
||||
cardVisible: false,
|
||||
visible: false,
|
||||
create: true,
|
||||
component: 'select',
|
||||
attrs: {
|
||||
optionValue: 'id',
|
||||
optionLabel: 'code',
|
||||
url: 'Companies',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'travelFk',
|
||||
label: t('entry.list.tableVisibleColumns.travelFk'),
|
||||
cardVisible: false,
|
||||
visible: false,
|
||||
create: true,
|
||||
},
|
||||
]);
|
||||
function getBadgeAttrs(row) {
|
||||
const date = row.landed;
|
||||
let today = Date.vnNew();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
let timeTicket = new Date(date);
|
||||
timeTicket.setHours(0, 0, 0, 0);
|
||||
|
||||
let timeDiff = today - timeTicket;
|
||||
|
||||
if (timeDiff > 0) return { color: 'warning', 'text-color': 'black' };
|
||||
switch (row.entryTypeCode) {
|
||||
case 'regularization':
|
||||
case 'life':
|
||||
case 'internal':
|
||||
case 'inventory':
|
||||
if (!row.isOrdered || !row.isConfirmed)
|
||||
return { color: 'negative', 'text-color': 'black' };
|
||||
break;
|
||||
case 'product':
|
||||
case 'packaging':
|
||||
case 'devaluation':
|
||||
case 'payment':
|
||||
case 'transport':
|
||||
if (
|
||||
row.invoiceAmount === null ||
|
||||
(row.invoiceNumber === null && row.reference === null) ||
|
||||
!row.isOrdered ||
|
||||
!row.isConfirmed
|
||||
)
|
||||
return { color: 'negative', 'text-color': 'black' };
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (timeDiff < 0) return { color: 'info', 'text-color': 'black' };
|
||||
return { color: 'transparent' };
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
defaultEntry.value = (await axios.get('EntryConfigs/findOne')).data;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<VnSearchbar
|
||||
|
@ -214,40 +281,35 @@ const columns = computed(() => [
|
|||
</template>
|
||||
</RightMenu>
|
||||
<VnTable
|
||||
v-if="defaultEntry.defaultSupplierFk"
|
||||
ref="tableRef"
|
||||
data-key="EntryList"
|
||||
url="Entries/filter"
|
||||
:filter="entryFilter"
|
||||
:filter="entryQueryFilter"
|
||||
:create="{
|
||||
urlCreate: 'Entries',
|
||||
title: t('Create entry'),
|
||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||
formInitialData: {},
|
||||
formInitialData: {
|
||||
supplierFk: defaultEntry.defaultSupplierFk,
|
||||
dated: Date.vnNew(),
|
||||
companyFk: user?.companyFk,
|
||||
},
|
||||
}"
|
||||
order="id DESC"
|
||||
:columns="columns"
|
||||
redirect="entry"
|
||||
:right-search="false"
|
||||
>
|
||||
<template #column-status="{ row }">
|
||||
<div class="row q-gutter-xs">
|
||||
<QIcon
|
||||
v-if="!!row.isExcludedFromAvailable"
|
||||
name="vn:inventory"
|
||||
color="primary"
|
||||
>
|
||||
<QTooltip>{{
|
||||
t('entry.list.tableVisibleColumns.isExcludedFromAvailable')
|
||||
}}</QTooltip>
|
||||
</QIcon>
|
||||
<QIcon v-if="!!row.isRaid" name="vn:net" color="primary">
|
||||
<QTooltip>
|
||||
{{
|
||||
t('globals.raid', { daysInForward: row.daysInForward })
|
||||
}}</QTooltip
|
||||
>
|
||||
</QIcon>
|
||||
</div>
|
||||
<template #column-landed="{ row }">
|
||||
<QBadge
|
||||
v-if="row?.travelFk"
|
||||
v-bind="getBadgeAttrs(row)"
|
||||
class="q-pa-sm"
|
||||
style="font-size: 14px"
|
||||
>
|
||||
{{ toDate(row.landed) }}
|
||||
</QBadge>
|
||||
</template>
|
||||
<template #column-supplierFk="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
|
@ -255,12 +317,6 @@ const columns = computed(() => [
|
|||
<SupplierDescriptorProxy :id="row.supplierFk" />
|
||||
</span>
|
||||
</template>
|
||||
<template #column-travelFk="{ row }">
|
||||
<span class="link" @click.stop>
|
||||
{{ row.travelRef }}
|
||||
<TravelDescriptorProxy :id="row.travelFk" />
|
||||
</span>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@ const $props = defineProps({
|
|||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
proxyRender: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const { openCloneDialog } = cloneItem();
|
||||
|
@ -171,7 +175,7 @@ const openRegularizeStockForm = () => {
|
|||
</QCardActions>
|
||||
</template>
|
||||
<template #actions="{}">
|
||||
<QCardActions class="row justify-center">
|
||||
<QCardActions class="row justify-center" v-if="proxyRender">
|
||||
<QBtn
|
||||
:to="{
|
||||
name: 'ItemDiary',
|
||||
|
@ -184,6 +188,16 @@ const openRegularizeStockForm = () => {
|
|||
>
|
||||
<QTooltip>{{ t('item.descriptor.itemDiary') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
:to="{
|
||||
name: 'ItemLastEntries',
|
||||
}"
|
||||
size="md"
|
||||
icon="vn:regentry"
|
||||
color="primary"
|
||||
>
|
||||
<QTooltip>{{ t('item.descriptor.itemLastEntries') }}</QTooltip>
|
||||
</QBtn>
|
||||
</QCardActions>
|
||||
</template>
|
||||
</CardDescriptor>
|
||||
|
|
|
@ -4,7 +4,7 @@ import ItemSummary from './ItemSummary.vue';
|
|||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
type: [Number, String],
|
||||
required: true,
|
||||
},
|
||||
dated: {
|
||||
|
@ -30,6 +30,7 @@ const $props = defineProps({
|
|||
:dated="dated"
|
||||
:sale-fk="saleFk"
|
||||
:warehouse-fk="warehouseFk"
|
||||
:proxy-render="true"
|
||||
/>
|
||||
</QPopupProxy>
|
||||
</template>
|
||||
|
|
|
@ -117,6 +117,7 @@ item:
|
|||
available: Available
|
||||
warehouseText: 'Calculated on the warehouse of { warehouseName }'
|
||||
itemDiary: Item diary
|
||||
itemLastEntries: Last entries
|
||||
producer: Producer
|
||||
clone:
|
||||
title: All its properties will be copied
|
||||
|
|
|
@ -119,6 +119,7 @@ item:
|
|||
available: Disponible
|
||||
warehouseText: 'Calculado sobre el almacén de { warehouseName }'
|
||||
itemDiary: Registro de compra-venta
|
||||
itemLastEntries: Últimas entradas
|
||||
producer: Productor
|
||||
clone:
|
||||
title: Todas sus propiedades serán copiadas
|
||||
|
|
Loading…
Reference in New Issue