feat: refs #8945 add Fixed Asset management components
gitea/salix-front/pipeline/pr-dev There was a failure building this commit Details

This commit is contained in:
Jose Antonio Tubau 2025-05-05 15:04:58 +02:00
parent 47bde21df5
commit ca0d90c07e
10 changed files with 1463 additions and 0 deletions

View File

@ -0,0 +1,215 @@
<script setup>
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { ref } from 'vue';
import FormModel from 'components/FormModel.vue';
import VnRow from 'components/ui/VnRow.vue';
import VnSelect from 'components/common/VnSelect.vue';
import VnInput from 'components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
import { toCurrency } from 'src/filters';
import FetchData from 'src/components/FetchData.vue';
const { t } = useI18n();
const route = useRoute();
const isNew = Boolean(!route.params.id);
const natureOptions = ref([]);
const prueba = ref();
</script>
<template>
<FetchData
url="Ppes/getNatures"
@on-fetch="(data) => (natureOptions = data)"
auto-load
/>
<VnSubToolbar v-if="isNew" />
<div class="q-pa-md">
<FormModel :url-update="`Ppes/${route.params.id}`" model="FixedAsset" auto-load>
<template #form="{ data }">
<VnRow>
<VnInput
:label="t('globals.description')"
v-model="data.description"
fill-input
/>
</VnRow>
<VnRow>
<VnSelect
url="companies"
:label="t('globals.company')"
v-model="data.companyFk"
option-value="id"
option-label="code"
hide-selected
/>
<VnSelect
:label="t('fixedAsset.nature')"
v-model="data.nature"
:options="natureOptions"
option-value="nature"
option-label="nature"
hide-selected
/>
<VnInputNumber
:label="t('fixedAsset.value')"
v-model="data.value"
fill-input
/>
</VnRow>
<VnRow>
<VnSelect
url="Ppes/getSubAccounts"
:label="t('fixedAsset.account')"
v-model="data.account"
option-value="code"
option-label="code"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.description}`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.code}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnSelect
url="Ppes/getEndowments"
:label="t('fixedAsset.endowment')"
v-model="data.endowment"
option-value="code"
option-label="code"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.description}`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.code}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnAccountNumber
:label="t('fixedAsset.elementAccount')"
v-model="data.elementAccount"
fill-input
/>
</VnRow>
<VnRow>
<VnSelect
url="PpeLocations"
:label="t('fixedAsset.location')"
v-model="data.locationFk"
option-value="code"
:option-label="(value) => `${value.code} - ${value.description}`"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.description}`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.code}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnSelect
url="PpeGroups"
:label="t('globals.group')"
v-model="data.groupFk"
option-value="id"
option-label="description"
hide-selected
/>
</VnRow>
<VnRow>
<VnInputDate
:label="t('fixedAsset.firstAmortizated')"
v-model="data.firstAmortizated"
placeholder="dd-mm-aaaa"
fill-input
/>
<VnInputDate
:label="t('fixedAsset.lastAmortizated')"
v-model="data.lastAmortizated"
placeholder="dd-mm-aaaa"
fill-input
/>
</VnRow>
<VnRow>
<VnInputDate
:label="t('fixedAsset.finished')"
v-model="data.finished"
placeholder="dd-mm-aaaa"
fill-input
/>
<VnInputNumber
:label="t('fixedAsset.amortization')"
v-model="data.amortization"
fill-input
/>
<VnSelect
url="PpePlans"
:label="t('fixedAsset.plan')"
v-model="data.planFk"
:option-label="(value) => `${value.rate}% - ${value.days} days`"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.rate}% - ${scope.opt?.days} days`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.id}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</VnRow>
<VnRow>
<VnInputDate
:label="t('fixedAsset.discharged')"
v-model="data.discharged"
placeholder="dd-mm-aaaa"
fill-input
/>
<VnInput
:label="t('fixedAsset.cause')"
v-model="data.cause"
fill-input
/>
</VnRow>
<VnRow>
<VnCheckbox
v-model="data.isInvestmentAsset"
:label="t('fixedAsset.isInvestmentAsset')"
/>
<VnCheckbox :label="t('fixedAsset.isDone')" v-model="data.isDone" />
</VnRow>
</template>
</FormModel>
</div>
</template>

View File

@ -0,0 +1,12 @@
<script setup>
import VnCard from 'components/common/VnCard.vue';
import FixedAssetDescriptor from 'pages/FixedAsset/Card/FixedAssetDescriptor.vue';
</script>
<template>
<VnCard
data-key="FixedAsset"
url="Ppes"
:descriptor="FixedAssetDescriptor"
:filter="{ where: { id: $route.params.id } }"
/>
</template>

View File

@ -0,0 +1,103 @@
<script setup>
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import CardDescriptor from 'src/components/ui/CardDescriptor.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import FixedAssetCard from './FixedAssetCard.vue';
import EditPictureForm from 'src/components/EditPictureForm.vue';
import VnImg from 'src/components/ui/VnImg.vue';
import FixedAssetDescriptorMenu from './FixedAssetDescriptorMenu.vue';
const route = useRoute();
const entityId = computed(() => {
return Number(props.id || route.params.id);
});
const props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
summary: {
type: Object,
default: null,
},
});
const image = ref(null);
const showEditPhotoForm = ref(false);
const toggleEditPictureForm = () => {
showEditPhotoForm.value = !showEditPhotoForm.value;
};
</script>
<template>
<CardDescriptor
v-bind="$attrs"
:id="entityId"
:card="FixedAssetCard"
title="description"
module="FixedAsset"
>
<template #before>
<div class="relative-position">
<VnImg
ref="image"
:id="parseInt(entityId)"
collection="fixedAsset"
resolution="520x520"
class="photo"
>
<template #error>
<div
class="absolute-full picture text-center q-pa-md flex flex-center"
>
<div>
<div
class="text-grey-5"
style="opacity: 0.4; font-size: 5vh"
>
<QIcon name="vn:claims" />
</div>
<div class="text-grey-5" style="opacity: 0.4">
{{ t('fixedAsset.imageNotFound') }}
</div>
</div>
</div>
</template> </VnImg
><QBtn
color="primary"
size="lg"
round
class="edit-photo-btn"
@click="toggleEditPictureForm()"
>
<QIcon name="edit" size="sm" />
<QDialog ref="editPhotoFormDialog" v-model="showEditPhotoForm">
<EditPictureForm
collection="fixedAsset"
:id="entityId"
@close-form="toggleEditPictureForm()"
@on-photo-uploaded="handlePhotoUpdated"
/>
</QDialog>
</QBtn>
</div>
</template>
<template #body="{ entity }">
<VnLv
:label="$t('fixedAsset.elementAccount')"
:value="entity.elementAccount"
copy
/>
<VnLv
:label="$t('fixedAsset.location')"
:value="entity.location.description"
/>
</template>
<template #menu="{ entity }">
<FixedAssetDescriptorMenu :fixedAsset="entity" />
</template>
</CardDescriptor>
</template>

View File

@ -0,0 +1,47 @@
<script setup>
import axios from 'axios';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import VnConfirm from 'components/ui/VnConfirm.vue';
const props = defineProps({
fixedAsset: {
type: Object,
required: true,
},
});
const router = useRouter();
const quasar = useQuasar();
const { t } = useI18n();
const fixedAssetId = props.fixedAsset.id;
function confirmRemove() {
quasar
.dialog({
component: VnConfirm,
componentProps: {
title: t('fixedAsset.confirmDeletion'),
message: t('fixedAsset.confirmDeletionMessage'),
promise: remove,
},
})
.onOk(async () => await router.push({ name: 'FixedAssetList' }));
}
async function remove() {
await axios.delete(`Ppes/${fixedAssetId}`);
quasar.notify({
message: t('globals.dataDeleted'),
type: 'positive',
});
}
</script>
<template>
<QItem @click="confirmRemove" v-ripple clickable>
<QItemSection avatar>
<QIcon name="delete" />
</QItemSection>
<QItemSection>{{ t('fixedAsset.delete') }}</QItemSection>
</QItem>
</template>

View File

@ -0,0 +1,24 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import VnDmsList from 'src/components/common/VnDmsList.vue';
const { t } = useI18n();
const dmsListRef = ref(null);
const showImportDialog = ref(false);
const onDataSaved = () => dmsListRef.value.dmsRef.fetch();
</script>
<template>
<VnDmsList
ref="dmsListRef"
model="PpeDms"
update-model="PpeDms"
delete-model="PpeDms"
download-model="dms"
default-dms-code="fixedAssets"
filter="ppeFk"
/>
</template>

View File

@ -0,0 +1,140 @@
<script setup>
import VnTable from 'src/components/VnTable/VnTable.vue';
import InvoiceInDescriptorProxy from 'pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import { toDate, toCurrency } from 'src/filters/index';
import { useRoute } from 'vue-router';
import { ref, computed } from 'vue';
import { useVnConfirm } from 'composables/useVnConfirm';
import { useI18n } from 'vue-i18n';
import useNotify from 'src/composables/useNotify.js';
import axios from 'axios';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
const tableRef = ref();
const { t } = useI18n();
const route = useRoute();
const { notify } = useNotify();
const dataKey = 'fixedAssetInvoiceIn';
const { openConfirmationModal } = useVnConfirm();
const columns = computed(() => [
{
align: 'left',
name: 'issued',
label: t('invoiceIn.list.issued'),
columnFilter: {
component: 'date',
},
format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.issued)),
cardVisible: true,
},
{
align: 'left',
name: 'supplierFk',
label: t('invoiceIn.list.supplier'),
columnFilter: {
component: 'select',
attrs: {
url: 'Suppliers',
fields: ['id', 'name'],
},
},
format: ({ supplierName }) => supplierName,
columnClass: 'expand',
cardVisible: true,
},
{
align: 'left',
name: 'supplierRef',
label: t('invoiceIn.supplierRef'),
cardVisible: true,
},
{
align: 'left',
name: 'amount',
label: t('invoiceIn.list.amount'),
format: ({ amount }) => toCurrency(amount),
columnFilter: false,
cardVisible: true,
},
{
align: 'right',
name: 'tableActions',
actions: [
{
title: t('fixedAsset.invoice.unassignInvoice'),
icon: 'delete',
action: (row) =>
openConfirmationModal(
t('fixedAsset.invoice.unassignInvoice'),
t('fixedAsset.invoice.unassignInvoiceConfirmation'),
() => unassignInvoice(row.id),
),
isPrimary: true,
},
],
},
]);
async function unassignInvoice(id) {
try {
await axios.delete(`PpeComponents/${id}`);
notify(t('fixedAsset.invoice.unassignedInvoice'), 'positive');
tableRef.value.reload();
} catch (e) {
throw e;
}
}
</script>
<template>
<VnTable
ref="tableRef"
:data-key="dataKey"
:url="`ppes/${route.params.id}/getInvoices`"
:columns="columns"
search-url="fixedAssetInvoiceIns"
:order="['issued DESC', 'supplierRef ASC']"
:create="{
urlCreate: 'ppeComponents',
title: t('fixedAsset.invoice.assignInvoice'),
formInitialData: {
ppeFk: parseInt(route.params.id, 10),
},
onDataSaved: ( {id} ) => tableRef.reload(),
}"
auto-load
>
<template #column-supplierFk="{ row }">
<span class="link" @click.stop>
{{ row.supplierName }}
<SupplierDescriptorProxy :id="row.supplierId" />
</span>
</template>
<template #column-supplierRef="{ row }">
<span class="link" @click.stop>
{{ row.supplierRef }}
<InvoiceInDescriptorProxy :id="row.invoiceInFk" />
</span>
</template>
<template #more-create-dialog="{ data }">
<VnSelect
url="invoiceIns"
:label="t('invoiceIn.supplierRef')"
:fields="['id', 'supplierRef', 'supplierFk']"
:filter-options="['id', 'supplierRef']"
v-model="data.invoiceInFk"
option-label="supplierRef"
:required="true"
>
</VnSelect>
<VnInputNumber
:label="t('invoiceIn.list.amount')"
v-model="data.amount"
required
/>
</template>
</VnTable>
</template>

View File

@ -0,0 +1,6 @@
<script setup>
import VnLog from 'src/components/common/VnLog.vue';
</script>
<template>
<VnLog model="Ppe" url="/FixedAssetLogs" />
</template>

View File

@ -0,0 +1,345 @@
<script setup>
import { onMounted, ref, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { dashIfEmpty, toDate, toCurrency } from 'src/filters';
import { getTotal } from 'src/composables/getTotal';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import { getUrl } from 'src/composables/getUrl';
import VnTitle from 'src/components/common/VnTitle.vue';
import VnToSummary from 'src/components/ui/VnToSummary.vue';
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import InvoiceInDescriptorProxy from 'src/pages/InvoiceIn/Card/InvoiceInDescriptorProxy.vue';
import FixedAssetDescriptorMenu from './FixedAssetDescriptorMenu.vue';
const route = useRoute();
const { t } = useI18n();
const $props = defineProps({
id: {
type: Number,
default: null,
},
});
const dmsColumns = ref([
{
align: 'left',
label: t('globals.id'),
name: 'id',
field: ({ id }) => id,
},
{
align: 'left',
label: t('globals.type'),
name: 'type',
field: ({ type }) => type?.name,
},
{
align: 'left',
label: t('globals.order'),
name: 'order',
field: ({ hardCopyNumber }) => dashIfEmpty(hardCopyNumber),
},
{
align: 'left',
label: t('globals.reference'),
name: 'reference',
field: ({ reference }) => dashIfEmpty(reference),
},
{
align: 'left',
label: t('globals.description'),
name: 'description',
field: ({ description }) => dashIfEmpty(description),
},
{
align: 'left',
label: t('globals.original'),
name: 'hasFile',
toolTip: t('The documentation is available in paper form'),
component: 'checkbox',
field: ({ hasFile }) => hasFile,
},
{
align: 'left',
label: t('globals.worker'),
name: 'worker',
field: ({ worker }) => worker?.name,
},
{
align: 'left',
label: t('globals.created'),
name: 'created',
field: ({ created }) => toDate(created),
},
]);
const entityId = computed(() => $props.id || route.params.id);
const summary = ref();
const fixedAssetUrl = ref();
onMounted(async () => {
fixedAssetUrl.value = (await getUrl('fixedAsset/')) + entityId.value + '/';
});
function toFixedAssetUrl(section) {
return '#/fixedAsset/' + entityId.value + '/' + section;
}
</script>
<template>
<CardSummary
ref="summary"
:url="`Ppes/${entityId}/summary`"
data-key="FixedAssetSummary"
v-bind="$attrs.width"
>
<template #header-left>
<VnToSummary
v-if="route?.name !== 'FixedAssetSummary'"
:route-name="'FixedAssetSummary'"
:entity-id="entityId"
:url="FixedAssetUrl"
/>
</template>
<template #header="{ entity }">
<div>Fixed asset #{{ entity.id }} - {{ entity.description }}</div>
</template>
<template #menu="{ entity }">
<FixedAssetDescriptorMenu :fixedAsset="entity" />
</template>
<template #body="{ entity }">
<QCard class="vn-two">
<VnTitle
:url="toFixedAssetUrl('basic-data')"
:text="t('globals.summary.basicData')"
data-cy="titleBasicDataBlock1"
/>
<div class="vn-card-group">
<div class="vn-card-content">
<VnLv
:label="t('globals.description')"
:value="dashIfEmpty(entity.description)"
/>
<VnLv
:label="t('globals.company')"
:value="entity.company.code"
/>
<VnLv
:label="t('fixedAsset.account')"
:value="entity.account"
copy
/>
<VnLv
:label="t('fixedAsset.endowment')"
:value="entity.endowment"
copy
/>
<VnLv
:label="t('fixedAsset.elementAccount')"
:value="entity.elementAccount"
copy
/>
<VnLv
:label="t('fixedAsset.nature')"
:value="dashIfEmpty(entity.nature)"
/>
<VnLv
:label="t('fixedAsset.location')"
:value="
dashIfEmpty(
`${entity.location.code} - ${entity.location.description}`,
)
"
/>
<VnLv
:label="t('globals.group')"
:value="dashIfEmpty(entity.group.description)"
/>
<VnLv
:label="t('fixedAsset.isInvestmentAsset')"
:value="entity.isInvestmentAsset"
/>
</div>
</div>
</QCard>
<QCard class="vn-two">
<VnTitle
:url="toFixedAssetUrl('basic-data')"
:text="t('globals.summary.basicData')"
data-cy="titleBasicDataBlock2"
/>
<div class="vn-card-content">
<VnLv
:label="t('fixedAsset.value')"
:value="dashIfEmpty(toCurrency(entity.value))"
copy
/>
<VnLv
:label="$t('fixedAsset.firstAmortizated')"
:tooltip="$t('fixedAsset.firstAmortizatedTooltip')"
:value="dashIfEmpty(toDate(entity.firstAmortizated))"
/>
<VnLv
:label="t('fixedAsset.lastAmortizated')"
:tooltip="t('fixedAsset.lastAmortizatedTooltip')"
:value="dashIfEmpty(toDate(entity.lastAmortizated))"
/>
<VnLv
:label="$t('fixedAsset.finished')"
:tooltip="$t('fixedAsset.finishedTooltip')"
:value="dashIfEmpty(toDate(entity.finished))"
/>
<VnLv
:label="t('fixedAsset.amortization')"
:value="dashIfEmpty(toCurrency(entity.amortization))"
/>
<VnLv
:label="t('fixedAsset.plan')"
:value="
dashIfEmpty(`${entity.plan.rate}% - ${entity.plan.days}days`)
"
/>
<VnLv
:label="t('fixedAsset.discharged')"
:value="dashIfEmpty(toDate(entity.discharged))"
/>
<VnLv
:label="t('fixedAsset.cause')"
:value="dashIfEmpty(entity.cause)"
/>
<VnLv :label="t('fixedAsset.isDone')" :value="entity.isDone" />
</div>
</QCard>
<QCard v-if="entity?.ppeDms?.length > 0" class="vn-two">
<VnTitle
:url="toFixedAssetUrl('dms')"
:text="t('globals.pageTitles.dms')"
data-cy="titleDmsBlock"
/>
<QTable :columns="dmsColumns" :rows="entity?.ppeDms" flat>
<template #header="props">
<QTr :props="props">
<QTh auto-width class="text-left">{{ t('globals.id') }}</QTh>
<QTh auto-width class="text-left">{{
t('globals.type')
}}</QTh>
<QTh auto-width class="text-left">{{
t('globals.order')
}}</QTh>
<QTh auto-width class="text-left">{{
t('globals.reference')
}}</QTh>
<QTh auto-width class="text-left">{{
t('globals.description')
}}</QTh>
<QTh auto-width class="text-center">{{
t('globals.original')
}}</QTh>
<QTh auto-width class="text-left">{{
t('globals.worker')
}}</QTh>
<QTh auto-width class="text-center">{{
t('globals.created')
}}</QTh>
</QTr>
</template>
<template #body="props">
<QTr :props="props">
<QTd class="text-left">{{ props.row.dms.id }}</QTd>
<QTd class="text-left">{{ props.row.dms.dmsType.name }}</QTd>
<QTd class="text-left">{{
props.row.dms.hardCopyNumber
}}</QTd>
<QTd class="text-left">{{ props.row.dms.reference }}</QTd>
<QTd class="text-left">{{ props.row.dms.description }}</QTd>
<QTd class="text-center"
><VnCheckbox
:disable="true"
v-model="props.row.dms.hasFile"
/></QTd>
<QTd class="text-left"
><span class="link" @click.stop
>{{ props.row.dms.worker.firstName
}}<WorkerDescriptorProxy
:id="props.row.dms.worker.id" /></span
></QTd>
<QTd class="text-center">{{
toDate(props.row.dms.created)
}}</QTd>
</QTr>
</template>
</QTable>
</QCard>
<QCard v-if="entity.ppeComponents?.length > 0" class="vn-two">
<VnTitle
:url="toFixedAssetUrl('invoice-in')"
:text="$t('vehicle.ticket.assignedInvoices')"
/>
<QTable :rows="entity.ppeComponents" style="text-align: center">
<template #body-cell="{ value }">
<QTd>{{ value }}</QTd>
</template>
<template #header="props">
<QTr class="tr-header" :props="props">
<QTh auto-width>{{ $t('invoiceIn.list.issued') }}</QTh>
<QTh auto-width>{{ $t('invoiceIn.list.supplier') }}</QTh>
<QTh auto-width>{{ $t('invoiceIn.supplierRef') }}</QTh>
<QTh auto-width>{{ $t('invoiceIn.list.amount') }}</QTh>
</QTr>
</template>
<template #body="props">
<QTr :props="props">
<QTd>{{ toDate(props.row.invoiceIn.issued) }}</QTd>
<QTd>
<span class="link">
{{ props.row.invoiceIn.supplier.name }}
<SupplierDescriptorProxy :id="props.row.supplierFk" />
</span>
</QTd>
<QTd>
<span class="link">
{{ props.row.invoiceInFk }}
<InvoiceInDescriptorProxy
:id="props.row.invoiceInFk"
/>
</span>
</QTd>
<QTd>{{ toCurrency(props.row.amount) }}</QTd>
</QTr>
</template>
<template #bottom-row>
<QTr class="bg">
<QTd></QTd>
<QTd></QTd>
<QTd></QTd>
<QTd>
{{ toCurrency(getTotal(entity.ppeComponents, 'amount')) }}
</QTd>
</QTr>
</template>
</QTable>
</QCard>
</template>
</CardSummary>
</template>
<style lang="scss" scoped>
.q-card.q-card--dark.q-dark.vn-one {
& > .bodyCard {
padding: 1%;
}
}
.q-table {
tr,
th,
.q-td {
border-bottom: 1px solid black;
}
}
</style>

View File

@ -0,0 +1,207 @@
<script setup>
import { useI18n } from 'vue-i18n';
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnInputDate from 'components/common/VnInputDate.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
const { t } = useI18n();
const props = defineProps({
dataKey: {
type: String,
required: true,
},
});
</script>
<template>
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
<template #tags="{ tag, formatFn }">
<div class="q-gutter-x-xs">
<strong>{{ t(`fixedAsset.params.${tag.label}`) }}: </strong>
<span>{{ formatFn(tag.value) }}</span>
</div>
</template>
<template #body="{ params, searchFn }">
<QItem>
<QItemSection>
<VnInput
v-model="params.id"
:label="t('globals.id')"
dense
filled
data-cy="idInput"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInput
v-model="params.description"
:label="t('globals.description')"
dense
filled
data-cy="nameInput"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnSelect
url="Companies"
:label="t('globals.company')"
v-model="params.companyFk"
option-value="id"
option-label="code"
dense
filled
data-cy="fixedAssetGroupSelect"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInputDate
v-model="params.firstAmortizated"
:label="t('fixedAsset.firstAmortizated')"
dense
filled
data-cy="firstAmortizatedDateInput"
/>
</QItemSection>
<QItemSection>
<VnInputDate
v-model="params.lastAmortizated"
:label="t('fixedAsset.lastAmortizated')"
dense
filled
data-cy="lastAmortizatedDateInput"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnInputDate
v-model="params.finished"
:label="t('fixedAsset.finished')"
dense
filled
data-cy="finishedDateInput"
/>
</QItemSection>
<QItemSection>
<VnInputDate
v-model="params.discharged"
:label="t('fixedAsset.discharged')"
dense
filled
data-cy="dischargedDateInput"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnSelect
url="Ppes/getNatures"
:label="t('fixedAsset.nature')"
v-model="params.nature"
option-value="nature"
option-label="nature"
dense
filled
data-cy="natureSelect"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnSelect
url="PpePlans"
:label="t('fixedAsset.plan')"
v-model="params.planFk"
:option-label="(value) => `${value.rate}% - ${value.days} days`"
dense
filled
data-cy="planSelect"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.rate}% - ${scope.opt?.days} days`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.id}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnSelect
url="PpeGroups"
:label="t('globals.group')"
v-model="params.groupFk"
option-value="id"
option-label="description"
dense
filled
data-cy="groupSelect"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnSelect
url="PpeLocations"
:label="t('fixedAsset.location')"
v-model="params.locationFk"
option-value="code"
:option-label="(value) => `${value.code} - ${value.description}`"
dense
filled
data-cy="locationSelect"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{ scope.opt?.description }}</QItemLabel>
<QItemLabel caption>
{{ scope.opt?.code }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnCheckbox
v-model="params.isInvestmentAsset"
:label="t('fixedAsset.isInvestmentAsset')"
dense
filled
data-cy="isInvestmentAssetCheckbox"
/>
</QItemSection>
</QItem>
<QItem>
<QItemSection>
<VnCheckbox
v-model="params.isDone"
:label="t('fixedAsset.isDone')"
dense
filled
data-cy="isDoneCheckbox"
/>
</QItemSection>
</QItem>
</template>
</VnFilterPanel>
</template>

View File

@ -0,0 +1,364 @@
<script setup>
import { computed, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useState } from 'src/composables/useState';
import VnTable from 'src/components/VnTable/VnTable.vue';
import VnSection from 'src/components/common/VnSection.vue';
import { dashIfEmpty, toCurrency, toDate } from 'src/filters';
import FixedAssetFilter from './FixedAssetFilter.vue';
import VnInput from 'src/components/common/VnInput.vue';
import VnRow from 'src/components/ui/VnRow.vue';
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
import VnSelect from 'src/components/common/VnSelect.vue';
import VnInputDate from 'src/components/common/VnInputDate.vue';
import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
const user = useState().getUser();
const { t } = useI18n();
const tableRef = ref();
const dataKey = 'FixedAssetList';
const columns = computed(() => [
{
align: 'right',
name: 'id',
label: t('globals.id'),
width: '35px',
chip: {
condition: () => true,
},
isId: true,
},
{
align: 'left',
name: 'description',
label: t('globals.description'),
cardVisible: true,
columnClass: 'expand',
},
{
name: 'companyFk',
label: t('globals.company'),
component: 'select',
attrs: {
url: 'companies',
optionValue: 'code',
},
format: ({ company }) => company?.code,
cardVisible: true,
},
{
name: 'value',
label: t('fixedAsset.value'),
component: 'number',
format: ({ value }) => toCurrency(value),
cardVisible: true,
},
{
align: 'center',
name: 'firstAmortizated',
label: t('fixedAsset.firstAmortizated'),
toolTip: t('fixedAsset.firstAmortizatedTooltip'),
component: 'date',
format: ({ firstAmortizated }) => dashIfEmpty(toDate(firstAmortizated)),
cardVisible: true,
},
{
align: 'center',
name: 'lastAmortizated',
label: t('fixedAsset.lastAmortizated'),
toolTip: t('fixedAsset.lastAmortizatedTooltip'),
component: 'date',
format: ({ lastAmortizated }) => dashIfEmpty(toDate(lastAmortizated)),
cardVisible: true,
},
{
align: 'center',
name: 'finished',
label: t('fixedAsset.finished'),
toolTip: t('fixedAsset.finishedTooltip'),
component: 'date',
format: ({ finished }) => dashIfEmpty(toDate(finished)),
cardVisible: true,
},
{
align: 'center',
name: 'discharged',
label: t('fixedAsset.discharged'),
toolTip: t('fixedAsset.dischargedTooltip'),
component: 'date',
format: ({ discharged }) => dashIfEmpty(toDate(discharged)),
cardVisible: true,
},
{
name: 'amortization',
label: t('fixedAsset.amortization'),
component: 'number',
format: ({ amortization }) => toCurrency(amortization),
cardVisible: true,
},
{
name: 'nature',
label: t('fixedAsset.nature'),
component: 'select',
attrs: {
url: 'Ppes/getNatures',
optionValue: 'nature',
optionLabel: 'nature',
},
format: ({ nature }) => dashIfEmpty(nature),
cardVisible: true,
},
{
name: 'plan',
label: t('fixedAsset.plan'),
toolTip: t('fixedAsset.planTooltip'),
component: 'select',
attrs: {
url: 'PpePlans',
optionValue: 'rate',
optionLabel: 'days',
},
format: ({ plan }) => dashIfEmpty(`${plan?.rate * 100}% - ${plan?.days} days`),
cardVisible: true,
},
{
name: 'group',
label: t('globals.group'),
component: 'select',
attrs: {
url: 'PpeGroups',
optionValue: 'id',
optionLabel: 'description',
},
format: ({ group }) => dashIfEmpty(group?.description),
cardVisible: true,
},
{
name: 'locationFk',
label: t('fixedAsset.location'),
component: 'select',
attrs: {
url: 'PpeLocations',
optionValue: 'code',
optionLabel: 'description',
},
format: ({ location }) =>
dashIfEmpty(`${location?.code} - ${location?.description}`),
cardVisible: true,
},
{
labelAbbreviation: t('fixedAsset.isInvestmentAssetAbbr'),
label: t('fixedAsset.isInvestmentAsset'),
toolTip: t('fixedAsset.isInvestmentAsset'),
name: 'isInvestmentAsset',
component: 'checkbox',
cardVisible: true,
},
{
labelAbbreviation: t('fixedAsset.isDoneAbbr'),
label: t('fixedAsset.isDone'),
toolTip: t('fixedAsset.isDone'),
name: 'isDone',
component: 'checkbox',
cardVisible: true,
},
]);
</script>
<template>
<VnSection
:data-key="dataKey"
:columns="columns"
prefix="fixedAsset"
:array-data-props="{
url: 'ppes/filter',
}"
>
<template #advanced-menu>
<FixedAssetFilter :data-key="dataKey" />
</template>
<template #body>
<VnTable
ref="tableRef"
:data-key="dataKey"
:columns="columns"
redirect="fixedAsset"
:create="{
urlCreate: 'Ppes/createFixedAsset',
title: t('fixedAsset.createFixedAsset'),
onDataSaved: ({ id }) => tableRef.redirect(id),
formInitialData: {
nature: 'INMOVILIZADO',
companyFk: user.companyFk,
},
}"
:right-search="false"
:column-search="false"
>
<template #more-create-dialog="{ data }">
<div class="col-span-2">
<VnRow>
<VnInput
v-model="data.id"
:label="$t('globals.id')"
required
/>
<VnInputNumber
v-model="data.value"
:label="$t('fixedAsset.value')"
required
/>
</VnRow>
<VnRow>
<VnInput
v-model="data.description"
:label="$t('globals.description')"
required
/>
</VnRow>
<VnRow>
<VnInputDate
v-model="data.firstAmortizated"
:label="$t('fixedAsset.firstAmortizated')"
placeholder="dd-mm-aaaa"
/>
<VnInputDate
v-model="data.lastAmortizated"
:label="$t('fixedAsset.lastAmortizated')"
placeholder="dd-mm-aaaa"
/>
</VnRow>
<VnRow>
<VnSelect
url="Ppes/getSubaccounts"
v-model="data.account"
:label="$t('fixedAsset.account')"
option-value="code"
option-label="code"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.description}`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.code}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
<VnSelect
url="Ppes/getEndowments"
v-model="data.endowment"
:label="$t('fixedAsset.endowment')"
option-value="code"
option-label="code"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.description}`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.code}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</VnRow>
<VnRow>
<VnAccountNumber
:label="$t('fixedAsset.elementAccount')"
v-model="data.elementAccount"
required
/>
<VnSelect
url="PpePlans"
v-model="data.planFk"
:label="$t('fixedAsset.plan')"
option-value="id"
:option-label="
(value) => `${value.rate * 100}% - ${value.days} days`
"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.rate * 100}% - ${scope.opt?.days} days`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.id}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</VnRow>
<VnRow>
<VnSelect
url="Ppes/getNatures"
v-model="data.nature"
:label="$t('fixedAsset.nature')"
option-value="nature"
option-label="nature"
hide-selected
/>
<VnSelect
url="PpeGroups"
v-model="data.groupFk"
:label="$t('globals.group')"
option-value="id"
option-label="description"
hide-selected
/>
</VnRow>
<VnRow>
<VnSelect
url="Companies"
:fields="['id', 'code']"
v-model="data.companyFk"
:label="$t('globals.company')"
option-value="id"
option-label="code"
hide-selected
/>
<VnSelect
url="PpeLocations"
v-model="data.locationFk"
:label="$t('fixedAsset.location')"
option-value="code"
:option-label="
(value) => `${value.code} - ${value.description}`
"
hide-selected
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>{{
`${scope.opt?.description}`
}}</QItemLabel>
<QItemLabel caption>
{{ `#${scope.opt?.code}` }}
</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</VnRow>
</div>
</template>
</VnTable>
</template>
</VnSection>
</template>