6157-actionClaim #106

Merged
carlossa merged 22 commits from 6157-actionClaim into dev 2023-11-24 07:46:30 +00:00
19 changed files with 661 additions and 71 deletions

View File

@ -269,7 +269,7 @@ watch(formUrl, async () => {
</VnPaginate>
<SkeletonTable v-if="!formData" />
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<QBtnGroup push class="q-gutter-x-sm">
<QBtnGroup push style="column-gap: 10px">
<slot name="moreBeforeActions" />
<QBtn
:label="tMobile('globals.remove')"

View File

@ -4,7 +4,7 @@ const emit = defineEmits(['update:modelValue', 'update:options']);
const $props = defineProps({
modelValue: {
type: [String, Number],
type: [String, Number, Object],
default: null,
},
options: {
@ -81,7 +81,6 @@ const value = computed({
map-options
use-input
@filter="filterHandler"
hide-selected
fill-input
ref="vnSelectRef"
>

View File

@ -1,8 +1,9 @@
<script setup>
import { onMounted, useSlots, ref, watch } from 'vue';
import { onMounted, useSlots, ref, watch, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import axios from 'axios';
import SkeletonDescriptor from 'components/ui/SkeletonDescriptor.vue';
import { useArrayData } from 'composables/useArrayData';
const $props = defineProps({
url: {
@ -25,33 +26,37 @@ const $props = defineProps({
type: Number,
default: 0,
},
dataKey: {
type: String,
default: '',
},
});
const slots = useSlots();
const { t } = useI18n();
const entity = ref();
const entity = computed(() => useArrayData($props.dataKey).store.data);
carlossa marked this conversation as resolved
Review

Esta tb borrala

Esta tb borrala
onMounted(async () => {
await fetch();
await getData();
watch(
() => $props.url,
async (newUrl, lastUrl) => {
if (newUrl == lastUrl) return;
entity.value = null;
await getData();
}
);
});
const emit = defineEmits(['onFetch']);
async function fetch() {
const params = {};
if ($props.filter) params.filter = JSON.stringify($props.filter);
const { data } = await axios.get($props.url, { params });
entity.value = data;
async function getData() {
const arrayData = useArrayData($props.dataKey, {
url: $props.url,
filter: $props.filter,
skip: 0,
});
const { data } = await arrayData.fetch({ append: false });
emit('onFetch', data);
}
watch($props, async () => {
entity.value = null;
await fetch();
});
const emit = defineEmits(['onFetch']);
</script>
<template>

View File

@ -29,6 +29,10 @@ export function useArrayData(key, userOptions) {
}
});
if (key && userOptions) {
setOptions();
}
function setOptions() {
const allowedOptions = [
'url',
@ -42,7 +46,7 @@ export function useArrayData(key, userOptions) {
];
if (typeof userOptions === 'object') {
for (const option in userOptions) {
const isEmpty = userOptions[option] == null || userOptions[option] == '';
const isEmpty = userOptions[option] == null || userOptions[option] === '';
if (isEmpty || !allowedOptions.includes(option)) continue;
if (Object.prototype.hasOwnProperty.call(store, option)) {
@ -97,6 +101,7 @@ export function useArrayData(key, userOptions) {
store.isLoading = false;
canceller = null;
return response;
}
function destroy() {
@ -147,10 +152,11 @@ export function useArrayData(key, userOptions) {
if (store.userParams && Object.keys(store.userParams).length !== 0)
query.params = JSON.stringify(store.userParams);
router.replace({
path: route.path,
query: query,
});
if (router)
router.replace({
path: route.path,
query: query,
});
}
const totalRows = computed(() => (store.data && store.data.length) || 0);

View File

@ -45,3 +45,9 @@ body.body--dark {
.bg-vn-dark {
background-color: var(--vn-dark);
}
.vn-card {
background-color: var(--vn-gray);
color: var(--vn-text);
border-radius: 8px;
}

View File

@ -274,6 +274,7 @@ export default {
development: 'Development',
log: 'Audit logs',
notes: 'Notes',
action: 'Action',
},
list: {
customer: 'Customer',

View File

@ -273,6 +273,7 @@ export default {
photos: 'Fotos',
log: 'Registros de auditoría',
notes: 'Notas',
action: 'Acción',
},
list: {
customer: 'Cliente',

View File

@ -0,0 +1,518 @@
<script setup>
import { ref, computed, onMounted } from 'vue';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import { useRoute, useRouter } from 'vue-router';
import axios from 'axios';
import { useStateStore } from 'src/stores/useStateStore';
import { toDate, toPercentage, toCurrency } from 'filters/index';
import { tMobile } from 'src/composables/tMobile';
import CrudModel from 'src/components/CrudModel.vue';
import FetchData from 'src/components/FetchData.vue';
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import { useArrayData } from 'composables/useArrayData';
const { t } = useI18n();
const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const stateStore = computed(() => useStateStore());
const claim = ref(null);
const claimRef = ref();
const claimId = route.params.id;
const dialogDestination = ref(false);
const claimDestinationFk = ref(null);
const resolvedStateId = ref(null);
const claimActionsForm = ref();
const rows = ref([]);
const selectedRows = ref([]);
const destinationTypes = ref([]);
const totalClaimed = ref(null);
const DEFAULT_MAX_RESPONSABILITY = 5;
const DEFAULT_MIN_RESPONSABILITY = 1;
const arrayData = useArrayData('claimData');
const marker_labels = [
{ value: DEFAULT_MIN_RESPONSABILITY, label: t('claim.summary.company') },
{ value: DEFAULT_MAX_RESPONSABILITY, label: t('claim.summary.person') },
];
const columns = computed(() => [
{
name: 'Id',
label: t('Id item'),
field: (row) => row.itemFk,
},
{
name: 'ticket',
carlossa marked this conversation as resolved
Review

Pq no pots possar row.claimDestinationFk ?

Pq no pots possar row.claimDestinationFk ?
label: t('Ticket'),
field: (row) => row.ticketFk,
align: 'center',
},
{
name: 'destination',
label: t('Destination'),
field: (row) => row.claimDestinationFk,
align: 'left',
},
{
name: 'Landed',
label: t('Landed'),
field: (row) => toDate(row.landed),
},
{
name: 'quantity',
label: t('Quantity'),
field: (row) => row.quantity,
},
{
name: 'concept',
label: t('Description'),
field: (row) => row.concept,
align: 'left',
},
{
name: 'price',
label: t('Price'),
field: (row) => row.price,
format: (value) => value,
align: 'center',
},
{
name: 'discount',
label: t('Discount'),
field: (row) => row.discount,
format: (value) => toPercentage(value / 100),
align: 'left',
},
{
name: 'total',
label: t('Total'),
field: (row) => row.total,
format: (value) => value,
align: 'center',
},
{
name: 'delete',
},
]);
onMounted(() => {
getTotal();
});
function setData(data) {
rows.value = data;
getTotal();
}
function getTotal() {
if (rows.value.length) {
totalClaimed.value = rows.value.reduce((total, row) => total + row.total, 0);
}
}
async function updateDestinations(claimDestinationFk) {
await updateDestination(claimDestinationFk, selectedRows.value, { reload: true });
}
async function updateDestination(claimDestinationFk, row, options = {}) {
if (claimDestinationFk) {
await axios.post('Claims/updateClaimDestination', {
carlossa marked this conversation as resolved
Review

Y esto también!!

Y esto también!!
claimDestinationFk,
rows: Array.isArray(row) ? row : [row],
});
options.reload && claimActionsForm.value.reload();
}
}
async function regularizeClaim() {
const query = `Claims/${claimId}/regularizeClaim`;
await axios.post(query);
if (claim.value.responsibility >= Math.ceil(DEFAULT_MAX_RESPONSABILITY) / 2) {
await claimRef.value.fetch();
quasar
.dialog({
component: VnConfirm,
componentProps: {
title: t('confirmGreuges'),
message: t('confirmGreugesMessage'),
},
})
.onOk(async () => await onUpdateGreugeAccept());
} else {
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
}
await arrayData.fetch({ append: false });
}
async function updateGreuge(greuges) {
const { data } = await axios.post(`Greuges`, greuges);
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
return data;
}
async function onUpdateGreugeAccept() {
const greugeTypeFreightId = await getGreugeTypeId();
const freightPickUpPrice = await getGreugeConfig();
await updateGreuge({
clientFk: claim.value.clientFk,
description: `${t('ClaimGreugeDescription')} ${claimId}`.toUpperCase(),
amount: freightPickUpPrice,
greugeTypeFk: greugeTypeFreightId,
ticketFk: claim.value.ticketFk,
});
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
}
async function getGreugeTypeId() {
const params = { filter: { where: { code: 'freightPickUp' } } };
const query = `GreugeTypes/findOne`;
const { data } = await axios.get(query, { params });
return data.id;
}
async function getGreugeConfig() {
const query = `GreugeConfigs/findOne`;
const { data } = await axios.get(query);
return data.freightPickUpPrice;
}
async function save(data) {
const query = `Claims/${claimId}/updateClaimAction`;
await axios.patch(query, data);
}
async function importToNewRefundTicket() {
const query = `ClaimBeginnings/${claimId}/importToNewRefundTicket`;
await axios.post(query);
claimActionsForm.value.reload();
quasar.notify({
message: t('globals.dataSaved'),
type: 'positive',
});
}
</script>
<template>
<FetchData
ref="claimRef"
:url="`Claims/${claimId}`"
@on-fetch="(data) => (claim = data)"
auto-load
/>
<FetchData
url="ClaimStates/findOne"
@on-fetch="(data) => (resolvedStateId = data.id)"
auto-load
:where="{ code: 'resolved' }"
/>
<FetchData
url="ClaimDestinations"
auto-load
@on-fetch="(data) => (destinationTypes = data)"
/>
<template v-if="stateStore.isHeaderMounted()">
<Teleport to="#actions-append">
<div class="row q-gutter-x-sm">
<QBtn
flat
@click="stateStore.toggleRightDrawer()"
round
dense
icon="menu"
>
<QTooltip bottom anchor="bottom right">
{{ t('globals.collapseMenu') }}
</QTooltip>
</QBtn>
</div>
</Teleport>
</template>
<QDrawer
v-model="stateStore.rightDrawer"
side="right"
:width="300"
show-if-above
v-if="claim"
>
<QCard class="totalClaim vn-card q-my-md q-pa-sm">
{{ `${t('Total claimed')}: ${toCurrency(totalClaimed)}` }}
</QCard>
<QCard class="vn-card q-mb-md q-pa-sm">
<QItem class="justify-between">
<QItemLabel class="slider-container">
<p class="text-primary">
{{ t('claim.summary.actions') }}
</p>
<QSlider
class="responsibility { 'background-color:primary': quasar.platform.is.mobile }"
v-model="claim.responsibility"
:label-value="t('claim.summary.responsibility')"
carlossa marked this conversation as resolved
Review

Si, los labels cambian, tienes que venir hasta el HTML?
Quizás, mejor definirlo en el apartado de

Si, los labels cambian, tienes que venir hasta el HTML? Quizás, mejor definirlo en el apartado de <script setup>
@change="(value) => save({ responsibility: value })"
label-always
color="primary"
markers
carlossa marked this conversation as resolved
Review

Podemos definir este valor como constante?
Tipo
DEFAULT_MIN_SLIDER =1
DEFAULT_MAX_SLIDER =5

Podemos definir este valor como constante? Tipo DEFAULT_MIN_SLIDER =1 DEFAULT_MAX_SLIDER =5
:marker-labels="marker_labels"
:min="DEFAULT_MIN_RESPONSABILITY"
:max="DEFAULT_MAX_RESPONSABILITY"
/>
</QItemLabel>
</QItem>
</QCard>
<QItemLabel class="mana q-mb-md">
<QCheckbox
v-model="claim.isChargedToMana"
@update:model-value="(value) => save({ isChargedToMana: value })"
/>
<span>{{ t('mana') }}</span>
</QItemLabel>
</QDrawer>
<Teleport to="#st-data" v-if="stateStore.isSubToolbarShown()"> </Teleport>
<CrudModel
v-if="claim"
data-key="ClaimEnds"
url="ClaimEnds/filter"
save-url="ClaimEnds/crud"
ref="claimActionsForm"
v-model:selected="selectedRows"
:filter="{ where: { claimFk: claimId } }"
:default-remove="true"
:default-save="false"
:default-reset="false"
@on-fetch="setData"
auto-load
>
<template #body>
<QTable
:columns="columns"
:rows="rows"
:dense="$q.screen.lt.md"
row-key="id"
selection="multiple"
v-model:selected="selectedRows"
:grid="$q.screen.lt.md"
>
<template #body-cell-ticket="{ value }">
<QTd align="center">
<span class="link">
{{ value }}
<TicketDescriptorProxy :id="value" />
</span>
</QTd>
</template>
<template #body-cell-destination="{ row }">
<QTd>
<VnSelectFilter
v-model="row.claimDestinationFk"
:options="destinationTypes"
option-label="description"
option-value="id"
:autofocus="true"
dense
input-debounce="0"
hide-selected
@update:model-value="(value) => updateDestination(value, row)"
/>
</QTd>
</template>
<template #body-cell-price="{ value }">
<QTd align="center">
{{ toCurrency(value) }}
</QTd>
</template>
<template #body-cell-total="{ value }">
<QTd align="center">
{{ toCurrency(value) }}
</QTd>
</template>
<!-- View for grid mode -->
<template #item="props">
<div class="q-mb-md col-12 grid-style-transition">
<QCard>
<QCardSection class="row justify-between">
<QCheckbox v-model="props.selected" />
<QBtn color="primary" icon="delete" flat round />
</QCardSection>
<QSeparator inset />
<QList dense>
<QItem v-for="column of props.cols" :key="column.name">
<QItemSection>
<QItemLabel caption>
{{ column.label }}
</QItemLabel>
</QItemSection>
<QItemSection side>
<QItemLabel v-if="column.name === 'destination'">
{{ column.value.description }}
</QItemLabel>
<QItemLabel v-else>
{{ column.value }}
</QItemLabel>
</QItemSection>
</QItem>
</QList>
</QCard>
</div>
</template>
</QTable>
</template>
<template #moreBeforeActions>
<QBtn
color="primary"
text-color="white"
:unelevated="true"
:label="tMobile('Regularize')"
:title="t('Regularize')"
icon="check"
@click="regularizeClaim"
:disable="claim.claimStateFk == resolvedStateId"
/>
<QBtn
color="primary"
text-color="white"
:unelevated="true"
:disable="!selectedRows.length"
:label="tMobile('Change destination')"
:title="t('Change destination')"
icon="swap_horiz"
@click="dialogDestination = !dialogDestination"
/>
<QBtn
color="primary"
text-color="white"
:unelevated="true"
:label="tMobile('Import claim')"
:title="t('Import claim')"
icon="Upload"
@click="importToNewRefundTicket"
:disable="claim.claimStateFk == resolvedStateId"
/>
</template>
</CrudModel>
<QDialog v-model="dialogDestination">
<QCard>
<QCardSection>
<QItem class="q-pa-sm">
<span class="q-dialog__title text-white">
{{ t('dialog title') }}
</span>
<QBtn icon="close" flat round dense v-close-popup />
</QItem>
</QCardSection>
<QItemSection>
<VnSelectFilter
class="q-pa-sm"
v-model="claimDestinationFk"
:options="destinationTypes"
option-label="description"
option-value="id"
:autofocus="true"
dense
input-debounce="0"
hide-selected
/>
</QItemSection>
<QCardActions class="justify-end q-mr-sm">
<QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
<QBtn
:disable="!claimDestinationFk"
:label="t('globals.save')"
color="primary"
v-close-popup
@click="updateDestinations(claimDestinationFk)"
/>
</QCardActions>
</QCard>
</QDialog>
<!-- <QDialog v-model="dialogGreuge">
<QCardSection>
<QItem class="q-pa-sm">
<span class="q-pa-sm q-dialog__title text-white">
{{ t('dialogGreuge title') }}
</span>
<QBtn class="q-pa-sm" icon="close" flat round dense v-close-popup />
</QItem>
<QCardActions class="justify-end q-mr-sm">
<QBtn flat :label="t('globals.close')" color="primary" v-close-popup />
<QBtn
:label="t('globals.save')"
color="primary"
v-close-popup
@click="onUpdateGreugeAccept"
/>
</QCardActions>
</QCardSection>
</QDialog> -->
</template>
<style lang="scss" scoped>
carlossa marked this conversation as resolved
Review

Com?

Com?
.slider-container {
width: 50%;
}
@media (max-width: $breakpoint-xs) {
.slider-container {
width: 90%;
}
}
.q-table {
.q-item {
min-height: min-content;
height: 0;
}
}
.q-dialog {
.q-btn {
height: min-content;
}
}
.responsibility {
max-width: 100%;
margin-left: 40px;
}
.mana {
carlossa marked this conversation as resolved
Review

Aço si ja esta en els descriptors, en els summarys te que haver alguna clase ja feta (si no fesla)

Aço si ja esta en els descriptors, en els summarys te que haver alguna clase ja feta (si no fesla)
float: inline-start;
}
</style>
<i18n>
en:
mana: Is paid with mana
dialog title: Change destination to all selected rows
confirmGreuges: Do you want to insert complaints?
confirmGreugesMessage: Insert complaints into the client's record
es:
mana: Cargado al maná
Delivered: Descripción
Quantity: Cantidad
Claimed: Rec
Description: Descripción
Price: Precio
Discount: Dto.
Destination: Destino
Landed: F.entrega
Remove line: Eliminar línea
Total claimed: Total reclamado
Regularize: Regularizar
Change destination: Cambiar destino
Import claim: Importar reclamación
dialog title: Cambiar destino en todas las filas seleccionadas
Remove: Eliminar
dialogGreuge title: Insertar greuges en la ficha del cliente
ClaimGreugeDescription: Id reclamación
Id item: Id artículo
confirmGreuges: ¿Desea insertar greuges?
confirmGreugesMessage: Insertar greuges en la ficha del cliente
</i18n>

View File

@ -22,11 +22,6 @@ const $props = defineProps({
const entityId = computed(() => {
carlossa marked this conversation as resolved
Review

esto no se usa, no?

esto no se usa, no?
return $props.id || route.params.id;
});
let salixUrl;
onMounted(async () => {
salixUrl = await getUrl(`claim/${entityId.value}`);
});
</script>
<template>
<Teleport to="#searchbar" v-if="stateStore.isHeaderMounted()">
@ -42,18 +37,6 @@ onMounted(async () => {
<ClaimDescriptor />
<QSeparator />
<LeftMenu source="card" />
<QSeparator />
<QList>
<QItem
active-class="text-primary"
clickable
v-ripple
:href="`${salixUrl}/action`"
>
<QItemSection avatar><QIcon name="vn:actions"></QIcon></QItemSection>
<QItemSection>{{ t('Action') }}</QItemSection>
</QItem>
</QList>
</QScrollArea>
</QDrawer>
<QPageContainer>

View File

@ -62,13 +62,18 @@ const filter = {
],
};
const STATE_COLOR = {
pending: 'positive',
managed: 'warning',
resolved: 'negative',
};
function stateColor(code) {
if (code === 'pending') return 'positive';
if (code === 'managed') return 'warning';
if (code === 'resolved') return 'negative';
return STATE_COLOR[code];
}
const data = ref(useCardDescription());
const setData = (entity) => {
if (!entity) return;
data.value = useCardDescription(entity.client.name, entity.id);
state.set('ClaimDescriptor', entity);
};
@ -83,6 +88,7 @@ const setData = (entity) => {
:title="data.title"
:subtitle="data.subtitle"
@on-fetch="setData"
data-key="claimData"
>
<template #menu="{ entity }">
<ClaimDescriptorMenu :claim="entity" />
@ -120,16 +126,16 @@ const setData = (entity) => {
<VnLv :label="t('claim.card.commercial')">
<template #value>
<span class="link">
{{ entity.client.salesPersonUser.name }}
<WorkerDescriptorProxy :id="entity.client.salesPersonFk" />
{{ entity.client?.salesPersonUser?.name }}
<WorkerDescriptorProxy :id="entity.client?.salesPersonFk" />
</span>
</template>
</VnLv>
<VnLv
:label="t('claim.card.province')"
:value="entity.ticket.address.province.name"
:value="entity.ticket?.address?.province?.name"
/>
<VnLv :label="t('claim.card.zone')" :value="entity.ticket.zone.name" />
<VnLv :label="t('claim.card.zone')" :value="entity.ticket?.zone?.name" />
</template>
<template #actions="{ entity }">
<QCardActions>

View File

@ -7,6 +7,7 @@ import FetchData from 'components/FetchData.vue';
import VnSelectFilter from 'components/common/VnSelectFilter.vue';
import { getUrl } from 'composables/getUrl';
import { tMobile } from 'composables/tMobile';
import router from 'src/router';
const route = useRoute();
@ -102,10 +103,6 @@ const columns = computed(() => [
tabIndex: 5,
},
]);
function goToAction() {
location.href = `${salixUrl}/action`;
}
</script>
<template>
<FetchData
@ -148,7 +145,7 @@ function goToAction() {
:data-required="{ claimFk: route.params.id }"
v-model:selected="selected"
auto-load
@save-changes="goToAction"
@save-changes="$router.push(`/claim/${route.params.id}/action`)"
:default-save="false"
>
<template #body="{ rows }">
@ -175,6 +172,7 @@ function goToAction() {
:option-label="col.optionLabel"
:autofocus="col.tabIndex == 1"
input-debounce="0"
hide-selected
>
<template #option="scope" v-if="col.name == 'worker'">
<QItem v-bind="scope.itemProps">
@ -213,6 +211,7 @@ function goToAction() {
dense
input-debounce="0"
:autofocus="col.tabIndex == 1"
hide-selected
/>
</QItemSection>
</QItem>

View File

@ -85,10 +85,15 @@ const detailsColumns = ref([
},
]);
const STATE_COLOR = {
pending: 'positive',
managed: 'warning',
resolved: 'negative',
};
function stateColor(code) {
if (code === 'pending') return 'green';
if (code === 'managed') return 'orange';
if (code === 'resolved') return 'red';
return STATE_COLOR[code];
}
const developmentColumns = ref([

View File

@ -17,12 +17,14 @@ const router = useRouter();
const quasar = useQuasar();
const { t } = useI18n();
const STATE_COLOR = {
pending: 'positive',
managed: 'warning',
resolved: 'negative',
};
carlossa marked this conversation as resolved
Review

Els introoooooooooooos, tens prettier?

Els introoooooooooooos, tens prettier?
function stateColor(code) {
if (code === 'pending') return 'green';
if (code === 'managed') return 'orange';
if (code === 'resolved') return 'red';
return STATE_COLOR[code];
}
function navigate(id) {
router.push({ path: `/claim/${id}` });
}

View File

@ -68,7 +68,7 @@ function viewSummary(id) {
</div>
</Teleport>
</template>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above>
<QDrawer v-model="stateStore.rightDrawer" side="right" :width="256">
<QScrollArea class="fit text-grey-8">
<TicketFilter data-key="TicketList" />
</QScrollArea>

View File

@ -47,19 +47,22 @@ const filter = {
],
};
const sip = computed(() => worker.value.sip && worker.value.sip.extension);
const sip = computed(() => worker.value?.sip && worker.value.sip.extension);
function getWorkerAvatar() {
const token = getToken();
return `/api/Images/user/160x160/${route.params.id}/download?access_token=${token}`;
}
const data = ref(useCardDescription());
const setData = (entity) =>
(data.value = useCardDescription(entity.user.nickname, entity.id));
const setData = (entity) => {
if (!entity) return;
data.value = useCardDescription(entity.user.nickname, entity.id);
};
</script>
<template>
<CardDescriptor
module="Worker"
data-key="workerData"
:url="`Workers/${entityId}`"
:filter="filter"
:title="data.title"
@ -90,8 +93,8 @@ const setData = (entity) =>
</QImg>
</template>
<template #body="{ entity }">
<VnLv :label="t('worker.card.name')" :value="entity.user.nickname" />
<VnLv :label="t('worker.card.email')" :value="entity.user.email"> </VnLv>
<VnLv :label="t('worker.card.name')" :value="entity.user?.nickname" />
<VnLv :label="t('worker.card.email')" :value="entity.user?.email"> </VnLv>
<VnLv
:label="t('worker.list.department')"
:value="entity.department ? entity.department.department.name : null"

View File

@ -19,6 +19,7 @@ export default {
'ClaimLog',
'ClaimNotes',
'ClaimDevelopment',
'ClaimAction',
],
},
children: [
@ -130,6 +131,15 @@ export default {
},
component: () => import('src/pages/Claim/Card/ClaimNotes.vue'),
},
{
name: 'ClaimAction',
path: 'action',
meta: {
title: 'action',
icon: 'vn:actions',
},
component: () => import('src/pages/Claim/Card/ClaimAction.vue'),
},
],
},
],

View File

@ -18,7 +18,7 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
skip: 0,
order: '',
data: ref(),
isLoading: false
isLoading: false,
};
}

View File

@ -0,0 +1,45 @@
/// <reference types="cypress" />
describe('ClaimAction', () => {
const claimId = 2;
const firstRow = 'tbody > :nth-child(1)';
const destinationRow = '.q-item__section > .q-field';
beforeEach(() => {
cy.viewport(1920, 1080);
cy.login('developer');
cy.visit(`/#/claim/${claimId}/action`);
});
it('should import claim', () => {
cy.get('[title="Import claim"]').click();
});
it('should change destination', () => {
const rowData = [true, null, null, 'Bueno'];
cy.fillRow(firstRow, rowData);
});
it('should change destination from other button', () => {
const rowData = [true];
cy.fillRow(firstRow, rowData);
cy.get('[title="Change destination"]').click();
cy.selectOption(destinationRow, 'Confeccion');
cy.get('.q-card > .q-card__actions > .q-btn--standard').click();
});
it('should regularize', () => {
cy.get('[title="Regularize"]').click();
cy.clickConfirm();
});
it('should remove the line', () => {
cy.fillRow(firstRow, [true]);
cy.removeCard();
cy.clickConfirm();
cy.reload();
cy.get(firstRow).should('not.exist');
});
});

View File

@ -88,7 +88,8 @@ Cypress.Commands.add('addCard', () => {
cy.get('.q-page-sticky > div > .q-btn').click();
});
Cypress.Commands.add('clickConfirm', () => {
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
cy.waitForElement('.q-dialog__inner > .q-card');
cy.get('.q-card__actions > .q-btn--unelevated > .q-btn__content > .block').click();
});
Cypress.Commands.add('notificationHas', (selector, text) => {