Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix-front into dev
gitea/salix-front/pipeline/head This commit looks good
Details
gitea/salix-front/pipeline/head This commit looks good
Details
This commit is contained in:
commit
6a97c368e4
|
@ -897,7 +897,7 @@ const rowCtrlClickFunction = computed(() => {
|
|||
{{ row[splittedColumns.title.name] }}
|
||||
</span>
|
||||
</QCardSection>
|
||||
<!-- Fields -->
|
||||
<!-- Fields -->
|
||||
<QCardSection
|
||||
class="q-pl-sm q-py-xs"
|
||||
:class="$props.cardClass"
|
||||
|
@ -1156,7 +1156,7 @@ es:
|
|||
|
||||
.grid-create {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, max-content));
|
||||
max-width: 100%;
|
||||
grid-gap: 20px;
|
||||
margin: 0 auto;
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
<script setup>
|
||||
import VnConfirm from '../ui/VnConfirm.vue';
|
||||
import VnInput from './VnInput.vue';
|
||||
import VnDms from './VnDms.vue';
|
||||
import axios from 'axios';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { downloadFile } from 'src/composables/downloadFile';
|
||||
|
||||
const { t } = useI18n();
|
||||
const quasar = useQuasar();
|
||||
const documentDialogRef = ref({});
|
||||
const editDownloadDisabled = ref(false);
|
||||
const $props = defineProps({
|
||||
defaultDmsCode: {
|
||||
type: String,
|
||||
default: 'InvoiceIn',
|
||||
},
|
||||
disable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
formRef: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
function deleteFile(dmsFk) {
|
||||
quasar
|
||||
.dialog({
|
||||
component: VnConfirm,
|
||||
componentProps: {
|
||||
title: t('globals.confirmDeletion'),
|
||||
message: t('globals.confirmDeletionMessage'),
|
||||
},
|
||||
})
|
||||
.onOk(async () => {
|
||||
await axios.post(`dms/${dmsFk}/removeFile`);
|
||||
$props.formRef.formData.dmsFk = null;
|
||||
$props.formRef.formData.dms = undefined;
|
||||
$props.formRef.hasChanges = true;
|
||||
$props.formRef.save();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="row no-wrap">
|
||||
<VnInput
|
||||
:label="t('Document')"
|
||||
v-model="data.dmsFk"
|
||||
clearable
|
||||
clear-icon="close"
|
||||
class="full-width"
|
||||
:disable="disable"
|
||||
/>
|
||||
<div
|
||||
v-if="data.dmsFk"
|
||||
class="row no-wrap q-pa-xs q-gutter-x-xs"
|
||||
data-cy="dms-buttons"
|
||||
>
|
||||
<QBtn
|
||||
:disable="editDownloadDisabled"
|
||||
@click="downloadFile(data.dmsFk)"
|
||||
icon="cloud_download"
|
||||
color="primary"
|
||||
flat
|
||||
:class="{
|
||||
'no-pointer-events': editDownloadDisabled,
|
||||
}"
|
||||
padding="xs"
|
||||
round
|
||||
>
|
||||
<QTooltip>{{ t('Download file') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
:disable="editDownloadDisabled"
|
||||
@click="
|
||||
() => {
|
||||
documentDialogRef.show = true;
|
||||
documentDialogRef.dms = data.dms;
|
||||
}
|
||||
"
|
||||
icon="edit"
|
||||
color="primary"
|
||||
flat
|
||||
:class="{
|
||||
'no-pointer-events': editDownloadDisabled,
|
||||
}"
|
||||
padding="xs"
|
||||
round
|
||||
>
|
||||
<QTooltip>{{ t('Edit document') }}</QTooltip>
|
||||
</QBtn>
|
||||
<QBtn
|
||||
:disable="editDownloadDisabled"
|
||||
@click="deleteFile(data.dmsFk)"
|
||||
icon="delete"
|
||||
color="primary"
|
||||
flat
|
||||
round
|
||||
:class="{
|
||||
'no-pointer-events': editDownloadDisabled,
|
||||
}"
|
||||
padding="xs"
|
||||
>
|
||||
<QTooltip>{{ t('Delete file') }}</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
<QBtn
|
||||
v-else
|
||||
icon="add_circle"
|
||||
color="primary"
|
||||
flat
|
||||
round
|
||||
v-shortcut="'+'"
|
||||
padding="xs"
|
||||
@click="
|
||||
() => {
|
||||
documentDialogRef.show = true;
|
||||
delete documentDialogRef.dms;
|
||||
}
|
||||
"
|
||||
data-cy="dms-create"
|
||||
>
|
||||
<QTooltip>{{ t('Create document') }}</QTooltip>
|
||||
</QBtn>
|
||||
</div>
|
||||
<QDialog v-model="documentDialogRef.show">
|
||||
<VnDms
|
||||
model="dms"
|
||||
:default-dms-code="defaultDmsCode"
|
||||
:form-initial-data="documentDialogRef.dms"
|
||||
:url="
|
||||
documentDialogRef.dms
|
||||
? `Dms/${documentDialogRef.dms.id}/updateFile`
|
||||
: 'Dms/uploadFile'
|
||||
"
|
||||
:description="documentDialogRef.supplierName"
|
||||
@on-data-saved="
|
||||
(_, { data }) => {
|
||||
let dmsData = data;
|
||||
if (Array.isArray(data)) dmsData = data[0];
|
||||
formRef.formData.dmsFk = dmsData.id;
|
||||
formRef.formData.dms = dmsData;
|
||||
formRef.hasChanges = true;
|
||||
formRef.save();
|
||||
}
|
||||
"
|
||||
/>
|
||||
</QDialog>
|
||||
</template>
|
||||
<i18n>
|
||||
es:
|
||||
Document: Documento
|
||||
Download file: Descargar archivo
|
||||
Edit document: Editar documento
|
||||
Delete file: Eliminar archivo
|
||||
Create document: Crear documento
|
||||
|
||||
</i18n>
|
|
@ -84,7 +84,7 @@ const mixinRules = [
|
|||
...($attrs.rules ?? []),
|
||||
(val) => {
|
||||
const maxlength = $props.maxlength;
|
||||
if (maxlength && +val.length > maxlength)
|
||||
if (maxlength && +val?.length > maxlength)
|
||||
return t(`maxLength`, { value: maxlength });
|
||||
const { min, max } = vnInputRef.value.$attrs;
|
||||
if (!min) return null;
|
||||
|
|
|
@ -325,7 +325,6 @@ input::-webkit-inner-spin-button {
|
|||
min-height: auto !important;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding-bottom: 2px;
|
||||
.q-field__native.row {
|
||||
min-height: auto !important;
|
||||
}
|
||||
|
|
|
@ -817,6 +817,7 @@ travel:
|
|||
search: Search travel
|
||||
searchInfo: You can search by travel id or name
|
||||
id: Id
|
||||
awbFk: AWB
|
||||
travelList:
|
||||
tableVisibleColumns:
|
||||
ref: Reference
|
||||
|
|
|
@ -900,6 +900,7 @@ travel:
|
|||
search: Buscar envío
|
||||
searchInfo: Buscar envío por id o nombre
|
||||
id: Id
|
||||
awbFk: Guía aérea
|
||||
travelList:
|
||||
tableVisibleColumns:
|
||||
ref: Referencia
|
||||
|
|
|
@ -14,6 +14,8 @@ import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
|||
import VnSelectTravelExtended from 'src/components/common/VnSelectTravelExtended.vue';
|
||||
import VnSelectSupplier from 'src/components/common/VnSelectSupplier.vue';
|
||||
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
||||
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
||||
import VnDmsInput from 'src/components/common/VnDmsInput.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -24,6 +26,7 @@ const user = state.getUser().fn();
|
|||
|
||||
const companiesOptions = ref([]);
|
||||
const currenciesOptions = ref([]);
|
||||
const entryRef = ref({});
|
||||
|
||||
onMounted(() => {
|
||||
checkEntryLock(route.params.id, user.id);
|
||||
|
@ -48,10 +51,11 @@ onMounted(() => {
|
|||
auto-load
|
||||
/>
|
||||
<FormModel
|
||||
:url-update="`Entries/${route.params.id}`"
|
||||
ref="entryRef"
|
||||
model="Entry"
|
||||
auto-load
|
||||
:url-update="`Entries/${route.params.id}`"
|
||||
:clear-store-on-unmount="false"
|
||||
auto-load
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnRow class="q-py-sm">
|
||||
|
@ -67,11 +71,18 @@ onMounted(() => {
|
|||
/>
|
||||
</VnRow>
|
||||
<VnRow class="q-py-sm">
|
||||
<VnInput v-model="data.reference" :label="t('globals.reference')" />
|
||||
<VnInputNumber
|
||||
v-model="data.invoiceAmount"
|
||||
:label="t('entry.summary.invoiceAmount')"
|
||||
:positive="false"
|
||||
<VnInput
|
||||
v-model="data.reference"
|
||||
:label="t('entry.list.tableVisibleColumns.reference')"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.typeFk"
|
||||
url="entryTypes"
|
||||
:fields="['code', 'description']"
|
||||
option-value="code"
|
||||
optionLabel="description"
|
||||
sortBy="description"
|
||||
:label="t('entry.list.tableVisibleColumns.entryTypeDescription')"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow class="q-py-sm">
|
||||
|
@ -113,7 +124,6 @@ onMounted(() => {
|
|||
name="initialTemperature"
|
||||
:label="t('entry.basicData.initialTemperature')"
|
||||
:step="0.5"
|
||||
:decimal-places="2"
|
||||
:positive="false"
|
||||
/>
|
||||
<VnInputNumber
|
||||
|
@ -121,20 +131,21 @@ onMounted(() => {
|
|||
name="finalTemperature"
|
||||
:label="t('entry.basicData.finalTemperature')"
|
||||
:step="0.5"
|
||||
:decimal-places="2"
|
||||
:positive="false"
|
||||
/>
|
||||
<VnSelect
|
||||
v-model="data.typeFk"
|
||||
url="entryTypes"
|
||||
:fields="['code', 'description']"
|
||||
option-value="code"
|
||||
optionLabel="description"
|
||||
sortBy="description"
|
||||
/>
|
||||
</VnRow>
|
||||
<VnRow class="q-py-sm">
|
||||
<QInput
|
||||
<VnInputNumber
|
||||
v-model="data.invoiceAmount"
|
||||
:label="t('entry.list.tableVisibleColumns.invoiceAmount')"
|
||||
:positive="false"
|
||||
@update:model-value="data.buyerFk = user.id"
|
||||
/>
|
||||
<VnSelectWorker v-model="data.buyerFk" hide-selected />
|
||||
<VnDmsInput :data="data" :formRef="entryRef" :disable="false" />
|
||||
</VnRow>
|
||||
<VnRow class="q-py-sm">
|
||||
<VnInputNumber
|
||||
:label="t('entry.basicData.observation')"
|
||||
type="textarea"
|
||||
v-model="data.observation"
|
||||
|
|
|
@ -18,6 +18,7 @@ import VnSelectEnum from 'src/components/common/VnSelectEnum.vue';
|
|||
import { checkEntryLock } from 'src/composables/checkEntryLock';
|
||||
import VnRow from 'src/components/ui/VnRow.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
|
@ -44,6 +45,8 @@ const entityId = ref($props.id ?? route.params.id);
|
|||
const entryBuysRef = ref();
|
||||
const footerFetchDataRef = ref();
|
||||
const footer = ref({});
|
||||
const dialogRef = ref(false);
|
||||
const newEntryRef = ref(null);
|
||||
const columns = [
|
||||
{
|
||||
align: 'center',
|
||||
|
@ -250,6 +253,7 @@ const columns = [
|
|||
component: 'number',
|
||||
attrs: {
|
||||
positive: false,
|
||||
decimalPlaces: 3,
|
||||
},
|
||||
cellEvent: {
|
||||
'update:modelValue': async (value, oldValue, row) => {
|
||||
|
@ -497,6 +501,23 @@ async function setBuyUltimate(itemFk, data) {
|
|||
});
|
||||
}
|
||||
|
||||
async function transferBuys(rows, newEntry) {
|
||||
if (!newEntry) return;
|
||||
|
||||
const promises = rows.map((row) => {
|
||||
return axios.patch('Buys', { id: row.id, entryFk: newEntry });
|
||||
});
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
await axios.post(`Entries/${newEntry}/recalcEntryPrices`);
|
||||
await axios.post(`Entries/${entityId.value}/recalcEntryPrices`);
|
||||
|
||||
entryBuysRef.value.reload();
|
||||
newEntryRef.value = null;
|
||||
dialogRef.value = false;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
stateStore.rightDrawer = false;
|
||||
if ($props.editableMode) checkEntryLock(entityId.value, user.id);
|
||||
|
@ -571,6 +592,47 @@ onMounted(() => {
|
|||
</QItem>
|
||||
</QList>
|
||||
</QBtnDropdown>
|
||||
<QBtn
|
||||
icon="move_group"
|
||||
color="primary"
|
||||
:title="t('Transfer buys')"
|
||||
data-cy="transferBuys"
|
||||
flat
|
||||
@click="dialogRef = true"
|
||||
:disable="!selectedRows.length"
|
||||
/>
|
||||
<QDialog v-model="dialogRef">
|
||||
<QCard>
|
||||
<QCardSection>
|
||||
<span>{{ t('Transfer buys') }}</span>
|
||||
</QCardSection>
|
||||
<QCardSection>
|
||||
<VnInputNumber
|
||||
v-model="newEntryRef"
|
||||
:label="t('Entry')"
|
||||
type="number"
|
||||
data-cy="entryDestinyInput"
|
||||
/>
|
||||
</QCardSection>
|
||||
<QCardSection>
|
||||
<QCardActions>
|
||||
<QBtn
|
||||
label="Cancel"
|
||||
flat
|
||||
color="primary"
|
||||
@click="dialogRef = false"
|
||||
/>
|
||||
<QBtn
|
||||
label="Transfer"
|
||||
data-cy="transferBuysBtn"
|
||||
flat
|
||||
color="primary"
|
||||
@click="transferBuys(selectedRows, newEntryRef)"
|
||||
/>
|
||||
</QCardActions>
|
||||
</QCardSection>
|
||||
</QCard>
|
||||
</QDialog>
|
||||
</QBtnGroup>
|
||||
</Teleport>
|
||||
<FetchData
|
||||
|
@ -620,7 +682,7 @@ onMounted(() => {
|
|||
},
|
||||
columnGridStyle: {
|
||||
'max-width': '50%',
|
||||
'margin-right': '30px',
|
||||
'margin-right': '5%',
|
||||
flex: 1,
|
||||
},
|
||||
previousStyle: {
|
||||
|
@ -816,6 +878,8 @@ es:
|
|||
Create buy: Crear compra
|
||||
Invert quantity value: Invertir valor de cantidad
|
||||
Check buy amount: Marcar como correcta la cantidad de compra
|
||||
Transfer buys: Transferir compras
|
||||
Entry: Entrada
|
||||
</i18n>
|
||||
<style lang="scss" scoped>
|
||||
.centered-container {
|
||||
|
|
|
@ -92,7 +92,7 @@ const getEntryRedirectionFilter = (entry) => {
|
|||
};
|
||||
|
||||
function showEntryReport() {
|
||||
openReport(`Entries/${entityId.value}/entry-order-pdf`);
|
||||
openReport(`Entries/${entityId.value}/entry-order-pdf`, {}, true);
|
||||
}
|
||||
|
||||
function showNotification(type, message) {
|
||||
|
@ -147,7 +147,7 @@ async function deleteEntry() {
|
|||
<template>
|
||||
<EntityDescriptor
|
||||
:url="`Entries/${entityId}`"
|
||||
:filter="entryFilter"
|
||||
:user-filter="entryFilter"
|
||||
title="supplier.nickname"
|
||||
data-key="Entry"
|
||||
width="lg-width"
|
||||
|
|
|
@ -84,7 +84,10 @@ onMounted(async () => {
|
|||
:label="t('globals.company')"
|
||||
:value="entry?.company?.code"
|
||||
/>
|
||||
<VnLv :label="t('globals.reference')" :value="entry?.reference" />
|
||||
<VnLv
|
||||
:label="t('entry.list.tableVisibleColumns.reference')"
|
||||
:value="entry?.reference"
|
||||
/>
|
||||
<VnLv
|
||||
:label="t('entry.summary.invoiceNumber')"
|
||||
:value="entry?.invoiceNumber"
|
||||
|
@ -159,6 +162,7 @@ onMounted(async () => {
|
|||
/>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<VnLv :label="t('travel.awbFk')" :value="entry.travel.awbFk" />
|
||||
<VnCheckbox
|
||||
:label="t('entry.summary.travelDelivered')"
|
||||
v-model="entry.travel.isDelivered"
|
||||
|
|
|
@ -162,8 +162,8 @@ async function beforeSave(data, getChanges) {
|
|||
}
|
||||
|
||||
await Promise.all(patchPromises);
|
||||
const filteredChanges = changes.filter((change) => change?.isReal !== false);
|
||||
data.creates = filteredChanges;
|
||||
data.creates = [];
|
||||
return data;
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
|
@ -203,7 +203,7 @@ async function beforeSave(data, getChanges) {
|
|||
</VnRow>
|
||||
</template>
|
||||
</VnSubToolbar>
|
||||
<QDialog v-model="travelDialogRef" :maximized="true" :class="['vn-row', 'wrap']">
|
||||
<QDialog v-model="travelDialogRef" :class="['vn-row', 'wrap']">
|
||||
<FormModelPopup
|
||||
:url-update="`Travels/${travel?.id}`"
|
||||
model="travel"
|
||||
|
@ -252,12 +252,15 @@ async function beforeSave(data, getChanges) {
|
|||
</span>
|
||||
</template>
|
||||
<template #column-footer-reserve>
|
||||
<span>
|
||||
<span class="q-pr-xs">
|
||||
{{ round(footer.reserve) }}
|
||||
</span>
|
||||
</template>
|
||||
<template #column-footer-bought>
|
||||
<span :style="boughtStyle(footer?.bought, footer?.reserve)">
|
||||
<span
|
||||
:style="boughtStyle(footer?.bought, footer?.reserve)"
|
||||
class="q-pr-xs"
|
||||
>
|
||||
{{ round(footer.bought) }}
|
||||
</span>
|
||||
</template>
|
||||
|
@ -275,7 +278,7 @@ async function beforeSave(data, getChanges) {
|
|||
}
|
||||
.column {
|
||||
min-width: 35%;
|
||||
margin-top: 5%;
|
||||
margin-top: 1%;
|
||||
}
|
||||
.text-negative {
|
||||
color: $negative !important;
|
||||
|
|
|
@ -25,7 +25,7 @@ entry:
|
|||
entryTypeDescription: Tipo entrada
|
||||
invoiceAmount: Importe
|
||||
dated: Fecha
|
||||
inventoryEntry: Es inventario
|
||||
inventoryEntry: Es inventario
|
||||
summary:
|
||||
commission: Comisión
|
||||
currency: Moneda
|
||||
|
@ -33,7 +33,8 @@ entry:
|
|||
invoiceAmount: Importe
|
||||
ordered: Pedida
|
||||
booked: Contabilizada
|
||||
excludedFromAvailable: Excluido
|
||||
excludedFromAvailable: Excluir del disponible
|
||||
isConfirmed: Lista para etiquetar
|
||||
travelReference: Referencia
|
||||
travelAgency: Agencia
|
||||
travelShipped: F. envio
|
||||
|
@ -56,7 +57,7 @@ entry:
|
|||
observation: Observación
|
||||
commission: Comisión
|
||||
booked: Contabilizada
|
||||
excludedFromAvailable: Excluido
|
||||
excludedFromAvailable: Excluir del disponible
|
||||
initialTemperature: Ini °C
|
||||
finalTemperature: Fin °C
|
||||
buys:
|
||||
|
@ -119,9 +120,9 @@ entry:
|
|||
supplierName: Proveedor
|
||||
entryFilter:
|
||||
params:
|
||||
isExcludedFromAvailable: Excluido
|
||||
isExcludedFromAvailable: Excluir del disponible
|
||||
isOrdered: Pedida
|
||||
isConfirmed: Confirmado
|
||||
isConfirmed: Lista para etiquetar
|
||||
isReceived: Recibida
|
||||
isRaid: Raid
|
||||
landed: Fecha
|
||||
|
|
|
@ -36,7 +36,7 @@ const warehousesOptionsIn = ref([]);
|
|||
auto-load
|
||||
:filter="{ where: { isDestiny: TRUE } }"
|
||||
/>
|
||||
<FormModel :url-update="`Travels/${route.params.id}`" model="Travel" auto-load>
|
||||
<FormModel :url-update="`Travels/${route.params.id}`" model="Travel">
|
||||
<template #form="{ data }">
|
||||
<VnRow>
|
||||
<VnInput v-model="data.ref" :label="t('globals.reference')" />
|
||||
|
@ -57,8 +57,8 @@ const warehousesOptionsIn = ref([]);
|
|||
<VnRow>
|
||||
<VnInputDate
|
||||
v-model="data.availabled"
|
||||
:label="t('travel.summary.availabled')"
|
||||
/>
|
||||
:label="t('travel.summary.availabled')"
|
||||
/>
|
||||
<VnInputTime
|
||||
v-model="data.availabled"
|
||||
:label="t('travel.summary.availabledHour')"
|
||||
|
@ -96,6 +96,7 @@ const warehousesOptionsIn = ref([]);
|
|||
</QIcon>
|
||||
</template>
|
||||
</VnInput>
|
||||
<VnInput v-model="data.awbFk" :label="t('travel.awbFk')" />
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<QCheckbox v-model="data.isRaid" :label="t('travel.basicData.isRaid')" />
|
||||
|
|
|
@ -12,6 +12,7 @@ export default {
|
|||
'isRaid',
|
||||
'daysInForward',
|
||||
'availabled',
|
||||
'awbFk',
|
||||
],
|
||||
include: [
|
||||
{
|
||||
|
|
|
@ -80,6 +80,11 @@ describe('EntryBuys', () => {
|
|||
checkColor('amount', COLORS.positive);
|
||||
cy.saveCard();
|
||||
|
||||
cy.get('tbody > tr [tabindex="0"][role="checkbox"]').click();
|
||||
cy.dataCy('transferBuys').should('be.enabled').click();
|
||||
cy.dataCy('entryDestinyInput').should('be.visible').type('100');
|
||||
cy.dataCy('transferBuysBtn').click();
|
||||
|
||||
cy.deleteEntry();
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue