diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index d175a4167..1a0f50a94 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -7,7 +7,6 @@ import axios from 'axios'; import { usePrintService } from 'composables/usePrintService'; import VnUserLink from '../ui/VnUserLink.vue'; -import { downloadFile } from 'src/composables/downloadFile'; import VnImg from 'components/ui/VnImg.vue'; import VnPaginate from 'components/ui/VnPaginate.vue'; import VnDms from 'src/components/common/VnDms.vue'; diff --git a/src/pages/Customer/Card/CustomerCredits.vue b/src/pages/Customer/Card/CustomerCredits.vue index d6e4be89e..1469fbe3d 100644 --- a/src/pages/Customer/Card/CustomerCredits.vue +++ b/src/pages/Customer/Card/CustomerCredits.vue @@ -3,12 +3,13 @@ import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import { toCurrency, toDateHourMin } from 'src/filters'; +import { useArrayData } from 'composables/useArrayData'; import VnTable from 'components/VnTable/VnTable.vue'; import VnUserLink from 'src/components/ui/VnUserLink.vue'; const { t } = useI18n(); const route = useRoute(); - +const arrayData = useArrayData('Customer'); const filter = computed(() => { return { include: [ @@ -77,7 +78,10 @@ const columns = computed(() => [ :create="{ urlUpdate: `Clients/${route.params.id}`, title: t('New credit'), - onDataSaved: () => tableRef.reload(), + onDataSaved: () => { + arrayData.fetch({ append: false }); + tableRef.reload(); + }, formInitialData: { credit: tableData.at(0)?.amount }, }" > diff --git a/src/pages/Customer/Card/CustomerFileManagement.vue b/src/pages/Customer/Card/CustomerFileManagement.vue index 419719251..f914993b7 100644 --- a/src/pages/Customer/Card/CustomerFileManagement.vue +++ b/src/pages/Customer/Card/CustomerFileManagement.vue @@ -5,7 +5,7 @@ import { useRoute, useRouter } from 'vue-router'; import { QBadge, QBtn, QCheckbox } from 'quasar'; -import { downloadFile } from 'src/composables/downloadFile'; +import { usePrintService } from 'composables/usePrintService'; import { toDateTimeFormat } from 'src/filters/date'; import FetchData from 'components/FetchData.vue'; @@ -15,7 +15,7 @@ import CustomerFileManagementActions from 'src/pages/Customer/components/Custome const { t } = useI18n(); const route = useRoute(); const router = useRouter(); - +const { openReport } = usePrintService(); const ClientDmsRef = ref(null); const rows = ref([]); @@ -87,7 +87,7 @@ const tableColumnComponents = { file: { component: QBtn, props: () => ({ flat: true }), - event: ({ row }) => downloadFile(row.dmsFk), + event: ({ row }) => openReport(`dms/${row.dmsFk}/downloadFile`, {}, '_blank'), }, employee: { component: QBtn, diff --git a/src/pages/Item/components/ItemProposal.vue b/src/pages/Item/components/ItemProposal.vue index 30f050097..5c735d170 100644 --- a/src/pages/Item/components/ItemProposal.vue +++ b/src/pages/Item/components/ItemProposal.vue @@ -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; } @@ -315,6 +320,7 @@ function filterRows(data) { >