forked from verdnatura/salix-front
feat: refs #6897 add success messages for entry lock and improve data attributes for better testing
This commit is contained in:
parent
e121cc5d5c
commit
b37923e194
|
@ -181,6 +181,7 @@ const selectTravel = ({ id }) => {
|
|||
color="primary"
|
||||
:disabled="isLoading"
|
||||
:loading="isLoading"
|
||||
data-cy="save-filter-travel-form"
|
||||
/>
|
||||
</div>
|
||||
<QTable
|
||||
|
@ -191,9 +192,10 @@ const selectTravel = ({ id }) => {
|
|||
:no-data-label="t('Enter a new search')"
|
||||
class="q-mt-lg"
|
||||
@row-click="(_, row) => selectTravel(row)"
|
||||
data-cy="table-filter-travel-form"
|
||||
>
|
||||
<template #body-cell-id="{ row }">
|
||||
<QTd auto-width @click.stop>
|
||||
<QTd auto-width @click.stop data-cy="travelFk-travel-form">
|
||||
<QBtn flat color="blue">{{ row.id }}</QBtn>
|
||||
<TravelDescriptorProxy :id="row.id" />
|
||||
</QTd>
|
||||
|
|
|
@ -26,6 +26,7 @@ const itemComputed = computed(() => {
|
|||
:to="{ name: itemComputed.name }"
|
||||
clickable
|
||||
v-ripple
|
||||
:data-cy="`${itemComputed.name}-menu-item`"
|
||||
>
|
||||
<QItemSection avatar v-if="itemComputed.icon">
|
||||
<QIcon :name="itemComputed.icon" />
|
||||
|
|
|
@ -28,7 +28,6 @@ const hover = ref();
|
|||
const arrayData = useArrayData($props.dataKey, { searchUrl: $props.searchUrl });
|
||||
|
||||
async function orderBy(name, direction) {
|
||||
console.log('orderBy');
|
||||
if (!name) return;
|
||||
switch (direction) {
|
||||
case 'DESC':
|
||||
|
@ -41,11 +40,8 @@ async function orderBy(name, direction) {
|
|||
direction = 'DESC';
|
||||
break;
|
||||
}
|
||||
console.log('name: ', name);
|
||||
if (!direction) return await arrayData.deleteOrder(name);
|
||||
|
||||
console.log('direction: ', direction);
|
||||
console.log('name: ', name);
|
||||
await arrayData.addOrder(name, direction);
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,9 @@ const $props = defineProps({
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
createComplement: {
|
||||
type: Object,
|
||||
},
|
||||
});
|
||||
const { t } = useI18n();
|
||||
const stateStore = useStateStore();
|
||||
|
@ -920,7 +923,7 @@ const checkbox = ref(null);
|
|||
v-model="showForm"
|
||||
transition-show="scale"
|
||||
transition-hide="scale"
|
||||
:full-width="create?.isFullWidth ?? false"
|
||||
:full-width="createComplement?.isFullWidth ?? false"
|
||||
@before-hide="
|
||||
() => {
|
||||
if (createRef.isSaveAndContinue) {
|
||||
|
@ -929,6 +932,7 @@ const checkbox = ref(null);
|
|||
}
|
||||
}
|
||||
"
|
||||
data-cy="vn-table-create-dialog"
|
||||
>
|
||||
<FormModelPopup
|
||||
ref="createRef"
|
||||
|
@ -937,11 +941,11 @@ const checkbox = ref(null);
|
|||
@on-data-saved="(_, res) => createForm.onDataSaved(res)"
|
||||
>
|
||||
<template #form-inputs="{ data }">
|
||||
<div :class="create?.containerClass">
|
||||
<div :style="createComplement?.containerStyle">
|
||||
<div>
|
||||
<slot name="previous-create-dialog" :data="data" />
|
||||
</div>
|
||||
<div class="grid-create" :style="create?.columnGridStyle">
|
||||
<div class="grid-create" :style="createComplement?.columnGridStyle">
|
||||
<slot
|
||||
v-for="column of splittedColumns.create"
|
||||
:key="column.name"
|
||||
|
@ -957,6 +961,7 @@ const checkbox = ref(null);
|
|||
v-model="data[column.name]"
|
||||
:show-label="true"
|
||||
component-prop="columnCreate"
|
||||
:data-cy="`${column.name}-create-popup`"
|
||||
/>
|
||||
</slot>
|
||||
<slot name="more-create-dialog" :data="data" />
|
||||
|
@ -1042,11 +1047,7 @@ es:
|
|||
grid-gap: 20px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px; /* Espacio entre los divs */
|
||||
}
|
||||
|
||||
.flex-one {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
|
|
|
@ -28,6 +28,7 @@ const $props = defineProps({
|
|||
hide-selected
|
||||
:required="true"
|
||||
action-icon="filter_alt"
|
||||
:roles-allowed-to-create="['buyer']"
|
||||
>
|
||||
<template #form>
|
||||
<FilterTravelForm @travel-selected="onFilterTravelSelected(data, $event)" />
|
||||
|
|
|
@ -73,7 +73,7 @@ onBeforeMount(async () => {
|
|||
() => [$props.url, $props.filter],
|
||||
async () => {
|
||||
if (!isSameDataKey.value) await getData();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -108,7 +108,7 @@ const iconModule = computed(() => route.matched[1].meta.icon);
|
|||
const toModule = computed(() =>
|
||||
route.matched[1].path.split('/').length > 2
|
||||
? route.matched[1].redirect
|
||||
: route.matched[1].children[0].redirect
|
||||
: route.matched[1].children[0].redirect,
|
||||
);
|
||||
</script>
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ function cancel() {
|
|||
@click="cancel()"
|
||||
/>
|
||||
</QCardSection>
|
||||
<QCardSection class="q-pb-none">
|
||||
<QCardSection class="q-pb-none" data-cy="VnConfirm_message">
|
||||
<span v-if="message !== false" v-html="message" />
|
||||
</QCardSection>
|
||||
<QCardSection class="row items-center q-pt-none">
|
||||
|
@ -95,6 +95,7 @@ function cancel() {
|
|||
:disable="isLoading"
|
||||
flat
|
||||
@click="cancel()"
|
||||
data-cy="VnConfirm_cancel"
|
||||
/>
|
||||
<QBtn
|
||||
:label="t('globals.confirm')"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<QTooltip>
|
||||
{{ $t('components.cardDescriptor.moreOptions') }}
|
||||
</QTooltip>
|
||||
<QMenu ref="menuRef">
|
||||
<QMenu ref="menuRef" data-cy="descriptor-more-opts-menu">
|
||||
<QList>
|
||||
<slot name="menu" :menu-ref="$refs.menuRef" />
|
||||
</QList>
|
||||
|
|
|
@ -19,15 +19,17 @@ export async function checkEntryLock(entryFk, userFk) {
|
|||
const entryConfig = await axios.get('EntryConfigs/findOne');
|
||||
|
||||
if (data?.lockerUserFk && data?.locked) {
|
||||
const now = new Date().getTime();
|
||||
const now = new Date(Date.vnNow()).getTime();
|
||||
const lockedTime = new Date(data.locked).getTime();
|
||||
const timeDiff = (now - lockedTime) / 1000;
|
||||
const isMaxTimeLockExceeded = entryConfig.data.maxLockTime > timeDiff;
|
||||
|
||||
if (data?.lockerUserFk !== userFk && isMaxTimeLockExceeded) {
|
||||
quasar
|
||||
.dialog({
|
||||
component: VnConfirm,
|
||||
componentProps: {
|
||||
'data-cy': 'entry-lock-confirm',
|
||||
title: t('entry.lock.title'),
|
||||
message: t('entry.lock.message', {
|
||||
userName: data?.user?.nickname,
|
||||
|
@ -56,7 +58,7 @@ export async function checkEntryLock(entryFk, userFk) {
|
|||
quasar.notify({
|
||||
message: t('entry.lock.success'),
|
||||
color: 'positive',
|
||||
position: 'top',
|
||||
group: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -93,8 +93,7 @@ onMounted(() => {
|
|||
<VnInputNumber
|
||||
:label="t('entry.summary.commission')"
|
||||
v-model="data.commission"
|
||||
step="1"
|
||||
autofocus
|
||||
:step="1"
|
||||
:positive="false"
|
||||
/>
|
||||
<VnSelect
|
||||
|
|
|
@ -214,7 +214,6 @@ const columns = [
|
|||
{
|
||||
align: 'center',
|
||||
labelAbbreviation: 'GM',
|
||||
label: t('Grouping selector'),
|
||||
toolTip: t('Grouping selector'),
|
||||
name: 'groupingMode',
|
||||
component: 'toggle',
|
||||
|
@ -471,7 +470,8 @@ async function beforeSave(data, getChanges) {
|
|||
|
||||
function invertQuantitySign(rows, sign) {
|
||||
for (const row of rows) {
|
||||
row.quantity = row.quantity * sign;
|
||||
if (sign > 0) row.quantity = Math.abs(row.quantity);
|
||||
else if (row.quantity > 0) row.quantity = -row.quantity;
|
||||
}
|
||||
}
|
||||
function setIsChecked(rows, value) {
|
||||
|
@ -517,18 +517,27 @@ onMounted(() => {
|
|||
flat
|
||||
:title="t('Invert quantity value')"
|
||||
:disable="!selectedRows.length"
|
||||
data-cy="change-quantity-sign"
|
||||
>
|
||||
<QList>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QBtn flat @click="invertQuantitySign(selectedRows, -1)">
|
||||
<QBtn
|
||||
flat
|
||||
@click="invertQuantitySign(selectedRows, -1)"
|
||||
data-cy="set-negative-quantity"
|
||||
>
|
||||
<span style="font-size: medium">-1</span>
|
||||
</QBtn>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QBtn flat @click="invertQuantitySign(selectedRows, 1)">
|
||||
<QBtn
|
||||
flat
|
||||
@click="invertQuantitySign(selectedRows, 1)"
|
||||
data-cy="set-positive-quantity"
|
||||
>
|
||||
<span style="font-size: medium">1</span>
|
||||
</QBtn>
|
||||
</QItemSection>
|
||||
|
@ -541,6 +550,7 @@ onMounted(() => {
|
|||
flat
|
||||
:title="t('Check buy amount')"
|
||||
:disable="!selectedRows.length"
|
||||
data-cy="check-buy-amount"
|
||||
>
|
||||
<QTooltip>{{}}</QTooltip>
|
||||
<QList>
|
||||
|
@ -550,6 +560,7 @@ onMounted(() => {
|
|||
icon="check"
|
||||
flat
|
||||
@click="setIsChecked(selectedRows, true)"
|
||||
data-cy="check-amount"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
@ -559,6 +570,7 @@ onMounted(() => {
|
|||
icon="close"
|
||||
flat
|
||||
@click="setIsChecked(selectedRows, false)"
|
||||
data-cy="uncheck-amount"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
@ -598,16 +610,25 @@ onMounted(() => {
|
|||
entryBuysRef.reload();
|
||||
},
|
||||
formInitialData: { entryFk: entityId, isIgnored: false },
|
||||
isFullWidth: true,
|
||||
containerClass: 'form-container',
|
||||
showSaveAndContinueBtn: true,
|
||||
columnGridStyle: {
|
||||
'max-width': '50%',
|
||||
flex: 1,
|
||||
},
|
||||
}
|
||||
: null
|
||||
"
|
||||
:create-complement="{
|
||||
isFullWidth: true,
|
||||
containerStyle: {
|
||||
display: 'flex',
|
||||
'flex-wrap': 'wrap',
|
||||
gap: '16px',
|
||||
position: 'relative',
|
||||
height: '450px',
|
||||
},
|
||||
columnGridStyle: {
|
||||
'max-width': '50%',
|
||||
flex: 1,
|
||||
'margin-right': '30px',
|
||||
},
|
||||
}"
|
||||
:is-editable="editableMode"
|
||||
:without-header="!editableMode"
|
||||
:with-filters="editableMode"
|
||||
|
@ -642,22 +663,23 @@ onMounted(() => {
|
|||
</template>
|
||||
<template #column-footer-stickers>
|
||||
<div>
|
||||
<span style="color: var(--vn-label-color)">{{
|
||||
footer?.printedStickers
|
||||
}}</span>
|
||||
<span>/{{ footer?.stickers }}</span>
|
||||
<span style="color: var(--vn-label-color)">
|
||||
{{ footer?.printedStickers }}</span
|
||||
>
|
||||
<span>/</span>
|
||||
<span data-cy="footer-stickers">{{ footer?.stickers }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #column-footer-weight>
|
||||
{{ footer?.weight }}
|
||||
</template>
|
||||
<template #column-footer-quantity>
|
||||
<span :style="getQuantityStyle(footer)">
|
||||
<span :style="getQuantityStyle(footer)" data-cy="footer-quantity">
|
||||
{{ footer?.quantity }}
|
||||
</span>
|
||||
</template>
|
||||
<template #column-footer-amount>
|
||||
<span :style="getAmountStyle(footer)">
|
||||
<span :style="getAmountStyle(footer)" data-cy="footer-amount">
|
||||
{{ footer?.amount }}
|
||||
</span>
|
||||
</template>
|
||||
|
@ -675,6 +697,7 @@ onMounted(() => {
|
|||
}
|
||||
"
|
||||
:required="true"
|
||||
data-cy="itemFk-create-popup"
|
||||
/>
|
||||
</template>
|
||||
<template #column-create-groupingMode="{ data }">
|
||||
|
@ -689,7 +712,9 @@ onMounted(() => {
|
|||
/>
|
||||
</template>
|
||||
<template #previous-create-dialog="{ data }">
|
||||
<ItemDescriptor :id="data.itemFk" />
|
||||
<div style="position: absolute">
|
||||
<ItemDescriptor :id="data.itemFk ?? NaN" />
|
||||
</div>
|
||||
</template>
|
||||
</VnTable>
|
||||
</template>
|
||||
|
|
|
@ -94,25 +94,53 @@ const getEntryRedirectionFilter = (entry) => {
|
|||
function showEntryReport() {
|
||||
openReport(`Entries/${entityId.value}/entry-order-pdf`);
|
||||
}
|
||||
async function recalculateRates(entity) {
|
||||
const entryConfig = await axios.get('EntryConfigs/findOne');
|
||||
if (entryConfig.data?.inventorySupplierFk === entity.supplierFk) {
|
||||
quasar.notify({
|
||||
type: 'negative',
|
||||
message: t('Cannot recalculate prices because this is an inventory entry'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await axios.post(`Entries/${entityId.value}/recalcEntryPrices`);
|
||||
function showNotification(type, message) {
|
||||
quasar.notify({
|
||||
type: type,
|
||||
message: t(message),
|
||||
});
|
||||
}
|
||||
|
||||
async function recalculateRates(entity) {
|
||||
try {
|
||||
const entryConfig = await axios.get('EntryConfigs/findOne');
|
||||
if (entryConfig.data?.inventorySupplierFk === entity.supplierFk) {
|
||||
showNotification(
|
||||
'negative',
|
||||
'Cannot recalculate prices because this is an inventory entry',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
await axios.post(`Entries/${entityId.value}/recalcEntryPrices`);
|
||||
showNotification('positive', 'Entry prices recalculated');
|
||||
} catch (error) {
|
||||
showNotification('negative', 'Failed to recalculate rates');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function cloneEntry() {
|
||||
await axios
|
||||
.post(`Entries/${entityId.value}/cloneEntry`)
|
||||
.then((response) => push(`/entry/${response.data[0].vNewEntryFk}`));
|
||||
try {
|
||||
const response = await axios.post(`Entries/${entityId.value}/cloneEntry`);
|
||||
push({ path: `/entry/${response.data[0].vNewEntryFk}` });
|
||||
showNotification('positive', 'Entry cloned');
|
||||
} catch (error) {
|
||||
showNotification('negative', 'Failed to clone entry');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteEntry() {
|
||||
await axios.post(`Entries/${entityId.value}/deleteEntry`).then(() => push(`/entry/`));
|
||||
try {
|
||||
await axios.post(`Entries/${entityId.value}/deleteEntry`);
|
||||
push({ path: `/entry/list` });
|
||||
showNotification('positive', 'Entry deleted');
|
||||
} catch (error) {
|
||||
showNotification('negative', 'Failed to delete entry');
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -146,7 +174,13 @@ async function deleteEntry() {
|
|||
<QItem v-ripple clickable @click="cloneEntry(entity)" data-cy="clone-entry">
|
||||
<QItemSection>{{ t('Clone') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-ripple clickable @click="deleteEntry(entity)" data-cy="delete-entry">
|
||||
<QItem
|
||||
v-ripple
|
||||
clickable
|
||||
@click="deleteEntry(entity)"
|
||||
data-cy="delete-entry"
|
||||
v-if="entity?.travelFk"
|
||||
>
|
||||
<QItemSection>{{ t('Delete') }}</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
|
@ -253,4 +287,10 @@ es:
|
|||
landed: Recibido
|
||||
This entry is deleted: Esta entrada está eliminada
|
||||
Cannot recalculate prices because this is an inventory entry: No se pueden recalcular los precios porque es una entrada de inventario
|
||||
Entry deleted: Entrada eliminada
|
||||
Entry cloned: Entrada clonada
|
||||
Entry prices recalculated: Precios de la entrada recalculados
|
||||
Failed to recalculate rates: No se pudieron recalcular las tarifas
|
||||
Failed to clone entry: No se pudo clonar la entrada
|
||||
Failed to delete entry: No se pudo eliminar la entrada
|
||||
</i18n>
|
||||
|
|
|
@ -176,9 +176,8 @@ onMounted(async () => {
|
|||
/>
|
||||
<EntryBuys
|
||||
v-if="entityId"
|
||||
:id="entityId"
|
||||
:id="Number(entityId)"
|
||||
:editable-mode="false"
|
||||
:isEditable="false"
|
||||
table-height="49vh"
|
||||
/>
|
||||
</QCard>
|
||||
|
|
|
@ -263,12 +263,12 @@ onBeforeMount(async () => {
|
|||
<template>
|
||||
<VnSection
|
||||
:data-key="dataKey"
|
||||
:columns="columns"
|
||||
prefix="entry"
|
||||
url="Entries/filter"
|
||||
:array-data-props="{
|
||||
url: 'Entries/filter',
|
||||
userFilter: entryQueryFilter,
|
||||
order: 'landed DESC',
|
||||
userFilter: EntryFilter,
|
||||
}"
|
||||
>
|
||||
<template #advanced-menu>
|
||||
|
@ -281,6 +281,7 @@ onBeforeMount(async () => {
|
|||
:data-key="dataKey"
|
||||
url="Entries/filter"
|
||||
:filter="entryQueryFilter"
|
||||
order="landed DESC"
|
||||
:create="{
|
||||
urlCreate: 'Entries',
|
||||
title: t('Create entry'),
|
||||
|
|
|
@ -2,6 +2,7 @@ entry:
|
|||
lock:
|
||||
title: Lock entry
|
||||
message: This entry has been locked by {userName} for {time} minutes. Do you want to unlock it?
|
||||
success: The entry has been locked successfully
|
||||
list:
|
||||
newEntry: New entry
|
||||
tableVisibleColumns:
|
||||
|
|
|
@ -2,7 +2,7 @@ entry:
|
|||
lock:
|
||||
title: Entrada bloqueada
|
||||
message: Esta entrada ha sido bloqueada por {userName} hace {time} minutos. ¿Quieres desbloquearla?
|
||||
|
||||
success: La entrada ha sido bloqueada correctamente
|
||||
list:
|
||||
newEntry: Nueva entrada
|
||||
tableVisibleColumns:
|
||||
|
|
|
@ -121,7 +121,7 @@ const updateStock = async () => {
|
|||
<template #value>
|
||||
<span class="link">
|
||||
{{ entity.itemType?.worker?.user?.name }}
|
||||
<WorkerDescriptorProxy :id="entity.itemType?.worker?.id" />
|
||||
<WorkerDescriptorProxy :id="entity.itemType?.worker?.id ?? NaN" />
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
|
|
|
@ -260,7 +260,7 @@ async function getZone(options) {
|
|||
auto-load
|
||||
/>
|
||||
<QForm>
|
||||
<VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
||||
<VnSelect
|
||||
:label="t('ticketList.client')"
|
||||
v-model="clientId"
|
||||
|
@ -296,7 +296,7 @@ async function getZone(options) {
|
|||
:rules="validate('ticketList.warehouse')"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md no-wrap">
|
||||
<VnSelect
|
||||
:label="t('basicData.address')"
|
||||
v-model="addressId"
|
||||
|
|
|
@ -109,6 +109,7 @@ export default {
|
|||
title: 'list',
|
||||
icon: 'view_list',
|
||||
},
|
||||
component: () => import('src/pages/Entry/EntryList.vue'),
|
||||
},
|
||||
entryCard,
|
||||
],
|
||||
|
|
|
@ -4,15 +4,215 @@ describe('Entry', () => {
|
|||
cy.login('buyer');
|
||||
cy.visit(`/#/entry/list`);
|
||||
});
|
||||
|
||||
it('Filter deleted entries and other fields', () => {
|
||||
cy.get('button[data-cy="vnTableCreateBtn"]').click();
|
||||
cy.get('input[data-cy="entry-travel-select"]').type('1{enter}');
|
||||
cy.get('button[data-cy="descriptor-more-opts"]').click();
|
||||
cy.get('div[data-cy="delete-entry"]').click();
|
||||
cy.visit(`/#/entry/list`);
|
||||
createEntry();
|
||||
|
||||
cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
|
||||
deleteEntry();
|
||||
cy.typeSearchbar('{enter}');
|
||||
cy.get('span[title="Date"]').click();
|
||||
cy.get('span[title="Date"]').click();
|
||||
cy.get('td[data-row-index="0"][data-col-field="landed"]').contains('-');
|
||||
cy.get('span[title="Date"]').click().click();
|
||||
cy.typeSearchbar('{enter}');
|
||||
cy.url().should('include', 'order');
|
||||
cy.get('td[data-row-index="0"][data-col-field="landed"]').should(
|
||||
'have.text',
|
||||
'-',
|
||||
);
|
||||
});
|
||||
|
||||
it('Create entry, modify travel and add buys', () => {
|
||||
createEntryAndBuy();
|
||||
cy.get('a[data-cy="EntryBasicData-menu-item"]').click();
|
||||
selectTravel('two');
|
||||
cy.saveCard();
|
||||
cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
|
||||
deleteEntry();
|
||||
});
|
||||
|
||||
it('Clone entry and recalculate rates', () => {
|
||||
createEntry();
|
||||
cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
|
||||
|
||||
cy.url().then((perviousUrl) => {
|
||||
cy.log('URL antes de clonar:', perviousUrl);
|
||||
|
||||
cy.get('[data-cy="descriptor-more-opts"]').click();
|
||||
cy.get('div[data-cy="clone-entry"]').click();
|
||||
|
||||
cy.url().then((newUrl) => {
|
||||
expect(perviousUrl).not.to.eq(newUrl);
|
||||
|
||||
cy.get('[data-cy="descriptor-more-opts"]').click();
|
||||
cy.get('div[data-cy="recalculate-rates"]').click();
|
||||
|
||||
cy.get('.q-notification__message')
|
||||
.eq(1)
|
||||
.should('have.text', 'Entry prices recalculated');
|
||||
|
||||
deleteEntry();
|
||||
|
||||
cy.visit(perviousUrl);
|
||||
|
||||
deleteEntry();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Should notify when entry is lock by another user', () => {
|
||||
const checkLockMessage = () => {
|
||||
cy.get('[data-cy="entry-lock-confirm"]').should('be.visible');
|
||||
cy.get('[data-cy="VnConfirm_message"] > span').should(
|
||||
'contain.text',
|
||||
'This entry has been locked by buyerNick',
|
||||
);
|
||||
};
|
||||
|
||||
createEntry();
|
||||
goToEntryBuys();
|
||||
cy.get('.q-notification__message')
|
||||
.eq(1)
|
||||
.should('have.text', 'The entry has been locked successfully');
|
||||
|
||||
cy.login('logistic');
|
||||
cy.reload();
|
||||
checkLockMessage();
|
||||
cy.get('[data-cy="VnConfirm_cancel"]').click();
|
||||
cy.url().should('include', 'summary');
|
||||
|
||||
goToEntryBuys();
|
||||
checkLockMessage();
|
||||
cy.get('[data-cy="VnConfirm_confirm"]').click();
|
||||
cy.url().should('include', 'buys');
|
||||
|
||||
deleteEntry();
|
||||
});
|
||||
|
||||
it('Edit buys and use toolbar actions', () => {
|
||||
const COLORS = {
|
||||
negative: 'rgb(251, 82, 82)',
|
||||
positive: 'rgb(200, 228, 132)',
|
||||
enabled: 'rgb(255, 255, 255)',
|
||||
disable: 'rgb(168, 168, 168)',
|
||||
};
|
||||
|
||||
const selectCell = (field, row = 0) =>
|
||||
cy.get(`td[data-col-field="${field}"][data-row-index="${row}"]`);
|
||||
const selectSpan = (field, row = 0) => selectCell(field, row).find('div > span');
|
||||
const selectButton = (cySelector) => cy.get(`button[data-cy="${cySelector}"]`);
|
||||
const clickAndType = (field, value, row = 0) =>
|
||||
selectCell(field, row).click().type(value);
|
||||
const checkText = (field, expectedText, row = 0) =>
|
||||
selectCell(field, row).should('have.text', expectedText);
|
||||
const checkColor = (field, expectedColor, row = 0) =>
|
||||
selectSpan(field, row).should('have.css', 'color', expectedColor);
|
||||
|
||||
createEntryAndBuy();
|
||||
|
||||
selectCell('isIgnored')
|
||||
.click()
|
||||
.click()
|
||||
.trigger('keydown', { key: 'Tab', keyCode: 9, which: 9 });
|
||||
checkText('isIgnored', 'check');
|
||||
checkColor('quantity', COLORS.negative);
|
||||
|
||||
clickAndType('stickers', '1');
|
||||
checkText('quantity', '11');
|
||||
checkText('amount', '550');
|
||||
clickAndType('packing', '2');
|
||||
checkText('packing', '12close');
|
||||
checkText('weight', '12');
|
||||
checkText('quantity', '132');
|
||||
checkText('amount', '6600');
|
||||
checkColor('packing', COLORS.enabled);
|
||||
|
||||
selectCell('groupingMode').click().click().click();
|
||||
checkColor('packing', COLORS.disable);
|
||||
checkColor('grouping', COLORS.enabled);
|
||||
|
||||
selectCell('buyingValue').click().clear().type('{backspace}{backspace}1');
|
||||
checkText('amount', '132');
|
||||
checkColor('minPrice', COLORS.disable);
|
||||
|
||||
selectCell('hasMinPrice').click().click();
|
||||
checkColor('minPrice', COLORS.enabled);
|
||||
selectCell('hasMinPrice').click();
|
||||
|
||||
cy.saveCard();
|
||||
cy.get('span[data-cy="footer-stickers"]').should('have.text', '11');
|
||||
cy.get('.q-notification__message').contains('Data saved');
|
||||
|
||||
selectButton('change-quantity-sign').should('be.disabled');
|
||||
selectButton('check-buy-amount').should('be.disabled');
|
||||
cy.get('tr.cursor-pointer > .q-table--col-auto-width > .q-checkbox').click();
|
||||
selectButton('change-quantity-sign').should('be.enabled');
|
||||
selectButton('check-buy-amount').should('be.enabled');
|
||||
|
||||
selectButton('change-quantity-sign').click();
|
||||
selectButton('set-negative-quantity').click();
|
||||
checkText('quantity', '-132');
|
||||
selectButton('set-positive-quantity').click();
|
||||
checkText('quantity', '132');
|
||||
checkColor('amount', COLORS.disable);
|
||||
|
||||
selectButton('check-buy-amount').click();
|
||||
selectButton('uncheck-amount').click();
|
||||
checkColor('amount', COLORS.disable);
|
||||
|
||||
selectButton('check-amount').click();
|
||||
checkColor('amount', COLORS.positive);
|
||||
cy.saveCard();
|
||||
|
||||
cy.get('span[data-cy="footer-amount"]').should(
|
||||
'have.css',
|
||||
'color',
|
||||
COLORS.positive,
|
||||
);
|
||||
|
||||
deleteEntry();
|
||||
});
|
||||
|
||||
function goToEntryBuys() {
|
||||
const entryBuySelector = 'a[data-cy="EntryBuys-menu-item"]';
|
||||
cy.get(entryBuySelector).should('be.visible');
|
||||
cy.get(entryBuySelector).click();
|
||||
cy.get(entryBuySelector).click();
|
||||
}
|
||||
|
||||
function deleteEntry() {
|
||||
cy.get('[data-cy="descriptor-more-opts"]').click();
|
||||
cy.get('div[data-cy="delete-entry"]').click();
|
||||
cy.url().should('include', 'list');
|
||||
}
|
||||
|
||||
function createEntryAndBuy() {
|
||||
createEntry();
|
||||
createBuy();
|
||||
}
|
||||
|
||||
function createEntry() {
|
||||
cy.get('button[data-cy="vnTableCreateBtn"]').click();
|
||||
selectTravel('one');
|
||||
cy.get('button[data-cy="FormModelPopup_save"]').click();
|
||||
cy.url().should('include', 'summary');
|
||||
cy.get('.q-notification__message').eq(0).should('have.text', 'Data created');
|
||||
}
|
||||
|
||||
function selectTravel(warehouse) {
|
||||
cy.get('i[data-cy="Travel_icon"]').click();
|
||||
cy.get('input[data-cy="Warehouse Out_select"]').type(warehouse);
|
||||
cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
|
||||
cy.get('button[data-cy="save-filter-travel-form"]').click();
|
||||
cy.get('tr').eq(1).click();
|
||||
}
|
||||
|
||||
function createBuy() {
|
||||
cy.get('a[data-cy="EntryBuys-menu-item"]').click();
|
||||
cy.get('a[data-cy="EntryBuys-menu-item"]').click();
|
||||
cy.get('button[data-cy="vnTableCreateBtn"]').click();
|
||||
|
||||
cy.get('input[data-cy="itemFk-create-popup"]').type('1');
|
||||
cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
|
||||
cy.get('input[data-cy="Grouping mode_select"]').should('have.value', 'packing');
|
||||
cy.get('button[data-cy="FormModelPopup_save"]').click();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const waitUntil = (subject, checkFunction, originalOptions = {}) => {
|
||||
if (!(checkFunction instanceof Function)) {
|
||||
throw new Error(
|
||||
'`checkFunction` parameter should be a function. Found: ' + checkFunction
|
||||
'`checkFunction` parameter should be a function. Found: ' + checkFunction,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue