Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 3888-ticket.expedition_moveExpedition
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
b0471037a7
|
@ -17,14 +17,16 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.deleteTrashFiles = async options => {
|
Self.deleteTrashFiles = async options => {
|
||||||
const tx = await Self.beginTransaction({});
|
let tx;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
if (!myOptions.transaction)
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
myOptions.transaction = tx;
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (process.env.NODE_ENV == 'test')
|
if (process.env.NODE_ENV == 'test')
|
||||||
|
@ -61,10 +63,9 @@ module.exports = Self => {
|
||||||
const dstFolder = path.join(dmsContainer.client.root, pathHash);
|
const dstFolder = path.join(dmsContainer.client.root, pathHash);
|
||||||
try {
|
try {
|
||||||
await fs.rmdir(dstFolder);
|
await fs.rmdir(dstFolder);
|
||||||
await dms.destroy(myOptions);
|
} catch (err) {}
|
||||||
} catch (err) {
|
|
||||||
await dms.destroy(myOptions);
|
await dms.destroy(myOptions);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
drop procedure `vn`.`ticket_closeByTicket`;
|
||||||
|
|
||||||
|
create
|
||||||
|
definer = root@localhost procedure `vn`.`ticket_closeByTicket`(IN vTicketFk int)
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserta el ticket en la tabla temporal
|
||||||
|
* para ser cerrado.
|
||||||
|
*
|
||||||
|
* @param vTicketFk Id del ticket
|
||||||
|
*/
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE IF EXISTS tmp.ticket_close;
|
||||||
|
CREATE TEMPORARY TABLE tmp.ticket_close ENGINE = MEMORY (
|
||||||
|
SELECT
|
||||||
|
t.id AS ticketFk
|
||||||
|
FROM ticket t
|
||||||
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
|
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
|
||||||
|
JOIN alertLevel al ON al.id = ts.alertLevel
|
||||||
|
WHERE al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered')
|
||||||
|
AND t.id = vTicketFk
|
||||||
|
AND t.refFk IS NULL
|
||||||
|
GROUP BY t.id);
|
||||||
|
|
||||||
|
CALL ticket_close();
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE tmp.ticket_close;
|
||||||
|
END;
|
||||||
|
|
|
@ -1023,8 +1023,8 @@ export default {
|
||||||
},
|
},
|
||||||
travelExtraCommunity: {
|
travelExtraCommunity: {
|
||||||
anySearchResult: 'vn-travel-extra-community > vn-card div > tbody > tr[ng-attr-id="{{::travel.id}}"]',
|
anySearchResult: 'vn-travel-extra-community > vn-card div > tbody > tr[ng-attr-id="{{::travel.id}}"]',
|
||||||
firstTravelReference: 'vn-travel-extra-community tbody:nth-child(2) vn-textfield[ng-model="travel.ref"]',
|
firstTravelReference: 'vn-travel-extra-community tbody:nth-child(2) vn-td-editable[name="reference"]',
|
||||||
firstTravelLockedKg: 'vn-travel-extra-community tbody:nth-child(2) vn-input-number[ng-model="travel.kg"]',
|
firstTravelLockedKg: 'vn-travel-extra-community tbody:nth-child(2) vn-td-editable[name="lockedKg"]',
|
||||||
removeContinentFilter: 'vn-searchbar > form > vn-textfield > div.container > div.prepend > prepend > div > span:nth-child(3) > vn-icon > i'
|
removeContinentFilter: 'vn-searchbar > form > vn-textfield > div.container > div.prepend > prepend > div > span:nth-child(3) > vn-icon > i'
|
||||||
},
|
},
|
||||||
travelBasicData: {
|
travelBasicData: {
|
||||||
|
|
|
@ -19,10 +19,10 @@ describe('Travel extra community path', () => {
|
||||||
it('should edit the travel reference and the locked kilograms', async() => {
|
it('should edit the travel reference and the locked kilograms', async() => {
|
||||||
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
||||||
await page.waitForSpinnerLoad();
|
await page.waitForSpinnerLoad();
|
||||||
await page.clearInput(selectors.travelExtraCommunity.firstTravelReference);
|
await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelReference, 'edited reference');
|
||||||
await page.write(selectors.travelExtraCommunity.firstTravelReference, 'edited reference');
|
await page.waitForSpinnerLoad();
|
||||||
await page.clearInput(selectors.travelExtraCommunity.firstTravelLockedKg);
|
await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelLockedKg, '1500');
|
||||||
await page.write(selectors.travelExtraCommunity.firstTravelLockedKg, '1500');
|
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
expect(message.text).toContain('Data saved!');
|
||||||
|
@ -32,9 +32,9 @@ describe('Travel extra community path', () => {
|
||||||
await page.accessToSection('travel.index');
|
await page.accessToSection('travel.index');
|
||||||
await page.accessToSection('travel.extraCommunity');
|
await page.accessToSection('travel.extraCommunity');
|
||||||
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter);
|
||||||
|
await page.waitForTextInElement(selectors.travelExtraCommunity.firstTravelReference, 'edited reference');
|
||||||
const reference = await page.waitToGetProperty(selectors.travelExtraCommunity.firstTravelReference, 'value');
|
const reference = await page.getProperty(selectors.travelExtraCommunity.firstTravelReference, 'innerText');
|
||||||
const lockedKg = await page.waitToGetProperty(selectors.travelExtraCommunity.firstTravelLockedKg, 'value');
|
const lockedKg = await page.getProperty(selectors.travelExtraCommunity.firstTravelLockedKg, 'innerText');
|
||||||
|
|
||||||
expect(reference).toContain('edited reference');
|
expect(reference).toContain('edited reference');
|
||||||
expect(lockedKg).toContain(1500);
|
expect(lockedKg).toContain(1500);
|
||||||
|
|
|
@ -6,8 +6,98 @@ export default class Textfield extends Field {
|
||||||
super($element, $scope, $compile);
|
super($element, $scope, $compile);
|
||||||
this.buildInput('text');
|
this.buildInput('text');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set maxLength(value) {
|
||||||
|
this.input.maxLength = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get maxLength() {
|
||||||
|
return this.input.maxLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
set insertable(value) {
|
||||||
|
if (this._insertable === value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (this._insertable)
|
||||||
|
this.input.removeEventListener('keypress', this.keyPressListener);
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
this.keyPressListener = async e => await this.onKeyPress(e);
|
||||||
|
this.input.addEventListener('keypress', this.keyPressListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._insertable = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get insertable() {
|
||||||
|
return this._insertable;
|
||||||
|
}
|
||||||
|
|
||||||
|
async onKeyPress(e) {
|
||||||
|
if (e.key == 'Enter')
|
||||||
|
return; // If the enter key is pressed dismiss it
|
||||||
|
|
||||||
|
let maxLength = this.maxLength;
|
||||||
|
|
||||||
|
// Call the function that obtains the current cursor position
|
||||||
|
let pointerPosition = getCaretPosition(e.target);
|
||||||
|
|
||||||
|
// If the cursor position is on the last allowed character,
|
||||||
|
// prevent any keystroke from doing anything
|
||||||
|
if (pointerPosition >= maxLength) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case by any ways the input is longer than the max especified size, cut it to it.
|
||||||
|
let currentArrValue = e.target.value.slice(0, maxLength);
|
||||||
|
|
||||||
|
// Transform said input to a array with each character on one position
|
||||||
|
currentArrValue = currentArrValue.split('');
|
||||||
|
|
||||||
|
// Cut the array in 2 parts, one with everything right of the caret,
|
||||||
|
// and one with everything left to it
|
||||||
|
let rightToTheCaret = currentArrValue.slice(pointerPosition);
|
||||||
|
|
||||||
|
let leftToTheCaret = currentArrValue.slice(0, pointerPosition);
|
||||||
|
|
||||||
|
// Remove the first number on the array that was right of the caret
|
||||||
|
rightToTheCaret.shift();
|
||||||
|
|
||||||
|
// The part that was left to the caret is not modified in any way and is put back into the textField
|
||||||
|
e.target.value = leftToTheCaret.join('');
|
||||||
|
|
||||||
|
// Add one millisecond of delay to give the UI time to update,
|
||||||
|
// so that it detects the changes on the textField
|
||||||
|
await new Promise(r => setTimeout(r, 1));
|
||||||
|
|
||||||
|
// Add the values that should be right to the Caret back in the textField
|
||||||
|
e.target.value = e.target.value + rightToTheCaret.join('');
|
||||||
|
|
||||||
|
// Update the current pointer position so that it moves 1 position to the right
|
||||||
|
pointerPosition++;
|
||||||
|
e.target.setSelectionRange(pointerPosition, pointerPosition);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCaretPosition(targetElement) {
|
||||||
|
let caretPosition = 0;
|
||||||
|
|
||||||
|
if (targetElement.selectionStart || targetElement.selectionStart == 0) // Firefox Support
|
||||||
|
caretPosition = targetElement.selectionStart;
|
||||||
|
|
||||||
|
return caretPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnTextfield', {
|
ngModule.vnComponent('vnTextfield', {
|
||||||
controller: Textfield
|
controller: Textfield,
|
||||||
|
bindings: {
|
||||||
|
maxLength: '<?',
|
||||||
|
insertable: '<?'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
"image/png",
|
"image/png",
|
||||||
"image/jpeg",
|
"image/jpeg",
|
||||||
"image/jpg",
|
"image/jpg",
|
||||||
|
"image/webp",
|
||||||
"video/mp4"
|
"video/mp4"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -60,7 +61,8 @@
|
||||||
"multipart/x-zip",
|
"multipart/x-zip",
|
||||||
"image/png",
|
"image/png",
|
||||||
"image/jpeg",
|
"image/jpeg",
|
||||||
"image/jpg"
|
"image/jpg",
|
||||||
|
"image/webp"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"imageStorage": {
|
"imageStorage": {
|
||||||
|
@ -72,7 +74,8 @@
|
||||||
"allowedContentTypes": [
|
"allowedContentTypes": [
|
||||||
"image/png",
|
"image/png",
|
||||||
"image/jpeg",
|
"image/jpeg",
|
||||||
"image/jpg"
|
"image/jpg",
|
||||||
|
"image/webp"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"invoiceStorage": {
|
"invoiceStorage": {
|
||||||
|
@ -96,6 +99,7 @@
|
||||||
"image/png",
|
"image/png",
|
||||||
"image/jpeg",
|
"image/jpeg",
|
||||||
"image/jpg",
|
"image/jpg",
|
||||||
|
"image/webp",
|
||||||
"video/mp4"
|
"video/mp4"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,8 +19,8 @@ describe('Item', () => {
|
||||||
describe('set item()', () => {
|
describe('set item()', () => {
|
||||||
it('should set warehouseFk property based on itemType warehouseFk', () => {
|
it('should set warehouseFk property based on itemType warehouseFk', () => {
|
||||||
jest.spyOn(controller.$, '$applyAsync');
|
jest.spyOn(controller.$, '$applyAsync');
|
||||||
controller.item = {id: 1};
|
|
||||||
controller.vnConfig = {warehouseFk: 1};
|
controller.vnConfig = {warehouseFk: 1};
|
||||||
|
controller.item = {id: 1};
|
||||||
|
|
||||||
expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
|
expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
|
|
|
@ -211,7 +211,7 @@ module.exports = Self => {
|
||||||
LEFT JOIN province p ON p.id = a.provinceFk
|
LEFT JOIN province p ON p.id = a.provinceFk
|
||||||
LEFT JOIN warehouse w ON w.id = t.warehouseFk
|
LEFT JOIN warehouse w ON w.id = t.warehouseFk
|
||||||
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
|
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
STRAIGHT_JOIN ticketState ts ON ts.ticketFk = t.id
|
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
|
||||||
LEFT JOIN state st ON st.id = ts.stateFk
|
LEFT JOIN state st ON st.id = ts.stateFk
|
||||||
LEFT JOIN client c ON c.id = t.clientFk
|
LEFT JOIN client c ON c.id = t.clientFk
|
||||||
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
|
LEFT JOIN worker wk ON wk.id = c.salesPersonFk
|
||||||
|
|
|
@ -60,6 +60,8 @@
|
||||||
vn-one
|
vn-one
|
||||||
label="Account"
|
label="Account"
|
||||||
ng-model="$ctrl.supplier.account"
|
ng-model="$ctrl.supplier.account"
|
||||||
|
insertable="true"
|
||||||
|
max-length="10"
|
||||||
rule>
|
rule>
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
|
|
|
@ -52,7 +52,7 @@ 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
|
||||||
WHERE al.code = 'PACKED'
|
WHERE al.code = 'PACKED' OR (am.code = 'refund' AND al.code != 'delivered')
|
||||||
AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
AND DATE(t.shipped) BETWEEN DATE_ADD(?, INTERVAL -2 DAY)
|
||||||
AND util.dayEnd(?)
|
AND util.dayEnd(?)
|
||||||
AND t.refFk IS NULL
|
AND t.refFk IS NULL
|
||||||
|
|
|
@ -101,6 +101,7 @@ module.exports = async function(Self, tickets, reqArgs = {}) {
|
||||||
if (firstOrder == 1) {
|
if (firstOrder == 1) {
|
||||||
const args = {
|
const args = {
|
||||||
id: ticket.clientFk,
|
id: ticket.clientFk,
|
||||||
|
companyId: ticket.companyFk,
|
||||||
recipientId: ticket.clientFk,
|
recipientId: ticket.clientFk,
|
||||||
recipient: ticket.recipient,
|
recipient: ticket.recipient,
|
||||||
replyTo: ticket.salesPersonEmail
|
replyTo: ticket.salesPersonEmail
|
||||||
|
@ -109,7 +110,7 @@ module.exports = async function(Self, tickets, reqArgs = {}) {
|
||||||
const email = new Email('incoterms-authorization', args);
|
const email = new Email('incoterms-authorization', args);
|
||||||
await email.send();
|
await email.send();
|
||||||
|
|
||||||
const sample = await Self.rawSql(
|
const [sample] = await Self.rawSql(
|
||||||
`SELECT id
|
`SELECT id
|
||||||
FROM sample
|
FROM sample
|
||||||
WHERE code = 'incoterms-authorization'
|
WHERE code = 'incoterms-authorization'
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.25.0",
|
||||||
|
"bcrypt": "^5.0.1",
|
||||||
"bmp-js": "^0.1.0",
|
"bmp-js": "^0.1.0",
|
||||||
"compression": "^1.7.3",
|
"compression": "^1.7.3",
|
||||||
"fs-extra": "^5.0.0",
|
"fs-extra": "^5.0.0",
|
||||||
|
@ -40,7 +41,7 @@
|
||||||
"puppeteer": "^18.0.5",
|
"puppeteer": "^18.0.5",
|
||||||
"read-chunk": "^3.2.0",
|
"read-chunk": "^3.2.0",
|
||||||
"require-yaml": "0.0.1",
|
"require-yaml": "0.0.1",
|
||||||
"sharp": "^0.27.1",
|
"sharp": "^0.31.0",
|
||||||
"smbhash": "0.0.1",
|
"smbhash": "0.0.1",
|
||||||
"strong-error-handler": "^2.3.2",
|
"strong-error-handler": "^2.3.2",
|
||||||
"uuid": "^3.3.3",
|
"uuid": "^3.3.3",
|
||||||
|
|
Loading…
Reference in New Issue