#6321 - Negative ticket #158

Open
jsegarra wants to merge 220 commits from 6321_negative_tickets into dev
6 changed files with 70 additions and 168 deletions
Showing only changes of commit 055a0b8751 - Show all commits

View File

@ -5,6 +5,8 @@ import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import { toCurrency } from 'filters/index';
import VnStockValueDisplay from 'src/components/ui/VnStockValueDisplay.vue';
import VnTable from 'src/components/VnTable/VnTable.vue';
import axios from 'axios';
import notifyResults from 'src/utils/notifyResults';
const MATCH_VALUES = [5, 6, 7, 8];
jgallego marked this conversation as resolved Outdated

configuracion a tablas

configuracion a tablas

ya no hace falta

ya no hace falta
const { t } = useI18n();
@ -12,8 +14,6 @@ const extractNumericValue = (percentageString) => {
const match = percentageString.match(/(\d+(\.\d+)?)/);
return match ? parseFloat(match[0]) : null;
};
const primaryColor = '#f5b351';
const colorSpacer = '#ecf0f1';
const compatibilityItem = (value) => `${100 * (value / MATCH_VALUES.length)}%`;
const gradientStyle = (value) => {
let color = 'white';
@ -157,7 +157,8 @@ const columns = computed(() => [
field: 'located',
},
jgallego marked this conversation as resolved Outdated

Aqui no veo correcto usar las variables de colores definidos

Aqui no veo correcto usar las variables de colores definidos

yo lo que no veo correcto es usar el amarillo que nos de javascript sin saber cual és, creemos una variable amarillo porque tal vez en el dark o en el light lo queramos hacer amarillo pero no el mismo tono

yo lo que no veo correcto es usar el amarillo que nos de javascript sin saber cual és, creemos una variable amarillo porque tal vez en el dark o en el light lo queramos hacer amarillo pero no el mismo tono

ok, vale, cambio de style por class

ok, vale, cambio de style por class
]);
const isSelected = (row) => proposalSelected.value.some((item) => row.id === item.id);
const isSelected = (row) =>
proposalSelected.value.some((item) => row.itemFk === item.itemFk);
function change(row) {
if (isSelected(row)) {
confirm(row);
@ -165,29 +166,24 @@ function change(row) {
}
proposalSelected.value = [row];
}
async function confirm(row) {
async function confirm() {
try {
// const params = {
// saleFk: saleFk.value,
// substitutionFk: proposalSelected.value[0].id,
// quantity: quantity.value,
// };
// const { data } = await axios.post('Sales/replaceItem', params);
const params = [
saleFk.value,
row ?? proposalSelected.value[0].id,
quantity.value,
];
// const { data } = await axios.post('Applications/sale_replaceItem/execute-proc', {
// schema: 'vn',
// params,
// });
// proposalTableRef.value.reload();
const substitutionFk = proposalSelected.value[0].itemFk;
const promises = $props.sales.map(({ saleFk, quantity }) => {
const params = {
saleFk,
substitutionFk,
quantity,
};
return axios.post('Sales/replaceItem', params);
});
const results = await Promise.allSettled(promises);
notifyResults(results, 'saleFk');
emit('itemReplaced', {
type: 'refresh',
quantity: quantity.value,
itemProposal: proposalSelected.value[0],
...params,
});
proposalSelected.value = [];
} catch (error) {
@ -198,13 +194,9 @@ const filter = computed(() => ({
itemFk: $props.itemLack.itemFk,
sales: saleFk.value,
}));
function handleSelection(value, _) {
quantity.value = value.available;
}
const isSelectionAvailable = (itemProposal) => {
const { price2 } = itemProposal;
const salePrice = sale.value.price;
// debugger;
const byPrice = (100 * price2) / salePrice > 30;
if (byPrice) {
return byPrice;
@ -213,8 +205,6 @@ const isSelectionAvailable = (itemProposal) => {
(100 * itemProposal.available) / Math.abs($props.itemLack.lack) < 30;
return byQuantity;
};
const isDisabled = (row) => !isSelectionAvailable(row);
</script>
<template>
<VnTable

View File

@ -1,7 +1,5 @@
<script setup>
import ItemProposal from './ItemProposal.vue';
import { ref } from 'vue';
const popupProxyRef = ref(null);
import { useDialogPluginComponent } from 'quasar';
const emit = defineEmits([
'onDialogClosed',
@ -12,8 +10,7 @@ const emit = defineEmits([
]);
defineExpose({ show: () => dialogRef.value.show(), hide: () => dialogRef.value.hide() });
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
useDialogPluginComponent();
const { dialogRef } = useDialogPluginComponent();
const $props = defineProps({
itemLack: {
type: Object,
@ -41,21 +38,12 @@ const $props = defineProps({
<QBtn icon="close" flat round dense v-close-popup />
</QCardSection>
<QCardSection>
<!-- <VnImg :id="itemLack.id" class="rounded image-wrapper"></VnImg>
<QBtn flat class="link text-blue">
{{ itemLack.longName }}
<ItemDescriptorProxy :id="itemLack.id" />
</QBtn>
<FetchedTags :item="itemLack" />
</QCardSection>
<QCardSection class="q-pt-none"> -->
<ItemProposal
v-bind="$props"
@item-replaced="
(data) => {
emit('itemReplaced', data);
popupProxyRef.value.hide();
dialogRef.hide();
}
"
></ItemProposal

View File

@ -8,6 +8,7 @@ import TicketTransferForm from './TicketTransferForm.vue';
import { toDateFormat } from 'src/filters/date.js';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import split from './components/split';
const emit = defineEmits(['ticketTransfered']);
const $props = defineProps({
mana: {
@ -94,7 +95,8 @@ const handleRowClick = (row) => {
};
const splitSelectedRows = async () => {
const tickets = Array.isArray($props.ticket) ? $props.ticket : [$props.ticket];
await split(tickets);
await split(tickets, splitDate.value);
emit('ticketTransfered', tickets);
};
</script>

View File

@ -1,13 +1,13 @@
import axios from 'axios';
import notifyResults from 'src/utils/notifyResults';
export default async function (data) {
export default async function (data, date) {
const reducedData = data.reduce((acc, item) => {
const existing = acc.find(({ ticketFk }) => ticketFk === item.id);
if (existing) {
existing.sales.push(item.saleFk);
} else {
acc.push({ ticketFk: item.id, sales: [item.saleFk] });
acc.push({ ticketFk: item.id, sales: [item.saleFk], date });
}
return acc;
}, []);

View File

@ -13,9 +13,6 @@ import { useRoute } from 'vue-router';
import TicketLackTable from './TicketLackTable.vue';
import VnPopupProxy from 'src/components/common/VnPopupProxy.vue';
import ItemProposalProxy from 'src/pages/Item/components/ItemProposalProxy.vue';
import FetchedTags from 'components/ui/FetchedTags.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnImg from 'src/components/ui/VnImg.vue';
import { useQuasar } from 'quasar';
const quasar = useQuasar();
@ -41,76 +38,27 @@ onUnmounted(() => {
const entityId = computed(() => route.params.id);
const item = ref({});
const itemLackForm = ref();
const itemProposalSelected = ref(null);
const reload = async () => {
itemLackForm.value.fetch();
tableRef.value.tableRef.reload();
};
defineExpose({ reload });
// Función de comparación
// function freeFirst({ alertLevel: a }, { alertLevel: b }) {
// const DEFAULT = 0;
// // Si el estado de 'a' es 'free' y el de 'b' no lo es, 'a' viene primero
// if (a === DEFAULT && b !== DEFAULT) {
// return -1;
// }
// // Si el estado de 'b' es 'free' y el de 'a' no lo es, 'b' viene primero
// if (b === DEFAULT && a !== DEFAULT) {
// return 1;
// }
// // En cualquier otro caso, no se cambia el orden
// return 0;
// }
// const { store } = useArrayData(URL_KEY);
// const handleRows = (rows) => {
// // rows.forEach((row) => (row.concept = item.value.name));
// rows = rows.sort(freeFirst);
// if (showFree.value) return rows.filter(({ alertLevel }) => alertLevel === 0);
// return rows;
// };
const someBasket = computed(() => selectedRows.value.some((row) => row.isBasket === 1));
const itemProposalEvt = (data) => {
const { itemProposal, quantity } = data;
itemProposalSelected.value = itemProposal;
// badgeLackRef.value.reload();
itemLack.value.lack += +quantity;
tableRef.value.reload();
// replaceItem();
reload();
};
const itemProposalSelected = ref(null);
// const replaceItem = () => {
// const rows = handleRows(originalRowDataCopy.value).sort((row) => row.quantity);
// for (const ticket of rows) {
// if (ticket.quantity > itemProposalSelected.value.available) continue;
// originalRowDataCopy.value.splice(originalRowDataCopy.value.indexOf(ticket));
// ticket.itemFk = itemProposalSelected.value.id;
// selectedRows.value.push({ ticketFk: ticket.ticketFk });
// itemProposalSelected.value.available -= ticket.quantity;
// itemLack.value.lack += ticket.quantity;
// const index = store.data.findIndex((t) => t.ticketFk === ticket.ticketFk);
// store.data.splice(index, 1);
// console.log(ticket);
// useArrayData('ItemsGetSimilar').store.data[1].available =
// itemProposalSelected.value.available;
// }
// };
function onBuysFetched(data) {
Object.assign(item.value, data[0]);
}
const closeDialogs = (refs, evt) => {
changeItemDialogRef.value.hide();
changeQuantityDialogRef.value.hide();
changeStateDialogRef.value.hide();
};
const showItemProposal = () => {
quasar
.dialog({
component: ItemProposalProxy,
componentProps: {
itemLack: itemLack.value,
itemLack: tableRef.value.itemLack,
replaceAction: true,
sales: selectedRows.value,
},
@ -139,16 +87,7 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
@on-fetch="onBuysFetched"
auto-load
/>
<FetchData
:url="`Tickets/itemLack`"
:params="{ itemFk: entityId }"
@on-fetch="(data) => (itemLack = data[0])"
auto-load
/>
<!-- <VnSubToolbar>
<template #st-data> </template>
<template #st-actions> </template>
</VnSubToolbar> -->
<TicketLackTable
ref="tableRef"
jsegarra marked this conversation as resolved
Review

2 ?

2 ?
Review

Esto ya lo habia cambiado, pero a lo mejor al hacer otros cambios se ha machacado

Esto ya lo habia cambiado, pero a lo mejor al hacer otros cambios se ha machacado
:filter="filterTable"
@ -171,6 +110,7 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
sales: selectedRows,
lastActiveTickets: selectedRows.map((row) => row.id),
}"
@ticket-transfered="reload"
></TicketTransfer>
</QBtn>
<QBtn
@ -183,13 +123,6 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
class="rotate-90"
@click="showItemProposal"
></QIcon>
<!-- <ItemProposalProxy
ref="proposalDialogRef"
:item-lack="itemLack"
:replace-action="true"
:sales="selectedRows"
@item-replaced="itemProposalEvt"
></ItemProposalProxy> -->
<QTooltip bottom anchor="bottom right">
{{ t('itemProposal') }}
</QTooltip>
@ -238,27 +171,6 @@ const filterTable = { stateFk: 0, warehouseFk: useState().getUser().value.wareho
/></template>
</VnPopupProxy> </QBtnGroup
></template>
<template #top-left>
<div style="display: flex; align-items: center" v-if="itemLack">
<VnImg :id="itemLack.itemFk" class="rounded image-wrapper"></VnImg>
<div class="flex column" style="align-items: center">
<QBadge
ref="badgeLackRef"
class="q-ml-xs"
text-color="white"
:color="itemLack.lack === 0 ? 'green' : 'red'"
:label="itemLack.lack"
/>
</div>
<div class="flex column left" style="align-items: flex-start">
<QBtn flat class="link text-blue">
{{ item?.longName ?? item.name }}
<ItemDescriptorProxy :id="entityId" />
</QBtn>
<FetchedTags class="q-ml-md" :item="item" :columns="7" />
</div>
</div>
</template>
</TicketLackTable>
</template>
<style lang="scss" scoped>

View File

@ -1,4 +1,7 @@
<script setup>
import FetchedTags from 'components/ui/FetchedTags.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
import VnImg from 'src/components/ui/VnImg.vue';
import { computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
@ -70,6 +73,7 @@ const saveChange = async (field, { rowIndex, row }) => {
break;
}
notify('globals.dataSaved', 'positive');
fetchItemLack.value.fetch();
} catch (err) {
console.error('Error saving changes', err);
f;
@ -82,34 +86,7 @@ const rowColor = (row) => {
if (hasToIgnore(row)) return 'transparent';
return 'negative';
};
// const textRowColor = (row) => {
// if (row.hasToIgnore) return 'black';
// return 'white';
// };
const columns = computed(() => [
// {
// align: 'left',
// label: t('negative.detail.isBasket'),
// name: 'isBasket',
// cardVisible: true,
// create: true,
// component: 'checkbox',
// attrs: ({ row }) => {
// return {
// 'toggle-indeterminate': true,
// };
// },
// columnClass: 'shrink',
// },
// {
// align: 'left',
// label: t('negative.detail.hasSubstitution'),
// name: 'hasSubstitution',
// cardVisible: true,
// create: true,
// component: 'checkbox',
// columnClass: 'shrink',
// },
{
name: 'status',
align: 'left',
@ -206,15 +183,24 @@ const columns = computed(() => [
]);
const emit = defineEmits(['update:selection']);
const itemLack = ref(null);
const fetchItemLack = ref(null);
const tableRef = ref(null);
watch(selectedRows, () => emit('update:selection', selectedRows));
function onBuysFetched(data) {
Object.assign(item.value, data[0]);
}
defineExpose({ tableRef, itemLack });
jgallego marked this conversation as resolved Outdated

2?

2?

cambiado por entitytId

cambiado por entitytId
</script>
<template>
<FetchData
ref="fetchItemLack"
:url="`Tickets/itemLack`"
:params="{ itemFk: entityId }"
@on-fetch="(data) => (itemLack = data[0])"
auto-load
/>
<FetchData
:url="`Items/${entityId}/getCard`"
:fields="['longName']"
@ -253,7 +239,25 @@ function onBuysFetched(data) {
:disable-option="{ card: true }"
>
<template #top-left>
<slot name="top-left" />
<div style="display: flex; align-items: center" v-if="itemLack">
<VnImg :id="itemLack.itemFk" class="rounded image-wrapper"></VnImg>
<div class="flex column" style="align-items: center">
<QBadge
ref="badgeLackRef"
class="q-ml-xs"
text-color="white"
:color="itemLack.lack === 0 ? 'green' : 'red'"
:label="itemLack.lack"
/>
</div>
<div class="flex column left" style="align-items: flex-start">
<QBtn flat class="link text-blue">
{{ item?.longName ?? item.name }}
<ItemDescriptorProxy :id="entityId" />
</QBtn>
<FetchedTags class="q-ml-md" :item="item" :columns="7" />
</div>
</div>
</template>
<template #top-right>
<slot name="top-right" />
@ -263,6 +267,7 @@ function onBuysFetched(data) {
<QTd style="width: 150px">
<div class="icon-container">
<QIcon
v-if="row.isBasket"
name="vn:basket"
color="primary"
class="cursor-pointer"
@ -271,6 +276,7 @@ function onBuysFetched(data) {
<QTooltip>{{ t('negative.detail.isBasket') }}</QTooltip>
</QIcon>
<QIcon
v-if="row.hasToIgnore"
name="star"
color="primary"
class="cursor-pointer fill-icon"
@ -279,6 +285,7 @@ function onBuysFetched(data) {
<QTooltip>{{ t('negative.detail.hasToIgnore') }}</QTooltip>
</QIcon>
<QIcon
v-if="row.hasSubstitution"
name="change_circle"
color="primary"
class="cursor-pointer"
@ -288,6 +295,7 @@ function onBuysFetched(data) {
t('negative.detail.hasSubstitution')
}}</QTooltip> </QIcon
><QIcon
v-if="row.isRookie"
name="vn:Person"
size="xs"
color="primary"
@ -296,6 +304,7 @@ function onBuysFetched(data) {
<QTooltip>{{ t('negative.detail.isRookie') }}</QTooltip>
</QIcon>
<QIcon
v-if="row.peticionCompra"
name="vn:buyrequest"
size="xs"
color="primary"
@ -304,6 +313,7 @@ function onBuysFetched(data) {
<QTooltip>{{ t('negative.detail.peticionCompra') }}</QTooltip>
</QIcon>
<QIcon
v-if="row.turno"
name="vn:calendar"
size="xs"
color="primary"