Compare commits

...

63 Commits

Author SHA1 Message Date
Alex Moreno 816a7f23e5 Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 14:18:19 +01:00
Alex Moreno 93a0d4cdf4 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into test
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 14:18:06 +01:00
Alex Moreno 3c70dd77c9 Merge pull request 'build: dump db' (!3250) from 8231_dump into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3250
Reviewed-by: Jon Elias <jon@verdnatura.es>
2024-11-26 13:17:51 +00:00
Alex Moreno c66ae728d6 build: dump db
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 14:12:10 +01:00
Guillermo Bonet 89d941c115 refactor: refs #8235 Deleted deprecated objects
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 14:10:39 +01:00
Guillermo Bonet f8a79057b2 fix: refs #7899 Version
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 13:42:33 +01:00
Ivan Mas f2b74794de Merge pull request 'refactor: refs #7899 delete unused states' (!3238) from 7899-deleteUnusedStates into dev
gitea/salix/pipeline/head There was a failure building this commit Details
Reviewed-on: #3238
Reviewed-by: Guillermo Bonet <guillermo@verdnatura.es>
2024-11-26 12:30:25 +00:00
Ivan Mas f32d709b9d Merge branch 'dev' into 7899-deleteUnusedStates
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-26 12:22:30 +00:00
Alex Moreno 45f7b60f1b Merge pull request 'fix: refs #7641 display buy.comment' (!3247) from 7641-hotfix-dropComment into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3247
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2024-11-26 11:26:48 +00:00
Jorge Penadés 00288e5a7f fix: refs #7641 display buy.comment
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 12:22:35 +01:00
Guillermo Bonet c14484366e Merge branch 'test' into dev
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 10:10:09 +01:00
Guillermo Bonet 6487497638 Merge branch 'master' into test
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 10:09:45 +01:00
Pablo Natek 7b3a08d222 Merge pull request 'fix: refs #8087 correct SQL join condition in entry_beforeUpdate trigger' (!3246) from 8087-correctFix into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3246
Reviewed-by: Robert Ferrús <robert@verdnatura.es>
2024-11-26 08:20:10 +00:00
Pablo Natek e6df9d426f fix: refs #8087 correct SQL query to use alias for isRaid in entry_beforeUpdate trigger
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 09:17:18 +01:00
Pablo Natek 3057d80e76 fix: refs #8087 correct SQL join condition in entry_beforeUpdate trigger
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 09:14:38 +01:00
Guillermo Bonet ed6f490188 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 09:11:38 +01:00
Guillermo Bonet 45e6d7f046 fix: refs #4948 ticket_selfConsumptionPackaging 2024-11-26 09:11:36 +01:00
Pablo Natek 5a050e2748 Merge pull request 'fix: refs #8087 correct SQL join condition in entry_beforeUpdate trigger' (!3245) from 8087-fixTrigger into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3245
Reviewed-by: Robert Ferrús <robert@verdnatura.es>
2024-11-26 08:09:43 +00:00
Robert Ferrús 43e39fd127 Merge branch 'master' into 8087-fixTrigger
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 08:08:13 +00:00
Robert Ferrús 56b0d254b8 Merge pull request 'fix: refs #8124 workCenterFk por commissionWorkCenterFk' (!3244) from hotFix2route_calcCommission into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3244
Reviewed-by: Pablo Natek <pablone@verdnatura.es>
2024-11-26 08:07:58 +00:00
Pablo Natek 0cbaac91c2 fix: refs #8087 correct SQL join condition in entry_beforeUpdate trigger
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 09:06:25 +01:00
Robert Ferrús 00353186e6 fix: refs #8124 workCenterFk por commissionWorkCenterFk
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 09:03:22 +01:00
Guillermo Bonet 2eed2f00a9 fix: refs #4948 ticket_selfConsumptionPackaging
gitea/salix/pipeline/head This commit looks good Details
2024-11-26 09:01:04 +01:00
Robert Ferrús 4fc3006298 Merge pull request 'fix: refs #8124 workCenter por workCenterFk' (!3243) from hotFixroute_calcCommission into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3243
Reviewed-by: Pablo Natek <pablone@verdnatura.es>
2024-11-26 07:36:57 +00:00
Robert Ferrús 35b508d3d6 fix: refs #8124 workCenter por workCenterFk
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-26 08:33:56 +01:00
Alex Moreno 1a11832281 Merge pull request '8231_testToMaster_2448' (!3241) from 8231_testToMaster_2448 into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3241
Reviewed-by: Guillermo Bonet <guillermo@verdnatura.es>
2024-11-26 06:04:21 +00:00
Carlos Andrés d007e4f218 Actualizar db/versions/11363-silverCarnation/00-firstScript.sql
gitea/salix/pipeline/head This commit looks good Details
2024-11-25 17:53:44 +00:00
Carlos Andrés 26406b6fdb feat: refs #8124 Enrutadores nuevos requerimientos
gitea/salix/pipeline/head There was a failure building this commit Details
2024-11-25 18:45:37 +01:00
Sergio De la torre b0b64b2630 Merge pull request 'feat: refs #8213 refs#8213 picker ItemShelvingSale' (!3242) from 8213-itemShelvingSalePicker into test
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3242
Reviewed-by: Carlos Andrés <carlosap@verdnatura.es>
2024-11-25 15:22:55 +00:00
Sergio De la torre f6941928cd feat: refs #8213 refs#8213 picker ItemShelvingSale
gitea/salix/pipeline/pr-test This commit looks good Details
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-25 16:20:25 +01:00
Sergio De la torre 0b5ef35d22 feat: refs #8213 refs#8213 picker ItemShelvingSale
gitea/salix/pipeline/pr-test This commit looks good Details
2024-11-25 16:16:47 +01:00
Alex Moreno ed39ae7e4b chore: refs #8231 add changelog
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-25 14:48:59 +01:00
Jorge Penadés e2d827d937 Merge pull request 'fix: refs #7229 update env col for consistency' (!3240) from 7229-fixEnvironment into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3240
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2024-11-25 13:43:17 +00:00
Jorge Penadés 584287b211 fix: refs #7229 update default environment
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-25 14:20:15 +01:00
Jorge Penadés a68d7e8c0b fix: refs #7229 rollback
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-25 14:15:10 +01:00
Jorge Penadés 9da5b4ecda fix: refs #7229 update default environment
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-25 14:05:12 +01:00
Jorge Penadés ca1ccff10b fix: refs #7229 update env col for consistency
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2024-11-25 13:55:07 +01:00
Guillermo Bonet 65ca1b5af3 Merge pull request 'feat: refs #8149 Group by CuentaIvaRepercutido' (!3201) from 8149-ivaXDiario into dev
gitea/salix/pipeline/head This commit looks good Details
gitea/salix/pipeline/pr-dev This commit looks good Details
Reviewed-on: #3201
Reviewed-by: Carlos Andrés <carlosap@verdnatura.es>
2024-11-22 12:09:47 +00:00
Carlos Andrés 771aeaa9bd Merge pull request 'test' (!3237) from test into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3237
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2024-11-22 12:03:18 +00:00
Guillermo Bonet 1c6f59a0ec Merge branch '8149-ivaXDiario' of https://gitea.verdnatura.es/verdnatura/salix into 8149-ivaXDiario
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-22 12:59:26 +01:00
Guillermo Bonet 4ab2d7fd09 feat: refs #8149 Group by CuentaIvaRepercutido 2024-11-22 12:59:24 +01:00
Ivan Mas 00412e3258 refactor: refs #7899 delete unused states
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-22 12:21:05 +01:00
Carlos Andrés 7cf6acec19 Merge pull request '8124-enrutadoresNuevosRequerimientos' (!3235) from 8124-enrutadoresNuevosRequerimientos into test
gitea/salix/pipeline/pr-dev This commit looks good Details
gitea/salix/pipeline/head This commit looks good Details
gitea/salix/pipeline/pr-master This commit looks good Details
Reviewed-on: #3235
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2024-11-22 09:46:03 +00:00
Guillermo Bonet c440472693 Merge branch 'dev' into 8149-ivaXDiario
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-22 09:43:26 +00:00
Jorge Penadés 470d9bde64 Merge pull request 'fix: refs #7229 set right urls' (!3226) from 7229-fixDownloadFile into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3226
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2024-11-22 09:34:16 +00:00
Jorge Penadés b97058735c Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7229-fixDownloadFile
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-22 10:25:28 +01:00
Guillermo Bonet 46c85d44d6 Merge branch 'test' into dev
gitea/salix/pipeline/head This commit looks good Details
2024-11-22 09:12:23 +01:00
Guillermo Bonet a731bb3a45 Merge branch 'master' into test
gitea/salix/pipeline/head This commit looks good Details
2024-11-22 09:11:29 +01:00
Guillermo Bonet c73196edec fix: refs #7834 expeditionScan_Put no throw
gitea/salix/pipeline/head This commit looks good Details
2024-11-22 09:10:18 +01:00
Javier Segarra f01051a266 Merge pull request 'Revert ItemMigration and enbale in Salix (cd7ed6987a)' (!3236) from revert_7283_itemMigration3 into test
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3236
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2024-11-22 08:02:49 +00:00
Javier Segarra a6d2f9c3f8 Merge branch 'test' into revert_7283_itemMigration3
gitea/salix/pipeline/pr-test This commit looks good Details
2024-11-22 07:56:09 +00:00
Javier Segarra 0c592946e6 revert cd7ed6987a
gitea/salix/pipeline/pr-test This commit looks good Details
2024-11-21 20:24:33 +01:00
Carlos Andrés 52364bbe2d feat: refs #8124 Enrutadores nuevos requerimientos
gitea/salix/pipeline/pr-test This commit looks good Details
2024-11-21 18:44:47 +01:00
Carlos Andrés 7ad17d75d7 feat: refs #8124 Enrutadores nuevos requerimientos 2024-11-21 18:41:55 +01:00
Sergio De la torre fc75eae338 Merge pull request 'fix: refs #7855 refs#7855 isCheckedDeleted' (!3234) from 7855-expedition_printOut into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3234
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2024-11-21 15:37:56 +00:00
Sergio De la torre 5ac255ac52 fix: refs #7855 refs#7855 isCheckedDeleted
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-21 16:27:45 +01:00
Carlos Satorres 7b177fa09f Merge pull request 'fix: hotfix errorMyTeam' (!3229) from hotfix-filterOrder into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3229
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2024-11-21 09:23:14 +00:00
Carlos Satorres 2978af8341 fix: hotfix errorMyTeam
gitea/salix/pipeline/pr-master This commit looks good Details
2024-11-21 10:18:17 +01:00
Jorge Penadés e125dee691 refactor: refs #7229 desestructure
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-20 16:51:14 +01:00
Jorge Penadés 940bc8caed Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7229-fixDownloadFile
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-20 15:34:04 +01:00
Jorge Penadés 16111220fb Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7229-fixDownloadFile
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-11-20 13:52:55 +01:00
Jorge Penadés bbb7815765 fix: refs #7229 set right urls
gitea/salix/pipeline/pr-dev Build queued... Details
2024-11-20 13:52:24 +01:00
Guillermo Bonet 477fb7ded9 feat: refs #8149 Group by CuentaIvaRepercutido
gitea/salix/pipeline/pr-dev Build queued... Details
2024-11-13 14:27:54 +01:00
160 changed files with 12021 additions and 2399 deletions

View File

@ -1,3 +1,117 @@
# Version 24.48 - 2024-11-25
### Added 🆕
- feat: refs #4948 Added ticket_selfConsumptionPackaging by:guillermo
- feat: refs #6818 add config table by:jorgep
- feat: refs #6818 add records by:jorgep
- feat: refs #6818 saysimple integration by:jorgep
- feat: refs #6845 userInterface by:sergiodt
- feat: refs #6869 add back by:jorgep
- feat: refs #6869 define model by:jorgep
- feat: refs #6869 refs#6869 itemShelving_get (origin/6869-createGetDetails) by:sergiodt
- feat: refs #7006 itemTypeLog by:guillermo
- feat: refs #7006 itemTypeLog created by:guillermo
- feat: refs #7006 Requested changes by:guillermo
- feat: refs #7193 added scope in parking model by:Jon
- feat: refs #7244 Requested changes by:guillermo
- feat: refs #7266 Added details and improvements in item label reports by:guillermo
- feat: refs #7266 buyFkForPrint by:sergiodt
- feat: refs #7266 First commit by:guillermo
- feat: refs #7266 Item label barcode by:guillermo
- feat: refs #7266 Item label QR by:guillermo
- feat: refs #7266 Item label QR finished by:guillermo
- feat: refs #7266 Minor change by:guillermo
- feat: refs #7266 Print corrections by:guillermo
- feat: refs #7266 Requested changes and improvements by:guillermo
- feat: refs #7266 Requested changes and query optimization by:guillermo
- feat: refs #7266 Version by:guillermo
- feat: refs #7289 #7289 apply option 1 by:Javier Segarra
- feat: refs #7289 #7289 remove bad translation by:Javier Segarra
- feat: refs #7524 restrict fields by:jorgep
- feat: refs #7641 fine tunning by:jorgep
- feat: refs #7641 improve style by:jorgep
- feat: refs #7743 add simple spec for sendMail by:pablone
- feat: refs #7743 add try catch stmt to the test by:pablone
- feat: refs #7874 add default type by:jorgep
- feat: refs #7874 use name by:jorgep
- feat: refs #7920 Added ItemShelving in shelvingLog by:guillermo
- feat: refs #7921 refs#7921 sendLostExpedition by:sergiodt
- feat: refs #7922 refs #792 scanOrder by:sergiodt
- feat: refs #7943 quitar lectura en metodos comunes by:jgallego
- feat: refs #7943 return just the required content by:jorgep
- feat: refs #7943 usa back con permisos by:jgallego
- feat: refs #8020 machineWorkerDeprecated by:sergiodt
- feat: refs #8057 Added data updates by:guillermo
- feat: refs #8057 Added data updates (origin/8057-geoFk) by:guillermo
- feat: refs #8057 Added geoFk columns by:guillermo
- feat: refs #8057 Fix version by:guillermo
- feat: refs #8057 More precision in getGeo by:guillermo
- feat: refs #8057 Requested changes by:guillermo
- feat: refs #8071 quitar esquema by:robert
- feat: refs #8071 travel_weeklyClone by:robert
- feat: refs #8080 Added column comment by:guillermo
- feat: refs #8083 add prop by:jorgep
- feat: refs #8087 Traspasar redadas a travels by:Carlos Andrés
- feat: refs #8099 refs#8099 addComplmentSalary by:sergiodt
- feat: refs #8124 Enrutadores nuevos requerimientos by:Carlos Andrés
- feat: refs #8124 Enrutadores nuevos requerimientos (origin/8124-enrutadoresNuevosRequerimientos) by:Carlos Andrés
- feat: refs #8127 entry_getCommission by:robert
- feat: refs #8127 quitar esquemas by:robert
- feat: refs #8135 refs#8135 updateTicketACL (origin/8135-ticketACL) by:sergiodt
- feat: refs #8143 deprecate recoverPass and sync from account.user by:ivanm
- feat: refs #8150 movExpeditions by:sergiodt
- feat: refs #8151 Added test by:guillermo
- feat: refs #8151 moveExpeditions by:guillermo
- feat: refs #8151 Requested changes by:guillermo
- feat(Supplier): refs #6828 add companySize by:alexm
- refactor: refs #7641 entry report style by:jorgep
### Changed 📦
- refactor: refs #6920 add correct role by:alexm
- refactor: refs #7242 Deleted select column by:guillermo
- refactor: refs #7457 Added from param if not exists by:guillermo
- refactor: refs #7641 entry report style by:jorgep
- refactor: refs #7715 Deleted hasNewLabelMrwMethod column by:guillermo
- refactor: refs #7920 Fix tests by:guillermo
- refactor: refs #7920 Fix version by:guillermo
- refactor: refs #7920 itemShelvingLog by:guillermo
- refactor: refs #7920 Main change by:guillermo
- refactor: refs #7920 Major changes by:guillermo
- refactor: refs #7920 No changes in itemShelvingLog table by:guillermo
- refactor: refs #7920 Requested changes by:guillermo
- refactor: refs #7950 Created cmr model (7950-cmrModelUnify) by:guillermo
- refactor: refs #7950 Requested changes by:guillermo
- refactor: refs #8153 Optimized order_getTax by:guillermo
### Fixed 🛠️
- fix: clean deletes also zoneEvent range records by:jgallego
- fix: more data for fixture.before by:Pako
- fix: refs #4948 Tests by:guillermo
- fix: refs #6644 email and translations by:carlossa
- fix: refs #6818 add config by:jorgep
- fix: refs #6818 add defaultChannel by:jorgep
- fix: refs #6818 use right col type by:jorgep
- fix: refs #6869 use id as primaryKey by:jorgep
- fix: refs #7244 Added collection ACL by:guillermo
- fix: refs #7283 item filters by:carlossa
- fix: refs #7283 remove by:carlossa
- fix: refs #7283 remove tests by:carlossa
- fix: refs #7283 tback by:carlossa
- fix: refs #7323 add remaining fields (origin/7323-warfix-addRemainingFields) by:jorgep
- fix: refs #7457 add with on select to reduce by:pablone
- fix: refs #7457 empty commit for gitea by:pablone
- fix: refs #7457 error on empty from param and add translate by:pablone
- fix: refs #7457 remove group by calc time reduce bellow 1s by:pablone
- fix: refs #7457 remove translate and use param definition for restriction by:pablone
- fix: refs #7641 align columns by:jorgep
- fix: refs #7641 drop boilerplate code by:jorgep
- fix: refs #7920 refs#7920 itemShelvingLog by:sergiodt
- fix: refs #8153 Version by:guillermo
- revert cd7ed6987a88e00275b562d3248f368b6333620c by:Javier Segarra
# Version 24.38 - 2024-09-17 # Version 24.38 - 2024-09-17
### Added 🆕 ### Added 🆕

View File

@ -63,7 +63,8 @@ module.exports = Self => {
p.pickingOrder pickingOrder, p.pickingOrder pickingOrder,
iss.id itemShelvingSaleFk, iss.id itemShelvingSaleFk,
iss.isPicked, iss.isPicked,
iss.itemShelvingFk iss.itemShelvingFk,
st.code stateCode
FROM ticketCollection tc FROM ticketCollection tc
LEFT JOIN collection c ON c.id = tc.collectionFk LEFT JOIN collection c ON c.id = tc.collectionFk
JOIN sale s ON s.ticketFk = tc.ticketFk JOIN sale s ON s.ticketFk = tc.ticketFk
@ -77,6 +78,7 @@ module.exports = Self => {
LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN parking p ON p.id = sh.parkingFk
LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk
LEFT JOIN origin o ON o.id = i.originFk LEFT JOIN origin o ON o.id = i.originFk
LEFT JOIN state st ON st.id = sg.stateFk
WHERE tc.collectionFk = ? WHERE tc.collectionFk = ?
GROUP BY s.id, ish.id, p.code, p2.code GROUP BY s.id, ish.id, p.code, p2.code
UNION ALL UNION ALL
@ -104,7 +106,8 @@ module.exports = Self => {
p.pickingOrder, p.pickingOrder,
iss.id itemShelvingSaleFk, iss.id itemShelvingSaleFk,
iss.isPicked, iss.isPicked,
iss.itemShelvingFk iss.itemShelvingFk,
st.code stateCode
FROM sectorCollection sc FROM sectorCollection sc
JOIN sectorCollectionSaleGroup ss ON ss.sectorCollectionFk = sc.id JOIN sectorCollectionSaleGroup ss ON ss.sectorCollectionFk = sc.id
JOIN saleGroup sg ON sg.id = ss.saleGroupFk JOIN saleGroup sg ON sg.id = ss.saleGroupFk
@ -118,6 +121,7 @@ module.exports = Self => {
LEFT JOIN parking p ON p.id = sh.parkingFk LEFT JOIN parking p ON p.id = sh.parkingFk
LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk
LEFT JOIN origin o ON o.id = i.originFk LEFT JOIN origin o ON o.id = i.originFk
LEFT JOIN state st ON st.id = sg.stateFk
WHERE sc.id = ? WHERE sc.id = ?
AND sgd.saleGroupFk AND sgd.saleGroupFk
GROUP BY s.id, ish.id, p.code, p2.code`, [id, id], myOptions); GROUP BY s.id, ish.id, p.code, p2.code`, [id, id], myOptions);

View File

@ -22,7 +22,7 @@ module.exports = Self => {
const url = await Self.app.models.Url.findOne({ const url = await Self.app.models.Url.findOne({
where: { where: {
appName, appName,
environment: process.env.NODE_ENV || 'dev' environment: process.env.NODE_ENV || 'development'
} }
}); });
return url?.url; return url?.url;

View File

@ -14,9 +14,6 @@
}, },
"itemFk": { "itemFk": {
"type": "number" "type": "number"
},
"isChecked": {
"type": "boolean"
} }
} }
} }

View File

@ -4,7 +4,7 @@ USE `util`;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
INSERT INTO `version` VALUES ('vn-database','11311','315864403260623fede9f0471ef3d9036faf23b1','2024-11-12 08:00:59','11336'); INSERT INTO `version` VALUES ('vn-database','11358','45f7b60f1b43b24505a3e9abc6738dc484ad4fd5','2024-11-26 12:27:58','11365');
INSERT INTO `versionLog` VALUES ('vn-database','10107','00-firstScript.sql','jenkins@10.0.2.69','2022-04-23 10:53:53',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','10107','00-firstScript.sql','jenkins@10.0.2.69','2022-04-23 10:53:53',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','10112','00-firstScript.sql','jenkins@10.0.2.69','2022-05-09 09:14:53',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','10112','00-firstScript.sql','jenkins@10.0.2.69','2022-05-09 09:14:53',NULL,NULL);
@ -1065,11 +1065,50 @@ INSERT INTO `versionLog` VALUES ('vn-database','11290','00-firstScript.sql','jen
INSERT INTO `versionLog` VALUES ('vn-database','11291','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-17 09:10:30',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11291','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-17 09:10:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11294','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:37',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11294','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:37',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11295','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-10 08:45:13',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11295','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-10 08:45:13',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11297','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:29',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11297','01-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11298','00-closure.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:37',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11298','00-closure.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:37',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11300','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-18 08:27:05',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11300','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-18 08:27:05',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11302','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:57',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11302','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:57',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11308','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-23 12:41:55',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11308','00-firstScript.sql','jenkins@db-proxy1.servers.dc.verdnatura.es','2024-10-23 12:41:55',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11311','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:57',NULL,NULL); INSERT INTO `versionLog` VALUES ('vn-database','11311','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 08:00:57',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11314','00-restrictedAsterisk.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11315','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11316','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11317','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11319','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11321','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11324','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-13 10:49:47',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11325','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11326','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11330','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11331','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11336','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11337','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11338','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-12 09:14:12',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11339','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:05:30',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11342','00-itemShelving.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:06:34',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11342','01-itemShelving.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:06:35',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11342','02-itemShelving.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:06:37',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11342','03-itemShelving.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:11:07',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11342','04-itemShelvingLog.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:11:07',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11342','05-itemShelvingLog.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:11:07',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11342','06-itemShelvingLog.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:11:07',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11343','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:11:07',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11344','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-13 17:36:45',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11344','01-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-13 17:46:26',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11345','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:11:08',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11346','00-address.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:15:02',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11346','01-client.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:16:29',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11346','02-supplier.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:27:57',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11347','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:27:57',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11348','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:28:14',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11349','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:28:14',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11350','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:28:14',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11353','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:28:14',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11355','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:28:14',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11357','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:28:16',NULL,NULL);
INSERT INTO `versionLog` VALUES ('vn-database','11358','00-firstScript.sql','jenkins@db-proxy2.servers.dc.verdnatura.es','2024-11-26 07:28:21',NULL,NULL);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
@ -1973,13 +2012,11 @@ INSERT INTO `ACL` VALUES (605,'Ticket','sendSms','WRITE','ALLOW','ROLE','employe
INSERT INTO `ACL` VALUES (606,'Ticket','isLocked','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (606,'Ticket','isLocked','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (607,'Ticket','freightCost','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (607,'Ticket','freightCost','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (608,'Ticket','getComponentsSum','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','delivery',NULL); INSERT INTO `ACL` VALUES (609,'Ticket','updateAttributes','WRITE','ALLOW','ROLE','deliveryAssistant',10578);
INSERT INTO `ACL` VALUES (610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (610,'Ticket','deliveryNoteCsv','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (611,'State','find','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (611,'State','find','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (612,'State','findById','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (612,'State','findById','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (613,'State','findOne','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (613,'State','findOne','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (614,'Worker','find','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (616,'Worker','findOne','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (617,'Worker','filter','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (617,'Worker','filter','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (618,'Worker','getWorkedHours','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (619,'Worker','active','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (619,'Worker','active','READ','ALLOW','ROLE','employee',NULL);
@ -2045,7 +2082,6 @@ INSERT INTO `ACL` VALUES (716,'ExpeditionMistake','*','WRITE','ALLOW','ROLE','em
INSERT INTO `ACL` VALUES (717,'WorkerMistake','*','WRITE','ALLOW','ROLE','coolerAssist',NULL); INSERT INTO `ACL` VALUES (717,'WorkerMistake','*','WRITE','ALLOW','ROLE','coolerAssist',NULL);
INSERT INTO `ACL` VALUES (718,'MistakesTypes','*','WRITE','ALLOW','ROLE','coolerAssist',NULL); INSERT INTO `ACL` VALUES (718,'MistakesTypes','*','WRITE','ALLOW','ROLE','coolerAssist',NULL);
INSERT INTO `ACL` VALUES (719,'MistakeType','*','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (719,'MistakeType','*','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (720,'MachineWorker','*','READ','ALLOW','ROLE','coolerAssist',NULL);
INSERT INTO `ACL` VALUES (721,'Printer','*','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (721,'Printer','*','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (722,'SaleMistake','*','WRITE','ALLOW','ROLE','production',NULL); INSERT INTO `ACL` VALUES (722,'SaleMistake','*','WRITE','ALLOW','ROLE','production',NULL);
INSERT INTO `ACL` VALUES (723,'Item','setVisibleDiscard','WRITE','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (723,'Item','setVisibleDiscard','WRITE','ALLOW','ROLE','employee',NULL);
@ -2083,13 +2119,10 @@ INSERT INTO `ACL` VALUES (755,'Route','findById','READ','ALLOW','ROLE','employee
INSERT INTO `ACL` VALUES (756,'Route','findOne','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (756,'Route','findOne','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (757,'Route','getRoutesByWorker','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (757,'Route','getRoutesByWorker','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (758,'Route','canViewAllRoute','READ','ALLOW','ROLE','deliveryAssistant',NULL); INSERT INTO `ACL` VALUES (758,'Route','canViewAllRoute','READ','ALLOW','ROLE','deliveryAssistant',NULL);
INSERT INTO `ACL` VALUES (759,'Route','cmr','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (760,'Cmr','downloadZip','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (761,'Route','downloadZip','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (761,'Route','downloadZip','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (762,'Route','filter','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (762,'Route','filter','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (763,'Route','getByWorker','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (763,'Route','getByWorker','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (764,'Route','getDeliveryPoint','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (764,'Route','getDeliveryPoint','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (765,'Route','cmrs','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (766,'Route','getSuggestedTickets','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (766,'Route','getSuggestedTickets','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (767,'Route','getTickets','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (767,'Route','getTickets','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (768,'Route','guessPriority','WRITE','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (768,'Route','guessPriority','WRITE','ALLOW','ROLE','employee',NULL);
@ -2130,7 +2163,6 @@ INSERT INTO `ACL` VALUES (802,'MailAliasAccount','deleteById','WRITE','ALLOW','R
INSERT INTO `ACL` VALUES (804,'DeviceProduction','*','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (804,'DeviceProduction','*','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (805,'Collection','assign','WRITE','ALLOW','ROLE','production',NULL); INSERT INTO `ACL` VALUES (805,'Collection','assign','WRITE','ALLOW','ROLE','production',NULL);
INSERT INTO `ACL` VALUES (806,'ExpeditionPallet','getPallet','READ','ALLOW','ROLE','production',NULL); INSERT INTO `ACL` VALUES (806,'ExpeditionPallet','getPallet','READ','ALLOW','ROLE','production',NULL);
INSERT INTO `ACL` VALUES (807,'MachineWorker','updateInTime','WRITE','ALLOW','ROLE','production',NULL);
INSERT INTO `ACL` VALUES (808,'MobileAppVersionControl','getVersion','READ','ALLOW','ROLE','employee',NULL); INSERT INTO `ACL` VALUES (808,'MobileAppVersionControl','getVersion','READ','ALLOW','ROLE','employee',NULL);
INSERT INTO `ACL` VALUES (809,'SaleTracking','delete','WRITE','ALLOW','ROLE','production',NULL); INSERT INTO `ACL` VALUES (809,'SaleTracking','delete','WRITE','ALLOW','ROLE','production',NULL);
INSERT INTO `ACL` VALUES (810,'SaleTracking','updateTracking','WRITE','ALLOW','ROLE','production',NULL); INSERT INTO `ACL` VALUES (810,'SaleTracking','updateTracking','WRITE','ALLOW','ROLE','production',NULL);
@ -2216,7 +2248,7 @@ INSERT INTO `ACL` VALUES (895,'ItemShelvingLog','*','READ','ALLOW','ROLE','produ
INSERT INTO `ACL` VALUES (901,'WorkerTimeControl','sendMail','WRITE','ALLOW','ROLE','system',NULL); INSERT INTO `ACL` VALUES (901,'WorkerTimeControl','sendMail','WRITE','ALLOW','ROLE','system',NULL);
INSERT INTO `ACL` VALUES (902,'Entry','filter','READ','ALLOW','ROLE','supplier',NULL); INSERT INTO `ACL` VALUES (902,'Entry','filter','READ','ALLOW','ROLE','supplier',NULL);
INSERT INTO `ACL` VALUES (903,'Entry','getBuys','READ','ALLOW','ROLE','supplier',NULL); INSERT INTO `ACL` VALUES (903,'Entry','getBuys','READ','ALLOW','ROLE','supplier',NULL);
INSERT INTO `ACL` VALUES (904,'Entry','buyLabel','READ','ALLOW','ROLE','supplier',NULL); INSERT INTO `ACL` VALUES (904,'Entry','buyLabelSupplier','READ','ALLOW','ROLE','supplier',10578);
INSERT INTO `ACL` VALUES (905,'AddressWaste','*','READ','ALLOW','ROLE','production',NULL); INSERT INTO `ACL` VALUES (905,'AddressWaste','*','READ','ALLOW','ROLE','production',NULL);
INSERT INTO `ACL` VALUES (906,'Entry','print','READ','ALLOW','ROLE','supplier',NULL); INSERT INTO `ACL` VALUES (906,'Entry','print','READ','ALLOW','ROLE','supplier',NULL);
INSERT INTO `ACL` VALUES (907,'Expedition_PrintOut','*','*','ALLOW','ROLE','production',NULL); INSERT INTO `ACL` VALUES (907,'Expedition_PrintOut','*','*','ALLOW','ROLE','production',NULL);
@ -2230,7 +2262,6 @@ INSERT INTO `ACL` VALUES (914,'VnToken','killSession','*','ALLOW','ROLE','develo
INSERT INTO `ACL` VALUES (915,'ACL','*','WRITE','ALLOW','ROLE','developerBoss',10578); INSERT INTO `ACL` VALUES (915,'ACL','*','WRITE','ALLOW','ROLE','developerBoss',10578);
INSERT INTO `ACL` VALUES (917,'InvoiceOut','refundAndInvoice','WRITE','ALLOW','ROLE','administrative',10578); INSERT INTO `ACL` VALUES (917,'InvoiceOut','refundAndInvoice','WRITE','ALLOW','ROLE','administrative',10578);
INSERT INTO `ACL` VALUES (918,'Worker','__get__descriptor','READ','ALLOW','ROLE','employee',10578); INSERT INTO `ACL` VALUES (918,'Worker','__get__descriptor','READ','ALLOW','ROLE','employee',10578);
INSERT INTO `ACL` VALUES (919,'Worker','findById','READ','ALLOW','ROLE','employee',10578);
INSERT INTO `ACL` VALUES (920,'QuadmindsApiConfig','*','*','ALLOW','ROLE','delivery',19295); INSERT INTO `ACL` VALUES (920,'QuadmindsApiConfig','*','*','ALLOW','ROLE','delivery',19295);
INSERT INTO `ACL` VALUES (922,'SaleGroup','*','WRITE','ALLOW','ROLE','production',19294); INSERT INTO `ACL` VALUES (922,'SaleGroup','*','WRITE','ALLOW','ROLE','production',19294);
INSERT INTO `ACL` VALUES (923,'Worker','__get__advancedSummary','READ','ALLOW','ROLE','hr',10578); INSERT INTO `ACL` VALUES (923,'Worker','__get__advancedSummary','READ','ALLOW','ROLE','hr',10578);
@ -2250,6 +2281,23 @@ INSERT INTO `ACL` VALUES (936,'Device','handleUser','*','ALLOW','ROLE','employee
INSERT INTO `ACL` VALUES (937,'WorkerTimeControlMail','count','READ','ALLOW','ROLE','employee',10578); INSERT INTO `ACL` VALUES (937,'WorkerTimeControlMail','count','READ','ALLOW','ROLE','employee',10578);
INSERT INTO `ACL` VALUES (938,'Worker','__get__mail','READ','ALLOW','ROLE','hr',10578); INSERT INTO `ACL` VALUES (938,'Worker','__get__mail','READ','ALLOW','ROLE','hr',10578);
INSERT INTO `ACL` VALUES (939,'Machine','*','*','ALLOW','ROLE','productionBoss',10578); INSERT INTO `ACL` VALUES (939,'Machine','*','*','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (940,'ItemTypeLog','find','READ','ALLOW','ROLE','employee',10578);
INSERT INTO `ACL` VALUES (941,'Entry','buyLabel','READ','ALLOW','ROLE','employee',10578);
INSERT INTO `ACL` VALUES (942,'Cmr','filter','READ','ALLOW','ROLE','production',10578);
INSERT INTO `ACL` VALUES (943,'Cmr','downloadZip','READ','ALLOW','ROLE','production',10578);
INSERT INTO `ACL` VALUES (944,'Cmr','print','READ','ALLOW','ROLE','production',10578);
INSERT INTO `ACL` VALUES (945,'Collection','create','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (946,'Collection','upsert','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (947,'Collection','replaceById','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (948,'Collection','updateAll','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (949,'Collection','updateAttributes','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (950,'Collection','deleteById','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (951,'Collection','destroyAll','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (952,'Collection','destroyById','WRITE','ALLOW','ROLE','productionBoss',10578);
INSERT INTO `ACL` VALUES (953,'RouteAction','find','READ','ALLOW','ROLE','delivery',10578);
INSERT INTO `ACL` VALUES (954,'RouteComplement','find','READ','ALLOW','ROLE','delivery',10578);
INSERT INTO `ACL` VALUES (955,'RouteComplement','create','WRITE','ALLOW','ROLE','delivery',10578);
INSERT INTO `ACL` VALUES (956,'RouteComplement','deleteById','WRITE','ALLOW','ROLE','delivery',10578);
INSERT INTO `fieldAcl` VALUES (1,'Client','name','update','employee'); INSERT INTO `fieldAcl` VALUES (1,'Client','name','update','employee');
INSERT INTO `fieldAcl` VALUES (2,'Client','contact','update','employee'); INSERT INTO `fieldAcl` VALUES (2,'Client','contact','update','employee');
@ -2581,13 +2629,13 @@ INSERT INTO `department` VALUES (1,'VN','VERDNATURA',1,116,763,0,0,0,0,26,NULL,'
INSERT INTO `department` VALUES (22,'shopping','COMPRAS',2,5,NULL,72,0,0,1,1,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (22,'shopping','COMPRAS',2,5,NULL,72,0,0,1,1,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (23,'CMA','CAMARA',15,16,NULL,72,1,1,2,0,37,'/1/37/',NULL,0,NULL,0,1,1,1,NULL,NULL,NULL,'PREVIOUS'); INSERT INTO `department` VALUES (23,'CMA','CAMARA',15,16,NULL,72,1,1,2,0,37,'/1/37/',NULL,0,NULL,0,1,1,1,NULL,NULL,NULL,'PREVIOUS');
INSERT INTO `department` VALUES (31,'it','INFORMATICA',6,7,NULL,72,0,0,1,0,1,'/1/','informatica-cau',1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (31,'it','INFORMATICA',6,7,NULL,72,0,0,1,0,1,'/1/','informatica-cau',1,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (34,'accounting','CONTABILIDAD',8,9,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (34,'accounting','CONTABILIDAD',8,9,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (35,'finance','FINANZAS',10,11,NULL,0,0,0,1,0,1,'/1/',NULL,1,'begonya@verdnatura.es',0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (35,'finance','FINANZAS',10,11,NULL,0,0,0,1,0,1,'/1/',NULL,1,'begonya@verdnatura.es',0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (36,'labor','LABORAL',12,13,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (36,'labor','LABORAL',12,13,NULL,0,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (37,'PROD','PRODUCCION',14,37,NULL,72,1,1,1,11,1,'/1/',NULL,0,NULL,0,1,1,1,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (37,'PROD','PRODUCCION',14,37,NULL,72,1,1,1,11,1,'/1/',NULL,0,NULL,0,1,1,1,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (38,'picking','SACADO',17,18,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,1,0,1,NULL,NULL,NULL,'ON_PREPARATION'); INSERT INTO `department` VALUES (38,'picking','SACADO',17,18,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,1,0,1,NULL,NULL,NULL,'ON_PREPARATION');
INSERT INTO `department` VALUES (39,'packing','ENCAJADO',19,20,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,'PACKING'); INSERT INTO `department` VALUES (39,'packing','ENCAJADO',19,20,NULL,72,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,'PACKING');
INSERT INTO `department` VALUES (41,'administration','ADMINISTRACION',38,39,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (41,'administration','ADMINISTRACION',38,39,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,1,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (43,'VT','VENTAS',40,75,NULL,0,0,0,1,17,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (43,'VT','VENTAS',40,75,NULL,0,0,0,1,17,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (44,'management','GERENCIA',76,77,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (44,'management','GERENCIA',76,77,NULL,72,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (45,'logistic','LOGISTICA',78,79,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (45,'logistic','LOGISTICA',78,79,NULL,72,0,0,1,0,1,'/1/',NULL,1,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
@ -2630,7 +2678,7 @@ INSERT INTO `department` VALUES (135,'routers','ENRUTADORES',110,111,NULL,0,0,0,
INSERT INTO `department` VALUES (136,'heavyVehicles','VEHICULOS PESADOS',112,113,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (136,'heavyVehicles','VEHICULOS PESADOS',112,113,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (137,'sorter','SORTER',114,115,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (137,'sorter','SORTER',114,115,NULL,0,0,0,1,0,1,'/1/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (139,'spainTeam4','EQUIPO ESPAÑA 4',67,68,3803,0,0,0,2,0,43,'/1/43/','es4_equipo',1,'es4@verdnatura.es',0,0,0,0,NULL,NULL,'5400',NULL); INSERT INTO `department` VALUES (139,'spainTeam4','EQUIPO ESPAÑA 4',67,68,3803,0,0,0,2,0,43,'/1/43/','es4_equipo',1,'es4@verdnatura.es',0,0,0,0,NULL,NULL,'5400',NULL);
INSERT INTO `department` VALUES (140,'internationalTeam','EQUIPO INTERNACIONAL',69,70,33320,0,0,0,2,0,43,'/1/43/','int_equipo',1,'international@verdnatura.es',0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (140,'internationalTeam','EQUIPO INTERNACIONAL',69,70,24065,0,0,0,2,0,43,'/1/43/','int_equipo',1,'international@verdnatura.es',0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (141,NULL,'PREVIA',35,36,NULL,0,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,'PREVIOUS'); INSERT INTO `department` VALUES (141,NULL,'PREVIA',35,36,NULL,0,1,0,2,0,37,'/1/37/',NULL,0,NULL,0,0,0,1,NULL,NULL,NULL,'PREVIOUS');
INSERT INTO `department` VALUES (146,NULL,'VERDNACOLOMBIA',3,4,NULL,72,0,0,2,0,22,'/1/22/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL); INSERT INTO `department` VALUES (146,NULL,'VERDNACOLOMBIA',3,4,NULL,72,0,0,2,0,22,'/1/22/',NULL,0,NULL,0,0,0,0,NULL,NULL,NULL,NULL);
INSERT INTO `department` VALUES (147,'spainTeamAsia','EQUIPO ESPAÑA ASIA',71,72,40214,0,0,0,2,0,43,'/1/43/','esA_equipo',0,'esA@verdnatura.es',0,0,0,0,NULL,NULL,'5500',NULL); INSERT INTO `department` VALUES (147,'spainTeamAsia','EQUIPO ESPAÑA ASIA',71,72,40214,0,0,0,2,0,43,'/1/43/','esA_equipo',0,'esA@verdnatura.es',0,0,0,0,NULL,NULL,'5500',NULL);

View File

@ -49,6 +49,7 @@ INSERT IGNORE INTO `db` VALUES ('','geo','developerBoss','Y','Y','Y','Y','N','N'
INSERT IGNORE INTO `db` VALUES ('','floranet','developer','Y','Y','Y','Y','N','N','N','N','N','N','N','N','N','N','N','N','Y','N','N','N'); INSERT IGNORE INTO `db` VALUES ('','floranet','developer','Y','Y','Y','Y','N','N','N','N','N','N','N','N','N','N','N','N','Y','N','N','N');
INSERT IGNORE INTO `db` VALUES ('','tmp','guest','Y','Y','Y','Y','N','Y','N','N','N','N','Y','N','N','N','N','N','N','N','N','N'); INSERT IGNORE INTO `db` VALUES ('','tmp','guest','Y','Y','Y','Y','N','Y','N','N','N','N','Y','N','N','N','N','N','N','N','N','N');
INSERT IGNORE INTO `db` VALUES ('','util','salix','Y','Y','Y','Y','N','N','N','N','N','N','Y','N','N','N','N','N','Y','N','N','N'); INSERT IGNORE INTO `db` VALUES ('','util','salix','Y','Y','Y','Y','N','N','N','N','N','N','Y','N','N','N','N','N','Y','N','N','N');
INSERT IGNORE INTO `db` VALUES ('','srt','maintenanceBoss','Y','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N');
INSERT IGNORE INTO `db` VALUES ('','dipole','developerBoss','Y','Y','Y','Y','N','N','Y','N','N','N','N','N','N','N','N','N','Y','N','N','N'); INSERT IGNORE INTO `db` VALUES ('','dipole','developerBoss','Y','Y','Y','Y','N','N','Y','N','N','N','N','N','N','N','N','N','Y','N','N','N');
INSERT IGNORE INTO `db` VALUES ('','bi','developerBoss','Y','Y','Y','Y','N','N','Y','N','N','N','N','N','N','N','N','N','Y','N','N','N'); INSERT IGNORE INTO `db` VALUES ('','bi','developerBoss','Y','Y','Y','Y','N','N','Y','N','N','N','N','N','N','N','N','N','Y','N','N','N');
INSERT IGNORE INTO `db` VALUES ('','sage','developerBoss','Y','Y','Y','Y','N','N','Y','N','N','N','N','N','N','N','N','N','Y','N','N','N'); INSERT IGNORE INTO `db` VALUES ('','sage','developerBoss','Y','Y','Y','Y','N','N','Y','N','N','N','N','N','N','N','N','N','Y','N','N','N');
@ -941,7 +942,6 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','volumeConfig','alex
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','coolerBoss','ticketTrackingState','alexm@%','0000-00-00 00:00:00','Select,Insert,Update',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','coolerBoss','ticketTrackingState','alexm@%','0000-00-00 00:00:00','Select,Insert,Update','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','warehouse','alexm@%','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','warehouse','alexm@%','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','role','alexm@%','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','role','alexm@%','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','hr','workCenter','alexm@%','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','clientCredit','juan@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','clientCredit','juan@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','worker','alexm@%','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','worker','alexm@%','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','coolerAssist','workerAppTester','alexm@%','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','coolerAssist','workerAppTester','alexm@%','0000-00-00 00:00:00','Select','');
@ -1246,7 +1246,6 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','bs','deliveryAssistant','m3','alexm
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','ticketDms','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','ticketDms','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','time','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','time','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryAssistant','v_Articles_botanical','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','deliveryAssistant','v_Articles_botanical','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','workCenter','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','workerDepartment','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','workerDepartment','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','zoneEvent','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryAssistant','zoneEvent','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','bi','deliveryAssistant','rotacion','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','bi','deliveryAssistant','rotacion','alexm@db-proxy2.static.verdnatura.es','0000-00-00 00:00:00','Select','');
@ -1388,7 +1387,7 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','administrative','entry','jenki
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','Cubos_Retorno','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','Cubos_Retorno','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','claimDestination','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','claimDestination','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','entryConfig','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','entryConfig','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','administrative','farmingDeliveryNote','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','administrative','farmingDeliveryNote','carlosap@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','sage','grafana','TiposIva','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','sage','grafana','TiposIva','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','bs','buyer','waste','alexm@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','bs','buyer','waste','alexm@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','clientObservation','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','clientObservation','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
@ -1419,13 +1418,9 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','financialBoss','accountDetail'
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','adminOfficer','accountDetail','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Update',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','adminOfficer','accountDetail','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Update','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','maintenanceBoss','project','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','maintenanceBoss','project','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','maintenanceBoss','machineDetail','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','maintenanceBoss','machineDetail','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','antenna','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyerSalesAssistant','route','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Update','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','bufferPool','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','employee','workCenter','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','enteringLog','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyerSalesAssistant','Rutas','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Update','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','expeditionLoading','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','failureLog','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','movingLog','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','sorterLog','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','genericAllocation','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','buyer','genericAllocation','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','hr','businessReasonEnd','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','hr','businessReasonEnd','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','buy_edi','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn2008','buyer','buy_edi','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
@ -1463,7 +1458,7 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryBoss','vehicleDms','gu
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryBoss','vehicleInvoiceIn','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryBoss','vehicleInvoiceIn','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryBoss','vehicleNotes','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','deliveryBoss','vehicleNotes','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','production','saleGroup','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Insert,Update,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','production','saleGroup','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','srt','maintenanceBoss','bufferLog','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','shelvingLog','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','financialBoss','supplierAccount','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Insert,Update,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','financialBoss','supplierAccount','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','productionAssi','tillSerial','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','productionAssi','tillSerial','alexm@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','stockBuyed','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','stockBuyed','guillermo@db-proxy1.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
@ -1494,6 +1489,7 @@ INSERT IGNORE INTO `tables_priv` VALUES ('','vn','logisticAssist','itemStemTag',
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','logisticAssist','itemBaseTag','jenkins@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','logisticAssist','itemBaseTag','jenkins@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','logisticAssist','itemBreederTag','jenkins@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','logisticAssist','itemBreederTag','jenkins@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','itemShelvingLog','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select',''); INSERT IGNORE INTO `tables_priv` VALUES ('','vn','grafana','itemShelvingLog','guillermo@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select','');
INSERT IGNORE INTO `tables_priv` VALUES ('','vn','logisticAssist','itemTextureTag','jenkins@db-proxy2.servers.dc.verdnatura.es','0000-00-00 00:00:00','Select,Insert,Update,Delete','');
/*!40000 ALTER TABLE `tables_priv` ENABLE KEYS */; /*!40000 ALTER TABLE `tables_priv` ENABLE KEYS */;
/*!40000 ALTER TABLE `columns_priv` DISABLE KEYS */; /*!40000 ALTER TABLE `columns_priv` DISABLE KEYS */;
@ -1873,6 +1869,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','claimManager','buy_getVolumeByE
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','buy_getVolumeByEntry','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','buy_getVolumeByEntry','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','entry_moveNotPrinted','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','entry_moveNotPrinted','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','buy_getVolume','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','buy_getVolume','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','stockBuyedByWorker','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','buy_getsplit','PROCEDURE','juan@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','buy_getsplit','PROCEDURE','juan@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','salesAssistant','subordinategetlist','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','salesAssistant','subordinategetlist','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','buy_afterUpsert','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','buy_afterUpsert','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
@ -1925,7 +1922,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','util','grafana','firstdayofyear','FU
INSERT IGNORE INTO `procs_priv` VALUES ('','util','claimManager','dayend','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','util','claimManager','dayend','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','util','employee','log_add','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','util','employee','log_add','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','srt','employee','moving_between','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','srt','employee','moving_between','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','bi','financial','defaultersfromdate','PROCEDURE','juan@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','bi','financial','defaultersfromdate','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','getuser','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','getuser','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','hasanynegativebase','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','hasanynegativebase','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','marketingBoss','hasanynegativebase','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','marketingBoss','hasanynegativebase','FUNCTION','alexm@%','Execute','0000-00-00 00:00:00');
@ -2020,6 +2017,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','hr','logshow','PROCEDURE','alex
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyerBoss','supplierpackaging_reportsource','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyerBoss','supplierpackaging_reportsource','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','financialBoss','supplierexpenses','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','financialBoss','supplierexpenses','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','grafana','firstdayofweek','FUNCTION','juan@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','grafana','firstdayofweek','FUNCTION','juan@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','buyer','stockBuyed_add','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','mail_insert','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','mail_insert','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','duaParcialMake','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','administrative','duaParcialMake','PROCEDURE','alexm@%','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','palletizerBoss','packingsite_startcollection','PROCEDURE','alexm@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','palletizerBoss','packingsite_startcollection','PROCEDURE','alexm@db-proxy2.static.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -2099,7 +2097,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','collection_printst
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','deviceproductionuser_getworker','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','deviceproductionuser_getworker','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','ticket_printlabelprevious','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','ticket_printlabelprevious','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','ticket_isoutclosurezone','FUNCTION','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','ticket_isoutclosurezone','FUNCTION','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','workermachinery_isregistered','FUNCTION','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','ticketstatetoday_setstate','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','ticketstatetoday_setstate','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','device_checklogin','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','device_checklogin','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','worker_getfromhasmistake','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','worker_getfromhasmistake','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -2107,7 +2104,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','sectorcollection_n
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','sectorcollection_get','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','sectorcollection_get','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','setparking','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','setparking','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','shelvingparking_get','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','shelvingparking_get','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','machine_getworkerplate','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','employee','report_print','PROCEDURE','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','saletracking_addprevok','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','saletracking_addprevok','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','sectorcollectionsalegroup_add','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','sectorcollectionsalegroup_add','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','saletracking_updateischecked','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','saletracking_updateischecked','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -2116,7 +2113,7 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','travel_updatepacki
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','freelance_getinfo','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','freelance_getinfo','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','company_getfiscaldata','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','company_getfiscaldata','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','expedition_getfromroute','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','expedition_getfromroute','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','machineworker_gethistorical','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','buy_getUltimate','FUNCTION','guillermo@db-proxy2.servers.dc.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemplacementsupplyaiming','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','itemplacementsupplyaiming','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','expeditionstate_addbypallet','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','production','expeditionstate_addbypallet','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','srt','production','expeditionloading_add','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','srt','production','expeditionloading_add','PROCEDURE','alexm@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -2150,7 +2147,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','collection_printstic
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','deviceproductionuser_getworker','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','deviceproductionuser_getworker','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','ticket_printlabelprevious','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','ticket_printlabelprevious','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','ticket_isoutclosurezone','FUNCTION','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','ticket_isoutclosurezone','FUNCTION','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','workermachinery_isregistered','FUNCTION','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','ticketstatetoday_setstate','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','ticketstatetoday_setstate','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','device_checklogin','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','device_checklogin','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','worker_getfromhasmistake','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','worker_getfromhasmistake','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -2158,7 +2154,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','sectorcollection_new
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','sectorcollection_get','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','sectorcollection_get','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','setparking','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','setparking','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','shelvingparking_get','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','shelvingparking_get','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','machine_getworkerplate','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','saletracking_addprevok','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','saletracking_addprevok','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','sectorcollectionsalegroup_add','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','sectorcollectionsalegroup_add','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','saletracking_updateischecked','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','saletracking_updateischecked','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -2167,7 +2162,6 @@ INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','travel_updatepacking
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','freelance_getinfo','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','freelance_getinfo','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','company_getfiscaldata','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','company_getfiscaldata','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','expedition_getfromroute','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','expedition_getfromroute','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','machineworker_gethistorical','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','itemplacementsupplyaiming','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','itemplacementsupplyaiming','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','expeditionstate_addbypallet','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','vn','delivery','expeditionstate_addbypallet','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
INSERT IGNORE INTO `procs_priv` VALUES ('','srt','delivery','expeditionloading_add','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00'); INSERT IGNORE INTO `procs_priv` VALUES ('','srt','delivery','expeditionloading_add','PROCEDURE','guillermo@db-proxy1.static.verdnatura.es','Execute','0000-00-00 00:00:00');
@ -2257,6 +2251,7 @@ INSERT IGNORE INTO `global_priv` VALUES ('','assetManager','{\"access\":0,\"vers
INSERT IGNORE INTO `global_priv` VALUES ('','buyer','{\"access\": 0, \"version_id\": 101106, \"is_role\": true}'); INSERT IGNORE INTO `global_priv` VALUES ('','buyer','{\"access\": 0, \"version_id\": 101106, \"is_role\": true}');
INSERT IGNORE INTO `global_priv` VALUES ('','buyerAssistant','{\"access\":0,\"version_id\":101106,\"is_role\":true}'); INSERT IGNORE INTO `global_priv` VALUES ('','buyerAssistant','{\"access\":0,\"version_id\":101106,\"is_role\":true}');
INSERT IGNORE INTO `global_priv` VALUES ('','buyerBoss','{\"access\": 0, \"version_id\": 101106, \"is_role\": true}'); INSERT IGNORE INTO `global_priv` VALUES ('','buyerBoss','{\"access\": 0, \"version_id\": 101106, \"is_role\": true}');
INSERT IGNORE INTO `global_priv` VALUES ('','buyerSalesAssistant','{\"access\":0,\"version_id\":101106,\"is_role\":true}');
INSERT IGNORE INTO `global_priv` VALUES ('','claimManager','{\"access\":0,\"version_id\":101106,\"is_role\":true}'); INSERT IGNORE INTO `global_priv` VALUES ('','claimManager','{\"access\":0,\"version_id\":101106,\"is_role\":true}');
INSERT IGNORE INTO `global_priv` VALUES ('','cooler','{\"access\":0,\"version_id\":101106,\"is_role\":true}'); INSERT IGNORE INTO `global_priv` VALUES ('','cooler','{\"access\":0,\"version_id\":101106,\"is_role\":true}');
INSERT IGNORE INTO `global_priv` VALUES ('','coolerAssist','{\"access\":0,\"version_id\":100707,\"is_role\":true}'); INSERT IGNORE INTO `global_priv` VALUES ('','coolerAssist','{\"access\":0,\"version_id\":100707,\"is_role\":true}');

File diff suppressed because it is too large Load Diff

View File

@ -875,7 +875,7 @@ BEGIN
b.stickers = NEW.NumberOfUnits b.stickers = NEW.NumberOfUnits
WHERE i.supplyResponseFk = NEW.ID WHERE i.supplyResponseFk = NEW.ID
AND am.name = 'LOGIFLORA' AND am.name = 'LOGIFLORA'
AND e.isRaid AND tr.isRaid
AND tr.landed >= util.VN_CURDATE(); AND tr.landed >= util.VN_CURDATE();
END */;; END */;;
@ -1460,6 +1460,9 @@ DELIMITER ;;
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
IF NEW.`property` = '*' THEN
CALL util.throw('The property field cannot be *');
END IF;
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -2000,6 +2003,7 @@ BEGIN
DECLARE vIsEqualizated BOOL; DECLARE vIsEqualizated BOOL;
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
SET NEW.geoFk = address_getGeo(NEW.id);
IF (NEW.phone <> '') THEN IF (NEW.phone <> '') THEN
CALL pbx.phone_isValid(NEW.phone); CALL pbx.phone_isValid(NEW.phone);
@ -2036,7 +2040,6 @@ DELIMITER ;;
BEFORE UPDATE ON `address` BEFORE UPDATE ON `address`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
IF !(NEW.phone <=> OLD.phone) AND (NEW.phone <> '') THEN IF !(NEW.phone <=> OLD.phone) AND (NEW.phone <> '') THEN
@ -2047,6 +2050,11 @@ BEGIN
CALL pbx.phone_isValid(NEW.mobile); CALL pbx.phone_isValid(NEW.mobile);
END IF; END IF;
IF NOT (NEW.provinceFk <=> OLD.provinceFk)
OR (NEW.postalCode <=> OLD.postalCode) THEN
SET NEW.geoFk = address_getGeo(NEW.id);
END IF;
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -3423,8 +3431,10 @@ DELIMITER ;;
BEFORE INSERT ON `client` BEFORE INSERT ON `client`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
SET NEW.accountingAccount = 4300000000 + NEW.id;
SET NEW.lastSalesPersonFk = NEW.salesPersonFk;
SET NEW.geoFk = client_getGeo(NEW.id);
IF (NEW.phone <> '') THEN IF (NEW.phone <> '') THEN
CALL pbx.phone_isValid(NEW.phone); CALL pbx.phone_isValid(NEW.phone);
@ -3433,10 +3443,6 @@ BEGIN
IF (NEW.mobile <> '') THEN IF (NEW.mobile <> '') THEN
CALL pbx.phone_isValid(NEW.mobile); CALL pbx.phone_isValid(NEW.mobile);
END IF; END IF;
SET NEW.accountingAccount = 4300000000 + NEW.id;
SET NEW.lastSalesPersonFk = NEW.salesPersonFk;
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -3550,6 +3556,12 @@ BEGIN
IF NOT (NEW.businessTypeFk <=> OLD.businessTypeFk) AND (NEW.businessTypeFk = 'individual' OR OLD.businessTypeFk = 'individual') THEN IF NOT (NEW.businessTypeFk <=> OLD.businessTypeFk) AND (NEW.businessTypeFk = 'individual' OR OLD.businessTypeFk = 'individual') THEN
SET NEW.isTaxDataChecked = 0; SET NEW.isTaxDataChecked = 0;
END IF; END IF;
IF NOT (NEW.provinceFk <=> OLD.provinceFk)
OR (NEW.postcode <=> OLD.postcode) THEN
SET NEW.geoFk = client_getGeo(NEW.id);
END IF;
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -4960,7 +4972,7 @@ DELIMITER ;;
BEFORE UPDATE ON `entry` BEFORE UPDATE ON `entry`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
DECLARE vIsVirtual BOOL; DECLARE vIsRaid BOOL;
DECLARE vPrintedCount INT; DECLARE vPrintedCount INT;
DECLARE vHasDistinctWarehouses BOOL; DECLARE vHasDistinctWarehouses BOOL;
DECLARE vTotalBuy INT; DECLARE vTotalBuy INT;
@ -4995,17 +5007,19 @@ BEGIN
CALL travel_throwAwb(NEW.travelFk); CALL travel_throwAwb(NEW.travelFk);
END IF; END IF;
SELECT COUNT(*) > 0 INTO vIsVirtual SELECT t.isRaid INTO vIsRaid
FROM entryVirtual WHERE entryFk = NEW.id; FROM travel t
JOIN entry e ON e.travelFk = t.id
WHERE e.id = NEW.id;
SELECT NOT (o.warehouseInFk <=> n.warehouseInFk) SELECT NOT (o.warehouseInFk <=> n.warehouseInFk)
OR NOT (o.warehouseOutFk <=> n.warehouseOutFk) OR NOT (o.warehouseOutFk <=> n.warehouseOutFk)
INTO vHasDistinctWarehouses INTO vHasDistinctWarehouses
FROM travel o, travel n FROM travel o, travel n
WHERE o.id = OLD.travelFk WHERE o.id = OLD.travelFk
AND n.id = NEW.travelFk; AND n.id = NEW.travelFk;
IF vIsVirtual AND vHasDistinctWarehouses THEN IF vIsRaid AND vHasDistinctWarehouses THEN
SIGNAL SQLSTATE '45000' SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'A cloned entry cannot be moved to a travel with different warehouses'; SET MESSAGE_TEXT = 'A cloned entry cannot be moved to a travel with different warehouses';
END IF; END IF;
@ -5326,6 +5340,7 @@ BEGIN
FROM expedition e WHERE e.ticketFk = OLD.ticketFk and e.freightItemFk) FROM expedition e WHERE e.ticketFk = OLD.ticketFk and e.freightItemFk)
WHERE t.id = OLD.ticketFk; WHERE t.id = OLD.ticketFk;
CALL expedition_selfConsumptionPackaging(OLD.id, 'remove');
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -6909,10 +6924,31 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;; DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`itemType_beforeInsert`
BEFORE INSERT ON `itemType`
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb4 */ ;
/*!50003 SET character_set_results = utf8mb4 */ ;
/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`itemType_beforeUpdate` /*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`itemType_beforeUpdate`
BEFORE UPDATE ON `itemType` BEFORE UPDATE ON `itemType`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
SET NEW.editorFk = account.myUser_getId();
IF NEW.itemPackingTypeFk = '' THEN IF NEW.itemPackingTypeFk = '' THEN
SET NEW.itemPackingTypeFk = NULL; SET NEW.itemPackingTypeFk = NULL;
@ -6939,6 +6975,30 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;; DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`itemType_afterDelete`
AFTER DELETE ON `itemType`
FOR EACH ROW
BEGIN
INSERT INTO itemTypeLog
SET `action` = 'delete',
`changedModel` = 'ItemType',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb4 */ ;
/*!50003 SET character_set_results = utf8mb4 */ ;
/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`machine_beforeInsert` /*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`machine_beforeInsert`
BEFORE INSERT ON `machine` BEFORE INSERT ON `machine`
FOR EACH ROW FOR EACH ROW
@ -7584,7 +7644,7 @@ DELIMITER ;;
AFTER DELETE ON `productionConfig` AFTER DELETE ON `productionConfig`
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
INSERT INTO productionConfig INSERT INTO productionConfigLog
SET `action` = 'delete', SET `action` = 'delete',
`changedModel` = 'ProductionConfig', `changedModel` = 'ProductionConfig',
`changedModelId` = OLD.id, `changedModelId` = OLD.id,
@ -8187,7 +8247,8 @@ BEGIN
OR !(NEW.kmEnd <=> OLD.kmEnd) OR !(NEW.kmEnd <=> OLD.kmEnd)
OR !(NEW.workerFk <=> OLD.workerFk) OR !(NEW.workerFk <=> OLD.workerFk)
OR !(NEW.m3 <=> OLD.m3) OR !(NEW.m3 <=> OLD.m3)
OR !(NEW.agencyModeFk <=> OLD.agencyModeFk)THEN OR !(NEW.agencyModeFk <=> OLD.agencyModeFk)
OR !(NEW.vehicleFk <=> OLD.vehicleFk)THEN
CALL route_calcCommission(NEW.id); CALL route_calcCommission(NEW.id);
END IF; END IF;
@ -9086,6 +9147,7 @@ DELIMITER ;;
FOR EACH ROW FOR EACH ROW
BEGIN BEGIN
SET NEW.editorFk = account.myUser_getId(); SET NEW.editorFk = account.myUser_getId();
SET NEW.geoFk = supplier_getGeo(NEW.id);
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -9180,6 +9242,11 @@ BEGIN
SET NEW.isPayMethodChecked = FALSE; SET NEW.isPayMethodChecked = FALSE;
END IF; END IF;
IF NOT (NEW.provinceFk <=> OLD.provinceFk)
OR (NEW.postCode <=> OLD.postCode) THEN
SET NEW.geoFk = supplier_getGeo(NEW.id);
END IF;
END */;; END */;;
DELIMITER ; DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET sql_mode = @saved_sql_mode */ ;
@ -10501,28 +10568,6 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;; DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`town_beforeUpdate`
BEFORE UPDATE ON `town`
FOR EACH ROW
BEGIN
-- IF !(OLD.geoFk <=> NEW.geoFk) THEN
-- CALL zoneGeo_throwNotEditable;
-- END IF;
END */;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
/*!50003 SET character_set_results = @saved_cs_results */ ;
/*!50003 SET collation_connection = @saved_col_connection */ ;
/*!50003 SET @saved_cs_client = @@character_set_client */ ;
/*!50003 SET @saved_cs_results = @@character_set_results */ ;
/*!50003 SET @saved_col_connection = @@collation_connection */ ;
/*!50003 SET character_set_client = utf8mb4 */ ;
/*!50003 SET character_set_results = utf8mb4 */ ;
/*!50003 SET collation_connection = utf8mb4_unicode_ci */ ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'IGNORE_SPACE,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
/*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`town_afterUpdate` /*!50003 CREATE*/ /*!50017 DEFINER=`vn`@`localhost`*/ /*!50003 TRIGGER `vn`.`town_afterUpdate`
AFTER UPDATE ON `town` AFTER UPDATE ON `town`
FOR EACH ROW FOR EACH ROW
@ -10581,6 +10626,10 @@ BEGIN
CALL travel_checkWarehouseIsFeedStock(NEW.warehouseInFk); CALL travel_checkWarehouseIsFeedStock(NEW.warehouseInFk);
IF NEW.isRaid IS NOT NULL OR NEW.daysInForward IS NOT NULL THEN
CALL travel_checkRaid(NEW.isRaid, NEW.daysInForward);
END IF;
IF NEW.awbFk IS NOT NULL THEN IF NEW.awbFk IS NOT NULL THEN
CALL travel_throwAwb(NEW.id); CALL travel_throwAwb(NEW.id);
END IF; END IF;
@ -10620,6 +10669,10 @@ BEGIN
CALL travel_checkWarehouseIsFeedStock(NEW.warehouseInFk); CALL travel_checkWarehouseIsFeedStock(NEW.warehouseInFk);
END IF; END IF;
IF NOT (NEW.isRaid <=> OLD.isRaid) OR NOT (NEW.daysInForward <=> OLD.daysInForward) THEN
CALL travel_checkRaid(NEW.isRaid, NEW.daysInForward);
END IF;
IF NOT (NEW.awbFk <=> OLD.awbFk)THEN IF NOT (NEW.awbFk <=> OLD.awbFk)THEN
SELECT COUNT(*) INTO vHasAnyInvoiceBooked SELECT COUNT(*) INTO vHasAnyInvoiceBooked
FROM travel t FROM travel t
@ -11526,4 +11579,4 @@ USE `vn2008`;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2024-11-12 7:06:44 -- Dump completed on 2024-11-26 12:09:13

View File

@ -26,7 +26,7 @@ BEGIN
DECLARE vCursor CURSOR FOR DECLARE vCursor CURSOR FOR
SELECT it.taxableBase, SELECT it.taxableBase,
CAST((( it.taxableBase / 100) * t.PorcentajeIva) AS DECIMAL (10,2)), CAST(SUM((( it.taxableBase / 100) * t.PorcentajeIva)) AS DECIMAL (10,2)),
t.PorcentajeIva, t.PorcentajeIva,
it.transactionTypeSageFk, it.transactionTypeSageFk,
it.taxTypeSageFk, it.taxTypeSageFk,
@ -39,7 +39,8 @@ BEGIN
JOIN TiposTransacciones tt ON tt.CodigoTransaccion = it.transactionTypeSageFk JOIN TiposTransacciones tt ON tt.CodigoTransaccion = it.transactionTypeSageFk
LEFT JOIN vn.dua d ON d.id = vInvoiceInFk LEFT JOIN vn.dua d ON d.id = vInvoiceInFk
WHERE i.id = vInvoiceInFk WHERE i.id = vInvoiceInFk
AND d.id IS NULL; AND d.id IS NULL
GROUP BY it.taxTypeSageFk;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;

View File

@ -4,12 +4,12 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`expeditionScan_Put`(
vExpeditionFk INT vExpeditionFk INT
) )
BEGIN BEGIN
IF NOT (SELECT TRUE FROM expedition WHERE id = vExpeditionFk LIMIT 1) THEN IF NOT EXISTS (SELECT id FROM expeditionPallet WHERE id = vPalletFk) THEN
CALL util.throw('Expedition not exists'); CALL util.throw('Pallet not exists');
END IF; END IF;
IF NOT (SELECT TRUE FROM expeditionPallet WHERE id = vPalletFk LIMIT 1) THEN IF NOT EXISTS (SELECT id FROM expedition WHERE id = vExpeditionFk) THEN
CALL util.throw('Pallet not exists'); CALL util.throw('Expedition not exists');
END IF; END IF;
REPLACE expeditionScan(expeditionFk, palletFk) REPLACE expeditionScan(expeditionFk, palletFk)

View File

@ -3,7 +3,7 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`expedition_selfConsum
vSelf INT, vSelf INT,
vAction ENUM('add', 'remove') vAction ENUM('add', 'remove')
) )
BEGIN proc:BEGIN
/** /**
* Maneja el consumo de cajas para autoconsumo, permitiendo * Maneja el consumo de cajas para autoconsumo, permitiendo
* añadir o quitar cajas utilizadas según la acción indicada. * añadir o quitar cajas utilizadas según la acción indicada.
@ -37,14 +37,14 @@ BEGIN
vWarehouseFk, vWarehouseFk,
vCreated vCreated
FROM expedition e FROM expedition e
JOIN packaging p ON p.id = e.packagingFk LEFT JOIN packaging p ON p.id = e.packagingFk
JOIN item i ON i.id = p.itemFk LEFT JOIN item i ON i.id = p.itemFk
JOIN ticket t ON t.id = e.ticketFk JOIN ticket t ON t.id = e.ticketFk
JOIN productionConfig pc JOIN productionConfig pc
WHERE e.id = vSelf; WHERE e.id = vSelf;
IF vClientFk IS NULL OR vAddressFk IS NULL THEN IF vClientFk IS NULL OR vItemFk IS NULL THEN
CALL util.throw('Some config parameters are not set'); LEAVE proc;
END IF; END IF;
SET vCreated = DATE(vCreated); SET vCreated = DATE(vCreated);

View File

@ -219,7 +219,7 @@ BEGIN
) eWithheld ON TRUE ) eWithheld ON TRUE
WHERE tii.taxTypeSageFk IS NOT NULL WHERE tii.taxTypeSageFk IS NOT NULL
AND (tii.taxCode IS NULL OR tii.taxCode NOT IN ('import10', 'import21')) AND (tii.taxCode IS NULL OR tii.taxCode NOT IN ('import10', 'import21'))
GROUP BY tii.PorcentajeIva, tii.expenseFk; GROUP BY tii.CuentaIvaRepercutido;
-- Línea iva inversor sujeto pasivo -- Línea iva inversor sujeto pasivo
INSERT INTO XDiario( INSERT INTO XDiario(
@ -284,7 +284,7 @@ BEGIN
AND NOT(tii.isVies AND NOT(tii.isVies
AND c.nontaxableTransactionTypeFk = tii.transactionTypeSageFk AND c.nontaxableTransactionTypeFk = tii.transactionTypeSageFk
AND tii.taxCode = 'nonTaxable') AND tii.taxCode = 'nonTaxable')
GROUP BY tii.PorcentajeIva, tii.expenseFk; GROUP BY tii.CuentaIvaRepercutido;
-- Actualización del registro original -- Actualización del registro original
UPDATE invoiceIn ii UPDATE invoiceIn ii

View File

@ -11,6 +11,8 @@ BEGIN
*/ */
DECLARE vIsUpdatable, vIsFreelance BOOL DEFAULT 0; DECLARE vIsUpdatable, vIsFreelance BOOL DEFAULT 0;
DECLARE vAgencyModePricePercentage DOUBLE; DECLARE vAgencyModePricePercentage DOUBLE;
DECLARE vIsKmTruckRate BOOL;
DECLARE vCountryFk INT;
SELECT r.created >= rc.cutoffDated INTO vIsUpdatable SELECT r.created >= rc.cutoffDated INTO vIsUpdatable
FROM route r FROM route r
@ -21,10 +23,17 @@ BEGIN
DELETE FROM routeCommission DELETE FROM routeCommission
WHERE routeFk = vSelf; WHERE routeFk = vSelf;
SELECT w.isFreelance INTO vIsFreelance SELECT w.isFreelance, v.isKmTruckRate, p.countryFk INTO vIsFreelance, vIsKmTruckRate, vCountryFk
FROM route r FROM route r
JOIN worker w ON w.id = r.workerFk JOIN worker w ON w.id = r.workerFk
WHERE r.id = vSelf; JOIN vehicle v ON v.id = r.vehicleFk
LEFT JOIN ticket t ON t.routeFk = r.id
LEFT JOIN address a ON a.id = t.addressFk
LEFT JOIN province p ON p.id = a.provinceFk
WHERE r.id = vSelf
GROUP BY p.countryFk
ORDER BY COUNT(*) DESC
LIMIT 1;
SELECT ampp.percentage INTO vAgencyModePricePercentage SELECT ampp.percentage INTO vAgencyModePricePercentage
FROM route r FROM route r
@ -39,7 +48,9 @@ BEGIN
workCenterFk, workCenterFk,
freelanceYearlyM3, freelanceYearlyM3,
cat4m3, cat4m3,
cat5m3 cat5m3,
isKmTruckRate,
countryFk
) )
SELECT vSelf, SELECT vSelf,
r.commissionWorkCenterFk, r.commissionWorkCenterFk,
@ -51,11 +62,14 @@ BEGIN
IFNULL(r.m3, 0), IFNULL(r.m3, 0),
0 0
), ),
rc.distributionCat4M3 * IFNULL(r.m3, 0), IFNULL(wc.distributionCat4M3, rc.distributionCat4M3) * IFNULL(r.m3, 0),
rc.distributionCat5M3 * IFNULL(r.m3, 0) IFNULL(wc.distributionCat5M3, rc.distributionCat5M3) * IFNULL(r.m3, 0),
vIsKmTruckRate,
vCountryFk
FROM route r FROM route r
JOIN vehicle v ON v.id = r.vehicleFk JOIN vehicle v ON v.id = r.vehicleFk
JOIN routeConfig rc JOIN routeConfig rc
LEFT JOIN workCenterCommission wc ON wc.workCenterFk = r.commissionWorkCenterFk
WHERE r.id = vSelf WHERE r.id = vSelf
AND r.workerFk AND r.workerFk
AND r.commissionWorkCenterFk; AND r.commissionWorkCenterFk;
@ -68,21 +82,28 @@ BEGIN
yearlyKm, yearlyKm,
yearlyM3, yearlyM3,
cat4m3, cat4m3,
cat5m3 cat5m3,
isKmTruckRate,
countryFk
) )
SELECT vSelf, SELECT vSelf,
r.commissionWorkCenterFk, r.commissionWorkCenterFk,
(r.kmEnd - r.kmStart) * (r.kmEnd - r.kmStart) *
IF(v.isKmTruckRate, rc.kmHeavy, rc.kmLight), IF(v.isKmTruckRate, rc.kmHeavy, rc.kmLight),
IFNULL(r.m3, 0) * IFNULL(r.m3, 0) *
IF(v.isKmTruckRate, rc.deliveryM3Cat5, rc.deliveryM3Cat4), IF(v.isKmTruckRate,
IFNULL(wc.deliveryM3Cat5, rc.deliveryM3Cat5),
IFNULL(wc.deliveryM3Cat4, rc.deliveryM3Cat4)),
(r.kmEnd - r.kmStart) * rc.kmYearly, (r.kmEnd - r.kmStart) * rc.kmYearly,
IFNULL(r.m3, 0) * rc.m3Yearly, IFNULL(r.m3, 0) * rc.m3Yearly,
rc.distributionCat4M3 * IFNULL(r.m3, 0), IFNULL(wc.distributionCat4M3, rc.distributionCat4M3) * IFNULL(r.m3, 0),
rc.distributionCat5M3 * IFNULL(r.m3, 0) IFNULL(wc.distributionCat5M3, rc.distributionCat5M3) * IFNULL(r.m3, 0),
vIsKmTruckRate,
vCountryFk
FROM route r FROM route r
JOIN vehicle v ON v.id = r.vehicleFk JOIN vehicle v ON v.id = r.vehicleFk
JOIN routeConfig rc JOIN routeConfig rc
LEFT JOIN workCenterCommission wc ON wc.workCenterFk = r.commissionWorkCenterFk
WHERE r.id = vSelf WHERE r.id = vSelf
AND r.kmStart AND r.kmStart
AND r.kmEnd AND r.kmEnd

View File

@ -0,0 +1,51 @@
ALTER TABLE vn.routeCommission ADD IF NOT EXISTS countryFk mediumint(8) unsigned DEFAULT NULL NULL;
ALTER TABLE vn.routeCommission ADD IF NOT EXISTS isKmTruckRate TINYINT(1) DEFAULT NULL NULL;
ALTER TABLE vn.routeCommission DROP FOREIGN KEY IF EXISTS routeCommission_country_FK;
ALTER TABLE vn.routeCommission ADD CONSTRAINT routeCommission_country_FK FOREIGN KEY (countryFk)
REFERENCES vn.country(id) ON DELETE RESTRICT ON UPDATE CASCADE;
CREATE TABLE IF NOT EXISTS vn.workCenterCommission (
`workCenterFk` INT(11) NOT NULL,
`deliveryManAdjustment` DECIMAL(4,2) DEFAULT NULL
COMMENT 'Número de trabajadores para equilibrar los repartidores de diferentes centros.
Utilizado en repartidores de grafana',
`distributionM3Category1` decimal(5,2) DEFAULT NULL,
`distributionM3Category2` decimal(5,2) DEFAULT NULL,
`distributionCat4M3` DECIMAL(5,2) DEFAULT NULL
COMMENT 'Comisión por gestión de la distribución Cat IV',
`distributionCat5M3` DECIMAL(5,2) DEFAULT NULL
COMMENT 'Comisión por gestión de la distribución Cat V',
PRIMARY KEY (`workCenterFk`),
CONSTRAINT `workCenterCommission_workCenterFk` FOREIGN KEY (`workCenterFk`)
REFERENCES `workCenter` (`id`) ON UPDATE CASCADE ON DELETE RESTRICT
);
UPDATE vn.routeCommission rc
JOIN (SELECT id, countryFk, isKmTruckRate
FROM (SELECT r.id, c.countryFk, v.isKmTruckRate
FROM vn.route r
JOIN vn.routeCommission rc ON rc.routeFk = r.id
LEFT JOIN vn.ticket t ON t.routeFk = r.id
LEFT JOIN vn.client c ON c.id = t.clientFk
LEFT JOIN vn.vehicle v ON v.id = r.vehicleFk
WHERE r.created >= '2023-12-01'
GROUP BY r.id, c.countryFk
ORDER BY r.id, COUNT(*) DESC
LIMIT 100000000000
)sub
GROUP BY id
)sub ON sub.id = rc.routeFk
SET rc.isKmTruckRate = sub.isKmTruckRate,
rc.countryFk = sub.countryFk;
ALTER TABLE vn.workerDistributionCategory ADD IF NOT EXISTS countryFk mediumint(8) unsigned DEFAULT NULL NULL;
ALTER TABLE vn.workerDistributionCategory ADD IF NOT EXISTS isKmTruckRate TINYINT(1) DEFAULT NULL NULL;
ALTER TABLE vn.workerDistributionCategory DROP FOREIGN KEY IF EXISTS workerDistributionCategory_country_FK;
ALTER TABLE vn.workerDistributionCategory ADD CONSTRAINT workerDistributionCategory_country_FK FOREIGN KEY (countryFk)
REFERENCES vn.country(id) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE vn.workerDistributionCategory ADD IF NOT EXISTS commissionSplitWorkers INT UNSIGNED NOT NULL DEFAULT 1
COMMENT 'Número de enrutadores entr los que se reparte la comsión';

View File

@ -0,0 +1,8 @@
DELETE FROM vn.stateI18n
WHERE `name` IN ('Billed', 'Facturado', 'Assisted preparation', 'Preparación asistida', 'Shipped', 'Embarcado', 'Stowaway OK', 'Polizón OK');
UPDATE vn.`state` SET nextStateFk = 43
WHERE nextStateFk IN (11, 27, 30, 32, 41);
DELETE FROM vn.`state`
WHERE code IN ('INVOICED', 'ASSISTED_PREPARATION', 'BOARD', 'OK STOWAWAY', 'PARTIAL_PREPARATION');

View File

@ -0,0 +1,4 @@
INSERT INTO salix.ACL (model, property, accessType, permission, principalType, principalId)
VALUES('SaleGroup', 'find', 'READ', 'ALLOW', 'ROLE', 'production');

View File

@ -0,0 +1,7 @@
ALTER TABLE vn.workCenterCommission ADD IF NOT EXISTS deliveryM3Cat4 DECIMAL(5,2) DEFAULT NULL NULL;
ALTER TABLE vn.workCenterCommission ADD IF NOT EXISTS deliveryM3Cat5 DECIMAL(5,2) DEFAULT NULL NULL;
INSERT IGNORE INTO vn.workCenterCommission (workCenterFk, deliveryM3Cat4, deliveryM3Cat5)
VALUES (5,8.0,8.0);

View File

@ -0,0 +1,7 @@
ALTER TABLE `vn`.`creditInsurance` DROP COLUMN `creditClassification__`;
ALTER TABLE `vn`.`worker` DROP COLUMN `isF11Allowed__`;
ALTER TABLE `util`.`config` DROP COLUMN `dbVersion__`;
ALTER TABLE `util`.`config` DROP COLUMN `hasTriggersDisabled__`;
ALTER TABLE `vn`.`agencyMode` DROP COLUMN `showAgencyName__`;
DROP TABLE `account`.`accountLog__`;
DROP TABLE `vn`.`silexACL__`;

View File

@ -0,0 +1,133 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item summary path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'item');
});
afterAll(async() => {
await browser.close();
});
it('should search for an item', async() => {
await page.doSearch('Ranged weapon');
const resultsCount = await page.countElement(selectors.itemsIndex.searchResult);
await page.waitForTextInElement(selectors.itemsIndex.firstSearchResult, 'Ranged weapon');
await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton);
const isVisible = await page.isVisible(selectors.itemSummary.basicData);
expect(resultsCount).toBe(4);
expect(isVisible).toBeTruthy();
});
it(`should check the item summary preview shows fields from basic data`, async() => {
await page.waitForTextInElement(selectors.itemSummary.basicData, 'Ranged weapon longbow 200cm');
const result = await page.waitToGetProperty(selectors.itemSummary.basicData, 'innerText');
expect(result).toContain('Ranged weapon longbow 200cm');
});
it(`should check the item summary preview shows fields from tags`, async() => {
await page.waitForTextInElement(selectors.itemSummary.tags, 'Brown');
const result = await page.waitToGetProperty(selectors.itemSummary.tags, 'innerText');
expect(result).toContain('Brown');
});
it(`should check the item summary preview shows fields from botanical`, async() => {
await page.waitForTextInElement(selectors.itemSummary.botanical, 'Abelia');
const result = await page.waitToGetProperty(selectors.itemSummary.botanical, 'innerText');
expect(result).toContain('Abelia');
});
it(`should check the item summary preview shows fields from barcode`, async() => {
await page.waitForTextInElement(selectors.itemSummary.barcode, '1');
const result = await page.waitToGetProperty(selectors.itemSummary.barcode, 'innerText');
expect(result).toContain('1');
});
it(`should close the summary popup`, async() => {
await page.closePopup();
await page.waitForSelector(selectors.itemSummary.basicData, {hidden: true});
});
it('should search for other item', async() => {
await page.doSearch('Melee Reinforced');
const resultsCount = await page.countElement(selectors.itemsIndex.searchResult);
await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton);
await page.waitForSelector(selectors.itemSummary.basicData, {visible: true});
expect(resultsCount).toBe(3);
});
it(`should now check the item summary preview shows fields from basic data`, async() => {
await page.waitForTextInElement(selectors.itemSummary.basicData, 'Melee Reinforced weapon combat fist 15cm');
const result = await page.waitToGetProperty(selectors.itemSummary.basicData, 'innerText');
expect(result).toContain('Melee Reinforced weapon combat fist 15cm');
});
it(`should now check the item summary preview shows fields from tags`, async() => {
await page.waitForTextInElement(selectors.itemSummary.tags, 'Silver');
const result = await page.waitToGetProperty(selectors.itemSummary.tags, 'innerText');
expect(result).toContain('Silver');
});
it(`should now check the item summary preview shows fields from botanical`, async() => {
await page.waitForTextInElement(selectors.itemSummary.botanical, '-');
const result = await page.waitToGetProperty(selectors.itemSummary.botanical, 'innerText');
expect(result).toContain('-');
});
it(`should now close the summary popup`, async() => {
await page.closePopup();
await page.waitForSelector(selectors.itemSummary.basicData, {hidden: true});
});
it(`should navigate to one of the items detailed section`, async() => {
await page.accessToSearchResult('Melee weapon combat fist 15cm');
await page.waitForState('item.card.summary');
});
it(`should check the descritor edit button is not visible for employee`, async() => {
const visibleButton = await page.isVisible(selectors.itemDescriptor.editButton);
expect(visibleButton).toBeFalsy();
});
it(`should check the item summary shows fields from basic data section`, async() => {
await page.waitForTextInElement(selectors.itemSummary.basicData, 'Melee weapon combat fist 15cm');
const result = await page.waitToGetProperty(selectors.itemSummary.basicData, 'innerText');
expect(result).toContain('Melee weapon combat fist 15cm');
});
it(`should check the item summary shows fields from tags section`, async() => {
const result = await page.waitToGetProperty(selectors.itemSummary.tags, 'innerText');
expect(result).toContain('Silver');
});
it(`should check the item summary shows fields from botanical section`, async() => {
const result = await page.waitToGetProperty(selectors.itemSummary.botanical, 'innerText');
expect(result).toContain('procera');
});
it(`should check the item summary shows fields from barcodes section`, async() => {
const result = await page.waitToGetProperty(selectors.itemSummary.barcode, 'innerText');
expect(result).toContain('4');
});
});

View File

@ -0,0 +1,64 @@
import getBrowser from '../../helpers/puppeteer';
const $ = {
form: 'vn-item-basic-data form',
intrastatForm: '.vn-dialog.shown form',
newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button'
};
describe('Item Edit basic data path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSearchResult('Melee weapon combat fist 15cm');
});
beforeEach(async() => {
await page.accessToSection('item.card.basicData');
});
afterAll(async() => {
await browser.close();
});
it(`should edit the item basic data and confirm the item data was edited`, async() => {
const values = {
type: 'Anthurium',
intrastat: 'Coral y materiales similares',
relevancy: 1,
generic: 'Pallet',
isActive: false,
priceInKg: true,
isFragile: true,
packingOut: 5
};
const message = await page.sendForm($.form, values);
await page.reloadSection('item.card.basicData');
const formValues = await page.fetchForm($.form, Object.keys(values));
expect(message.isSuccess).toBeTrue();
expect(formValues).toEqual(values);
});
it(`should create a new intrastat and save it`, async() => {
await page.click($.newIntrastatButton);
await page.waitForSelector($.intrastatForm);
await page.fillForm($.intrastatForm, {
id: '588420239',
description: 'Tropical Flowers'
});
await page.respondToDialog('accept');
const message = await page.sendForm($.form);
await page.reloadSection('item.card.basicData');
const formValues = await page.fetchForm($.form, ['intrastat']);
expect(message.isSuccess).toBeTrue();
expect(formValues).toEqual({intrastat: 'Tropical Flowers'});
});
});

View File

@ -0,0 +1,48 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item edit tax path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSearchResult('Ranged weapon longbow 200cm');
await page.accessToSection('item.card.tax');
});
afterAll(async() => {
await browser.close();
});
it(`should add the item tax to all countries`, async() => {
await page.autocompleteSearch(selectors.itemTax.firstClass, 'General VAT');
await page.autocompleteSearch(selectors.itemTax.secondClass, 'General VAT');
await page.waitToClick(selectors.itemTax.submitTaxButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the first item tax class was edited`, async() => {
await page.reloadSection('item.card.tax');
const firstVatType = await page.waitToGetProperty(selectors.itemTax.firstClass, 'value');
expect(firstVatType).toEqual('General VAT');
});
it(`should confirm the second item tax class was edited`, async() => {
const secondVatType = await page
.waitToGetProperty(selectors.itemTax.secondClass, 'value');
expect(secondVatType).toEqual('General VAT');
});
it(`should edit the first class without saving the form`, async() => {
await page.autocompleteSearch(selectors.itemTax.firstClass, 'Reduced VAT');
const firstVatType = await page.waitToGetProperty(selectors.itemTax.firstClass, 'value');
expect(firstVatType).toEqual('Reduced VAT');
});
});

View File

@ -0,0 +1,79 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item create tags path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSearchResult('Ranged weapon longbow 200cm');
await page.accessToSection('item.card.tags');
});
afterAll(async() => {
await browser.close();
});
it('should create a new tag and delete a former one', async() => {
await page.waitToClick(selectors.itemTags.fourthRemoveTagButton);
await page.waitToClick(selectors.itemTags.addItemTagButton);
await page.autocompleteSearch(selectors.itemTags.seventhTag, 'Ancho de la base');
await page.write(selectors.itemTags.seventhValue, '50');
await page.clearInput(selectors.itemTags.seventhRelevancy);
await page.write(selectors.itemTags.seventhRelevancy, '4');
await page.waitToClick(selectors.itemTags.submitItemTagsButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the fourth row data is the expected one', async() => {
await page.reloadSection('item.card.tags');
await page.waitForSelector('vn-item-tags');
let result = await page.waitToGetProperty(selectors.itemTags.fourthTag, 'value');
expect(result).toEqual('Ancho de la base');
result = await page
.waitToGetProperty(selectors.itemTags.fourthValue, 'value');
expect(result).toEqual('50');
result = await page
.waitToGetProperty(selectors.itemTags.fourthRelevancy, 'value');
expect(result).toEqual('4');
});
it('should confirm the fifth row data is the expected one', async() => {
let tag = await page
.waitToGetProperty(selectors.itemTags.fifthTag, 'value');
let value = await page
.waitToGetProperty(selectors.itemTags.fifthValue, 'value');
let relevancy = await page
.waitToGetProperty(selectors.itemTags.fifthRelevancy, 'value');
expect(tag).toEqual('Color');
expect(value).toEqual('Brown');
expect(relevancy).toEqual('5');
});
it('should confirm the sixth row data is the expected one', async() => {
let tag = await page
.waitToGetProperty(selectors.itemTags.sixthTag, 'value');
let value = await page
.waitToGetProperty(selectors.itemTags.sixthValue, 'value');
let relevancy = await page
.waitToGetProperty(selectors.itemTags.sixthRelevancy, 'value');
expect(tag).toEqual('Categoria');
expect(value).toEqual('+1 precission');
expect(relevancy).toEqual('6');
});
});

View File

@ -0,0 +1,66 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item Create botanical path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSearchResult('Ranged weapon pistol 9mm');
await page.accessToSection('item.card.botanical');
});
afterAll(async() => {
await browser.close();
});
it(`should create a new botanical for the item`, async() => {
await page.autocompleteSearch(selectors.itemBotanical.genus, 'Abelia');
await page.autocompleteSearch(selectors.itemBotanical.species, 'dealbata');
await page.waitToClick(selectors.itemBotanical.submitBotanicalButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the Genus for the item was created`, async() => {
await page.waitForTextInField(selectors.itemBotanical.genus, 'Abelia');
const result = await page
.waitToGetProperty(selectors.itemBotanical.genus, 'value');
expect(result).toEqual('Abelia');
});
it(`should confirm the Species for the item was created`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBotanical.species, 'value');
expect(result).toEqual('dealbata');
});
it(`should edit botanical for the item`, async() => {
await page.autocompleteSearch(selectors.itemBotanical.genus, 'Abies');
await page.autocompleteSearch(selectors.itemBotanical.species, 'decurrens');
await page.waitToClick(selectors.itemBotanical.submitBotanicalButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the Genus for the item was edited`, async() => {
await page.waitForTextInField(selectors.itemBotanical.genus, 'Abies');
const result = await page
.waitToGetProperty(selectors.itemBotanical.genus, 'value');
expect(result).toEqual('Abies');
});
it(`should confirm the Species for the item was edited`, async() => {
const result = await page
.waitToGetProperty(selectors.itemBotanical.species, 'value');
expect(result).toEqual('decurrens');
});
});

View File

@ -0,0 +1,37 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item Create barcodes path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSearchResult('Ranged weapon longbow 200cm');
await page.accessToSection('item.card.itemBarcode');
});
afterAll(async() => {
await browser.close();
});
it(`should click create a new code and delete a former one`, async() => {
await page.waitToClick(selectors.itemBarcodes.firstCodeRemoveButton);
await page.waitToClick(selectors.itemBarcodes.addBarcodeButton);
await page.write(selectors.itemBarcodes.thirdCode, '5');
await page.waitToClick(selectors.itemBarcodes.submitBarcodesButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the barcode 5 is created and it is now the third barcode as the first was deleted`, async() => {
await page.reloadSection('item.card.itemBarcode');
await page.waitForTextInField(selectors.itemBarcodes.thirdCode, '5');
const result = await page
.waitToGetProperty(selectors.itemBarcodes.thirdCode, 'value');
expect(result).toEqual('5');
});
});

View File

@ -0,0 +1,65 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
const $ = {
form: 'vn-item-create form'
};
describe('Item Create', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
});
afterAll(async() => {
await browser.close();
});
it('should access to the create item view by clicking the create floating button', async() => {
await page.waitToClick(selectors.itemsIndex.createItemButton);
await page.waitForState('item.create');
});
it('should return to the item index by clickig the cancel button', async() => {
await page.waitToClick(selectors.itemCreateView.cancelButton);
await page.waitForState('item.index');
});
it('should now access to the create item view by clicking the create floating button', async() => {
await page.waitToClick(selectors.itemsIndex.createItemButton);
await page.waitForState('item.create');
});
it('should throw an error when insert an invalid priority', async() => {
const values = {
name: 'Infinity Gauntlet',
type: 'Crisantemo',
intrastat: 'Coral y materiales similares',
origin: 'Holand',
priority: null
};
const message = await page.sendForm($.form, values);
expect(message.text).toContain('Valid priorities');
});
it('should create the Infinity Gauntlet item', async() => {
const values = {
name: 'Infinity Gauntlet',
type: 'Crisantemo',
intrastat: 'Coral y materiales similares',
origin: 'Holand',
priority: '2'
};
await page.fillForm($.form, values);
const formValues = await page.fetchForm($.form, Object.keys(values));
const message = await page.sendForm($.form);
expect(message.isSuccess).toBeTrue();
expect(formValues).toEqual(values);
});
});

View File

@ -0,0 +1,141 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item regularize path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'item');
});
afterAll(async() => {
await browser.close();
});
it('should edit the user local warehouse', async() => {
await page.waitForSpinnerLoad();
await page.waitToClick(selectors.globalItems.userMenuButton);
await page.autocompleteSearch(selectors.globalItems.userLocalWarehouse, 'Warehouse Four');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should check the local settings were saved', async() => {
const userLocalWarehouse = await page
.waitToGetProperty(selectors.globalItems.userLocalWarehouse, 'value');
await page.closePopup();
expect(userLocalWarehouse).toContain('Warehouse Four');
});
it('should search for a specific item', async() => {
await page.accessToSearchResult('Ranged weapon pistol 9mm');
await page.waitForState('item.card.summary');
});
it('should open the regularize dialog and check the warehouse matches the local user settings', async() => {
await page.waitToClick(selectors.itemDescriptor.moreMenu);
await page.waitToClick(selectors.itemDescriptor.moreMenuRegularizeButton);
const result = await page.waitToGetProperty(selectors.itemDescriptor.regularizeWarehouse, 'value');
expect(result).toEqual('Warehouse Four');
});
it('should regularize the item', async() => {
await page.write(selectors.itemDescriptor.regularizeQuantity, '100');
await page.autocompleteSearch(selectors.itemDescriptor.regularizeWarehouse, 'Warehouse One');
await page.waitToClick(selectors.itemDescriptor.regularizeSaveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should click on the Tickets button of the top bar menu', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await Promise.all([
page.waitForNavigation({waitUntil: ['load', 'networkidle0', 'domcontentloaded']}),
page.waitToClick(selectors.globalItems.ticketsButton)
]);
await page.waitForState('ticket.index');
});
it('should clear the user local settings now', async() => {
await page.waitToClick(selectors.globalItems.userMenuButton);
await page.waitForContentLoaded();
await page.clearInput(selectors.globalItems.userConfigFirstAutocomplete);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should search for the ticket with alias missing', async() => {
await page.keyboard.press('Escape');
await page.accessToSearchResult('missing');
await page.waitForState('ticket.card.summary');
});
it(`should check the ticket sale quantity is showing a negative value`, async() => {
await page.waitForTextInElement(selectors.ticketSummary.firstSaleQuantity, '-100');
const result = await page
.waitToGetProperty(selectors.ticketSummary.firstSaleQuantity, 'innerText');
expect(result).toContain('-100');
});
it(`should check the ticket sale discount is 100%`, async() => {
const result = await page
.waitToGetProperty(selectors.ticketSummary.firstSaleDiscount, 'innerText');
expect(result).toContain('100 %');
});
it('should now click on the Items button of the top bar menu', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.itemsButton);
await page.waitForState('item.index');
});
it('should search for the item once again', async() => {
await page.accessToSearchResult('Ranged weapon pistol 9mm');
await page.waitForState('item.card.summary');
});
it('should regularize the item once more', async() => {
await page.waitToClick(selectors.itemDescriptor.moreMenu);
await page.waitToClick(selectors.itemDescriptor.moreMenuRegularizeButton);
await page.write(selectors.itemDescriptor.regularizeQuantity, '100');
await page.autocompleteSearch(selectors.itemDescriptor.regularizeWarehouse, 'Warehouse One');
await page.waitToClick(selectors.itemDescriptor.regularizeSaveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should again click on the Tickets button of the top bar menu', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await Promise.all([
page.waitForNavigation({waitUntil: ['load', 'networkidle0', 'domcontentloaded']}),
page.waitToClick(selectors.globalItems.ticketsButton)
]);
await page.waitForState('ticket.index');
});
it('should search for the ticket missing once again', async() => {
await page.accessToSearchResult('Missing');
await page.waitForState('ticket.card.summary');
});
it(`should check the ticket contains now two sales`, async() => {
await page.waitForTextInElement(selectors.ticketSummary.firstSaleQuantity, '-100');
const result = await page.countElement(selectors.ticketSummary.sale);
expect(result).toEqual(2);
});
});

View File

@ -0,0 +1,84 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item index path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('salesPerson', 'item');
await page.waitToClick(selectors.globalItems.searchButton);
});
afterAll(async() => {
await browser.close();
});
it('should click on the fields to show button to open the list of columns to show', async() => {
await page.waitToClick(selectors.itemsIndex.shownColumns);
const visible = await page.isVisible(selectors.itemsIndex.shownColumnsList);
expect(visible).toBeTruthy();
});
it('should unmark all checkboxes except the first and the last ones', async() => {
await page.waitToClick(selectors.itemsIndex.idCheckbox);
await page.waitToClick(selectors.itemsIndex.stemsCheckbox);
await page.waitToClick(selectors.itemsIndex.sizeCheckbox);
await page.waitToClick(selectors.itemsIndex.typeCheckbox);
await page.waitToClick(selectors.itemsIndex.categoryCheckbox);
await page.waitToClick(selectors.itemsIndex.intrastadCheckbox);
await page.waitToClick(selectors.itemsIndex.originCheckbox);
await page.waitToClick(selectors.itemsIndex.buyerCheckbox);
await page.waitToClick(selectors.itemsIndex.weightByPieceCheckbox);
await page.waitToClick(selectors.itemsIndex.saveFieldsButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should navigate forth and back to see the images column is still visible', async() => {
await page.closePopup();
await page.waitToClick(selectors.itemsIndex.firstSearchResult);
await page.waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton);
await page.waitToClick(selectors.globalItems.searchButton);
await page.waitForSelector(selectors.itemsIndex.searchResult);
await page.waitImgLoad(selectors.itemsIndex.firstItemImage);
const imageVisible = await page.isVisible(selectors.itemsIndex.firstItemImageTd);
expect(imageVisible).toBeTruthy();
});
it('should check the ids column is not visible', async() => {
await page.waitForSelector(selectors.itemsIndex.firstItemId, {hidden: true});
});
it('should mark all unchecked boxes to leave the index as it was', async() => {
await page.waitToClick(selectors.itemsIndex.shownColumns);
await page.waitToClick(selectors.itemsIndex.idCheckbox);
await page.waitToClick(selectors.itemsIndex.stemsCheckbox);
await page.waitToClick(selectors.itemsIndex.sizeCheckbox);
await page.waitToClick(selectors.itemsIndex.typeCheckbox);
await page.waitToClick(selectors.itemsIndex.categoryCheckbox);
await page.waitToClick(selectors.itemsIndex.intrastadCheckbox);
await page.waitToClick(selectors.itemsIndex.originCheckbox);
await page.waitToClick(selectors.itemsIndex.buyerCheckbox);
await page.waitToClick(selectors.itemsIndex.weightByPieceCheckbox);
await page.waitToClick(selectors.itemsIndex.saveFieldsButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should now navigate forth and back to see the ids column is now visible', async() => {
await page.closePopup();
await page.waitToClick(selectors.itemsIndex.firstSearchResult);
await page.waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton);
await page.waitToClick(selectors.globalItems.searchButton);
await page.waitForSelector(selectors.itemsIndex.searchResult);
const idVisible = await page.isVisible(selectors.itemsIndex.firstItemId);
expect(idVisible).toBeTruthy();
});
});

View File

@ -0,0 +1,45 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item log path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('developer', 'item');
});
afterAll(async() => {
await browser.close();
});
it(`should search for the Knowledge artifact to confirm it isn't created yet`, async() => {
await page.doSearch('Knowledge artifact');
const nResults = await page.countElement(selectors.itemsIndex.searchResult);
expect(nResults).toEqual(1);
});
it('should access to the create item view by clicking the create floating button', async() => {
await page.waitToClick(selectors.itemsIndex.createItemButton);
await page.waitForState('item.create');
});
it('should create the Knowledge artifact item', async() => {
await page.write(selectors.itemCreateView.temporalName, 'Knowledge artifact');
await page.autocompleteSearch(selectors.itemCreateView.type, 'Crisantemo');
await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares');
await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand');
await page.waitToClick(selectors.itemCreateView.createButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should return to the items index by clicking the return to items button', async() => {
await page.waitToClick(selectors.itemBasicData.goToItemIndexButton);
await page.waitForSelector(selectors.itemsIndex.createItemButton);
await page.waitForState('item.index');
});
});

View File

@ -0,0 +1,41 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item descriptor path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSearchResult('1');
await page.accessToSection('item.card.basicData');
});
afterAll(async() => {
await browser.close();
});
it('should set the item to inactive', async() => {
await page.waitToClick(selectors.itemBasicData.isActiveCheckbox);
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should reload the section and check the inactive icon is visible', async() => {
await page.reloadSection('item.card.basicData');
const visibleIcon = await page.isVisible(selectors.itemDescriptor.inactiveIcon);
expect(visibleIcon).toBeTruthy();
});
it('should set the item back to active', async() => {
await page.waitToClick(selectors.itemBasicData.isActiveCheckbox);
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});

View File

@ -0,0 +1,45 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item request path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSection('item.request');
});
afterAll(async() => {
await browser.close();
});
it('should reach the item request section', async() => {
await page.waitForState('item.request');
});
it('should fill the id and quantity then check the concept was updated', async() => {
await page.writeOnEditableTD(selectors.itemRequest.firstRequestItemID, '4');
await page.writeOnEditableTD(selectors.itemRequest.firstRequestQuantity, '10');
await page.waitForTextInElement(selectors.itemRequest.firstRequestConcept, 'Melee weapon heavy shield 100cm');
let filledConcept = await page.waitToGetProperty(selectors.itemRequest.firstRequestConcept, 'innerText');
expect(filledConcept).toContain('Melee weapon heavy shield 100cm');
});
it('should check the status of the request should now be accepted', async() => {
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
expect(status).toContain('Accepted');
});
it('should now click on the second declain request icon then type the reason', async() => {
await page.waitToClick(selectors.itemRequest.secondRequestDecline);
await page.write(selectors.itemRequest.declineReason, 'Not quite as expected');
await page.respondToDialog('accept');
let status = await page.waitToGetProperty(selectors.itemRequest.secondRequestStatus, 'innerText');
expect(status).toContain('Denied');
});
});

View File

@ -0,0 +1,97 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
const $ = selectors.itemFixedPrice;
describe('Item fixed prices path', () => {
let browser;
let page;
let httpRequest;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSection('item.fixedPrice');
page.on('request', req => {
if (req.url().includes(`FixedPrices/filter`))
httpRequest = req.url();
});
});
afterAll(async() => {
await browser.close();
});
it('should filter using all the fields', async() => {
await page.write($.generalSearchFilter, 'item');
await page.keyboard.press('Enter');
expect(httpRequest).toContain('search=item');
await page.click($.chip);
await page.click($.reignFilter);
expect(httpRequest).toContain('categoryFk');
await page.autocompleteSearch($.typeFilter, 'Alstroemeria');
expect(httpRequest).toContain('typeFk');
await page.click($.chip);
await page.autocompleteSearch($.buyerFilter, 'buyerNick');
expect(httpRequest).toContain('buyerFk');
await page.click($.chip);
await page.autocompleteSearch($.warehouseFilter, 'Algemesi');
expect(httpRequest).toContain('warehouseFk');
await page.click($.chip);
await page.click($.mineFilter);
expect(httpRequest).toContain('mine=true');
await page.click($.chip);
await page.click($.hasMinPriceFilter);
expect(httpRequest).toContain('hasMinPrice=true');
await page.click($.chip);
await page.click($.addTag);
await page.autocompleteSearch($.tagFilter, 'Color');
await page.autocompleteSearch($.tagValueFilter, 'Brown');
expect(httpRequest).toContain('tags');
await page.click($.chip);
});
it('should click on the add new fixed price button', async() => {
await page.waitToClick($.add);
await page.waitForSelector($.fourthFixedPrice);
});
it('should fill the fixed price data', async() => {
const now = Date.vnNew();
await page.autocompleteSearch($.fourthWarehouse, 'Warehouse one');
await page.writeOnEditableTD($.fourthGroupingPrice, '1');
await page.writeOnEditableTD($.fourthPackingPrice, '1');
await page.write($.fourthMinPrice, '1');
await page.pickDate($.fourthStarted, now);
await page.pickDate($.fourthEnded, now);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should reload the section and check the created price has the expected ID', async() => {
await page.goto(`http://localhost:5000/#!/item/fixed-price`);
await page.autocompleteSearch($.warehouseFilter, 'Warehouse one');
await page.click($.chip);
const result = await page.waitToGetProperty($.fourthItemID, 'value');
expect(result).toContain('13');
});
});

View File

@ -0,0 +1,99 @@
import selectors from '../../../helpers/selectors.js';
import getBrowser from '../../../helpers/puppeteer';
describe('Ticket List sale path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult('13');
await page.accessToSection('ticket.card.sale');
});
afterAll(async() => {
await browser.close();
});
it('should confirm the first ticket sale contains the colour tag', async() => {
const value = await page
.waitToGetProperty(selectors.ticketSales.firstSaleColour, 'innerText');
expect(value).toContain('Black');
});
it('should confirm the first sale contains the price', async() => {
const value = await page
.waitToGetProperty(selectors.ticketSales.firstSalePrice, 'innerText');
expect(value).toContain('1.72');
});
it('should confirm the first sale contains the discount', async() => {
const value = await page
.waitToGetProperty(selectors.ticketSales.firstSaleDiscount, 'innerText');
expect(value).toContain('0.00%');
});
it('should confirm the first sale contains the total import', async() => {
const value = await page
.waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText');
expect(value).toContain('34.40');
});
it('should add an empty item to the sale list', async() => {
await page.waitToClick(selectors.ticketSales.newItemButton);
const sales = await page
.countElement(selectors.ticketSales.saleLine);
expect(sales).toEqual(2);
});
it('should select a valid item to be added as the second item in the sales list', async() => {
let searchValue = 'Melee weapon heavy shield 100cm';
await page.autocompleteSearch(selectors.ticketSales.secondSaleIdAutocomplete, searchValue);
await page.waitToClick(selectors.ticketSales.secondSaleQuantityCell);
await page.type(selectors.ticketSales.secondSaleQuantity, '8');
await page.keyboard.press('Enter');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should update the description of the new sale', async() => {
await page.click(selectors.ticketSales.secondSaleConceptCell);
await page.write(selectors.ticketSales.secondSaleConceptInput, 'Aegis of Valor');
await page.keyboard.press('Enter');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should add a third empty item to the sale list', async() => {
await page.waitToClick(selectors.ticketSales.newItemButton);
await page.waitForNumberOfElements(selectors.ticketSales.saleLine, 3);
const sales = await page.countElement(selectors.ticketSales.saleLine);
expect(sales).toEqual(3);
});
it('should select the 2nd and 3th item and delete both', async() => {
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketSales.deleteSaleButton);
await page.waitToClick(selectors.globalItems.acceptButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should verify there's only 1 single line remaining`, async() => {
const sales = await page.countElement(selectors.ticketSales.saleLine);
expect(sales).toEqual(1);
});
});

View File

@ -0,0 +1,415 @@
import selectors from '../../../helpers/selectors.js';
import getBrowser from '../../../helpers/puppeteer';
describe('Ticket Edit sale path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
});
afterAll(async() => {
await browser.close();
});
it(`should click on the first sale claim icon to navigate over there`, async() => {
await page.waitToClick(selectors.ticketSales.firstSaleClaimIcon);
await page.waitForNavigation();
await page.goBack();
await page.goBack();
});
it('should navigate to the tickets index', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.ticketsButton);
await page.waitForState('ticket.index');
});
it(`should search for a ticket and then navigate to it's sales`, async() => {
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
});
it(`should set the ticket as libre`, async() => {
const searchValue = 'libre';
await page.waitToClick(selectors.ticketSales.stateMenuButton);
await page.write(selectors.ticketSales.moreMenuState, searchValue);
try {
await page.waitForFunction(searchValue => {
const element = document.querySelector('li.active');
if (element)
return element.innerText.toLowerCase().includes(searchValue.toLowerCase());
}, {}, searchValue);
} catch (error) {
const builtSelector = await page.selectorFormater(selectors.ticketSales.moreMenuState);
const inputValue = await page.evaluate(() => {
return document.querySelector('.vn-drop-down.shown vn-textfield input').value;
});
throw new Error(`${builtSelector} value is ${inputValue}! ${error}`);
}
await page.waitForState('ticket.card.sale');
await page.keyboard.press('Enter');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should check it's state is libre now`, async() => {
await page.waitForTextInElement(selectors.ticketDescriptor.stateLabelValue, 'Libre');
const result = await page.waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText');
expect(result).toEqual('State Libre');
});
it(`should set the ticket as OK`, async() => {
await page.waitToClick(selectors.ticketSales.setOk);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should check it's state is OK now`, async() => {
await page.waitForTextInElement(selectors.ticketDescriptor.stateLabelValue, 'OK');
const result = await page.waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText');
expect(result).toEqual('State OK');
});
it(`should check the zoomed image isn't present`, async() => {
const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(0);
});
it(`should click on the thumbnail image of the 1st sale and see the zoomed image`, async() => {
await page.waitToClick(selectors.ticketSales.firstSaleThumbnailImage);
const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(1);
});
it(`should click on the zoomed image to close it`, async() => {
await page.waitToClick(selectors.ticketSales.firstSaleZoomedImage);
const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(0);
});
it(`should click on the first sale ID making now the item descriptor visible`, async() => {
await page.waitToClick(selectors.ticketSales.firstSaleId);
await page.waitImgLoad(selectors.ticketSales.firstSaleDescriptorImage);
const visible = await page.isVisible(selectors.ticketSales.saleDescriptorPopover);
expect(visible).toBeTruthy();
});
it(`should click on the descriptor image of the 1st sale and see the zoomed image`, async() => {
await page.waitToClick('vn-item-descriptor img');
const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(1);
});
it(`should now click on the zoomed image to close it`, async() => {
await page.waitToClick(selectors.ticketSales.firstSaleZoomedImage);
const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage);
expect(result).toEqual(0);
});
it(`should click on the summary icon of the item-descriptor to access to the item summary`, async() => {
await page.waitToClick(selectors.ticketSales.saleDescriptorPopoverSummaryButton);
await page.waitForState('item.card.summary');
});
it('should return to ticket sales section', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.ticketsButton);
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
});
it('should remove 1 from the first sale quantity', async() => {
await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell);
await page.waitForSelector(selectors.ticketSales.firstSaleQuantity);
await page.type(selectors.ticketSales.firstSaleQuantity, '9\u000d');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should update the price', async() => {
await page.waitToClick(selectors.ticketSales.firstSalePrice);
await page.waitForSelector(selectors.ticketSales.firstSalePriceInput);
await page.type(selectors.ticketSales.firstSalePriceInput, '5\u000d');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the price have been updated', async() => {
const result = await page.waitToGetProperty(selectors.ticketSales.firstSalePrice, 'innerText');
expect(result).toContain('5.00');
});
it('should confirm the total price for that item have been updated', async() => {
const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText');
expect(result).toContain('45.00');
});
it('should update the discount', async() => {
await page.waitToClick(selectors.ticketSales.firstSaleDiscount);
await page.waitForSelector(selectors.ticketSales.firstSaleDiscountInput);
await page.type(selectors.ticketSales.firstSaleDiscountInput, '50');
await page.waitToClick(selectors.ticketSales.saveSaleDiscountButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the discount have been updated', async() => {
await page.waitForTextInElement(selectors.ticketSales.firstSaleDiscount, '50.00%');
const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleDiscount, 'innerText');
expect(result).toContain('50.00%');
});
it('should confirm the total import for that item have been updated', async() => {
await page.waitForTextInElement(selectors.ticketSales.firstSaleImport, '22.50');
const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText');
expect(result).toContain('22.50');
});
it('should recalculate price of sales', async() => {
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuRecalculatePrice);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should log in as salesAssistant and navigate to ticket sales', async() => {
await page.loginAndModule('salesAssistant', 'ticket');
await page.accessToSearchResult('15');
await page.accessToSection('ticket.card.sale');
});
it('should select the first sale and create a refund with warehouse', async() => {
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuRefund);
await page.waitToClick(selectors.ticketSales.refundWithWarehouse);
await page.waitForSnackbar();
await page.waitForState('ticket.card.sale');
});
it('should select the first sale and create a refund without warehouse', async() => {
await page.accessToSearchResult('18');
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuRefund);
await page.waitToClick(selectors.ticketSales.refundWithoutWarehouse);
await page.waitForSnackbar();
await page.waitForState('ticket.card.sale');
});
it('should show error trying to delete a ticket with a refund', async() => {
await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('8');
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
await page.waitToClick(selectors.globalItems.acceptButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Tickets with associated refunds can\'t be deleted');
await page.waitToClick(selectors.globalItems.cancelButton);
});
it('should select the third sale and create a claim of it', async() => {
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim);
await page.waitToClick(selectors.globalItems.acceptButton);
await page.waitForNavigation();
});
it('should search for a ticket then access to the sales section', async() => {
await page.goBack();
await page.goBack();
await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
});
it('should select the third sale and delete it', async() => {
await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketSales.deleteSaleButton);
await page.waitToClick(selectors.globalItems.acceptButton);
await page.waitForSpinnerLoad();
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the third sale was deleted`, async() => {
const result = await page.countElement(selectors.ticketSales.saleLine);
expect(result).toEqual(3);
});
it('should select the second sale and transfer it to a valid ticket', async() => {
const targetTicketId = '12';
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
await page.waitToClick(selectors.ticketSales.transferSaleButton);
await page.waitToClick(selectors.ticketSales.transferQuantityCell);
await page.type(selectors.ticketSales.transferQuantityInput, '10\u000d');
await page.type(selectors.ticketSales.moveToTicketInput, targetTicketId);
await page.waitToClick(selectors.ticketSales.moveToTicketButton);
await page.expectURL(`ticket/${targetTicketId}/sale`);
});
it('should confirm the transfered line is the correct one', async() => {
await page.waitForSelector(selectors.ticketSales.secondSaleText);
const result = await page.waitToGetProperty(selectors.ticketSales.secondSaleText, 'innerText');
expect(result).toContain(`Melee weapon heavy shield`);
});
it('should confirm the transfered quantity is the correct one', async() => {
const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleQuantityCell, 'innerText');
expect(result).toContain('20');
});
it('should go back to the original ticket sales section', async() => {
await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton);
await page.accessToSearchResult('16');
await page.accessToSection('ticket.card.sale');
});
it(`should confirm the original ticket has still three lines`, async() => {
await page.waitForSelector(selectors.ticketSales.saleLine);
const result = await page.countElement(selectors.ticketSales.saleLine);
expect(result).toEqual(3);
});
it(`should confirm the second sale quantity is now half of it's original value after the transfer`, async() => {
const result = await page.waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText');
expect(result).toContain('10');
});
it('should go back to the receiver ticket sales section', async() => {
await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton);
await page.accessToSearchResult('12');
await page.accessToSection('ticket.card.sale');
});
it('should transfer the sale back to the original ticket', async() => {
const targetTicketId = '16';
await page.waitToClick(selectors.ticketSales.secondSaleCheckbox);
await page.waitToClick(selectors.ticketSales.transferSaleButton);
await page.type(selectors.ticketSales.moveToTicketInput, targetTicketId);
await page.waitToClick(selectors.ticketSales.moveToTicketButton);
await page.expectURL(`ticket/${targetTicketId}/sale`);
});
it('should confirm the original ticket received the line', async() => {
const expectedLines = 4;
await page.waitForNumberOfElements(selectors.ticketSales.saleLine, expectedLines);
const result = await page.countElement(selectors.ticketSales.saleLine);
expect(result).toEqual(expectedLines);
});
it(`should throw an error when attempting to create a ticket for an inactive client`, async() => {
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
await page.waitToClick(selectors.ticketSales.transferSaleButton);
await page.waitToClick(selectors.ticketSales.moveToNewTicketButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain(`You can't create a ticket for an inactive client`);
await page.closePopup();
});
it('should go now to the ticket sales section of an active, not frozen client', async() => {
await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton);
await page.accessToSearchResult('13');
await page.accessToSection('ticket.card.sale');
});
it(`should select all sales, tranfer them to a new ticket and delete the sender ticket as it would've been left empty`, async() => {
const senderTicketId = '13';
await page.waitToClick(selectors.ticketSales.selectAllSalesCheckbox);
await page.waitToClick(selectors.ticketSales.transferSaleButton);
await page.waitToClick(selectors.ticketSales.moveToNewTicketButton);
await page.evaluate((selector, ticketId) => {
return document.querySelector(selector).innerText.toLowerCase().indexOf(`#${ticketId}`) == -1;
}, selectors.ticketDescriptor.id, senderTicketId);
await page.waitForState('ticket.card.sale');
});
it('should confirm the new ticket received the line', async() => {
const expectedLines = 1;
const result = await page.countElement(selectors.ticketSales.saleLine);
expect(result).toEqual(expectedLines);
});
it('should check the first sale reserved icon isnt visible', async() => {
const result = await page.isVisible(selectors.ticketSales.firstSaleReservedIcon);
expect(result).toBeFalsy();
});
it('should mark the first sale as reserved', async() => {
await page.waitToClick(selectors.ticketSales.firstSaleCheckbox);
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuReserve);
await page.closePopup();
await page.waitForClassNotPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide');
const result = await page.isVisible(selectors.ticketSales.firstSaleReservedIcon);
expect(result).toBeTruthy();
});
it('should unmark the first sale as reserved', async() => {
await page.waitToClick(selectors.ticketSales.moreMenu);
await page.waitToClick(selectors.ticketSales.moreMenuUnmarkReseved);
await page.waitForClassPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide');
const result = await page.isVisible(selectors.ticketSales.firstSaleReservedIcon);
expect(result).toBeFalsy();
});
it('should log in as Production role and go to a target ticket summary', async() => {
await page.loginAndModule('production', 'ticket');
await page.accessToSearchResult('13');
await page.waitForState('ticket.card.summary');
});
it(`should check the ticket is deleted`, async() => {
await page.waitForSelector(selectors.ticketDescriptor.isDeletedIcon);
});
});

View File

@ -0,0 +1,50 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Create notes path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult('5');
await page.accessToSection('ticket.card.observation');
});
afterAll(async() => {
await browser.close();
});
it('should create a new note', async() => {
await page.waitToClick(selectors.ticketNotes.addNoteButton);
await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'ItemPicker');
await page.write(selectors.ticketNotes.firstDescription, 'description');
await page.waitToClick(selectors.ticketNotes.submitNotesButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the note is the expected one', async() => {
await page.reloadSection('ticket.card.observation');
const result = await page
.waitToGetProperty(selectors.ticketNotes.firstNoteType, 'value');
expect(result).toEqual('ItemPicker');
const firstDescription = await page
.waitToGetProperty(selectors.ticketNotes.firstDescription, 'value');
expect(firstDescription).toEqual('description');
});
it('should delete the note', async() => {
await page.waitToClick(selectors.ticketNotes.firstNoteRemoveButton);
await page.waitToClick(selectors.ticketNotes.submitNotesButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});

View File

@ -0,0 +1,32 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket expeditions and log path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('production', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.expedition');
});
afterAll(async() => {
await browser.close();
});
it(`should delete a former expedition and confirm the remaining expedition are the expected ones`, async() => {
await page.waitToClick(selectors.ticketExpedition.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketExpedition.deleteExpeditionButton);
await page.waitToClick(selectors.globalItems.acceptButton);
await page.reloadSection('ticket.card.expedition');
await page.waitForSelector(selectors.ticketExpedition.expeditionRow, {});
const result = await page
.countElement(selectors.ticketExpedition.expeditionRow);
expect(result).toEqual(6);
});
});

View File

@ -0,0 +1,78 @@
import getBrowser from '../../helpers/puppeteer';
const $ = {
firstPackage: 'vn-autocomplete[label="Package"]',
firstQuantity: 'vn-ticket-package vn-horizontal:nth-child(1) vn-input-number[ng-model="package.quantity"]',
firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]',
addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]',
savePackagesButton: `button[type=submit]`
};
describe('Ticket Create packages path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.package');
});
afterAll(async() => {
await browser.close();
});
it(`should attempt create a new package but receive an error if package is blank`, async() => {
await page.waitToClick($.firstRemovePackageButton);
await page.waitToClick($.addPackageButton);
await page.write($.firstQuantity, '99');
await page.waitToClick($.savePackagesButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Package cannot be blank');
});
it(`should delete the first package and receive and error to save a new one with blank quantity`, async() => {
await page.clearInput($.firstQuantity);
await page.autocompleteSearch($.firstPackage, 'Container medical box 100cm');
await page.waitToClick($.savePackagesButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Some fields are invalid');
});
it(`should confirm the quantity input isn't invalid yet`, async() => {
const result = await page
.evaluate(selector => {
return document.querySelector(`${selector} input`).checkValidity();
}, $.firstQuantity);
expect(result).toBeTruthy();
});
it(`should create a new package with correct data`, async() => {
await page.clearInput($.firstQuantity);
await page.write($.firstQuantity, '-99');
await page.waitToClick($.savePackagesButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the first select is the expected one`, async() => {
await page.reloadSection('ticket.card.package');
await page.waitForTextInField($.firstPackage, 'Container medical box 100cm');
const result = await page.waitToGetProperty($.firstPackage, 'value');
expect(result).toEqual('Container medical box 100cm');
});
it(`should confirm quantity is just a number and the string part was ignored by the imput number`, async() => {
await page.waitForTextInField($.firstQuantity, '-99');
const result = await page.waitToGetProperty($.firstQuantity, 'value');
expect(result).toEqual('-99');
});
});

View File

@ -0,0 +1,72 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Create new tracking state path', () => {
let browser;
let page;
afterAll(async() => {
await browser.close();
});
describe('as production', () => {
it('should log into the ticket 1 tracking', async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('production', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.tracking.index');
});
it('should access to the create state view by clicking the create floating button', async() => {
await page.waitToClick(selectors.ticketTracking.createStateButton);
await page.waitForSelector(selectors.createStateView.state, {visible: true});
await page.waitForState('ticket.card.tracking.edit');
});
it(`should create a new state`, async() => {
await page.autocompleteSearch(selectors.createStateView.state, 'OK');
await page.waitToClick(selectors.createStateView.saveStateButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});
describe('as salesPerson', () => {
it('should now log into the ticket 1 tracking', async() => {
await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.tracking.index');
});
it('should now access to the create state view by clicking the create floating button', async() => {
await page.waitForSelector('.vn-popup', {hidden: true});
await page.waitToClick(selectors.ticketTracking.createStateButton);
await page.waitForState('ticket.card.tracking.edit');
});
it(`should attemp to create an state for which salesPerson doesn't have permissions`, async() => {
await page.autocompleteSearch(selectors.createStateView.state, 'Encajado');
await page.waitToClick(selectors.createStateView.saveStateButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain(`You don't have enough privileges`);
});
it(`should make sure the worker gets autocomplete uppon selecting the assigned state`, async() => {
await page.autocompleteSearch(selectors.createStateView.state, 'asignado');
const result = await page
.waitToGetProperty(selectors.createStateView.worker, 'value');
expect(result).toEqual('salesperson');
});
it(`should succesfully create a valid state`, async() => {
await page.waitToClick(selectors.createStateView.saveStateButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});
});

View File

@ -0,0 +1,143 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Edit basic data path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult('11');
await page.accessToSection('ticket.card.basicData.stepOne');
});
afterAll(async() => {
await browser.close();
});
it(`should confirm the zone autocomplete is disabled unless your role is productionBoss`, async() => {
await page.waitForSelector(selectors.ticketBasicData.zone, {});
const disabled = await page.evaluate(selector => {
return document.querySelector(selector).disabled;
}, `${selectors.ticketBasicData.zone} input`);
expect(disabled).toBeTruthy();
});
it(`should now log as productionBoss to perform the rest of the tests`, async() => {
await page.loginAndModule('productionBoss', 'ticket');
await page.accessToSearchResult('11');
await page.accessToSection('ticket.card.basicData.stepOne');
});
it(`should confirm the zone autocomplete is enabled for the role productionBoss`, async() => {
await page.waitForSpinnerLoad();
await page.waitForSelector(selectors.ticketBasicData.zone);
const disabled = await page.evaluate(selector => {
return document.querySelector(selector).disabled;
}, `${selectors.ticketBasicData.zone} input`);
expect(disabled).toBeFalsy();
});
it(`should check the zone is for Gotham247`, async() => {
let zone = await page
.waitToGetProperty(selectors.ticketBasicData.zone, 'value');
expect(zone).toContain('Zone 247 A');
});
it(`should edit the ticket agency then check there are no zones for it`, async() => {
await page.autocompleteSearch(selectors.ticketBasicData.agency, 'Super-Man delivery');
let emptyZone = await page
.expectPropertyValue(selectors.ticketBasicData.zone, 'value', '');
expect(emptyZone).toBeTruthy();
});
it(`should edit the ticket zone then check the agency is for the new zone`, async() => {
await page.clearInput(selectors.ticketBasicData.agency);
await page.autocompleteSearch(selectors.ticketBasicData.zone, 'Zone expensive A');
let zone = await page
.waitToGetProperty(selectors.ticketBasicData.agency, 'value');
expect(zone).toContain('Gotham247Expensive');
});
it(`should click next`, async() => {
await page.waitToClick(selectors.ticketBasicData.nextStepButton);
await page.waitForState('ticket.card.basicData.stepTwo');
});
it(`should have a price diference`, async() => {
const result = await page
.waitToGetProperty(selectors.ticketBasicData.stepTwoTotalPriceDif, 'innerText');
expect(result).toContain('-€228.25');
});
it(`should select a new reason for the changes made then click on finalize`, async() => {
await page.waitToClick(selectors.ticketBasicData.chargesReason);
await page.waitToClick(selectors.ticketBasicData.finalizeButton);
await page.waitForState('ticket.card.summary');
});
it(`should not find ticket`, async() => {
await page.doSearch('29');
const count = await page.countElement(selectors.ticketsIndex.searchResult);
expect(count).toEqual(0);
});
it(`should split ticket without negatives`, async() => {
const newAgency = 'Gotham247';
const newDate = Date.vnNew();
newDate.setDate(newDate.getDate() - 1);
await page.accessToSearchResult('14');
await page.accessToSection('ticket.card.basicData.stepOne');
await page.autocompleteSearch(selectors.ticketBasicData.agency, newAgency);
await page.pickDate(selectors.ticketBasicData.shipped, newDate);
await page.waitToClick(selectors.ticketBasicData.nextStepButton);
await page.waitToClick(selectors.ticketBasicData.finalizeButton);
await page.waitForState('ticket.card.summary');
const newTicketAgency = await page
.waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText');
const newTicketDate = await page
.waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText');
expect(newAgency).toEqual(newTicketAgency);
expect(newTicketDate).toContain(newDate.getDate());
});
it(`should new ticket have sale of old ticket`, async() => {
await page.accessToSection('ticket.card.sale');
await page.waitForState('ticket.card.sale');
const item = await page.waitToGetProperty(selectors.ticketSales.firstSaleId, 'innerText');
expect(item).toEqual('4');
});
it(`should old ticket have old date and agency`, async() => {
const oldDate = Date.vnNew();
const oldAgency = 'Super-Man delivery';
await page.accessToSearchResult('14');
const oldTicketAgency = await page
.waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryAgency, 'innerText');
const oldTicketDate = await page
.waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText');
expect(oldTicketAgency).toEqual(oldAgency);
expect(oldTicketDate).toContain(oldDate.getDate());
});
});

View File

@ -0,0 +1,30 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket List components path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.components');
});
afterAll(async() => {
await browser.close();
});
it('should confirm the total base is correct', async() => {
const name = 'Base €';
const minLength = name.length;
await page.waitPropertyLength(selectors.ticketComponents.base, 'innerText', minLength);
const base = await page.waitToGetProperty(selectors.ticketComponents.base, 'innerText');
expect(base).toContain('Base');
expect(base.length).toBeGreaterThan(minLength);
});
});

View File

@ -0,0 +1,123 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket descriptor path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyerBoss', 'ticket');
await page.accessToSection('ticket.weekly.index');
});
afterAll(async() => {
await browser.close();
});
it('should count the amount of tickets in the turns section', async() => {
const result = await page.countElement(selectors.ticketsIndex.weeklyTicket);
expect(result).toEqual(6);
});
it('should go back to the ticket index then search and access a ticket summary', async() => {
await page.accessToSection('ticket.index');
await page.accessToSearchResult('33');
});
it('should add the ticket to thursday turn using the descriptor more menu', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuAddToTurn);
await page.waitToClick(selectors.ticketDescriptor.thursdayButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Current ticket deleted and added to shift');
});
it('should again click on the Tickets button of the top bar menu', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.ticketsButton);
await page.waitForState('ticket.index');
});
it('should confirm the ticket 33 was added to thursday', async() => {
await page.accessToSection('ticket.weekly.index');
const result = await page.waitToGetProperty(selectors.ticketsIndex.thirdWeeklyTicket, 'value');
expect(result).toEqual('Thursday');
});
it('should click on the Tickets button of the top bar menu once more', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.ticketsButton);
await page.waitForState('ticket.index');
});
it('should now search for the ticket 33', async() => {
await page.accessToSearchResult('33');
await page.waitForState('ticket.card.summary');
});
it('should add the ticket to saturday turn using the descriptor more menu', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuAddToTurn);
await page.waitToClick(selectors.ticketDescriptor.saturdayButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Current ticket deleted and added to shift');
});
it('should click on the Tickets button of the top bar menu once again', async() => {
await page.waitToClick(selectors.globalItems.applicationsMenuButton);
await page.waitForSelector(selectors.globalItems.applicationsMenuVisible);
await page.waitToClick(selectors.globalItems.ticketsButton);
await page.waitForState('ticket.index');
});
it('should confirm the ticket 33 was added on saturday', async() => {
await page.accessToSection('ticket.weekly.index');
await page.waitForTimeout(5000);
const result = await page.waitToGetProperty(selectors.ticketsIndex.thirdWeeklyTicket, 'value');
expect(result).toEqual('Saturday');
});
it('should now search for the weekly ticket 33', async() => {
await page.doSearch('33');
const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult);
expect(nResults).toEqual(2);
});
it('should delete the weekly ticket 33', async() => {
await page.waitToClick(selectors.ticketsIndex.firstWeeklyTicketDeleteIcon);
await page.waitToClick(selectors.ticketsIndex.acceptDeleteTurn);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the sixth weekly ticket was deleted', async() => {
await page.doSearch();
const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult);
expect(nResults).toEqual(6);
});
it('should update the agency then remove it afterwards', async() => {
await page.autocompleteSearch(selectors.ticketsIndex.firstWeeklyTicketAgency, 'Gotham247');
let message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
await page.clearInput(selectors.ticketsIndex.firstWeeklyTicketAgency);
message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});

View File

@ -0,0 +1,77 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket purchase request path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('salesPerson', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.request.index');
});
afterAll(async() => {
await browser.close();
});
it('should add a new request', async() => {
await page.waitToClick(selectors.ticketRequests.addRequestButton);
await page.write(selectors.ticketRequests.descriptionInput, 'New stuff');
await page.write(selectors.ticketRequests.quantity, '9');
await page.autocompleteSearch(selectors.ticketRequests.atender, 'buyerNick');
await page.write(selectors.ticketRequests.price, '999');
await page.waitToClick(selectors.ticketRequests.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should have been redirected to the request index', async() => {
await page.waitForState('ticket.card.request.index');
});
it(`should edit the third request quantity as it's state is still new`, async() => {
await page.write(selectors.ticketRequests.thirdRequestQuantity, '9');
await page.keyboard.press('Enter');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should check the new request was added', async() => {
await page.reloadSection('ticket.card.request.index');
const result = await page.waitToGetProperty(selectors.ticketRequests.thirdRequestQuantity, 'value');
expect(result).toEqual('99');
});
it(`should check the first request can't be edited as its state is different to new`, async() => {
await page.waitForClassPresent(selectors.ticketRequests.firstRequestQuantity, 'disabled');
const result = await page.isDisabled(selectors.ticketRequests.firstRequestQuantity);
expect(result).toBe(true);
});
it(`should check the second request can't be edited as its state is different to new`, async() => {
await page.waitForClassPresent(selectors.ticketRequests.secondRequestQuantity, 'disabled');
const result = await page.isDisabled(selectors.ticketRequests.secondRequestQuantity);
expect(result).toBe(true);
});
it('should delete the added request', async() => {
await page.waitToClick(selectors.ticketRequests.thirdRemoveRequestButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should check the request was deleted', async() => {
await page.reloadSection('ticket.card.request.index');
await page.waitForSelector(selectors.ticketRequests.addRequestButton);
await page.waitForSelector(selectors.ticketRequests.thirdDescription, {hidden: true});
});
});

View File

@ -0,0 +1,148 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket descriptor path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('salesperson', 'ticket');
});
afterAll(async() => {
await browser.close();
});
describe('Delete ticket', () => {
it('should search for an specific ticket', async() => {
await page.accessToSearchResult('18');
await page.waitForState('ticket.card.summary');
});
it(`should update the shipped hour using the descriptor menu`, async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuChangeShippedHour);
await page.pickTime(selectors.ticketDescriptor.changeShippedHour, '08:15');
await page.waitToClick(selectors.ticketDescriptor.acceptChangeHourButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Shipped hour updated');
});
it(`should confirm the ticket descriptor shows the correct shipping hour`, async() => {
await page.waitForState('ticket.card.summary');
const result = await page
.waitToGetProperty(selectors.ticketDescriptor.descriptorDeliveryDate, 'innerText');
expect(result).toContain('08:15');
});
it('should delete the ticket using the descriptor menu', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
await page.waitToClick(selectors.ticketDescriptor.acceptDialog);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Ticket deleted. You can undo this action within the first hour');
});
it('should have been relocated to the ticket index', async() => {
await page.waitForState('ticket.index');
});
it(`should search for the deleted ticket and check the deletedTicket icon and it's date`, async() => {
await page.write(selectors.ticketsIndex.topbarSearch, '18');
await page.waitToClick(selectors.globalItems.searchButton);
await page.waitForState('ticket.card.summary');
await page.isVisible(selectors.ticketDescriptor.isDeletedIcon);
const result = await page.waitToGetProperty(selectors.ticketsIndex.searchResultDate, 'innerText');
expect(result).toContain(2000);
});
});
describe('Restore ticket', () => {
it('should restore the ticket using the descriptor menu', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuRestoreTicket);
await page.waitToClick(selectors.ticketDescriptor.acceptDialog);
await page.waitForState('ticket.card.summary');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});
describe('Make invoice', () => {
it('should login as administrative role then search for a ticket', async() => {
const invoiceableTicketId = '14';
await page.loginAndModule('administrative', 'ticket');
await page.accessToSearchResult(invoiceableTicketId);
await page.waitForState('ticket.card.summary');
});
it(`should make sure the ticket doesn't have an invoiceOutFk yet`, async() => {
const result = await page
.waitToGetProperty(selectors.ticketSummary.invoiceOutRef, 'innerText');
expect(result).toEqual('-');
});
it('should invoice the ticket using the descriptor menu', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitForContentLoaded();
await page.waitToClick(selectors.ticketDescriptor.moreMenuMakeInvoice);
await page.waitToClick(selectors.ticketDescriptor.acceptInvoiceOutButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Ticket invoiced');
});
it(`should make sure the ticket summary have an invoiceOutFk`, async() => {
await page.waitForTextInElement(selectors.ticketSummary.invoiceOutRef, 'T4444445');
const result = await page.waitToGetProperty(selectors.ticketSummary.invoiceOutRef, 'innerText');
expect(result).toEqual('T4444445');
});
it(`should regenerate the invoice using the descriptor menu`, async() => {
const expectedMessage = 'The invoice PDF document has been regenerated';
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitForContentLoaded();
await page.waitToClick(selectors.ticketDescriptor.moreMenuRegenerateInvoice);
await page.respondToDialog('accept');
const message = await page.waitForSnackbar();
expect(message.text).toContain(expectedMessage);
});
});
describe('SMS', () => {
it('should send the payment SMS using the descriptor menu', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuSMSOptions);
await page.waitToClick(selectors.ticketDescriptor.moreMenuPaymentSMS);
await page.waitForSelector(selectors.ticketDescriptor.SMStext);
await page.waitPropertyLength(selectors.ticketDescriptor.SMStext, 'value', 128);
await page.waitToClick(selectors.ticketDescriptor.sendSMSbutton);
const message = await page.waitForSnackbar();
expect(message).toBeDefined();
});
it('should send the import SMS using the descriptor menu', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenuSMSOptions);
await page.waitToClick(selectors.ticketDescriptor.moreMenuSendImportSms);
await page.waitForSelector(selectors.ticketDescriptor.SMStext);
await page.waitPropertyLength(selectors.ticketDescriptor.SMStext, 'value', 144);
await page.waitToClick(selectors.ticketDescriptor.sendSMSbutton);
const message = await page.waitForSnackbar();
expect(message).toBeDefined();
});
});
});

View File

@ -0,0 +1,127 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket services path', () => {
let browser;
let page;
const invoicedTicketId = '1';
afterAll(async() => {
await browser.close();
});
describe('as employee', () => {
it('should log in as employee, search for an invoice and get to services', async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult(invoicedTicketId);
await page.accessToSection('ticket.card.service');
});
it('should find the add descripton button disabled for this user role', async() => {
await page.waitForClassPresent(selectors.ticketService.firstAddServiceTypeButton, 'disabled');
await page.waitToClick(selectors.ticketService.addServiceButton);
await page.waitForSelector(selectors.ticketService.firstAddServiceTypeButton);
const disabled = await page.isDisabled(selectors.ticketService.firstAddServiceTypeButton);
expect(disabled).toBe(true);
});
it('should receive an error if you attempt to save a service without access rights', async() => {
await page.clearInput(selectors.ticketService.firstPrice);
await page.write(selectors.ticketService.firstPrice, '999');
await page.waitToClick(selectors.ticketService.saveServiceButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain(`The current ticket can't be modified`);
});
});
describe('as administrative', () => {
let editableTicketId = '16';
it('should navigate to the services of a target ticket', async() => {
await page.loginAndModule('administrative', 'ticket');
await page.accessToSearchResult(editableTicketId);
await page.accessToSection('ticket.card.service');
});
it('should click on the add button to prepare the form to create a new service', async() => {
await page.waitToClick(selectors.ticketService.addServiceButton);
const result = await page
.isVisible(selectors.ticketService.firstServiceType);
expect(result).toBeTruthy();
});
it('should receive an error if you attempt to save it with empty fields', async() => {
await page.waitToClick(selectors.ticketService.saveServiceButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain(`can't be blank`);
});
it('should click on the add new service type to open the dialog', async() => {
await page.waitToClick(selectors.ticketService.firstAddServiceTypeButton);
await page.waitForSelector('.vn-dialog.shown');
const result = await page.isVisible(selectors.ticketService.newServiceTypeName);
expect(result).toBeTruthy();
});
it('should receive an error if service type is empty on submit', async() => {
await page.waitToClick(selectors.ticketService.saveServiceTypeButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain(`Name can't be empty`);
});
it('should create a new service type then add price then create the service', async() => {
await page.write(selectors.ticketService.newServiceTypeName, 'Documentos');
await page.waitToClick(selectors.ticketService.saveServiceTypeButton);
await page.write(selectors.ticketService.firstPrice, '999');
await page.waitToClick(selectors.ticketService.saveServiceButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the service description was created correctly', async() => {
await page.reloadSection('ticket.card.service');
const result = await page
.waitToGetProperty(selectors.ticketService.firstServiceType, 'value');
expect(result).toEqual('Documentos');
});
it('should confirm the service quantity was created correctly', async() => {
const result = await page
.waitToGetProperty(selectors.ticketService.firstQuantity, 'value');
expect(result).toEqual('1');
});
it('should confirm the service price was created correctly', async() => {
const result = await page
.waitToGetProperty(selectors.ticketService.firstPrice, 'value');
expect(result).toEqual('999');
});
it('should delete the service', async() => {
await page.waitToClick(selectors.ticketService.fistDeleteServiceButton);
await page.waitForNumberOfElements(selectors.ticketService.serviceLine, 0);
await page.waitToClick(selectors.ticketService.saveServiceButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should confirm the service was removed`, async() => {
await page.reloadSection('ticket.card.service');
const nResults = await page.countElement(selectors.ticketService.serviceLine);
expect(nResults).toEqual(0);
});
});
});

View File

@ -0,0 +1,69 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket create path', () => {
let browser;
let page;
let nextMonth = Date.vnNew();
nextMonth.setMonth(nextMonth.getMonth() + 1);
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('salesPerson', 'ticket');
});
afterAll(async() => {
await browser.close();
});
it('should open the new ticket form', async() => {
await page.waitToClick(selectors.ticketsIndex.newTicketButton);
await page.waitForState('ticket.create');
});
it('should succeed to create a ticket', async() => {
await page.autocompleteSearch(selectors.createTicketView.client, 'Clark Kent');
await page.pickDate(selectors.createTicketView.deliveryDate, nextMonth);
await page.autocompleteSearch(selectors.createTicketView.warehouse, 'Warehouse Two');
await page.autocompleteSearch(selectors.createTicketView.agency, 'Gotham247');
await page.waitToClick(selectors.createTicketView.createButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should check the url is now the summary of the ticket', async() => {
await page.waitForState('ticket.card.summary');
});
it('should again open the new ticket form', async() => {
await page.waitToClick(selectors.globalItems.returnToModuleIndexButton);
await page.waitToClick(selectors.ticketsIndex.newTicketButton);
await page.waitForState('ticket.create');
});
it('should succeed to create another ticket for the same client', async() => {
await page.autocompleteSearch(selectors.createTicketView.client, 'Clark Kent');
await page.pickDate(selectors.createTicketView.deliveryDate, nextMonth);
await page.autocompleteSearch(selectors.createTicketView.warehouse, 'Warehouse One');
await page.autocompleteSearch(selectors.createTicketView.agency, 'Gotham247');
await page.waitToClick(selectors.createTicketView.createButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should check the url is now the summary of the created ticket', async() => {
await page.waitForState('ticket.card.summary');
});
it('should delete the current ticket', async() => {
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
await page.waitToClick(selectors.ticketDescriptor.acceptDialog);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Ticket deleted. You can undo this action within the first hour');
});
});

View File

@ -0,0 +1,37 @@
import getBrowser from '../../helpers/puppeteer';
const $ = {
form: 'vn-ticket-create-card',
moreMenu: 'vn-client-descriptor vn-icon-button[icon=more_vert]',
simpleTicketButton: '.vn-menu [name="simpleTicket"]'
};
describe('Ticket create from client path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'client');
await page.accessToSearchResult('Petter Parker');
});
afterAll(async() => {
await browser.close();
});
it('should create simple ticket and check if the client details are the expected ones', async() => {
await page.waitToClick($.moreMenu);
await page.waitToClick($.simpleTicketButton);
await page.waitForState('ticket.create');
const values = {
client: 'Petter Parker',
address: 'Petter Parker'
};
const formValues = await page.fetchForm($.form, Object.keys(values));
expect(formValues).toEqual(values);
});
});

View File

@ -0,0 +1,108 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Summary path', () => {
let browser;
let page;
const ticketId = '20';
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
});
afterAll(async() => {
await browser.close();
});
it('should navigate to the target ticket summary section', async() => {
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult(ticketId);
await page.waitForState('ticket.card.summary');
});
it(`should display details from the ticket and it's client on the top of the header`, async() => {
await page.waitForTextInElement(selectors.ticketSummary.header, 'Bruce Banner');
const result = await page.waitToGetProperty(selectors.ticketSummary.header, 'innerText');
expect(result).toContain(`Ticket #${ticketId}`);
expect(result).toContain('Bruce Banner (1109)');
expect(result).toContain('Somewhere in Thailand');
});
it('should display ticket details', async() => {
let result = await page
.waitToGetProperty(selectors.ticketSummary.state, 'innerText');
expect(result).toContain('Arreglar');
});
it('should display delivery details', async() => {
let result = await page
.waitToGetProperty(selectors.ticketSummary.route, 'innerText');
expect(result).toContain('3');
});
it('should display the ticket total', async() => {
let result = await page
.waitToGetProperty(selectors.ticketSummary.total, 'innerText');
expect(result).toContain('€155.54');
});
it('should display the ticket line(s)', async() => {
let result = await page
.waitToGetProperty(selectors.ticketSummary.firstSaleItemId, 'innerText');
expect(result).toContain('2');
});
it(`should click on the first sale ID to make the item descriptor visible`, async() => {
await page.waitToClick(selectors.ticketSummary.firstSaleItemId);
await page.waitImgLoad(selectors.ticketSummary.firstSaleDescriptorImage);
const visible = await page.isVisible(selectors.ticketSummary.itemDescriptorPopover);
expect(visible).toBeTruthy();
});
it(`should check the url for the item diary link of the descriptor is for the right item id`, async() => {
await page.waitForSelector(selectors.ticketSummary.itemDescriptorPopoverItemDiaryButton, {visible: true});
});
it('should log in as production then navigate to the summary of the same ticket', async() => {
await page.loginAndModule('production', 'ticket');
await page.accessToSearchResult(ticketId);
await page.waitForState('ticket.card.summary');
});
it('should set the ticket state to OK using the top right button', async() => {
const searchValue = 'OK';
await page.waitToClick(selectors.ticketSummary.stateButton);
await page.write(selectors.ticketSummary.stateAutocomplete, searchValue);
try {
await page.waitForFunction(text => {
const element = document.querySelector('li.active');
if (element)
return element.innerText.toLowerCase().includes(text.toLowerCase());
}, {}, searchValue);
} catch (error) {
const state = await page.evaluate(() => {
const stateSelector = 'vn-ticket-summary vn-label-value:nth-child(1) > section > span';
return document.querySelector(stateSelector).value;
});
throw new Error(`${stateSelector} innerText is ${state}! ${error}`);
}
await page.keyboard.press('Enter');
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it('should confirm the ticket state was updated', async() => {
await page.waitForSpinnerLoad();
const result = await page.waitToGetProperty(selectors.ticketSummary.state, 'innerText');
expect(result).toContain('OK');
});
});

View File

@ -0,0 +1,34 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket log path', () => {
let browser;
let page;
const ticketId = '5';
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
});
afterAll(async() => {
await browser.close();
});
it('should navigate to the target ticket notes section', async() => {
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult(ticketId);
await page.accessToSection('ticket.card.observation');
await page.waitForState('ticket.card.observation');
});
it('should create a new note for the test', async() => {
await page.waitToClick(selectors.ticketNotes.addNoteButton);
await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'ItemPicker');
await page.write(selectors.ticketNotes.firstDescription, 'description');
await page.waitToClick(selectors.ticketNotes.submitNotesButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
});

View File

@ -0,0 +1,70 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
const $ = {
newPayment: '.vn-dialog.shown',
anyBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr',
firstLineReference: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable'
};
describe('Ticket index payout path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('administrative', 'ticket');
await page.waitForState('ticket.index');
});
afterAll(async() => {
await browser.close();
});
it('should check the second ticket from a client and 1 of another', async() => {
await page.waitToClick(selectors.globalItems.searchButton);
await page.waitToClick(selectors.ticketsIndex.thirdTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.fifthTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.payoutButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('You cannot make a payment on account from multiple clients');
});
it('should search for tickets of the same client then open the payout form', async() => {
await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton);
await page.write(selectors.ticketsIndex.advancedSearchClient, '1101');
await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketsIndex.anySearchResult, 10);
await page.waitToClick(selectors.ticketsIndex.firstTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.payoutButton);
await page.waitForSelector(selectors.ticketsIndex.payoutCompany);
});
it('should fill the company and bank to perform a payout and check a new balance line was entered', async() => {
await page.fillForm($.newPayment, {
company: 'VNL',
bank: 'cash',
amountPaid: 100,
description: 'Payment',
viewReceipt: false
});
await page.respondToDialog('accept');
const message = await page.waitForSnackbar();
await page.waitToClick(selectors.globalItems.homeButton);
await page.selectModule('client');
await page.accessToSearchResult('1101');
await page.accessToSection('client.card.balance.index');
await page.waitForSelector($.anyBalanceLine);
const count = await page.countElement($.anyBalanceLine);
const reference = await page.innerText($.firstLineReference);
expect(message.isSuccess).toBeTrue();
expect(count).toEqual(4);
expect(reference).toContain('Payment');
});
});

View File

@ -0,0 +1,49 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket DMS path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.dms.index');
});
afterAll(async() => {
await browser.close();
});
it('should import a document', async() => {
await page.waitToClick(selectors.ticketDms.import);
await page.autocompleteSearch(selectors.ticketDms.document, '1');
await page.waitToClick(selectors.ticketDms.saveImport);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Data saved!');
});
it(`should check there's a listed document now`, async() => {
const result = await page.countElement(selectors.ticketDms.anyDocument);
expect(result).toEqual(1);
});
it('should attempt to import an existing document on this ticket', async() => {
await page.waitToClick(selectors.ticketDms.import);
await page.autocompleteSearch(selectors.ticketDms.document, '1');
await page.waitToClick(selectors.ticketDms.saveImport);
const message = await page.waitForSnackbar();
expect(message.text).toContain('This document already exists on this ticket');
});
it(`should check there's still one document`, async() => {
const result = await page.countElement(selectors.ticketDms.anyDocument);
expect(result).toEqual(1);
});
});

View File

@ -0,0 +1,50 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket expeditions', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('production', 'ticket');
await page.accessToSearchResult('1');
await page.accessToSection('ticket.card.expedition');
});
afterAll(async() => {
await browser.close();
});
it(`should move one expedition to new ticket withoute route`, async() => {
await page.waitToClick(selectors.ticketExpedition.thirdSaleCheckbox);
await page.waitToClick(selectors.ticketExpedition.moveExpeditionButton);
await page.waitToClick(selectors.ticketExpedition.moreMenuWithoutRoute);
await page.waitToClick(selectors.ticketExpedition.saveButton);
await page.waitForState('ticket.card.summary');
await page.accessToSection('ticket.card.expedition');
await page.waitForSelector(selectors.ticketExpedition.expeditionRow, {});
const result = await page
.countElement(selectors.ticketExpedition.expeditionRow);
expect(result).toEqual(2);
});
it(`should move one expedition to new ticket with route`, async() => {
await page.waitToClick(selectors.ticketExpedition.firstSaleCheckbox);
await page.waitToClick(selectors.ticketExpedition.moveExpeditionButton);
await page.waitToClick(selectors.ticketExpedition.moreMenuWithRoute);
await page.write(selectors.ticketExpedition.newRouteId, '1');
await page.waitToClick(selectors.ticketExpedition.saveButton);
await page.waitForState('ticket.card.summary');
await page.accessToSection('ticket.card.expedition');
await page.waitForSelector(selectors.ticketExpedition.expeditionRow, {});
const result = await page
.countElement(selectors.ticketExpedition.expeditionRow);
expect(result).toEqual(2);
});
});

View File

@ -0,0 +1,99 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Future path', () => {
let browser;
let page;
let httpRequest;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSection('ticket.future');
page.on('request', req => {
if (req.url().includes(`Tickets/getTicketsFuture`))
httpRequest = req.url();
});
});
afterAll(async() => {
await browser.close();
});
it('should search with required data, check three last tickets and move to the future', async() => {
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.warehouseFk);
await page.waitToClick(selectors.ticketFuture.submit);
let message = await page.waitForSnackbar();
expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.futureScopeDays);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('futureScopeDays is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.originScopeDays);
await page.waitToClick(selectors.ticketFuture.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('originScopeDays is a required argument');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketFuture.submit);
expect(httpRequest).toBeDefined();
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketFuture.ipt, 'H');
await page.waitToClick(selectors.ticketFuture.submit);
expect(httpRequest).toContain('ipt=H');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.ipt);
await page.autocompleteSearch(selectors.ticketFuture.futureIpt, 'H');
await page.waitToClick(selectors.ticketFuture.submit);
expect(httpRequest).toContain('futureIpt=H');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.futureIpt);
await page.autocompleteSearch(selectors.ticketFuture.state, 'Free');
await page.waitToClick(selectors.ticketFuture.submit);
expect(httpRequest).toContain('state=0');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.state);
await page.autocompleteSearch(selectors.ticketFuture.futureState, 'Free');
await page.waitToClick(selectors.ticketFuture.submit);
expect(httpRequest).toContain('futureState=0');
await page.waitToClick(selectors.ticketFuture.openAdvancedSearchButton);
await page.clearInput(selectors.ticketFuture.state);
await page.clearInput(selectors.ticketFuture.futureState);
await page.waitToClick(selectors.ticketFuture.submit);
await page.waitForNumberOfElements(selectors.ticketFuture.searchResult, 5);
await page.waitToClick(selectors.ticketFuture.multiCheck);
await page.waitToClick(selectors.ticketFuture.firstCheck);
await page.waitToClick(selectors.ticketFuture.moveButton);
await page.waitToClick(selectors.globalItems.acceptButton);
message = await page.waitForSnackbar();
expect(message.text).toContain('Tickets moved successfully!');
});
});

View File

@ -0,0 +1,79 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Advance path', () => {
let browser;
let page;
let httpRequest;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSection('ticket.advance');
page.on('request', req => {
if (req.url().includes(`Tickets/getTicketsAdvance`))
httpRequest = req.url();
});
});
afterAll(async() => {
await browser.close();
});
it('should search with the required data, check the first ticket and move to the present', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.warehouseFk);
await page.waitToClick(selectors.ticketAdvance.submit);
let message = await page.waitForSnackbar();
expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.dateToAdvance);
await page.waitToClick(selectors.ticketAdvance.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('dateToAdvance is a required argument');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.dateFuture);
await page.waitToClick(selectors.ticketAdvance.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('dateFuture is a required argument');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
expect(httpRequest).toBeDefined();
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.futureIpt, 'H');
await page.waitToClick(selectors.ticketAdvance.submit);
expect(httpRequest).toContain('futureIpt=H');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.futureIpt);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.ipt, 'H');
await page.waitToClick(selectors.ticketAdvance.submit);
expect(httpRequest).toContain('ipt=H');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.ipt);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitToClick(selectors.ticketAdvance.firstCheck);
await page.waitToClick(selectors.ticketAdvance.moveButton);
await page.waitToClick(selectors.ticketAdvance.acceptButton);
message = await page.waitForSnackbar();
expect(message.text).toContain('Tickets moved successfully!');
});
});

View File

@ -241,10 +241,10 @@
"The maximum height of the wagon is 200cm": "The maximum height of the wagon is 200cm", "The maximum height of the wagon is 200cm": "The maximum height of the wagon is 200cm",
"The quantity claimed cannot be greater than the quantity of the line": "The quantity claimed cannot be greater than the quantity of the line", "The quantity claimed cannot be greater than the quantity of the line": "The quantity claimed cannot be greater than the quantity of the line",
"There are tickets for this area, delete them first": "There are tickets for this area, delete them first", "There are tickets for this area, delete them first": "There are tickets for this area, delete them first",
"Payment method is required": "Payment method is required",
"You do not have permission to modify the booked field": "You do not have permission to modify the booked field", "You do not have permission to modify the booked field": "You do not have permission to modify the booked field",
"Invalid or expired verification code": "Invalid or expired verification code", "Invalid or expired verification code": "Invalid or expired verification code",
"ticketLostExpedition": "The ticket [{{ticketId}}]({{{ticketUrl}}}) has the following lost expedition:{{ expeditionId }}", "ticketLostExpedition": "The ticket [{{ticketId}}]({{{ticketUrl}}}) has the following lost expedition:{{ expeditionId }}",
"The raid information is not correct": "The raid information is not correct", "The raid information is not correct": "The raid information is not correct",
"Payment method is required": "Payment method is required",
"Sales already moved": "Sales already moved" "Sales already moved": "Sales already moved"
} }

View File

@ -0,0 +1,57 @@
<vn-crud-model
vn-id="model"
url="ItemBarcodes"
fields="['id', 'itemFk', 'code']"
link="{itemFk: $ctrl.$params.id}"
data="barcodes"
auto-load="true">
</vn-crud-model>
<vn-watcher
vn-id="watcher"
data="barcodes"
form="form">
</vn-watcher>
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal ng-repeat="barcode in barcodes track by $index">
<vn-textfield
vn-three
label="Code"
ng-model="barcode.code"
vn-acl="buyer, replenisher"
vn-focus>
</vn-textfield>
<vn-none>
<vn-icon-button
vn-acl="buyer,replenisher"
pointer
vn-tooltip="Remove barcode"
icon="delete"
ng-click="model.remove($index)">
</vn-icon-button>
</vn-none>
</vn-horizontal>
<vn-one>
<vn-icon-button
vn-acl="buyer, replenisher"
vn-tooltip="Add barcode"
vn-bind="+"
icon="add_circle"
ng-click="model.insert()">
</vn-icon-button>
</vn-one>
</vn-card>
<vn-button-bar>
<vn-submit
disabled="!watcher.dataChanged()"
label="Save">
</vn-submit>
<!-- # #2680 Undo changes button bugs -->
<!-- <vn-button
class="cancel"
label="Undo changes"
disabled="!watcher.dataChanged()"
ng-click="watcher.loadOriginalData()">
</vn-button> -->
</vn-button-bar>
</form>

View File

@ -0,0 +1,17 @@
import ngModule from '../module';
import Section from 'salix/components/section';
export default class Controller extends Section {
onSubmit() {
this.$.watcher.check();
this.$.model.save().then(() => {
this.$.watcher.notifySaved();
this.$.watcher.updateOriginalData();
});
}
}
ngModule.vnComponent('vnItemBarcode', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,318 @@
<mg-ajax
path="Items/{{patch.params.id}}"
options="vnPatch"
override="{filter: {include: [{relation: 'itemType'}, {relation: 'origin'}, {relation: 'ink'}, {relation: 'producer'}, {relation: 'expense'}]}}">
</mg-ajax>
<vn-watcher
vn-id="watcher"
data="$ctrl.item"
form="form"
save="patch">
</vn-watcher>
<vn-crud-model
auto-load="true"
url="Origins"
data="originsData"
order="name"
vn-id="origin-model">
</vn-crud-model>
<form name="form" ng-submit="watcher.submit()" ng-cloak class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-autocomplete
url="ItemTypes"
label="Type"
show-field="name"
value-field="id"
ng-model="$ctrl.item.typeFk"
vn-name="type"
initial-data="$ctrl.item.itemType"
fields="['categoryFk']"
include="'category'">
<tpl-item>
<div>{{::name}}</div>
<div class="text-caption text-secondary">
{{::category.name}}
</div>
</tpl-item>
</vn-autocomplete>
<vn-textfield
label="Reference"
ng-model="$ctrl.item.comment"
vn-name="comment"
rule>
</vn-textfield>
<vn-input-number
min="0"
label="Relevancy"
ng-model="$ctrl.item.relevancy"
vn-name="relevancy"
rule>
</vn-input-number>
</vn-horizontal>
<vn-horizontal>
<vn-input-number
min="0"
label="stems"
ng-model="$ctrl.item.stems"
vn-name="stems"
rule>
</vn-input-number>
<vn-input-number
min="0"
label="Multiplier"
ng-model="$ctrl.item.stemMultiplier"
vn-name="stemMultiplier">
</vn-input-number>
<vn-autocomplete
label="Generic"
url="Items/withName"
ng-model="$ctrl.item.genericFk"
vn-name="generic"
show-field="name"
value-field="id"
search-function="$ctrl.itemSearchFunc($search)"
order="id DESC"
tabindex="1">
<tpl-item>
<div>{{::name}}</div>
<div class="text-caption text-secondary">
#{{::id}}
</div>
</tpl-item>
<append>
<vn-icon-button
icon="filter_alt"
vn-click-stop="$ctrl.showFilterDialog($ctrl.item)"
vn-tooltip="Filter...">
</vn-icon-button>
</append>
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete
url="Intrastats"
label="Intrastat"
show-field="description"
value-field="id"
ng-model="$ctrl.item.intrastatFk"
vn-name="intrastat"
search-function="{or: [{id: {like: $search +'%'}}, {description: {like: '%'+ $search +'%'}}]}"
initial-data="$ctrl.item.intrastat">
<tpl-item>
<div>{{::description}}</div>
<div class="text-caption text-secondary">
#{{::id}}
</div>
</tpl-item>
<append>
<vn-icon-button
icon="add_circle"
vn-tooltip="New intrastat"
ng-click="$ctrl.showIntrastat($event)">
</vn-icon-button>
</append>
</vn-autocomplete>
<vn-autocomplete
url="Expenses"
label="Expense"
ng-model="$ctrl.item.expenseFk"
vn-name="expense"
initial-data="$ctrl.item.expense">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-input-number
min="0"
label="Weight/Piece"
ng-model="$ctrl.item.weightByPiece"
vn-name="weightByPiece"
rule>
</vn-input-number>
<vn-input-number
min="0"
label="Units/Box"
ng-model="$ctrl.item.packingOut"
vn-name="packingOut"
rule>
</vn-input-number>
<vn-input-number
min="0"
label="Recycled Plastic"
ng-model="$ctrl.item.recycledPlastic"
vn-name="recycledPlastic"
rule>
</vn-input-number>
<vn-input-number
min="0"
label="Non recycled plastic"
ng-model="$ctrl.item.nonRecycledPlastic"
vn-name="nonRecycledPlastic"
rule>
</vn-input-number>
</vn-horizontal>
<vn-horizontal>
<vn-check
label="Active"
ng-model="$ctrl.item.isActive"
vn-name="isActive">
</vn-check>
<vn-check
label="Price in kg"
ng-model="$ctrl.item.hasKgPrice"
vn-name="priceInKg">
</vn-check>
<vn-check
label="Fragile"
ng-model="$ctrl.item.isFragile"
vn-name="isFragile"
info="Is shown at website, app that this item cannot travel (wreath, palms, ...)">
</vn-check>
<vn-check
label="Do photo"
ng-model="$ctrl.item.isPhotoRequested"
vn-name="isPhotoRequested"
info="This item does need a photo">
</vn-check>
</vn-horizontal>
<vn-horizontal>
<vn-textarea
label="Description"
ng-model="$ctrl.item.description"
vn-name="description"
rule>
</vn-textarea>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit
disabled="!watcher.dataChanged()"
label="Save">
</vn-submit>
<vn-button
class="cancel"
label="Undo changes"
disabled="!watcher.dataChanged()"
ng-click="watcher.loadOriginalData()">
</vn-button>
</vn-button-bar>
</form>
<!-- Create custom agent dialog -->
<vn-dialog class="edit"
vn-id="intrastat"
on-accept="$ctrl.onIntrastatAccept()"
message="New intrastat">
<tpl-body>
<vn-horizontal>
<vn-input-number
vn-focus
label="Identifier"
ng-model="$ctrl.newIntrastat.intrastatId"
vn-name="id"
required="true">
</vn-input-number>
</vn-horizontal>
<vn-horizontal>
<vn-textfield
label="Description"
ng-model="$ctrl.newIntrastat.description"
vn-name="description"
required="true">
</vn-textfield>
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Create</button>
</tpl-buttons>
</vn-dialog>
<!-- Filter item dialog -->
<vn-dialog
vn-id="filterDialog"
message="Filter item">
<tpl-body class="itemFilter">
<vn-horizontal>
<vn-textfield
label="Name"
ng-model="$ctrl.itemFilterParams.name"
vn-focus>
</vn-textfield>
<vn-textfield
label="Size"
ng-model="$ctrl.itemFilterParams.size">
</vn-textfield>
<vn-autocomplete
label="Producer"
ng-model="$ctrl.itemFilterParams.producerFk"
url="Producers"
show-field="name"
value-field="id">
</vn-autocomplete>
<vn-autocomplete
label="Type"
ng-model="$ctrl.itemFilterParams.typeFk"
url="ItemTypes"
show-field="name"
value-field="id">
</vn-autocomplete>
<vn-autocomplete
label="Color"
ng-model="$ctrl.itemFilterParams.inkFk"
url="Inks"
show-field="name"
value-field="id">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal class="vn-mb-md">
<vn-button vn-none
label="Search"
ng-click="$ctrl.filter()">
</vn-button>
</vn-horizontal>
<vn-crud-model
vn-id="itemsModel"
url="Items/withName"
filter="$ctrl.itemFilter"
data="items"
limit="10">
</vn-crud-model>
<vn-data-viewer
model="itemsModel"
class="vn-w-lg">
<vn-table class="scrollable">
<vn-thead>
<vn-tr>
<vn-th shrink>ID</vn-th>
<vn-th expand>Item</vn-th>
<vn-th number>Size</vn-th>
<vn-th expand>Producer</vn-th>
<vn-th>Color</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody>
<a ng-repeat="item in items"
class="clickable vn-tr search-result"
ng-click="$ctrl.selectItem(item.id)">
<vn-td shrink>
<span
vn-click-stop="itemDescriptor.show($event, item.id)"
class="link">
{{::item.id}}
</span>
</vn-td>
<vn-td expand>{{::item.name}}</vn-td>
<vn-td number>{{::item.size}}</vn-td>
<vn-td expand>{{::item.producer.name}}</vn-td>
<vn-td>{{::item.ink.name}}</vn-td>
</a>
</vn-tbody>
</vn-table>
</vn-data-viewer>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.vnConfig.warehouseFk">
</vn-item-descriptor-popover>
</tpl-body>
</vn-dialog>

View File

@ -0,0 +1,87 @@
import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
showIntrastat(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.newIntrastat = {
taxClassFk: this.item.taxClassFk
};
this.$.intrastat.show();
}
onIntrastatAccept() {
const query = `Items/${this.$params.id}/createIntrastat`;
return this.$http.patch(query, this.newIntrastat)
.then(res => this.item.intrastatFk = res.data.id);
}
itemSearchFunc($search) {
return /^\d+$/.test($search)
? {id: $search}
: {name: {like: '%' + $search + '%'}};
}
showFilterDialog(item) {
this.activeItem = item;
this.itemFilterParams = {};
this.itemFilter = {
include: [
{
relation: 'producer',
scope: {
fields: ['name']
}
},
{
relation: 'ink',
scope: {
fields: ['name']
}
}
]
};
this.$.filterDialog.show();
}
selectItem(id) {
this.activeItem['genericFk'] = id;
this.$.filterDialog.hide();
}
filter() {
const filter = this.itemFilter;
const params = this.itemFilterParams;
const where = {};
for (let key in params) {
const value = params[key];
if (!value) continue;
switch (key) {
case 'name':
where[key] = {like: `%${value}%`};
break;
case 'producerFk':
case 'typeFk':
case 'size':
case 'inkFk':
where[key] = value;
}
}
filter.where = where;
this.$.itemsModel.applyFilter(filter);
}
}
ngModule.vnComponent('vnItemBasicData', {
template: require('./index.html'),
bindings: {
item: '<'
},
controller: Controller
});

View File

@ -0,0 +1,32 @@
import './index.js';
describe('vnItemBasicData', () => {
describe('Component vnItemBasicData', () => {
let $httpBackend;
let $scope;
let controller;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new();
const $element = angular.element('<vn-item-basic-data></vn-item-basic-data>');
controller = $componentController('vnItemBasicData', {$element, $scope});
controller.$.watcher = {};
controller.$params.id = 1;
controller.item = {id: 1, name: 'Rainbow Coral'};
}));
describe('onIntrastatAccept()', () => {
it('should pass the data to the watcher', () => {
const newIntrastatId = 20;
$httpBackend.expect('PATCH', 'Items/1/createIntrastat').respond({id: 20});
controller.onIntrastatAccept();
$httpBackend.flush();
expect(controller.item.intrastatFk).toEqual(newIntrastatId);
});
});
});
});

View File

@ -0,0 +1,19 @@
Reference: Referencia
Full name calculates based on tags 1-3. Is not recommended to change it manually: >-
El nombre completo se calcula
basado en los tags 1-3.
No se recomienda cambiarlo manualmente
Is active: Activo
Expense: Gasto
Price in kg: Precio en kg
New intrastat: Nuevo intrastat
Identifier: Identificador
Fragile: Frágil
Is shown at website, app that this item cannot travel (wreath, palms, ...): Se muestra en la web, app que este artículo no puede viajar (coronas, palmas, ...)
Multiplier: Multiplicador
Generic: Genérico
This item does need a photo: Este artículo necesita una foto
Do photo: Hacer foto
Recycled Plastic: Plástico reciclado
Non recycled plastic: Plástico no reciclado
Minimum sales quantity: Cantidad mínima de venta

View File

@ -0,0 +1,102 @@
<vn-watcher
vn-id="watcher"
data="$ctrl.botanical"
form="form">
</vn-watcher>
<form name="form" ng-submit="$ctrl.onSubmit()" ng-cloak class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-autocomplete
label="Genus"
ng-model="$ctrl.botanical.genusFk"
url="Genera"
show-field="name"
value-field="id">
<append>
<vn-icon-button
icon="add_circle"
vn-tooltip="New genus"
ng-click="$ctrl.showGenus($event)"
vn-acl="logisticBoss"
vn-acl-action="remove">
</vn-icon-button>
</append>
</vn-autocomplete>
<vn-autocomplete
label="Species"
ng-model="$ctrl.botanical.specieFk"
url="Species"
show-field="name"
value-field="id">
<tpl-item>
<div>{{name}}</div>
<div class="text-caption text-secondary">
{{genus.name}}
</div>
</tpl-item>
<append>
<vn-icon-button
icon="add_circle"
vn-tooltip="New species"
ng-click="$ctrl.showSpecies($event)"
vn-acl="logisticBoss"
vn-acl-action="remove">
</vn-icon-button>
</append>
</vn-autocomplete>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit
disabled="!watcher.dataChanged()"
label="Save">
</vn-submit>
<!-- # #2680 Undo changes button bugs -->
<!-- <vn-button
class="cancel"
label="Undo changes"
disabled="!watcher.dataChanged()"
ng-click="watcher.loadOriginalData()">
</vn-button> -->
</vn-button-bar>
</form>
<!-- Create new genus dialog -->
<vn-dialog class="edit"
vn-id="genus"
on-response="$ctrl.onGenusResponse($response)"
on-accept="$ctrl.onGenusAccept()"
message="New genus">
<tpl-body>
<vn-horizontal>
<vn-textfield vn-one vn-focus
label="Latin genus name"
ng-model="$ctrl.data.name"
required="true">
</vn-textfield>
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Create</button>
</tpl-buttons>
</vn-dialog>
<!-- Create new species dialog -->
<vn-dialog class="edit"
vn-id="species"
on-response="$ctrl.onSpeciesResponse($response)"
on-accept="$ctrl.onSpeciesAccept()"
message="New species">
<tpl-body>
<vn-horizontal>
<vn-textfield vn-one vn-focus
label="Latin species name"
ng-model="$ctrl.data.name"
required="true">
</vn-textfield>
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Create</button>
</tpl-buttons>
</vn-dialog>

View File

@ -0,0 +1,99 @@
import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
get item() {
return this._item;
}
set item(value) {
this._item = value;
if (value)
this.getBotanicalData();
}
showGenus(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.$.genus.show();
}
showSpecies(event) {
if (event.defaultPrevented) return;
event.preventDefault();
this.$.species.show();
}
onGenusAccept() {
try {
if (!this.data.name)
throw new Error(`The name of the genus can't be empty`);
this.$http.post(`genera`, this.data).then(res => {
this.vnApp.showMessage(this.$t('The genus has been created'));
this.emit('response', {$response: res.data});
this.onGenusResponse(res.data);
});
} catch (e) {
this.vnApp.showError(this.$t(e.message));
return false;
}
return true;
}
onSpeciesAccept() {
try {
if (!this.data.name)
throw new Error(`The name of the species can't be empty`);
this.$http.post(`species`, this.data).then(res => {
this.vnApp.showMessage(this.$t('The species has been created'));
this.emit('response', {$response: res.data});
this.onSpeciesResponse(res.data);
});
} catch (e) {
this.vnApp.showError(this.$t(e.message));
return false;
}
return true;
}
getBotanicalData() {
const filter = {
where: {itemFk: this.item.id}
};
const filterParams = encodeURIComponent(JSON.stringify(filter));
this.$http.get(`ItemBotanicals?filter=${filterParams}`).then(res => {
if (res.data[0])
this.botanical = res.data[0];
else
this.botanical = {itemFk: this.item.id};
});
}
onSubmit() {
this.$.watcher.check();
this.$http.patch(`ItemBotanicals`, this.botanical).then(() => {
this.$.watcher.notifySaved();
this.$.watcher.updateOriginalData();
});
}
onGenusResponse(response) {
this.botanical.genusFk = response.id;
}
onSpeciesResponse(response) {
this.botanical.specieFk = response.id;
}
}
ngModule.vnComponent('vnItemBotanical', {
template: require('./index.html'),
bindings: {
item: '<'
},
controller: Controller
});

View File

@ -0,0 +1,179 @@
import './index.js';
describe('vnItemBotanical', () => {
describe('Component vnItemBotanical', () => {
let $httpBackend;
let $scope;
let controller;
let vnApp;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _vnApp_) => {
$httpBackend = _$httpBackend_;
vnApp = _vnApp_;
jest.spyOn(vnApp, 'showError');
$scope = $rootScope.$new();
const $element = angular.element('<vn-item-botanical></vn-item-botanical>');
controller = $componentController('vnItemBotanical', {$element, $scope});
controller.item = {id: 5};
controller.$params = {itemFk: 5};
controller.$ = {
watcher: {
check: () => {},
notifySaved: () => {},
updateOriginalData: () => {}},
genus: {
show: () => {}
},
species: {
show: () => {}
}};
}));
beforeEach(() => {
const response = {data: 'MyResult'};
$httpBackend.whenRoute('GET', 'ItemBotanicals').respond(response);
});
describe('showGenus()', () => {
it('should do nothing in genus field if it default is prevented', () => {
const event = {
defaultPrevented: true,
preventDefault: () => {}
};
jest.spyOn(event, 'preventDefault');
jest.spyOn(controller.$.genus, 'show');
controller.showGenus(event);
expect(event.preventDefault).not.toHaveBeenCalledWith();
expect(controller.$.genus.show).not.toHaveBeenCalledWith();
});
it('should call show function in genus field when the default is not prevented', () => {
const event = {
defaultPrevented: false,
preventDefault: () => {}
};
jest.spyOn(event, 'preventDefault');
jest.spyOn(controller.$.genus, 'show');
controller.showGenus(event);
expect(event.preventDefault).toHaveBeenCalledWith();
expect(controller.$.genus.show).toHaveBeenCalledWith();
});
});
describe('showSpecies()', () => {
it('should do nothing in species field if it default is prevented', () => {
const event = {
defaultPrevented: true,
preventDefault: () => {}
};
jest.spyOn(event, 'preventDefault');
jest.spyOn(controller.$.species, 'show');
controller.showSpecies(event);
expect(event.preventDefault).not.toHaveBeenCalledWith();
expect(controller.$.species.show).not.toHaveBeenCalledWith();
});
it('should call show function in species field when the default is not prevented', () => {
const event = {
defaultPrevented: false,
preventDefault: () => {}
};
jest.spyOn(event, 'preventDefault');
jest.spyOn(controller.$.species, 'show');
controller.showSpecies(event);
expect(event.preventDefault).toHaveBeenCalledWith();
expect(controller.$.species.show).toHaveBeenCalledWith();
});
});
describe('onGenusAccept()', () => {
it('should throw an error if the item botanical has no genus name', () => {
jest.spyOn(controller.vnApp, 'showMessage');
controller.data = {};
controller.onGenusAccept();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The name of the genus can't be empty`);
});
it('should add the new genus', () => {
controller.data = {
id: 4,
name: 'Anilius'
};
$httpBackend.expectPOST('genera', controller.data).respond(200, controller.data);
controller.onGenusAccept();
$httpBackend.flush();
controller.onGenusResponse(controller.data);
expect(controller.botanical.genusFk).toEqual(controller.data.id);
});
});
describe('onSpeciesAccept()', () => {
it('should throw an error if the item botanical has no species name', () => {
jest.spyOn(controller.vnApp, 'showMessage');
controller.data = {};
controller.onSpeciesAccept();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The name of the species can't be empty`);
});
it('should add the new species', () => {
controller.data = {
id: 2,
name: 'Spasiva'
};
$httpBackend.expectPOST('species', controller.data).respond(200, controller.data);
controller.onSpeciesAccept();
$httpBackend.flush();
controller.onSpeciesResponse(controller.data);
});
});
describe('onSubmit()', () => {
it('should make HTTP POST request to save the genus and species data', () => {
jest.spyOn(controller.$.watcher, 'updateOriginalData');
jest.spyOn(controller.$.watcher, 'check');
jest.spyOn(controller.$.watcher, 'notifySaved');
$httpBackend.expectPATCH('ItemBotanicals').respond();
controller.onSubmit();
$httpBackend.flush();
expect(controller.$.watcher.updateOriginalData).toHaveBeenCalledWith();
expect(controller.$.watcher.check).toHaveBeenCalledWith();
expect(controller.$.watcher.notifySaved).toHaveBeenCalledWith();
});
});
describe('getBotanicalData()', () => {
it('should get the species and genus data references of the item', () => {
controller.getBotanicalData();
$httpBackend.flush();
expect(controller.botanical).toEqual(controller.$params);
});
});
});
});

View File

@ -0,0 +1,5 @@
The genus has been created: El genus ha sido creado
The species has been created: La especie ha sido creada
Latin species name: Nombre de la especie en latín
Latin genus name: Nombre del genus en latín
Species: Especie

View File

@ -0,0 +1,8 @@
<vn-portal slot="menu">
<vn-item-descriptor
warehouse-fk="$ctrl.warehouseFk"
item="$ctrl.item"
card-reload="$ctrl.reload()"></vn-item-descriptor>
<vn-left-menu source="card"></vn-left-menu>
</vn-portal>
<ui-view></ui-view>

View File

@ -0,0 +1,33 @@
import ngModule from '../module';
import ModuleCard from 'salix/components/module-card';
class Controller extends ModuleCard {
reload() {
this.$http.get(`Items/${this.$params.id}/getCard`)
.then(res => this.item = res.data);
this.$http.get('ItemConfigs/findOne')
.then(res => {
if (this.$state.getCurrentPath()[4].state.name === 'item.card.diary') return;
this.warehouseFk = res.data.warehouseFk;
this.getWarehouseName(res.data.warehouseFk);
});
}
getWarehouseName(warehouseFk) {
const filter = {
where: {id: warehouseFk}
};
this.$http.get('Warehouses/findOne', {filter})
.then(res => {
this.warehouseText = this.$t('WarehouseFk', {
warehouseName: res.data.name
});
});
}
}
ngModule.vnComponent('vnItemCard', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,32 @@
import './index.js';
describe('Item', () => {
describe('Component vnItemCard', () => {
let controller;
let $httpBackend;
let $state;
let data = {id: 1, name: 'fooName'};
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, _$httpBackend_, $stateParams, _$state_) => {
$httpBackend = _$httpBackend_;
$state = _$state_;
$state.getCurrentPath = () => [null, null, null, null, {state: {name: 'item.card.diary'}}];
let $element = angular.element('<div></div>');
controller = $componentController('vnItemCard', {$element});
$stateParams.id = data.id;
$httpBackend.whenRoute('GET', 'Items/:id/getCard').respond(data);
}));
it('should request data and set it on the controller', () => {
$httpBackend.expect('GET', `ItemConfigs/findOne`).respond({});
controller.reload();
$httpBackend.flush();
expect(controller.item).toEqual(data);
});
});
});

View File

@ -0,0 +1,95 @@
<vn-watcher
vn-id="watcher"
url="Items/new"
data="$ctrl.item"
insert-mode="true"
form="form">
</vn-watcher>
<vn-crud-model
auto-load="true"
url="Origins"
data="originsData"
order="name"
vn-id="origin-model">
</vn-crud-model>
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-textfield
label="Name"
ng-model="$ctrl.item.provisionalName"
vn-name="name"
vn-focus>
</vn-textfield>
<vn-autocomplete
ng-model="$ctrl.item.tag"
url="Tags"
show-field="name"
value-field="id"
label="Tag"
vn-name="tag">
</vn-autocomplete>
<vn-autocomplete
data="$ctrl.validPriorities"
label="Priority"
ng-model="$ctrl.item.priority"
show-field="priority"
value-field="priority"
vn-name="priority">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete
label="Type"
ng-model="$ctrl.item.typeFk"
vn-name="type"
url="ItemTypes"
fields="['code', 'categoryFk']"
search-function="{or: [{code: {like: $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
include="'category'">
<tpl-item>
<div style="display: flex;">
<div style="width: 3em; padding-right: 1em;">{{::code}}</div>
<div>{{::name}}</div>
</div>
<div class="text-caption text-secondary">
{{category.name}}
</div>
</tpl-item>
</vn-autocomplete>
<vn-autocomplete
label="Intrastat"
ng-model="$ctrl.item.intrastatFk"
vn-name="intrastat"
url="Intrastats"
show-field="description"
search-function="{or: [{id: {like: $search +'%'}}, {description: {like: '%'+ $search +'%'}}]}">
<tpl-item>
<div>{{::description}}</div>
<div class="text-caption text-secondary">
#{{::id}}
</div>
</tpl-item>
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-autocomplete
data="originsData"
label="Origin"
ng-model="$ctrl.item.originFk"
vn-name="origin">
</vn-autocomplete>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit
disabled="!watcher.dataChanged()"
label="Create">
</vn-submit>
<vn-button
class="cancel"
label="Cancel"
ui-sref="item.index">
</vn-button>
</vn-button-bar>
</form>

View File

@ -0,0 +1,40 @@
import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
constructor($element, $) {
super($element, $);
this.fetchDefaultPriorityTag();
}
fetchDefaultPriorityTag() {
this.validPriorities = [];
const filter = {fields: ['defaultPriority', 'defaultTag', 'validPriorities'], limit: 1};
this.$http.get(`ItemConfigs`, {filter})
.then(res => {
if (res.data) {
const dataRow = res.data[0];
dataRow.validPriorities.forEach(priority => {
this.validPriorities.push({priority});
});
this.item = {
priority: dataRow.defaultPriority,
tag: dataRow.defaultTag
};
}
});
}
onSubmit() {
this.$.watcher.submit().then(
json => this.$state.go('item.card.basicData', {id: json.data.id})
);
}
}
Controller.$inject = ['$element', '$scope'];
ngModule.vnComponent('vnItemCreate', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,37 @@
import './index.js';
describe('Item', () => {
describe('Component vnItemCreate', () => {
let $scope;
let $state;
let controller;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, $rootScope, _$state_) => {
$scope = $rootScope.$new();
$state = _$state_;
$scope.watcher = {
submit: () => {
return {
then: callback => {
callback({data: {id: 1}});
}
};
}
};
const $element = angular.element('<vn-item-create></vn-item-create>');
controller = $componentController('vnItemCreate', {$element, $scope});
}));
describe('onSubmit()', () => {
it(`should call submit() on the watcher then expect a callback`, () => {
jest.spyOn($state, 'go');
controller.onSubmit();
expect(controller.$state.go).toHaveBeenCalledWith('item.card.basicData', {id: 1});
});
});
});
});

View File

@ -0,0 +1 @@
Temporal name: Nombre temporal

View File

@ -0,0 +1,2 @@
<vn-card>
</vn-card>

View File

@ -0,0 +1,21 @@
import ngModule from '../module';
import Section from 'salix/components/section';
class Controller extends Section {
constructor($element, $) {
super($element, $);
}
async $onInit() {
this.$state.go('item.card.summary', {id: this.$params.id});
window.location.href = await this.vnApp.getUrl(`item/${this.$params.id}/diary`);
}
}
ngModule.vnComponent('vnItemDiary', {
template: require('./index.html'),
controller: Controller,
bindings: {
item: '<'
}
});

View File

@ -0,0 +1,40 @@
<vn-horizontal>
<vn-auto>
<section
class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.tag5}"
title="{{::$ctrl.item.tag5}}: {{::$ctrl.item.value5}}">
{{::$ctrl.item.value5}}
</section>
<section
class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.tag6}"
title="{{::$ctrl.item.tag6}}: {{::$ctrl.item.value6}}">
{{::$ctrl.item.value6}}
</section>
<section
class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.tag7}"
title="{{::$ctrl.item.tag7}}: {{::$ctrl.item.value7}}">
{{::$ctrl.item.value7}}
</section>
<section
class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.tag8}"
title="{{::$ctrl.item.tag8}}: {{::$ctrl.item.value8}}">
{{::$ctrl.item.value8}}
</section>
<section
class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.tag9}"
title="{{::$ctrl.item.tag9}}: {{::$ctrl.item.value9}}">
{{::$ctrl.item.value9}}
</section>
<section
class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.tag10}"
title="{{::$ctrl.item.tag10}}: {{::$ctrl.item.value10}}">
{{::$ctrl.item.value10}}
</section>
</vn-auto>
</vn-horizontal>

View File

@ -0,0 +1,12 @@
import ngModule from '../module';
import Component from 'core/lib/component';
import './style.scss';
ngModule.vnComponent('vnFetchedTags', {
template: require('./index.html'),
controller: Component,
bindings: {
maxLength: '<',
item: '<',
}
});

View File

@ -0,0 +1,61 @@
@import "variables";
[vn-fetched-tags] {
min-width: 155px;
& [wide] {
width: 430px;
}
& div {
display: flex;
flex-wrap: wrap;
align-items: center;
& vn-one {
min-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
font-size: 1rem;
}
& vn-one h3 {
color: $color-font-secondary;
text-transform: uppercase;
line-height: initial;
font-size: 0.75rem;
margin-bottom: 0px;
}
}
}
vn-fetched-tags {
& > vn-horizontal {
align-items: center;
max-width: 210px;
& > vn-auto {
flex-wrap: wrap;
& > .inline-tag {
margin: 1px;
}
}
& > vn-auto {
display: flex;
& > .inline-tag {
color: $color-font-secondary;
text-align: center;
font-size: .8rem;
height: 13px;
padding: 1px;
width: 64px;
min-width: 64px;
max-width: 64px;
flex: 1;
border: 1px solid $color-font-secondary;
&.empty {
border: 1px solid darken($color-font-secondary, 30%);
}
}
}
}
}

View File

@ -0,0 +1,214 @@
<vn-crud-model url="Tags" fields="['id','name','isFree']" data="$ctrl.tags" auto-load="true" />
<vn-crud-model url="ItemCategories" data="categories" auto-load="true" />
<vn-side-menu side="right">
<vn-horizontal class="input">
<vn-textfield
label="General search"
ng-model="$ctrl.filter.search"
info="Search items by id, name or barcode"
vn-focus
ng-keydown="$ctrl.onKeyPress($event)">
</vn-textfield>
</vn-horizontal>
<vn-horizontal class="item-category">
<vn-autocomplete
vn-id="category"
data="categories"
ng-model="$ctrl.filter.categoryFk"
show-field="name"
value-field="id"
label="Category">
</vn-autocomplete>
<vn-one ng-repeat="category in categories">
<vn-icon
ng-class="{'active': $ctrl.filter.categoryFk == category.id}"
icon="{{::category.icon}}"
vn-tooltip="{{::category.name}}"
ng-click="$ctrl.changeCategory(category.id)">
</vn-icon>
</vn-one>
</vn-horizontal>
<vn-vertical class="input">
<vn-autocomplete
vn-id="type"
disabled="!$ctrl.filter.categoryFk"
url="ItemTypes"
label="Type"
where="{categoryFk: $ctrl.filter.categoryFk}"
show-field="name"
value-field="id"
ng-model="$ctrl.filter.typeFk"
fields="['categoryFk']"
include="'category'"
on-change="$ctrl.addFilters()">
<tpl-item>
<div>{{name}}</div>
<div class="text-caption text-secondary">
{{category.name}}
</div>
</tpl-item>
</vn-autocomplete>
</vn-vertical>
<vn-horizontal class="input horizontal">
<vn-autocomplete
vn-id="buyer"
disabled="false"
ng-model="$ctrl.filter.buyerFk"
url="TicketRequests/getItemTypeWorker"
show-field="nickname"
search-function="{firstName: $search}"
value-field="id"
label="Buyer"
on-change="$ctrl.addFilters()">
</vn-autocomplete>
<vn-autocomplete
vn-id="warehouse"
label="Warehouse"
ng-model="$ctrl.filter.warehouseFk"
url="Warehouses"
show-field="name"
value-field="id"
on-change="$ctrl.addFilters()">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal class="input horizontal">
<vn-date-picker
label="From"
ng-model="$ctrl.filter.started"
on-change="$ctrl.addFilters()">
</vn-date-picker>
<vn-date-picker
label="To"
ng-model="$ctrl.filter.ended"
on-change="$ctrl.addFilters()">
</vn-date-picker>
</vn-horizontal>
<vn-horizontal class="input horizontal">
<vn-check
label="For me"
ng-model="$ctrl.filter.mine"
triple-state="true"
ng-click="$ctrl.addFilters()">
</vn-check>
<vn-check
label="Minimum price"
ng-model="$ctrl.filter.hasMinPrice"
triple-state="true"
ng-click="$ctrl.addFilters()">
</vn-check>
</vn-horizontal>
<vn-horizontal class="tags">
<vn-one class="text-subtitle1" translate> Tags </vn-one>
<vn-icon-button
vn-none
vn-tooltip="Add tag"
icon="add_circle"
ng-click="$ctrl.filter.tags.push({})">
</vn-icon-button>
</vn-horizontal>
<vn-horizontal class="tags horizontal" ng-repeat="itemTag in $ctrl.filter.tags">
<vn-autocomplete
vn-id="tag"
data="$ctrl.tags"
ng-model="itemTag.tagFk"
show-field="name"
label="Tag"
on-change="itemTag.value = null">
</vn-autocomplete>
<vn-textfield
ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
label="Value"
ng-model="itemTag.value"
ng-keydown="$ctrl.onKeyPress($event)">
</vn-textfield>
<vn-autocomplete
ng-show="tag.selection.isFree === false"
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
search-function="{value: $search}"
label="Value"
ng-model="itemTag.value"
show-field="value"
value-field="value"
on-change="$ctrl.addFilters()">
</vn-autocomplete>
<vn-icon-button
vn-none
vn-tooltip="Remove tag"
icon="delete"
ng-click="$ctrl.removeTag(itemTag)">
</vn-icon-button>
</vn-horizontal>
<div class="chips">
<vn-chip
ng-if="$ctrl.filter.search"
removable="true"
on-remove="$ctrl.removeItemFilter('search')"
class="colored">
<span>Id/{{$ctrl.$t('Name')}}: {{$ctrl.filter.search}}</span>
</vn-chip>
<vn-chip
ng-if="category.selection"
removable="true"
on-remove="$ctrl.removeItemFilter('categoryFk')"
class="colored">
<span>{{$ctrl.$t('Category')}}: {{category.selection.name}}</span>
</vn-chip>
<vn-chip
ng-if="type.selection"
removable="true"
on-remove="$ctrl.removeItemFilter('typeFk')"
class="colored">
<span>{{$ctrl.$t('Type')}}: {{type.selection.name}}</span>
</vn-chip>
<vn-chip
ng-if="buyer.selection"
removable="true"
on-remove="$ctrl.removeItemFilter('buyerFk')"
class="colored">
<span>{{$ctrl.$t('Buyer')}}: {{buyer.selection.nickname}}</span>
</vn-chip>
<vn-chip
ng-if="warehouse.selection"
removable="true"
on-remove="$ctrl.removeItemFilter('warehouseFk')"
class="colored">
<span>{{$ctrl.$t('Warehouse')}}: {{warehouse.selection.name}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.started"
removable="true"
on-remove="$ctrl.removeItemFilter('started')"
class="colored">
<span>{{$ctrl.$t('Started')}}: {{$ctrl.filter.started | date:'dd/MM/yyyy'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.ended"
removable="true"
on-remove="$ctrl.removeItemFilter('ended')"
class="colored">
<span>{{$ctrl.$t('Ended')}}: {{$ctrl.filter.ended | date:'dd/MM/yyyy'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.mine != null"
removable="true"
on-remove="$ctrl.removeItemFilter('mine')"
class="colored">
<span>{{$ctrl.$t('For me')}}: {{$ctrl.filter.mine ? '✓' : '✗'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.hasMinPrice != null"
removable="true"
on-remove="$ctrl.removeItemFilter('hasMinPrice')"
class="colored">
<span>{{$ctrl.$t('Minimum price')}}: {{$ctrl.filter.hasMinPrice ? '✓' : '✗'}}</span>
</vn-chip>
<vn-chip
ng-repeat="chipTag in $ctrl.filter.tags"
removable="true"
on-remove="$ctrl.removeTag(chipTag)"
class="colored"
ng-if="chipTag.value">
<span>{{$ctrl.showTagInfo(chipTag)}}</span>
</vn-chip>
</div>
</vn-side-menu>

View File

@ -0,0 +1,60 @@
import ngModule from '../module';
import SearchPanel from 'core/components/searchbar/search-panel';
import './style.scss';
class Controller extends SearchPanel {
constructor($element, $) {
super($element, $);
}
$onInit() {
this.filter = {
tags: []
};
}
changeCategory(id) {
if (this.filter.categoryFk != id) {
this.filter.categoryFk = id;
this.addFilters();
}
}
removeItemFilter(param) {
this.filter[param] = null;
if (param == 'categoryFk') this.filter['typeFk'] = null;
this.addFilters();
}
removeTag(tag) {
const index = this.filter.tags.indexOf(tag);
if (index > -1) this.filter.tags.splice(index, 1);
this.addFilters();
}
onKeyPress($event) {
if ($event.key === 'Enter')
this.addFilters();
}
addFilters() {
for (let i = 0; i < this.filter.tags.length; i++) {
if (!this.filter.tags[i].value)
this.filter.tags.splice(i, 1);
}
return this.model.addFilter({}, this.filter);
}
showTagInfo(itemTag) {
if (!itemTag.tagFk) return itemTag.value;
return `${this.tags.find(tag => tag.id == itemTag.tagFk).name}: ${itemTag.value}`;
}
}
ngModule.vnComponent('vnFixedPriceSearchPanel', {
template: require('./index.html'),
controller: Controller,
bindings: {
model: '<'
}
});

View File

@ -0,0 +1,56 @@
import './index.js';
describe('Item', () => {
describe('Component vnFixedPriceSearchPanel', () => {
let $element;
let controller;
beforeEach(ngModule('item'));
beforeEach(angular.mock.inject($componentController => {
$element = angular.element(`<vn-fixed-price-search-panel></vn-fixed-price-search-panel>`);
controller = $componentController('vnFixedPriceSearchPanel', {$element});
controller.model = {addFilter: () => {}};
}));
describe('removeItemFilter()', () => {
it(`should remove param from filter`, () => {
controller.filter = {tags: [], categoryFk: 1, typeFk: 1};
const expectFilter = {tags: [], categoryFk: null, typeFk: null};
controller.removeItemFilter('categoryFk');
expect(controller.filter).toEqual(expectFilter);
});
});
describe('removeTag()', () => {
it(`should remove tag from filter`, () => {
const tag = {tagFk: 1, value: 'Value'};
controller.filter = {tags: [tag]};
const expectFilter = {tags: []};
controller.removeTag(tag);
expect(controller.filter).toEqual(expectFilter);
});
});
describe('showTagInfo()', () => {
it(`should show tag value`, () => {
const tag = {value: 'Value'};
const result = controller.showTagInfo(tag);
expect(result).toEqual('Value');
});
it(`should show tag name and value`, () => {
const tag = {tagFk: 1, value: 'Value'};
controller.tags = [{id: 1, name: 'tagName'}];
const result = controller.showTagInfo(tag);
expect(result).toEqual('tagName: Value');
});
});
});
});

View File

@ -0,0 +1,4 @@
Started: Inicio
Ended: Fin
Minimum price: Precio mínimo
Item ID: ID Artículo

View File

@ -0,0 +1,71 @@
@import "variables";
vn-fixed-price-search-panel vn-side-menu {
.menu {
min-width: $menu-width;
}
& > div {
.input {
padding-left: $spacing-md;
padding-right: $spacing-md;
border-color: $color-spacer;
border-bottom: $border-thin;
}
.horizontal {
padding-left: $spacing-md;
padding-right: $spacing-md;
grid-auto-flow: column;
grid-column-gap: $spacing-sm;
align-items: center;
}
.tags {
padding: $spacing-md;
padding-bottom: 0%;
padding-top: 0%;
align-items: center;
}
.chips {
display: flex;
flex-wrap: wrap;
padding: $spacing-md;
overflow: hidden;
max-width: 100%;
border-color: $color-spacer;
border-top: $border-thin;
}
.item-category {
padding: $spacing-sm;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
vn-autocomplete[vn-id="category"] {
display: none;
}
& > vn-one {
padding: $spacing-sm;
min-width: 33.33%;
text-align: center;
box-sizing: border-box;
& > vn-icon {
padding: $spacing-sm;
background-color: $color-font-secondary;
border-radius: 50%;
cursor: pointer;
&.active {
background-color: $color-main;
color: #fff;
}
& > i:before {
font-size: 2.6rem;
width: 16px;
height: 16px;
}
}
}
}
}
}

View File

@ -0,0 +1,284 @@
<vn-crud-model
vn-id="model"
url="FixedPrices/filter"
user-params="::$ctrl.filterParams"
limit="20"
data="prices"
order="itemFk"
auto-load="false">
</vn-crud-model>
<vn-crud-model
auto-load="true"
url="Warehouses"
data="warehouses"
order="name">
</vn-crud-model>
<vn-portal slot="topbar">
</vn-portal>
<vn-fixed-price-search-panel
model="model">
</vn-fixed-price-search-panel>
<div class="vn-w-xl">
<vn-card>
<smart-table
model="model"
options="$ctrl.smartTableOptions"
expr-builder="$ctrl.exprBuilder(param, value)">
<slot-table>
<table>
<thead>
<tr>
<th shrink>
<vn-multi-check
model="model"
checked="$ctrl.checkAll"
check-field="checked"
check-dummy-enabled="true"
checked-dummy-count="$ctrl.checkedDummyCount">
</vn-multi-check>
</th>
<th field="itemFk">
<span translate>Item ID</span>
</th>
<th field="name">
<span translate>Description</span>
</th>
<th
field="rate2">
<span translate>Grouping price</span>
</th>
<th
field="rate3">
<span translate>Packing price</span>
</th>
<th field="minPrice">
<span translate>Min price</span>
</th>
<th field="started">
<span translate>Started</span>
</th>
<th field="ended">
<span translate>Ended</span>
</th>
<th field="warehouseFk">
<span translate>Warehouse</span>
</th>
<th shrink></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="price in prices">
<td>
<vn-check
ng-model="price.checked"
on-change="$ctrl.saveChecked(price.id)"
vn-click-stop>
</vn-check>
</td>
<td shrink-field>
<vn-autocomplete
vn-id="itemFk"
class="dense"
url="Items/withName"
ng-model="price.itemFk"
fields="['name']"
show-field="id"
value-field="id"
search-function="$ctrl.itemSearchFunc($search)"
ng-change="$ctrl.upsertPrice(price, true)"
order="id DESC"
tabindex="1">
<tpl-item>
<div>{{id}}</div>
<div class="text-caption text-secondary">
{{name}}
</div>
</tpl-item>
</vn-autocomplete>
</td>
<td vn-fetched-tags>
<div>
<span
vn-one
ng-if="price.itemFk"
ng-click="itemDescriptor.show($event, price.itemFk)"
class="link">
{{itemFk.selection.name}}
</span>
<vn-one ng-if="price.subName">
<h3 title="{{price.subName}}">{{price.subName}}</h3>
</vn-one>
</div>
<vn-fetched-tags
max-length="6"
item="price"
tabindex="-1">
</vn-fetched-tags>
</td>
<td shrink-field>
<vn-td-editable number>
<text>
<strong>{{price.rate2 | currency: 'EUR':2}}</strong>
</text>
<field>
<vn-input-number
class="dense"
vn-focus
ng-model="price.rate2"
on-change="$ctrl.upsertPrice(price)"
step="0.01">
</vn-input-number>
</field>
</vn-td-editable>
</td>
<td shrink-field>
<vn-td-editable number>
<text>
<strong>{{price.rate3 | currency: 'EUR':2}}</strong>
</text>
<field>
<vn-input-number
class="dense"
vn-focus
ng-model="price.rate3"
on-change="$ctrl.upsertPrice(price);"
step="0.01"s>
</vn-input-number>
</field>
</vn-td-editable>
</td>
<td shrink-field-expand class="minPrice">
<vn-check
vn-one
ng-model="price.hasMinPrice"
on-change="$ctrl.upsertPrice(price)">
</vn-check>
<vn-input-number
ng-class="{inactive: !price.hasMinPrice}"
ng-model="price.minPrice"
on-change="$ctrl.upsertPrice(price)"
step="0.01">
</vn-input-number>
</td>
<td shrink-date>
<vn-chip class="chip {{$ctrl.isBigger(price.started)}} transparent">
<vn-date-picker
vn-one
ng-model="price.started"
on-change="$ctrl.upsertPrice(price)">
</vn-date-picker>
</vn-chip>
</td>
<td shrink-date>
<vn-chip class="chip {{$ctrl.isLower(price.ended)}} transparent">
<vn-date-picker
vn-one
ng-model="price.ended"
on-change="$ctrl.upsertPrice(price)">
</vn-date-picker>
</vn-chip>
</td>
<td expand>
<vn-autocomplete
vn-one
ng-model="price.warehouseFk"
data="warehouses"
on-change="$ctrl.upsertPrice(price)"
tabindex="2">
</vn-autocomplete>
</td>
<td shrink>
<vn-icon-button
icon="delete"
vn-tooltip="Delete"
ng-click="deleteFixedPrice.show({$index})">
</vn-icon-button>
</td>
</tr>
</tbody>
</table>
<div class="vn-pa-md">
<vn-icon-button
vn-tooltip="Add fixed price"
icon="add_circle"
vn-bind="+"
ng-click="$ctrl.add()">
</vn-icon-button>
</div>
</slot-table>
</smart-table>
</vn-card>
</div>
<div fixed-bottom-right>
<vn-vertical style="align-items: center;">
<vn-button class="round sm vn-mb-sm"
icon="edit"
ng-show="$ctrl.totalChecked > 0"
ng-click="edit.show($event)"
vn-tooltip="Edit fixed price(s)"
tooltip-position="left">
</vn-button>
</vn-vertical>
</div>
<vn-dialog class="edit"
vn-id="edit"
on-accept="$ctrl.onEditAccept()"
on-close="$ctrl.editedColumn = null">
<tpl-body style="width: 400px;">
<span translate>Edit</span>
<span class="countLines">
{{::$ctrl.totalChecked}}
</span>
<span translate>buy(s)</span>
<vn-horizontal>
<vn-autocomplete
vn-one
ng-model="$ctrl.editedColumn.field"
data="$ctrl.columns"
value-field="field"
show-field="displayName"
label="Field to edit">
</vn-autocomplete>
<vn-input-number
vn-one
ng-if="$ctrl.editedColumn.field == 'rate2' || $ctrl.editedColumn.field == 'rate3' || $ctrl.editedColumn.field == 'minPrice'"
label="Value"
ng-model="$ctrl.editedColumn.newValue">
</vn-input-number>
<vn-check
vn-one
ng-if="$ctrl.editedColumn.field == 'hasMinPrice'"
ng-model="$ctrl.editedColumn.newValue">
</vn-check>
<vn-date-picker
vn-one
ng-if="$ctrl.editedColumn.field == 'started' || $ctrl.editedColumn.field == 'ended'"
label="Date"
ng-model="$ctrl.editedColumn.newValue">
</vn-date-picker>
<vn-autocomplete
vn-one
ng-if="$ctrl.editedColumn.field == 'warehouseFk'"
label="Warehouse"
ng-model="$ctrl.editedColumn.newValue"
data="warehouses">
</vn-autocomplete>
</vn-horizontal>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.vnConfig.warehouseFk">
</vn-item-descriptor-popover>
<vn-confirm
vn-id="deleteFixedPrice"
on-accept="$ctrl.removePrice($data.$index)"
question="Are you sure you want to continue?"
message="This row will be removed">
</vn-confirm>

View File

@ -0,0 +1,254 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
export default class Controller extends Section {
constructor($element, $) {
super($element, $);
this.editedColumn;
this.checkAll = false;
this.checkedFixedPrices = [];
this.smartTableOptions = {
activeButtons: {
search: true
},
columns: [
{
field: 'warehouseFk',
autocomplete: {
url: 'Warehouses',
showField: 'name',
valueField: 'id',
}
},
{
field: 'started',
searchable: false
},
{
field: 'ended',
searchable: false
}
]
};
this.filterParams = {
warehouseFk: this.vnConfig.warehouseFk
};
}
getFilterParams() {
return {
warehouseFk: this.vnConfig.warehouseFk
};
}
get columns() {
if (this._columns) return this._columns;
this._columns = [
{field: 'rate2', displayName: this.$t('Grouping price')},
{field: 'rate3', displayName: this.$t('Packing price')},
{field: 'hasMinPrice', displayName: this.$t('Has min price')},
{field: 'minPrice', displayName: this.$t('Min price')},
{field: 'started', displayName: this.$t('Started')},
{field: 'ended', displayName: this.$t('Ended')},
{field: 'warehouseFk', displayName: this.$t('Warehouse')}
];
return this._columns;
}
get checked() {
const fixedPrices = this.$.model.data || [];
const checkedBuys = [];
for (let fixedPrice of fixedPrices) {
if (fixedPrice.checked)
checkedBuys.push(fixedPrice);
}
return checkedBuys;
}
uncheck() {
this.checkAll = false;
this.checkedFixedPrices = [];
}
get totalChecked() {
if (this.checkedDummyCount)
return this.checkedDummyCount;
return this.checked.length;
}
saveChecked(fixedPriceId) {
const index = this.checkedFixedPrices.indexOf(fixedPriceId);
if (index !== -1)
return this.checkedFixedPrices.splice(index, 1);
return this.checkedFixedPrices.push(fixedPriceId);
}
reCheck() {
if (!this.$.model.data) return;
if (!this.checkedFixedPrices.length) return;
this.$.model.data.forEach(fixedPrice => {
if (this.checkedFixedPrices.includes(fixedPrice.id))
fixedPrice.checked = true;
});
}
onEditAccept() {
const rowsToEdit = [];
for (let row of this.checked)
rowsToEdit.push({id: row.id, itemFk: row.itemFk});
const data = {
field: this.editedColumn.field,
newValue: this.editedColumn.newValue,
lines: rowsToEdit
};
if (this.checkedDummyCount && this.checkedDummyCount > 0) {
const params = {};
if (this.$.model.userParams) {
const userParams = this.$.model.userParams;
for (let param in userParams) {
let newParam = this.exprBuilder(param, userParams[param]);
if (!newParam)
newParam = {[param]: userParams[param]};
Object.assign(params, newParam);
}
}
if (this.$.model.userFilter)
Object.assign(params, this.$.model.userFilter.where);
data.filter = params;
}
return this.$http.post('FixedPrices/editFixedPrice', data)
.then(() => {
this.uncheck();
this.$.model.refresh();
});
}
isBigger(date) {
let today = Date.vnNew();
today.setHours(0, 0, 0, 0);
date = new Date(date);
date.setHours(0, 0, 0, 0);
const timeDifference = today - date;
if (timeDifference < 0) return 'warning';
}
isLower(date) {
let today = Date.vnNew();
today.setHours(0, 0, 0, 0);
date = new Date(date);
date.setHours(0, 0, 0, 0);
const timeDifference = today - date;
if (timeDifference > 0) return 'warning';
}
add() {
if (!this.$.model.data || this.$.model.data.length == 0) {
this.$.model.data = [];
this.$.model.proxiedData = [];
const today = Date.vnNew();
const millisecsInDay = 86400000;
const daysInWeek = 7;
const nextWeek = new Date(today.getTime() + daysInWeek * millisecsInDay);
this.$.model.insert({
started: today,
ended: nextWeek
});
return;
}
const lastIndex = this.$.model.data.length - 1;
const lastItem = this.$.model.data[lastIndex];
this.$.model.insert({
itemFk: lastItem.itemFk,
name: lastItem.name,
subName: lastItem.subName,
value5: lastItem.value5,
value6: lastItem.value6,
value7: lastItem.value7,
value8: lastItem.value8,
value9: lastItem.value9,
value10: lastItem.value10,
warehouseFk: lastItem.warehouseFk,
rate2: lastItem.rate2,
rate3: lastItem.rate3,
hasMinPrice: lastItem.hasMinPrice,
minPrice: lastItem.minPrice,
started: lastItem.started,
ended: lastItem.ended,
});
}
upsertPrice(price, resetMinPrice) {
if (resetMinPrice)
delete price['minPrice'];
const requiredFields = ['itemFk', 'started', 'ended', 'rate2', 'rate3'];
for (const field of requiredFields)
if (price[field] == undefined) return;
const query = 'FixedPrices/upsertFixedPrice';
this.$http.patch(query, price)
.then(res => {
this.vnApp.showSuccess(this.$t('Data saved!'));
Object.assign(price, res.data);
});
}
removePrice($index) {
const price = this.$.model.data[$index];
if (price.id) {
this.$http.delete(`FixedPrices/${price.id}`)
.then(() => {
this.$.model.remove($index);
this.vnApp.showSuccess(this.$t('Data saved!'));
});
} else
this.$.model.remove($index);
}
itemSearchFunc($search) {
return /^\d+$/.test($search)
? {id: $search}
: {name: {like: '%' + $search + '%'}};
}
exprBuilder(param, value) {
switch (param) {
case 'name':
return {'i.name': {like: `%${value}%`}};
case 'itemFk':
case 'warehouseFk':
case 'rate2':
case 'rate3':
param = `fp.${param}`;
return {[param]: value};
case 'minPrice':
param = `i.${param}`;
return {[param]: value};
}
}
}
ngModule.vnComponent('vnFixedPrice', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,173 @@
import './index';
describe('fixed price', () => {
describe('Component vnFixedPrice', () => {
let controller;
let $httpBackend;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
$httpBackend = _$httpBackend_;
const $scope = $rootScope.$new();
const $element = angular.element('<vn-fixed-price></vn-fixed-price>');
controller = $componentController('vnFixedPrice', {$element, $scope});
controller.$ = {
model: {refresh: () => {}},
edit: {hide: () => {}}
};
}));
describe('get columns', () => {
it(`should return a set of columns`, () => {
let result = controller.columns;
let length = result.length;
let anyColumn = Object.keys(result[Math.floor(Math.random() * Math.floor(length))]);
expect(anyColumn).toContain('field', 'displayName');
});
});
describe('get checked', () => {
it(`should return a set of checked lines`, () => {
controller.$.model.data = [
{checked: true, id: 1},
{checked: true, id: 2},
{checked: true, id: 3},
{checked: false, id: 4},
];
let result = controller.checked;
expect(result.length).toEqual(3);
});
});
describe('reCheck()', () => {
it(`should recheck buys`, () => {
controller.$.model.data = [
{checked: false, id: 1},
{checked: false, id: 2},
{checked: false, id: 3},
{checked: false, id: 4},
];
controller.checkedFixedPrices = [1, 2];
controller.reCheck();
expect(controller.$.model.data[0].checked).toEqual(true);
expect(controller.$.model.data[1].checked).toEqual(true);
expect(controller.$.model.data[2].checked).toEqual(false);
expect(controller.$.model.data[3].checked).toEqual(false);
});
});
describe('saveChecked()', () => {
it(`should check buy`, () => {
const buyCheck = 3;
controller.checkedFixedPrices = [1, 2];
controller.saveChecked(buyCheck);
expect(controller.checkedFixedPrices[2]).toEqual(buyCheck);
});
it(`should uncheck buy`, () => {
const buyUncheck = 3;
controller.checkedFixedPrices = [1, 2, 3];
controller.saveChecked(buyUncheck);
expect(controller.checkedFixedPrices[2]).toEqual(undefined);
});
});
describe('onEditAccept()', () => {
it(`should perform a query to update columns`, () => {
controller.editedColumn = {field: 'my field', newValue: 'the new value'};
const query = 'FixedPrices/editFixedPrice';
$httpBackend.expectPOST(query).respond();
controller.onEditAccept();
$httpBackend.flush();
const result = controller.checked;
expect(result.length).toEqual(0);
});
});
describe('upsertPrice()', () => {
it('should do nothing if one or more required arguments are missing', () => {
jest.spyOn(controller.vnApp, 'showSuccess');
controller.upsertPrice({});
expect(controller.vnApp.showSuccess).not.toHaveBeenCalled();
});
it('should perform an http request to update the price', () => {
const now = Date.vnNew();
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expectPATCH('FixedPrices/upsertFixedPrice').respond();
controller.upsertPrice({
itemFk: 1,
started: now,
ended: now,
rate2: 1,
rate3: 2
});
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
});
});
describe('removePrice()', () => {
it(`should only remove the created instance by the model as it doesn't have an ID yet`, () => {
const $index = 0;
controller.$ = {
model: {
remove: () => {},
data: [{
foo: 'bar'
}]
}
};
jest.spyOn(controller.vnApp, 'showSuccess');
jest.spyOn(controller.$.model, 'remove');
$httpBackend.expectGET('Warehouses').respond();
controller.removePrice($index);
expect(controller.vnApp.showSuccess).not.toHaveBeenCalled();
expect(controller.$.model.remove).toHaveBeenCalled();
});
it('should remove the instance performing an delete http request', () => {
const $index = 0;
controller.$ = {
model: {
remove: () => {},
data: [{
id: '1'
}]
}
};
jest.spyOn(controller.vnApp, 'showSuccess');
jest.spyOn(controller.$.model, 'remove');
const query = `FixedPrices/${controller.$.model.data[0].id}`;
$httpBackend.expectDELETE(query).respond();
controller.removePrice($index);
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
expect(controller.$.model.remove).toHaveBeenCalled();
});
});
});
});

View File

@ -0,0 +1,7 @@
Fixed prices: Precios fijados
Search prices by item ID or code: Buscar por ID de artículo o código
Search fixed prices: Buscar precios fijados
Add fixed price: Añadir precio fijado
This row will be removed: Esta linea se eliminará
Edit fixed price(s): Editar precio(s) fijado(s)
Has min price: Tiene precio mínimo

View File

@ -0,0 +1,46 @@
@import "variables";
vn-fixed-price{
smart-table table{
[shrink-field]{
width: 90px;
max-width: 90px;
}
[shrink-field-expand]{
width: 150px;
max-width: 150px;
}
}
.minPrice {
align-items: center;
text-align: center;
vn-input-number {
width: 75px;
max-width: 75px;
}
}
smart-table table tbody > * > td .chip {
padding: 0px;
}
smart-table table tbody > * > td{
padding: 0px;
padding-left: 5px;
padding-right: 5px;
}
smart-table table tbody > * > td .chip.warning {
color: $color-font-bg
}
.vn-field > .container > .infix > .control > input {
color: inherit;
}
vn-input-number.inactive{
input {
color: $color-font-light !important;
}
}
}

View File

@ -1,6 +1,27 @@
export * from './module'; export * from './module';
import './main'; import './main';
import './index/';
import './search-panel';
import './diary';
import './create';
import './card';
import './descriptor'; import './descriptor';
import './descriptor-popover'; import './descriptor-popover';
import './basic-data';
import './fetched-tags';
import './tags';
import './tax';
import './log';
import './request';
import './request-search-panel';
import './last-entries';
import './botanical';
import './barcode';
import './summary';
import './waste/index/';
import './fixed-price';
import './fixed-price-search-panel';
import './item-type';
import './item-shelving';

View File

@ -0,0 +1,197 @@
<vn-auto-search
model="model">
</vn-auto-search>
<vn-card>
<smart-table
model="model"
view-config-id="itemsIndex"
options="$ctrl.smartTableOptions"
expr-builder="$ctrl.exprBuilder(param, value)">
<slot-table>
<table>
<thead>
<tr>
<th shrink></th>
<th field="id">
<span translate>Identifier</span>
</th>
<th field="grouping">
<span translate>Grouping</span>
</th>
<th field="packing">
<span translate>Packing</span>
</th>
<th field="name">
<span translate>Description</span>
</th>
<th field="stems">
<span translate>Stems</span>
</th>
<th field="size">
<span translate>Size</span>
</th>
<th field="typeFk">
<span translate>Type</span>
</th>
<th field="category">
<span translate>Category</span>
</th>
<th field="intrastat">
<span translate>Intrastat</span>
</th>
<th field="origin">
<span translate>Origin</span>
</th>
<th field="buyerFk">
<span translate>Buyer</span>
</th>
<th field="weightByPiece">
<span translate>Weight/Piece</span>
</th>
<th field="stemMultiplier">
<span translate>Multiplier</span>
</th>
<th field="active">
<span translate>Active</span>
</th>
<th field="producer">
<span translate>Producer</span>
</th>
<th field="landed">
<span translate>Landed</span>
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in model.data"
vn-anchor="::{
state: 'item.card.summary',
params: {id: item.id}
}">
<td>
<img
ng-src="{{::$root.imagePath('catalog', '50x50', item.id)}}"
zoom-image="{{::$root.imagePath('catalog', '1600x900', item.id)}}"
vn-click-stop
on-error-src/>
</td>
<td>
<span
vn-click-stop="itemDescriptor.show($event, item.id)"
class="link">
{{::item.id}}
</span>
</td>
<td>{{::item.grouping | dashIfEmpty}}</td>
<td>{{::item.packing | dashIfEmpty}}</td>
<td vn-fetched-tags>
<div>
<vn-one title="{{::item.name}}">{{::item.name}}</vn-one>
<vn-one ng-if="::item.subName">
<h3 title="{{::item.subName}}">{{::item.subName}}</h3>
</vn-one>
</div>
<vn-fetched-tags
max-length="6"
item="item"
tabindex="-1">
</vn-fetched-tags>
</td>
<td>{{::item.stems}}</td>
<td>{{::item.size}}</td>
<td title="{{::item.typeName}}">
{{::item.typeName}}
</td>
<td title="{{::item.category}}">
{{::item.category}}
</td>
<td title="{{::item.intrastat}}">
{{::item.intrastat}}
</td>
<td>{{::item.origin}}</td>
<td title="{{::item.userName}}">
<span
class="link"
vn-click-stop="workerDescriptor.show($event, item.buyerFk)">
{{::item.userName}}
</span>
</td>
<td>{{::item.weightByPiece}}</td>
<td>{{::item.stemMultiplier}}</td>
<td>
<vn-check
disabled="true"
ng-model="::item.isActive">
</vn-check>
</td>
<td>{{::item.producer | dashIfEmpty}}</td>
<td shrink-date>{{::item.landed | date:'dd/MM/yyyy'}}</td>
<td>
<vn-horizontal class="buttons">
<vn-icon-button
vn-click-stop="clone.show(item.id)"
vn-tooltip="Clone"
icon="icon-clone">
</vn-icon-button>
<vn-icon-button
vn-click-stop="$ctrl.preview(item)"
vn-tooltip="Preview"
icon="preview">
</vn-icon-button>
</vn-horizontal>
</td>
</tr>
</tbody>
</table>
</slot-table>
</smart-table>
</vn-card>
<a ui-sref="item.create" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
<vn-float-button icon="add"></vn-float-button>
</a>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.vnConfig.warehouseFk">
</vn-item-descriptor-popover>
<vn-worker-descriptor-popover
vn-id="worker-descriptor">
</vn-worker-descriptor-popover>
<vn-confirm
vn-id="clone"
on-accept="$ctrl.onCloneAccept($data)"
question="Do you want to clone this item?"
message="All it's properties will be copied">
</vn-confirm>
<vn-popup vn-id="preview">
<vn-item-summary
item="$ctrl.itemSelected">
</vn-item-summary>
</vn-popup>
<vn-contextmenu
vn-id="contextmenu"
targets="['smart-table']"
model="model"
expr-builder="$ctrl.exprBuilder(param, value)">
<slot-menu>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.filterBySelection()">
Filter by selection
</vn-item>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.excludeSelection()">
Exclude selection
</vn-item>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.removeFilter()">
Remove filter
</vn-item>
<vn-item translate
ng-click="contextmenu.removeAllFilters()">
Remove all filters
</vn-item>
</slot-menu>
</vn-contextmenu>

View File

@ -0,0 +1,112 @@
import ngModule from '../module';
import Section from 'salix/components/section';
import './style.scss';
class Controller extends Section {
constructor($element, $) {
super($element, $);
this.smartTableOptions = {
activeButtons: {
search: true,
shownColumns: true,
},
columns: [
{
field: 'category',
autocomplete: {
url: 'ItemCategories',
valueField: 'name',
}
},
{
field: 'origin',
autocomplete: {
url: 'Origins',
showField: 'code',
valueField: 'code'
}
},
{
field: 'typeFk',
autocomplete: {
url: 'ItemTypes',
}
},
{
field: 'intrastat',
autocomplete: {
url: 'Intrastats',
showField: 'description',
valueField: 'description'
}
},
{
field: 'buyerFk',
autocomplete: {
url: 'TicketRequests/getItemTypeWorker',
searchFunction: '{firstName: $search}',
showField: 'nickname',
valueField: 'id',
}
},
{
field: 'active',
searchable: false
},
{
field: 'landed',
searchable: false
},
]
};
}
exprBuilder(param, value) {
switch (param) {
case 'category':
return {'ic.name': value};
case 'buyerFk':
return {'it.workerFk': value};
case 'grouping':
return {'b.grouping': value};
case 'packing':
return {'b.packing': value};
case 'origin':
return {'ori.code': value};
case 'typeFk':
return {'i.typeFk': value};
case 'intrastat':
return {'intr.description': value};
case 'name':
return {'i.name': {like: `%${value}%`}};
case 'producer':
return {'pr.name': {like: `%${value}%`}};
case 'id':
case 'size':
case 'subname':
case 'isActive':
case 'weightByPiece':
case 'stemMultiplier':
case 'stems':
return {[`i.${param}`]: value};
}
}
onCloneAccept(itemFk) {
return this.$http.post(`Items/${itemFk}/clone`)
.then(res => {
this.$state.go('item.card.tags', {id: res.data.id});
});
}
preview(item) {
this.itemSelected = item;
this.$.preview.show();
}
}
ngModule.vnComponent('vnItemIndex', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,30 @@
import './index.js';
describe('Item', () => {
describe('Component vnItemIndex', () => {
let controller;
let $httpBackend;
let $scope;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new();
const $element = angular.element('<vn-item-index></vn-item-index>');
controller = $componentController('vnItemIndex', {$element, $scope});
}));
describe('onCloneAccept()', () => {
it('should perform a post query and then call go() then update itemSelected in the controller', () => {
jest.spyOn(controller.$state, 'go');
$httpBackend.expectRoute('POST', `Items/:id/clone`).respond({id: 99});
controller.onCloneAccept(1);
$httpBackend.flush();
expect(controller.$state.go).toHaveBeenCalledWith('item.card.tags', {id: 99});
});
});
});
});

View File

@ -0,0 +1,2 @@
picture: Foto
Buy requests: Peticiones de compra

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 30 24" style="enable-background:new 0 0 30 24;" xml:space="preserve" width="24px" heigth="24px">
<g>
<path d="M27,0H3C1.4,0,0,1.3,0,3v18c0,1.7,1.4,3,3,3h24c1.6,0,3-1.3,3-3V3C30,1.3,28.6,0,27,0z M27.9,19.8c0,1.4-1.2,2.6-2.6,2.6
H4.6c-1.4,0-2.6-1.2-2.6-2.6V4.2c0-1.4,1.2-2.6,2.6-2.6h20.7c1.4,0,2.6,1.2,2.6,2.6V19.8z"/>
<path d="M24.6,2.9H5.4c-1,0-1.9,0.8-1.9,1.9v14.4c0,1,0.8,1.9,1.9,1.9h19.1c1,0,1.9-0.8,1.9-1.9V4.8C26.4,3.8,25.6,2.9,24.6,2.9z"
/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 750 B

View File

@ -0,0 +1,34 @@
@import "variables";
vn-item-product {
display: block;
.id {
background-color: $color-main;
color: $color-font-dark;
margin-bottom: 0;
}
.image {
height: 112px;
width: 112px;
& > img {
max-height: 100%;
max-width: 100%;
border-radius: 3px;
}
}
vn-label-value:first-of-type section{
margin-top: 9px;
}
}
vn-item-index {
table {
img {
border-radius: 50%;
width: 50px;
height: 50px;
}
}
}

View File

@ -0,0 +1,118 @@
<vn-crud-model
vn-id="model"
url="ItemShelvingPlacementSupplyStocks"
link="{itemFk: $ctrl.$params.id}"
data="$ctrl.itemShelvingPlacementSupplyStocks"
auto-load="true">
</vn-crud-model>
<vn-card>
<smart-table
model="model"
options="$ctrl.smartTableOptions"
expr-builder="$ctrl.exprBuilder(param, value)">
<slot-actions>
<div>
<div class="totalBox" style="text-align: center;">
<h6 translate>Total</h6>
<vn-label-value
label="Total labels"
value="{{$ctrl.labelTotal.toFixed(2)}}">
</vn-label-value>
</div>
</div>
<div class="vn-pa-md">
<vn-button
disabled="!$ctrl.checked.length"
ng-click="removeConfirm.show()"
icon="delete"
vn-tooltip="Remove selected lines"
vn-acl="replenisherBos">
</vn-button>
</div>
</slot-actions>
<slot-table>
<table>
<thead>
<tr>
<th shrink>
<vn-multi-check
model="model">
</vn-multi-check>
</th>
<th field="created">
<span translate>Created</span>
</th>
<th shrink field="itemFk">
<span translate>Item</span>
</th>
<th
field="longName">
<span translate>Concept</span>
</th>
<th
field="parking">
<span translate>Parking</span>
</th>
<th field="shelving">
<span translate>Shelving</span>
</th>
<th
field="label">
<span translate>Etiqueta</span>
</th>
<th
field="packing"
shrink>
<span translate>Packing</span>
</th>
</tr>
</thead>
<tbody>
<tr
ng-repeat="itemShelvingPlacementSupplyStock in $ctrl.itemShelvingPlacementSupplyStocks"
vn-repeat-last on-last="$ctrl.calculateTotals()">
<td shrink>
<vn-check
ng-model="itemShelvingPlacementSupplyStock.checked"
vn-click-stop>
</vn-check>
</td>
<td shrink-date>{{::itemShelvingPlacementSupplyStock.created | date: 'dd/MM/yyyy'}}</td>
<td>
{{::itemShelvingPlacementSupplyStock.itemFk}}
</td>
<td expand title="{{::itemShelvingPlacementSupplyStock.longName}}">
<span
vn-click-stop="itemDescriptor.show($event, itemShelvingPlacementSupplyStock.itemFk)"
class="link">
{{itemShelvingPlacementSupplyStock.longName}}
</span>
</td>
<td>
{{::itemShelvingPlacementSupplyStock.parking}}
</td>
<td>
{{::itemShelvingPlacementSupplyStock.shelving}}
</td>
<td>
{{(itemShelvingPlacementSupplyStock.stock / itemShelvingPlacementSupplyStock.packing).toFixed(2)}}
</td>
<td>
{{::itemShelvingPlacementSupplyStock.packing}}
</td>
</tr>
</tbody>
</table>
</slot-table>
</smart-table>
</vn-card>
<vn-item-descriptor-popover
vn-id="item-descriptor">
</vn-item-descriptor-popover>
<vn-confirm
vn-id="removeConfirm"
message="Selected lines will be deleted"
question="Are you sure you want to continue?"
on-accept="$ctrl.onRemove()">
</vn-confirm>

View File

@ -0,0 +1,89 @@
import ngModule from '../module';
import Section from 'salix/components/section';
export default class Controller extends Section {
constructor($element, $) {
super($element, $);
this.smartTableOptions = {
activeButtons: {
search: true
},
columns: [
{
field: 'parking',
autocomplete: {
url: 'Parkings',
showField: 'code',
valueField: 'code'
}
},
{
field: 'shelving',
autocomplete: {
url: 'Shelvings',
showField: 'code',
valueField: 'code'
}
},
{
field: 'created',
searchable: false
},
{
field: 'itemFk',
searchable: false
},
{
field: 'longName',
searchable: false
}
]
};
}
get checked() {
const itemShelvings = this.$.model.data || [];
const checkedLines = [];
for (let itemShelving of itemShelvings) {
if (itemShelving.checked)
checkedLines.push(itemShelving.itemShelvingFk);
}
return checkedLines;
}
calculateTotals() {
this.labelTotal = 0;
const itemShelvings = this.$.model.data || [];
itemShelvings.forEach(itemShelving => {
const label = itemShelving.stock / itemShelving.packing;
this.labelTotal += label;
});
}
onRemove() {
const params = {itemShelvingIds: this.checked};
const query = `ItemShelvings/deleteItemShelvings`;
this.$http.post(query, params)
.then(() => {
this.vnApp.showSuccess(this.$t('ItemShelvings removed'));
this.$.model.refresh();
});
}
exprBuilder(param, value) {
switch (param) {
case 'parking':
case 'shelving':
case 'label':
case 'packing':
return {[param]: value};
}
}
}
ngModule.vnComponent('vnItemShelving', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1,81 @@
import './index';
import crudModel from 'core/mocks/crud-model';
describe('item shelving', () => {
describe('Component vnItemShelving', () => {
let controller;
let $httpBackend;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
const $element = angular.element('<vn-item-shelving></vn-item-shelving>');
controller = $componentController('vnItemShelving', {$element});
controller.$.model = crudModel;
controller.$.model.data = [
{itemShelvingFk: 1, packing: 10, stock: 1},
{itemShelvingFk: 2, packing: 12, stock: 5},
{itemShelvingFk: 4, packing: 20, stock: 10}
];
const modelData = controller.$.model.data;
modelData[0].checked = true;
modelData[1].checked = true;
}));
describe('checked() getter', () => {
it('should return a the selected rows', () => {
const result = controller.checked;
expect(result).toEqual(expect.arrayContaining([1, 2]));
});
});
describe('calculateTotals()', () => {
it('should calculate the total of labels', () => {
controller.calculateTotals();
expect(controller.labelTotal).toEqual(1.0166666666666666);
});
});
describe('onRemove()', () => {
it('shoud remove the selected lines', () => {
jest.spyOn(controller.$.model, 'refresh');
const expectedParams = {itemShelvingIds: [1, 2]};
$httpBackend.expectPOST('ItemShelvings/deleteItemShelvings', expectedParams).respond(200);
controller.onRemove();
$httpBackend.flush();
expect(controller.$.model.refresh).toHaveBeenCalled();
});
});
describe('exprBuilder()', () => {
it('should search by parking', () => {
const expr = controller.exprBuilder('parking', '700-01');
expect(expr).toEqual({'parking': '700-01'});
});
it('should search by shelving', () => {
const expr = controller.exprBuilder('shelving', 'AAA');
expect(expr).toEqual({'shelving': 'AAA'});
});
it('should search by label', () => {
const expr = controller.exprBuilder('label', 0.17);
expect(expr).toEqual({'label': 0.17});
});
it('should search by packing', () => {
const expr = controller.exprBuilder('packing', 10);
expect(expr).toEqual({'packing': 10});
});
});
});
});

View File

@ -0,0 +1,5 @@
Shelving: Matrícula
Remove selected lines: Eliminar líneas seleccionadas
Selected lines will be deleted: Las líneas seleccionadas serán eliminadas
ItemShelvings removed: Carros eliminados
Total labels: Total etiquetas

View File

@ -0,0 +1,62 @@
<vn-watcher
vn-id="watcher"
url="ItemTypes"
data="$ctrl.itemType"
form="form">
</vn-watcher>
<form
name="form"
ng-submit="watcher.submit()"
class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-vertical>
<vn-textfield
label="Code"
ng-model="$ctrl.itemType.code"
rule
vn-focus>
</vn-textfield>
<vn-textfield
label="Name"
ng-model="$ctrl.itemType.name"
rule>
</vn-textfield>
<vn-autocomplete
label="Worker"
ng-model="$ctrl.itemType.workerFk"
url="Workers/search"
show-field="nickname"
value-field="id"
rule>
</vn-autocomplete>
<vn-autocomplete
label="Category"
ng-model="$ctrl.itemType.categoryFk"
url="ItemCategories"
show-field="name"
value-field="id"
rule>
</vn-autocomplete>
<vn-autocomplete
label="Temperature"
ng-model="$ctrl.itemType.temperatureFk"
url="Temperatures"
show-field="name"
value-field="code"
rule>
</vn-autocomplete>
</vn-vertical>
</vn-card>
<vn-button-bar>
<vn-submit
disabled="!watcher.dataChanged()"
label="Save">
</vn-submit>
<vn-button
class="cancel"
label="Undo changes"
disabled="!watcher.dataChanged()"
ng-click="watcher.loadOriginalData()">
</vn-button>
</vn-button-bar>
</form>

View File

@ -0,0 +1,12 @@
import ngModule from '../../module';
import Section from 'salix/components/section';
export default class Controller extends Section {}
ngModule.component('vnItemTypeBasicData', {
template: require('./index.html'),
controller: Controller,
bindings: {
itemType: '<'
}
});

View File

@ -0,0 +1,5 @@
<vn-portal slot="menu">
<vn-item-type-descriptor item-type="$ctrl.itemType"></vn-item-type-descriptor>
<vn-left-menu source="itemType"></vn-left-menu>
</vn-portal>
<ui-view></ui-view>

View File

@ -0,0 +1,23 @@
import ngModule from '../../module';
import ModuleCard from 'salix/components/module-card';
class Controller extends ModuleCard {
reload() {
const filter = {
include: [
{relation: 'worker'},
{relation: 'category'},
{relation: 'itemPackingType'},
{relation: 'temperature'}
]
};
this.$http.get(`ItemTypes/${this.$params.id}`, {filter})
.then(res => this.itemType = res.data);
}
}
ngModule.vnComponent('vnItemTypeCard', {
template: require('./index.html'),
controller: Controller
});

Some files were not shown because too many files have changed in this diff Show More