Merge branch 'dev' into 8825-bajaOpinionCredito
gitea/salix-front/pipeline/pr-dev There was a failure building this commit Details

This commit is contained in:
Pau Rovira 2025-05-16 03:46:36 +00:00
commit 2f8e8cf33a
8 changed files with 124 additions and 60 deletions

View File

@ -102,6 +102,10 @@ const $props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
customMethod: {
type: String,
default: null,
},
}); });
const emit = defineEmits(['onFetch', 'onDataSaved', 'submit']); const emit = defineEmits(['onFetch', 'onDataSaved', 'submit']);
const modelValue = computed( const modelValue = computed(
@ -237,7 +241,9 @@ async function save() {
const url = const url =
$props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url; $props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url;
const response = await Promise.resolve( const response = await Promise.resolve(
$props.saveFn ? $props.saveFn(body) : axios[method](url, body), $props.saveFn
? $props.saveFn(body)
: axios[$props.customMethod ?? method](url, body),
); );
if ($props.urlCreate) notify('globals.dataCreated', 'positive'); if ($props.urlCreate) notify('globals.dataCreated', 'positive');

View File

@ -896,6 +896,7 @@ components:
rate3: Packing price rate3: Packing price
minPrice: Min. Price minPrice: Min. Price
itemFk: Item id itemFk: Item id
dated: Date
userPanel: userPanel:
copyToken: Token copied to clipboard copyToken: Token copied to clipboard
settings: Settings settings: Settings

View File

@ -980,6 +980,7 @@ components:
rate3: Precio packing rate3: Precio packing
minPrice: Precio mínimo minPrice: Precio mínimo
itemFk: Id item itemFk: Id item
dated: Fecha
userPanel: userPanel:
copyToken: Token copiado al portapapeles copyToken: Token copiado al portapapeles
settings: Configuración settings: Configuración

View File

@ -1,9 +1,11 @@
<script setup> <script setup>
import { onMounted, ref, onUnmounted, computed, watch } from 'vue'; import { onMounted, ref, onUnmounted, computed, watch } from 'vue';
import axios from 'axios';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { useStateStore } from 'stores/useStateStore'; import { useStateStore } from 'stores/useStateStore';
import { useState } from 'src/composables/useState'; import { useState } from 'src/composables/useState';
import { beforeSave } from 'src/composables/updateMinPriceBeforeSave'; import { beforeSave } from 'src/composables/updateMinPriceBeforeSave';
import FetchedTags from 'components/ui/FetchedTags.vue'; import FetchedTags from 'components/ui/FetchedTags.vue';
@ -14,13 +16,13 @@ import RightMenu from 'src/components/common/RightMenu.vue';
import VnTable from 'src/components/VnTable/VnTable.vue'; import VnTable from 'src/components/VnTable/VnTable.vue';
import VnColor from 'src/components/common/VnColor.vue'; import VnColor from 'src/components/common/VnColor.vue';
import { toDate } from 'src/filters'; import { toDate, toCurrency } from 'src/filters';
import { isLower, isBigger } from 'src/filters/date.js'; import { isLower, isBigger } from 'src/filters/date.js';
import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue'; import ItemFixedPriceFilter from './ItemFixedPriceFilter.vue';
import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue'; import ItemDescriptorProxy from './Card/ItemDescriptorProxy.vue';
import { toCurrency } from 'src/filters';
const stateStore = useStateStore(); const stateStore = useStateStore();
const quasar = useQuasar();
const { t } = useI18n(); const { t } = useI18n();
const tableRef = ref(); const tableRef = ref();
const editFixedPriceForm = ref(null); const editFixedPriceForm = ref(null);
@ -218,11 +220,36 @@ const dateStyle = (date) =>
} }
: { color: dateColor, 'background-color': 'transparent' }; : { color: dateColor, 'background-color': 'transparent' };
const onDataSaved = () => { const onDataSaved = async (data) => {
tableRef.value.CrudModelRef.saveChanges(); for (const row of data) {
await axios.patch('FixedPrices/upsertFixedPrice', row);
}
selectedRows.value = []; selectedRows.value = [];
tableRef.value.reload();
tableRef.value.CrudModelRef.reset();
}; };
async function saveData(data, getChanges) {
const changes = getChanges();
if (changes?.updates?.length) {
for (const change of changes.updates) {
const row = data.find((row) => row.id === change.where.id);
await axios.patch('FixedPrices/upsertFixedPrice', row);
}
}
if (data?.deletes?.length) {
for (const deleteItem of data.deletes) {
await axios.delete(`FixedPrices/${deleteItem}`);
quasar.notify({
message: t('globals.dataDeleted'),
color: 'positive',
});
}
}
tableRef.value.reload();
}
onMounted(() => { onMounted(() => {
if (tableRef.value) { if (tableRef.value) {
tableRef.value.showForm = false; tableRef.value.showForm = false;
@ -273,7 +300,8 @@ watch(
data-key="ItemFixedPrices" data-key="ItemFixedPrices"
url="FixedPrices/filter" url="FixedPrices/filter"
:order="'name DESC'" :order="'name DESC'"
save-url="FixedPrices/crud" save-url="FixedPrices/upsertFixedPrice"
:saveFn="saveData"
:columns="columns" :columns="columns"
:is-editable="true" :is-editable="true"
:right-search="false" :right-search="false"
@ -283,7 +311,8 @@ watch(
}" }"
v-model:selected="selectedRows" v-model:selected="selectedRows"
:create="{ :create="{
urlCreate: 'FixedPrices', urlCreate: 'FixedPrices/upsertFixedPrice',
customMethod: 'patch',
title: t('Create fixed price'), title: t('Create fixed price'),
formInitialData: { warehouseFk: warehouse }, formInitialData: { warehouseFk: warehouse },
onDataSaved: () => tableRef.reload(), onDataSaved: () => tableRef.reload(),

View File

@ -3,6 +3,7 @@ import { useI18n } from 'vue-i18n';
import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnSelect from 'components/common/VnSelect.vue'; import VnSelect from 'components/common/VnSelect.vue';
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue'; import ItemsFilterPanel from 'src/components/ItemsFilterPanel.vue';
const { t } = useI18n(); const { t } = useI18n();
@ -51,42 +52,41 @@ const props = defineProps({
/> />
</QItemSection> </QItemSection>
</QItem> </QItem>
<QSeparator />
<QItemSection>
<QIcon name="info" size="sm" class="info-icon cursor-pointer">
<QTooltip>{{ t('params.incompatibleFilters') }}</QTooltip>
</QIcon>
<QItem>
<QItemSection>
<VnInputDate
v-model="params.dated"
:label="t('params.date')"
filled
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnCheckbox
v-model="params.showBadDates"
:label="t(`params.showBadDates`)"
toggle-indeterminate
@update:model-value="searchFn()"
/>
</QItemSection>
</QItem>
</QItemSection>
<QSeparator />
<QItem> <QItem>
<QItemSection> <QItemSection>
<VnInputDate <VnCheckbox
v-model="params.started"
:label="t('params.started')"
filled
@update:model-value="searchFn()"
/>
</QItemSection>
<QItemSection>
<VnInputDate
v-model="params.ended"
:label="t('params.ended')"
filled
@update:model-value="searchFn()"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<QCheckbox
:label="t('params.mine')" :label="t('params.mine')"
v-model="params.mine" v-model="params.mine"
toggle-indeterminate toggle-indeterminate
@update:model-value="searchFn()" @update:model-value="searchFn()"
/> />
<VnCheckbox
<QCheckbox
v-model="params.showBadDates"
:label="t(`params.showBadDates`)"
toggle-indeterminate
@update:model-value="searchFn()"
>
</QCheckbox>
<QCheckbox
:label="t('params.hasMinPrice')" :label="t('params.hasMinPrice')"
v-model="params.hasMinPrice" v-model="params.hasMinPrice"
toggle-indeterminate toggle-indeterminate
@ -97,6 +97,13 @@ const props = defineProps({
</template> </template>
</ItemsFilterPanel> </ItemsFilterPanel>
</template> </template>
<style lang="scss" scoped>
.info-icon {
position: relative;
top: 0;
left: 90%;
}
</style>
<i18n> <i18n>
en: en:
params: params:
@ -107,6 +114,8 @@ en:
mine: Mine mine: Mine
showBadDates: Show future items showBadDates: Show future items
hasMinPrice: Has Min Price hasMinPrice: Has Min Price
date: Date
incompatibleFilters: Cannot select "Date" and "Show future items" at the same time
es: es:
params: params:
buyerFk: Comprador buyerFk: Comprador
@ -116,4 +125,6 @@ es:
mine: Para mi mine: Para mi
showBadDates: Ver items a futuro showBadDates: Ver items a futuro
hasMinPrice: Precio mínimo hasMinPrice: Precio mínimo
date: Fecha
incompatibleFilters: No se puede seleccionar "Fecha" y "Ver items a futuro" a la vez
</i18n> </i18n>

View File

@ -26,7 +26,6 @@ const $props = defineProps({
default: () => {}, default: () => {},
}, },
}); });
const { t } = useI18n(); const { t } = useI18n();
const emit = defineEmits(['onDataSaved']); const emit = defineEmits(['onDataSaved']);
@ -38,7 +37,7 @@ const inputs = {
select: markRaw(VnSelect), select: markRaw(VnSelect),
}; };
const newValue = ref(null); const newFieldValue = ref(null);
const selectedField = ref(null); const selectedField = ref(null);
const closeButton = ref(null); const closeButton = ref(null);
const isLoading = ref(false); const isLoading = ref(false);
@ -46,7 +45,11 @@ const isLoading = ref(false);
const onSubmit = async () => { const onSubmit = async () => {
isLoading.value = true; isLoading.value = true;
$props.rows.forEach((row) => { $props.rows.forEach((row) => {
row[selectedField.value.name] = newValue.value; const newValue =
selectedField.value.component === 'number'
? parseInt(newFieldValue.value)
: newFieldValue.value;
row[selectedField.value.name] = newValue;
}); });
emit('onDataSaved', $props.rows); emit('onDataSaved', $props.rows);
closeForm(); closeForm();
@ -77,11 +80,19 @@ const closeForm = () => {
data-cy="EditFixedPriceSelectOption" data-cy="EditFixedPriceSelectOption"
@update:model-value="newValue = null" @update:model-value="newValue = null"
:class="{ 'is-select': selectedField?.component === 'select' }" :class="{ 'is-select': selectedField?.component === 'select' }"
/> >
<template #option="{ opt, itemProps }">
<QItem v-bind="itemProps" class="q-pa-xs row items-center">
<QItemSection class="col-9 justify-center">
<span>{{ opt?.label }}</span>
</QItemSection>
</QItem>
</template>
</VnSelect>
<component <component
:is="inputs[selectedField?.component || 'input']" :is="inputs[selectedField?.component || 'input']"
v-bind="selectedField?.attrs || {}" v-bind="selectedField?.attrs || {}"
v-model="newValue" v-model="newFieldValue"
:label="t('Value')" :label="t('Value')"
data-cy="EditFixedPriceValueOption" data-cy="EditFixedPriceValueOption"
style="width: 200px" style="width: 200px"

View File

@ -32,7 +32,17 @@ describe('Client fiscal data', () => {
cy.visit('#/customer/1107/fiscal-data'); cy.visit('#/customer/1107/fiscal-data');
}); });
it.skip('check as equalizated', () => { it('check as equalizated', () => {
cy.get('[data-cy="vnCheckboxInvoice by address"] > .q-checkbox__inner').then(
($el) => {
if (!$el.hasClass('q-checkbox__inner--truthy')) {
cy.wrap($el).click({ force: true });
}
},
);
cy.get(
'[data-cy="vnCheckboxInvoice by address"] > .q-checkbox__inner',
).should('have.class', 'q-checkbox__inner--truthy');
cy.dataCy('vnCheckboxIs equalizated').click(); cy.dataCy('vnCheckboxIs equalizated').click();
cy.get('.q-btn-group > .q-btn--standard > .q-btn__content').click(); cy.get('.q-btn-group > .q-btn--standard > .q-btn__content').click();
@ -40,7 +50,6 @@ describe('Client fiscal data', () => {
'contain', 'contain',
'You changed the equalization tax', 'You changed the equalization tax',
); );
cy.get('.q-card > :nth-child(2) > span').should( cy.get('.q-card > :nth-child(2) > span').should(
'have.text', 'have.text',
'Do you want to spread the change?', 'Do you want to spread the change?',

View File

@ -40,7 +40,7 @@ describe('ZoneCalendar', { testIsolation: true }, () => {
it('should exclude an event', () => { it('should exclude an event', () => {
cy.get('.q-mb-sm > .q-radio__inner').click(); cy.get('.q-mb-sm > .q-radio__inner').click();
cy.get('.q-current-day > .q-calendar-month__day--label__wrapper').click(); cy.get('.q-current-day > .q-calendar-month__day--label__wrapper').click();
cy.get('.q-mt-lg > .q-btn--standard').click(); cy.get(submitBtn).click();
cy.get( cy.get(
'.q-current-day > .q-calendar-month__day--content > [data-cy="ZoneCalendarDay"]', '.q-current-day > .q-calendar-month__day--content > [data-cy="ZoneCalendarDay"]',
).click(); ).click();
@ -48,19 +48,15 @@ describe('ZoneCalendar', { testIsolation: true }, () => {
cy.dataCy('VnConfirm_confirm').click(); cy.dataCy('VnConfirm_confirm').click();
}); });
it( it('should not exclude an event if there are tickets for that zone and day', () => {
'should not exclude an event if there are tickets for that zone and day', cy.get('[data-cy="vn-searchbar_input"]').type('3{enter}');
{ testIsoaltion: true }, cy.get('[aria-label="Exclude"] > .q-radio__label').click();
() => { cy.get(
cy.visit(`/#/zone/3/events`); '.q-current-day > .q-calendar-month__day--content > [data-cy="ZoneCalendarDay"]',
cy.get('.q-mb-sm > .q-radio__inner').click(); ).click();
cy.get( cy.get(submitBtn).click();
'.q-current-day > .q-calendar-month__day--content > [data-cy="ZoneCalendarDay"]', cy.checkNotification(
).click(); 'Can not close this zone because there are tickets programmed for that day',
cy.get('.q-mt-lg > .q-btn--standard').click(); );
cy.checkNotification( });
'Can not close this zone because there are tickets programmed for that day',
);
},
);
}); });