Merge branch 'dev' into 3571-refactor-e2e
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Alexandre Riera 2023-01-12 06:55:09 +00:00
commit 7bdc04cd13
32 changed files with 540 additions and 210 deletions

View File

@ -9,9 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- [General](Inicio) Permite recuperar la contraseña - [General](Inicio) Permite recuperar la contraseña
- [Artículo](Datos Básicos) Añadido campo Unidades/Caja
### Changed ### Changed
- [Tickets](Líneas preparadas) Actualizada sección para que sea más visual
### Fixed
- [General] Al utilizar el traductor de Google se descuadraban los iconos
### Removed ### Removed
- [Tickets](Control clientes) Eliminada sección - [Tickets](Control clientes) Eliminada sección

View File

@ -0,0 +1,2 @@
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`)
VALUES ('ItemShelvingSale','*','*','ALLOW','employee');

View File

@ -0,0 +1,4 @@
SET FOREIGN_KEY_CHECKS = 0;
ALTER TABLE `vn`.`report` MODIFY COLUMN id tinyint(3) unsigned NOT NULL AUTO_INCREMENT;
ALTER TABLE `vn`.`printer` MODIFY COLUMN id tinyint(3) unsigned NOT NULL AUTO_INCREMENT;
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -1143,10 +1143,10 @@ INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `visible`, `grouping`,
INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`) INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`)
VALUES VALUES
('1', '1', '1', '', '1106'), ('1', '1', '1', util.VN_CURDATE(), '1106'),
('2', '2', '5', '', '1106'), ('2', '2', '5', util.VN_CURDATE(), '1106'),
('1', '7', '1', '', '1106'), ('1', '7', '1', util.VN_CURDATE(), '1106'),
('2', '8', '5', '', '1106'); ('2', '8', '5', util.VN_CURDATE(), '1106');
INSERT INTO `vncontrol`.`accion`(`accion_id`, `accion`) INSERT INTO `vncontrol`.`accion`(`accion_id`, `accion`)
VALUES VALUES
@ -1779,7 +1779,7 @@ INSERT INTO `vn`.`claimDestination`(`id`, `description`, `addressFk`)
INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`) INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`)
VALUES VALUES
(1, 1, 1, 21, 1, 1, 2, 5), (1, 1, 1, 21, 1, 1, 2, 5),
(2, 1, 1, 21, 7, 2, 2, 5), (2, 1, 2, 21, 7, 2, 2, 5),
(3, 2, 7, 21, 9, 3, 2, 5), (3, 2, 7, 21, 9, 3, 2, 5),
(4, 3, 7, 21, 15, 8, 2, 5), (4, 3, 7, 21, 15, 8, 2, 5),
(5, 4, 7, 21, 7, 8, 2, 5); (5, 4, 7, 21, 7, 8, 2, 5);

View File

@ -463,6 +463,7 @@ export default {
generic: 'vn-autocomplete[ng-model="$ctrl.item.genericFk"]', generic: 'vn-autocomplete[ng-model="$ctrl.item.genericFk"]',
isFragile: 'vn-check[ng-model="$ctrl.item.isFragile"]', isFragile: 'vn-check[ng-model="$ctrl.item.isFragile"]',
longName: 'vn-textfield[ng-model="$ctrl.item.longName"]', longName: 'vn-textfield[ng-model="$ctrl.item.longName"]',
packingOut: 'vn-input-number[ng-model="$ctrl.item.packingOut"]',
isActiveCheckbox: 'vn-check[label="Active"]', isActiveCheckbox: 'vn-check[label="Active"]',
priceInKgCheckbox: 'vn-check[label="Price in kg"]', priceInKgCheckbox: 'vn-check[label="Price in kg"]',
newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button', newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button',

View File

@ -35,6 +35,7 @@ describe('Item Edit basic data path', () => {
await page.waitToClick(selectors.itemBasicData.isActiveCheckbox); await page.waitToClick(selectors.itemBasicData.isActiveCheckbox);
await page.waitToClick(selectors.itemBasicData.priceInKgCheckbox); await page.waitToClick(selectors.itemBasicData.priceInKgCheckbox);
await page.waitToClick(selectors.itemBasicData.isFragile); await page.waitToClick(selectors.itemBasicData.isFragile);
await page.write(selectors.itemBasicData.packingOut, '5');
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton); await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
const message = await page.waitForSnackbar(); const message = await page.waitForSnackbar();
@ -128,4 +129,11 @@ describe('Item Edit basic data path', () => {
expect(result).toBe('checked'); expect(result).toBe('checked');
}); });
it(`should confirm the item packingOut was edited`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBasicData.packingOut, 'value');
expect(result).toEqual('5');
});
}); });

View File

@ -26,7 +26,7 @@ class Icon {
Icon.$inject = ['$attrs']; Icon.$inject = ['$attrs'];
ngModule.vnComponent('vnIcon', { ngModule.vnComponent('vnIcon', {
template: '<i class="{{::$ctrl.iconClass}} unselectable">{{::$ctrl.iconContent}}</i>', template: '<i class="{{::$ctrl.iconClass}} unselectable notranslate">{{::$ctrl.iconContent}}</i>',
controller: Icon, controller: Icon,
bindings: { bindings: {
icon: '@' icon: '@'

View File

@ -29,7 +29,7 @@ vn-table {
& > tbody { & > tbody {
display: table-row-group; display: table-row-group;
} }
& > vn-tfoot, & > vn-tfoot,
& > .vn-tfoot, & > .vn-tfoot,
& > tfoot { & > tfoot {
border-top: $border; border-top: $border;
@ -42,7 +42,7 @@ vn-table {
height: 48px; height: 48px;
} }
vn-thead, .vn-thead, vn-thead, .vn-thead,
vn-tbody, .vn-tbody, vn-tbody, .vn-tbody,
vn-tfoot, .vn-tfoot, vn-tfoot, .vn-tfoot,
thead, tbody, tfoot { thead, tbody, tfoot {
& > * { & > * {
@ -153,6 +153,18 @@ vn-table {
background-color: $color-font-bg-dark; background-color: $color-font-bg-dark;
color: $color-font-bg; color: $color-font-bg;
} }
&.dark-notice {
background-color: $color-notice;
color: $color-font-bg;
}
&.yellow {
background-color: $color-yellow;
color: $color-font-bg;
}
&.pink {
background-color: $color-pink;
color: $color-font-bg;
}
} }
vn-icon-menu { vn-icon-menu {
display: inline-block; display: inline-block;
@ -194,7 +206,7 @@ vn-table.scrollable > .vn-table,
} }
vn-thead th, vn-thead th,
vn-thead vn-th, vn-thead vn-th,
thead vn-th, thead vn-th,
thead th { thead th {
border-bottom: $border; border-bottom: $border;
@ -217,4 +229,4 @@ vn-table.scrollable.lg,
.tableWrapper { .tableWrapper {
overflow-x: auto; overflow-x: auto;
} }

View File

@ -101,6 +101,8 @@ $color-marginal: #222;
$color-success: #a3d131; $color-success: #a3d131;
$color-notice: #32b1ce; $color-notice: #32b1ce;
$color-alert: #fa3939; $color-alert: #fa3939;
$color-pink: #ff99cc;
$color-yellow: #ffff00;
$color-button: $color-secondary; $color-button: $color-secondary;
$color-spacer: rgba(255, 255, 255, .3); $color-spacer: rgba(255, 255, 255, .3);

118
front/package-lock.json generated
View File

@ -1,15 +1,8 @@
{ {
"name": "salix-front", "name": "salix-front",
"version": "1.0.0", "version": "1.0.0",
"lockfileVersion": 1, "lockfileVersion": 2,
"requires": true, "requires": true,
<<<<<<< HEAD
"dependencies": {
"@uirouter/angularjs": {
"version": "1.0.29",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
=======
"packages": { "packages": {
"": { "": {
"name": "salix-front", "name": "salix-front",
@ -32,8 +25,7 @@
}, },
"node_modules/@uirouter/angularjs": { "node_modules/@uirouter/angularjs": {
"version": "1.0.30", "version": "1.0.30",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz", "license": "MIT",
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
"dependencies": { "dependencies": {
"@uirouter/core": "6.0.8" "@uirouter/core": "6.0.8"
}, },
@ -46,17 +38,14 @@
}, },
"node_modules/@uirouter/core": { "node_modules/@uirouter/core": {
"version": "6.0.8", "version": "6.0.8",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz", "license": "MIT",
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw==",
"engines": { "engines": {
"node": ">=4.0.0" "node": ">=4.0.0"
} }
}, },
"node_modules/angular": { "node_modules/angular": {
"version": "1.8.3", "version": "1.8.3",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz", "license": "MIT"
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw==",
"deprecated": "For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward."
}, },
"node_modules/angular-animate": { "node_modules/angular-animate": {
"version": "1.8.2", "version": "1.8.2",
@ -74,8 +63,7 @@
}, },
"node_modules/angular-translate": { "node_modules/angular-translate": {
"version": "2.19.0", "version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz", "license": "MIT",
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
"dependencies": { "dependencies": {
"angular": "^1.8.0" "angular": "^1.8.0"
}, },
@ -85,8 +73,7 @@
}, },
"node_modules/angular-translate-loader-partial": { "node_modules/angular-translate-loader-partial": {
"version": "2.19.0", "version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz", "license": "MIT",
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
"dependencies": { "dependencies": {
"angular-translate": "~2.19.0" "angular-translate": "~2.19.0"
} }
@ -133,8 +120,7 @@
}, },
"node_modules/moment": { "node_modules/moment": {
"version": "2.29.4", "version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "license": "MIT",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
"engines": { "engines": {
"node": "*" "node": "*"
} }
@ -179,97 +165,51 @@
"dependencies": { "dependencies": {
"@uirouter/angularjs": { "@uirouter/angularjs": {
"version": "1.0.30", "version": "1.0.30",
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
>>>>>>> dev
"requires": { "requires": {
"@uirouter/core": "6.0.8" "@uirouter/core": "6.0.8"
} }
}, },
"@uirouter/core": { "@uirouter/core": {
<<<<<<< HEAD "version": "6.0.8"
"version": "6.0.7",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w=="
}, },
"angular": { "angular": {
"version": "1.8.2", "version": "1.8.3"
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
=======
"version": "6.0.8",
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw=="
},
"angular": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw=="
>>>>>>> dev
}, },
"angular-animate": { "angular-animate": {
"version": "1.8.2", "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": { "angular-moment": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
"requires": { "requires": {
"moment": ">=2.8.0 <3.0.0" "moment": ">=2.8.0 <3.0.0"
} }
}, },
"angular-translate": { "angular-translate": {
<<<<<<< HEAD
"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==",
=======
"version": "2.19.0", "version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
>>>>>>> dev
"requires": { "requires": {
"angular": "^1.8.0" "angular": "^1.8.0"
} }
}, },
"angular-translate-loader-partial": { "angular-translate-loader-partial": {
<<<<<<< HEAD
"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==",
=======
"version": "2.19.0", "version": "2.19.0",
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
>>>>>>> dev
"requires": { "requires": {
"angular-translate": "~2.19.0" "angular-translate": "~2.19.0"
} }
}, },
"argparse": { "argparse": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"requires": { "requires": {
"sprintf-js": "~1.0.2" "sprintf-js": "~1.0.2"
} }
}, },
"croppie": { "croppie": {
"version": "2.6.5", "version": "2.6.5"
"resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz",
"integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ=="
}, },
"esprima": { "esprima": {
"version": "4.0.1", "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": { "js-yaml": {
"version": "3.14.1", "version": "3.14.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
"requires": { "requires": {
"argparse": "^1.0.7", "argparse": "^1.0.7",
"esprima": "^4.0.0" "esprima": "^4.0.0"
@ -277,45 +217,27 @@
}, },
"mg-crud": { "mg-crud": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
"integrity": "sha512-mAR6t0aQHKnT0QHKHpLOi0kNPZfO36iMpIoiLjFHxuio6mIJyuveBJ4VNlNXJRxLh32/FLADEb41/sYo7QUKFw==",
"requires": { "requires": {
"angular": "^1.6.1" "angular": "^1.6.1"
} }
}, },
"moment": { "moment": {
<<<<<<< HEAD "version": "2.29.4"
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
=======
"version": "2.29.4",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
>>>>>>> dev
}, },
"oclazyload": { "oclazyload": {
"version": "0.6.3", "version": "0.6.3"
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
"integrity": "sha512-HpOSYUgjtt6sTB/C6+FWsExR+9HCnXKsUA96RWkDXfv11C8Cc9X2DlR0WIZwFIiG6FQU0pwB5dhoYyut8bFAOQ=="
}, },
"require-yaml": { "require-yaml": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
"integrity": "sha512-M6eVEgLPRbeOhgSCnOTtdrOOEQzbXRchg24Xa13c39dMuraFKdI9emUo97Rih0YEFzSICmSKg8w4RQp+rd9pOQ==",
"requires": { "requires": {
"js-yaml": "^4.1.0" "js-yaml": ""
}, },
"dependencies": { "dependencies": {
"argparse": { "argparse": {
"version": "2.0.1", "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": { "js-yaml": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"requires": { "requires": {
"argparse": "^2.0.1" "argparse": "^2.0.1"
} }
@ -323,14 +245,10 @@
} }
}, },
"sprintf-js": { "sprintf-js": {
"version": "1.0.3", "version": "1.0.3"
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
}, },
"validator": { "validator": {
"version": "6.3.0", "version": "6.3.0"
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
"integrity": "sha512-BylxTwhqwjQI5MDJF7amCy/L0ejJO+74DvCsLV52Lq3+3bhVcVMKqNqOiNcQJm2G48u9EAcw4xFERAmFbwXM9Q=="
} }
} }
} }

View File

@ -23,7 +23,7 @@ module.exports = Self => {
{ {
arg: 'search', arg: 'search',
type: 'string', type: 'string',
description: `If it's and integer searchs by id, otherwise it searchs by client name`, description: `If it's a number searchs by id, otherwise it searchs by client name`,
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
@ -34,31 +34,31 @@ module.exports = Self => {
}, },
{ {
arg: 'id', arg: 'id',
type: 'integer', type: 'number',
description: 'The claim id', description: 'The claim id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'clientFk', arg: 'clientFk',
type: 'integer', type: 'number',
description: 'The client id', description: 'The client id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'claimStateFk', arg: 'claimStateFk',
type: 'integer', type: 'number',
description: 'The claim state id', description: 'The claim state id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'salesPersonFk', arg: 'salesPersonFk',
type: 'integer', type: 'number',
description: 'The salesPerson id', description: 'The salesPerson id',
http: {source: 'query'} http: {source: 'query'}
}, },
{ {
arg: 'attenderFk', arg: 'attenderFk',
type: 'integer', type: 'number',
description: 'The attender worker id', description: 'The attender worker id',
http: {source: 'query'} http: {source: 'query'}
}, },
@ -67,6 +67,18 @@ module.exports = Self => {
type: 'date', type: 'date',
description: 'The to date filter', description: 'The to date filter',
http: {source: 'query'} http: {source: 'query'}
},
{
arg: 'itemFk',
type: 'number',
description: 'The item id',
http: {source: 'query'}
},
{
arg: 'claimResponsibleFk',
type: 'number',
description: 'The claimResponsible id',
http: {source: 'query'}
} }
], ],
returns: { returns: {
@ -80,33 +92,58 @@ module.exports = Self => {
}); });
Self.filter = async(ctx, filter, options) => { Self.filter = async(ctx, filter, options) => {
const models = Self.app.models;
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const args = ctx.args;
const myOptions = {}; const myOptions = {};
let to; let to;
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const where = buildFilter(ctx.args, (param, value) => { let claimIdsByItemFk = [];
let claimIdsByClaimResponsibleFk = [];
if (args.itemFk) {
query = `SELECT cb.claimFk
FROM claimBeginning cb
LEFT JOIN sale s ON s.id = cb.saleFk
WHERE s.itemFk = ?`;
const claims = await Self.rawSql(query, [args.itemFk], myOptions);
claimIdsByItemFk = claims.map(claim => claim.claimFk);
}
if (args.claimResponsibleFk) {
const claims = await models.ClaimDevelopment.find({
fields: ['claimFk'],
where: {claimResponsibleFk: args.claimResponsibleFk}
}, myOptions);
claimIdsByClaimResponsibleFk = claims.map(claim => claim.claimFk);
}
const where = buildFilter(args, (param, value) => {
switch (param) { switch (param) {
case 'search': case 'search':
return /^\d+$/.test(value) return /^\d+$/.test(value)
? {'cl.id': value} ? {'cl.id': value}
: { : {
or: [ or: [
{'cl.clientName': {like: `%${value}%`}} {'c.name': {like: `%${value}%`}}
] ]
}; };
case 'clientName': case 'clientName':
return {'cl.clientName': {like: `%${value}%`}}; return {'c.name': {like: `%${value}%`}};
case 'clientFk': case 'clientFk':
return {'cl.clientFk': value};
case 'id': case 'id':
case 'claimStateFk': case 'claimStateFk':
case 'priority': case 'priority':
return {[`cl.${param}`]: value}; return {[`cl.${param}`]: value};
case 'itemFk':
return {'cl.id': {inq: claimIdsByItemFk}};
case 'claimResponsibleFk':
return {'cl.id': {inq: claimIdsByClaimResponsibleFk}};
case 'salesPersonFk': case 'salesPersonFk':
return {'cl.salesPersonFk': value}; return {'c.salesPersonFk': value};
case 'attenderFk': case 'attenderFk':
return {'cl.workerFk': value}; return {'cl.workerFk': value};
case 'created': case 'created':
@ -118,29 +155,23 @@ module.exports = Self => {
} }
}); });
filter = mergeFilters(ctx.args.filter, {where}); filter = mergeFilters(args.filter, {where});
const stmts = []; const stmts = [];
const stmt = new ParameterizedSQL( const stmt = new ParameterizedSQL(
`SELECT * `SELECT
FROM ( cl.id,
SELECT cl.clientFk,
cl.id, c.name AS clientName,
cl.clientFk, cl.workerFk,
c.name AS clientName, u.name AS workerName,
cl.workerFk, cs.description,
u.name AS workerName, cl.created
cs.description, FROM claim cl
cl.created, LEFT JOIN client c ON c.id = cl.clientFk
cs.priority, LEFT JOIN account.user u ON u.id = cl.workerFk
cl.claimStateFk, LEFT JOIN claimState cs ON cs.id = cl.claimStateFk`
c.salesPersonFk
FROM claim cl
LEFT JOIN client c ON c.id = cl.clientFk
LEFT JOIN worker w ON w.id = cl.workerFk
LEFT JOIN account.user u ON u.id = w.userFk
LEFT JOIN claimState cs ON cs.id = cl.claimStateFk ) cl`
); );
stmt.merge(conn.makeSuffix(filter)); stmt.merge(conn.makeSuffix(filter));

View File

@ -57,4 +57,44 @@ describe('claim filter()', () => {
throw e; throw e;
} }
}); });
it('should return 3 results filtering by item id', async() => {
const tx = await app.models.Claim.beginTransaction({});
try {
const options = {transaction: tx};
const result = await app.models.Claim.filter({args: {filter: {}, itemFk: 2}}, null, options);
expect(result.length).toEqual(3);
expect(result[0].id).toEqual(1);
expect(result[1].id).toEqual(2);
expect(result[2].id).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return 3 results filtering by claimResponsible id', async() => {
const tx = await app.models.Claim.beginTransaction({});
try {
const options = {transaction: tx};
const result = await app.models.Claim.filter({args: {filter: {}, claimResponsibleFk: 7}}, null, options);
expect(result.length).toEqual(3);
expect(result[0].id).toEqual(2);
expect(result[1].id).toEqual(3);
expect(result[2].id).toEqual(4);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
}); });

View File

@ -58,8 +58,28 @@
ng-model="filter.created"> ng-model="filter.created">
</vn-date-picker> </vn-date-picker>
</vn-horizontal> </vn-horizontal>
<vn-horizontal>
<vn-autocomplete vn-one class="dense"
label="Item"
url="Items/withName"
ng-model="filter.itemFk"
show-field="name"
value-field="id"
search-function="$ctrl.itemSearchFunc($search)"
order="id DESC">
<tpl-item>{{::id}} - {{::name}}</tpl-item>
</vn-autocomplete>
<vn-autocomplete
vn-one
ng-model="filter.claimResponsibleFk"
url="ClaimResponsibles"
show-field="description"
value-field="id"
label="Responsible">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal class="vn-mt-lg"> <vn-horizontal class="vn-mt-lg">
<vn-submit label="Search"></vn-submit> <vn-submit label="Search"></vn-submit>
</vn-horizontal> </vn-horizontal>
</form> </form>
</div> </div>

View File

@ -1,7 +1,14 @@
import ngModule from '../module'; import ngModule from '../module';
import SearchPanel from 'core/components/searchbar/search-panel'; import SearchPanel from 'core/components/searchbar/search-panel';
class Controller extends SearchPanel {
itemSearchFunc($search) {
return /^\d+$/.test($search)
? {id: $search}
: {name: {like: '%' + $search + '%'}};
}
}
ngModule.vnComponent('vnClaimSearchPanel', { ngModule.vnComponent('vnClaimSearchPanel', {
template: require('./index.html'), template: require('./index.html'),
controller: SearchPanel controller: Controller
}); });

View File

@ -4,7 +4,7 @@ import Dialog from 'core/components/dialog';
class Controller extends Dialog { class Controller extends Dialog {
constructor($element, $, $transclude, vnReport) { constructor($element, $, $transclude, vnReport) {
super($element, $, $transclude); super($element, $, $transclude);
this.viewReceipt = true;
this.vnReport = vnReport; this.vnReport = vnReport;
this.receipt = {}; this.receipt = {};
} }

View File

@ -75,6 +75,7 @@ describe('Client', () => {
jest.spyOn(controller.vnReport, 'show'); jest.spyOn(controller.vnReport, 'show');
controller.$params = {id: 1101}; controller.$params = {id: 1101};
controller.viewReceipt = false;
$httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1}); $httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1});
controller.responseHandler('accept'); controller.responseHandler('accept');

View File

@ -11,7 +11,6 @@ describe('InvoiceOut createPdf()', () => {
const ctx = {req: activeCtx}; const ctx = {req: activeCtx};
it('should create a new PDF file and set true the hasPdf property', async() => { it('should create a new PDF file and set true the hasPdf property', async() => {
pending('https://redmine.verdnatura.es/issues/4875');
const invoiceId = 1; const invoiceId = 1;
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: activeCtx active: activeCtx

View File

@ -13,7 +13,6 @@ describe('InvoiceOut downloadZip()', () => {
}; };
it('should return part of link to dowloand the zip', async() => { it('should return part of link to dowloand the zip', async() => {
pending('https://redmine.verdnatura.es/issues/4875');
const tx = await models.InvoiceOut.beginTransaction({}); const tx = await models.InvoiceOut.beginTransaction({});
try { try {

View File

@ -51,7 +51,6 @@ describe('InvoiceOut filter()', () => {
}); });
it('should return the invoice out matching hasPdf', async() => { it('should return the invoice out matching hasPdf', async() => {
pending('https://redmine.verdnatura.es/issues/4875');
const tx = await models.InvoiceOut.beginTransaction({}); const tx = await models.InvoiceOut.beginTransaction({});
const options = {transaction: tx}; const options = {transaction: tx};
@ -67,7 +66,7 @@ describe('InvoiceOut filter()', () => {
const result = await models.InvoiceOut.filter(ctx, {id: invoiceOut.id}, options); const result = await models.InvoiceOut.filter(ctx, {id: invoiceOut.id}, options);
expect(result.length).toEqual(1); expect(result.length).toBeGreaterThanOrEqual(1);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -17,12 +17,12 @@
target="_blank" target="_blank"
name="showInvoicePdf" name="showInvoicePdf"
translate> translate>
Show as PDF as PDF
</a> </a>
<vn-item <vn-item
ng-click="$ctrl.showCsvInvoice()" ng-click="$ctrl.showCsvInvoice()"
translate> translate>
Show as CSV as CSV
</vn-item> </vn-item>
</vn-list> </vn-list>
</vn-menu> </vn-menu>

View File

@ -2,6 +2,8 @@ Show invoice...: Ver factura...
Send invoice...: Enviar factura... Send invoice...: Enviar factura...
Send PDF invoice: Enviar factura en PDF Send PDF invoice: Enviar factura en PDF
Send CSV invoice: Enviar factura en CSV Send CSV invoice: Enviar factura en CSV
as PDF: como PDF
as CSV: como CSV
Delete Invoice: Eliminar factura Delete Invoice: Eliminar factura
Clone Invoice: Clonar factura Clone Invoice: Clonar factura
Book invoice: Asentar factura Book invoice: Asentar factura

View File

@ -0,0 +1,49 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('filter', {
description: 'Returns all item shelving sale matching with the filter',
accessType: 'READ',
accepts: [{
arg: 'filter',
type: 'object',
description: 'Filter defining where and paginated data'
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/filter`,
verb: 'GET'
}
});
Self.filter = async(filter, options) => {
const conn = Self.dataSource.connector;
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const stmt = new ParameterizedSQL(`
SELECT iss.created,
iss.saleFk,
iss.quantity,
iss.userFk,
ish.shelvingFk,
p.code,
u.name
FROM itemShelvingSale iss
LEFT JOIN itemShelving ish ON iss.itemShelvingFk = ish.id
LEFT JOIN shelving s ON ish.shelvingFk = s.code
LEFT JOIN parking p ON s.parkingFk = p.id
LEFT JOIN account.user u ON u.id = iss.userFk`
);
stmt.merge(conn.makeSuffix(filter));
return conn.executeStmt(stmt);
};
};

View File

@ -0,0 +1,3 @@
module.exports = Self => {
require('../methods/item-shelving-sale/filter')(Self);
};

View File

@ -12,21 +12,12 @@
"id": true, "id": true,
"description": "Identifier" "description": "Identifier"
}, },
"shelve": {
"type": "string"
},
"shelvingFk": { "shelvingFk": {
"type": "string" "type": "string"
}, },
"itemFk": { "itemFk": {
"type": "number" "type": "number"
}, },
"deep": {
"type": "number"
},
"quantity": {
"type": "number"
},
"created": { "created": {
"type": "date" "type": "date"
} }
@ -41,6 +32,11 @@
"type": "belongsTo", "type": "belongsTo",
"model": "Account", "model": "Account",
"foreignKey": "userFk" "foreignKey": "userFk"
} },
"shelving": {
"type": "belongsTo",
"model": "Shelving",
"foreignKey": "shelvingFk"
}
} }
} }

View File

@ -1,6 +1,6 @@
<mg-ajax <mg-ajax
path="Items/{{patch.params.id}}" path="Items/{{patch.params.id}}"
options="vnPatch" options="vnPatch"
override="{filter: {include: [{relation: 'itemType'}, {relation: 'origin'}, {relation: 'ink'}, {relation: 'producer'}, {relation: 'expense'}]}}"> override="{filter: {include: [{relation: 'itemType'}, {relation: 'origin'}, {relation: 'ink'}, {relation: 'producer'}, {relation: 'expense'}]}}">
</mg-ajax> </mg-ajax>
<vn-watcher <vn-watcher
@ -26,8 +26,8 @@
rule rule
vn-focus> vn-focus>
</vn-textfield> </vn-textfield>
<vn-textfield <vn-textfield
vn-one label="Full name" vn-one label="Full name"
ng-model="$ctrl.item.longName" ng-model="$ctrl.item.longName"
rule rule
info="Full name calculates based on tags 1-3. Is not recommended to change it manually"> info="Full name calculates based on tags 1-3. Is not recommended to change it manually">
@ -95,7 +95,7 @@
<vn-input-number <vn-input-number
vn-one vn-one
min="0" min="0"
label="Relevancy" label="Relevancy"
ng-model="$ctrl.item.relevancy" ng-model="$ctrl.item.relevancy"
rule> rule>
</vn-input-number> </vn-input-number>
@ -108,15 +108,15 @@
</vn-input-number> </vn-input-number>
<vn-input-number <vn-input-number
vn-one vn-one
min="0" min="0"
label="stems" label="stems"
ng-model="$ctrl.item.stems" ng-model="$ctrl.item.stems"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-input-number <vn-input-number
vn-one vn-one
min="0" min="0"
label="Multiplier" label="Multiplier"
ng-model="$ctrl.item.stemMultiplier"> ng-model="$ctrl.item.stemMultiplier">
</vn-input-number> </vn-input-number>
</vn-horizontal> </vn-horizontal>
@ -124,10 +124,17 @@
<vn-input-number <vn-input-number
vn-one vn-one
min="0" min="0"
label="Weight/Piece" label="Weight/Piece"
ng-model="$ctrl.item.weightByPiece" ng-model="$ctrl.item.weightByPiece"
rule> rule>
</vn-input-number> </vn-input-number>
<vn-input-number
vn-one
min="0"
label="Units/Box"
ng-model="$ctrl.item.packingOut"
rule>
</vn-input-number>
<vn-autocomplete <vn-autocomplete
vn-one vn-one
label="Generic" label="Generic"
@ -192,7 +199,7 @@
</form> </form>
<!-- Create custom agent dialog --> <!-- Create custom agent dialog -->
<vn-dialog class="edit" <vn-dialog class="edit"
vn-id="intrastat" vn-id="intrastat"
on-accept="$ctrl.onIntrastatAccept()" on-accept="$ctrl.onIntrastatAccept()"
message="New intrastat"> message="New intrastat">
@ -225,12 +232,12 @@
<tpl-body class="itemFilter"> <tpl-body class="itemFilter">
<vn-horizontal> <vn-horizontal>
<vn-textfield <vn-textfield
label="Name" label="Name"
ng-model="$ctrl.itemFilterParams.name" ng-model="$ctrl.itemFilterParams.name"
vn-focus> vn-focus>
</vn-textfield> </vn-textfield>
<vn-textfield <vn-textfield
label="Size" label="Size"
ng-model="$ctrl.itemFilterParams.size"> ng-model="$ctrl.itemFilterParams.size">
</vn-textfield> </vn-textfield>
<vn-autocomplete <vn-autocomplete
@ -262,7 +269,7 @@
</vn-button> </vn-button>
</vn-horizontal> </vn-horizontal>
<vn-crud-model <vn-crud-model
vn-id="itemsModel" vn-id="itemsModel"
url="Items/withName" url="Items/withName"
filter="$ctrl.itemFilter" filter="$ctrl.itemFilter"
data="items" data="items"
@ -305,4 +312,4 @@
warehouse-fk="$ctrl.vnConfig.warehouseFk"> warehouse-fk="$ctrl.vnConfig.warehouseFk">
</vn-item-descriptor-popover> </vn-item-descriptor-popover>
</tpl-body> </tpl-body>
</vn-dialog> </vn-dialog>

View File

@ -44,6 +44,7 @@ Weight/Piece: Peso/tallo
Search items by id, name or barcode: Buscar articulos por identificador, nombre o codigo de barras Search items by id, name or barcode: Buscar articulos por identificador, nombre o codigo de barras
SalesPerson: Comercial SalesPerson: Comercial
Concept: Concepto Concept: Concepto
Units/Box: Unidades/Caja
# Sections # Sections
Items: Artículos Items: Artículos
@ -61,4 +62,4 @@ Item diary: Registro de compra-venta
Last entries: Últimas entradas Last entries: Últimas entradas
Tags: Etiquetas Tags: Etiquetas
Waste breakdown: Desglose de mermas Waste breakdown: Desglose de mermas
Waste breakdown by item: Desglose de mermas por artículo Waste breakdown by item: Desglose de mermas por artículo

View File

@ -0,0 +1,33 @@
module.exports = Self => {
Self.remoteMethodCtx('salePreparingList', {
description: 'Returns a list with the lines of a ticket and its different states of preparation',
accessType: 'READ',
accepts: [{
arg: 'id',
type: 'number',
required: true,
description: 'The ticket id',
http: {source: 'path'}
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/:id/salePreparingList`,
verb: 'GET'
}
});
Self.salePreparingList = async(ctx, id, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
query = `CALL vn.salePreparingList(?)`;
const [sales] = await Self.rawSql(query, [id], myOptions);
return sales;
};
};

View File

@ -1,5 +1,6 @@
module.exports = Self => { module.exports = Self => {
require('../methods/sale/getClaimableFromTicket')(Self); require('../methods/sale/getClaimableFromTicket')(Self);
require('../methods/sale/salePreparingList')(Self);
require('../methods/sale/reserve')(Self); require('../methods/sale/reserve')(Self);
require('../methods/sale/deleteSales')(Self); require('../methods/sale/deleteSales')(Self);
require('../methods/sale/updatePrice')(Self); require('../methods/sale/updatePrice')(Self);

View File

@ -1,10 +1,11 @@
<vn-crud-model <vn-crud-model
vn-id="model" vn-id="model"
url="SaleTrackings/listSaleTracking" url="sales"
filter="::$ctrl.filter"
link="{ticketFk: $ctrl.$params.id}" link="{ticketFk: $ctrl.$params.id}"
limit="20" limit="20"
data="sales" data="$ctrl.sales"
order="itemFk DESC" order="concept ASC"
auto-load="true"> auto-load="true">
</vn-crud-model> </vn-crud-model>
<vn-data-viewer model="model"> <vn-data-viewer model="model">
@ -12,31 +13,27 @@
<vn-table model="model"> <vn-table model="model">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th shrink></vn-th> <vn-th field="isChecked" center>Is checked</vn-th>
<vn-th field="itemFk" number>Item</vn-th> <vn-th field="itemFk" number>Item</vn-th>
<vn-th expand>Description</vn-th> <vn-th field="concept">Description</vn-th>
<vn-th field="quantity" number>Quantity</vn-th> <vn-th field="quantity" number>Quantity</vn-th>
<vn-th field="originalQuantity" number>Original</vn-th> <vn-th></vn-th>
<vn-th field="workerFk">Worker</vn-th>
<vn-th field="state" shrink>State</vn-th>
<vn-th field="created" expand>Created</vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="sale in sales"> <vn-tr ng-repeat="sale in $ctrl.sales">
<vn-td shrink> <vn-td center>
<vn-icon <span class="chip {{$ctrl.chipHasSaleGroupDetail(sale.preparingList.hasSaleGroupDetail)}} vn-mx-xs chip2" vn-tooltip="has saleGroupDetail"></span>
class="bright" <span class="chip {{$ctrl.chipIsPreviousSelected(sale.preparingList.isPreviousSelected)}} vn-ml-xs" vn-tooltip="is previousSelected"></span>
icon="warning" <span class="chip {{$ctrl.chipIsPrevious(sale.preparingList.isPrevious)}} vn-mr-xs" vn-tooltip="is previous"></span>
ng-if="sale.quantity != sale.originalQuantity" <span class="chip {{$ctrl.chipIsPrepared(sale.preparingList.isPrepared)}} vn-mx-xs" vn-tooltip="is prepared"></span>
vn-tooltip="The quantity do not match"> <span class="chip {{$ctrl.chipIsControled(sale.preparingList.isControled)}} vn-mx-xs" vn-tooltip="is controled"></span>
</vn-icon>
</vn-td> </vn-td>
<vn-td number> <vn-td number>
<span <span
ng-click="itemDescriptor.show($event, sale.itemFk, sale.id)" ng-click="$ctrl.showItemDescriptor($event, sale)"
class="link"> class="link">
{{sale.itemFk | zeroFill:6}} {{::sale.itemFk | zeroFill:6}}
</span> </span>
</vn-td> </vn-td>
<vn-td vn-fetched-tags> <vn-td vn-fetched-tags>
@ -53,16 +50,18 @@
</vn-fetched-tags> </vn-fetched-tags>
</vn-td> </vn-td>
<vn-td number>{{::sale.quantity}}</vn-td> <vn-td number>{{::sale.quantity}}</vn-td>
<vn-td number>{{::sale.originalQuantity}}</vn-td> <vn-td actions>
<vn-td expand> <vn-icon-button
<span vn-click-stop="$ctrl.showSaleTracking(sale)"
class="link" vn-tooltip="Sale tracking"
ng-click="workerDescriptor.show($event, sale.workerFk)"> icon="history">
{{::sale.userNickname | dashIfEmpty}} </vn-icon-button>
</span> <vn-icon-button
vn-click-stop="$ctrl.showItemShelvingSale(sale)"
vn-tooltip="ItemShelvings sale"
icon="icon-inventory">
</vn-icon-button>
</vn-td> </vn-td>
<vn-td shrink>{{::sale.state}}</vn-td>
<vn-td expand>{{::sale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>
</vn-table> </vn-table>
@ -70,8 +69,99 @@
</vn-data-viewer> </vn-data-viewer>
<vn-item-descriptor-popover <vn-item-descriptor-popover
vn-id="item-descriptor" vn-id="item-descriptor"
warehouse-fk="$ctrl.ticket.warehouseFk"> warehouse-fk="$ctrl.ticket.warehouseFk"
ticket-fk="$ctrl.ticket.id">
</vn-item-descriptor-popover> </vn-item-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="worker-descriptor"> <vn-popup vn-id="saleTracking">
</vn-worker-descriptor-popover> <vn-crud-model
vn-id="modelSaleTracking"
url="SaleTrackings/listSaleTracking"
link="{saleFk: $ctrl.saleId}"
limit="20"
data="saleTrackings"
order="itemFk DESC"
auto-load="true">
</vn-crud-model>
<vn-data-viewer model="modelSaleTracking">
<vn-card class="vn-w-lg">
<vn-table model="modelSaleTracking">
<vn-thead>
<vn-tr>
<vn-th field="quantity" number>Quantity</vn-th>
<vn-th field="originalQuantity" number>Original</vn-th>
<vn-th field="workerFk">Worker</vn-th>
<vn-th field="state" shrink>State</vn-th>
<vn-th field="created" expand>Created</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="sale in saleTrackings">
<vn-td number>{{::sale.quantity}}</vn-td>
<vn-td number>{{::sale.originalQuantity}}</vn-td>
<vn-td expand>
<span
class="link"
ng-click="workerDescriptor.show($event, sale.workerFk)">
{{::sale.userNickname | dashIfEmpty}}
</span>
</vn-td>
<vn-td shrink>{{::sale.state}}</vn-td>
<vn-td expand>{{::sale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-card>
</vn-data-viewer>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.ticket.warehouseFk">
</vn-item-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="worker-descriptor">
</vn-worker-descriptor-popover>
</vn-popup>
<vn-popup vn-id="itemShelvingSale">
<vn-crud-model
vn-id="modelSaleTracking"
url="ItemShelvingSales/filter"
link="{saleFk: $ctrl.saleId}"
limit="20"
data="$ctrl.itemShelvingSales"
auto-load="true">
</vn-crud-model>
<vn-data-viewer model="modelSaleTracking">
<vn-card class="vn-w-lg">
<vn-table model="modelSaleTracking">
<vn-thead>
<vn-tr>
<vn-th field="quantity" number>Quantity</vn-th>
<vn-th field="workerFk">Worker</vn-th>
<vn-th field="shelving" shrink>Shelving</vn-th>
<vn-th field="parking" shrink>Parking</vn-th>
<vn-th field="created" expand>Created</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="itemShelvingSale in $ctrl.itemShelvingSales">
<vn-td number>{{::itemShelvingSale.quantity}}</vn-td>
<vn-td expand>
<span
class="link"
ng-click="workerDescriptor.show($event, itemShelvingSale.userFk)">
{{::itemShelvingSale.name | dashIfEmpty}}
</span>
</vn-td>
<vn-td shrink>{{::itemShelvingSale.shelvingFk}}</vn-td>
<vn-td shrink>{{::itemShelvingSale.code}}</vn-td>
<vn-td expand>{{::itemShelvingSale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr>
</vn-tbody>
</vn-table>
</vn-card>
</vn-data-viewer>
<vn-worker-descriptor-popover
vn-id="worker-descriptor">
</vn-worker-descriptor-popover>
</vn-popup>

View File

@ -1,12 +1,100 @@
import ngModule from '../module'; import ngModule from '../module';
import Section from 'salix/components/section'; import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {} class Controller extends Section {
constructor($element, $) {
super($element, $);
this.filter = {
include: [
{
relation: 'item'
}, {
relation: 'saleTracking',
scope: {
fields: ['isChecked']
}
}
]
};
}
get sales() {
return this._sales;
}
set sales(value) {
this._sales = value;
if (value) {
const query = `Sales/${this.$params.id}/salePreparingList`;
this.$http.get(query)
.then(res => {
this.salePreparingList = res.data;
for (const salePreparing of this.salePreparingList) {
for (const sale of this.sales) {
if (salePreparing.saleFk == sale.id)
sale.preparingList = salePreparing;
}
}
});
}
}
showItemDescriptor(event, sale) {
this.quicklinks = {
btnThree: {
icon: 'icon-transaction',
state: `item.card.diary({
id: ${sale.itemFk},
warehouseFk: ${this.ticket.warehouseFk},
lineFk: ${sale.id}
})`,
tooltip: 'Item diary'
}
};
this.$.itemDescriptor.show(event.target, sale.itemFk);
}
chipHasSaleGroupDetail(hasSaleGroupDetail) {
if (hasSaleGroupDetail) return 'pink';
else return 'message';
}
chipIsPreviousSelected(isPreviousSelected) {
if (isPreviousSelected) return 'notice';
else return 'message';
}
chipIsPrevious(isPrevious) {
if (isPrevious) return 'dark-notice';
else return 'message';
}
chipIsPrepared(isPrepared) {
if (isPrepared) return 'warning';
else return 'message';
}
chipIsControled(isControled) {
if (isControled) return 'yellow';
else return 'message';
}
showSaleTracking(sale) {
this.saleId = sale.id;
this.$.saleTracking.show();
}
showItemShelvingSale(sale) {
this.saleId = sale.id;
this.$.itemShelvingSale.show();
}
}
ngModule.vnComponent('vnTicketSaleTracking', { ngModule.vnComponent('vnTicketSaleTracking', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller, controller: Controller,
bindings: { bindings: {
ticket: '<', ticket: '<'
}, }
}); });

View File

@ -0,0 +1,6 @@
ItemShelvings sale: Carros línea
has saleGroupDetail: tiene detalle grupo lineas
is previousSelected: es previa seleccionada
is previous: es previa
is prepared: esta preparado
is controled: esta controlado

View File

@ -0,0 +1,7 @@
@import "variables";
.chip {
display: inline-block;
min-width: 15px;
min-height: 25px;
}