Merge branch 'master' into Hotfix-OpenFilesInsteadOfDownloading
gitea/salix-front/pipeline/pr-master This commit looks good
Details
gitea/salix-front/pipeline/pr-master This commit looks good
Details
This commit is contained in:
commit
a8f6a31cef
|
@ -56,26 +56,6 @@ const defaultColumnAttrs = {
|
|||
sortable: false,
|
||||
};
|
||||
const emit = defineEmits(['onDialogClosed', 'itemReplaced']);
|
||||
|
||||
const priceStatusClass = (proposalPrice) => {
|
||||
const originalPrice = sale.value?.price;
|
||||
|
||||
if (
|
||||
!originalPrice ||
|
||||
!ticketConfig.value ||
|
||||
typeof ticketConfig.value.lackAlertPrice !== 'number'
|
||||
) {
|
||||
return 'price-ok';
|
||||
}
|
||||
|
||||
const priceIncreasePercentage =
|
||||
((proposalPrice - originalPrice) / originalPrice) * 100;
|
||||
|
||||
return priceIncreasePercentage > ticketConfig.value.lackAlertPrice
|
||||
? 'price-alert'
|
||||
: 'price-ok';
|
||||
};
|
||||
|
||||
const columns = computed(() => [
|
||||
{
|
||||
...defaultColumnAttrs,
|
||||
|
@ -196,7 +176,6 @@ const columns = computed(() => [
|
|||
{
|
||||
title: t('Replace'),
|
||||
icon: 'change_circle',
|
||||
show: (row) => isSelectionAvailable(row),
|
||||
action: change,
|
||||
isPrimary: true,
|
||||
},
|
||||
|
@ -204,11 +183,18 @@ const columns = computed(() => [
|
|||
},
|
||||
]);
|
||||
|
||||
function extractMatchValues(obj) {
|
||||
return Object.keys(obj)
|
||||
.filter((key) => key.startsWith(MATCH))
|
||||
.map((key) => parseInt(key.replace(MATCH, ''), 10));
|
||||
}
|
||||
const priceStatusClass = (proposalPrice) => {
|
||||
const originalPrice = sale.value?.price;
|
||||
const { lackAlertPrice: lackAlert } = ticketConfig.value;
|
||||
if (!originalPrice || !ticketConfig.value || typeof lackAlert !== 'number') {
|
||||
return 'price-ok';
|
||||
}
|
||||
|
||||
const percentage = ((proposalPrice - originalPrice) / originalPrice) * 100;
|
||||
|
||||
return percentage > lackAlert ? 'price-alert' : 'price-ok';
|
||||
};
|
||||
|
||||
const gradientStyleClass = (row) => {
|
||||
let color = 'white';
|
||||
const value = parseFloat(row);
|
||||
|
@ -226,28 +212,49 @@ const gradientStyleClass = (row) => {
|
|||
}
|
||||
return color;
|
||||
};
|
||||
|
||||
const extractMatchValues = (obj) => {
|
||||
return Object.keys(obj)
|
||||
.filter((key) => key.startsWith(MATCH))
|
||||
.map((key) => parseInt(key.replace(MATCH, ''), 10));
|
||||
};
|
||||
|
||||
const statusConditionalValue = (row) => {
|
||||
const matches = extractMatchValues(row);
|
||||
const value = matches.reduce((acc, i) => acc + row[`${MATCH}${i}`], 0);
|
||||
return 100 * (value / matches.length);
|
||||
};
|
||||
|
||||
const isSelectionAvailable = (itemProposal) => {
|
||||
const { price2, available } = itemProposal;
|
||||
const salePrice = sale.value.price;
|
||||
const { lackAlertPrice } = ticketConfig.value;
|
||||
const isPriceTooHigh = (100 * price2) / salePrice > lackAlertPrice;
|
||||
if (isPriceTooHigh) {
|
||||
return isPriceTooHigh;
|
||||
const canReplace = (itemProposal) => {
|
||||
if (!canReplaceByPrice(itemProposal)) {
|
||||
return false;
|
||||
}
|
||||
const hasEnoughQuantity =
|
||||
(100 * available) / Math.abs($props.itemLack.lack) < lackAlertPrice;
|
||||
return hasEnoughQuantity;
|
||||
return canReplaceByQuantity(itemProposal);
|
||||
};
|
||||
const differenceByPrice = ({ price2: proposalPrice }) => {
|
||||
const { price: salePrice } = sale.value;
|
||||
const percentage = ((proposalPrice - salePrice) / salePrice) * 100;
|
||||
return percentage;
|
||||
};
|
||||
const canReplaceByPrice = (itemProposal) =>
|
||||
differenceByPrice(itemProposal) < ticketConfig.value.lackAlertPrice;
|
||||
|
||||
const differenceByQuantity = ({ available }) => {
|
||||
const { quantity: saleQuantity } = sale.value;
|
||||
const percentage = ((saleQuantity - available) / available) * 100;
|
||||
return percentage;
|
||||
};
|
||||
|
||||
const canReplaceByQuantity = (itemProposal) =>
|
||||
differenceByQuantity(itemProposal) < ticketConfig.value.lackAlertPrice;
|
||||
|
||||
async function change(itemSubstitution) {
|
||||
if (!isSelectionAvailable(itemSubstitution)) {
|
||||
notify(t('notAvailable'), 'warning');
|
||||
if (!canReplaceByPrice(itemSubstitution)) {
|
||||
notify(t('notAvailableByPrice'), 'warning');
|
||||
return;
|
||||
}
|
||||
if (!canReplaceByQuantity(itemSubstitution)) {
|
||||
notify(t('notAvailableByQuantity'), 'warning');
|
||||
return;
|
||||
}
|
||||
const { itemFk: substitutionFk } = itemSubstitution;
|
||||
|
@ -277,9 +284,7 @@ async function handleTicketConfig(data) {
|
|||
}
|
||||
|
||||
function filterRows(data) {
|
||||
const filteredRows = data.sort(
|
||||
(a, b) => isSelectionAvailable(b) - isSelectionAvailable(a),
|
||||
);
|
||||
const filteredRows = data.sort((a, b) => canReplace(b) - canReplace(a));
|
||||
proposalTableRef.value.CrudModelRef.formData = filteredRows;
|
||||
}
|
||||
</script>
|
||||
|
@ -315,6 +320,7 @@ function filterRows(data) {
|
|||
>
|
||||
<template #top-right>
|
||||
<QBtn
|
||||
:disable="false"
|
||||
flat
|
||||
class="q-mr-sm"
|
||||
color="primary"
|
||||
|
@ -369,16 +375,19 @@ function filterRows(data) {
|
|||
</template>
|
||||
<template #column-price2="{ row }">
|
||||
<div class="flex column items-center content-center">
|
||||
<!-- Use class binding for tooltip background -->
|
||||
<QTooltip :offset="[0, 5]" anchor="top middle" self="bottom middle">
|
||||
<div>{{ $t('proposal.price2') }}: {{ toCurrency(row.price2) }}</div>
|
||||
<div>
|
||||
{{ $t('proposal.itemOldPrice') }}:
|
||||
{{ toCurrency(sales[0]?.price) }}
|
||||
{{ $t('proposal.itemOldPrice') }}:{{
|
||||
toCurrency(sales[0]?.price)
|
||||
}}
|
||||
</div>
|
||||
<div>{{ $t('%€') }}: {{ differenceByPrice(row) }}%</div>
|
||||
</QTooltip>
|
||||
<VnStockValueDisplay :format="'currency'" :value="-row.price2 / 100" />
|
||||
<!-- Use class binding for text color -->
|
||||
<VnStockValueDisplay
|
||||
:format="'currency'"
|
||||
:value="row.price2 - sales[0]?.price"
|
||||
/>
|
||||
<span :class="[priceStatusClass(row.price2)]">{{
|
||||
toCurrency(row.price2)
|
||||
}}</span>
|
||||
|
@ -434,7 +443,12 @@ function filterRows(data) {
|
|||
</style>
|
||||
<i18n>
|
||||
en:
|
||||
notAvailable: 'Not available for replacement'
|
||||
notAvailable: Not available for replacement
|
||||
notAvailableByPrice: Not available for replacement by price
|
||||
notAvailableByQuantity: Not available for replacement by quantity
|
||||
es:
|
||||
notAvailable: 'No disponible para reemplazo'
|
||||
notAvailable: No disponible para reemplazo
|
||||
notAvailableByPrice: No disponible para reemplazo por precio
|
||||
notAvailableByQuantity: No disponible para reemplazo por cantidad
|
||||
Replace: Remplazar
|
||||
</i18n>
|
||||
|
|
|
@ -26,7 +26,8 @@ const { notify } = useNotify();
|
|||
const totalRows = ref({});
|
||||
const arrayData = useArrayData('SupplierConsumption', {
|
||||
url: 'Suppliers/consumption',
|
||||
order: ['itemTypeFk', 'itemName', 'itemSize'],
|
||||
order: ['shipped DESC', 'itemTypeFk', 'itemName', 'itemSize'],
|
||||
limit: 0,
|
||||
userFilter: { where: { supplierFk: route.params.id } },
|
||||
});
|
||||
const headerColumns = computed(() => [
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||
import split from './components/split';
|
||||
import { displayResults } from 'src/pages/Ticket/Negative/composables/notifyResults';
|
||||
const { notifyResults } = displayResults();
|
||||
const emit = defineEmits(['ticketTransferred']);
|
||||
const { t } = useI18n();
|
||||
|
||||
const $props = defineProps({
|
||||
ticket: {
|
||||
|
@ -27,7 +29,7 @@ const splitSelectedRows = async () => {
|
|||
<template>
|
||||
<VnInputDate
|
||||
class="q-mr-sm"
|
||||
:label="$t('New date')"
|
||||
:label="t('New date')"
|
||||
v-model="splitDate"
|
||||
clearable
|
||||
autofocus
|
||||
|
@ -41,6 +43,9 @@ const splitSelectedRows = async () => {
|
|||
</style>
|
||||
<i18n>
|
||||
es:
|
||||
New date: Nueva fecha
|
||||
Split: Separar
|
||||
Transfer lines: Transferir líneas
|
||||
Sales to transfer: Líneas a transferir
|
||||
Destination ticket: Ticket destinatario
|
||||
</i18n>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import '../commands.js';
|
||||
describe('EntryBuys', () => {
|
||||
describe.skip('EntryBuys', () => {
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('buyer');
|
||||
|
|
|
@ -13,7 +13,7 @@ const clickNotificationAction = () => {
|
|||
expect(firstArg).to.include(`/ticket/${ticketId}/sale`);
|
||||
});
|
||||
};
|
||||
describe('Ticket Lack detail', { testIsolation: true }, () => {
|
||||
describe.skip('Ticket Lack detail', { testIsolation: true }, () => {
|
||||
beforeEach(() => {
|
||||
cy.viewport(1980, 1020);
|
||||
cy.login('developer');
|
||||
|
|
Loading…
Reference in New Issue