Item Fixed prices #307
|
@ -1,9 +1,12 @@
|
|||
<script setup>
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ref, markRaw } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import { QCheckbox } from 'quasar';
|
||||
|
||||
import axios from 'axios';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
|
@ -28,11 +31,16 @@ const $props = defineProps({
|
|||
const { t } = useI18n();
|
||||
const { notify } = useNotify();
|
||||
|
||||
const formData = reactive({
|
||||
field: null,
|
||||
newValue: null,
|
||||
});
|
||||
const inputs = {
|
||||
input: markRaw(VnInput),
|
||||
number: markRaw(VnInput),
|
||||
date: markRaw(VnInputDate),
|
||||
checkbox: markRaw(QCheckbox),
|
||||
select: markRaw(VnSelectFilter),
|
||||
};
|
||||
|
||||
const newValue = ref(null);
|
||||
const selectedField = ref(null);
|
||||
const closeButton = ref(null);
|
||||
const isLoading = ref(false);
|
||||
|
||||
|
@ -47,8 +55,8 @@ const submitData = async () => {
|
|||
isLoading.value = true;
|
||||
const rowsToEdit = $props.rows.map((row) => ({ id: row.id, itemFk: row.itemFk }));
|
||||
const payload = {
|
||||
field: formData.field,
|
||||
newValue: formData.newValue,
|
||||
field: selectedField.value.field,
|
||||
newValue: newValue.value,
|
||||
lines: rowsToEdit,
|
||||
};
|
||||
|
||||
|
@ -75,19 +83,20 @@ const closeForm = () => {
|
|||
<span class="countLines">{{ ` ${rows.length} ` }}</span>
|
||||
<span class="title">{{ t('buy(s)') }}</span>
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Field to edit')"
|
||||
:options="fieldsOptions"
|
||||
hide-selected
|
||||
option-label="label"
|
||||
option-value="field"
|
||||
v-model="formData.field"
|
||||
v-model="selectedField"
|
||||
/>
|
||||
<component
|
||||
:is="inputs[selectedField?.component || 'input']"
|
||||
v-bind="selectedField?.attrs || {}"
|
||||
v-model="newValue"
|
||||
:label="t('Value')"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInput :label="t('Value')" v-model="formData.newValue" />
|
||||
</div>
|
||||
</VnRow>
|
||||
<div class="q-mt-lg row justify-end">
|
||||
<QBtn
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { onMounted, ref, computed, reactive, onUnmounted } from 'vue';
|
||||
import { onMounted, ref, computed, onUnmounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
|
@ -220,16 +220,63 @@ const columns = computed(() => [
|
|||
// },
|
||||
// },
|
||||
},
|
||||
{ name: 'deleteAction', align: 'center' },
|
||||
]);
|
||||
|
||||
const editTableFieldsOptions = [
|
||||
{ field: 'rate2', label: t('item.fixedPrice.groupingPrice') },
|
||||
{ field: 'rate3', label: t('item.fixedPrice.packingPrice') },
|
||||
{ field: 'hasMinPrice', label: t('item.fixedPrice.hasMinPrice') },
|
||||
{ field: 'minPrice', label: t('item.fixedPrice.minPrice') },
|
||||
{ field: 'started', label: t('item.fixedPrice.started') },
|
||||
{ field: 'ended', label: t('item.fixedPrice.ended') },
|
||||
{ field: 'warehouseFk', label: t('item.fixedPrice.warehouse') },
|
||||
{
|
||||
field: 'rate2',
|
||||
label: t('item.fixedPrice.groupingPrice'),
|
||||
component: 'input',
|
||||
attrs: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'rate3',
|
||||
label: t('item.fixedPrice.packingPrice'),
|
||||
component: 'input',
|
||||
attrs: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'minPrice',
|
||||
label: t('item.fixedPrice.minPrice'),
|
||||
component: 'input',
|
||||
attrs: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'hasMinPrice',
|
||||
label: t('item.fixedPrice.hasMinPrice'),
|
||||
component: 'checkbox',
|
||||
attrs: {
|
||||
'false-value': 0,
|
||||
'true-value': 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'started',
|
||||
label: t('item.fixedPrice.started'),
|
||||
component: 'date',
|
||||
},
|
||||
{
|
||||
field: 'ended',
|
||||
label: t('item.fixedPrice.ended'),
|
||||
component: 'date',
|
||||
},
|
||||
{
|
||||
field: 'warehouseFk',
|
||||
label: t('item.fixedPrice.warehouse'),
|
||||
component: 'select',
|
||||
attrs: {
|
||||
options: [],
|
||||
'option-label': 'name',
|
||||
'option-value': 'id',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const onFixedPricesFetched = (data) => {
|
||||
|
@ -255,17 +302,25 @@ const getRowUpdateInputEvents = (props, resetMinPrice, inputType = 'text') => {
|
|||
// };
|
||||
// };
|
||||
|
||||
const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice) => {
|
||||
// Si la row no tiene id significa que fue agregada con addRow y no se ha guardado en la base de datos
|
||||
const validations = (row, rowIndex, col) => {
|
||||
const isNew = !row.id;
|
||||
// Si la row no tiene id significa que fue agregada con addRow y no se ha guardado en la base de datos
|
||||
// Si isNew es falso no se checkea si el valor es igual a la original
|
||||
if (!isNew)
|
||||
if (fixedPricesOriginalData.value[rowIndex][col.field] == row[col.field]) return;
|
||||
if (fixedPricesOriginalData.value[rowIndex][col.field] == row[col.field])
|
||||
return false;
|
||||
|
||||
const requiredFields = ['itemFk', 'started', 'ended', 'rate2', 'rate3'];
|
||||
return requiredFields.every(
|
||||
(field) => row[field] !== null && row[field] !== undefined
|
||||
);
|
||||
};
|
||||
|
||||
const upsertPrice = async ({ row, col, rowIndex }, resetMinPrice = false) => {
|
||||
if (!validations(row, rowIndex, col)) return;
|
||||
jsegarra marked this conversation as resolved
|
||||
|
||||
try {
|
||||
if (resetMinPrice) row.hasMinPrice = 0;
|
||||
const requiredFields = ['itemFk', 'started', 'ended', 'rate2', 'rate3'];
|
||||
for (const field of requiredFields) if (!row[field]) return;
|
||||
|
||||
const { data } = await axios.patch('FixedPrices/upsertFixedPrice', row);
|
||||
row = data;
|
||||
|
@ -296,8 +351,9 @@ const addRow = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
const lastIndex = fixedPrices.value.length - 1;
|
||||
const lastItemCopy = JSON.parse(JSON.stringify(fixedPrices.value[lastIndex]));
|
||||
const lastItemCopy = JSON.parse(
|
||||
JSON.stringify(fixedPrices.value[fixedPrices.value.length - 1])
|
||||
);
|
||||
const { id, ...restOfData } = lastItemCopy;
|
||||
fixedPricesOriginalData.value.push(restOfData);
|
||||
fixedPrices.value.push(restOfData);
|
||||
|
@ -312,6 +368,37 @@ const onEditCellDataSaved = async () => {
|
|||
await fixedPricesFetchRef.value.fetch();
|
||||
};
|
||||
|
||||
const onWarehousesFetched = (data) => {
|
||||
warehousesOptions.value = data;
|
||||
// Actualiza las 'options' del elemento con field 'warehouseFk' en 'editTableFieldsOptions'.
|
||||
const warehouseField = editTableFieldsOptions.find(
|
||||
(field) => field.field === 'warehouseFk'
|
||||
);
|
||||
warehouseField.attrs.options = data;
|
||||
};
|
||||
|
||||
const removePrice = async (id, rowIndex) => {
|
||||
try {
|
||||
await axios.delete(`FixedPrices/${id}`);
|
||||
fixedPrices.value.splice(rowIndex, 1);
|
||||
fixedPricesOriginalData.value.splice(rowIndex, 1);
|
||||
notify(t('globals.dataSaved'), 'positive');
|
||||
} catch (err) {
|
||||
console.error('Error removing price', err);
|
||||
}
|
||||
};
|
||||
jsegarra marked this conversation as resolved
Outdated
jsegarra
commented
Is bigger e is lower es lo mismo menos la comparación Is bigger e is lower es lo mismo menos la comparación
Código duplicado
wbuezas
commented
Si, lo había copiado exactamente igual que como estaba en salix, pero bueno le hice un refactor. Commit: Si, lo había copiado exactamente igual que como estaba en salix, pero bueno le hice un refactor.
Commit: https://gitea.verdnatura.es/verdnatura/salix-front/commit/2105d7870b0f5bb0d9d30511bee9ad59dc6819bc
|
||||
|
||||
const updateMinPrice = async (value, props) => {
|
||||
// El checkbox hasMinPrice se encuentra en la misma columna que el input hasMinPrice
|
||||
// Por lo tanto le mandamos otro objeto con las mismas propiedades pero con el campo 'field' cambiado
|
||||
props.row.hasMinPrice = value;
|
||||
await upsertPrice({
|
||||
row: props.row,
|
||||
col: { field: 'hasMinPrice' },
|
||||
rowIndex: props.rowIndex,
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
stateStore.rightDrawer = true;
|
||||
});
|
||||
|
@ -332,7 +419,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
|||
url="Warehouses"
|
||||
:filter="{ order: ['name'] }"
|
||||
auto-load
|
||||
@on-fetch="(data) => (warehousesOptions = data)"
|
||||
@on-fetch="(data) => onWarehousesFetched(data)"
|
||||
/>
|
||||
<FetchData
|
||||
url="Items/withName"
|
||||
|
@ -422,10 +509,11 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
|||
<div class="row">
|
||||
<QCheckbox
|
||||
class="col"
|
||||
v-model="props.row.hasMinPrice"
|
||||
:model-value="props.row.hasMinPrice"
|
||||
@update:model-value="updateMinPrice($event, props)"
|
||||
:false-value="0"
|
||||
:true-value="1"
|
||||
v-on="getRowUpdateInputEvents(props)"
|
||||
:toggle-indeterminate="false"
|
||||
/>
|
||||
<VnInput
|
||||
class="col"
|
||||
|
@ -465,6 +553,27 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
|||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-deleteAction="{ row, rowIndex }">
|
||||
<QTd class="col">
|
||||
<QIcon
|
||||
name="delete"
|
||||
size="sm"
|
||||
class="cursor-pointer fill-icon-on-hover"
|
||||
color="primary"
|
||||
@click.stop="
|
||||
openConfirmationModal(
|
||||
t('This row will be removed'),
|
||||
t('Do you want to clone this item?'),
|
||||
() => removePrice(row.id, rowIndex)
|
||||
)
|
||||
"
|
||||
>
|
||||
<QTooltip class="text-no-wrap">
|
||||
{{ t('Delete') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #bottom-row>
|
||||
<QTd align="center">
|
||||
<QIcon
|
||||
|
@ -502,4 +611,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
|
|||
es:
|
||||
Add fixed price: Añadir precio fijado
|
||||
Edit fixed price(s): Editar precio(s) fijado(s)
|
||||
This row will be removed: Esta linea se eliminará
|
||||
Are you sure you want to continue?: ¿Seguro que quieres continuar?
|
||||
Delete: Eliminar
|
||||
</i18n>
|
||||
|
|
Loading…
Reference in New Issue
Mismo objeto
Cambiado
Commit:
dce48b536d