@@ -319,11 +320,13 @@ function getLink(param) {
-
-
+
+
@@ -347,10 +350,7 @@ function getLink(param) {
-
+
-
+
diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue
index 9508c669c..46c95c734 100644
--- a/src/pages/InvoiceIn/InvoiceInList.vue
+++ b/src/pages/InvoiceIn/InvoiceInList.vue
@@ -112,7 +112,6 @@ function navigate(id) {
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
index 9c1bb3649..e01706e84 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue
@@ -2,13 +2,15 @@
import { ref, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
-import { toCurrency, toDate } from 'src/filters';
+
import CardDescriptor from 'components/ui/CardDescriptor.vue';
import CustomerDescriptorProxy from 'pages/Customer/Card/CustomerDescriptorProxy.vue';
import VnLv from 'src/components/ui/VnLv.vue';
-import useCardDescription from 'src/composables/useCardDescription';
import InvoiceOutDescriptorMenu from './InvoiceOutDescriptorMenu.vue';
+import useCardDescription from 'src/composables/useCardDescription';
+import { toCurrency, toDate } from 'src/filters';
+
const $props = defineProps({
id: {
type: Number,
@@ -23,7 +25,6 @@ const { t } = useI18n();
const entityId = computed(() => {
return $props.id || route.params.id;
});
-const descriptor = ref();
const filter = {
include: [
@@ -42,6 +43,8 @@ const filter = {
],
};
+const descriptor = ref();
+
function ticketFilter(invoice) {
return JSON.stringify({ refFk: invoice.ref });
}
@@ -61,7 +64,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
data-key="invoiceOutData"
>
-
+
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue b/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue
index ab8b6470b..10af631bc 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutDescriptorMenu.vue
@@ -1,40 +1,260 @@
-
- {{ t('Transfer invoice to') }}
+
+ {{ t('Transfer invoice to...') }}
- {{ t('See invoice') }}
+ {{ t('Show invoice...') }}
+
+
+
+
+
+
+ {{ t('As PDF') }}
+
+
+ {{ t('As CSV') }}
+
+
+
- {{ t('Send invoice') }}
+ {{ t('Send invoice...') }}
+
+
+
+
+
+
+ {{ t('Send PDF') }}
+
+
+ {{ t('Send CSV') }}
+
+
+
-
+
{{ t('Delete invoice') }}
-
- {{ t('Post invoice') }}
+
+ {{ t('Book invoice') }}
+
+
+ {{ t('Generate PDF invoice') }}
- {{ t('Regenerate invoice PDF') }}
-
-
- {{ t('Pass') }}
+ {{ t('Refund...') }}
+
+
+
+
+
+
+ {{ t('With warehouse') }}
+
+
+ {{ t('Without warehouse') }}
+
+
+
+
+ {{ t('Create a single ticket with all the content of the current invoice') }}
+
+
+
+
+
es:
- Transfer invoice to: Transferir factura a
- See invoice: Ver factura
- Send invoice: Enviar factura
+ Transfer invoice to...: Transferir factura a...
+ Show invoice...: Ver factura...
+ Send invoice...: Enviar factura...
Delete invoice: Eliminar factura
- Post invoice: Asentar factura
- Regenerate invoice PDF: Regenerar PDF factura
- Pass: Abono
+ Book invoice: Asentar factura
+ Generate PDF invoice: Generar PDF factura
+ Refund...: Abono
+ As PDF: como PDF
+ As CSV: como CSV
+ Send PDF: Enviar PDF
+ Send CSV: Enviar CSV
+ With warehouse: Con almacén
+ Without warehouse: Sin almacén
+ InvoiceOut deleted: Factura eliminada
+ Confirm deletion: Confirmar eliminación
+ Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura?
+ Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
+ InvoiceOut booked: Factura asentada
+ Generate PDF invoice document: Generar PDF de la factura
+ Are you sure you want to generate/regenerate the PDF invoice?: ¿Seguro que quieres generar/regenerar el PDF de la factura?
+ The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado
+ Create a single ticket with all the content of the current invoice: Crear un ticket único con todo el contenido de la factura actual
+ refundInvoiceSuccessMessage: Se ha creado el siguiente ticket de abono {refundTicket}
+ The email can't be empty: El email no puede estar vacío
+
+en:
+ refundInvoiceSuccessMessage: The following refund ticket have been created {refundTicket}
diff --git a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue
index c5c17fa87..a6a28bdde 100644
--- a/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue
+++ b/src/pages/InvoiceOut/Card/InvoiceOutSummary.vue
@@ -7,6 +7,9 @@ import { toCurrency, toDate } from 'src/filters';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import { getUrl } from 'src/composables/getUrl';
+import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue';
+import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
onMounted(async () => {
fetch();
@@ -67,29 +70,33 @@ const taxColumns = ref([
const ticketsColumns = ref([
{
name: 'item',
- label: 'invoiceOut.summary.ticketId',
+ label: t('invoiceOut.summary.ticketId'),
field: (row) => row.id,
sortable: true,
+ align: 'left',
},
{
name: 'quantity',
- label: 'invoiceOut.summary.nickname',
+ label: t('invoiceOut.summary.nickname'),
field: (row) => row.nickname,
sortable: true,
+ align: 'left',
},
{
name: 'landed',
- label: 'invoiceOut.summary.shipped',
+ label: t('invoiceOut.summary.shipped'),
field: (row) => row.shipped,
format: (value) => toDate(value),
sortable: true,
+ align: 'left',
},
{
name: 'landed',
- label: 'invoiceOut.summary.totalWithVat',
+ label: t('invoiceOut.summary.totalWithVat'),
field: (row) => row.totalWithVat,
format: (value) => toCurrency(value),
sortable: true,
+ align: 'left',
},
]);
@@ -105,10 +112,7 @@ const ticketsColumns = ref([
-
+
-
+
@@ -146,17 +147,23 @@ const ticketsColumns = ref([
-
+
-
-
-
- {{ t(col.label) }}
-
-
+
+
+
+ {{ value }}
+
+
+
+
+
+
+
+ {{ value }}
+
+
+
diff --git a/src/pages/InvoiceOut/InvoiceOutGlobal.vue b/src/pages/InvoiceOut/InvoiceOutGlobal.vue
index b4f26aa7c..e8ec2b70e 100644
--- a/src/pages/InvoiceOut/InvoiceOutGlobal.vue
+++ b/src/pages/InvoiceOut/InvoiceOutGlobal.vue
@@ -21,6 +21,7 @@ const {
nPdfs,
totalPdfs,
errors,
+ addresses,
} = storeToRefs(invoiceOutGlobalStore);
const selectedCustomerId = ref(null);
@@ -86,6 +87,14 @@ const selectCustomerId = (id) => {
selectedCustomerId.value = id;
};
+const statusText = computed(() => {
+ return status.value === 'invoicing'
+ ? `${t(`status.${status.value}`)} ${
+ addresses.value[getAddressNumber.value]?.clientId
+ }`
+ : t(`status.${status.value}`);
+});
+
onMounted(() => (stateStore.rightDrawer = true));
onUnmounted(() => {
stateStore.rightDrawer = false;
@@ -103,7 +112,7 @@ onUnmounted(() => {
- {{ t(`status.${status}`) }}
+ {{ statusText }}
{{
t('invoiceOut.globalInvoices.statusCard.percentageText', {
getPercentage: getPercentage,
@@ -154,7 +163,7 @@ onUnmounted(() => {
display: flex;
justify-content: center;
width: 100%;
- background-color: var(--vn-dark);
+ background-color: var(--vn-section-color);
padding: 16px;
.card-section {
@@ -165,7 +174,7 @@ onUnmounted(() => {
.text {
font-size: 14px;
- color: var(--vn-text);
+ color: var(--vn-text-color);
}
}
diff --git a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
index c61b9f7ff..a000d6d4f 100644
--- a/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
+++ b/src/pages/InvoiceOut/InvoiceOutGlobalForm.vue
@@ -13,13 +13,8 @@ const { t } = useI18n();
const invoiceOutGlobalStore = useInvoiceOutGlobalStore();
// invoiceOutGlobalStore state and getters
-const {
- initialDataLoading,
- formInitialData,
-
- invoicing,
- status,
-} = storeToRefs(invoiceOutGlobalStore);
+const { initialDataLoading, formInitialData, invoicing, status } =
+ storeToRefs(invoiceOutGlobalStore);
// invoiceOutGlobalStore actions
const { makeInvoice, setStatusValue } = invoiceOutGlobalStore;
@@ -32,13 +27,7 @@ const printersOptions = ref([]);
const clientsOptions = ref([]);
-const formData = ref({
- companyFk: null,
- invoiceDate: null,
- maxShipped: null,
- clientId: null,
- printer: null,
-});
+const formData = ref({});
const optionsInitialData = computed(() => {
return (
diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue
index 08f893db2..266dac26e 100644
--- a/src/pages/InvoiceOut/InvoiceOutList.vue
+++ b/src/pages/InvoiceOut/InvoiceOutList.vue
@@ -2,25 +2,32 @@
import { onMounted, onUnmounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
-import { exportFile, useQuasar } from 'quasar';
-import { useStateStore } from 'stores/useStateStore';
+
import VnPaginate from 'src/components/ui/VnPaginate.vue';
import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
-import { toDate, toCurrency } from 'src/filters/index';
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
-import InvoiceOutFilter from './InvoiceOutFilter.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import CardList from 'src/components/ui/CardList.vue';
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
+import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
+import CreateManualInvoiceForm from 'src/components/CreateManualInvoiceForm.vue';
+
+import InvoiceOutFilter from './InvoiceOutFilter.vue';
+import { toDate, toCurrency } from 'src/filters/index';
+import { useStateStore } from 'stores/useStateStore';
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
+import { useSession } from 'src/composables/useSession';
const { t } = useI18n();
-const selectedCards = ref(new Map());
-const quasar = useQuasar();
const router = useRouter();
const stateStore = useStateStore();
+const session = useSession();
+const token = session.getToken();
const { viewSummary } = useSummaryDialog();
+const manualInvoiceDialogRef = ref(null);
+const selectedCards = ref(new Map());
+
onMounted(() => (stateStore.rightDrawer = true));
onUnmounted(() => (stateStore.rightDrawer = false));
@@ -52,37 +59,37 @@ const toggleAllCards = (cardsData) => {
}
};
-const downloadCsv = () => {
- if (selectedCards.value.size === 0) return;
- const selectedCardsArray = Array.from(selectedCards.value.values());
- let file;
- for (var i = 0; i < selectedCardsArray.length; i++) {
- if (i == 0) file += Object.keys(selectedCardsArray[i]).join(';') + '\n';
- file +=
- Object.keys(selectedCardsArray[i])
- .map(function (key) {
- return selectedCardsArray[i][key];
- })
- .join(';') + '\n';
- }
- const status = exportFile('file.csv', file, {
- encoding: 'windows-1252',
- mimeType: 'text/csv;charset=windows-1252;',
- });
- if (status === true) {
- quasar.notify({
- message: t('fileAllowed'),
- color: 'positive',
- icon: 'check',
- });
- } else {
- quasar.notify({
- message: t('fileDenied'),
- color: 'negative',
- icon: 'warning',
- });
+const openPdf = () => {
+ try {
+ if (selectedCards.value.size === 0) return;
+ const selectedCardsArray = Array.from(selectedCards.value.values());
+
+ if (selectedCards.value.size === 1) {
+ const [invoiceOut] = selectedCardsArray;
+ const url = `api/InvoiceOuts/${invoiceOut.id}/download?access_token=${token}`;
+ window.open(url, '_blank');
+ } else {
+ const invoiceOutIdsArray = selectedCardsArray.map(
+ (invoiceOut) => invoiceOut.id
+ );
+ const invoiceOutIds = invoiceOutIdsArray.join(',');
+
+ const params = new URLSearchParams({
+ access_token: token,
+ ids: invoiceOutIds,
+ });
+
+ const url = `api/InvoiceOuts/downloadZip?${params}`;
+ window.open(url, '_blank');
+ }
+ } catch (err) {
+ console.error('Error opening PDF');
}
};
+
+const openCreateInvoiceModal = () => {
+ manualInvoiceDialogRef.value.show();
+};
@@ -119,52 +126,21 @@ const downloadCsv = () => {
-
+
-
+ {{ t('downloadPdf') }}
+
{
>
-
+
+
+
+ {{ row?.clientSocialName }}
+
+
+
+
{
/>
-
{
+
+
+
+ {{ t('createInvoice') }}
+
+
+
+
+
+
@@ -246,9 +234,13 @@ en:
fileDenied: Browser denied file download...
fileAllowed: Successful download of CSV file
youCanSearchByInvoiceReference: You can search by invoice reference
+ downloadPdf: Download PDF
+ createInvoice: Make invoice
es:
searchInvoice: Buscar factura emitida
fileDenied: El navegador denegó la descarga de archivos...
fileAllowed: Descarga exitosa de archivo CSV
youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
+ downloadPdf: Descargar PDF
+ createInvoice: Crear factura
diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
index b8fd77714..fb434124c 100644
--- a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
+++ b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue
@@ -1,17 +1,17 @@
-
-
+
+
+ {{ t('Download as CSV') }}
+
@@ -234,31 +169,37 @@ const selectWorkerId = (id) => {
row-key="clientId"
class="full-width q-mt-md"
>
-
-
-
- {{ props.value }}
-
-
-
-
+
+
+ {{ row.clientId }}
+
+
+
+
+
+ {{ row.ticketFk }}
+
+
+
+
+
+ {{ row.comercialName }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -272,4 +213,7 @@ const selectWorkerId = (id) => {
}
-
+
+es:
+ Download as CSV: Descargar como CSV
+
diff --git a/src/pages/Login/VerifyEmail.vue b/src/pages/Login/VerifyEmail.vue
index 4c02e5869..1febd0eaa 100644
--- a/src/pages/Login/VerifyEmail.vue
+++ b/src/pages/Login/VerifyEmail.vue
@@ -57,10 +57,13 @@ onMounted(async () => {
:href="button.url"
>
-
+
-
diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue
index 760c48726..402df1173 100644
--- a/src/pages/Order/Card/OrderCatalogFilter.vue
+++ b/src/pages/Order/Card/OrderCatalogFilter.vue
@@ -420,7 +420,7 @@ const getCategoryClass = (category, params) => {
.category-icon {
border-radius: 50%;
- background-color: var(--vn-light-gray);
+ background-color: var(--vn-accent-color);
font-size: 2.6rem;
padding: 8px;
cursor: pointer;
diff --git a/src/pages/Order/Card/OrderCatalogItem.vue b/src/pages/Order/Card/OrderCatalogItem.vue
index a197ceafc..0e1005493 100644
--- a/src/pages/Order/Card/OrderCatalogItem.vue
+++ b/src/pages/Order/Card/OrderCatalogItem.vue
@@ -88,11 +88,11 @@ const dialog = ref(null);
font-size: 11px;
.label {
- color: var(--vn-label);
+ color: var(--vn-label-color);
}
.value {
- color: var(--vn-text);
+ color: var(--vn-text-color);
}
}
}
@@ -125,7 +125,7 @@ const dialog = ref(null);
gap: 4px;
.subName {
- color: var(--vn-label);
+ color: var(--vn-label-color);
text-transform: uppercase;
}
@@ -163,7 +163,7 @@ const dialog = ref(null);
position: absolute;
bottom: 12px;
right: 12px;
- background: linear-gradient($dark, $primary);
+ background: linear-gradient(var(--vn-section-color), $primary);
border-radius: 50%;
width: 40px;
height: 40px;
diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue
index 488cd5846..a2daedb73 100644
--- a/src/pages/Order/Card/OrderSummary.vue
+++ b/src/pages/Order/Card/OrderSummary.vue
@@ -247,7 +247,7 @@ const detailsColumns = ref([
.subName {
text-transform: uppercase;
- color: var(--vn-label);
+ color: var(--vn-label-color);
}
}
}
diff --git a/src/pages/Order/OrderCatalog.vue b/src/pages/Order/OrderCatalog.vue
index 21442d10d..1ed03c47d 100644
--- a/src/pages/Order/OrderCatalog.vue
+++ b/src/pages/Order/OrderCatalog.vue
@@ -104,7 +104,7 @@ function extractTags(items) {
.no-result {
font-size: 24px;
font-weight: bold;
- color: var(--vn-label);
+ color: var(--vn-label-color);
text-align: center;
}
diff --git a/src/pages/Order/OrderLines.vue b/src/pages/Order/OrderLines.vue
index 4b6c21c75..5a31598e1 100644
--- a/src/pages/Order/OrderLines.vue
+++ b/src/pages/Order/OrderLines.vue
@@ -213,7 +213,7 @@ async function confirmOrder() {
gap: 2%;
.label {
- color: var(--vn-label);
+ color: var(--vn-label-color);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -246,13 +246,13 @@ async function confirmOrder() {
}
.subname {
- color: var(--vn-label);
+ color: var(--vn-label-color);
}
.no-result {
font-size: 24px;
font-weight: bold;
- color: var(--vn-label);
+ color: var(--vn-label-color);
text-align: center;
}
diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue
index b7b233a64..203eaccd1 100644
--- a/src/pages/Order/OrderList.vue
+++ b/src/pages/Order/OrderList.vue
@@ -104,7 +104,7 @@ function navigate(id) {
/>
-
+
{{ toDate(row?.landed) }}
diff --git a/src/pages/Order/OrderVolume.vue b/src/pages/Order/OrderVolume.vue
index 5bb106edc..67f409b45 100644
--- a/src/pages/Order/OrderVolume.vue
+++ b/src/pages/Order/OrderVolume.vue
@@ -106,7 +106,7 @@ const loadVolumes = async (rows) => {
gap: 2%;
.label {
- color: var(--vn-label);
+ color: var(--vn-label-color);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -132,7 +132,7 @@ const loadVolumes = async (rows) => {
.no-result {
font-size: 24px;
font-weight: bold;
- color: var(--vn-label);
+ color: var(--vn-label-color);
text-align: center;
}
diff --git a/src/pages/Route/Cmr/CmrList.vue b/src/pages/Route/Cmr/CmrList.vue
index f2ab45a41..69f030fa0 100644
--- a/src/pages/Route/Cmr/CmrList.vue
+++ b/src/pages/Route/Cmr/CmrList.vue
@@ -139,6 +139,7 @@ function downloadPdfs() {
-
+
{{ t('Total') }}
@@ -213,6 +213,16 @@ function navigateToRouteSummary(event, row) {
{{ toCurrency(total) }}
+
+
+ {{ t('Create invoiceIn') }}
+
+
-
-
-
- {{ t('Create invoiceIn') }}
-
-
-
{
(agencyList = data)" auto-load />
(vehicleList = data)" auto-load />
-
+
@@ -182,7 +182,7 @@ function navigateToRoadmapSummary(event, row) {
-
+
{{ t('Preview') }}
diff --git a/src/pages/Route/RouteTickets.vue b/src/pages/Route/RouteTickets.vue
index 8410232c5..c1ca5507e 100644
--- a/src/pages/Route/RouteTickets.vue
+++ b/src/pages/Route/RouteTickets.vue
@@ -15,8 +15,8 @@ import VnConfirm from 'components/ui/VnConfirm.vue';
import FetchData from 'components/FetchData.vue';
import { openBuscaman } from 'src/utils/buscaman';
import SendSmsDialog from 'components/common/SendSmsDialog.vue';
-import RouteSearchbar from "pages/Route/Card/RouteSearchbar.vue";
-import {useStateStore} from "stores/useStateStore";
+import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue';
+import { useStateStore } from 'stores/useStateStore';
const { t } = useI18n();
const quasar = useQuasar();
@@ -257,7 +257,7 @@ const openSmsDialog = async () => {
-
+
{{ t('Sort routes') }}
diff --git a/src/pages/Shelving/Card/ShelvingDescriptorMenu.vue b/src/pages/Shelving/Card/ShelvingDescriptorMenu.vue
index 684a46807..16351fdd4 100644
--- a/src/pages/Shelving/Card/ShelvingDescriptorMenu.vue
+++ b/src/pages/Shelving/Card/ShelvingDescriptorMenu.vue
@@ -17,15 +17,14 @@ const quasar = useQuasar();
const { t } = useI18n();
function confirmRemove() {
- quasar
- .dialog({
- component: VnConfirm,
- componentProps: {
- title: t('Confirm deletion'),
- message: t('Are you sure you want to delete this shelving?'),
- promise: remove
- },
- })
+ quasar.dialog({
+ component: VnConfirm,
+ componentProps: {
+ title: t('Confirm deletion'),
+ message: t('Are you sure you want to delete this shelving?'),
+ promise: remove,
+ },
+ });
}
async function remove() {
diff --git a/src/pages/Supplier/Card/SupplierConsumption.vue b/src/pages/Supplier/Card/SupplierConsumption.vue
index 08298f503..33d235a5f 100644
--- a/src/pages/Supplier/Card/SupplierConsumption.vue
+++ b/src/pages/Supplier/Card/SupplierConsumption.vue
@@ -194,7 +194,7 @@ onMounted(async () => {
diff --git a/src/pages/Supplier/Card/SupplierContacts.vue b/src/pages/Supplier/Card/SupplierContacts.vue
index 3abe5a9cc..a78c376a9 100644
--- a/src/pages/Supplier/Card/SupplierContacts.vue
+++ b/src/pages/Supplier/Card/SupplierContacts.vue
@@ -117,7 +117,7 @@ onMounted(() => {
diff --git a/src/pages/Supplier/Card/SupplierSummary.vue b/src/pages/Supplier/Card/SupplierSummary.vue
index edc2c742b..9d00ba8f7 100644
--- a/src/pages/Supplier/Card/SupplierSummary.vue
+++ b/src/pages/Supplier/Card/SupplierSummary.vue
@@ -8,6 +8,7 @@ import { getUrl } from 'src/composables/getUrl';
import { useRole } from 'src/composables/useRole';
import { dashIfEmpty } from 'src/filters';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
onUpdated(() => summaryRef.value.fetch());
diff --git a/src/pages/Ticket/Card/TicketDescriptor.vue b/src/pages/Ticket/Card/TicketDescriptor.vue
index f0ded019b..dfbcfc106 100644
--- a/src/pages/Ticket/Card/TicketDescriptor.vue
+++ b/src/pages/Ticket/Card/TicketDescriptor.vue
@@ -98,7 +98,10 @@ const setData = (entity) =>
-
+
{{ entity.ticketState.state.name }}
diff --git a/src/pages/Ticket/Card/TicketDescriptorMenu.vue b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
index 95f6a94d9..c7784bc2a 100644
--- a/src/pages/Ticket/Card/TicketDescriptorMenu.vue
+++ b/src/pages/Ticket/Card/TicketDescriptorMenu.vue
@@ -3,7 +3,7 @@ import axios from 'axios';
import { ref } from 'vue';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
-import { useRouter, useRoute } from 'vue-router';
+import { useRouter } from 'vue-router';
import { usePrintService } from 'composables/usePrintService';
import SendEmailDialog from 'components/common/SendEmailDialog.vue';
import VnConfirm from 'components/ui/VnConfirm.vue';
@@ -17,13 +17,49 @@ const props = defineProps({
},
});
-const router = useRouter();
-const route = useRoute();
-const quasar = useQuasar();
+const { push, currentRoute } = useRouter();
+const { dialog, notify } = useQuasar();
const { t } = useI18n();
const { openReport, sendEmail } = usePrintService();
const ticket = ref(props.ticket);
+const ticketId = currentRoute.value.params.id;
+const actions = {
+ clone: async () => {
+ const opts = { message: t('Ticket cloned'), type: 'positive' };
+ let clonedTicketId;
+
+ try {
+ const { data } = await axios.post(`Tickets/${ticketId}/clone`, {
+ shipped: ticket.value.shipped,
+ });
+ clonedTicketId = data;
+ } catch (e) {
+ opts.message = t('It was not able to clone the ticket');
+ opts.type = 'negative';
+ } finally {
+ notify(opts);
+
+ if (clonedTicketId)
+ push({ name: 'TicketSummary', params: { id: clonedTicketId } });
+ }
+ },
+ remove: async () => {
+ try {
+ await axios.post(`Tickets/${ticketId}/setDeleted`);
+
+ notify({ message: t('Ticket deleted'), type: 'positive' });
+ notify({
+ message: t('You can undo this action within the first hour'),
+ icon: 'info',
+ });
+
+ push({ name: 'TicketList' });
+ } catch (e) {
+ notify({ message: e.message, type: 'negative' });
+ }
+ },
+};
function openDeliveryNote(type = 'deliveryNote', documentType = 'pdf') {
const path = `Tickets/${ticket.value.id}/delivery-note-${documentType}`;
@@ -35,7 +71,7 @@ function openDeliveryNote(type = 'deliveryNote', documentType = 'pdf') {
function sendDeliveryNoteConfirmation(type = 'deliveryNote', documentType = 'pdf') {
const customer = ticket.value.client;
- quasar.dialog({
+ dialog({
component: SendEmailDialog,
componentProps: {
data: {
@@ -67,7 +103,7 @@ function showSmsDialog(template, customData) {
const address = ticket.value.address;
const client = ticket.value.client;
const phone =
- route.params.phone ||
+ currentRoute.value.params.phone ||
address.mobile ||
address.phone ||
client.mobile ||
@@ -82,7 +118,7 @@ function showSmsDialog(template, customData) {
Object.assign(data, customData);
}
- quasar.dialog({
+ dialog({
component: VnSmsDialog,
componentProps: {
phone: phone,
@@ -95,42 +131,26 @@ function showSmsDialog(template, customData) {
}
async function showSmsDialogWithChanges() {
- const query = `TicketLogs/${route.params.id}/getChanges`;
+ const query = `TicketLogs/${ticketId}/getChanges`;
const response = await axios.get(query);
showSmsDialog('orderChanges', { changes: response.data });
}
async function sendSms(body) {
- await axios.post(`Tickets/${route.params.id}/sendSms`, body);
- quasar.notify({
+ await axios.post(`Tickets/${ticketId}/sendSms`, body);
+ notify({
message: 'Notification sent',
type: 'positive',
});
}
-function confirmDelete() {
- quasar
- .dialog({
- component: VnConfirm,
- componentProps: {
- promise: remove,
- },
- })
- .onOk(async () => await router.push({ name: 'TicketList' }));
-}
-
-async function remove() {
- const id = route.params.id;
- await axios.post(`Tickets/${id}/setDeleted`);
-
- quasar.notify({
- message: t('Ticket deleted'),
- type: 'positive',
- });
- quasar.notify({
- message: t('You can undo this action within the first hour'),
- icon: 'info',
+function openConfirmDialog(callback) {
+ dialog({
+ component: VnConfirm,
+ componentProps: {
+ promise: actions[callback],
+ },
});
}
@@ -227,9 +247,15 @@ async function remove() {
+
+
+
+
+ {{ t('To clone ticket') }}
+
-
+
@@ -253,4 +279,7 @@ es:
Order changes: Cambios del pedido
Ticket deleted: Ticket eliminado
You can undo this action within the first hour: Puedes deshacer esta acción dentro de la primera hora
+ To clone ticket: Clonar ticket
+ Ticket cloned: Ticked clonado
+ It was not able to clone the ticket: No se pudo clonar el ticket
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index fbca21086..85d98f353 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -12,6 +12,7 @@ import VnLv from 'src/components/ui/VnLv.vue';
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import { getUrl } from 'src/composables/getUrl';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
onUpdated(() => summaryRef.value.fetch());
@@ -74,7 +75,7 @@ async function changeState(value) {
code: value,
};
- await axios.post(`TicketTrackings/changeState`, formData);
+ await axios.post(`Tickets/state`, formData);
router.go(route.fullPath);
}
@@ -102,8 +103,8 @@ async function changeState(value) {
@@ -147,10 +148,10 @@ async function changeState(value) {
-
+
@@ -193,10 +194,10 @@ async function changeState(value) {
/>
-
+
-
+
-
+
@@ -396,10 +397,7 @@ async function changeState(value) {
class="vn-max"
v-if="ticket.packagings.length > 0 || ticket.services.length > 0"
>
-
+
@@ -416,11 +414,10 @@ async function changeState(value) {
-
-
+
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index 72c2da57c..c5d25fed2 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -89,6 +89,7 @@ function navigate(id) {
-
+
{
/>
-
+
{
-
-
-
-
-
{
+
+
+
+
+
{
{
{
@@ -172,7 +182,9 @@ onMounted(async () => {
en:
addEntry: Add entry
+ searchByIdOrReference: Search by ID or reference
es:
addEntry: Añadir entrada
+ searchByIdOrReference: Buscar por ID o por referencia
diff --git a/src/pages/Wagon/Type/WagonTypeList.vue b/src/pages/Wagon/Type/WagonTypeList.vue
index a7c713039..23f56e4c3 100644
--- a/src/pages/Wagon/Type/WagonTypeList.vue
+++ b/src/pages/Wagon/Type/WagonTypeList.vue
@@ -61,7 +61,6 @@ async function remove(row) {
+import VnLog from 'src/components/common/VnLog.vue';
+
+
+
+
diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue
index 9d0e18b15..dad21cda5 100644
--- a/src/pages/Worker/Card/WorkerSummary.vue
+++ b/src/pages/Worker/Card/WorkerSummary.vue
@@ -8,6 +8,7 @@ import VnLv from 'src/components/ui/VnLv.vue';
import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue';
import CardSummary from 'components/ui/CardSummary.vue';
import VnUserLink from 'src/components/ui/VnUserLink.vue';
+import VnTitle from 'src/components/common/VnTitle.vue';
const route = useRoute();
const { t } = useI18n();
@@ -71,10 +72,10 @@ const filter = {
-
+
-
+
diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue
index 5214a9066..b11d531dd 100644
--- a/src/pages/Worker/WorkerList.vue
+++ b/src/pages/Worker/WorkerList.vue
@@ -82,7 +82,6 @@ const redirectToCreateView = () => {
import('src/pages/InvoiceOut/InvoiceOutNegativeBases.vue'),
diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js
index 1c722afe8..448aab79c 100644
--- a/src/router/modules/worker.js
+++ b/src/router/modules/worker.js
@@ -12,7 +12,7 @@ export default {
redirect: { name: 'WorkerMain' },
menus: {
main: ['WorkerList', 'WorkerDepartment'],
- card: ['WorkerNotificationsManager', 'WorkerPda'],
+ card: ['WorkerNotificationsManager', 'WorkerPda', 'WorkerLog'],
departmentCard: ['BasicData'],
},
children: [
@@ -85,6 +85,15 @@ export default {
},
component: () => import('src/pages/Worker/Card/WorkerPda.vue'),
},
+ {
+ name: 'WorkerLog',
+ path: 'log',
+ meta: {
+ title: 'log',
+ icon: 'vn:History',
+ },
+ component: () => import('src/pages/Worker/Card/WorkerLog.vue'),
+ },
],
},
],
diff --git a/src/stores/invoiceOutGlobal.js b/src/stores/invoiceOutGlobal.js
index 7151aac5f..b1bcc0e7d 100644
--- a/src/stores/invoiceOutGlobal.js
+++ b/src/stores/invoiceOutGlobal.js
@@ -73,6 +73,9 @@ export const useInvoiceOutGlobalStore = defineStore({
const stringDate = data.issued.substring(0, 10);
this.minInvoicingDate = stringDate;
this.formInitialData.invoiceDate = stringDate;
+
+ this.minInvoicingDate = new Date(data.issued);
+ this.formInitialData.invoiceDate = this.minInvoicingDate;
} catch (err) {
console.error('Error fetching invoice out global initial data');
throw new Error();
@@ -103,12 +106,8 @@ export const useInvoiceOutGlobalStore = defineStore({
if (clientsToInvoice == 'all') params.clientId = undefined;
- const addressesResponse = await await axios.post(
- 'InvoiceOuts/clientsToInvoice',
- params
- );
-
- this.addresses = addressesResponse.data;
+ const { data } = await axios.post('InvoiceOuts/clientsToInvoice', params);
+ this.addresses = data;
if (!this.addresses || !this.addresses.length > 0) {
notify(
@@ -118,9 +117,9 @@ export const useInvoiceOutGlobalStore = defineStore({
throw new Error("There aren't addresses to invoice");
}
- this.addresses.forEach(async (address) => {
+ for (const address of this.addresses) {
await this.invoiceClient(address, formData);
- });
+ }
} catch (err) {
this.handleError(err);
}
@@ -186,15 +185,10 @@ export const useInvoiceOutGlobalStore = defineStore({
this.status = 'invoicing';
this.invoicing = true;
- const invoiceResponse = await axios.post(
- 'InvoiceOuts/invoiceClient',
- params
- );
-
- if (invoiceResponse.data) {
- this.makePdfAndNotify(invoiceResponse.data, address);
- }
+ const { data } = await axios.post('InvoiceOuts/invoiceClient', params);
+ if (data) await this.makePdfAndNotify(data, address);
+ this.addressIndex++;
this.isInvoicing = false;
} catch (err) {
if (
@@ -203,8 +197,7 @@ export const useInvoiceOutGlobalStore = defineStore({
err.response.status >= 400 &&
err.response.status < 500
) {
- this.invoiceClientError(address, err.response);
- this.addressIndex++;
+ this.invoiceClientError(address, err.response?.data?.error?.message);
return;
} else {
this.invoicing = false;
@@ -227,12 +220,11 @@ export const useInvoiceOutGlobalStore = defineStore({
this.nPdfs++;
this.nRequests--;
} catch (err) {
- this.invoiceClientError(client, err, true);
+ this.invoiceClientError(client, err.response?.data?.error?.message, true);
}
},
- invoiceClientError(client, response, isWarning) {
- const message = response.data?.error?.message || response.message;
+ invoiceClientError(client, message, isWarning) {
this.errors.unshift({ client, message, isWarning });
},
diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
index ce79dc976..5e2a5aa4c 100644
--- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
@@ -4,7 +4,7 @@ describe('InvoiceInList', () => {
const firstChipId =
':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content';
const firstDetailBtn = '.q-card:nth-child(1) .q-btn:nth-child(2)';
- const summaryHeaders = '.summaryBody .header';
+ const summaryHeaders = '.summaryBody .header-link';
const screen = '.q-page-container > .q-drawer-container > .fullscreen';
beforeEach(() => {
@@ -17,7 +17,7 @@ describe('InvoiceInList', () => {
cy.get(firstChipId)
.invoke('text')
.then((content) => {
- const id = content.substring(4);
+ const id = content.replace(/\D/g, '');
cy.get(firstCard).click();
cy.url().should('include', `/invoice-in/${id}/summary`);
});
diff --git a/test/cypress/integration/ticket/ticketDescriptor.spec.js b/test/cypress/integration/ticket/ticketDescriptor.spec.js
new file mode 100644
index 000000000..c212d3b4a
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketDescriptor.spec.js
@@ -0,0 +1,27 @@
+///
+describe('Ticket descriptor', () => {
+ const toCloneOpt = '.q-list > :nth-child(5)';
+ const warehouseValue = '.summaryBody > :nth-child(2) > :nth-child(6) > .value > span';
+ const summaryHeader = '.summaryHeader > div';
+
+ beforeEach(() => {
+ const ticketId = 1;
+
+ cy.login('developer');
+ cy.visit(`/#/ticket/${ticketId}/summary`);
+ });
+
+ it('should clone the ticket without warehouse', () => {
+ cy.openLeftMenu();
+ cy.openActionsDescriptor();
+ cy.get(toCloneOpt).click();
+ cy.clickConfirm();
+ cy.get(warehouseValue).contains('-');
+ cy.get(summaryHeader)
+ .invoke('text')
+ .then((text) => {
+ const [, owner] = text.split('-');
+ cy.wrap(owner.trim()).should('eq', 'Bruce Wayne (1101)');
+ });
+ });
+});
diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js
index bc4b2383e..c950f9fed 100644
--- a/test/cypress/integration/worker/workerList.spec.js
+++ b/test/cypress/integration/worker/workerList.spec.js
@@ -16,7 +16,10 @@ describe('WorkerList', () => {
it('should open the worker summary', () => {
cy.openListSummary(0);
cy.get('.summaryHeader div').should('have.text', '1110 - Jessica Jones');
- cy.get('.summary .header-link').eq(0).invoke('text').should('include', 'Basic data');
- cy.get('.summary .header-link').eq(1).should('have.text', 'User data');
+ cy.get('.summary .header-link')
+ .eq(0)
+ .invoke('text')
+ .should('include', 'Basic data');
+ cy.get('.summary .header-link').eq(1).should('have.text', 'User data ');
});
});
diff --git a/test/vitest/__tests__/components/Paginate.spec.js b/test/vitest/__tests__/components/Paginate.spec.js
index f3bf01489..7bd0c1eda 100644
--- a/test/vitest/__tests__/components/Paginate.spec.js
+++ b/test/vitest/__tests__/components/Paginate.spec.js
@@ -49,6 +49,8 @@ describe('VnPaginate', () => {
],
});
vm.arrayData.hasMoreData.value = true;
+ await vm.$nextTick();
+
vm.store.data = [
{ id: 1, name: 'Tony Stark' },
{ id: 2, name: 'Jessica Jones' },