8179-testToMaster #3176
|
@ -56,6 +56,3 @@ COPY \
|
||||||
./
|
./
|
||||||
|
|
||||||
CMD ["pm2-runtime", "./back/process.yml"]
|
CMD ["pm2-runtime", "./back/process.yml"]
|
||||||
|
|
||||||
HEALTHCHECK --interval=15s --timeout=10s \
|
|
||||||
CMD curl -f http://localhost:3000/api/Applications/status || exit 1
|
|
||||||
|
|
|
@ -19,8 +19,15 @@ module.exports = Self => {
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
const [info, info2, [{'@vCollectionFk': collectionFk}]] = await Self.rawSql(
|
|
||||||
'CALL vn.collection_getAssigned(?, @vCollectionFk);SELECT @vCollectionFk', [userId], myOptions);
|
const randStr = Math.random().toString(36).substring(3);
|
||||||
|
const result = await Self.rawSql(`
|
||||||
|
CALL vn.collection_getAssigned(?, @vCollectionFk);
|
||||||
|
SELECT @vCollectionFk ?
|
||||||
|
`, [userId, randStr], myOptions);
|
||||||
|
|
||||||
|
const collectionFk = result.find(item => item[0]?.[randStr] !== undefined)?.[0]?.[randStr];
|
||||||
|
|
||||||
if (!collectionFk) throw new UserError('There are not picking tickets');
|
if (!collectionFk) throw new UserError('There are not picking tickets');
|
||||||
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
|
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,8 @@ module.exports = Self => {
|
||||||
p.code parkingCodePrevia,
|
p.code parkingCodePrevia,
|
||||||
p.pickingOrder pickingOrderPrevia,
|
p.pickingOrder pickingOrderPrevia,
|
||||||
iss.id itemShelvingSaleFk,
|
iss.id itemShelvingSaleFk,
|
||||||
iss.isPicked
|
iss.isPicked,
|
||||||
|
iss.itemShelvingFk
|
||||||
FROM ticketCollection tc
|
FROM ticketCollection tc
|
||||||
LEFT JOIN collection c ON c.id = tc.collectionFk
|
LEFT JOIN collection c ON c.id = tc.collectionFk
|
||||||
JOIN sale s ON s.ticketFk = tc.ticketFk
|
JOIN sale s ON s.ticketFk = tc.ticketFk
|
||||||
|
@ -102,7 +103,8 @@ module.exports = Self => {
|
||||||
p.code,
|
p.code,
|
||||||
p.pickingOrder,
|
p.pickingOrder,
|
||||||
iss.id itemShelvingSaleFk,
|
iss.id itemShelvingSaleFk,
|
||||||
iss.isPicked
|
iss.isPicked,
|
||||||
|
iss.itemShelvingFk
|
||||||
FROM sectorCollection sc
|
FROM sectorCollection sc
|
||||||
JOIN sectorCollectionSaleGroup ss ON ss.sectorCollectionFk = sc.id
|
JOIN sectorCollectionSaleGroup ss ON ss.sectorCollectionFk = sc.id
|
||||||
JOIN saleGroup sg ON sg.id = ss.saleGroupFk
|
JOIN saleGroup sg ON sg.id = ss.saleGroupFk
|
||||||
|
|
|
@ -4,21 +4,45 @@ module.exports = Self => {
|
||||||
/**
|
/**
|
||||||
* Returns basic headers
|
* Returns basic headers
|
||||||
*
|
*
|
||||||
* @param {string} cookie - The docuware cookie
|
|
||||||
* @return {object} - The headers
|
* @return {object} - The headers
|
||||||
*/
|
*/
|
||||||
Self.getOptions = async() => {
|
Self.getOptions = async() => {
|
||||||
const docuwareConfig = await Self.app.models.DocuwareConfig.findOne();
|
const docuwareConfig = await Self.app.models.DocuwareConfig.findOne();
|
||||||
|
const now = Date.vnNow();
|
||||||
|
let {url, username, password, token, expired} = docuwareConfig;
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV && (!expired || expired < now + 60)) {
|
||||||
|
const {data: {IdentityServiceUrl}} = await axios.get(`${url}/Home/IdentityServiceInfo`);
|
||||||
|
const {data: {token_endpoint}} = await axios.get(`${IdentityServiceUrl}/.well-known/openid-configuration`);
|
||||||
|
const {data} = await axios.post(token_endpoint, {
|
||||||
|
grant_type: 'password',
|
||||||
|
scope: 'docuware.platform',
|
||||||
|
client_id: 'docuware.platform.net.client',
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
}, {headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
}});
|
||||||
|
|
||||||
|
const newToken = data.access_token;
|
||||||
|
token = data.token_type + ' ' + newToken;
|
||||||
|
await docuwareConfig.updateAttributes({
|
||||||
|
token,
|
||||||
|
expired: now + data.expires_in
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Cookie': docuwareConfig.cookie
|
'Authorization': token
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
url: docuwareConfig.url,
|
url,
|
||||||
headers
|
headers
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,26 +2,21 @@ const axios = require('axios');
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('Docuware core', () => {
|
describe('Docuware core', () => {
|
||||||
beforeAll(() => {
|
const fileCabinetCode = 'deliveryNote';
|
||||||
|
beforeAll(async() => {
|
||||||
process.env.NODE_ENV = 'testing';
|
process.env.NODE_ENV = 'testing';
|
||||||
|
|
||||||
|
const docuwareInfo = await models.Docuware.findOne({
|
||||||
|
where: {
|
||||||
|
code: fileCabinetCode
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
spyOn(axios, 'get').and.callFake(url => {
|
||||||
delete process.env.NODE_ENV;
|
if (url.includes('IdentityServiceInfo')) return {data: {IdentityServiceUrl: 'IdentityServiceUrl'}};
|
||||||
});
|
if (url.includes('IdentityServiceUrl')) return {data: {token_endpoint: 'token_endpoint'}};
|
||||||
|
if (url.includes('dialogs')) {
|
||||||
describe('getOptions()', () => {
|
return {
|
||||||
it('should return url and headers', async() => {
|
|
||||||
const result = await models.Docuware.getOptions();
|
|
||||||
|
|
||||||
expect(result.url).toBeDefined();
|
|
||||||
expect(result.headers).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getDialog()', () => {
|
|
||||||
it('should return dialogId', async() => {
|
|
||||||
const dialogs = {
|
|
||||||
data: {
|
data: {
|
||||||
Dialog: [
|
Dialog: [
|
||||||
{
|
{
|
||||||
|
@ -31,58 +26,30 @@ describe('Docuware core', () => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
|
||||||
const result = await models.Docuware.getDialog('deliveryNote', 'find', 'randomFileCabinetId');
|
|
||||||
|
|
||||||
expect(result).toEqual('getDialogTest');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getFileCabinet()', () => {
|
|
||||||
it('should return fileCabinetId', async() => {
|
|
||||||
const code = 'deliveryNote';
|
|
||||||
const docuwareInfo = await models.Docuware.findOne({
|
|
||||||
where: {
|
|
||||||
code
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
const dialogs = {
|
if (url.includes('FileCabinets')) {
|
||||||
data: {
|
return {data: {
|
||||||
FileCabinet: [
|
FileCabinet: [
|
||||||
{
|
{
|
||||||
Name: docuwareInfo.fileCabinetName,
|
Name: docuwareInfo.fileCabinetName,
|
||||||
Id: 'getFileCabinetTest'
|
Id: 'getFileCabinetTest'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
|
||||||
const result = await models.Docuware.getFileCabinet(code);
|
|
||||||
|
|
||||||
expect(result).toEqual('getFileCabinetTest');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('get()', () => {
|
spyOn(axios, 'post').and.callFake(url => {
|
||||||
it('should return data without parse', async() => {
|
if (url.includes('token_endpoint')) {
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
return {data: {
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
access_token: 'access_token',
|
||||||
const data = {
|
token_type: 'bearer',
|
||||||
data: {
|
expires_in: 10000
|
||||||
id: 1
|
}};
|
||||||
}
|
}
|
||||||
};
|
if (url.includes('DialogExpression')) {
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
return {data: {
|
||||||
const result = await models.Docuware.get('deliveryNote');
|
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return data with parse', async() => {
|
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
|
||||||
const data = {
|
|
||||||
data: {
|
|
||||||
Items: [{
|
Items: [{
|
||||||
Fields: [
|
Fields: [
|
||||||
{
|
{
|
||||||
|
@ -104,11 +71,51 @@ describe('Docuware core', () => {
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
delete process.env.NODE_ENV;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getOptions()', () => {
|
||||||
|
it('should return url and headers', async() => {
|
||||||
|
const result = await models.Docuware.getOptions();
|
||||||
|
|
||||||
|
expect(result.url).toBeDefined();
|
||||||
|
expect(result.headers).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Dialog()', () => {
|
||||||
|
it('should return dialogId', async() => {
|
||||||
|
const result = await models.Docuware.getDialog('deliveryNote', 'find', 'randomFileCabinetId');
|
||||||
|
|
||||||
|
expect(result).toEqual('getDialogTest');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getFileCabinet()', () => {
|
||||||
|
it('should return fileCabinetId', async() => {
|
||||||
|
const result = await models.Docuware.getFileCabinet(fileCabinetCode);
|
||||||
|
|
||||||
|
expect(result).toEqual('getFileCabinetTest');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('get()', () => {
|
||||||
|
it('should return data without parse', async() => {
|
||||||
|
const [result] = await models.Docuware.get('deliveryNote');
|
||||||
|
|
||||||
|
expect(result.firstRequiredField).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with parse', async() => {
|
||||||
const parse = {
|
const parse = {
|
||||||
'firstRequiredField': 'id',
|
'firstRequiredField': 'id',
|
||||||
'secondRequiredField': 'name',
|
'secondRequiredField': 'name',
|
||||||
};
|
};
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
|
||||||
const [result] = await models.Docuware.get('deliveryNote', null, parse);
|
const [result] = await models.Docuware.get('deliveryNote', null, parse);
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
expect(result.id).toEqual(1);
|
||||||
|
@ -119,17 +126,14 @@ describe('Docuware core', () => {
|
||||||
|
|
||||||
describe('getById()', () => {
|
describe('getById()', () => {
|
||||||
it('should return data', async() => {
|
it('should return data', async() => {
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(models.Docuware, 'get');
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
await models.Docuware.getById('deliveryNote', 1);
|
||||||
const data = {
|
|
||||||
data: {
|
|
||||||
id: 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
|
||||||
const result = await models.Docuware.getById('deliveryNote', 1);
|
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
expect(models.Docuware.get).toHaveBeenCalledWith(
|
||||||
|
'deliveryNote',
|
||||||
|
{condition: [Object({DBName: 'N__ALBAR_N', Value: [1]})]},
|
||||||
|
undefined
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -143,7 +143,7 @@ module.exports = Self => {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
'X-File-ModifiedDate': Date.vnNew(),
|
'X-File-ModifiedDate': Date.vnNew(),
|
||||||
'Cookie': docuwareOptions.headers.headers.Cookie,
|
'Authorization': docuwareOptions.headers.headers.Authorization,
|
||||||
...data.getHeaders()
|
...data.getHeaders()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,9 +72,9 @@ describe('Renew Token', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
expect(error).toBeDefined();
|
||||||
const query = 'SELECT * FROM util.debug';
|
|
||||||
|
|
||||||
const debugLog = await models.Application.rawSql(query, null);
|
const query = 'SELECT * FROM util.debug WHERE variable = "renewToken"';
|
||||||
|
const debugLog = await models.Application.rawSql(query);
|
||||||
|
|
||||||
expect(debugLog.length).toEqual(1);
|
expect(debugLog.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
"url": {
|
"url": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"cookie": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"acls": [
|
"username": {
|
||||||
{
|
"type": "string"
|
||||||
"property": "*",
|
},
|
||||||
"accessType": "*",
|
"password": {
|
||||||
"principalType": "ROLE",
|
"type": "string"
|
||||||
"principalId": "$everyone",
|
},
|
||||||
"permission": "ALLOW"
|
"expired":{
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,23 +388,23 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`)
|
||||||
(4, 'GCN Channel'),
|
(4, 'GCN Channel'),
|
||||||
(5, 'The Newspaper');
|
(5, 'The Newspaper');
|
||||||
|
|
||||||
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`, `hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`businessTypeFk`,`typeFk`)
|
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`, `hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`businessTypeFk`,`typeFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
(1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
||||||
(1102, 'Petter Parker', '87945234L', 'SPIDER MAN', 'Aunt May', '20 INGRAM STREET, QUEENS, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
(1102, 'Petter Parker', '87945234L', 'SPIDER MAN', 'Aunt May', '20 INGRAM STREET, QUEENS, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
||||||
(1103, 'Clark Kent', '06815934E', 'SUPER MAN', 'lois lane', '344 CLINTON STREET, APARTAMENT 3-D', 'Gotham', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
(1103, 'Clark Kent', '06815934E', 'SUPER MAN', 'lois lane', '344 CLINTON STREET, APARTAMENT 3-D', 'Gotham', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
||||||
(1104, 'Tony Stark', '06089160W', 'IRON MAN', 'Pepper Potts', '10880 MALIBU POINT, 90265', 'Gotham', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
(1104, 'Tony Stark', '06089160W', 'IRON MAN', 'Pepper Potts', '10880 MALIBU POINT, 90265', 'Gotham', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 18, 0, 'florist','normal'),
|
||||||
(1105, 'Max Eisenhardt', '251628698', 'MAGNETO', 'Rogue', 'UNKNOWN WHEREABOUTS', 'Gotham', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 300, 8, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 18, 0, 'florist','normal'),
|
(1105, 'Max Eisenhardt', '251628698', 'MAGNETO', 'Rogue', 'UNKNOWN WHEREABOUTS', 'Gotham', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 300, 8, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 18, 0, 'florist','normal'),
|
||||||
(1106, 'DavidCharlesHaller', '53136686Q', 'LEGION', 'Charles Xavier', 'CITY OF NEW YORK, NEW YORK, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 19, 0, 'florist','normal'),
|
(1106, 'DavidCharlesHaller', '53136686Q', 'LEGION', 'Charles Xavier', 'CITY OF NEW YORK, NEW YORK, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, 19, 0, 'florist','normal'),
|
||||||
(1107, 'Hank Pym', '09854837G', 'ANT MAN', 'Hawk', 'ANTHILL, SAN FRANCISCO, CALIFORNIA', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 19, 0, 'florist','normal'),
|
(1107, 'Hank Pym', '09854837G', 'ANT MAN', 'Hawk', 'ANTHILL, SAN FRANCISCO, CALIFORNIA', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 19, 0, 'florist','normal'),
|
||||||
(1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 19, 0, 'florist','normal'),
|
(1108, 'Charles Xavier', '22641921P', 'PROFESSOR X', 'Beast', '3800 VICTORY PKWY, CINCINNATI, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 5, 1, 300, 13, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, NULL, 0, 0, 19, 0, 'florist','normal'),
|
||||||
(1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 9, 0, 'florist','normal'),
|
(1109, 'Bruce Banner', '16104829E', 'HULK', 'Black widow', 'SOMEWHERE IN NEW YORK', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 0, 0, NULL, 0, 0, 9, 0, 'florist','normal'),
|
||||||
(1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, NULL, 1, 'florist','normal'),
|
(1110, 'Jessica Jones', '58282869H', 'JESSICA JONES', 'Luke Cage', 'NYCC 2015 POSTER', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, NULL, 0, 0, NULL, 1, 'florist','normal'),
|
||||||
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses'),
|
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses'),
|
||||||
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses');
|
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 0, 1, 0, NULL, 1, 0, NULL, 0, 'others','loses');
|
||||||
|
|
||||||
INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`)
|
INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`)
|
||||||
SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), UPPER(CONCAT(name, 'Social')), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, util.VN_CURDATE(), 1
|
SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), UPPER(CONCAT(name, 'Social')), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, 10, 5, util.VN_CURDATE(), 1
|
||||||
FROM `account`.`role` `r`
|
FROM `account`.`role` `r`
|
||||||
WHERE `r`.`hasLogin` = 1;
|
WHERE `r`.`hasLogin` = 1;
|
||||||
|
|
||||||
|
@ -546,7 +546,8 @@ INSERT INTO `vn`.`observationType`(`id`,`description`, `code`)
|
||||||
(6, 'Weight', 'weight'),
|
(6, 'Weight', 'weight'),
|
||||||
(7, 'InvoiceOut', 'invoiceOut'),
|
(7, 'InvoiceOut', 'invoiceOut'),
|
||||||
(8, 'DropOff', 'dropOff'),
|
(8, 'DropOff', 'dropOff'),
|
||||||
(9, 'Sustitución', 'substitution');
|
(9, 'Sustitución', 'substitution'),
|
||||||
|
(10, 'Finance', 'finance');
|
||||||
|
|
||||||
INSERT INTO `vn`.`addressObservation`(`id`,`addressFk`,`observationTypeFk`,`description`)
|
INSERT INTO `vn`.`addressObservation`(`id`,`addressFk`,`observationTypeFk`,`description`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -22,7 +22,6 @@ BEGIN
|
||||||
DECLARE vItemFk INT;
|
DECLARE vItemFk INT;
|
||||||
DECLARE vConcept VARCHAR(30);
|
DECLARE vConcept VARCHAR(30);
|
||||||
DECLARE vAmount INT;
|
DECLARE vAmount INT;
|
||||||
DECLARE vAvailable INT;
|
|
||||||
DECLARE vPrice DECIMAL(10,2);
|
DECLARE vPrice DECIMAL(10,2);
|
||||||
DECLARE vSaleFk INT;
|
DECLARE vSaleFk INT;
|
||||||
DECLARE vRowFk INT;
|
DECLARE vRowFk INT;
|
||||||
|
@ -32,7 +31,6 @@ BEGIN
|
||||||
DECLARE vClientFk INT;
|
DECLARE vClientFk INT;
|
||||||
DECLARE vCompanyFk INT;
|
DECLARE vCompanyFk INT;
|
||||||
DECLARE vAgencyModeFk INT;
|
DECLARE vAgencyModeFk INT;
|
||||||
DECLARE vCalcFk INT;
|
|
||||||
DECLARE vIsTaxDataChecked BOOL;
|
DECLARE vIsTaxDataChecked BOOL;
|
||||||
|
|
||||||
DECLARE vDates CURSOR FOR
|
DECLARE vDates CURSOR FOR
|
||||||
|
@ -109,7 +107,7 @@ BEGIN
|
||||||
) INTO vHas0Amount;
|
) INTO vHas0Amount;
|
||||||
|
|
||||||
IF vHas0Amount THEN
|
IF vHas0Amount THEN
|
||||||
CALL util.throw('Remove lines with quantity = 0 before confirming');
|
CALL util.throw('Hay líneas vacías. Por favor, elimínelas');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
|
|
|
@ -4,7 +4,7 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `hedera`.`orderRow_afterIns
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE `order`
|
UPDATE `order`
|
||||||
SET rowUpdated = NOW()
|
SET rowUpdated = util.VN_NOW()
|
||||||
WHERE id = NEW.orderFk;
|
WHERE id = NEW.orderFk;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -5,100 +5,139 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`collection_getAssigne
|
||||||
)
|
)
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Comprueba si existen colecciones libres que se ajustan al perfil del usuario
|
* Comprueba si existen colecciones libres que se ajustan
|
||||||
* y le asigna la más antigua.
|
* al perfil del usuario y le asigna la más antigua.
|
||||||
* Añade un registro al semillero de colecciones y hace la reserva para la colección
|
* Añade un registro al semillero de colecciones.
|
||||||
*
|
*
|
||||||
* @param vUserFk Id de usuario
|
* @param vUserFk Id de usuario
|
||||||
* @param vCollectionFk Id de colección
|
* @param vCollectionFk Id de colección
|
||||||
*/
|
*/
|
||||||
DECLARE vHasTooMuchCollections BOOL;
|
DECLARE vHasTooMuchCollections BOOL;
|
||||||
DECLARE vItemPackingTypeFk VARCHAR(1);
|
DECLARE vDone BOOL DEFAULT FALSE;
|
||||||
DECLARE vWarehouseFk INT;
|
DECLARE vCollectionWorker INT;
|
||||||
DECLARE vLockName VARCHAR(215);
|
DECLARE vMaxNotAssignedCollectionLifeTime TIME;
|
||||||
DECLARE vLockTime INT DEFAULT 30;
|
|
||||||
|
DECLARE vCollections CURSOR FOR
|
||||||
|
WITH collections AS (
|
||||||
|
SELECT tc.collectionFk,
|
||||||
|
SUM(sv.volume) volume,
|
||||||
|
c.saleTotalCount,
|
||||||
|
c.itemPackingTypeFk,
|
||||||
|
c.trainFk,
|
||||||
|
c.warehouseFk,
|
||||||
|
c.wagons
|
||||||
|
FROM vn.ticketCollection tc
|
||||||
|
JOIN vn.collection c ON c.id = tc.collectionFk
|
||||||
|
JOIN vn.saleVolume sv ON sv.ticketFk = tc.ticketFk
|
||||||
|
WHERE c.workerFk IS NULL
|
||||||
|
AND sv.shipped >= util.VN_CURDATE()
|
||||||
|
GROUP BY tc.collectionFk
|
||||||
|
) SELECT c.collectionFk
|
||||||
|
FROM collections c
|
||||||
|
JOIN vn.operator o
|
||||||
|
WHERE o.workerFk = vUserFk
|
||||||
|
AND (c.saleTotalCount <= o.linesLimit OR o.linesLimit IS NULL)
|
||||||
|
AND (c.itemPackingTypeFk = o.itemPackingTypeFk OR o.itemPackingTypeFk IS NULL)
|
||||||
|
AND o.numberOfWagons = c.wagons
|
||||||
|
AND o.trainFk = c.trainFk
|
||||||
|
AND o.warehouseFk = c.warehouseFk;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||||
|
-- Si hay colecciones sin terminar, sale del proceso
|
||||||
|
|
||||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
BEGIN
|
BEGIN
|
||||||
IF vLockName IS NOT NULL THEN
|
ROLLBACK;
|
||||||
DO RELEASE_LOCK(vLockName);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RESIGNAL;
|
RESIGNAL;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
-- Si hay colecciones sin terminar, sale del proceso
|
|
||||||
CALL collection_get(vUserFk);
|
CALL collection_get(vUserFk);
|
||||||
|
|
||||||
SELECT (pc.maxNotReadyCollections - COUNT(*)) <= 0,
|
SELECT (pc.maxNotReadyCollections - COUNT(*)) <= 0, pc.maxNotAssignedCollectionLifeTime
|
||||||
pc.collection_assign_lockname
|
INTO vHasTooMuchCollections, vMaxNotAssignedCollectionLifeTime
|
||||||
INTO vHasTooMuchCollections,
|
FROM productionConfig pc
|
||||||
vLockName
|
LEFT JOIN tmp.collection ON TRUE;
|
||||||
FROM tmp.collection c
|
|
||||||
JOIN productionConfig pc;
|
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tmp.collection;
|
DROP TEMPORARY TABLE tmp.collection;
|
||||||
|
|
||||||
IF vHasTooMuchCollections THEN
|
IF vHasTooMuchCollections THEN
|
||||||
CALL util.throw('There are pending collections');
|
CALL util.throw('Hay colecciones pendientes');
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT warehouseFk, itemPackingTypeFk
|
|
||||||
INTO vWarehouseFk, vItemPackingTypeFk
|
|
||||||
FROM operator
|
|
||||||
WHERE workerFk = vUserFk;
|
|
||||||
|
|
||||||
SET vLockName = CONCAT_WS('/',
|
|
||||||
vLockName,
|
|
||||||
vWarehouseFk,
|
|
||||||
vItemPackingTypeFk
|
|
||||||
);
|
|
||||||
|
|
||||||
IF NOT GET_LOCK(vLockName, vLockTime) THEN
|
|
||||||
CALL util.throw(CONCAT('Cannot get lock: ', vLockName));
|
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Se eliminan las colecciones sin asignar que estan obsoletas
|
-- Se eliminan las colecciones sin asignar que estan obsoletas
|
||||||
|
|
||||||
INSERT INTO ticketTracking(stateFk, ticketFk)
|
INSERT INTO ticketTracking(stateFk, ticketFk)
|
||||||
SELECT s.id, tc.ticketFk
|
SELECT s.id, tc.ticketFk
|
||||||
FROM collection c
|
FROM `collection` c
|
||||||
JOIN ticketCollection tc ON tc.collectionFk = c.id
|
JOIN ticketCollection tc ON tc.collectionFk = c.id
|
||||||
JOIN state s ON s.code = 'PRINTED_AUTO'
|
JOIN `state` s ON s.code = 'PRINTED_AUTO'
|
||||||
JOIN productionConfig pc
|
|
||||||
WHERE c.workerFk IS NULL
|
WHERE c.workerFk IS NULL
|
||||||
AND TIMEDIFF(util.VN_NOW(), c.created) > pc.maxNotAssignedCollectionLifeTime;
|
AND TIMEDIFF(util.VN_NOW(), c.created) > vMaxNotAssignedCollectionLifeTime;
|
||||||
|
|
||||||
DELETE c
|
DELETE FROM `collection`
|
||||||
FROM collection c
|
WHERE workerFk IS NULL
|
||||||
JOIN productionConfig pc
|
AND TIMEDIFF(util.VN_NOW(), created) > vMaxNotAssignedCollectionLifeTime;
|
||||||
WHERE c.workerFk IS NULL
|
|
||||||
AND TIMEDIFF(util.VN_NOW(), c.created) > pc.maxNotAssignedCollectionLifeTime;
|
|
||||||
|
|
||||||
-- Se añade registro al semillero
|
-- Se añade registro al semillero
|
||||||
INSERT INTO collectionHotbed
|
|
||||||
SET userFk = vUserFk;
|
INSERT INTO collectionHotbed(userFk) VALUES(vUserFk);
|
||||||
|
|
||||||
-- Comprueba si hay colecciones disponibles que se ajustan a su configuracion
|
-- Comprueba si hay colecciones disponibles que se ajustan a su configuracion
|
||||||
SELECT MIN(c.id) INTO vCollectionFk
|
|
||||||
FROM collection c
|
|
||||||
JOIN operator o ON (o.itemPackingTypeFk = c.itemPackingTypeFk
|
|
||||||
OR c.itemPackingTypeFk IS NULL)
|
|
||||||
AND o.numberOfWagons = c.wagons
|
|
||||||
AND o.trainFk = c.trainFk
|
|
||||||
AND o.warehouseFk = c.warehouseFk
|
|
||||||
AND c.workerFk IS NULL
|
|
||||||
WHERE o.workerFk = vUserFk;
|
|
||||||
|
|
||||||
IF vCollectionFk IS NULL THEN
|
OPEN vCollections;
|
||||||
CALL collection_new(vUserFk, vCollectionFk);
|
l: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vCollections INTO vCollectionFk;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE l;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
UPDATE collection
|
BEGIN
|
||||||
|
DECLARE EXIT HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
ROLLBACK;
|
||||||
|
SET vCollectionFk = NULL;
|
||||||
|
RESIGNAL;
|
||||||
|
END;
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
SELECT workerFk INTO vCollectionWorker
|
||||||
|
FROM `collection`
|
||||||
|
WHERE id = vCollectionFk FOR UPDATE;
|
||||||
|
|
||||||
|
IF vCollectionWorker IS NULL THEN
|
||||||
|
UPDATE `collection`
|
||||||
SET workerFk = vUserFk
|
SET workerFk = vUserFk
|
||||||
WHERE id = vCollectionFk;
|
WHERE id = vCollectionFk;
|
||||||
|
|
||||||
CALL itemShelvingSale_addByCollection(vCollectionFk);
|
COMMIT;
|
||||||
|
LEAVE l;
|
||||||
|
END IF;
|
||||||
|
|
||||||
DO RELEASE_LOCK(vLockName);
|
ROLLBACK;
|
||||||
|
END;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vCollections;
|
||||||
|
|
||||||
|
IF vCollectionFk IS NULL THEN
|
||||||
|
CALL collection_new(vUserFk, vCollectionFk);
|
||||||
|
|
||||||
|
START TRANSACTION;
|
||||||
|
|
||||||
|
SELECT workerFk INTO vCollectionWorker
|
||||||
|
FROM `collection`
|
||||||
|
WHERE id = vCollectionFk FOR UPDATE;
|
||||||
|
|
||||||
|
IF vCollectionWorker IS NULL THEN
|
||||||
|
UPDATE `collection`
|
||||||
|
SET workerFk = vUserFk
|
||||||
|
WHERE id = vCollectionFk;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
END IF;
|
||||||
|
CALL itemShelvingSale_addByCollection(vCollectionFk);
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
|
@ -0,0 +1,20 @@
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`saleTracking_sectorCollectionAddPrevOK`(
|
||||||
|
vSectorCollectionFk INT
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Inserta los registros de sectorCollection con el estado PREVIA OK si la reserva está picked
|
||||||
|
*
|
||||||
|
* @param vSectorCollectionFk Identificador de vn.sectorCollection
|
||||||
|
*/
|
||||||
|
REPLACE saleTracking(saleFk, isChecked, workerFk, stateFk)
|
||||||
|
SELECT sgd.saleFk, TRUE, sc.userFk, s.id
|
||||||
|
FROM sectorCollection sc
|
||||||
|
JOIN sectorCollectionSaleGroup scsg ON scsg.sectorCollectionFk = sc.id
|
||||||
|
JOIN saleGroupDetail sgd ON sgd.saleGroupFk = scsg.saleGroupFk
|
||||||
|
JOIN state s ON s.code = 'OK PREVIOUS'
|
||||||
|
JOIN itemShelvingSale iss ON iss.saleFk = sgd.saleFk
|
||||||
|
WHERE sc.id = vSectorCollectionFk AND iss.isPicked;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
|
@ -3,10 +3,10 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`itemShelvingSale_afterI
|
||||||
AFTER INSERT ON `itemShelvingSale`
|
AFTER INSERT ON `itemShelvingSale`
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
|
|
||||||
UPDATE sale s
|
UPDATE sale s
|
||||||
JOIN operator o ON o.workerFk = account.myUser_getId()
|
JOIN operator o ON o.workerFk = account.myUser_getId()
|
||||||
SET s.isPicked = IF(o.isOnReservationMode, s.isPicked, TRUE)
|
JOIN sector se ON se.id = o.sectorFk
|
||||||
WHERE id = NEW.saleFk;
|
SET s.isPicked = IF(IFNULL(se.isOnReservationMode, o.isOnReservationMode), s.isPicked, TRUE)
|
||||||
|
WHERE s.id = NEW.saleFk;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
|
@ -22,7 +22,6 @@ AS SELECT `c`.`id` AS `id_cliente`,
|
||||||
`c`.`credit` AS `credito`,
|
`c`.`credit` AS `credito`,
|
||||||
`c`.`countryFk` AS `Id_Pais`,
|
`c`.`countryFk` AS `Id_Pais`,
|
||||||
`c`.`isActive` AS `activo`,
|
`c`.`isActive` AS `activo`,
|
||||||
`c`.`gestdocFk` AS `gestdoc_id`,
|
|
||||||
`c`.`quality` AS `calidad`,
|
`c`.`quality` AS `calidad`,
|
||||||
`c`.`payMethodFk` AS `pay_met_id`,
|
`c`.`payMethodFk` AS `pay_met_id`,
|
||||||
`c`.`created` AS `created`,
|
`c`.`created` AS `created`,
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE vn.clientObservation DROP COLUMN IF EXISTS observationTypeFk;
|
||||||
|
ALTER TABLE vn.clientObservation ADD COLUMN IF NOT EXISTS observationTypeFk TINYINT(3) UNSIGNED NULL;
|
||||||
|
ALTER TABLE vn.clientObservation ADD CONSTRAINT clientObservationTypeFk FOREIGN KEY IF NOT EXISTS (observationTypeFk) REFERENCES vn.observationType(id);
|
|
@ -0,0 +1,3 @@
|
||||||
|
INSERT IGNORE INTO vn.observationType
|
||||||
|
SET description = 'Finance',
|
||||||
|
code = 'finance';
|
|
@ -1,5 +1,3 @@
|
||||||
/*
|
|
||||||
UPDATE vn.sale
|
UPDATE vn.sale
|
||||||
SET originalQuantity = quantity
|
SET originalQuantity = quantity
|
||||||
WHERE originalQuantity IS NULL
|
WHERE originalQuantity IS NULL
|
||||||
*/
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
-- ALTER TABLE vn.sale MODIFY COLUMN originalQuantity decimal(10,2) DEFAULT 0.00 NOT NULL COMMENT 'Se utiliza para notificar a través de rocket los cambios de quantity';
|
ALTER TABLE vn.sale MODIFY COLUMN originalQuantity decimal(10,2) DEFAULT 0.00 NOT NULL COMMENT 'Se utiliza para notificar a través de rocket los cambios de quantity';
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE hedera.`order` ADD IF NOT EXISTS rowUpdated DATETIME NULL
|
||||||
|
COMMENT 'Timestamp for last updated record in orderRow table';
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
ALTER TABLE vn.sector ADD isOnReservationMode tinyint(1) DEFAULT FALSE NULL;
|
|
@ -0,0 +1,4 @@
|
||||||
|
ALTER TABLE vn.docuwareConfig ADD IF NOT EXISTS username varchar(100) NULL;
|
||||||
|
ALTER TABLE vn.docuwareConfig ADD IF NOT EXISTS password varchar(100) NULL;
|
||||||
|
ALTER TABLE vn.docuwareConfig ADD IF NOT EXISTS token text NULL;
|
||||||
|
ALTER TABLE vn.docuwareConfig ADD IF NOT EXISTS expired int(11) NULL;
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Place your SQL code here
|
||||||
|
ALTER TABLE vn.itemShelving DROP COLUMN IF EXISTS isMoving;
|
||||||
|
ALTER TABLE vn.itemShelving ADD IF NOT EXISTS movingState ENUM('selected','printed') NULL;
|
|
@ -0,0 +1,3 @@
|
||||||
|
ALTER TABLE `vn`.`ticketConfig`
|
||||||
|
ADD COLUMN `closureDaysAgo` int(11) NOT NULL DEFAULT 2 COMMENT 'Number of days to look back for ticket closure',
|
||||||
|
ADD CONSTRAINT `closureDaysAgo_check` CHECK (`closureDaysAgo` > 0);
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE vn.client CHANGE gestdocFk gestdocFk__ int(11) DEFAULT NULL NULL COMMENT '@deprecated 2024-10-17';
|
|
@ -1,42 +0,0 @@
|
||||||
import selectors from '../../helpers/selectors';
|
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
|
||||||
|
|
||||||
describe('Client Add notes path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
|
||||||
beforeAll(async() => {
|
|
||||||
browser = await getBrowser();
|
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('employee', 'client');
|
|
||||||
await page.accessToSearchResult('Bruce Banner');
|
|
||||||
await page.accessToSection('client.card.note.index');
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async() => {
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should reach the notes index`, async() => {
|
|
||||||
await page.waitForState('client.card.note.index');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should click on the add note button`, async() => {
|
|
||||||
await page.waitToClick(selectors.clientNotes.addNoteFloatButton);
|
|
||||||
await page.waitForState('client.card.note.create');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should create a note`, async() => {
|
|
||||||
await page.waitForSelector(selectors.clientNotes.note);
|
|
||||||
await page.type(`${selectors.clientNotes.note} textarea`, 'Meeting with Black Widow 21st 9am');
|
|
||||||
await page.waitToClick(selectors.clientNotes.saveButton);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should confirm the note was created', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.clientNotes.firstNoteText, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('Meeting with Black Widow 21st 9am');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -28,12 +28,12 @@ describe('Client defaulter path', () => {
|
||||||
const salesPersonName =
|
const salesPersonName =
|
||||||
await page.waitToGetProperty(selectors.clientDefaulter.firstSalesPersonName, 'innerText');
|
await page.waitToGetProperty(selectors.clientDefaulter.firstSalesPersonName, 'innerText');
|
||||||
|
|
||||||
expect(clientName).toEqual('Bruce Banner');
|
expect(clientName).toEqual('Ororo Munroe');
|
||||||
expect(salesPersonName).toEqual('developer');
|
expect(salesPersonName).toEqual('salesperson');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should first observation not changed', async() => {
|
it('should first observation not changed', async() => {
|
||||||
const expectedObservation = 'Meeting with Black Widow 21st 9am';
|
const expectedObservation = 'Madness, as you know, is like gravity, all it takes is a little push';
|
||||||
const result = await page.waitToGetProperty(selectors.clientDefaulter.firstObservation, 'value');
|
const result = await page.waitToGetProperty(selectors.clientDefaulter.firstObservation, 'value');
|
||||||
|
|
||||||
expect(result).toContain(expectedObservation);
|
expect(result).toContain(expectedObservation);
|
||||||
|
@ -62,13 +62,4 @@ describe('Client defaulter path', () => {
|
||||||
await page.write(selectors.clientDefaulter.observation, 'My new observation');
|
await page.write(selectors.clientDefaulter.observation, 'My new observation');
|
||||||
await page.waitToClick(selectors.clientDefaulter.saveButton);
|
await page.waitToClick(selectors.clientDefaulter.saveButton);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should first observation changed', async() => {
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
await page.waitForSelector(selectors.clientDefaulter.firstObservation);
|
|
||||||
const result = await page.waitToGetProperty(selectors.clientDefaulter.firstObservation, 'value');
|
|
||||||
|
|
||||||
expect(message.text).toContain('Observation saved!');
|
|
||||||
expect(result).toContain('My new observation');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -381,5 +381,6 @@
|
||||||
"The entry does not have stickers": "La entrada no tiene etiquetas",
|
"The entry does not have stickers": "La entrada no tiene etiquetas",
|
||||||
"This buyer has already made a reservation for this date": "Este comprador ya ha hecho una reserva para esta fecha",
|
"This buyer has already made a reservation for this date": "Este comprador ya ha hecho una reserva para esta fecha",
|
||||||
"No valid travel thermograph found": "No se encontró un termógrafo válido",
|
"No valid travel thermograph found": "No se encontró un termógrafo válido",
|
||||||
"The quantity claimed cannot be greater than the quantity of the line": "La cantidad reclamada no puede ser mayor que la cantidad de la línea"
|
"The quantity claimed cannot be greater than the quantity of the line": "La cantidad reclamada no puede ser mayor que la cantidad de la línea",
|
||||||
|
"type cannot be blank": "Se debe rellenar el tipo"
|
||||||
}
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
module.exports = function(Self) {
|
module.exports = function(Self) {
|
||||||
Self.validate('text', isEnabled, {message: 'Description cannot be blank'});
|
Self.validate('text', function(err) {
|
||||||
function isEnabled(err) {
|
|
||||||
if (!this.text) err();
|
if (!this.text) err();
|
||||||
}
|
}, {message: 'Description cannot be blank'});
|
||||||
|
|
||||||
|
Self.validate('observationTypeFk', function(err) {
|
||||||
|
if (!this.observationTypeFk) err();
|
||||||
|
}, {message: 'type cannot be blank'});
|
||||||
|
|
||||||
Self.observe('before save', function(ctx, next) {
|
Self.observe('before save', function(ctx, next) {
|
||||||
ctx.instance.created = Date();
|
ctx.instance.created = Date();
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
"created": {
|
"created": {
|
||||||
"type": "date",
|
"type": "date",
|
||||||
"description": "Creation date and time"
|
"description": "Creation date and time"
|
||||||
|
},
|
||||||
|
"observationTypeFk": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "Type of observation"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
@ -44,11 +48,15 @@
|
||||||
"include": {
|
"include": {
|
||||||
"relation": "worker",
|
"relation": "worker",
|
||||||
"scope": {
|
"scope": {
|
||||||
"fields": ["id"],
|
"fields": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
"include": {
|
"include": {
|
||||||
"relation": "user",
|
"relation": "user",
|
||||||
"scope": {
|
"scope": {
|
||||||
"fields": ["nickname"]
|
"fields": [
|
||||||
|
"nickname"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
<vn-crud-model
|
|
||||||
vn-id="model"
|
|
||||||
url="clientObservations"
|
|
||||||
filter="$ctrl.filter"
|
|
||||||
link="{clientFk: $ctrl.$params.id}"
|
|
||||||
data="notes"
|
|
||||||
auto-load="true">
|
|
||||||
</vn-crud-model>
|
|
||||||
<vn-data-viewer
|
|
||||||
model="model"
|
|
||||||
class="vn-w-md">
|
|
||||||
<vn-card class="vn-pa-md">
|
|
||||||
<div
|
|
||||||
ng-repeat="note in notes"
|
|
||||||
class="note vn-pa-sm border-solid border-radius vn-mb-md">
|
|
||||||
<vn-horizontal class="vn-mb-sm" style="color: #666">
|
|
||||||
<vn-one>{{::note.worker.user.nickname}}</vn-one>
|
|
||||||
<vn-auto>{{::note.created | date:'dd/MM/yyyy HH:mm'}}</vn-auto>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal class="text">
|
|
||||||
{{::note.text}}
|
|
||||||
</vn-horizontal>
|
|
||||||
</div>
|
|
||||||
</vn-card>
|
|
||||||
</vn-data-viewer>
|
|
||||||
<a vn-tooltip="New note"
|
|
||||||
ui-sref="client.card.note.create({id: $ctrl.$params.id})"
|
|
||||||
vn-bind="+"
|
|
||||||
fixed-bottom-right>
|
|
||||||
<vn-float-button icon="add"></vn-float-button>
|
|
||||||
</a>
|
|
|
@ -5,9 +5,10 @@ import './style.scss';
|
||||||
export default class Controller extends Section {
|
export default class Controller extends Section {
|
||||||
constructor($element, $) {
|
constructor($element, $) {
|
||||||
super($element, $);
|
super($element, $);
|
||||||
this.filter = {
|
}
|
||||||
order: 'created DESC',
|
async $onInit() {
|
||||||
};
|
this.$state.go('home');
|
||||||
|
window.location.href = await this.vnApp.getUrl(`customer/${this.$params.id}/notes`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
Tickets monitor: Monitor de tickets
|
||||||
|
Clients on website: Clientes activos en la web
|
||||||
|
Recent order actions: Acciones recientes en pedidos
|
||||||
|
Search tickets: Buscar tickets
|
||||||
|
Delete selected elements: Eliminar los elementos seleccionados
|
||||||
|
All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
|
||||||
|
Component lack: Faltan componentes
|
||||||
|
Ticket too little: Ticket demasiado pequeño
|
||||||
|
Minimize/Maximize: Minimizar/Maximizar
|
||||||
|
Problems: Problemas
|
||||||
|
Theoretical: Teórica
|
||||||
|
Practical: Práctica
|
||||||
|
Preparation: Preparación
|
||||||
|
Auto-refresh: Auto-refresco
|
||||||
|
Toggle auto-refresh every 2 minutes: Conmuta el refresco automático cada 2 minutos
|
||||||
|
Is fragile: Es frágil
|
|
@ -59,6 +59,9 @@
|
||||||
"isReserve": {
|
"isReserve": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
"isOnReservationMode": {
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,8 +53,9 @@ module.exports = Self => {
|
||||||
JOIN province p ON p.id = c.provinceFk
|
JOIN province p ON p.id = c.provinceFk
|
||||||
JOIN country co ON co.id = p.countryFk
|
JOIN country co ON co.id = p.countryFk
|
||||||
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
||||||
|
JOIN ticketConfig tc ON TRUE
|
||||||
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
|
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
|
||||||
AND DATE(t.shipped) BETWEEN ? - INTERVAL 7 DAY AND util.dayEnd(?)
|
AND t.shipped BETWEEN ? - INTERVAL tc.closureDaysAgo DAY AND util.dayEnd(?)
|
||||||
AND t.refFk IS NULL
|
AND t.refFk IS NULL
|
||||||
GROUP BY t.id
|
GROUP BY t.id
|
||||||
`, [toDate, toDate]);
|
`, [toDate, toDate]);
|
||||||
|
@ -108,6 +109,7 @@ module.exports = Self => {
|
||||||
JOIN alertLevel al ON al.id = ts.alertLevel
|
JOIN alertLevel al ON al.id = ts.alertLevel
|
||||||
JOIN client c ON c.id = t.clientFk
|
JOIN client c ON c.id = t.clientFk
|
||||||
JOIN province p ON p.id = c.provinceFk
|
JOIN province p ON p.id = c.provinceFk
|
||||||
|
JOIN ticketConfig tc ON TRUE
|
||||||
LEFT JOIN autonomy a ON a.id = p.autonomyFk
|
LEFT JOIN autonomy a ON a.id = p.autonomyFk
|
||||||
JOIN country co ON co.id = p.countryFk
|
JOIN country co ON co.id = p.countryFk
|
||||||
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
LEFT JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
|
||||||
|
@ -116,7 +118,7 @@ module.exports = Self => {
|
||||||
LEFT JOIN vn.invoiceOutSerial ios ON ios.taxAreaFk = 'WORLD'
|
LEFT JOIN vn.invoiceOutSerial ios ON ios.taxAreaFk = 'WORLD'
|
||||||
AND ios.code = invoiceSerial(t.clientFk, t.companyFk, 'multiple')
|
AND ios.code = invoiceSerial(t.clientFk, t.companyFk, 'multiple')
|
||||||
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
|
WHERE (al.code = 'PACKED' OR (am.code = 'refund' AND al.code <> 'delivered'))
|
||||||
AND DATE(t.shipped) BETWEEN ? - INTERVAL 2 DAY AND util.dayEnd(?)
|
AND t.shipped BETWEEN ? - INTERVAL tc.closureDaysAgo DAY AND util.dayEnd(?)
|
||||||
AND t.refFk IS NULL
|
AND t.refFk IS NULL
|
||||||
AND IFNULL(a.hasDailyInvoice, co.hasDailyInvoice)
|
AND IFNULL(a.hasDailyInvoice, co.hasDailyInvoice)
|
||||||
GROUP BY ticketFk
|
GROUP BY ticketFk
|
||||||
|
@ -141,9 +143,10 @@ module.exports = Self => {
|
||||||
JOIN alertLevel al ON al.id = ts.alertLevel
|
JOIN alertLevel al ON al.id = ts.alertLevel
|
||||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||||
|
JOIN ticketConfig tc ON TRUE
|
||||||
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
|
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id
|
||||||
SET t.routeFk = NULL
|
SET t.routeFk = NULL
|
||||||
WHERE DATE(t.shipped) BETWEEN ? - INTERVAL 2 DAY AND util.dayEnd(?)
|
WHERE t.shipped BETWEEN ? - INTERVAL tc.closureDaysAgo DAY AND util.dayEnd(?)
|
||||||
AND al.code NOT IN ('DELIVERED', 'PACKED')
|
AND al.code NOT IN ('DELIVERED', 'PACKED')
|
||||||
AND NOT t.packages
|
AND NOT t.packages
|
||||||
AND tob.id IS NULL
|
AND tob.id IS NULL
|
||||||
|
|
|
@ -12,10 +12,7 @@ module.exports = async function(ctx, Self, tickets, options) {
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
let tx;
|
let tx;
|
||||||
// if (!myOptions.transaction) {
|
// IMPORTANT: Due to its high cost in production, wrapping this process in a transaction may cause timeouts.
|
||||||
// tx = await Self.beginTransaction({});
|
|
||||||
// myOptions.transaction = tx;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (tickets.length == 0) return;
|
if (tickets.length == 0) return;
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,9 @@ describe('Ticket closure functionality', () => {
|
||||||
|
|
||||||
expect(ticketStateBefore.code).not.toBe(ticketStateAfter.code);
|
expect(ticketStateBefore.code).not.toBe(ticketStateAfter.code);
|
||||||
|
|
||||||
const ticketAfter = await models.TicketState.findById(ticketId, null, options);
|
const ticketAfter = await models.Ticket.findById(ticketId, null, options);
|
||||||
|
|
||||||
expect(ticketAfter.refFk).toBeUndefined();
|
expect(ticketAfter.refFk).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send Incoterms authorization email on first order', async() => {
|
it('should send Incoterms authorization email on first order', async() => {
|
||||||
|
|
|
@ -87,7 +87,7 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
relation: 'sector',
|
relation: 'sector',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['warehouseFk', 'description'],
|
fields: ['warehouseFk', 'description', 'isOnReservationMode'],
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
relation: 'printer',
|
relation: 'printer',
|
||||||
|
|
|
@ -217,6 +217,7 @@ module.exports = Self => {
|
||||||
const code = e.code;
|
const code = e.code;
|
||||||
const message = e.sqlMessage;
|
const message = e.sqlMessage;
|
||||||
|
|
||||||
|
if (e.message && e.message.includes('Invalid email')) throw new UserError('Invalid email');
|
||||||
if (e.message && e.message.includes(`Email already exists`)) throw new UserError(`This personal mail already exists`);
|
if (e.message && e.message.includes(`Email already exists`)) throw new UserError(`This personal mail already exists`);
|
||||||
if (code === 'ER_DUP_ENTRY' && message.includes(`CodigoTrabajador_UNIQUE`)) throw new UserError(`This worker code already exists`);
|
if (code === 'ER_DUP_ENTRY' && message.includes(`CodigoTrabajador_UNIQUE`)) throw new UserError(`This worker code already exists`);
|
||||||
if (code === 'ER_DUP_ENTRY' && message.includes(`PRIMARY`)) throw new UserError(`This worker already exists`);
|
if (code === 'ER_DUP_ENTRY' && message.includes(`PRIMARY`)) throw new UserError(`This worker already exists`);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "salix-back",
|
"name": "salix-back",
|
||||||
"version": "24.42.0",
|
"version": "24.44.0",
|
||||||
"author": "Verdnatura Levante SL",
|
"author": "Verdnatura Levante SL",
|
||||||
"description": "Salix backend",
|
"description": "Salix backend",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<th width="5%">{{$t('reference')}}</th>
|
<th width="5%">{{$t('reference')}}</th>
|
||||||
<th class="number">{{$t('quantity')}}</th>
|
<th class="number">{{$t('quantity')}}</th>
|
||||||
<th width="50%">{{$t('concept')}}</th>
|
<th width="50%">{{$t('concept')}}</th>
|
||||||
|
<th width="50%">{{$t('producer')}}</th>
|
||||||
<th class="number" v-if="showPrices">{{$t('price')}}</th>
|
<th class="number" v-if="showPrices">{{$t('price')}}</th>
|
||||||
<th class="centered" width="5%" v-if="showPrices">{{$t('discount')}}</th>
|
<th class="centered" width="5%" v-if="showPrices">{{$t('discount')}}</th>
|
||||||
<th class="centered" v-if="showPrices">{{$t('vat')}}</th>
|
<th class="centered" v-if="showPrices">{{$t('vat')}}</th>
|
||||||
|
@ -69,6 +70,7 @@
|
||||||
<td width="5%">{{sale.itemFk}}</td>
|
<td width="5%">{{sale.itemFk}}</td>
|
||||||
<td class="number">{{sale.quantity}}</td>
|
<td class="number">{{sale.quantity}}</td>
|
||||||
<td width="50%">{{sale.concept}}</td>
|
<td width="50%">{{sale.concept}}</td>
|
||||||
|
<td width="5%" class="font light-gray" v-if="sale.subName">{{sale.subName}}</td>
|
||||||
<td class="number" v-if="showPrices">{{sale.price | currency('EUR', $i18n.locale)}}</td>
|
<td class="number" v-if="showPrices">{{sale.price | currency('EUR', $i18n.locale)}}</td>
|
||||||
<td class="centered" width="5%" v-if="showPrices">{{(sale.discount / 100) | percentage}}</td>
|
<td class="centered" width="5%" v-if="showPrices">{{(sale.discount / 100) | percentage}}</td>
|
||||||
<td class="centered" v-if="showPrices">{{sale.vatType}}</td>
|
<td class="centered" v-if="showPrices">{{sale.vatType}}</td>
|
||||||
|
@ -81,7 +83,6 @@
|
||||||
<span v-if="sale.value5"> <strong>{{sale.tag5}}</strong> {{sale.value5}} </span>
|
<span v-if="sale.value5"> <strong>{{sale.tag5}}</strong> {{sale.value5}} </span>
|
||||||
<span v-if="sale.value6"> <strong>{{sale.tag6}}</strong> {{sale.value6}} </span>
|
<span v-if="sale.value6"> <strong>{{sale.tag6}}</strong> {{sale.value6}} </span>
|
||||||
<span v-if="sale.value7"> <strong>{{sale.tag7}}</strong> {{sale.value7}} </span>
|
<span v-if="sale.value7"> <strong>{{sale.tag7}}</strong> {{sale.value7}} </span>
|
||||||
<span v-if="sale.subName"> <strong>{{$t('producer')}}</strong> {{ sale.subName }}</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
Loading…
Reference in New Issue