diff --git a/modules/entry/front/buy/index/index.js b/modules/entry/front/buy/index/index.js
index c991b745b..9131c31f6 100644
--- a/modules/entry/front/buy/index/index.js
+++ b/modules/entry/front/buy/index/index.js
@@ -53,12 +53,8 @@ export default class Controller extends Section {
}
toggleGroupingMode(buy, mode) {
- const grouping = 1;
- const packing = 2;
- const groupingMode = mode === 'grouping' ? grouping : packing;
-
- const newGroupingMode = buy.groupingMode === groupingMode ? 0 : groupingMode;
-
+ const groupingMode = mode === 'grouping' ? mode : 'packing';
+ const newGroupingMode = buy.groupingMode === groupingMode ? null : groupingMode;
const params = {
groupingMode: newGroupingMode
};
diff --git a/modules/entry/front/buy/index/index.spec.js b/modules/entry/front/buy/index/index.spec.js
index b9d5fab51..f5c6d1bdb 100644
--- a/modules/entry/front/buy/index/index.spec.js
+++ b/modules/entry/front/buy/index/index.spec.js
@@ -57,45 +57,34 @@ describe('Entry buy', () => {
describe('toggleGroupingMode()', () => {
it(`should toggle grouping mode from grouping to packing`, () => {
- const grouping = 1;
- const packing = 2;
- const buy = {id: 999, groupingMode: grouping};
+ const buy = {id: 999, groupingMode: 'grouping'};
const query = `Buys/${buy.id}`;
- $httpBackend.expectPATCH(query, {groupingMode: packing}).respond(200);
+ $httpBackend.expectPATCH(query, {groupingMode: 'packing'}).respond(200);
controller.toggleGroupingMode(buy, 'packing');
$httpBackend.flush();
});
it(`should toggle grouping mode from packing to grouping`, () => {
- const grouping = 1;
- const packing = 2;
- const buy = {id: 999, groupingMode: packing};
-
+ const buy = {id: 999, groupingMode: 'packing'};
const query = `Buys/${buy.id}`;
- $httpBackend.expectPATCH(query, {groupingMode: grouping}).respond(200);
+ $httpBackend.expectPATCH(query, {groupingMode: 'grouping'}).respond(200);
controller.toggleGroupingMode(buy, 'grouping');
$httpBackend.flush();
});
it(`should toggle off the grouping mode if it was packing to packing`, () => {
- const noGrouping = 0;
- const packing = 2;
- const buy = {id: 999, groupingMode: packing};
-
+ const buy = {id: 999, groupingMode: 'packing'};
const query = `Buys/${buy.id}`;
- $httpBackend.expectPATCH(query, {groupingMode: noGrouping}).respond(200);
+ $httpBackend.expectPATCH(query, {groupingMode: null}).respond(200);
controller.toggleGroupingMode(buy, 'packing');
$httpBackend.flush();
});
it(`should toggle off the grouping mode if it was grouping to grouping`, () => {
- const noGrouping = 0;
- const grouping = 1;
- const buy = {id: 999, groupingMode: grouping};
-
+ const buy = {id: 999, groupingMode: 'grouping'};
const query = `Buys/${buy.id}`;
- $httpBackend.expectPATCH(query, {groupingMode: noGrouping}).respond(200);
+ $httpBackend.expectPATCH(query, {groupingMode: null}).respond(200);
controller.toggleGroupingMode(buy, 'grouping');
$httpBackend.flush();
});
diff --git a/modules/entry/front/latest-buys/index.html b/modules/entry/front/latest-buys/index.html
index 16e039cf0..2e6de83b9 100644
--- a/modules/entry/front/latest-buys/index.html
+++ b/modules/entry/front/latest-buys/index.html
@@ -143,12 +143,12 @@
-
+
{{::buy.packing | dashIfEmpty}}
|
-
+
{{::buy.grouping | dashIfEmpty}}
|
diff --git a/modules/entry/front/summary/index.html b/modules/entry/front/summary/index.html
index 655dcd66f..baa310bb6 100644
--- a/modules/entry/front/summary/index.html
+++ b/modules/entry/front/summary/index.html
@@ -121,12 +121,12 @@
{{::line.packagingFk | dashIfEmpty}} |
{{::line.weight}} |
-
+
{{::line.packing | dashIfEmpty}}
|
-
+
{{::line.grouping | dashIfEmpty}}
diff --git a/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js b/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js
index c188a511d..f21dad9f2 100644
--- a/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js
+++ b/modules/invoiceIn/back/methods/invoice-in-due-day/specs/new.spec.js
@@ -13,11 +13,10 @@ describe('invoiceInDueDay new()', () => {
it('should correctly create a new due day', async() => {
const userId = 9;
- const invoiceInFk = 6;
+ const invoiceInFk = 3;
const ctx = {
req: {
-
accessToken: {userId: userId},
}
};
diff --git a/modules/invoiceIn/back/methods/invoice-in/exchangeRateUpdate.js b/modules/invoiceIn/back/methods/invoice-in/exchangeRateUpdate.js
new file mode 100644
index 000000000..989b1d4a2
--- /dev/null
+++ b/modules/invoiceIn/back/methods/invoice-in/exchangeRateUpdate.js
@@ -0,0 +1,78 @@
+const axios = require('axios');
+const {DOMParser} = require('xmldom');
+const UserError = require('vn-loopback/util/user-error');
+
+module.exports = Self => {
+ Self.remoteMethod('exchangeRateUpdate', {
+ description: 'Updates the exchange rates from an XML feed',
+ accessType: 'WRITE',
+ accepts: [],
+ http: {
+ path: '/exchangeRateUpdate',
+ verb: 'post'
+ }
+ });
+
+ Self.exchangeRateUpdate = async() => {
+ const response = await axios.get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml');
+ const xmlData = response.data;
+
+ const doc = new DOMParser({errorHandler: {warning: () => {}}})?.parseFromString(xmlData, 'text/xml');
+ const cubes = doc?.getElementsByTagName('Cube');
+ if (!cubes || cubes.length === 0)
+ throw new UserError('No cubes found. Exiting the method.');
+
+ const models = Self.app.models;
+
+ const maxDateRecord = await models.ReferenceRate.findOne({order: 'dated DESC'});
+
+ const maxDate = maxDateRecord?.dated ? new Date(maxDateRecord.dated) : null;
+
+ for (const cube of Array.from(cubes)) {
+ if (cube.nodeType === doc.ELEMENT_NODE && cube.attributes.getNamedItem('time')) {
+ const xmlDate = new Date(cube.getAttribute('time'));
+ const xmlDateWithoutTime = new Date(xmlDate.getFullYear(), xmlDate.getMonth(), xmlDate.getDate());
+ if (!maxDate || maxDate < xmlDateWithoutTime) {
+ for (const rateCube of Array.from(cube.childNodes)) {
+ if (rateCube.nodeType === doc.ELEMENT_NODE) {
+ const currencyCode = rateCube.getAttribute('currency');
+ const rate = rateCube.getAttribute('rate');
+ if (['USD', 'CNY', 'GBP'].includes(currencyCode)) {
+ const currency = await models.Currency.findOne({where: {code: currencyCode}});
+ if (!currency) throw new UserError(`Currency not found for code: ${currencyCode}`);
+ const existingRate = await models.ReferenceRate.findOne({
+ where: {currencyFk: currency.id, dated: xmlDate}
+ });
+
+ if (existingRate) {
+ if (existingRate.value !== rate)
+ await existingRate.updateAttributes({value: rate});
+ } else {
+ await models.ReferenceRate.create({
+ currencyFk: currency.id,
+ dated: xmlDate,
+ value: rate
+ });
+ }
+ const monday = 1;
+ if (xmlDateWithoutTime.getDay() === monday) {
+ const saturday = new Date(xmlDateWithoutTime);
+ saturday.setDate(xmlDateWithoutTime.getDate() - 2);
+ const sunday = new Date(xmlDateWithoutTime);
+ sunday.setDate(xmlDateWithoutTime.getDate() - 1);
+
+ for (const date of [saturday, sunday]) {
+ await models.ReferenceRate.upsertWithWhere(
+ {currencyFk: currency.id, dated: date},
+ {currencyFk: currency.id, dated: date, value: rate}
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+};
diff --git a/modules/invoiceIn/back/methods/invoice-in/invoiceInPdf.js b/modules/invoiceIn/back/methods/invoice-in/invoiceInPdf.js
index 681a19fc6..1e9da86a4 100644
--- a/modules/invoiceIn/back/methods/invoice-in/invoiceInPdf.js
+++ b/modules/invoiceIn/back/methods/invoice-in/invoiceInPdf.js
@@ -29,7 +29,8 @@ module.exports = Self => {
http: {
path: '/:id/invoice-in-pdf',
verb: 'GET'
- }
+ },
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.invoiceInPdf = (ctx, id) => Self.printReport(ctx, id, 'invoiceIn');
diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/exchangeRateUpdate.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/exchangeRateUpdate.spec.js
new file mode 100644
index 000000000..0fd7ea165
--- /dev/null
+++ b/modules/invoiceIn/back/methods/invoice-in/specs/exchangeRateUpdate.spec.js
@@ -0,0 +1,52 @@
+describe('exchangeRateUpdate functionality', function() {
+ const axios = require('axios');
+ const models = require('vn-loopback/server/server').models;
+
+ beforeEach(function() {
+ spyOn(axios, 'get').and.returnValue(Promise.resolve({
+ data: `
+
+
+
+
+ `
+ }));
+ });
+
+ it('should process XML data and update or create rates in the database', async function() {
+ spyOn(models.ReferenceRate, 'findOne').and.returnValue(Promise.resolve(null));
+ spyOn(models.ReferenceRate, 'create').and.returnValue(Promise.resolve());
+
+ await models.InvoiceIn.exchangeRateUpdate();
+
+ expect(models.ReferenceRate.create).toHaveBeenCalledTimes(2);
+ });
+
+ it('should not create or update rates when no XML data is available', async function() {
+ axios.get.and.returnValue(Promise.resolve({}));
+ spyOn(models.ReferenceRate, 'create');
+
+ let thrownError = null;
+ try {
+ await models.InvoiceIn.exchangeRateUpdate();
+ } catch (error) {
+ thrownError = error;
+ }
+
+ expect(thrownError.message).toBe('No cubes found. Exiting the method.');
+ });
+
+ it('should handle errors gracefully', async function() {
+ axios.get.and.returnValue(Promise.reject(new Error('Network error')));
+ let error;
+
+ try {
+ await models.InvoiceIn.exchangeRateUpdate();
+ } catch (e) {
+ error = e;
+ }
+
+ expect(error).toBeDefined();
+ expect(error.message).toBe('Network error');
+ });
+});
diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/filter.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/filter.spec.js
index 9834989fc..ff2164783 100644
--- a/modules/invoiceIn/back/methods/invoice-in/specs/filter.spec.js
+++ b/modules/invoiceIn/back/methods/invoice-in/specs/filter.spec.js
@@ -158,7 +158,7 @@ describe('InvoiceIn filter()', () => {
const result = await models.InvoiceIn.filter(ctx, {}, options);
- expect(result.length).toEqual(6);
+ expect(result.length).toEqual(5);
await tx.rollback();
} catch (e) {
@@ -180,7 +180,7 @@ describe('InvoiceIn filter()', () => {
const result = await models.InvoiceIn.filter(ctx, {}, options);
- expect(result.length).toEqual(6);
+ expect(result.length).toEqual(5);
expect(result[0].isBooked).toBeTruthy();
await tx.rollback();
diff --git a/modules/invoiceIn/back/methods/invoice-in/specs/toUnbook.spec.js b/modules/invoiceIn/back/methods/invoice-in/specs/toUnbook.spec.js
new file mode 100644
index 000000000..b7d98e307
--- /dev/null
+++ b/modules/invoiceIn/back/methods/invoice-in/specs/toUnbook.spec.js
@@ -0,0 +1,32 @@
+const models = require('vn-loopback/server/server').models;
+
+describe('invoiceIn toUnbook()', () => {
+ it('should check that invoiceIn is unbooked', async() => {
+ const userId = 1;
+ const ctx = {
+ req: {
+
+ accessToken: {userId: userId},
+ headers: {origin: 'http://localhost:5000'},
+ }
+ };
+ const invoiceInId = 1;
+ const tx = await models.InvoiceIn.beginTransaction({});
+ const options = {transaction: tx};
+
+ try {
+ await models.InvoiceIn.toBook(ctx, invoiceInId, options);
+ const bookEntry = await models.InvoiceIn.toUnbook(ctx, invoiceInId, options);
+ const invoiceIn = await models.InvoiceIn.findById(invoiceInId, null, options);
+
+ expect(bookEntry.accountingEntries).toEqual(4);
+ expect(bookEntry.isLinked).toBeFalsy();
+ expect(invoiceIn.isBooked).toEqual(false);
+
+ await tx.rollback();
+ } catch (e) {
+ await tx.rollback();
+ throw e;
+ }
+ });
+});
diff --git a/modules/invoiceIn/back/methods/invoice-in/toBook.js b/modules/invoiceIn/back/methods/invoice-in/toBook.js
index 778742911..c3be5f8fc 100644
--- a/modules/invoiceIn/back/methods/invoice-in/toBook.js
+++ b/modules/invoiceIn/back/methods/invoice-in/toBook.js
@@ -32,7 +32,7 @@ module.exports = Self => {
}
try {
- await Self.rawSql(`CALL vn.invoiceIn_booking(?)`, [id], myOptions);
+ await Self.rawSql(`CALL vn.invoiceIn_booking(?, NULL)`, [id], myOptions);
if (tx) await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
diff --git a/modules/invoiceIn/back/methods/invoice-in/toUnbook.js b/modules/invoiceIn/back/methods/invoice-in/toUnbook.js
new file mode 100644
index 000000000..a697e9ddc
--- /dev/null
+++ b/modules/invoiceIn/back/methods/invoice-in/toUnbook.js
@@ -0,0 +1,80 @@
+module.exports = Self => {
+ Self.remoteMethodCtx('toUnbook', {
+ description: 'To unbook the invoiceIn',
+ accessType: 'WRITE',
+ accepts: {
+ arg: 'id',
+ type: 'number',
+ required: true,
+ description: 'The invoiceIn id',
+ http: {source: 'path'}
+ },
+ returns: {
+ type: 'object',
+ root: true
+ },
+ http: {
+ path: '/:id/toUnbook',
+ verb: 'POST'
+ }
+ });
+
+ Self.toUnbook = async(ctx, invoiceInId, options) => {
+ let tx;
+ const models = Self.app.models;
+ const myOptions = {userId: ctx.req.accessToken.userId};
+
+ if (typeof options == 'object')
+ Object.assign(myOptions, options);
+
+ if (!myOptions.transaction) {
+ tx = await Self.beginTransaction({});
+ myOptions.transaction = tx;
+ }
+
+ try {
+ let isLinked;
+ let accountingEntries;
+
+ let bookEntry = await models.Xdiario.findOne({
+ fields: ['ASIEN'],
+ where: {
+ and: [
+ {key: invoiceInId},
+ {enlazado: false},
+ {enlazadoSage: false}
+ ]
+ }
+ }, myOptions);
+
+ let asien = bookEntry?.ASIEN;
+ if (asien) {
+ accountingEntries = await models.Xdiario.count({ASIEN: asien}, myOptions);
+
+ await models.Xdiario.destroyAll({ASIEN: asien}, myOptions);
+ await Self.updateAll({id: invoiceInId}, {isBooked: false}, myOptions);
+ } else {
+ const linkedBookEntry = await models.Xdiario.findOne({
+ fields: ['ASIEN'],
+ where: {
+ key: invoiceInId,
+ and: [{or: [{enlazado: true, enlazadoSage: true}]}]
+ }
+ }, myOptions);
+
+ asien = linkedBookEntry?.ASIEN;
+ isLinked = true;
+ }
+ if (tx) await tx.commit();
+
+ return {
+ isLinked,
+ bookEntry: asien,
+ accountingEntries
+ };
+ } catch (e) {
+ if (tx) await tx.rollback();
+ throw e;
+ }
+ };
+};
diff --git a/modules/invoiceIn/back/methods/invoice-in/updateInvoiceIn.js b/modules/invoiceIn/back/methods/invoice-in/updateInvoiceIn.js
new file mode 100644
index 000000000..92a1ba8ee
--- /dev/null
+++ b/modules/invoiceIn/back/methods/invoice-in/updateInvoiceIn.js
@@ -0,0 +1,104 @@
+module.exports = Self => {
+ Self.remoteMethodCtx('updateInvoiceIn', {
+ description: 'To update the invoiceIn attributes',
+ accessType: 'WRITE',
+ accepts: [{
+ arg: 'id',
+ type: 'number',
+ required: true,
+ description: 'The invoiceIn id',
+ http: {source: 'path'}
+ }, {
+ arg: 'supplierFk',
+ type: 'number',
+ required: true
+ }, {
+ arg: 'supplierRef',
+ type: 'any',
+ }, {
+ arg: 'issued',
+ type: 'any',
+ }, {
+ arg: 'operated',
+ type: 'any',
+ }, {
+ arg: 'deductibleExpenseFk',
+ type: 'any',
+ }, {
+ arg: 'dmsFk',
+ type: 'any',
+ }, {
+ arg: 'bookEntried',
+ type: 'any',
+ }, {
+ arg: 'booked',
+ type: 'any',
+ }, {
+ arg: 'currencyFk',
+ type: 'number',
+ required: true
+ }, {
+ arg: 'companyFk',
+ type: 'any',
+ }, {
+ arg: 'withholdingSageFk',
+ type: 'any',
+ },
+ ],
+ returns: {
+ type: 'object',
+ root: true
+ },
+ http: {
+ path: '/:id/updateInvoiceIn',
+ verb: 'PATCH'
+ }
+ });
+
+ Self.updateInvoiceIn = async(ctx,
+ id,
+ supplierFk,
+ supplierRef,
+ issued,
+ operated,
+ deductibleExpenseFk,
+ dmsFk,
+ bookEntried,
+ booked,
+ currencyFk,
+ companyFk,
+ withholdingSageFk,
+ options
+ ) => {
+ let tx;
+ const myOptions = {userId: ctx.req.accessToken.userId};
+
+ if (typeof options == 'object') Object.assign(myOptions, options);
+
+ if (!myOptions.transaction) {
+ tx = await Self.beginTransaction({});
+ myOptions.transaction = tx;
+ }
+
+ try {
+ const invoiceIn = await Self.findById(id, null, myOptions);
+ invoiceIn.updateAttributes({supplierFk,
+ supplierRef,
+ issued,
+ operated,
+ deductibleExpenseFk,
+ dmsFk,
+ bookEntried,
+ booked,
+ currencyFk,
+ companyFk,
+ withholdingSageFk
+ }, myOptions);
+ if (tx) await tx.commit();
+ return invoiceIn;
+ } catch (e) {
+ if (tx) await tx.rollback();
+ throw e;
+ }
+ };
+};
diff --git a/modules/invoiceIn/back/models/invoice-in-config.json b/modules/invoiceIn/back/models/invoice-in-config.json
index c0236e654..638a97fa3 100644
--- a/modules/invoiceIn/back/models/invoice-in-config.json
+++ b/modules/invoiceIn/back/models/invoice-in-config.json
@@ -26,7 +26,7 @@
"sageWithholding": {
"type": "belongsTo",
"model": "SageWithholding",
- "foreignKey": "sageWithholdingFk"
+ "foreignKey": "sageFarmerWithholdingFk"
}
},
"acls": [{
diff --git a/modules/invoiceIn/back/models/invoice-in.js b/modules/invoiceIn/back/models/invoice-in.js
index af5efbcdf..1e69c0ef8 100644
--- a/modules/invoiceIn/back/models/invoice-in.js
+++ b/modules/invoiceIn/back/models/invoice-in.js
@@ -10,6 +10,9 @@ module.exports = Self => {
require('../methods/invoice-in/invoiceInEmail')(Self);
require('../methods/invoice-in/getSerial')(Self);
require('../methods/invoice-in/corrective')(Self);
+ require('../methods/invoice-in/exchangeRateUpdate')(Self);
+ require('../methods/invoice-in/toUnbook')(Self);
+ require('../methods/invoice-in/updateInvoiceIn')(Self);
Self.rewriteDbError(function(err) {
if (err.code === 'ER_ROW_IS_REFERENCED_2' && err.sqlMessage.includes('vehicleInvoiceIn'))
diff --git a/modules/invoiceIn/front/basic-data/index.html b/modules/invoiceIn/front/basic-data/index.html
index a22abbb33..fbb9b05a2 100644
--- a/modules/invoiceIn/front/basic-data/index.html
+++ b/modules/invoiceIn/front/basic-data/index.html
@@ -1,4 +1,4 @@
-
+
diff --git a/modules/invoiceIn/front/descriptor/index.js b/modules/invoiceIn/front/descriptor/index.js
index e005211a3..8fe270fa0 100644
--- a/modules/invoiceIn/front/descriptor/index.js
+++ b/modules/invoiceIn/front/descriptor/index.js
@@ -112,7 +112,7 @@ class Controller extends Descriptor {
}
isAgricultural() {
- return this.invoiceIn.supplier.sageWithholdingFk == this.config[0].sageWithholdingFk;
+ return this.invoiceIn.supplier.sageWithholdingFk == this.config[0].sageFarmerWithholdingFk;
}
}
diff --git a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js
index 043dfbead..c46da0ba5 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/createManualInvoice.js
@@ -46,12 +46,11 @@ module.exports = Self => {
}
});
- Self.createManualInvoice = async(ctx, options) => {
+ Self.createManualInvoice = async(ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options) => {
+ if (!clientFk && !ticketFk) throw new UserError(`Select ticket or client`);
const models = Self.app.models;
- const args = ctx.args;
-
- let tx;
const myOptions = {userId: ctx.req.accessToken.userId};
+ let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
@@ -61,18 +60,15 @@ module.exports = Self => {
myOptions.transaction = tx;
}
- const ticketId = args.ticketFk;
- let clientId = args.clientFk;
- let maxShipped = args.maxShipped;
let companyId;
let newInvoice;
let query;
try {
- if (ticketId) {
- const ticket = await models.Ticket.findById(ticketId, null, myOptions);
+ if (ticketFk) {
+ const ticket = await models.Ticket.findById(ticketFk, null, myOptions);
const company = await models.Company.findById(ticket.companyFk, null, myOptions);
- clientId = ticket.clientFk;
+ clientFk = ticket.clientFk;
maxShipped = ticket.shipped;
companyId = ticket.companyFk;
@@ -85,7 +81,7 @@ module.exports = Self => {
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
// Validates ticket nagative base
- const hasNegativeBase = await getNegativeBase(maxShipped, clientId, companyId, myOptions);
+ const hasNegativeBase = await getNegativeBase(maxShipped, clientFk, companyId, myOptions);
if (hasNegativeBase && company.code == 'VNL')
throw new UserError(`A ticket with a negative base can't be invoiced`);
} else {
@@ -95,7 +91,7 @@ module.exports = Self => {
const company = await models.Ticket.findOne({
fields: ['companyFk'],
where: {
- clientFk: clientId,
+ clientFk: clientFk,
shipped: {lte: maxShipped}
}
}, myOptions);
@@ -103,7 +99,7 @@ module.exports = Self => {
}
// Validate invoiceable client
- const isClientInvoiceable = await isInvoiceable(clientId, myOptions);
+ const isClientInvoiceable = await isInvoiceable(clientFk, myOptions);
if (!isClientInvoiceable)
throw new UserError(`This client is not invoiceable`);
@@ -114,27 +110,27 @@ module.exports = Self => {
if (maxShipped >= tomorrow)
throw new UserError(`Can't invoice to future`);
- const maxInvoiceDate = await getMaxIssued(args.serial, companyId, myOptions);
+ const maxInvoiceDate = await getMaxIssued(serial, companyId, myOptions);
if (Date.vnNew() < maxInvoiceDate)
throw new UserError(`Can't invoice to past`);
- if (ticketId) {
+ if (ticketFk) {
query = `CALL invoiceOut_newFromTicket(?, ?, ?, ?, @newInvoiceId)`;
await Self.rawSql(query, [
- ticketId,
- args.serial,
- args.taxArea,
- args.reference
+ ticketFk,
+ serial,
+ taxArea,
+ reference
], myOptions);
} else {
query = `CALL invoiceOut_newFromClient(?, ?, ?, ?, ?, ?, @newInvoiceId)`;
await Self.rawSql(query, [
- clientId,
- args.serial,
+ clientFk,
+ serial,
maxShipped,
companyId,
- args.taxArea,
- args.reference
+ taxArea,
+ reference
], myOptions);
}
@@ -146,26 +142,27 @@ module.exports = Self => {
throw e;
}
- if (newInvoice.id)
- await Self.createPdf(ctx, newInvoice.id);
+ if (!newInvoice.id) throw new UserError('It was not able to create the invoice');
+
+ await Self.createPdf(ctx, newInvoice.id);
return newInvoice;
};
- async function isInvoiceable(clientId, options) {
+ async function isInvoiceable(clientFk, options) {
const models = Self.app.models;
const query = `SELECT (hasToInvoice AND isTaxDataChecked) AS invoiceable
FROM client
WHERE id = ?`;
- const [result] = await models.InvoiceOut.rawSql(query, [clientId], options);
+ const [result] = await models.InvoiceOut.rawSql(query, [clientFk], options);
return result.invoiceable;
}
- async function getNegativeBase(maxShipped, clientId, companyId, options) {
+ async function getNegativeBase(maxShipped, clientFk, companyId, options) {
const models = Self.app.models;
await models.InvoiceOut.rawSql('CALL invoiceOut_exportationFromClient(?,?,?)',
- [maxShipped, clientId, companyId], options
+ [maxShipped, clientFk, companyId], options
);
const query = 'SELECT vn.hasAnyNegativeBase() AS base';
const [result] = await models.InvoiceOut.rawSql(query, [], options);
diff --git a/modules/invoiceOut/back/methods/invoiceOut/download.js b/modules/invoiceOut/back/methods/invoiceOut/download.js
index 24fb9fde3..f8d42072c 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/download.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/download.js
@@ -1,5 +1,6 @@
const fs = require('fs-extra');
const path = require('path');
+const isProduction = require('vn-loopback/server/boot/isProduction');
module.exports = Self => {
Self.remoteMethodCtx('download', {
@@ -32,7 +33,7 @@ module.exports = Self => {
path: '/:id/download',
verb: 'GET'
},
- // accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.download = async function(ctx, id, options) {
@@ -66,7 +67,7 @@ module.exports = Self => {
console.error(err);
});
- if (process.env.NODE_ENV == 'test') {
+ if (!isProduction()) {
try {
await fs.access(file.path);
} catch (error) {
diff --git a/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js b/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js
index 13305f6ed..8d6e7c6d9 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/downloadZip.js
@@ -32,7 +32,7 @@ module.exports = Self => {
path: '/downloadZip',
verb: 'GET'
},
- // accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.downloadZip = async function(ctx, ids, options) {
diff --git a/modules/invoiceOut/back/methods/invoiceOut/exportationPdf.js b/modules/invoiceOut/back/methods/invoiceOut/exportationPdf.js
index a2d877189..6c4845c11 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/exportationPdf.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/exportationPdf.js
@@ -35,7 +35,7 @@ module.exports = Self => {
path: '/:reference/exportation-pdf',
verb: 'GET'
},
- // accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.exportationPdf = (ctx, reference) => Self.printReport(ctx, reference, 'exportation');
diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceCsv.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceCsv.js
index 6208d0625..fd754d51b 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/invoiceCsv.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceCsv.js
@@ -38,7 +38,7 @@ module.exports = Self => {
path: '/:reference/invoice-csv',
verb: 'GET'
},
- // accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.invoiceCsv = async reference => {
diff --git a/modules/invoiceOut/back/methods/invoiceOut/invoiceOutPdf.js b/modules/invoiceOut/back/methods/invoiceOut/invoiceOutPdf.js
index 941d31596..f4bb6baa9 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/invoiceOutPdf.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/invoiceOutPdf.js
@@ -31,7 +31,8 @@ module.exports = Self => {
http: {
path: '/:reference/invoice-out-pdf',
verb: 'GET'
- }
+ },
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.invoiceOutPdf = async(ctx, reference) => {
diff --git a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js
index 4bba2498f..e2dc15993 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/makePdfAndNotify.js
@@ -33,7 +33,6 @@ module.exports = Self => {
try {
await Self.makePdf(id, options);
} catch (err) {
- console.error(err);
throw new UserError('Error while generating PDF', 'pdfError');
}
diff --git a/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js b/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js
index 66440616c..76ef29604 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/negativeBases.js
@@ -59,7 +59,7 @@ module.exports = Self => {
`CREATE OR REPLACE TEMPORARY TABLE tmp.filter
ENGINE = MEMORY
SELECT co.code company,
- cou.country,
+ cou.name country,
c.id clientId,
c.socialName clientSocialName,
u.nickname workerSocialName,
@@ -70,7 +70,7 @@ module.exports = Self => {
c.hasToInvoice,
c.isTaxDataChecked,
w.id comercialId,
- CONCAT(w.firstName, ' ', w.lastName) comercialName
+ u.name workerName
FROM vn.ticket t
JOIN vn.company co ON co.id = t.companyFk
JOIN vn.sale s ON s.ticketFk = t.id
diff --git a/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js b/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js
index 6970bf368..3e466d1f4 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js
@@ -40,7 +40,7 @@ module.exports = Self => {
path: '/negativeBasesCsv',
verb: 'GET'
},
- // accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.negativeBasesCsv = async(ctx, options) => {
diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js
index b166caf78..55739e570 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/specs/createManualInvoice.spec.js
@@ -1,13 +1,10 @@
-const models = require('vn-loopback/server/server').models;
+const {models} = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
describe('InvoiceOut createManualInvoice()', () => {
- const userId = 1;
const ticketId = 16;
const clientId = 1106;
- const activeCtx = {
- accessToken: {userId: userId},
- };
+ const activeCtx = {accessToken: {userId: 1}};
const ctx = {req: activeCtx};
it('should throw an error trying to invoice again', async() => {
@@ -18,13 +15,8 @@ describe('InvoiceOut createManualInvoice()', () => {
let error;
try {
- ctx.args = {
- ticketFk: ticketId,
- serial: 'T',
- taxArea: 'CEE'
- };
- await models.InvoiceOut.createManualInvoice(ctx, options);
- await models.InvoiceOut.createManualInvoice(ctx, options);
+ await createInvoice(ctx, options, undefined, ticketId);
+ await createInvoice(ctx, options, undefined, ticketId);
await tx.rollback();
} catch (e) {
@@ -47,17 +39,9 @@ describe('InvoiceOut createManualInvoice()', () => {
let error;
try {
const ticket = await models.Ticket.findById(ticketId, null, options);
- await ticket.updateAttributes({
- totalWithVat: 0
- }, options);
-
- ctx.args = {
- ticketFk: ticketId,
- serial: 'T',
- taxArea: 'CEE'
- };
- await models.InvoiceOut.createManualInvoice(ctx, options);
+ await ticket.updateAttributes({totalWithVat: 0}, options);
+ await createInvoice(ctx, options, undefined, ticketId);
await tx.rollback();
} catch (e) {
error = e;
@@ -75,13 +59,7 @@ describe('InvoiceOut createManualInvoice()', () => {
let error;
try {
- ctx.args = {
- clientFk: clientId,
- serial: 'T',
- taxArea: 'CEE'
- };
- await models.InvoiceOut.createManualInvoice(ctx, options);
-
+ await createInvoice(ctx, options, clientId);
await tx.rollback();
} catch (e) {
error = e;
@@ -103,16 +81,9 @@ describe('InvoiceOut createManualInvoice()', () => {
let error;
try {
const client = await models.Client.findById(clientId, null, options);
- await client.updateAttributes({
- isTaxDataChecked: false
- }, options);
+ await client.updateAttributes({isTaxDataChecked: false}, options);
- ctx.args = {
- ticketFk: ticketId,
- serial: 'T',
- taxArea: 'CEE'
- };
- await models.InvoiceOut.createManualInvoice(ctx, options);
+ await createInvoice(ctx, options, undefined, ticketId);
await tx.rollback();
} catch (e) {
@@ -130,12 +101,7 @@ describe('InvoiceOut createManualInvoice()', () => {
const options = {transaction: tx};
try {
- ctx.args = {
- ticketFk: ticketId,
- serial: 'T',
- taxArea: 'CEE'
- };
- const result = await models.InvoiceOut.createManualInvoice(ctx, options);
+ const result = await createInvoice(ctx, options, undefined, ticketId);
expect(result.id).toEqual(jasmine.any(Number));
@@ -146,3 +112,18 @@ describe('InvoiceOut createManualInvoice()', () => {
}
});
});
+
+function createInvoice(
+ ctx,
+ options,
+ clientFk = undefined,
+ ticketFk = undefined,
+ maxShipped = undefined,
+ serial = 'T',
+ taxArea = 'CEE',
+ reference = undefined
+) {
+ return models.InvoiceOut.createManualInvoice(
+ ctx, clientFk, ticketFk, maxShipped, serial, taxArea, reference, options
+ );
+}
diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js
index eaaef3e26..22787e730 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/specs/transferinvoice.spec.js
@@ -1,4 +1,3 @@
-
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
@@ -17,26 +16,27 @@ describe('InvoiceOut transferInvoice()', () => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx
});
- spyOn(models.InvoiceOut, 'makePdfAndNotify');
});
it('should return the id of the created issued invoice', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
- const args = {
- id: '4',
- refFk: 'T4444444',
- newClientFk: 1,
- cplusRectificationTypeFk: 1,
- siiTypeInvoiceOutFk: 1,
- invoiceCorrectionTypeFk: 1
- };
- ctx.args = args;
+ const id = 4;
+ const newClient = 1;
+ spyOn(models.InvoiceOut, 'makePdfList');
+
try {
- const {clientFk: oldClient} = await models.InvoiceOut.findById(args.id, {fields: ['clientFk']});
+ const {clientFk: oldClient} = await models.InvoiceOut.findById(id, {fields: ['clientFk']});
const invoicesBefore = await models.InvoiceOut.find({}, options);
const result = await models.InvoiceOut.transferInvoice(
ctx,
+ id,
+ 'T4444444',
+ newClient,
+ 1,
+ 1,
+ 1,
+ true,
options);
const invoicesAfter = await models.InvoiceOut.find({}, options);
const rectificativeInvoice = invoicesAfter[invoicesAfter.length - 2];
@@ -45,7 +45,7 @@ describe('InvoiceOut transferInvoice()', () => {
expect(result).toBeDefined();
expect(invoicesAfter.length - invoicesBefore.length).toEqual(2);
expect(rectificativeInvoice.clientFk).toEqual(oldClient);
- expect(newInvoice.clientFk).toEqual(args.newClientFk);
+ expect(newInvoice.clientFk).toEqual(newClient);
await tx.rollback();
} catch (e) {
@@ -54,22 +54,13 @@ describe('InvoiceOut transferInvoice()', () => {
}
});
- it('should throw an UserError when it is the same client', async() => {
+ it('should throw an error when it is the same client', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
- const args = {
- id: '1',
- refFk: 'T1111111',
- newClientFk: 1101,
- cplusRectificationTypeFk: 1,
- siiTypeInvoiceOutFk: 1,
- invoiceCorrectionTypeFk: 1
- };
- ctx.args = args;
+ spyOn(models.InvoiceOut, 'makePdfList');
+
try {
- await models.InvoiceOut.transferInvoice(
- ctx,
- options);
+ await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1101, 1, 1, 1, true, options);
await tx.rollback();
} catch (e) {
expect(e.message).toBe(`Select a different client`);
@@ -77,26 +68,49 @@ describe('InvoiceOut transferInvoice()', () => {
}
});
- it('should throw an UserError when it is refund', async() => {
+ it('should throw an error when it is refund', async() => {
const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx};
- const args = {
- id: '1',
- refFk: 'T1111111',
- newClientFk: 1102,
- cplusRectificationTypeFk: 1,
- siiTypeInvoiceOutFk: 1,
- invoiceCorrectionTypeFk: 1
- };
- ctx.args = args;
+ spyOn(models.InvoiceOut, 'makePdfList');
try {
- await models.InvoiceOut.transferInvoice(
- ctx,
- options);
+ await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1102, 1, 1, 1, true, options);
await tx.rollback();
} catch (e) {
expect(e.message).toContain(`This ticket is already a refund`);
await tx.rollback();
}
});
+
+ it('should throw an error when pdf failed', async() => {
+ const tx = await models.InvoiceOut.beginTransaction({});
+ const options = {transaction: tx};
+ spyOn(models.InvoiceOut, 'makePdfList').and.returnValue(() => {
+ throw new Error('test');
+ });
+
+ try {
+ await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1102, 1, 1, 1, true, options);
+ await tx.rollback();
+ } catch (e) {
+ expect(e.message).toContain(`It has been invoiced but the PDF could not be generated`);
+ await tx.rollback();
+ }
+ });
+
+ it('should not generate an invoice', async() => {
+ const tx = await models.InvoiceOut.beginTransaction({});
+ const options = {transaction: tx};
+ spyOn(models.InvoiceOut, 'makePdfList');
+
+ let response;
+ try {
+ response = await models.InvoiceOut.transferInvoice(ctx, '1', 'T1111111', 1102, 1, 1, 1, false, options);
+ await tx.rollback();
+ } catch (e) {
+ await tx.rollback();
+ throw e;
+ }
+
+ expect(response).not.toBeDefined();
+ });
});
diff --git a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js
index 8e234d7cc..0c86e5810 100644
--- a/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js
+++ b/modules/invoiceOut/back/methods/invoiceOut/transferInvoice.js
@@ -36,9 +36,14 @@ module.exports = Self => {
type: 'number',
required: true
},
+ {
+ arg: 'makeInvoice',
+ type: 'boolean',
+ required: true
+ },
],
returns: {
- type: 'boolean',
+ type: 'object',
root: true
},
http: {
@@ -47,10 +52,22 @@ module.exports = Self => {
}
});
- Self.transferInvoice = async(ctx, options) => {
+ Self.transferInvoice = async(
+ ctx,
+ id,
+ refFk,
+ newClientFk,
+ cplusRectificationTypeFk,
+ siiTypeInvoiceOutFk,
+ invoiceCorrectionTypeFk,
+ makeInvoice,
+ options
+ ) => {
const models = Self.app.models;
const myOptions = {userId: ctx.req.accessToken.userId};
- const {id, refFk, newClientFk, cplusRectificationTypeFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk} = ctx.args;
+ let invoiceId;
+ let refundId;
+
let tx;
if (typeof options == 'object')
Object.assign(myOptions, options);
@@ -94,14 +111,29 @@ module.exports = Self => {
};
const refundTicketIds = refundTickets.map(ticket => ticket.id);
- await models.Ticket.invoiceTickets(ctx, refundTicketIds, invoiceCorrection, myOptions);
+ refundId = await models.Ticket.invoiceTickets(ctx, refundTicketIds, invoiceCorrection, myOptions);
- const [invoiceId] = await models.Ticket.invoiceTicketsAndPdf(ctx, clonedTicketIds, null, myOptions);
+ if (makeInvoice)
+ invoiceId = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, null, myOptions);
- return invoiceId;
+ tx && await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
+
+ if (tx && makeInvoice) {
+ try {
+ await models.InvoiceOut.makePdfList(ctx, invoiceId);
+ } catch (e) {
+ throw new UserError('It has been invoiced but the PDF could not be generated');
+ }
+ try {
+ await models.InvoiceOut.makePdfList(ctx, refundId);
+ } catch (e) {
+ throw new UserError('It has been invoiced but the PDF of refund not be generated');
+ }
+ }
+ return invoiceId;
};
};
diff --git a/modules/invoiceOut/back/models/cplus-rectification-type.json b/modules/invoiceOut/back/models/cplus-rectification-type.json
index e7bfb957f..06a57ea67 100644
--- a/modules/invoiceOut/back/models/cplus-rectification-type.json
+++ b/modules/invoiceOut/back/models/cplus-rectification-type.json
@@ -15,5 +15,13 @@
"description": {
"type": "string"
}
- }
+ },
+ "acls": [
+ {
+ "accessType": "READ",
+ "principalType": "ROLE",
+ "principalId": "$everyone",
+ "permission": "ALLOW"
+ }
+ ]
}
\ No newline at end of file
diff --git a/modules/invoiceOut/back/models/invoice-out.js b/modules/invoiceOut/back/models/invoice-out.js
index e4fcc1a69..b0e05b626 100644
--- a/modules/invoiceOut/back/models/invoice-out.js
+++ b/modules/invoiceOut/back/models/invoice-out.js
@@ -1,6 +1,7 @@
const print = require('vn-print');
const path = require('path');
const UserError = require('vn-loopback/util/user-error');
+const isProduction = require('vn-loopback/server/boot/isProduction');
module.exports = Self => {
require('../methods/invoiceOut/filter')(Self);
@@ -59,7 +60,7 @@ module.exports = Self => {
hasPdf: true
}, options);
- if (process.env.NODE_ENV !== 'test') {
+ if (isProduction()) {
await print.storage.write(buffer, {
type: 'invoice',
path: pdfFile.path,
diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html
index 1bf34831e..da04c8e72 100644
--- a/modules/invoiceOut/front/descriptor-menu/index.html
+++ b/modules/invoiceOut/front/descriptor-menu/index.html
@@ -1,15 +1,3 @@
-
-
-
-
- {{::description}}
+ {{ ::description}}
@@ -226,7 +214,7 @@
+
+
+
+
diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js
index 5184c137e..8ea4507ec 100644
--- a/modules/invoiceOut/front/descriptor-menu/index.js
+++ b/modules/invoiceOut/front/descriptor-menu/index.js
@@ -7,6 +7,7 @@ class Controller extends Section {
super($element, $);
this.vnReport = vnReport;
this.vnEmail = vnEmail;
+ this.checked = true;
}
get invoiceOut() {
@@ -23,6 +24,26 @@ class Controller extends Section {
return this.aclService.hasAny(['invoicing']);
}
+ get isChecked() {
+ return this.checked;
+ }
+
+ set isChecked(value) {
+ this.checked = value;
+ }
+
+ $onInit() {
+ this.$http.get(`CplusRectificationTypes`, {filter: {order: 'description'}})
+ .then(res => {
+ this.cplusRectificationTypes = res.data;
+ this.cplusRectificationType = res.data.filter(type => type.description == 'I – Por diferencias')[0].id;
+ });
+ this.$http.get(`SiiTypeInvoiceOuts`, {filter: {where: {code: {like: 'R%'}}}})
+ .then(res => {
+ this.siiTypeInvoiceOuts = res.data;
+ this.siiTypeInvoiceOut = res.data.filter(type => type.code == 'R4')[0].id;
+ });
+ }
loadData() {
const filter = {
include: [
@@ -34,7 +55,7 @@ class Controller extends Section {
}, {
relation: 'client',
scope: {
- fields: ['id', 'name', 'email']
+ fields: ['id', 'name', 'email', 'hasToInvoiceByAddress']
}
}
]
@@ -136,12 +157,24 @@ class Controller extends Section {
newClientFk: this.clientId,
cplusRectificationTypeFk: this.cplusRectificationType,
siiTypeInvoiceOutFk: this.siiTypeInvoiceOut,
- invoiceCorrectionTypeFk: this.invoiceCorrectionType
+ invoiceCorrectionTypeFk: this.invoiceCorrectionType,
+ makeInvoice: this.checked
};
- this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => {
- const invoiceId = res.data;
- this.vnApp.showSuccess(this.$t('Transferred invoice'));
- this.$state.go('invoiceOut.card.summary', {id: invoiceId});
+
+ this.$http.get(`Clients/${this.clientId}`).then(response => {
+ const clientData = response.data;
+ const hasToInvoiceByAddress = clientData.hasToInvoiceByAddress;
+
+ if (this.checked && hasToInvoiceByAddress) {
+ if (!window.confirm(this.$t('confirmTransferInvoice')))
+ return;
+ }
+
+ this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => {
+ const invoiceId = res.data;
+ this.vnApp.showSuccess(this.$t('Transferred invoice'));
+ this.$state.go('invoiceOut.card.summary', {id: invoiceId});
+ });
});
}
}
diff --git a/modules/invoiceOut/front/descriptor-menu/locale/en.yml b/modules/invoiceOut/front/descriptor-menu/locale/en.yml
index 8fad5f25e..32ea03442 100644
--- a/modules/invoiceOut/front/descriptor-menu/locale/en.yml
+++ b/modules/invoiceOut/front/descriptor-menu/locale/en.yml
@@ -1,3 +1,7 @@
The following refund tickets have been created: "The following refund tickets have been created: {{ticketIds}}"
Transfer invoice to...: Transfer invoice to...
-Cplus Type: Cplus Type
\ No newline at end of file
+Cplus Type: Cplus Type
+transferInvoice: Transfer Invoice
+destinationClient: Bill destination client
+transferInvoiceInfo: New tickets from the destination customer will be generated in the default consignee.
+confirmTransferInvoice: Destination customer has marked to bill by consignee, do you want to continue?
\ No newline at end of file
diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml
index 9285fafa7..92c109878 100644
--- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml
+++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml
@@ -24,3 +24,7 @@ Refund...: Abono...
Transfer invoice to...: Transferir factura a...
Rectificative type: Tipo rectificativa
Transferred invoice: Factura transferida
+transferInvoice: Transferir factura
+destinationClient: Facturar cliente destino
+transferInvoiceInfo: Los nuevos tickets del cliente destino serán generados en el consignatario por defecto.
+confirmTransferInvoice: El cliente destino tiene marcado facturar por consignatario, ¿desea continuar?
\ No newline at end of file
diff --git a/modules/invoiceOut/front/index/manual/index.html b/modules/invoiceOut/front/index/manual/index.html
index 5872911e4..3b991618d 100644
--- a/modules/invoiceOut/front/index/manual/index.html
+++ b/modules/invoiceOut/front/index/manual/index.html
@@ -27,7 +27,7 @@
- {{::client.comercialName | dashIfEmpty}}
+ {{::client.workerName | dashIfEmpty}}
|
diff --git a/modules/item/back/methods/item-barcode/toItem.js b/modules/item/back/methods/item-barcode/toItem.js
index 96e9d5981..d189b77c3 100644
--- a/modules/item/back/methods/item-barcode/toItem.js
+++ b/modules/item/back/methods/item-barcode/toItem.js
@@ -4,7 +4,7 @@ module.exports = Self => {
accessType: 'READ',
accepts: [{
arg: 'barcode',
- type: 'number',
+ type: 'string',
required: true,
description: 'barcode'
}],
@@ -18,7 +18,7 @@ module.exports = Self => {
}
});
- Self.toItem = async(barcode, options) => {
+ Self.toItem = async (barcode, options) => {
const myOptions = {};
if (typeof options == 'object')
diff --git a/modules/item/back/methods/item-image-queue/download.js b/modules/item/back/methods/item-image-queue/download.js
index 354771071..001a2b950 100644
--- a/modules/item/back/methods/item-image-queue/download.js
+++ b/modules/item/back/methods/item-image-queue/download.js
@@ -11,7 +11,7 @@ module.exports = Self => {
path: `/download`,
verb: 'POST',
},
- //accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.download = async() => {
diff --git a/modules/item/back/methods/item-shelving/specs/upsertItem.spec.js b/modules/item/back/methods/item-shelving/specs/upsertItem.spec.js
index 8615b7b86..2dd43224c 100644
--- a/modules/item/back/methods/item-shelving/specs/upsertItem.spec.js
+++ b/modules/item/back/methods/item-shelving/specs/upsertItem.spec.js
@@ -1,18 +1,17 @@
-const { models } = require('vn-loopback/server/server');
+const {models} = require('vn-loopback/server/server');
const LoopBackContext = require('loopback-context');
-// #6276
describe('ItemShelving upsertItem()', () => {
const warehouseFk = 1;
let ctx;
let options;
let tx;
- beforeEach(async () => {
+ beforeEach(async() => {
ctx = {
req: {
- accessToken: { userId: 9 },
- headers: { origin: 'http://localhost' }
+ accessToken: {userId: 9},
+ headers: {origin: 'http://localhost'}
},
args: {}
};
@@ -21,35 +20,35 @@ describe('ItemShelving upsertItem()', () => {
active: ctx.req
});
- options = { transaction: tx };
+ options = {transaction: tx};
tx = await models.ItemShelving.beginTransaction({});
options.transaction = tx;
});
- afterEach(async () => {
+ afterEach(async() => {
await tx.rollback();
});
- it('should add two new records', async () => {
- const shelvingFk = 'ZPP';
+ it('should add two new records', async() => {
+ const shelvingFk = 'GVC';
const items = [1, 1, 1, 2];
await models.ItemShelving.upsertItem(ctx, shelvingFk, items, warehouseFk, options);
- const itemShelvings = await models.ItemShelving.find({ where: { shelvingFk } }, options);
+ const itemShelvings = await models.ItemShelving.find({where: {shelvingFk}}, options);
expect(itemShelvings.length).toEqual(2);
});
- it('should update the visible items', async () => {
+ it('should update the visible items', async() => {
const shelvingFk = 'GVC';
const items = [2, 2];
- const { visible: visibleItemsBefore } = await models.ItemShelving.findOne({
- where: { shelvingFk, itemFk: items[0] }
+ const {visible: visibleItemsBefore} = await models.ItemShelving.findOne({
+ where: {shelvingFk, itemFk: items[0]}
}, options);
await models.ItemShelving.upsertItem(ctx, shelvingFk, items, warehouseFk, options);
- const { visible: visibleItemsAfter } = await models.ItemShelving.findOne({
- where: { shelvingFk, itemFk: items[0] }
+ const {visible: visibleItemsAfter} = await models.ItemShelving.findOne({
+ where: {shelvingFk, itemFk: items[0]}
}, options);
expect(visibleItemsAfter).toEqual(visibleItemsBefore + 2);
diff --git a/modules/item/back/methods/item/getBalance.js b/modules/item/back/methods/item/getBalance.js
index d4e2d0f74..207f8020f 100644
--- a/modules/item/back/methods/item/getBalance.js
+++ b/modules/item/back/methods/item/getBalance.js
@@ -27,8 +27,11 @@ module.exports = Self => {
const where = filter.where;
const query = 'CALL vn.item_getBalance(?, ?, ?)';
+ if (where?.date) {
+ where.date = new Date(where.date);
+ where.date.setHours(0, 0, 0, 0);
+ }
const [diary] = await Self.rawSql(query, [where.itemFk, where.warehouseFk, where.date], myOptions);
-
for (const entry of diary)
if (entry.clientType === 'loses') entry.highlighted = true;
diff --git a/modules/item/back/methods/item/labelPdf.js b/modules/item/back/methods/item/labelPdf.js
index c2462353d..d7a50397e 100644
--- a/modules/item/back/methods/item/labelPdf.js
+++ b/modules/item/back/methods/item/labelPdf.js
@@ -51,7 +51,8 @@ module.exports = Self => {
http: {
path: '/:id/label-pdf',
verb: 'GET'
- }
+ },
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.labelPdf = (ctx, id) => Self.printReport(ctx, id, 'item-label');
diff --git a/modules/item/back/methods/item/specs/getBalance.spec.js b/modules/item/back/methods/item/specs/getBalance.spec.js
index 5e5148595..728b5f33e 100644
--- a/modules/item/back/methods/item/specs/getBalance.spec.js
+++ b/modules/item/back/methods/item/specs/getBalance.spec.js
@@ -64,7 +64,7 @@ describe('item getBalance()', () => {
const secondItemBalance = await models.Item.getBalance(ctx, secondFilter, options);
expect(firstItemBalance[9].claimFk).toEqual(null);
- expect(secondItemBalance[4].claimFk).toEqual(2);
+ expect(secondItemBalance[7].claimFk).toEqual(2);
await tx.rollback();
} catch (e) {
diff --git a/modules/item/back/models/expense.json b/modules/item/back/models/expense.json
index 468063602..e661cbc66 100644
--- a/modules/item/back/models/expense.json
+++ b/modules/item/back/models/expense.json
@@ -9,7 +9,7 @@
"properties": {
"id": {
"id": true,
- "type": "number",
+ "type": "string",
"description": "Identifier"
},
"name": {
diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json
index 9d48dcbfb..10cff3e04 100644
--- a/modules/item/back/models/item.json
+++ b/modules/item/back/models/item.json
@@ -155,6 +155,9 @@
"minQuantity": {
"type": "number",
"description": "Min quantity"
+ },
+ "photoMotivation": {
+ "type": "string"
}
},
"relations": {
diff --git a/modules/item/front/last-entries/index.html b/modules/item/front/last-entries/index.html
index 429955ef5..e3b84655c 100644
--- a/modules/item/front/last-entries/index.html
+++ b/modules/item/front/last-entries/index.html
@@ -71,12 +71,12 @@
{{entry.stickers | dashIfEmpty}}
-
+
{{::entry.packing | dashIfEmpty}}
-
+
{{::entry.grouping | dashIfEmpty}}
diff --git a/modules/item/front/summary/index.html b/modules/item/front/summary/index.html
index 5fe84591f..13c671d29 100644
--- a/modules/item/front/summary/index.html
+++ b/modules/item/front/summary/index.html
@@ -181,7 +181,7 @@
ng-show="!$ctrl.isBuyer && !$ctrl.isAdministrative">
Tax
-
diff --git a/modules/item/front/tax/index.html b/modules/item/front/tax/index.html
index e993f974f..78858704f 100644
--- a/modules/item/front/tax/index.html
+++ b/modules/item/front/tax/index.html
@@ -15,7 +15,7 @@
{
Self.remoteMethodCtx('upload', {
@@ -111,7 +112,7 @@ module.exports = Self => {
const destinationFile = path.join(
accessContainer.client.root, accessContainer.name, appName, `${toVersion}.7z`);
- if (process.env.NODE_ENV == 'test')
+ if (!isProduction())
await fs.unlink(srcFile);
else {
await fs.move(srcFile, destinationFile, {
diff --git a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
index bdafd14e2..c3da7f08b 100644
--- a/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
+++ b/modules/monitor/back/methods/sales-monitor/specs/salesFilter.spec.js
@@ -151,7 +151,7 @@ describe('SalesMonitor salesFilter()', () => {
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
const firstRow = result[0];
- expect(result.length).toEqual(12);
+ expect(result.length).toEqual(15);
expect(firstRow.alertLevel).not.toEqual(0);
await tx.rollback();
diff --git a/modules/route/back/locale/routesMonitor/en.yml b/modules/route/back/locale/routesMonitor/en.yml
index 8908ee636..c28c5cb4d 100644
--- a/modules/route/back/locale/routesMonitor/en.yml
+++ b/modules/route/back/locale/routesMonitor/en.yml
@@ -13,7 +13,6 @@ columns:
m3: m3
priority: priority
etd: etd
- expeditionTruckFk: truck
m3boxes: m3 boxes
bufferFk: buffer
- isPickingAllowed: is picking allowed
\ No newline at end of file
+ isPickingAllowed: is picking allowed
diff --git a/modules/route/back/locale/routesMonitor/es.yml b/modules/route/back/locale/routesMonitor/es.yml
index 9ded8983d..a8e807626 100644
--- a/modules/route/back/locale/routesMonitor/es.yml
+++ b/modules/route/back/locale/routesMonitor/es.yml
@@ -13,7 +13,6 @@ columns:
m3: m3
priority: prioridad
etd: etd
- expeditionTruckFk: camión
m3boxes: m3 cajas
bufferFk: buffer
- isPickingAllowed: está permitido recoger
\ No newline at end of file
+ isPickingAllowed: está permitido recoger
diff --git a/modules/route/back/methods/roadmap/clone.js b/modules/route/back/methods/roadmap/clone.js
index 456ed823d..5f1ab9229 100644
--- a/modules/route/back/methods/roadmap/clone.js
+++ b/modules/route/back/methods/roadmap/clone.js
@@ -37,17 +37,12 @@ module.exports = Self => {
fields: [
'id',
'name',
- 'tractorPlate',
- 'trailerPlate',
- 'phone',
'supplierFk',
- 'etd',
- 'observations',
- 'price'],
+ 'etd'],
include: [{
- relation: 'expeditionTruck',
+ relation: 'roadmapStop',
scope: {
- fields: ['roadmapFk', 'warehouseFk', 'eta', 'description']
+ fields: ['roadmapFk', 'addressFk', 'eta', 'description']
}
}]
@@ -62,12 +57,12 @@ module.exports = Self => {
const clone = await models.Roadmap.create(roadmap, options);
- const expeditionTrucks = roadmap.expeditionTruck();
- expeditionTrucks.map(expeditionTruck => {
- expeditionTruck.roadmapFk = clone.id;
- return expeditionTruck;
+ const roadmapStops = roadmap.roadmapStop();
+ roadmapStops.map(roadmapStop => {
+ roadmapStop.roadmapFk = clone.id;
+ return roadmapStop;
});
- await models.ExpeditionTruck.create(expeditionTrucks, options);
+ await models.RoadmapStop.create(roadmapStops, options);
}
await tx.commit();
diff --git a/modules/route/back/methods/route/cmr.js b/modules/route/back/methods/route/cmr.js
index cd7ef57ce..5033dee2f 100644
--- a/modules/route/back/methods/route/cmr.js
+++ b/modules/route/back/methods/route/cmr.js
@@ -29,7 +29,8 @@ module.exports = Self => {
http: {
path: '/:id/cmr',
verb: 'GET'
- }
+ },
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.cmr = (ctx, id) => Self.printReport(ctx, id, 'cmr');
diff --git a/modules/route/back/methods/route/downloadCmrsZip.js b/modules/route/back/methods/route/downloadCmrsZip.js
index 1ef25d175..c6934edca 100644
--- a/modules/route/back/methods/route/downloadCmrsZip.js
+++ b/modules/route/back/methods/route/downloadCmrsZip.js
@@ -30,7 +30,7 @@ module.exports = Self => {
path: '/downloadCmrsZip',
verb: 'GET'
},
- //accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.downloadCmrsZip = async function(ctx, ids, options) {
diff --git a/modules/route/back/methods/route/downloadZip.js b/modules/route/back/methods/route/downloadZip.js
index b226cf7f8..8eecf62e4 100644
--- a/modules/route/back/methods/route/downloadZip.js
+++ b/modules/route/back/methods/route/downloadZip.js
@@ -30,7 +30,7 @@ module.exports = Self => {
path: '/downloadZip',
verb: 'GET'
},
- //accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
Self.downloadZip = async function(ctx, id, options) {
diff --git a/modules/route/back/methods/route/driverRoutePdf.js b/modules/route/back/methods/route/driverRoutePdf.js
index 9469356bb..69b26d846 100644
--- a/modules/route/back/methods/route/driverRoutePdf.js
+++ b/modules/route/back/methods/route/driverRoutePdf.js
@@ -35,7 +35,7 @@ module.exports = Self => {
path: '/:id/driver-route-pdf',
verb: 'GET'
},
- //accessScopes: ['read:multimedia']
+ accessScopes: ['DEFAULT', 'read:multimedia']
});
diff --git a/modules/route/back/methods/route/filter.js b/modules/route/back/methods/route/filter.js
index 7c2225dc9..5b13a9004 100644
--- a/modules/route/back/methods/route/filter.js
+++ b/modules/route/back/methods/route/filter.js
@@ -67,6 +67,12 @@ module.exports = Self => {
type: 'string',
description: 'The description filter',
http: {source: 'query'}
+ },
+ {
+ arg: 'isOk',
+ type: 'boolean',
+ description: 'The isOk filter',
+ http: {source: 'query'}
}
],
returns: {
@@ -102,6 +108,8 @@ module.exports = Self => {
case 'agencyModeFk':
param = `r.${param}`;
return {[param]: value};
+ case 'isOk':
+ return {'r.isOk': value};
}
});
diff --git a/modules/route/back/methods/route/getExpeditionSummary.js b/modules/route/back/methods/route/getExpeditionSummary.js
index ee89401a8..2bd2ca43a 100644
--- a/modules/route/back/methods/route/getExpeditionSummary.js
+++ b/modules/route/back/methods/route/getExpeditionSummary.js
@@ -49,8 +49,7 @@ module.exports = Self => {
JOIN vn.agencyMode am ON am.id = r.agencyModeFk
JOIN vn.agency ag ON ag.id = am.agencyFk
LEFT JOIN vn.userConfig uc ON uc.userFk = account.myUser_getId()
- WHERE (r.created = util.VN_CURDATE() OR r.created = util.yesterday())
- AND t.routeFk = ?
+ WHERE t.routeFk = ?
GROUP BY t.addressFk, e.itemPackingTypeFk
) sub
GROUP BY addressFk
diff --git a/modules/route/back/methods/route/getExternalCmrs.js b/modules/route/back/methods/route/getExternalCmrs.js
index b8cd1041a..89536f50a 100644
--- a/modules/route/back/methods/route/getExternalCmrs.js
+++ b/modules/route/back/methods/route/getExternalCmrs.js
@@ -103,7 +103,7 @@ module.exports = Self => {
SELECT t.cmrFk,
t.id ticketFk,
t.routeFk,
- co.country,
+ co.name country,
t.clientFk,
IF(sub.id, TRUE, FALSE) hasCmrDms,
DATE(t.shipped) shipped
diff --git a/modules/route/back/methods/route/getTickets.js b/modules/route/back/methods/route/getTickets.js
index 59ba389ed..c0b952b70 100644
--- a/modules/route/back/methods/route/getTickets.js
+++ b/modules/route/back/methods/route/getTickets.js
@@ -33,60 +33,60 @@ module.exports = Self => {
const stmt = new ParameterizedSQL(
`SELECT
- t.id,
- t.packages,
- t.warehouseFk,
- t.nickname,
- t.clientFk,
- t.priority,
- t.addressFk,
- st.code ticketStateCode,
- st.name ticketStateName,
- wh.name warehouseName,
- tob.description ticketObservation,
- a.street,
- a.postalCode,
- a.city,
- am.name agencyModeName,
- u.nickname userNickname,
- vn.ticketTotalVolume(t.id) volume,
- tob.description,
- GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt,
- c.phone clientPhone,
- c.mobile clientMobile,
- a.phone addressPhone,
- a.mobile addressMobile,
- a.longitude,
- a.latitude,
- wm.mediaValue salePersonPhone,
- t.cmrFk,
- t.isSigned signed
- FROM vn.route r
- JOIN ticket t ON t.routeFk = r.id
- JOIN client c ON t.clientFk = c.id
- LEFT JOIN vn.sale s ON s.ticketFk = t.id
- LEFT JOIN vn.item i ON i.id = s.itemFk
- LEFT JOIN ticketState ts ON ts.ticketFk = t.id
- LEFT JOIN state st ON st.id = ts.stateFk
- LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
- LEFT JOIN observationType ot ON ot.code = 'delivery'
- LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
- AND tob.observationTypeFk = ot.id
- LEFT JOIN address a ON a.id = t.addressFk
- LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
- LEFT JOIN account.user u ON u.id = r.workerFk
- LEFT JOIN vehicle v ON v.id = r.vehicleFk
- LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk`
+ t.id,
+ t.packages,
+ t.warehouseFk,
+ t.nickname,
+ t.clientFk,
+ t.priority,
+ t.addressFk,
+ st.code ticketStateCode,
+ st.name ticketStateName,
+ wh.name warehouseName,
+ tob.description observationDelivery,
+ tob2.description observationDropOff,
+ tob2.id observationId,
+ a.street,
+ a.postalCode,
+ a.city,
+ am.name agencyModeName,
+ u.nickname userNickname,
+ vn.ticketTotalVolume(t.id) volume,
+ GROUP_CONCAT(DISTINCT i.itemPackingTypeFk ORDER BY i.itemPackingTypeFk) ipt,
+ c.phone clientPhone,
+ c.mobile clientMobile,
+ a.phone addressPhone,
+ a.mobile addressMobile,
+ a.longitude,
+ a.latitude,
+ wm.mediaValue salePersonPhone,
+ t.cmrFk,
+ t.isSigned signed
+ FROM vn.route r
+ JOIN ticket t ON t.routeFk = r.id
+ JOIN client c ON t.clientFk = c.id
+ LEFT JOIN vn.sale s ON s.ticketFk = t.id
+ LEFT JOIN vn.item i ON i.id = s.itemFk
+ LEFT JOIN ticketState ts ON ts.ticketFk = t.id
+ LEFT JOIN state st ON st.id = ts.stateFk
+ LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
+ LEFT JOIN observationType ot ON ot.code = 'delivery'
+ LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
+ AND tob.observationTypeFk = ot.id
+ LEFT JOIN observationType ot2 ON ot2.code = 'dropOff'
+ LEFT JOIN ticketObservation tob2 ON tob2.ticketFk = t.id
+ AND tob2.observationTypeFk = ot2.id
+ LEFT JOIN address a ON a.id = t.addressFk
+ LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
+ LEFT JOIN account.user u ON u.id = r.workerFk
+ LEFT JOIN vehicle v ON v.id = r.vehicleFk
+ LEFT JOIN workerMedia wm ON wm.workerFk = c.salesPersonFk`
);
if (!filter.where) filter.where = {};
const where = filter.where;
where['r.id'] = filter.id;
- where.and = [{or: [
- {'t.packages': {gt: 0}},
- {and: [{'ot.code': 'delivery'}, {'tob.observationTypeFk': {neq: null}}]}
- ]}];
stmt.merge(conn.makeWhere(filter.where));
stmt.merge(conn.makeGroupBy('t.id'));
diff --git a/modules/route/back/model-config.json b/modules/route/back/model-config.json
index 6cf8da986..ccae87bd9 100644
--- a/modules/route/back/model-config.json
+++ b/modules/route/back/model-config.json
@@ -8,7 +8,10 @@
"DeliveryPoint": {
"dataSource": "vn"
},
- "ExpeditionTruck": {
+ "RoadmapAddress": {
+ "dataSource": "vn"
+ },
+ "RoadmapStop": {
"dataSource": "vn"
},
"Roadmap": {
diff --git a/modules/route/back/models/roadmap.json b/modules/route/back/models/roadmap.json
index 2f6bb8c02..01572d718 100644
--- a/modules/route/back/models/roadmap.json
+++ b/modules/route/back/models/roadmap.json
@@ -54,9 +54,9 @@
"model": "Supplier",
"foreignKey": "supplierFk"
},
- "expeditionTruck": {
+ "roadmapStop": {
"type": "hasMany",
- "model": "ExpeditionTruck",
+ "model": "RoadmapStop",
"foreignKey": "roadmapFk"
}
}
diff --git a/modules/route/back/models/roadmapAddress.json b/modules/route/back/models/roadmapAddress.json
new file mode 100644
index 000000000..0241ce0d8
--- /dev/null
+++ b/modules/route/back/models/roadmapAddress.json
@@ -0,0 +1,26 @@
+{
+ "name": "RoadmapAddress",
+ "base": "VnModel",
+ "options": {
+ "mysql": {
+ "table": "roadmapAddress"
+ }
+ },
+ "properties": {
+ "addressFk": {
+ "type": "number",
+ "id": true,
+ "description": "Identifier"
+ },
+ "isActive": {
+ "type": "number"
+ }
+ },
+ "relations": {
+ "address": {
+ "type": "belongsTo",
+ "model": "Address",
+ "foreignKey": "addressFk"
+ }
+ }
+}
diff --git a/modules/route/back/models/expedition-truck.json b/modules/route/back/models/roadmapStop.json
similarity index 78%
rename from modules/route/back/models/expedition-truck.json
rename to modules/route/back/models/roadmapStop.json
index 8edc7347f..74b02cd7a 100644
--- a/modules/route/back/models/expedition-truck.json
+++ b/modules/route/back/models/roadmapStop.json
@@ -1,9 +1,9 @@
{
- "name": "ExpeditionTruck",
+ "name": "RoadmapStop",
"base": "VnModel",
"options": {
"mysql": {
- "table": "expeditionTruck"
+ "table": "roadmapStop"
}
},
"properties": {
@@ -15,7 +15,7 @@
"roadmapFk": {
"type": "number"
},
- "warehouseFk": {
+ "addressFk": {
"type": "number"
},
"eta": {
@@ -34,10 +34,10 @@
"model": "Roadmap",
"foreignKey": "roadmapFk"
},
- "warehouse": {
+ "address": {
"type": "belongsTo",
- "model": "Warehouse",
- "foreignKey": "warehouseFk"
+ "model": "Address",
+ "foreignKey": "addressFk"
}
}
}
diff --git a/modules/route/back/models/routesMonitor.json b/modules/route/back/models/routesMonitor.json
index 122026336..a14680b5c 100644
--- a/modules/route/back/models/routesMonitor.json
+++ b/modules/route/back/models/routesMonitor.json
@@ -48,9 +48,6 @@
"priority": {
"type": "number"
},
- "expeditionTruckFk": {
- "type": "number"
- },
"m3boxes": {
"type": "number"
},
diff --git a/modules/route/front/roadmap/stops/index.html b/modules/route/front/roadmap/stops/index.html
index b69492a21..82f30c326 100644
--- a/modules/route/front/roadmap/stops/index.html
+++ b/modules/route/front/roadmap/stops/index.html
@@ -1,22 +1,22 @@