Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix-front into 7277-RefundInvoices

This commit is contained in:
Javier Segarra 2024-09-04 15:32:14 +02:00
commit 95e30c88ee
31 changed files with 218 additions and 65 deletions

View File

@ -1,8 +1,10 @@
import routes from 'src/router/modules';
import { useRouter } from 'vue-router';
let isNotified = false;
export default {
mounted: function () {
created: function () {
const router = useRouter();
const keyBindingMap = routes
.filter((route) => route.meta.keyBinding)
@ -10,14 +12,27 @@ export default {
map[route.meta.keyBinding.toLowerCase()] = route.path;
return map;
}, {});
const handleKeyDown = (event) => {
const { ctrlKey, altKey, key } = event;
if (ctrlKey && altKey && keyBindingMap[key] && !isNotified) {
event.preventDefault();
if (ctrlKey && altKey && keyBindingMap[key]) {
router.push(keyBindingMap[key]);
isNotified = true;
}
};
const handleKeyUp = (event) => {
const { ctrlKey, altKey } = event;
// Resetea la bandera cuando se sueltan las teclas ctrl o alt
if (!ctrlKey || !altKey) {
isNotified = false;
}
};
window.addEventListener('keydown', handleKeyDown);
window.addEventListener('keyup', handleKeyUp);
},
};

View File

@ -2,10 +2,6 @@
import { computed } from 'vue';
const $props = defineProps({
maxLength: {
type: Number,
required: true,
},
item: {
type: Object,
required: true,

View File

@ -253,6 +253,7 @@ input::-webkit-inner-spin-button {
}
td {
font-size: 11pt;
border-top: 1px solid var(--vn-page-color);
border-collapse: collapse;
}
}

View File

@ -260,6 +260,7 @@ globals:
ticketsMonitor: Tickets monitor
clientsActionsMonitor: Clients and actions
serial: Serial
medical: Mutual
created: Created
worker: Worker
now: Now
@ -878,6 +879,7 @@ worker:
timeControl: Time control
locker: Locker
balance: Balance
medical: Medical
list:
name: Name
email: Email
@ -957,6 +959,15 @@ worker:
amount: Importe
remark: Bonficado
hasDiploma: Diploma
medical:
tableVisibleColumns:
date: Date
time: Hour
center: Formation Center
invoice: Invoice
amount: Amount
isFit: Fit
remark: Observations
imageNotFound: Image not found
balance:
tableVisibleColumns:

View File

@ -264,6 +264,7 @@ globals:
ticketsMonitor: Monitor de tickets
clientsActionsMonitor: Clientes y acciones
serial: Facturas por serie
medical: Mutua
created: Fecha creación
worker: Trabajador
now: Ahora
@ -881,6 +882,8 @@ worker:
timeControl: Control de horario
locker: Taquilla
balance: Balance
formation: Formación
medical: Mutua
list:
name: Nombre
email: Email
@ -951,6 +954,15 @@ worker:
amount: Importe
remark: Bonficado
hasDiploma: Diploma
medical:
tableVisibleColumns:
date: Fecha
time: Hora
center: Centro de Formación
invoice: Factura
amount: Importe
isFit: Apto
remark: Observaciones
imageNotFound: No se ha encontrado la imagen
balance:
tableVisibleColumns:

View File

@ -1,11 +1,10 @@
<script setup>
import axios from 'axios';
import { onMounted, ref, computed } from 'vue';
import { ref, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { toDate, toCurrency } from 'src/filters';
import dashIfEmpty from 'src/filters/dashIfEmpty';
import { getUrl } from 'src/composables/getUrl';
import { useSession } from 'src/composables/useSession';
import VnLv from 'src/components/ui/VnLv.vue';

View File

@ -423,7 +423,7 @@ const lockIconType = (groupingMode, mode) => {
<span v-if="props.row.item.subName" class="subName">
{{ props.row.item.subName }}
</span>
<FetchedTags :item="props.row.item" :max-length="5" />
<FetchedTags :item="props.row.item" />
</QTd>
</QTr>
</template>

View File

@ -319,7 +319,7 @@ const fetchEntryBuys = async () => {
<span v-if="row.item.subName" class="subName">
{{ row.item.subName }}
</span>
<FetchedTags :item="row.item" :max-length="5" />
<FetchedTags :item="row.item" />
</QTd>
</QTr>
<!-- Esta última row es utilizada para agregar un espaciado y así marcar una diferencia visual entre los diferentes buys -->

View File

@ -9,9 +9,6 @@ import RightMenu from 'src/components/common/RightMenu.vue';
import { toDate } from 'src/filters';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
import EntrySummary from './Card/EntrySummary.vue';
import VnUserLink from 'components/ui/VnUserLink.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';

View File

@ -19,7 +19,6 @@ const stateStore = useStateStore();
const { viewSummary } = useSummaryDialog();
const tableRef = ref();
const invoiceOutSerialsOptions = ref([]);
const ticketsOptions = ref([]);
const customerOptions = ref([]);
const selectedRows = ref([]);
const hasSelectedCards = computed(() => selectedRows.value.length > 0);

View File

@ -14,8 +14,6 @@ const route = useRoute();
const { t } = useI18n();
const itemBotanicalsRef = ref(null);
const itemGenusOptions = ref([]);
const itemSpeciesOptions = ref([]);
const itemBotanicals = ref([]);
let itemBotanicalsForm = reactive({ itemFk: null });

View File

@ -436,7 +436,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
{{ row.name }}
</span>
<ItemDescriptorProxy :id="row.itemFk" />
<FetchedTags :item="row" :max-length="6" />
<FetchedTags :item="row" />
</QTd>
</template>
<template #body-cell-groupingPrice="props">

View File

@ -517,7 +517,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
<template #body-cell-description="{ row }">
<QTd class="col">
<span>{{ row.name }} {{ row.subName }}</span>
<FetchedTags :item="row" :max-length="6" />
<FetchedTags :item="row" />
</QTd>
</template>
<template #body-cell-isActive="{ row }">

View File

@ -1,7 +1,6 @@
<script setup>
import { ref, computed, onMounted, onBeforeMount, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import FetchData from 'components/FetchData.vue';
import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';

View File

@ -380,21 +380,6 @@ function addOrder(value, field, params) {
@click="tagValues.push({})"
/>
</QItem>
<!-- <QItem>
<QItemSection class="q-py-sm">
<QBtn
:label="t('Search')"
class="full-width"
color="primary"
dense
icon="search"
rounded
type="button"
unelevated
@click.stop="applyTagFilter(params, searchFn)"
/>
</QItemSection>
</QItem> -->
<QSeparator />
</template>
</VnFilterPanel>

View File

@ -77,10 +77,6 @@ const addToOrder = async () => {
</template>
<style lang="scss" scoped>
// .container {
// max-width: 768px;
// width: 100%;
// }
.td {
width: 200px;
}

View File

@ -14,6 +14,7 @@ import FetchData from 'src/components/FetchData.vue';
import VnImg from 'src/components/ui/VnImg.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import FetchedTags from 'src/components/ui/FetchedTags.vue';
import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue';
const router = useRouter();
const stateStore = useStateStore();
@ -280,7 +281,12 @@ watch(
<VnImg :id="parseInt(row?.item?.image)" class="rounded" />
</div>
</template>
<template #column-id="{ row }">
<span class="link" @click.stop>
{{ row?.item?.id }}
<ItemDescriptorProxy :id="row?.item?.id" />
</span>
</template>
<template #column-itemFk="{ row }">
<div class="row column full-width justify-between items-start">
{{ row?.item?.name }}
@ -288,7 +294,7 @@ watch(
{{ row?.item?.subName.toUpperCase() }}
</div>
</div>
<FetchedTags :item="row?.item" :max-length="6" />
<FetchedTags :item="row?.item" />
</template>
<template #column-amount="{ row }">
{{ toCurrency(row.quantity * row.price) }}

View File

@ -192,7 +192,7 @@ const detailsColumns = ref([
</span>
</div>
</div>
<FetchedTags :item="props.row.item" :max-length="5" />
<FetchedTags :item="props.row.item" />
</QTd>
<QTd key="quantity" :props="props">
{{ props.row.quantity }}

View File

@ -2,8 +2,9 @@
import axios from 'axios';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import { dashIfEmpty } from 'src/filters';
import { useStateStore } from 'stores/useStateStore';
import FetchData from 'components/FetchData.vue';
import FetchedTags from 'components/ui/FetchedTags.vue';
@ -58,6 +59,9 @@ const loadVolumes = async (rows) => {
});
volumes.value = rows;
};
const stateStore = useStateStore();
onMounted(async () => (stateStore.rightDrawer = false));
</script>
<template>
@ -84,6 +88,7 @@ const loadVolumes = async (rows) => {
@on-fetch="(data) => loadVolumes(data)"
:right-search="false"
:column-search="false"
:disable-option="{ card: true }"
>
<template #column-itemFk="{ row }">
<span class="link">
@ -92,7 +97,13 @@ const loadVolumes = async (rows) => {
</span>
</template>
<template #column-description="{ row }">
<FetchedTags :item="row.item" :max-length="5" />
<div class="row column full-width justify-between items-start">
{{ row?.item?.name }}
<div v-if="row?.item?.subName" class="subName">
{{ row?.item?.subName.toUpperCase() }}
</div>
</div>
<FetchedTags :item="row?.item" />
</template>
<template #column-volume="{ rowIndex }">
{{ volumes?.[rowIndex]?.volume }}
@ -121,6 +132,11 @@ const loadVolumes = async (rows) => {
}
}
}
.subName {
color: var(--vn-label-color);
text-transform: uppercase;
}
</style>
<i18n>
en:

View File

@ -11,6 +11,9 @@ import VnSelect from 'src/components/common/VnSelect.vue';
import OrderSearchbar from './Card/OrderSearchbar.vue';
import RightMenu from 'src/components/common/RightMenu.vue';
import OrderFilter from './Card/OrderFilter.vue';
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
import { toDateTimeFormat } from 'src/filters/date';
const { t } = useI18n();
const { viewSummary } = useSummaryDialog();
@ -75,7 +78,7 @@ const columns = computed(() => [
label: t('module.created'),
component: 'date',
cardVisible: true,
format: (row) => toDate(row?.landed),
format: (row) => toDateTimeFormat(row?.landed),
columnField: {
component: null,
},
@ -115,6 +118,7 @@ const columns = computed(() => [
},
},
cardVisible: true,
columnClass: 'expand',
},
{
align: 'left',
@ -132,6 +136,7 @@ const columns = computed(() => [
title: t('InvoiceOutSummary'),
icon: 'preview',
action: (row) => viewSummary(row.id, OrderSummary),
isPrimary: true,
},
],
},
@ -154,6 +159,16 @@ async function fetchAgencies({ landed, addressId }) {
});
agencyList.value = data;
}
const getDateColor = (date) => {
const today = Date.vnNew();
today.setHours(0, 0, 0, 0);
const timeTicket = new Date(date);
timeTicket.setHours(0, 0, 0, 0);
const comparation = today - timeTicket;
if (comparation == 0) return 'bg-warning';
if (comparation < 0) return 'bg-success';
};
</script>
<template>
<OrderSearchbar />
@ -183,6 +198,25 @@ async function fetchAgencies({ landed, addressId }) {
:columns="columns"
redirect="order"
>
<template #column-clientFk="{ row }">
<span class="link" @click.stop>
{{ row?.clientName }}
<CustomerDescriptorProxy :id="row?.clientFk" />
</span>
</template>
<template #column-salesPersonFk="{ row }">
<span class="link" @click.stop>
{{ row?.name }}
<WorkerDescriptorProxy :id="row?.salesPersonFk" />
</span>
</template>
<template #column-landed="{ row }">
<span v-if="getDateColor(row.landed)">
<QChip :class="getDateColor(row.landed)" dense square>
{{ toDate(row?.landed) }}
</QChip>
</span>
</template>
<template #more-create-dialog="{ data }">
<VnSelect
url="Clients"

View File

@ -208,7 +208,7 @@ onMounted(async () => {
<QTd no-hover>
<span>{{ buy.subName }}</span>
<FetchedTags :item="buy" :max-length="5" />
<FetchedTags :item="buy" />
</QTd>
<QTd no-hover> {{ dashIfEmpty(buy.quantity) }}</QTd>
<QTd no-hover> {{ dashIfEmpty(buy.price) }}</QTd>

View File

@ -245,7 +245,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
<div class="column">
<span>{{ row.item.name }}</span>
<span class="color-vn-label">{{ row.item.subName }}</span>
<FetchedTags :item="row.item" :max-length="6" />
<FetchedTags :item="row.item" />
</div>
</QTd>
</template>

View File

@ -310,7 +310,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
<div class="column">
<span>{{ row.item.name }}</span>
<span class="color-vn-label">{{ row.item.subName }}</span>
<FetchedTags :item="row.item" :max-length="6" />
<FetchedTags :item="row.item" />
</div>
</QTd>
</template>

View File

@ -656,7 +656,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
<div class="column">
<span>{{ row.concept }}</span>
<span class="color-vn-label">{{ row.item?.subName }}</span>
<FetchedTags v-if="row.item" :item="row.item" :max-length="6" />
<FetchedTags v-if="row.item" :item="row.item" />
<QPopupProxy v-if="row.id && isTicketEditable">
<VnInput v-model="row.concept" @change="updateConcept(row)" />
</QPopupProxy>

View File

@ -412,7 +412,7 @@ const qCheckBoxController = (sale, action) => {
<span v-if="row.subName" class="color-vn-label">
{{ row.subName }}
</span>
<FetchedTags :item="row" :max-length="6" tag="value" />
<FetchedTags :item="row" tag="value" />
</div>
</QTd>
</template>

View File

@ -399,7 +399,6 @@ async function changeState(value) {
<FetchedTags
class="fetched-tags"
:item="props.row.item"
:max-length="5"
></FetchedTags>
</QTd>
<QTd>{{ props.row.price }} </QTd>

View File

@ -145,7 +145,7 @@ onUnmounted(() => (stateStore.rightDrawer = false));
<div class="column">
<span>{{ row.item.name }}</span>
<span class="color-vn-label">{{ row.item.subName }}</span>
<FetchedTags :item="row.item" :max-length="6" />
<FetchedTags :item="row.item" />
</div>
</QTd>
</template>

View File

@ -0,0 +1,91 @@
<script setup>
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import VnTable from 'components/VnTable/VnTable.vue';
const tableRef = ref();
const { t } = useI18n();
const route = useRoute();
const entityId = computed(() => route.params.id);
const columns = [
{
align: 'left',
name: 'date',
label: t('worker.medical.tableVisibleColumns.date'),
create: true,
component: 'date',
},
{
align: 'left',
name: 'time',
label: t('worker.medical.tableVisibleColumns.time'),
create: true,
component: 'time',
attrs: {
timeOnly: true,
},
},
{
align: 'left',
name: 'centerFk',
label: t('worker.medical.tableVisibleColumns.center'),
create: true,
component: 'select',
attrs: {
url: 'medicalCenters',
fields: ['id', 'name'],
},
},
{
align: 'left',
name: 'invoice',
label: t('worker.medical.tableVisibleColumns.invoice'),
create: true,
component: 'input',
},
{
align: 'left',
name: 'amount',
label: t('worker.medical.tableVisibleColumns.amount'),
create: true,
component: 'input',
},
{
align: 'left',
name: 'isFit',
label: t('worker.medical.tableVisibleColumns.isFit'),
create: true,
component: 'checkbox',
},
{
align: 'left',
name: 'remark',
label: t('worker.medical.tableVisibleColumns.remark'),
create: true,
component: 'input',
},
];
</script>
<template>
<VnTable
ref="tableRef"
data-key="WorkerMedical"
:url="`Workers/${entityId}/medicalReview`"
save-url="MedicalReviews/crud"
:create="{
urlCreate: 'medicalReviews',
title: t('Create medicalReview'),
onDataSaved: () => tableRef.reload(),
formInitialData: {
workerFk: entityId,
},
}"
order="date DESC"
:columns="columns"
auto-load
:right-search="false"
:is-editable="true"
:use-model="true"
/>
</template>

View File

@ -10,7 +10,6 @@ import CardSummary from 'components/ui/CardSummary.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
import VnTitle from 'src/components/common/VnTitle.vue';
import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue';
import VnRow from 'src/components/ui/VnRow.vue';
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
const route = useRoute();

View File

@ -10,17 +10,7 @@ import ZoneFilterPanel from '../ZoneFilterPanel.vue';
const { t } = useI18n();
const route = useRoute();
const routeName = computed(() => route.name);
const customRouteRedirectName = computed(() => {
if (routeName.value === 'ZoneLocations') return null;
return routeName.value;
});
const searchbarMakeFetch = computed(() => routeName.value !== 'ZoneEvents');
const searchBarDataKeys = {
ZoneWarehouses: 'ZoneWarehouses',
ZoneSummary: 'ZoneSummary',
ZoneLocations: 'ZoneLocations',
ZoneEvents: 'ZoneEvents',
};
function notIsLocations(ifIsFalse, ifIsTrue) {
if (routeName.value != 'ZoneLocations') return ifIsFalse;
return ifIsTrue;

View File

@ -25,6 +25,7 @@ export default {
'WorkerLocker',
'WorkerBalance',
'WorkerFormation',
'WorkerMedical',
],
},
children: [
@ -196,6 +197,15 @@ export default {
},
component: () => import('src/pages/Worker/Card/WorkerFormation.vue'),
},
{
name: 'WorkerMedical',
path: 'medical',
meta: {
title: 'medical',
icon: 'medical_information',
},
component: () => import('src/pages/Worker/Card/WorkerMedical.vue'),
},
],
},
],