Send invoice to specific email address from descriptor option #739

Merged
carlosjr merged 4 commits from 3010-send_invoice into dev 2021-09-24 07:54:01 +00:00
38 changed files with 148 additions and 47457 deletions
Showing only changes of commit 7369f4aa54 - Show all commits

8
Jenkinsfile vendored
View File

@ -40,7 +40,7 @@ pipeline {
NODE_ENV = "" NODE_ENV = ""
} }
steps { steps {
nodejs('node-v12') { nodejs('node-v14') {
sh 'npm install --no-audit --prefer-offline' sh 'npm install --no-audit --prefer-offline'
sh 'gulp install --ci' sh 'gulp install --ci'
} }
@ -57,14 +57,14 @@ pipeline {
parallel { parallel {
stage('Frontend') { stage('Frontend') {
steps { steps {
nodejs('node-v12') { nodejs('node-v14') {
sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=2' sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=2'
} }
} }
} }
// stage('Backend') { // stage('Backend') {
// steps { // steps {
// nodejs('node-v12') { // nodejs('node-v14') {
// sh 'gulp launchBackTest --ci' // sh 'gulp launchBackTest --ci'
// } // }
// } // }
@ -80,7 +80,7 @@ pipeline {
CREDENTIALS = credentials('docker-registry') CREDENTIALS = credentials('docker-registry')
} }
steps { steps {
nodejs('node-v12') { nodejs('node-v14') {
sh 'gulp build' sh 'gulp build'
} }

View File

@ -0,0 +1 @@
DROP TRIGGER vn.supplierAccount_AfterInsert;

View File

View File

@ -219,11 +219,12 @@ UPDATE `vn`.`agencyMode` SET `code` = 'refund' WHERE `id` = 23;
INSERT INTO `vn`.`payMethod`(`id`,`code`, `name`, `graceDays`, `outstandingDebt`, `ibanRequired`) INSERT INTO `vn`.`payMethod`(`id`,`code`, `name`, `graceDays`, `outstandingDebt`, `ibanRequired`)
VALUES VALUES
(1, NULL, 'PayMethod one', 0, 001, 0), (1, NULL, 'PayMethod one', 0, 001, 0),
(2, NULL, 'PayMethod two', 10, 001, 0), (2, NULL, 'PayMethod two', 10, 001, 0),
(3, 'compensation', 'PayMethod three', 0, 001, 0), (3, 'compensation', 'PayMethod three', 0, 001, 0),
(4, NULL, 'PayMethod with IBAN', 0, 001, 1), (4, NULL, 'PayMethod with IBAN', 0, 001, 1),
(5, NULL, 'PayMethod five', 10, 001, 0); (5, NULL, 'PayMethod five', 10, 001, 0),
(8,'wireTransfer', 'WireTransfer', 5, 001, 1);
INSERT INTO `vn`.`payDem`(`id`, `payDem`) INSERT INTO `vn`.`payDem`(`id`, `payDem`)
VALUES VALUES

308
front/package-lock.json generated
View File

@ -1,308 +0,0 @@
{
"name": "salix-front",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "salix-front",
"version": "1.0.0",
"license": "GPL-3.0",
"dependencies": {
"@uirouter/angularjs": "^1.0.20",
"angular": "^1.7.5",
"angular-animate": "^1.7.8",
"angular-moment": "^1.3.0",
"angular-translate": "^2.18.1",
"angular-translate-loader-partial": "^2.18.1",
"croppie": "^2.6.5",
"js-yaml": "^3.13.1",
"mg-crud": "^1.1.2",
"oclazyload": "^0.6.3",
"require-yaml": "0.0.1",
"validator": "^6.3.0"
}
},
"node_modules/@uirouter/angularjs": {
"version": "1.0.29",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
"dependencies": {
"@uirouter/core": "6.0.7"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/@uirouter/core": {
"version": "6.0.7",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/angular": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
},
"node_modules/angular-animate": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
},
"node_modules/angular-moment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
"dependencies": {
"moment": ">=2.8.0 <3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/angular-translate": {
"version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
"integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==",
"dependencies": {
"angular": "^1.8.0"
},
"engines": {
"node": "*"
}
},
"node_modules/angular-translate-loader-partial": {
"version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz",
"integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==",
"dependencies": {
"angular-translate": "~2.18.4"
}
},
"node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dependencies": {
"sprintf-js": "~1.0.2"
}
},
"node_modules/croppie": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz",
"integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ=="
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/js-yaml": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"dependencies": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/mg-crud": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
"integrity": "sha1-p6AWGzWSPK7/8ZpIBpS2V1vDggw=",
"dependencies": {
"angular": "^1.6.1"
}
},
"node_modules/moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"engines": {
"node": "*"
}
},
"node_modules/oclazyload": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
"integrity": "sha1-Kjirv/QJDAihEBZxkZRbWfLoJ5w="
},
"node_modules/require-yaml": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
"dependencies": {
"js-yaml": "^4.0.0"
}
},
"node_modules/require-yaml/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/require-yaml/node_modules/js-yaml": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"node_modules/validator": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
"integrity": "sha1-R84j7Y1Ord+p1LjvAHG2zxB418g=",
"engines": {
"node": ">= 0.10"
}
}
},
"dependencies": {
"@uirouter/angularjs": {
"version": "1.0.29",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
"requires": {
"@uirouter/core": "6.0.7"
}
},
"@uirouter/core": {
"version": "6.0.7",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w=="
},
"angular": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
},
"angular-animate": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
},
"angular-moment": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
"requires": {
"moment": ">=2.8.0 <3.0.0"
}
},
"angular-translate": {
"version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
"integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==",
"requires": {
"angular": "^1.8.0"
}
},
"angular-translate-loader-partial": {
"version": "2.18.4",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz",
"integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==",
"requires": {
"angular-translate": "~2.18.4"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"requires": {
"sprintf-js": "~1.0.2"
}
},
"croppie": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz",
"integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ=="
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"js-yaml": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"mg-crud": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
"integrity": "sha1-p6AWGzWSPK7/8ZpIBpS2V1vDggw=",
"requires": {
"angular": "^1.6.1"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"oclazyload": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
"integrity": "sha1-Kjirv/QJDAihEBZxkZRbWfLoJ5w="
},
"require-yaml": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
"integrity": "sha1-LhsY2RPDuqcqWk03O28Tjd0sMr0=",
"requires": {
"js-yaml": "^4.0.0"
},
"dependencies": {
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"js-yaml": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
"requires": {
"argparse": "^2.0.1"
}
}
}
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"validator": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
"integrity": "sha1-R84j7Y1Ord+p1LjvAHG2zxB418g="
}
}
}

View File

@ -11,6 +11,7 @@ class Controller extends Dialog {
throw new Error(`The country can't be empty`); throw new Error(`The country can't be empty`);
return this.$http.post(`bankEntities`, this.data) return this.$http.post(`bankEntities`, this.data)
.then(res => this.data.id = res.data.id)
.then(() => super.responseHandler(response)) .then(() => super.responseHandler(response))
.then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); .then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
} }

View File

@ -27,12 +27,13 @@ describe('Salix Component vnNewBankEntity', () => {
countryFk: 1 countryFk: 1
}; };
$httpBackend.expectPOST('bankEntities', controller.data).respond(200); $httpBackend.expectPOST('bankEntities', controller.data).respond({id: 1});
controller.responseHandler('accept'); controller.responseHandler('accept');
$httpBackend.flush(); $httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!'); expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
expect(controller.data.id).toEqual(1);
}); });
}); });
}); });

View File

@ -8,7 +8,7 @@
<vn-tr> <vn-tr>
<vn-th field="creationDate">Date</vn-th> <vn-th field="creationDate">Date</vn-th>
<vn-th field="userFk" class="expendable" shrink>Author</vn-th> <vn-th field="userFk" class="expendable" shrink>Author</vn-th>
<vn-th field="changedModel" class="expendable" shrink>Model</vn-th> <vn-th field="changedModel" class="expendable">Model</vn-th>
<vn-th field="action" class="expendable" shrink>Action</vn-th> <vn-th field="action" class="expendable" shrink>Action</vn-th>
<vn-th field="changedModelValue" class="expendable">Name</vn-th> <vn-th field="changedModelValue" class="expendable">Name</vn-th>
<vn-th expand>Before</vn-th> <vn-th expand>Before</vn-th>
@ -17,7 +17,7 @@
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="log in $ctrl.logs"> <vn-tr ng-repeat="log in $ctrl.logs">
<vn-td expand> <vn-td shrink-datetime>
{{::log.creationDate | date:'dd/MM/yyyy HH:mm'}} {{::log.creationDate | date:'dd/MM/yyyy HH:mm'}}
<div class="changes"> <div class="changes">
<div> <div>

View File

@ -12,6 +12,9 @@
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
"code": {
"type": "string"
},
"name": { "name": {
"type": "string", "type": "string",
"required": true "required": true

View File

@ -47,7 +47,7 @@
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th expand>Date</vn-th> <vn-th expand>Date</vn-th>
<vn-th expand>Creation date</vn-th> <vn-th>Creation date</vn-th>
<vn-th>Employee</vn-th> <vn-th>Employee</vn-th>
<vn-th>Reference</vn-th> <vn-th>Reference</vn-th>
<vn-th number>Bank</vn-th> <vn-th number>Bank</vn-th>
@ -65,7 +65,7 @@
{{::balance.payed | date:'dd/MM/yyyy'}} {{::balance.payed | date:'dd/MM/yyyy'}}
</span> </span>
</vn-td> </vn-td>
<vn-td expand> <vn-td shrink-datetime>
<span title="{{::balance.created | date:'dd/MM/yyyy HH:mm'}}"> <span title="{{::balance.created | date:'dd/MM/yyyy HH:mm'}}">
{{::balance.created | date:'dd/MM/yyyy HH:mm'}} {{::balance.created | date:'dd/MM/yyyy HH:mm'}}
</span> </span>

View File

@ -22,7 +22,7 @@
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="credit in credits track by credit.id"> <vn-tr ng-repeat="credit in credits track by credit.id">
<vn-td>{{::credit.created | date:'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td shrink-datetime>{{::credit.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td> <vn-td>
<span <span
ng-click="workerDescriptor.show($event, credit.worker.userFk)" ng-click="workerDescriptor.show($event, credit.worker.userFk)"

View File

@ -22,8 +22,8 @@
<vn-th expand>Description</vn-th> <vn-th expand>Description</vn-th>
<vn-th field="hasFile" shrink>Original</vn-th> <vn-th field="hasFile" shrink>Original</vn-th>
<vn-th shrink>File</vn-th> <vn-th shrink>File</vn-th>
<vn-th shrink>Employee</vn-th> <vn-th>Employee</vn-th>
<vn-th field="created" expand>Created</vn-th> <vn-th field="created">Created</vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
@ -70,7 +70,7 @@
ng-click="workerDescriptor.show($event, document.dms.workerFk)"> ng-click="workerDescriptor.show($event, document.dms.workerFk)">
{{::document.dms.worker.user.name | dashIfEmpty}} {{::document.dms.worker.user.name | dashIfEmpty}}
</span></vn-td> </span></vn-td>
<vn-td expand> <vn-td shrink-datetime>
{{::document.dms.created | date:'dd/MM/yyyy HH:mm'}} {{::document.dms.created | date:'dd/MM/yyyy HH:mm'}}
</vn-td> </vn-td>
<vn-td shrink> <vn-td shrink>

View File

@ -36,7 +36,7 @@
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="greuge in greuges"> <vn-tr ng-repeat="greuge in greuges">
<vn-td expand>{{::greuge.shipped | date:'dd/MM/yyyy HH:mm' }}</vn-td> <vn-td shrink-datetime>{{::greuge.shipped | date:'dd/MM/yyyy HH:mm' }}</vn-td>
<vn-td> <vn-td>
<span title="{{::greuge.description}}">{{::greuge.description}}</span> <span title="{{::greuge.description}}">{{::greuge.description}}</span>
</vn-td> </vn-td>

View File

@ -18,8 +18,8 @@
<vn-th field="id" number>Id</vn-th> <vn-th field="id" number>Id</vn-th>
<vn-th field="companyFk">Company</vn-th> <vn-th field="companyFk">Company</vn-th>
<vn-th field="mandateTypeFk">Type</vn-th> <vn-th field="mandateTypeFk">Type</vn-th>
<vn-th field="created" expand>Register date</vn-th> <vn-th field="created">Register date</vn-th>
<vn-th field="finished" expand>End date</vn-th> <vn-th field="finished">End date</vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
@ -27,8 +27,8 @@
<vn-td number>{{::mandate.id}}</vn-td> <vn-td number>{{::mandate.id}}</vn-td>
<vn-td>{{::mandate.company.code}}</vn-td> <vn-td>{{::mandate.company.code}}</vn-td>
<vn-td>{{::mandate.mandateType.name}}</vn-td> <vn-td>{{::mandate.mandateType.name}}</vn-td>
<vn-td expand>{{::mandate.created | date:'dd/MM/yyyy HH:mm' | dashIfEmpty}}</vn-td> <vn-td shrink-datetime>{{::mandate.created | date:'dd/MM/yyyy HH:mm' | dashIfEmpty}}</vn-td>
<vn-td expand>{{::mandate.finished | date:'dd/MM/yyyy HH:mm' | dashIfEmpty}}</vn-td> <vn-td shrink-datetime>{{::mandate.finished | date:'dd/MM/yyyy HH:mm' | dashIfEmpty}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>
</vn-table> </vn-table>

View File

@ -23,8 +23,8 @@
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="sample in samples"> <vn-tr ng-repeat="sample in samples">
<vn-td>{{::sample.created | date:'dd/MM/yyyy HH:mm' }}</vn-td> <vn-td shrink-datetime>{{::sample.created | date:'dd/MM/yyyy HH:mm' }}</vn-td>
<vn-td <vn-td expand
title="{{::sample.type.description}}"> title="{{::sample.type.description}}">
{{::sample.type.description}} {{::sample.type.description}}
</vn-td> </vn-td>

View File

@ -293,7 +293,7 @@
<vn-th field="id" number>Id</vn-th> <vn-th field="id" number>Id</vn-th>
<vn-th field="nickname" expand>Nickname</vn-th> <vn-th field="nickname" expand>Nickname</vn-th>
<vn-th field="agencyModeFk" expand>Agency</vn-th> <vn-th field="agencyModeFk" expand>Agency</vn-th>
<vn-th field="routeFk" shrink>Route</vn-th> <vn-th field="routeFk" expand>Route</vn-th>
<vn-th field="packages" shrink>Packages</vn-th> <vn-th field="packages" shrink>Packages</vn-th>
<vn-th field="shipped" shrink-date>Date</vn-th> <vn-th field="shipped" shrink-date>Date</vn-th>
<vn-th field="stateFk">State</vn-th> <vn-th field="stateFk">State</vn-th>

View File

@ -36,7 +36,7 @@
</vn-icon> </vn-icon>
</vn-td> </vn-td>
<vn-td number>{{::transaction.id}}</vn-td> <vn-td number>{{::transaction.id}}</vn-td>
<vn-td expand>{{::transaction.created | date:'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td>{{::transaction.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td number>{{::transaction.amount | currency: 'EUR':2}}</vn-td> <vn-td number>{{::transaction.amount | currency: 'EUR':2}}</vn-td>
<vn-td shrink> <vn-td shrink>
<vn-icon-button <vn-icon-button

View File

@ -10,13 +10,13 @@ describe('InvoiceIn', () => {
beforeEach(ngModule('invoiceIn')); beforeEach(ngModule('invoiceIn'));
beforeEach(inject(($componentController, _$httpBackend_, $rootScope, _vnApp_) => { beforeEach(inject(($componentController, $rootScope, _vnApp_) => {
vnApp = _vnApp_; vnApp = _vnApp_;
jest.spyOn(vnApp, 'showError'); jest.spyOn(vnApp, 'showError');
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.model = crudModel; $scope.model = crudModel;
$scope.watcher = watcher; $scope.watcher = watcher;
const $element = angular.element('<vn-invoice-in-tax></vn-invoice-in-tax>'); const $element = angular.element('<vn-invoice-in-tax></vn-invoice-in-tax>');
controller = $componentController('vnInvoiceInTax', {$element, $scope}); controller = $componentController('vnInvoiceInTax', {$element, $scope});
controller.invoiceIn = {id: 1}; controller.invoiceIn = {id: 1};

View File

@ -25,7 +25,7 @@
<vn-tr> <vn-tr>
<vn-th vn-tooltip="Ignored" center>Ig</vn-th> <vn-th vn-tooltip="Ignored" center>Ig</vn-th>
<vn-th field="warehouseFk">Warehouse</vn-th> <vn-th field="warehouseFk">Warehouse</vn-th>
<vn-th field="landed" expand>Landed</vn-th> <vn-th field="landed">Landed</vn-th>
<vn-th number>Entry</vn-th> <vn-th number>Entry</vn-th>
<vn-th number vn-tooltip="Price Per Unit">P.P.U</vn-th> <vn-th number vn-tooltip="Price Per Unit">P.P.U</vn-th>
<vn-th number vn-tooltip="Price Per Package">P.P.P</vn-th> <vn-th number vn-tooltip="Price Per Package">P.P.P</vn-th>
@ -49,7 +49,7 @@
</vn-check> </vn-check>
</vn-td> </vn-td>
<vn-td title="{{::entry.warehouse| dashIfEmpty}}">{{::entry.warehouse| dashIfEmpty}}</vn-td> <vn-td title="{{::entry.warehouse| dashIfEmpty}}">{{::entry.warehouse| dashIfEmpty}}</vn-td>
<vn-td expand>{{::entry.landed | date:'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td shrink-datetime>{{::entry.landed | date:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td shrink> <vn-td shrink>
<span <span
vn-click-stop="entryDescriptor.show($event, entry.entryFk)" vn-click-stop="entryDescriptor.show($event, entry.entryFk)"

View File

@ -1,4 +1,5 @@
const validateIban = require('vn-loopback/util/validateIban'); const validateIban = require('vn-loopback/util/validateIban');
const LoopBackContext = require('loopback-context');
module.exports = Self => { module.exports = Self => {
Self.validateAsync('iban', ibanValidation, { Self.validateAsync('iban', ibanValidation, {
@ -19,4 +20,16 @@ module.exports = Self => {
err(); err();
done(); done();
} }
Self.observe('after save', async ctx => {
const loopBackContext = LoopBackContext.getCurrentContext();
const models = Self.app.models;
const user = await models.user.findById(loopBackContext.active.accessToken.userId);
const bankEntity = await models.BankEntity.findById(ctx.instance.bankEntityFk);
await Self.app.models.Mail.create({
sender: 'finanzas@verdnatura.es',
subject: 'Añadida cuenta bancaria al proveedor' + ctx.instance.supplierFk,
body: user.username + ' ha añadido: ' +
ctx.instance.iban + ', entidad: ' + bankEntity.name + ', bic: ' + bankEntity.bic
});
});
}; };

View File

@ -15,31 +15,40 @@
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-lg"> <form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-lg">
<vn-card class="vn-pa-lg"> <vn-card class="vn-pa-lg">
<vn-horizontal ng-repeat="supplierAccount in $ctrl.supplierAccounts"> <vn-horizontal ng-repeat="supplierAccount in $ctrl.supplierAccounts">
<vn-textfield vn-three <vn-textfield
ng-show="supplierAccount.iban || supplierAccount.iban == undefined" ng-show="supplierAccount.iban || supplierAccount.iban == undefined"
label="Iban" label="Iban"
ng-model="supplierAccount.iban" ng-model="supplierAccount.iban"
rule> on-change="supplierAccount.bankEntityFk = supplierAccount.iban.slice(4,8)"
rule>
</vn-textfield> </vn-textfield>
<vn-autocomplete vn-three <vn-autocomplete
label="Bank entity" label="Bank entity"
ng-model="supplierAccount.bankEntityFk" ng-model="supplierAccount.bankEntityFk"
url="BankEntities" url="BankEntities"
show-field="name" show-field="name"
rule> rule>
<append>
<vn-icon-button
icon="add_circle"
vn-tooltip="New bank entity"
ng-click="$ctrl.showBankEntity($event, $index)"
tabindex="-1">
</vn-icon-button>
</append>
</vn-autocomplete> </vn-autocomplete>
<append> <vn-textfield
<vn-icon-button
vn-auto
icon="add_circle"
vn-click-stop="bankEntity.show({index: $index})"
vn-tooltip="New bank entity">
</vn-icon-button>
</append>
<vn-textfield vn-three
label="Beneficiary" label="Beneficiary"
ng-model="supplierAccount.beneficiary" ng-model="supplierAccount.beneficiary"
info="Beneficiary information"> info="Beneficiary information">
<append>
<vn-icon-button
vn-auto
icon="add_circle"
vn-click-stop="bankEntity.show({index: $index})"
vn-tooltip="New bank entity">
</vn-icon-button>
</append>
</vn-textfield> </vn-textfield>
<vn-none> <vn-none>
<vn-icon-button <vn-icon-button
@ -72,3 +81,10 @@
vn-id="bankEntity" vn-id="bankEntity"
on-accept="$ctrl.onAccept($data)"> on-accept="$ctrl.onAccept($data)">
</vn-new-bank-entity> </vn-new-bank-entity>
<vn-confirm
class="edit"
vn-id="payMethodToTransfer"
on-accept="$ctrl.setWireTransfer()"
message="Do you want to change the pay method to wire transfer?">
</vn-confirm>

View File

@ -10,6 +10,14 @@ class Controller extends Section {
fields: ['countryFk', 'id', 'name', 'bic'] fields: ['countryFk', 'id', 'name', 'bic']
} }
}; };
const filter = {
where: {code: 'wireTransfer'}
};
this.$http.get(`payMethods/findOne`, {filter})
.then(res => {
this.wireTransferFk = res.data.id;
});
} }
add() { add() {
@ -26,11 +34,16 @@ class Controller extends Section {
onSubmit() { onSubmit() {
this.$.watcher.check(); this.$.watcher.check();
this.$.model.save().then(() => { return this.$.model.save()
this.$.watcher.notifySaved(); .then(() => {
this.$.watcher.updateOriginalData(); this.$.watcher.notifySaved();
this.card.reload(); this.$.watcher.updateOriginalData();
}); return this.card.reload();
})
.then(() => {
if (this.supplier.payMethodFk != this.wireTransferFk)
this.$.payMethodToTransfer.show();
});
} }
} }

View File

@ -1,17 +1,22 @@
import './index.js'; import './index.js';
import watcher from 'core/mocks/watcher';
import crudModel from 'core/mocks/crud-model';
describe('Supplier Component vnSupplierAccount', () => { describe('Supplier Component vnSupplierAccount', () => {
let $scope; let $scope;
let $element;
let controller; let controller;
beforeEach(ngModule('supplier')); beforeEach(ngModule('supplier'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => { beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$scope = $rootScope.$new(); $scope = $rootScope.$new();
$scope.model = crudModel;
$scope.watcher = watcher;
$scope.bankEntity = { $scope.bankEntity = {
open: () => {} open: () => {}
}; };
$element = angular.element('<vn-supplier-accounts></supplier-accounts>');
const $element = angular.element('<vn-supplier-account></vn-supplier-account>');
controller = $componentController('vnSupplierAccount', {$element, $scope}); controller = $componentController('vnSupplierAccount', {$element, $scope});
controller.supplierAccount = { controller.supplierAccount = {
supplierFk: 442, supplierFk: 442,
@ -35,5 +40,31 @@ describe('Supplier Component vnSupplierAccount', () => {
expect(targetAccount.bankEntityFk).toEqual(data.id); expect(targetAccount.bankEntityFk).toEqual(data.id);
}); });
}); });
describe('onSubmit()', () => {
it(`should reload the card`, done => {
controller.card = {reload: () => {}};
controller.$.payMethodToTransfer = {show: () => {}};
jest.spyOn(controller.$.payMethodToTransfer, 'show');
jest.spyOn(controller.$.model, 'save').mockReturnValue(new Promise(resolve => {
return resolve({
id: 1234
});
}));
jest.spyOn(controller.card, 'reload').mockReturnValue(new Promise(resolve => {
return resolve({
id: 1234
});
}));
controller.wireTransferFk = 'a';
controller.supplier = {payMethodFk: 'b'};
controller.onSubmit().then(() => {
expect(controller.card.reload).toHaveBeenCalledWith();
expect(controller.$.payMethodToTransfer.show).toHaveBeenCalled();
done();
}).catch(done.fail);
});
});
}); });

View File

@ -3,3 +3,4 @@ swift: Swift BIC
Add account: Añadir cuenta Add account: Añadir cuenta
Beneficiary: Beneficiario Beneficiary: Beneficiario
Beneficiary information: Nombre del titular de la cuenta bancaria en caso de ser diferente del proveedor Beneficiary information: Nombre del titular de la cuenta bancaria en caso de ser diferente del proveedor
Do you want to change the pay method to wire transfer?: ¿Quieres modificar la forma de pago a transferencia?

View File

@ -37,7 +37,7 @@ class Controller extends ModuleCard {
} }
] ]
}; };
this.$http.get(`Suppliers/${this.$params.id}`, {filter}) return this.$http.get(`Suppliers/${this.$params.id}`, {filter})
.then(response => this.supplier = response.data); .then(response => this.supplier = response.data);
} }
} }

View File

@ -21,7 +21,7 @@
<vn-th field="hasFile" shrink>Original</vn-th> <vn-th field="hasFile" shrink>Original</vn-th>
<vn-th shrink>File</vn-th> <vn-th shrink>File</vn-th>
<vn-th shrink>Employee</vn-th> <vn-th shrink>Employee</vn-th>
<vn-th field="created" expand>Created</vn-th> <vn-th field="created">Created</vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
@ -69,7 +69,7 @@
{{::document.dms.worker.user.name | dashIfEmpty}} {{::document.dms.worker.user.name | dashIfEmpty}}
</span> </span>
</vn-td> </vn-td>
<vn-td expand> <vn-td shrink-datetime>
{{::document.dms.created | date:'dd/MM/yyyy HH:mm'}} {{::document.dms.created | date:'dd/MM/yyyy HH:mm'}}
</vn-td> </vn-td>
<vn-td shrink> <vn-td shrink>

View File

@ -28,7 +28,7 @@
{{::tracking.worker.user.name || 'System' | translate}} {{::tracking.worker.user.name || 'System' | translate}}
</span> </span>
</vn-td> </vn-td>
<vn-td>{{::tracking.created | date:'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td shrink-datetime>{{::tracking.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>
</vn-table> </vn-table>

View File

@ -59,7 +59,6 @@ module.exports = Self => {
travel.agencyFk travel.agencyFk
] ]
); );
stmts.push(stmt); stmts.push(stmt);
const newTravelIndex = stmts.push('SELECT @vTravelFk AS id') - 1; const newTravelIndex = stmts.push('SELECT @vTravelFk AS id') - 1;

View File

@ -20,7 +20,7 @@
<vn-th expand>Description</vn-th> <vn-th expand>Description</vn-th>
<vn-th field="hasFile" shrink>Original</vn-th> <vn-th field="hasFile" shrink>Original</vn-th>
<vn-th shrink>File</vn-th> <vn-th shrink>File</vn-th>
<vn-th field="created" expand>Created</vn-th> <vn-th field="created">Created</vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
@ -57,7 +57,7 @@
{{::document.file}} {{::document.file}}
</span> </span>
</vn-td> </vn-td>
<vn-td expand> <vn-td shrink-datetime>
{{::document.created | date:'dd/MM/yyyy HH:mm'}} {{::document.created | date:'dd/MM/yyyy HH:mm'}}
</vn-td> </vn-td>
<vn-td shrink> <vn-td shrink>

43409
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,6 @@
"strong-error-handler": "^2.3.2", "strong-error-handler": "^2.3.2",
"uuid": "^3.3.3", "uuid": "^3.3.3",
"vn-loopback": "file:./loopback", "vn-loopback": "file:./loopback",
"vn-mysql": "^1.0.3",
"xml2js": "^0.4.23" "xml2js": "^0.4.23"
}, },
"devDependencies": { "devDependencies": {

View File

@ -25,7 +25,7 @@ module.exports = {
throw err; throw err;
}).finally(async() => { }).finally(async() => {
await db.rawSql(` await db.rawSql(`
INSERT INTO vn.mail (sender, replyTo, sent, subject, body, status) INSERT INTO vn.mail (receiver, replyTo, sent, subject, body, status)
VALUES (?, ?, 1, ?, ?, ?)`, [ VALUES (?, ?, 1, ?, ?, ?)`, [
options.to, options.to,
options.replyTo, options.replyTo,

3672
print/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",
"intl": "^1.2.5", "intl": "^1.2.5",
"js-yaml": "^3.13.1", "js-yaml": "^3.13.1",
"jsonexport": "^3.2.0",
"juice": "^5.2.0", "juice": "^5.2.0",
"mysql2": "^1.7.0", "mysql2": "^1.7.0",
"nodemailer": "^4.7.0", "nodemailer": "^4.7.0",

View File

@ -29,7 +29,7 @@ services:
amount: Amount amount: Amount
tfoot: tfoot:
subtotal: Subtotal subtotal: Subtotal
warning: Deposit packaging will be invoiced if they have not been returned after 30 days of their delivery warning: Deposit packaging will be invoiced if they have not been returned after 30 days of their delivery.
packagings: packagings:
title: Buckets and packaging title: Buckets and packaging
theader: theader:

View File

@ -29,7 +29,7 @@ services:
amount: Importe amount: Importe
tfoot: tfoot:
subtotal: Subtotal subtotal: Subtotal
warning: Los embalajes en depósito se facturarán si no han sido devueltos pasados 30 dias de su entrega warning: Los embalajes en depósito se facturarán si no han sido devueltos pasados 30 dias de su entrega.
packagings: packagings:
title: Cubos y embalajes title: Cubos y embalajes
theader: theader:

View File

@ -29,7 +29,7 @@ services:
amount: Montant amount: Montant
tfoot: tfoot:
subtotal: Total partiel subtotal: Total partiel
warning: Les emballages de consigne seront facturés s'ils n'ont pas été retournés après 30 jours de leur livraison warning: Les emballages de consigne seront facturés s'ils n'ont pas été retournés après 30 jours de leur livraison.
packagings: packagings:
title: Bacs et emballages title: Bacs et emballages
theader: theader:

View File

@ -29,7 +29,7 @@ services:
amount: Quantia amount: Quantia
tfoot: tfoot:
subtotal: Subtotal subtotal: Subtotal
warning: Os pacotes do armazém serão cobrados se não forem devolvidos 30 dias após a entrega warning: As embalagens em depósito serão facturadas e cobradas se não são devolvidas 30 dias após a entrega.
packagings: packagings:
title: Baldes e Embalagens title: Baldes e Embalagens
theader: theader: