Compare commits

...

144 Commits
beta ... dev

Author SHA1 Message Date
Robert Ferrús 89de87c280 Merge pull request 'feat: refs #8398 sendCheckingPresence' (!3362) from 8398-mergeSendCheckingPresenceBack into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3362
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-01-23 09:51:03 +00:00
Robert Ferrús 14e69c1c64 Merge branch 'dev' into 8398-mergeSendCheckingPresenceBack
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-23 08:21:32 +00:00
Jon Elias 64c697da6c Merge pull request '#7184: Created myTeam filter' (!3378) from 7184-MyTeamFilter into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3378
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-01-23 08:03:05 +00:00
Alex Moreno 8ebf68cc4c Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-23 08:34:08 +01:00
Alex Moreno 200a7cf995 Merge branch 'master' of https://gitea.verdnatura.es/verdnatura/salix into test
gitea/salix/pipeline/head This commit looks good Details
2025-01-23 08:33:58 +01:00
Jon Elias 602e822599 refactor: refs #7184 deleted .value
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-23 08:21:19 +01:00
Jon Elias 6d5a329b49 fix: refs #7184 fixed filter and test
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-22 17:09:01 +01:00
Jon Elias 0eff155daf refactor: refs #7184 created myteam filter and modified filters where it is used
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-22 16:34:14 +01:00
Alex Moreno 9d289fa11e build: init version
gitea/salix/pipeline/head This commit looks good Details
2025-01-21 11:57:35 +01:00
Robert Ferrús 0e0db6591e Merge pull request 'feat: refs #8401 create triggers to itemTaxCountry' (!3370) from 8401-itemTaxCountryTrigger into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3370
Reviewed-by: Carlos Andrés <carlosap@verdnatura.es>
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2025-01-21 10:37:13 +00:00
Robert Ferrús 77606468fd Merge branch 'master' into 8401-itemTaxCountryTrigger
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-21 10:07:28 +00:00
Robert Ferrús 405e0adaec Merge pull request 'feat: refs #8447 create tables tag' (!3375) from 8447-createTableTags2 into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3375
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2025-01-21 10:02:01 +00:00
Alex Moreno ded035285b Merge pull request '8448-devToTest' (!3373) from 8448-devToTest into test
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3373
Reviewed-by: Carlos Satorres <carlossa@verdnatura.es>
2025-01-21 10:00:49 +00:00
Alex Moreno 05b383ecb0 test: refs #8448 fix e2e
gitea/salix/pipeline/pr-test This commit looks good Details
2025-01-21 10:57:40 +01:00
Robert Ferrús 785a10a26a feat: refs #8447 create tables tag
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-21 09:34:56 +01:00
Sergio De la torre 6f73758cad Merge pull request '7569-sendEmailOrderTicket' (!3350) from 7569-sendEmailOrderTicket into dev
gitea/salix/pipeline/head This commit looks good Details
gitea/salix/pipeline/pr-test This commit looks good Details
Reviewed-on: #3350
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2025-01-21 06:29:28 +00:00
Sergio De la torre c50ff6a43a feat: refs #7569 refs#7569 sendEmailNotification
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-21 07:05:42 +01:00
Sergio De la torre eee73f001d Merge branch 'dev' of https: refs #7569//gitea.verdnatura.es/verdnatura/salix into 7569-sendEmailOrderTicket
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-21 07:00:02 +01:00
Sergio De la torre 7f17cd59e7 Merge branch 'dev' of https: refs #7569//gitea.verdnatura.es/verdnatura/salix into 7569-sendEmailOrderTicket 2025-01-21 06:58:15 +01:00
Sergio De la torre ef68884fe0 feat: refs #7569 refs#7569 sendEmailNotification
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-20 16:27:35 +01:00
Sergio De la torre b5e27707a7 feat: refs #7569 refs#7569 sendEmailNotification
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-20 12:36:31 +01:00
Sergio De la torre 0340612645 feat: refs #7569 refs#7569 sendEmailNotification
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-20 12:35:55 +01:00
Robert Ferrús 316a17304f feat: refs #8401 restriction itemFk
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-20 12:26:29 +01:00
Robert Ferrús 4b78c12ee4 Merge branch 'master' into 8401-itemTaxCountryTrigger
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-20 10:26:14 +00:00
Robert Ferrús cb065f42cd feat: refs #8401 change request
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-20 11:19:24 +01:00
Guillermo Bonet aa62f1d483 Merge branch 'test' into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-20 08:10:38 +01:00
Guillermo Bonet 86a2b1de1e Merge branch 'master' into test
gitea/salix/pipeline/head This commit looks good Details
2025-01-20 08:10:29 +01:00
Guillermo Bonet 9584ffcf5b feat: refs #7531 Added landed index
gitea/salix/pipeline/head This commit looks good Details
2025-01-20 08:10:12 +01:00
Guillermo Bonet 04180bf8da Merge branch 'test' into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-20 07:52:04 +01:00
Guillermo Bonet 5998002420 Merge branch 'master' into test
gitea/salix/pipeline/head This commit looks good Details
2025-01-20 07:51:45 +01:00
Guillermo Bonet fff6979921 Merge pull request 'feat: refs #7531 Added address_hasDelivery' (!3361) from 7531-addressHasDelivery into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3361
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2025-01-20 06:51:18 +00:00
Guillermo Bonet 7a5ed0ff23 Merge branch 'master' into 7531-addressHasDelivery
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-20 06:49:42 +00:00
Guillermo Bonet 934507569e feat: refs #7531 Added comment
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-20 07:48:43 +01:00
Guillermo Bonet e6abb1d759 feat: refs #7531 Minor change
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-20 07:41:41 +01:00
Guillermo Bonet 044a22bc3e feat: refs #7531 Deleted address_hasDelivery
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-20 07:13:04 +01:00
PAU ROVIRA ROSALENY 5ef1d615a7 Merge pull request 'feat: #8258 added uppercase validation on supplier create' (!3368) from 8258-uppercaseInputs into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3368
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2025-01-20 06:01:20 +00:00
Robert Ferrús 6c2071742c Merge branch 'dev' into 8398-mergeSendCheckingPresenceBack
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-19 07:38:25 +00:00
Robert Ferrús 5fe032ac75 feat: refs #8401 create triggers to itemTaxCountry
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-19 08:30:14 +01:00
PAU ROVIRA ROSALENY 1cdeadb59d feat: refs #8258 added uppercase validation on supplier create
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-17 13:20:45 +01:00
Guillermo Bonet e636d43f04 feat: refs #7531 Added address_hasDelivery
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-17 09:42:15 +01:00
Guillermo Bonet a666cfa4cd feat: refs #7531 Added address_hasDelivery
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-17 09:40:07 +01:00
Javi Gallego d4b7d54052 Merge pull request '8298-zonePriceOptimum' (!3345) from 8298-zonePriceOptimum into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3345
Reviewed-by: Pako Natek <pako@verdnatura.es>
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-01-17 08:30:44 +00:00
Guillermo Bonet 1aa1fbda6c feat: refs #7531 Added address_hasDelivery
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-17 08:10:26 +01:00
Guillermo Bonet 69b78b6bf1 feat: refs #7531 Added address_hasDelivery
gitea/salix/pipeline/pr-master There was a failure building this commit Details
2025-01-16 15:04:21 +01:00
Javi Gallego 125b7730e7 feat: refs #8298 update price calculation logic and add packagesDiscountFactor column to client table
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-16 12:56:04 +01:00
Robert Ferrús df3f4c3d2e Merge branch 'dev' into 8398-mergeSendCheckingPresenceBack
gitea/salix/pipeline/pr-dev Build queued... Details
2025-01-16 08:59:15 +00:00
Guillermo Bonet 4d98c340d2 feat: refs #7882 Added coords to create a address
gitea/salix/pipeline/head This commit looks good Details
2025-01-16 09:34:18 +01:00
Javi Gallego b8dbaec46c Merge pull request 'test: refs #8361 enhance exchangeRateUpdate specs with additional scenarios' (!3340) from 8361-exchangeRateUpdateWithFestiveDays into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3340
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
Reviewed-by: Carlos Andrés <carlosap@verdnatura.es>
2025-01-16 08:10:09 +00:00
Robert Ferrús 03c974db12 Merge pull request 'feat: refs #257275 defaulterFilter' (!3356) from hotFixDefaulterFilter into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3356
Reviewed-by: Carlos Andrés <carlosap@verdnatura.es>
2025-01-16 07:00:48 +00:00
Javi Gallego 69f1e76307 Merge pull request 'feat: refs #8381 add initial and final temperature fields to entry model and queries' (!3354) from 8381-entryTemperature into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3354
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-01-16 06:56:42 +00:00
Robert Ferrús 0e8b4d92bf Merge branch 'master' into hotFixDefaulterFilter
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-16 06:53:00 +00:00
Robert Ferrús 4853e45051 feat: refs #8398 change merge.spec
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-16 07:29:40 +01:00
Carlos Andrés c24b008567 Actualizar modules/travel/back/methods/travel/filter.js
gitea/salix/pipeline/head This commit looks good Details
2025-01-15 16:34:44 +00:00
Ivan Mas 8da1d866e3 Merge pull request 'refactor: refs #8378 deprecate bi.f_tvc' (!3365) from 8378-deprecateBi.f_tvc into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3365
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2025-01-15 15:12:08 +00:00
Ivan Mas 416e6c81f1 refactor: refs #8378 deprecate bi.f_tvc
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-15 15:22:48 +01:00
Robert Ferrús 6ab0515f8e feat: refs #8398 sendCheckingPresence
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-15 12:31:28 +01:00
Guillermo Bonet c2ca9cfbe5 feat: refs #7531 Added address_hasDelivery
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-15 12:26:16 +01:00
Jon Elias d0df1c1f42 Merge pull request '#8247: Added new acl for VnUser model' (!3358) from 8247-CreateNewAcl into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3358
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-01-15 10:51:25 +00:00
Robert Ferrús 620d14355c Merge branch 'master' into hotFixDefaulterFilter
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-15 09:12:45 +00:00
Carlos Satorres d95482ea54 Merge pull request 'fix: hotfix 7366 6943' (!3360) from hotfix-7366-6943CreditBillingDataAWB into master
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3360
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-01-15 07:00:40 +00:00
Carlos Satorres d9716154bb Merge branch 'master' into hotfix-7366-6943CreditBillingDataAWB
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-14 11:54:20 +00:00
Carlos Satorres 01072f7cbc fix: hotfix 7366 6943
gitea/salix/pipeline/pr-master There was a failure building this commit Details
2025-01-14 11:36:54 +01:00
Alex Moreno e273733832 refactor: order by id
gitea/salix/pipeline/head This commit looks good Details
2025-01-14 09:33:26 +01:00
Javi Gallego 44765b5a64 feat: refs #8361 add hasToDownloadRate field to currency model and update exchange rate logic
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-14 09:07:00 +01:00
Robert Ferrús 2585cce627 Merge branch 'master' into hotFixDefaulterFilter
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-14 07:17:17 +00:00
Alex Moreno 48ad72ac98 Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-14 08:00:08 +01:00
Alex Moreno 105a5045cf Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-14 07:37:33 +01:00
Jon Elias 29e6a99983 feat: refs #8247 added new acl for VnUser model
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-14 07:36:23 +01:00
Robert Ferrús 0891fc6665 Merge branch 'master' into hotFixDefaulterFilter
gitea/salix/pipeline/pr-master This commit looks good Details
2025-01-14 06:31:23 +00:00
Robert Ferrús c4870d52de feat: refs #257275 defaulterFilter
gitea/salix/pipeline/pr-master Build queued... Details
2025-01-13 14:37:27 +01:00
Javi Gallego c15a3bfe50 feat: refs #8381 add initial and final temperature fields to entry model and queries
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-13 11:28:30 +01:00
Alex Moreno e15fc01267 Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-13 09:19:37 +01:00
Alex Moreno 951376af2f Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-13 09:19:03 +01:00
Jose Antonio Tubau 1cd7eda4ac Merge pull request 'feat: refs #8117 add worker first and last name to item type query' (!3330) from 8117-filtersAndValuesReviewed into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3330
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
2025-01-13 06:13:31 +00:00
Robert Ferrús f6f8f2214c Merge pull request 'feat: refs #7584 workerTimeControl_afterDelete' (!3307) from 7584-workerTimeControl_afterDelete into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3307
Reviewed-by: Juan Ferrer <juan@verdnatura.es>
2025-01-10 10:05:59 +00:00
Robert Ferrús 1c30de5eee Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-10 09:36:09 +00:00
Robert Ferrús bdaaffbbd7 feat: refs #7584 changes request
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-10 10:33:19 +01:00
Sergio De la torre a1e1d4fa72 fix: refs #7569 refs·6861 ticketOrderReserve
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-10 07:20:24 +01:00
Sergio De la torre 12fa87a93c fix: refs #7569 refs·6861 ticketOrderReserve
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-09 16:15:29 +01:00
Guillermo Bonet e01d7c1fc6 Merge branch 'test' into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-09 14:51:40 +01:00
Guillermo Bonet 4e608eccc8 Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-09 11:34:59 +01:00
Guillermo Bonet 2f0a79da3f Merge branch 'test' into dev 2025-01-09 11:34:53 +01:00
Alex Moreno c8cfbf8d40 Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-09 09:59:26 +01:00
Guillermo Bonet 6b39e5c651 Merge branch 'test' into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-09 07:30:14 +01:00
Robert Ferrús eba9a1e38c Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-09 06:11:26 +00:00
Javi Gallego 53c604762a Merge branch 'dev' into 8298-zonePriceOptimum
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-08 13:43:17 +01:00
Ivan Mas f9666b8e60 Merge pull request 'feat: refs #7343 delete sending to user' (!3334) from 7343-modifyDriverRouteEmail into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3334
Reviewed-by: Guillermo Bonet <guillermo@verdnatura.es>
2025-01-08 12:17:49 +00:00
Ivan Mas 14b88b1ad6 Merge branch 'dev' into 7343-modifyDriverRouteEmail
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-08 12:16:01 +00:00
Javi Gallego be56313706 feat: refs #8298 add priceOptimum column to zoneEvent and update zone fixture data
gitea/salix/pipeline/pr-dev Build queued... Details
2025-01-08 11:58:50 +01:00
Robert Ferrús bdbc02e1b7 Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-08 10:46:45 +00:00
Alex Moreno f1b45a3903 Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-08 11:43:00 +01:00
Alex Moreno ecc877e07d Merge branch 'test' of https://gitea.verdnatura.es/verdnatura/salix into dev
gitea/salix/pipeline/head This commit looks good Details
2025-01-08 11:35:30 +01:00
Javi Gallego 0d822d03c9 fix: refs #8298 remove duplicate entry in English locale file
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-08 10:30:47 +01:00
Javi Gallego 1816b6de67 feat: refs #8298 add priceOptimum and packagesDiscountFactor to zone and client tables 2025-01-08 10:24:18 +01:00
Robert Ferrús 94ccdabe89 Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-08 06:23:04 +00:00
Ivan Mas 0940a31288 Merge branch 'dev' into 7343-modifyDriverRouteEmail
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 16:47:43 +00:00
Javi Gallego dbd8d816c0 fix: refs #8361 streamline transaction handling in exchangeRateUpdate
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 14:53:26 +01:00
Guillermo Bonet 2572182a89 Merge pull request 'feat: refs #8357 Agregados triggers para manejar exclusiones de trabajadores en la tabla workerMana' (!3341) from 8357-workerManaExcludedTriggers into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3341
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
2025-01-07 13:38:47 +00:00
Robert Ferrús 8417030438 Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 12:43:57 +00:00
Guillermo Bonet c83e6a8bbd Merge branch 'dev' into 8357-workerManaExcludedTriggers
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 12:28:23 +00:00
Ivan Mas b68ffb0819 Merge pull request 'feat: refs #8073 #refs 8073 create vn.productionCountryVolume' (!3321) from 8073-newTableProductionCountryVolume into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3321
Reviewed-by: Guillermo Bonet <guillermo@verdnatura.es>
2025-01-07 12:19:13 +00:00
Ivan Mas 23fb04876c Merge branch 'dev' into 8073-newTableProductionCountryVolume
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 12:16:20 +00:00
Guillermo Bonet 065f13557b feat: refs #8357 Agregados triggers para manejar exclusiones de trabajadores en la tabla workerMana
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 11:58:36 +01:00
Javi Gallego 786f1fe661 test: refs #8361 enhance exchangeRateUpdate specs to validate day1 and day2 entries without backfilling day3
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2025-01-07 11:06:09 +01:00
Javi Gallego 73d5d508ce test: refs #8361 enhance exchangeRateUpdate specs with additional scenarios
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 10:45:51 +01:00
Jon Elias b1dda9f82b Merge pull request '#7202 added new field in InvoiceOut module' (!3034) from 7202-AddCustomAgentFkColumn into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3034
Reviewed-by: Alex Moreno <alexm@verdnatura.es>
Reviewed-by: Carlos Andrés <carlosap@verdnatura.es>
2025-01-07 09:03:14 +00:00
Jon Elias c06f2c4e6f Merge branch 'dev' into 7202-AddCustomAgentFkColumn
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 09:00:26 +00:00
Alex Moreno 1d8dcdf63f build: add new version
gitea/salix/pipeline/head This commit looks good Details
2025-01-07 09:44:50 +01:00
Robert Ferrús f04f88d2fc Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 08:00:54 +00:00
Javi Gallego 399081f83c Merge pull request '#7832 - ticketServiceModifyConcept' (!3332) from 7832-ticketServiceModifyConcept into dev
gitea/salix/pipeline/head This commit looks good Details
Reviewed-on: #3332
Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
2025-01-07 07:45:41 +00:00
Javi Gallego 4f3c101e42 Merge branch 'dev' into 7832-ticketServiceModifyConcept
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 07:43:19 +00:00
Robert Ferrús 5c42130495 Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-07 06:15:15 +00:00
Alex Moreno cfe886b687 Merge branch 'dev' into 8117-filtersAndValuesReviewed
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-03 06:52:04 +00:00
Ivan Mas 8822fde7fb feat: refs #7343 delete sending to user
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-02 18:04:53 +01:00
Sergio De la torre 05b8c3451a Merge branch 'dev' of https: refs #7569//gitea.verdnatura.es/verdnatura/salix into 7569-sendEmailOrderTicket 2025-01-02 10:47:11 +01:00
Jon Elias fb57a1fa31 Merge branch '7202-AddCustomAgentFkColumn' of https://gitea.verdnatura.es/verdnatura/salix into 7202-AddCustomAgentFkColumn
gitea/salix/pipeline/pr-dev This commit looks good Details
2025-01-02 08:39:59 +01:00
Jon Elias 5221b9254a Merge branch 'dev' of https: refs #7202//gitea.verdnatura.es/verdnatura/salix into 7202-AddCustomAgentFkColumn 2025-01-02 08:39:57 +01:00
Javi Gallego 0ad26b336d fix: refs #7832 update ticketService model test suite to correct describe block
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2024-12-31 11:48:05 +01:00
Javi Gallego 1f23ebf6d5 feat: refs #7832 implement refund ticket restrictions and add unit tests for ticket service updates 2024-12-31 11:46:32 +01:00
Ivan Mas 1cc6e37697 Merge branch 'dev' into 8073-newTableProductionCountryVolume
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-31 07:36:21 +00:00
Jose Antonio Tubau 48d2d1d327 feat: refs #8117 add worker first and last name to item type query
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-26 10:41:20 +01:00
Ivan Mas c59cae9f74 feat: refs #8073 new comment message
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-19 14:38:28 +01:00
Ivan Mas da4968f8b1 Merge branch 'dev' into 8073-newTableProductionCountryVolume
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-19 12:55:23 +00:00
Ivan Mas b7666f5395 Merge branch 'dev' into 8073-newTableProductionCountryVolume
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-18 14:08:31 +00:00
Ivan Mas 148ab57b1a feat: refs #8073 change names and primary key
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-18 15:06:49 +01:00
Ivan Mas 5620242d7e Merge branch 'dev' into 8073-newTableProductionCountryVolume
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-18 12:30:16 +00:00
Ivan Mas 1ba23ad450 feat: refs #8073 #refs 8073 create vn.productionCountryVolume
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-18 13:27:43 +01:00
Robert Ferrús 68715a8c36 Merge branch 'dev' into 7584-workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-12-16 13:25:38 +00:00
Robert Ferrús 1d7e69cb25 feat: refs #7584 workerTimeControl_afterDelete
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2024-12-16 07:40:49 +01:00
Sergio De la torre 2c672951c6 fix: refs #7569 refs#8188 add IfNotExists 2024-12-12 20:33:00 +01:00
Sergio De la torre 31a6db5da0 feat: refs #7569 refs#7569 sendMail 2024-12-12 20:30:38 +01:00
Jon Elias 2c0f596175 Merge branch 'dev' into 7202-AddCustomAgentFkColumn
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-10-24 10:37:54 +00:00
Jon Elias da824516f3 Merge branch '7202-AddCustomAgentFkColumn' of https://gitea.verdnatura.es/verdnatura/salix into 7202-AddCustomAgentFkColumn
gitea/salix/pipeline/pr-dev Build queued... Details
2024-10-23 08:10:03 +02:00
Jon Elias 2ec0d7f186 refactor: refs #7202 modified new invoice procedure and incoterms sql 2024-10-23 08:10:00 +02:00
Jon Elias e91386dc92 Merge branch 'dev' into 7202-AddCustomAgentFkColumn
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-10-01 10:49:00 +00:00
Jon Elias f4015117e3 Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7202-AddCustomAgentFkColumn 2024-10-01 12:43:47 +02:00
Jon Elias 8e2359a672 Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7202-AddCustomAgentFkColumn 2024-10-01 11:37:01 +02:00
Jon Elias ce77d4bf2b Merge branch '7202-AddCustomAgentFkColumn' of https://gitea.verdnatura.es/verdnatura/salix into 7202-AddCustomAgentFkColumn
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2024-10-01 10:39:59 +02:00
Jon Elias a6799cba0f refactor: refs #7202 modified procedure to include customsAgent field when creating an invoice 2024-10-01 10:39:57 +02:00
Jon Elias 698ef3dec3 Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 7202-AddCustomAgentFkColumn 2024-10-01 10:12:21 +02:00
Jon Elias 5d4b79e313 Merge branch 'dev' into 7202-AddCustomAgentFkColumn
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-09-30 07:47:29 +00:00
Jon Elias 451e3bebef fix: refs #7202 fixed back test
gitea/salix/pipeline/pr-dev This commit looks good Details
2024-09-30 09:45:55 +02:00
Jon Elias da749a5dcb fix: refs #7202 fixed sql
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2024-09-30 09:21:05 +02:00
Jon Elias 6fbc5a1a54 feat: refs #7202 added new field
gitea/salix/pipeline/pr-dev There was a failure building this commit Details
2024-09-30 09:17:27 +02:00
72 changed files with 1117 additions and 362 deletions

View File

@ -158,13 +158,13 @@ INSERT INTO `account`.`mailForward`(`account`, `forwardTo`)
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`, `hasToDownloadRate`)
VALUES
(1, 'EUR', 'Euro', 1),
(2, 'USD', 'Dollar USA', 1.4),
(3, 'GBP', 'Libra', 1),
(4, 'JPY', 'Yen Japones', 1),
(5, 'CNY', 'Yuan Chino', 1.2);
(1, 'EUR', 'Euro', 1, FALSE),
(2, 'USD', 'Dollar USA', 1.4, TRUE),
(3, 'GBP', 'Libra', 1, TRUE),
(4, 'JPY', 'Yen Japones', 1, FALSE),
(5, 'CNY', 'Yuan Chino', 1.2, TRUE);
INSERT INTO `vn`.`country`(`id`, `name`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`, `hasDailyInvoice`, `CEE`)
VALUES
@ -426,50 +426,50 @@ INSERT INTO `vn`.`clientConfig`(`id`, `riskTolerance`, `maxCreditRows`, `maxPric
(1, 200, 10, 0.25, 2, 4, 5, 300.00, 1, 1, 2);
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`, `isDefaultAddress`)
INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `phone`, `mobile`, `isActive`, `clientFk`, `agencyModeFk`, `longitude`, `latitude`, `isEqualizated`, `isDefaultAddress`, `customsAgentFk`)
VALUES
(1, 'Bruce Wayne', '1007 Mountain Drive, Gotham', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, -74.1111111, 10.1111111, 0, 1),
(2, 'Petter Parker', '20 Ingram Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, -74.2222222, 10.2222222, 0, 1),
(3, 'Clark Kent', '344 Clinton Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.3333333, 10.3333333, 0, 1),
(4, 'Tony Stark', '10880 Malibu Point', 'Gotham', 46460, 1, 1111111111, 222222222, 1 , 1104, 2, -74.4444444, 10.4444444, 0, 1),
(5, 'Max Eisenhardt', 'Unknown Whereabouts', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 1),
(6, 'DavidCharlesHaller', 'Evil hideout', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 1),
(7, 'Hank Pym', 'Anthill', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 1),
(8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 1),
(9, 'Bruce Banner', 'Somewhere in New York', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 1),
(10, 'Jessica Jones', 'NYCC 2015 Poster', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 1),
(11, 'Missing', 'The space', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1111, 10, NULL, NULL, 0, 1),
(12, 'Trash', 'New York city', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1112, 10, NULL, NULL, 0, 1),
(101, 'Somewhere in Thailand', 'address 01', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(102, 'Somewhere in Poland', 'address 02', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0),
(103, 'Somewhere in Japan', 'address 03', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0),
(104, 'Somewhere in Spain', 'address 04', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0),
(105, 'Somewhere in Potugal', 'address 05', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(106, 'Somewhere in UK', 'address 06', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(107, 'Somewhere in Valencia', 'address 07', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(108, 'Somewhere in Gotham', 'address 08', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0),
(109, 'Somewhere in London', 'address 09', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(110, 'Somewhere in Algemesi', 'address 10', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(111, 'Somewhere in Carlet', 'address 11', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(112, 'Somewhere in Campanar', 'address 12', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(113, 'Somewhere in Malilla', 'address 13', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(114, 'Somewhere in France', 'address 14', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(115, 'Somewhere in Birmingham', 'address 15', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(116, 'Somewhere in Scotland', 'address 16', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(117, 'Somewhere in nowhere', 'address 17', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(118, 'Somewhere over the rainbow', 'address 18', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(119, 'Somewhere in Alberic', 'address 19', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(120, 'Somewhere in Montortal', 'address 20', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0),
(121, 'the bat cave', 'address 21', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, NULL, NULL, 0, 0),
(122, 'NY roofs', 'address 22', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, NULL, NULL, 0, 0),
(123, 'The phone box', 'address 23', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.555555, 10.555555, 0, 0),
(124, 'Stark tower Gotham', 'address 24', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1104, 2, NULL, NULL, 0, 0),
(125, 'The plastic cell', 'address 25', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 0),
(126, 'Many places', 'address 26', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 0),
(127, 'Your pocket', 'address 27', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 0),
(128, 'Cerebro', 'address 28', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 0),
(129, 'Luke Cages Bar', 'address 29', 'Gotham', 'EC170150', 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 0),
(130, 'Non valid address', 'address 30', 'Gotham', 46460, 1, 1111111111, 222222222, 0, 1101, 2, NULL, NULL, 0, 0);
(1, 'Bruce Wayne', '1007 Mountain Drive, Gotham', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, -74.1111111, 10.1111111, 0, 1, 1),
(2, 'Petter Parker', '20 Ingram Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, -74.2222222, 10.2222222, 0, 1, NULL),
(3, 'Clark Kent', '344 Clinton Street', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.3333333, 10.3333333, 0, 1, NULL),
(4, 'Tony Stark', '10880 Malibu Point', 'Gotham', 46460, 1, 1111111111, 222222222, 1 , 1104, 2, -74.4444444, 10.4444444, 0, 1, NULL),
(5, 'Max Eisenhardt', 'Unknown Whereabouts', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 1, NULL),
(6, 'DavidCharlesHaller', 'Evil hideout', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 1, NULL),
(7, 'Hank Pym', 'Anthill', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 1, NULL),
(8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 1, NULL),
(9, 'Bruce Banner', 'Somewhere in New York', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 1, NULL),
(10, 'Jessica Jones', 'NYCC 2015 Poster', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 1, NULL),
(11, 'Missing', 'The space', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1111, 10, NULL, NULL, 0, 1, NULL),
(12, 'Trash', 'New York city', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1112, 10, NULL, NULL, 0, 1, NULL),
(101, 'Somewhere in Thailand', 'address 01', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(102, 'Somewhere in Poland', 'address 02', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(103, 'Somewhere in Japan', 'address 03', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(104, 'Somewhere in Spain', 'address 04', 'Gotham', 46460, 1, 3333333333, 444444444, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(105, 'Somewhere in Potugal', 'address 05', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(106, 'Somewhere in UK', 'address 06', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(107, 'Somewhere in Valencia', 'address 07', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(108, 'Somewhere in Gotham', 'address 08', 'Gotham', 46460, 1, 5555555555, 666666666, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(109, 'Somewhere in London', 'address 09', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(110, 'Somewhere in Algemesi', 'address 10', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(111, 'Somewhere in Carlet', 'address 11', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(112, 'Somewhere in Campanar', 'address 12', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(113, 'Somewhere in Malilla', 'address 13', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(114, 'Somewhere in France', 'address 14', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(115, 'Somewhere in Birmingham', 'address 15', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(116, 'Somewhere in Scotland', 'address 16', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(117, 'Somewhere in nowhere', 'address 17', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(118, 'Somewhere over the rainbow', 'address 18', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(119, 'Somewhere in Alberic', 'address 19', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(120, 'Somewhere in Montortal', 'address 20', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1109, 2, NULL, NULL, 0, 0, NULL),
(121, 'the bat cave', 'address 21', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1101, 2, NULL, NULL, 0, 0, NULL),
(122, 'NY roofs', 'address 22', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1102, 2, NULL, NULL, 0, 0, NULL),
(123, 'The phone box', 'address 23', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1103, 2, -74.555555, 10.555555, 0, 0, NULL),
(124, 'Stark tower Gotham', 'address 24', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1104, 2, NULL, NULL, 0, 0, NULL),
(125, 'The plastic cell', 'address 25', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1105, 2, NULL, NULL, 0, 0, NULL),
(126, 'Many places', 'address 26', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1106, 2, NULL, NULL, 0, 0, NULL),
(127, 'Your pocket', 'address 27', 'Gotham', 46460, 1, 1111111111, 222222222, 1, 1107, 2, NULL, NULL, 0, 0, NULL),
(128, 'Cerebro', 'address 28', 'Gotham', 46460, 5, 1111111111, 222222222, 1, 1108, 2, NULL, NULL, 0, 0, NULL),
(129, 'Luke Cages Bar', 'address 29', 'Gotham', 'EC170150', 1, 1111111111, 222222222, 1, 1110, 2, NULL, NULL, 0, 0, NULL),
(130, 'Non valid address', 'address 30', 'Gotham', 46460, 1, 1111111111, 222222222, 0, 1101, 2, NULL, NULL, 0, 0, NULL);
INSERT INTO `vn`.`address`( `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `isActive`, `clientFk`, `agencyModeFk`, `isDefaultAddress`)
SELECT name, CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, 1, id, 2, 1
@ -648,13 +648,13 @@ INSERT INTO `vn`.`invoiceOutSerial`
('X', 'Exportación global', 0, 'WORLD', 0, 'global'),
('N', 'Múltiple Intracomunitaria', 0, 'CEE', 1, 'multiple');
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`)
INSERT INTO `vn`.`invoiceOut`(`id`, `serial`, `amount`, `issued`,`clientFk`, `created`, `companyFk`, `dued`, `booked`, `bankFk`, `hasPdf`, `customsAgentFk`, `incotermsFk`)
VALUES
(1, 'T', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(4, 'T', 8.88, util.VN_CURDATE(), 1104, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0),
(5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0);
(1, 'E', 1026.24, util.VN_CURDATE(), 1101, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, 1, 'FAS'),
(2, 'T', 121.36, util.VN_CURDATE(), 1102, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, NULL, NULL),
(3, 'T', 8.88, util.VN_CURDATE(), 1103, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, NULL, NULL),
(4, 'T', 8.88, util.VN_CURDATE(), 1104, util.VN_CURDATE(), 442, util.VN_CURDATE(), util.VN_CURDATE(), 1, 0, NULL, NULL),
(5, 'A', 8.88, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 442, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 0, NULL, NULL);
UPDATE `vn`.`invoiceOut` SET ref = 'T1111111' WHERE id = 1;
UPDATE `vn`.`invoiceOut` SET ref = 'T2222222' WHERE id = 2;
@ -694,22 +694,22 @@ INSERT INTO `vn`.`invoiceOutExpense`(`id`, `invoiceOutFk`, `amount`, `expenseFk`
(6, 4, 8.07, 2000000000, util.VN_CURDATE()),
(7, 5, 8.07, 2000000000, util.VN_CURDATE());
INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `agencyModeFk`, `travelingDays`, `price`, `bonus`, `itemMaxSize`)
VALUES
(1, 'Zone pickup A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100),
(2, 'Zone pickup B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100),
(3, 'Zone 247 A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100),
(4, 'Zone 247 B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100),
(5, 'Zone expensive A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100),
(6, 'Zone expensive B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100),
(7, 'Zone refund', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 23, 0, 1, 0, 100),
(8, 'Zone others', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 10, 0, 1, 0, 100),
(9, 'Zone superMan', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 2, 0, 1, 0, 100),
(10, 'Zone teleportation', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 3, 0, 1, 0, 100),
(11, 'Zone pickup C', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100),
(12, 'Zone entanglement', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 4, 0, 1, 0, 100),
(13, 'Zone quantum break', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 5, 0, 1, 0, 100);
INSERT INTO `vn`.`zone`
(`id`, `name`, `hour`, `agencyModeFk`, `travelingDays`, `price`, `bonus`, `itemMaxSize`, `priceOptimum`)
VALUES
(1, 'Zone pickup A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100, 1),
(2, 'Zone pickup B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100, 1),
(3, 'Zone 247 A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100, 1),
(4, 'Zone 247 B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 100, 1),
(5, 'Zone expensive A', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100, 500),
(6, 'Zone expensive B', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 100, 500),
(7, 'Zone refund', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 23, 0, 1, 0, 100, 0.5),
(8, 'Zone others', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 10, 0, 1, 0, 100, 0.5),
(9, 'Zone superMan', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 2, 0, 1, 0, 100, 0.5),
(10, 'Zone teleportation', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 3, 0, 1, 0, 100, 0.5),
(11, 'Zone pickup C', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 1, 0, 1, 0, 100, 0.5),
(12, 'Zone entanglement', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 4, 0, 1, 0, 100, 0.5),
(13, 'Zone quantum break', CONCAT(util.VN_CURDATE(), ' ', TIME('23:59')), 5, 0, 1, 0, 100, 0.5);
INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`)
VALUES

View File

@ -0,0 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` EVENT `vn`.`client_setPackagesDiscountFactor`
ON SCHEDULE EVERY 1 DAY
STARTS '2024-10-18 03:00:00.000'
ON COMPLETION PRESERVE
ENABLE
DO CALL client_setPackagesDiscountFactor()$$
DELIMITER ;

View File

@ -231,7 +231,19 @@ BEGIN
SELECT tcc.warehouseFK,
tcc.itemFk,
c2.id,
z.inflation * ROUND(ic.cm3delivery * (IFNULL(zo.price,5000) - IFNULL(zo.bonus,0)) / (1000 * vc.standardFlowerBox) , 4) cost
z.inflation
* ROUND(
ic.cm3delivery
* (
(
zo.priceOptimum + (( zo.price - zo.priceOptimum) * 2 * ( 1 - c.packagesDiscountFactor))
)
- IFNULL(zo.bonus, 0)
)
/ (1000 * vc.standardFlowerBox),
4
) cost
FROM tmp.ticketComponentCalculate tcc
JOIN item i ON i.id = tcc.itemFk
JOIN tmp.zoneOption zo ON zo.zoneFk = vZoneFk
@ -239,6 +251,7 @@ BEGIN
JOIN agencyMode am ON am.id = z.agencyModeFk
JOIN vn.volumeConfig vc
JOIN vn.component c2 ON c2.code = 'delivery'
JOIN `client` c on c.id = vClientFk
LEFT JOIN itemCost ic ON ic.warehouseFk = tcc.warehouseFk
AND ic.itemFk = tcc.itemFk
HAVING cost <> 0;

View File

@ -0,0 +1,25 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost`
PROCEDURE `vn`.`client_setPackagesDiscountFactor`()
BEGIN
/**
* Set the discount factor for the packages of the clients.
*/
UPDATE client c
JOIN (
SELECT t.clientFk,
LEAST((
SUM(t.packages) / COUNT(DISTINCT DATE(t.shipped))
) / cc.packagesOptimum, 1) discountFactor
FROM ticket t
JOIN clientConfig cc ON TRUE
WHERE t.shipped > util.VN_CURDATE() - INTERVAL cc.monthsToCalcOptimumPrice MONTH
AND t.packages
GROUP BY t.clientFk
) ca ON c.id = ca.clientFk
SET c.packagesDiscountFactor = ca.discountFactor;
END$$
DELIMITER ;

View File

@ -34,6 +34,7 @@ BEGIN
DECLARE vMaxShipped DATE;
DECLARE vDone BOOL;
DECLARE vTicketFk INT;
DECLARE vAddressFk INT;
DECLARE vCursor CURSOR FOR
SELECT id
FROM tmp.ticketToInvoice;
@ -48,11 +49,13 @@ BEGIN
DATE(vInvoiceDate) >= invoiceOut_getMaxIssued(
vSerial,
t.companyFk,
YEAR(vInvoiceDate))
YEAR(vInvoiceDate)),
t.addressFk
INTO vClientFk,
vCompanyFk,
vMaxShipped,
vIsCorrectInvoiceDate
vIsCorrectInvoiceDate,
vAddressFk
FROM tmp.ticketToInvoice tt
JOIN ticket t ON t.id = tt.id;
@ -105,7 +108,9 @@ BEGIN
clientFk,
dued,
companyFk,
siiTypeInvoiceOutFk
siiTypeInvoiceOutFk,
customsAgentFk,
incotermsFk
)
SELECT
1,
@ -118,9 +123,12 @@ BEGIN
vCplusCorrectingInvoiceTypeFk,
IF(vSerial = vSimplifiedSerial,
vCplusSimplifiedInvoiceTypeFk,
vCplusStandardInvoiceTypeFk))
FROM client
WHERE id = vClientFk;
vCplusStandardInvoiceTypeFk)),
a.customsAgentFk,
a.incotermsFk
FROM client c
JOIN address a ON a.id = vAddressFk
WHERE c.id = vClientFk;
SET vNewInvoiceId = LAST_INSERT_ID();

View File

@ -19,6 +19,7 @@ BEGIN
sub2.iptd futureIpt,
sub2.state futureState,
t.clientFk,
cl.salespersonFk,
t.warehouseFk,
ts.alertLevel,
sub2.alertLevel futureAlertLevel,
@ -38,6 +39,7 @@ BEGIN
JOIN vn.province p ON p.id = a.provinceFk
JOIN vn.country c ON c.id = p.countryFk
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.client cl ON cl.id = t.clientFk
JOIN vn.state st ON st.id = ts.stateFk
JOIN vn.alertLevel al ON al.id = ts.alertLevel
LEFT JOIN vn.ticketParking tp ON tp.ticketFk = t.id

View File

@ -1,26 +1,27 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `vn`.`zone_getAddresses`(
vSelf INT,
vShipped DATE,
vLanded DATE,
vDepartmentFk INT
)
BEGIN
/**
* Devuelve un listado de todos los clientes activos
* con consignatarios a los que se les puede
* vender producto para esa zona.
* entregar producto para esa zona.
*
* @param vSelf Id de zona
* @param vShipped Fecha de envio
* @param vDepartmentFk Id de departamento
* @param vLanded Fecha de entrega
* @param vDepartmentFk Id de departamento | NULL para mostrar todos
* @return Un select
*/
CALL zone_getPostalCode(vSelf);
WITH clientWithTicket AS (
SELECT clientFk
SELECT DISTINCT clientFk
FROM vn.ticket
WHERE shipped BETWEEN vShipped AND util.dayEnd(vShipped)
WHERE landed BETWEEN vLanded AND util.dayEnd(vLanded)
AND NOT isDeleted
)
SELECT c.id,
c.name,
@ -30,7 +31,7 @@ BEGIN
u.name username,
aai.invoiced,
cnb.lastShipped,
cwt.clientFk
IF(cwt.clientFk, TRUE, FALSE) hasTicket
FROM vn.client c
JOIN vn.worker w ON w.id = c.salesPersonFk
JOIN vn.workerDepartment wd ON wd.workerFk = w.id
@ -50,7 +51,7 @@ BEGIN
AND c.isActive
AND ct.code = 'normal'
AND bt.code <> 'worker'
AND (d.id = vDepartmentFk OR NOT vDepartmentFk)
AND (d.id = vDepartmentFk OR vDepartmentFk IS NULL)
GROUP BY c.id;
DROP TEMPORARY TABLE tmp.zoneNodes;

View File

@ -30,6 +30,7 @@ BEGIN
TIME(IFNULL(e.`hour`, z.`hour`)) `hour`,
l.travelingDays,
IFNULL(e.price, z.price) price,
IFNULL(e.priceOptimum, z.priceOptimum) priceOptimum,
IFNULL(e.bonus, z.bonus) bonus,
l.landed,
vShipped shipped

View File

@ -0,0 +1,8 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`itemTaxCountry_beforeDelete`
BEFORE DELETE ON `itemTaxCountry`
FOR EACH ROW
BEGIN
CALL util.throw('Records in this table cannot be deleted');
END$$
DELIMITER ;

View File

@ -4,5 +4,9 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`itemTaxCountry_beforeUp
FOR EACH ROW
BEGIN
SET NEW.editorFk = account.myUser_getId();
IF NOT(NEW.`countryFk` <=> OLD.`countryFk`) OR NOT(NEW.`itemFk` <=> OLD.`itemFk`) THEN
CALL util.throw('Only the VAT can be modified');
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,9 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerManaExcluded_beforeInsert`
BEFORE INSERT ON `workerManaExcluded`
FOR EACH ROW
BEGIN
DELETE FROM workerMana
WHERE workerFk = NEW.workerFk;
END$$
DELIMITER ;

View File

@ -0,0 +1,9 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerManaExcluded_beforeUpdate`
BEFORE UPDATE ON `workerManaExcluded`
FOR EACH ROW
BEGIN
DELETE FROM workerMana
WHERE workerFk = NEW.workerFk;
END$$
DELIMITER ;

View File

@ -0,0 +1,10 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerMana_beforeInsert`
BEFORE INSERT ON `workerMana`
FOR EACH ROW
BEGIN
IF (SELECT EXISTS(SELECT TRUE FROM workerManaExcluded WHERE workerFk = NEW.workerFk)) THEN
CALL util.throw('Worker is excluded from mana');
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,10 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerMana_beforeUpdate`
BEFORE UPDATE ON `workerMana`
FOR EACH ROW
BEGIN
IF (SELECT EXISTS(SELECT TRUE FROM workerManaExcluded WHERE workerFk = NEW.workerFk)) THEN
CALL util.throw('Worker is excluded from mana');
END IF;
END$$
DELIMITER ;

View File

@ -3,10 +3,12 @@ CREATE OR REPLACE DEFINER=`vn`@`localhost` TRIGGER `vn`.`workerTimeControl_after
AFTER DELETE ON `workerTimeControl`
FOR EACH ROW
BEGIN
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'WorkerTimeControl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
IF account.myUser_getId() IS NOT NULL THEN
INSERT INTO workerLog
SET `action` = 'delete',
`changedModel` = 'WorkerTimeControl',
`changedModelId` = OLD.id,
`userFk` = account.myUser_getId();
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,15 @@
ALTER TABLE vn.invoiceOut ADD COLUMN IF NOT EXISTS customsAgentFk INT(11) DEFAULT NULL AFTER siiTrascendencyInvoiceOutFk;
ALTER TABLE vn.invoiceOut ADD COLUMN IF NOT EXISTS incotermsFk varchar(3) DEFAULT NULL AFTER customsAgentFk;
ALTER TABLE vn.invoiceOut ADD CONSTRAINT invoiceOut_customsAgentFk FOREIGN KEY (customsAgentFk)
REFERENCES vn.customsAgent (id) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE vn.invoiceOut ADD CONSTRAINT invoiceOut_incotermsFk FOREIGN KEY (incotermsFk)
REFERENCES vn.incoterms (`code`) ON DELETE RESTRICT ON UPDATE CASCADE;
UPDATE vn.invoiceOut io
JOIN vn.client c ON c.id = io.clientFk
JOIN vn.ticket t ON t.clientFk = c.id
JOIN vn.address a ON a.id = t.addressFk
SET io.customsAgentFk = a.customsAgentFk,
io.incotermsFk = a.incotermsFk;

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS vn.productionCountry(
countryFk MEDIUMINT(8) UNSIGNED NOT NULL,
volumeGrowthEstimatePercent DECIMAL(6, 2) COMMENT 'Porcentaje estimado de crecimiento del volumen',
PRIMARY KEY (countryFk),
CONSTRAINT productionCountryVolume_countryFK
FOREIGN KEY (countryFk) REFERENCES vn.country (id)
ON DELETE RESTRICT ON UPDATE CASCADE
) COMMENT = 'Datos de producción por país'

View File

@ -0,0 +1,5 @@
DELETE FROM vn.workerMana
WHERE workerFk IN (
SELECT workerFk
FROM vn.workerManaExcluded
);

View File

@ -0,0 +1,5 @@
ALTER TABLE `vn`.`zoneEvent`
ADD COLUMN `priceOptimum` DECIMAL(10,2) NULL COMMENT 'Precio mínimo que puede pagar un bulto'
AFTER `price`,
ADD CONSTRAINT `ck_zoneEvent_priceOptimum`
CHECK (priceOptimum <= price)

View File

@ -0,0 +1,5 @@
ALTER TABLE `vn`.`zone`
ADD COLUMN `priceOptimum` DECIMAL(10,2) NOT NULL COMMENT 'Precio mínimo que puede pagar un bulto'
AFTER `price`,
ADD CONSTRAINT `ck_zone_priceOptimum`
CHECK (priceOptimum <= price)

View File

@ -0,0 +1,2 @@
UPDATE `vn`.`zone`
SET `priceOptimum` = `price`;

View File

@ -0,0 +1,3 @@
ALTER TABLE `vn`.`client`
ADD COLUMN `packagesDiscountFactor` DECIMAL(4,3) NOT NULL DEFAULT 1.000
COMMENT 'Porcentaje de ajuste entre el numero de bultos medio del cliente, y el número medio óptimo para las zonas en las que compra';

View File

@ -0,0 +1,3 @@
ALTER TABLE `vn`.`clientConfig`
ADD COLUMN `packagesOptimum` INT UNSIGNED NOT NULL DEFAULT 20 COMMENT 'Numero de bultos por cliente/dia para conseguir el precio optimo',
ADD COLUMN `monthsToCalcOptimumPrice` TINYINT UNSIGNED NOT NULL DEFAULT 3 COMMENT 'Número de meses a usar para el cálculo de client.packagesDiscountFactor';

View File

@ -0,0 +1,3 @@
ALTER TABLE `vn`.`entry`
ADD COLUMN `initialTemperature` decimal(10,2) DEFAULT NULL COMMENT 'Temperatura de como lo recibimos del proveedor ej. en colombia',
ADD COLUMN `finalTemperature` decimal(10,2) DEFAULT NULL COMMENT 'Temperatura final de como llega a nuestras instalaciones';

View File

@ -0,0 +1,2 @@
ALTER TABLE `vn`.`currency`
ADD COLUMN `hasToDownloadRate` TINYINT(1) NOT NULL DEFAULT 0 comment 'Si se guarda el tipo de cambio diariamente en referenceRate';

View File

@ -0,0 +1,3 @@
UPDATE `vn`.`currency`
SET `hasToDownloadRate` = TRUE
WHERE `code` IN ('USD', 'CNY', 'GBP');

View File

@ -0,0 +1,2 @@
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
VALUES ('VnUser','adminUser','WRITE','ALLOW','ROLE','sysadmin');

View File

@ -0,0 +1,2 @@
RENAME TABLE bi.f_tvc TO bi.f_tvc__;
ALTER TABLE bi.f_tvc__ COMMENT='@deprecated 2025-01-15';

View File

@ -0,0 +1 @@
CREATE INDEX ticket_landed_IDX USING BTREE ON vn.ticket (landed);

View File

@ -0,0 +1,130 @@
-- Place your SQL code here
CREATE TABLE IF NOT EXISTS `vn`.`itemSoldOutTag` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT
CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Ultimas unidades');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Temporalmente');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Descatalogado');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Hasta mayo');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Hasta febrero');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Hasta diciembre');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Hasta enero');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Hasta marzo');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Hasta nueva temporada');
INSERT IGNORE INTO `vn`.`itemSoldOutTag` (`name`) VALUES ('Hasta septiembre');
UPDATE vn.tag
SET isFree=FALSE,
sourceTable='itemSoldOutTag'
WHERE name= 'Agotado';
CREATE TABLE IF NOT EXISTS `vn`.`itemDurationTag` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT
CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('10 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('11 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('12 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('13 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('14 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('15 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('17 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('7 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('9 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('16-20 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('17-21 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('19-23 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('3-4 semanas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('13-17 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('14-16 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('15-19 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('18-25 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('20 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('6 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('9 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('10-13 días');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('6 meses');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('5 años');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('10 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('20 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('35 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('6 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('11 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('12 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('14 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('15 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('18 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('19 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('24 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('25 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('30 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('32 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('4 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('40 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('45 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('50 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('55 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('70 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('8 horas');
INSERT IGNORE INTO `vn`.`itemDurationTag` (`name`) VALUES ('9 horas');
UPDATE vn.tag
SET isFree=FALSE,
sourceTable='itemDurationTag'
WHERE name= 'Duracion';
CREATE TABLE IF NOT EXISTS `vn`.`itemGrowingTag` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT
CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('01-05');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('01-06');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('01-12');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('02-06');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('03-05');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('03-07');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('03-08');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('03-11');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('04-06');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('04-09');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('04-11');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('05-07');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('05-08');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('05-10');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('05-11');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('06-09');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('06-10');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('06-11');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('07-09');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('07-10');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('07-11');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('07-12');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('09-12');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('01-04 / 10-12');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('01-04 / 9-12');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('01-05 / 10-12');
INSERT IGNORE INTO `vn`.`itemGrowingTag` (`name`) VALUES ('01-05 / 11-12');
UPDATE vn.tag
SET isFree=FALSE,
sourceTable='itemGrowingTag'
WHERE name= 'Recolecta';
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE vn.itemSoldOutTag TO logisticAssist;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE vn.itemDurationTag TO logisticAssist;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE vn.itemGrowingTag TO logisticAssist;

View File

@ -238,25 +238,11 @@ describe('Ticket Edit sale path', () => {
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();
it('should select the third sale and delete it', async() => {
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);

View File

@ -75,7 +75,7 @@ describe('Ticket Edit basic data path', () => {
const result = await page
.waitToGetProperty(selectors.ticketBasicData.stepTwoTotalPriceDif, 'innerText');
expect(result).toContain('-€228.25');
expect(result).toContain('-€111.75');
});
it(`should select a new reason for the changes made then click on finalize`, async() => {

View File

@ -211,7 +211,7 @@
"Name should be uppercase": "Name should be uppercase",
"You cannot update these fields": "You cannot update these fields",
"CountryFK cannot be empty": "Country cannot be empty",
"No tickets to invoice": "There are no tickets to invoice that meet the invoicing requirements",
"No tickets to invoice": "There are no tickets to invoice that meet the invoicing requirements",
"You are not allowed to modify the alias": "You are not allowed to modify the alias",
"You already have the mailAlias": "You already have the mailAlias",
"This machine is already in use.": "This machine is already in use.",
@ -247,9 +247,11 @@
"ticketLostExpedition": "The ticket [{{ticketId}}]({{{ticketUrl}}}) has the following lost expedition:{{ expeditionId }}",
"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",
"Holidays to past days not available": "Holidays to past days not available",
"Price cannot be blank": "Price cannot be blank",
"There are tickets to be invoiced": "There are tickets to be invoiced",
"The address of the customer must have information about Incoterms and Customs Agent": "The address of the customer must have information about Incoterms and Customs Agent"
"The address of the customer must have information about Incoterms and Customs Agent": "The address of the customer must have information about Incoterms and Customs Agent",
"Sales already moved": "Sales already moved",
"Holidays to past days not available": "Holidays to past days not available",
"Incorrect delivery order alert on route": "Incorrect delivery order alert on route: {{ route }} zone: {{ zone }}",
"Ticket has been delivered out of order": "The ticket {{ticket}} {{{fullUrl}}} has been delivered out of order."
}

View File

@ -390,13 +390,11 @@
"The web user's email already exists": "El correo del usuario web ya existe",
"Sales already moved": "Ya han sido transferidas",
"The raid information is not correct": "La información de la redada no es correcta",
"No trips found because input coordinates are not connected": "No se encontraron rutas porque las coordenadas de entrada no están conectadas",
"This request is not supported": "Esta solicitud no es compatible",
"Invalid options or too many coordinates": "Opciones invalidas o demasiadas coordenadas",
"No address has coordinates": "Ninguna dirección tiene coordenadas",
"An item type with the same code already exists": "Un tipo con el mismo código ya existe",
"Holidays to past days not available": "Las vacaciones a días pasados no están disponibles",
"All tickets have a route order": "Todos los tickets tienen orden de ruta",
"Price cannot be blank": "Price cannot be blank",
"There are tickets to be invoiced": "La zona tiene tickets por facturar"
"There are tickets to be invoiced": "La zona tiene tickets por facturar",
"Incorrect delivery order alert on route": "Alerta de orden de entrega incorrecta en ruta: {{ route }} zona: {{ zone }}",
"Ticket has been delivered out of order": "El ticket {{ticket}} {{{fullUrl}}} no ha sigo entregado en su orden.",
"Price cannot be blank": "El precio no puede estar en blanco"
}

View File

@ -362,9 +362,11 @@
"The invoices have been created but the PDFs could not be generated": "La facture a été émise mais le PDF n'a pas pu être généré",
"It has been invoiced but the PDF of refund not be generated": "Il a été facturé mais le PDF de remboursement n'a pas été généré",
"Cannot send mail": "Impossible d'envoyer le mail",
"Original invoice not found": "Facture originale introuvable",
"The quantity claimed cannot be greater than the quantity of the line": "Le montant réclamé ne peut pas être supérieur au montant de la ligne",
"You do not have permission to modify the booked field": "Vous n'avez pas la permission de modifier le champ comptabilisé",
"Original invoice not found": "Facture originale introuvable",
"The quantity claimed cannot be greater than the quantity of the line": "Le montant réclamé ne peut pas être supérieur au montant de la ligne",
"You do not have permission to modify the booked field": "Vous n'avez pas la permission de modifier le champ comptabilisé",
"ticketLostExpedition": "Le ticket [{{ticketId}}]({{{ticketUrl}}}) a l'expédition perdue suivante : {{expeditionId}}",
"The web user's email already exists": "L'email de l'internaute existe déjà"
"The web user's email already exists": "L'email de l'internaute existe déjà",
"Incorrect delivery order alert on route": "Alerte de bon de livraison incorrect sur l'itinéraire: {{ route }} zone : {{ zone }}",
"Ticket has been delivered out of order": "Le ticket {{ticket}} {{{fullUrl}}} a été livré hors ordre."
}

View File

@ -365,5 +365,7 @@
"Cannot send mail": "Não é possível enviar o email",
"The quantity claimed cannot be greater than the quantity of the line": "O valor reclamado não pode ser superior ao valor da linha",
"ticketLostExpedition": "O ticket [{{ticketId}}]({{{ticketUrl}}}) tem a seguinte expedição perdida: {{expeditionId}}",
"The web user's email already exists": "O e-mail do utilizador da web já existe."
"The web user's email already exists": "O e-mail do utilizador da web já existe.",
"Incorrect delivery order alert on route": "Alerta de ordem de entrega incorreta na rota: {{ route }} zona: {{ zone }}",
"Ticket has been delivered out of order": "O ticket {{ticket}} {{{fullUrl}}} foi entregue fora de ordem."
}

View File

@ -109,6 +109,7 @@ module.exports = Self => {
const args = ctx.args;
const myOptions = {};
let to;
let myTeamIds = [];
if (typeof options == 'object')
Object.assign(myOptions, options);
@ -133,21 +134,8 @@ module.exports = Self => {
claimIdsByClaimResponsibleFk = claims.map(claim => claim.claimFk);
}
// Apply filter by team
const teamMembersId = [];
if (args.myTeam != null) {
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
}
if (args.myTeam != null)
myTeamIds = await models.Worker.myTeam(userId);
const where = buildFilter(ctx.args, (param, value) => {
switch (param) {
@ -184,9 +172,9 @@ module.exports = Self => {
return {'t.zoneFk': value};
case 'myTeam':
if (value)
return {'cl.workerFk': {inq: teamMembersId}};
return {'cl.workerFk': {inq: myTeamIds}};
else
return {'cl.workerFk': {nin: teamMembersId}};
return {'cl.workerFk': {nin: myTeamIds}};
}
});

View File

@ -52,6 +52,14 @@ module.exports = function(Self) {
arg: 'customsAgentFk',
type: 'number'
},
{
arg: 'longitude',
type: 'number'
},
{
arg: 'latitude',
type: 'number'
},
{
arg: 'isActive',
type: 'boolean'

View File

@ -1,7 +1,7 @@
const models = require('vn-loopback/server/server').models;
describe('Address updateAddress', () => {
const clientId = 1101;
const addressId = 1;
const clientId = 1102;
const addressId = 2;
const provinceId = 5;
const incotermsId = 'FAS';
const customAgentOneId = 1;

View File

@ -94,7 +94,7 @@ module.exports = Self => {
AND r1.started = r2.maxStarted
) r ON r.clientFk = c.id
LEFT JOIN workerDepartment wd ON wd.workerFk = u.id
JOIN department dp ON dp.id = wd.departmentFk
LEFT JOIN department dp ON dp.id = wd.departmentFk
WHERE
d.created = ?
AND d.amount > 0

View File

@ -19,6 +19,9 @@
},
"created": {
"type": "date"
},
"workerFk": {
"type": "number"
}
},
"relations": {

View File

@ -119,6 +119,16 @@ module.exports = Self => {
arg: 'invoiceAmount',
type: 'number',
description: `The invoice amount`
},
{
arg: 'initialTemperature',
type: 'number',
description: 'Initial temperature value'
},
{
arg: 'finalTemperature',
type: 'number',
description: 'Final temperature value'
}
],
returns: {
@ -170,6 +180,10 @@ module.exports = Self => {
case 'invoiceInFk':
param = `e.${param}`;
return {[param]: value};
case 'initialTemperature':
return {'e.initialTemperature': {lte: value}};
case 'finalTemperature':
return {'e.finalTemperature': {gte: value}};
}
});
filter = mergeFilters(ctx.args.filter, {where});
@ -204,6 +218,8 @@ module.exports = Self => {
e.gestDocFk,
e.invoiceInFk,
e.invoiceAmount,
e.initialTemperature,
e.finalTemperature,
t.landed,
s.name supplierName,
s.nickname supplierAlias,

View File

@ -68,6 +68,12 @@
},
"invoiceAmount": {
"type": "number"
},
"initialTemperature": {
"type": "number"
},
"finalTemperature": {
"type": "number"
}
},
"relations": {

View File

@ -13,66 +13,114 @@ module.exports = Self => {
}
});
Self.exchangeRateUpdate = async() => {
const response = await axios.get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml');
const xmlData = response.data;
const doc = new DOMParser({errorHandler: {warning: () => {}}})?.parseFromString(xmlData, 'text/xml');
const cubes = doc?.getElementsByTagName('Cube');
if (!cubes || cubes.length === 0)
throw new UserError('No cubes found. Exiting the method.');
Self.exchangeRateUpdate = async(options = {}) => {
const models = Self.app.models;
const myOptions = {};
let tx;
const maxDateRecord = await models.ReferenceRate.findOne({order: 'dated DESC'});
if (typeof options == 'object')
Object.assign(myOptions, options);
const maxDate = maxDateRecord?.dated ? new Date(maxDateRecord.dated) : null;
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const response = await axios.get('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml');
const xmlData = response.data;
const doc = new DOMParser({errorHandler: {warning: () => {}}})
.parseFromString(xmlData, 'text/xml');
const cubes = doc?.getElementsByTagName('Cube');
if (!cubes || cubes.length === 0)
throw new UserError('No cubes found. Exiting the method.');
const currencies = await models.Currency.find({where: {hasToDownloadRate: true}}, myOptions);
const maxDateRecord = await models.ReferenceRate.findOne({order: 'dated DESC'}, myOptions);
const maxDate = maxDateRecord?.dated ? new Date(maxDateRecord.dated) : null;
let lastProcessedDate = maxDate;
for (const cube of Array.from(cubes)) {
if (cube.nodeType === doc.ELEMENT_NODE && cube.attributes.getNamedItem('time')) {
const xmlDate = new Date(cube.getAttribute('time'));
const xmlDateWithoutTime = new Date(
xmlDate.getFullYear(),
xmlDate.getMonth(),
xmlDate.getDate()
);
if (!maxDate || xmlDateWithoutTime > maxDate) {
if (lastProcessedDate && xmlDateWithoutTime > lastProcessedDate) {
for (const currency of currencies) {
await fillMissingDates(
models, currency, lastProcessedDate, xmlDateWithoutTime, myOptions
);
}
}
}
for (const cube of Array.from(cubes)) {
if (cube.nodeType === doc.ELEMENT_NODE && cube.attributes.getNamedItem('time')) {
const xmlDate = new Date(cube.getAttribute('time'));
const xmlDateWithoutTime = new Date(xmlDate.getFullYear(), xmlDate.getMonth(), xmlDate.getDate());
if (!maxDate || maxDate < xmlDateWithoutTime) {
for (const rateCube of Array.from(cube.childNodes)) {
if (rateCube.nodeType === doc.ELEMENT_NODE) {
const currencyCode = rateCube.getAttribute('currency');
const rate = rateCube.getAttribute('rate');
if (['USD', 'CNY', 'GBP'].includes(currencyCode)) {
const currency = await models.Currency.findOne({where: {code: currencyCode}});
if (!currency) throw new UserError(`Currency not found for code: ${currencyCode}`);
const currency = currencies.find(c => c.code === currencyCode);
if (currency) {
const existingRate = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: xmlDate}
});
where: {currencyFk: currency.id, dated: xmlDateWithoutTime}
}, myOptions);
if (existingRate) {
if (existingRate.value !== rate)
await existingRate.updateAttributes({value: rate});
await existingRate.updateAttributes({value: rate}, myOptions);
} else {
await models.ReferenceRate.create({
currencyFk: currency.id,
dated: xmlDate,
dated: xmlDateWithoutTime,
value: rate
});
}
const monday = 1;
if (xmlDateWithoutTime.getDay() === monday) {
const saturday = new Date(xmlDateWithoutTime);
saturday.setDate(xmlDateWithoutTime.getDate() - 2);
const sunday = new Date(xmlDateWithoutTime);
sunday.setDate(xmlDateWithoutTime.getDate() - 1);
for (const date of [saturday, sunday]) {
await models.ReferenceRate.upsertWithWhere(
{currencyFk: currency.id, dated: date},
{currencyFk: currency.id, dated: date, value: rate}
);
}
}, myOptions);
}
}
}
}
lastProcessedDate = xmlDateWithoutTime;
}
}
if (tx) await tx.commit();
} catch (error) {
if (tx) await tx.rollback();
throw error;
}
};
async function getLastValidRate(models, currencyId, date, myOptions) {
return models.ReferenceRate.findOne({
where: {currencyFk: currencyId, dated: {lt: date}},
order: 'dated DESC'
}, myOptions);
}
async function fillMissingDates(models, currency, startDate, endDate, myOptions) {
const cursor = new Date(startDate);
cursor.setDate(cursor.getDate() + 1);
while (cursor < endDate) {
const existingRate = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: cursor}
}, myOptions);
if (!existingRate) {
const lastValid = await getLastValidRate(models, currency.id, cursor, myOptions);
if (lastValid) {
await models.ReferenceRate.create({
currencyFk: currency.id,
dated: new Date(cursor),
value: lastValid.value
}, myOptions);
}
}
cursor.setDate(cursor.getDate() + 1);
}
}
};

View File

@ -1,52 +1,190 @@
describe('exchangeRateUpdate functionality', function() {
const axios = require('axios');
const models = require('vn-loopback/server/server').models;
let tx; let options;
beforeEach(function() {
spyOn(axios, 'get').and.returnValue(Promise.resolve({
data: `<Cube>
<Cube time='2024-04-12'>
<Cube currency='USD' rate='1.1'/>
<Cube currency='CNY' rate='1.2'/>
</Cube>
</Cube>`
}));
function formatYmd(d) {
const mm = (d.getMonth() + 1).toString().padStart(2, '0');
const dd = d.getDate().toString().padStart(2, '0');
return `${d.getFullYear()}-${mm}-${dd}`;
}
afterEach(async() => {
await tx.rollback();
});
it('should process XML data and update or create rates in the database', async function() {
beforeEach(async() => {
tx = await models.Sale.beginTransaction({});
options = {transaction: tx};
spyOn(axios, 'get').and.returnValue(Promise.resolve({data: ''}));
});
it('should process XML data and create rates', async function() {
const d1 = Date.vnNew();
const d4 = Date.vnNew();
d4.setDate(d4.getDate() + 1);
const xml = `<Cube>
<Cube time='${formatYmd(d1)}'>
<Cube currency='USD' rate='1.1'/>
<Cube currency='CNY' rate='1.2'/>
</Cube>
<Cube time='${formatYmd(d4)}'>
<Cube currency='USD' rate='1.3'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
spyOn(models.ReferenceRate, 'findOne').and.returnValue(Promise.resolve(null));
spyOn(models.ReferenceRate, 'create').and.returnValue(Promise.resolve());
await models.InvoiceIn.exchangeRateUpdate(options);
await models.InvoiceIn.exchangeRateUpdate();
expect(models.ReferenceRate.create).toHaveBeenCalledTimes(2);
expect(models.ReferenceRate.create).toHaveBeenCalledTimes(3);
});
it('should not create or update rates when no XML data is available', async function() {
it('should handle no data', async function() {
axios.get.and.returnValue(Promise.resolve({}));
spyOn(models.ReferenceRate, 'create');
let thrownError = null;
let e;
try {
await models.InvoiceIn.exchangeRateUpdate();
} catch (error) {
thrownError = error;
await models.InvoiceIn.exchangeRateUpdate(options);
} catch (err) {
e = err;
}
expect(thrownError.message).toBe('No cubes found. Exiting the method.');
expect(e.message).toBe('No cubes found. Exiting the method.');
expect(models.ReferenceRate.create).not.toHaveBeenCalled();
});
it('should handle errors gracefully', async function() {
it('should handle errors', async function() {
axios.get.and.returnValue(Promise.reject(new Error('Network error')));
let error;
let e;
try {
await models.InvoiceIn.exchangeRateUpdate();
} catch (e) {
error = e;
await models.InvoiceIn.exchangeRateUpdate(options);
} catch (err) {
e = err;
}
expect(error).toBeDefined();
expect(error.message).toBe('Network error');
expect(e).toBeDefined();
expect(e.message).toBe('Network error');
});
it('should update existing rate', async function() {
const existingRate = await models.ReferenceRate.findOne({
order: 'id DESC'
}, options);
if (!existingRate) return fail('No ReferenceRate records in DB');
const currency = await models.Currency.findById(existingRate.currencyFk, null, options);
const xml = `<Cube>
<Cube time='${formatYmd(existingRate.dated)}'>
<Cube currency='${currency.code}' rate='2.22'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
await models.InvoiceIn.exchangeRateUpdate(options);
const updatedRate = await models.ReferenceRate.findById(existingRate.id, null, options);
expect(updatedRate.value).toBeCloseTo('2.22');
});
it('should not update if same rate', async function() {
const existingRate = await models.ReferenceRate.findOne({order: 'id DESC'}, options);
if (!existingRate) return fail('No existing ReferenceRate in DB');
const currency = await models.Currency.findById(existingRate.currencyFk, null, options);
const oldValue = existingRate.value;
const xml = `<Cube>
<Cube time='${formatYmd(existingRate.dated)}'>
<Cube currency='${currency.code}' rate='${oldValue}'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
await models.InvoiceIn.exchangeRateUpdate(options);
const updatedRate = await models.ReferenceRate.findById(existingRate.id, null, options);
expect(updatedRate.value).toBe(oldValue);
});
it('should backfill missing dates', async function() {
const lastRate = await models.ReferenceRate.findOne({order: 'dated DESC'}, options);
if (!lastRate) return fail('No existing ReferenceRate data in DB');
const currency = await models.Currency.findById(lastRate.currencyFk, null, options);
const d1 = new Date(lastRate.dated);
d1.setDate(d1.getDate() + 1);
const d4 = new Date(lastRate.dated);
d4.setDate(d4.getDate() + 4);
const xml = `<Cube>
<Cube time='${formatYmd(d1)}'>
<Cube currency='${currency.code}' rate='1.0'/>
</Cube>
<Cube time='${formatYmd(d4)}'>
<Cube currency='${currency.code}' rate='2.0'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
const beforeCount = await models.ReferenceRate.count({}, options);
await models.InvoiceIn.exchangeRateUpdate(options);
const afterCount = await models.ReferenceRate.count({}, options);
expect(afterCount - beforeCount).toBe(4);
});
it('should create entries for day1 and day2 from the feed, and not backfill day3', async function() {
const lastRate = await models.ReferenceRate.findOne({order: 'dated DESC'}, options);
if (!lastRate) return fail('No existing ReferenceRate data in DB');
const currency = await models.Currency.findById(lastRate.currencyFk, null, options);
if (!currency) return fail(`No currency for ID ${lastRate.currencyFk}`);
const day1 = new Date(lastRate.dated);
day1.setDate(day1.getDate() + 1);
const day2 = new Date(lastRate.dated);
day2.setDate(day2.getDate() + 2);
const day3 = new Date(lastRate.dated);
day3.setDate(day3.getDate() + 3);
const xml = `<Cube>
<Cube time='${formatYmd(day1)}'>
<Cube currency='${currency.code}' rate='1.1'/>
</Cube>
<Cube time='${formatYmd(day2)}'>
<Cube currency='${currency.code}' rate='2.2'/>
</Cube>
</Cube>`;
axios.get.and.returnValue(Promise.resolve({data: xml}));
await models.InvoiceIn.exchangeRateUpdate(options);
const day3Record = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: day3}
}, options);
expect(day3Record).toBeNull();
const day1Record = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: day1}
}, options);
const day2Record = await models.ReferenceRate.findOne({
where: {currencyFk: currency.id, dated: day2}
}, options);
expect(day1Record.value).toBeCloseTo('1.1');
expect(day2Record.value).toBeCloseTo('2.2');
});
});

View File

@ -74,7 +74,8 @@ module.exports = Self => {
AND t.companyFk = ?
AND NOT t.isDeleted
GROUP BY IF(c.hasToInvoiceByAddress, a.id, c.id)
HAVING SUM(t.totalWithVat) > 0;`;
HAVING SUM(t.totalWithVat) > 0
ORDER BY c.id`;
const addresses = await Self.rawSql(query, [
minShipped,

View File

@ -79,6 +79,12 @@ module.exports = Self => {
type: 'date',
description: 'The due date filter',
http: {source: 'query'}
},
{
arg: 'customsAgentFk',
type: 'integer',
description: 'The customsAgent id',
http: {source: 'query'}
}
],
returns: {
@ -120,6 +126,7 @@ module.exports = Self => {
case 'companyFk':
case 'issued':
case 'dued':
case 'customsAgentFk':
param = `i.${param}`;
return {[param]: value};
}
@ -139,11 +146,14 @@ module.exports = Self => {
i.dued,
i.clientFk,
i.hasPdf,
i.customsAgentFk,
c.socialName AS clientSocialName,
co.code AS companyCode
co.code AS companyCode,
ca.fiscalName AS customsAgentName
FROM invoiceOut i
LEFT JOIN client c ON c.id = i.clientFk
LEFT JOIN company co ON co.id = i.companyFk`
LEFT JOIN company co ON co.id = i.companyFk
LEFT JOIN customsAgent ca ON ca.id = i.customsAgentFk`
);
stmt.merge(conn.makeSuffix(filter));

View File

@ -66,6 +66,11 @@
"model": "Ticket",
"foreignKey": "refFk",
"primaryKey": "ref"
},
"customsAgentFk": {
"type": "belongsTo",
"model": "CustomsAgent",
"foreignKey": "customsAgentFk"
}
}
}

View File

@ -123,25 +123,13 @@ module.exports = Self => {
date.setHours(0, 0, 0, 0);
const args = ctx.args;
const myOptions = {};
let myTeamIds = [];
if (typeof options == 'object')
Object.assign(myOptions, options);
// Apply filter by team
const teamMembersId = [];
if (args.myTeam != null) {
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
}
if (args.myTeam != null)
myTeamIds = await models.Worker.myTeam(userId);
if (ctx.args && args.to) {
const dateTo = args.to;
@ -163,9 +151,9 @@ module.exports = Self => {
case 'mine':
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
return {'c.salesPersonFk': {inq: myTeamIds}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
return {'c.salesPersonFk': {nin: myTeamIds}};
case 'id':
case 'clientFk':
param = `t.${param}`;

View File

@ -80,29 +80,15 @@ module.exports = Self => {
const conn = Self.dataSource.connector;
const myOptions = {};
const userId = ctx.req.accessToken.userId;
let myTeamIds = [];
if (typeof options == 'object')
Object.assign(myOptions, options);
const args = ctx.args;
// Apply filter by team
const teamMembersId = [];
if (args.myTeam != null) {
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
}
if (args?.myTeam)
args.teamIds = teamIds;
if (args.myTeam != null)
myTeamIds = await models.Worker.myTeam(userId);
if (args?.to)
args.to.setHours(23, 59, 0, 0);
@ -133,9 +119,9 @@ module.exports = Self => {
return {'o.confirmed': value ? 1 : 0};
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
return {'c.salesPersonFk': {inq: myTeamIds}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
return {'c.salesPersonFk': {nin: myTeamIds}};
case 'showEmpty':
return {'o.total': {neq: value}};
case 'id':

View File

@ -8,7 +8,7 @@ module.exports = Self => {
arg: 'id',
type: 'number',
required: true,
description: 'The client id',
description: 'The route id',
http: {source: 'path'}
}, {
arg: 'replyTo',
@ -31,26 +31,13 @@ module.exports = Self => {
});
Self.driverRouteEmail = async(ctx, id) => {
const models = Self.app.models;
const {workerFk, agencyMode} = await Self.findById(id, {
fields: ['workerFk', 'agencyModeFk'],
const {agencyMode} = await Self.findById(id, {
fields: ['agencyModeFk'],
include: {relation: 'agencyMode'}
});
const {reportMail} = agencyMode();
let user;
let account;
if (workerFk) {
user = await models.VnUser.findById(workerFk, {
fields: ['active', 'id'],
include: {relation: 'emailUser'}
});
account = await models.Account.findById(workerFk);
}
if (user?.active && account) ctx.args.recipient = user.emailUser().email;
else ctx.args.recipient = reportMail;
ctx.args.recipient = reportMail;
if (!ctx.args.recipient) throw new UserError('An email is necessary');
return Self.sendTemplate(ctx, 'driver-route');
};

View File

@ -28,6 +28,7 @@ module.exports = Self => {
delete args.ctx;
if (!args.name) throw new UserError('The social name cannot be empty');
if (args.name !== args.name.toUpperCase()) throw new UserError('Social name should be uppercase');
const data = {...args, ...{nickname: args.name}};
const supplier = await models.Supplier.create(data, myOptions);

View File

@ -87,6 +87,7 @@ module.exports = Self => {
const myOptions = {};
const models = Self.app.models;
const args = ctx.args;
let myTeamIds = [];
if (typeof options == 'object')
Object.assign(myOptions, options);
@ -94,20 +95,8 @@ module.exports = Self => {
if (ctx.args.mine)
ctx.args.attenderFk = userId;
const teamMembersId = [];
if (args.myTeam != null) {
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
}
if (args.myTeam != null)
myTeamIds = await models.Worker.myTeam(userId);
const today = Date.vnNew();
const future = Date.vnNew();
@ -145,9 +134,9 @@ module.exports = Self => {
return {'c.salesPersonFk': value};
case 'myTeam':
if (value)
return {'tr.requesterFk': {inq: teamMembersId}};
return {'tr.requesterFk': {inq: myTeamIds}};
else
return {'tr.requesterFk': {nin: teamMembersId}};
return {'tr.requesterFk': {nin: myTeamIds}};
case 'daysOnward':
today.setHours(0, 0, 0, 0);
future.setDate(today.getDate() + value);

View File

@ -30,7 +30,7 @@ module.exports = Self => {
Object.assign(myOptions, options);
const query =
`SELECT DISTINCT u.id, u.nickname
`SELECT DISTINCT u.id, u.nickname, w.firstName, w.lastName
FROM itemType it
JOIN worker w ON w.id = it.workerFk
JOIN account.user u ON u.id = w.id`;

View File

@ -142,28 +142,14 @@ module.exports = Self => {
date.setHours(0, 0, 0, 0);
const models = Self.app.models;
const args = ctx.args;
let myTeamIds = [];
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
// Apply filter by team
const teamMembersId = [];
if (args.myTeam != null) {
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
}
if (args.myTeam != null)
myTeamIds = await models.Worker.myTeam(userId);
if (ctx.args && args.to) {
const dateTo = args.to;
@ -195,9 +181,9 @@ module.exports = Self => {
case 'mine':
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: teamMembersId}};
return {'c.salesPersonFk': {inq: myTeamIds}};
else
return {'c.salesPersonFk': {nin: teamMembersId}};
return {'c.salesPersonFk': {nin: myTeamIds}};
case 'alertLevel':
return {'ts.alertLevel': value};

View File

@ -40,21 +40,23 @@ module.exports = Self => {
try {
for (let ticket of tickets) {
const originFullPath = `${url}ticket/${ticket.originId}/summary`;
const destinationFullPath = `${url}ticket/${ticket.destinationId}/summary`;
const message = $t('Ticket merged', {
originDated: dateUtil.toString(new Date(ticket.originShipped)),
destinationDated: dateUtil.toString(new Date(ticket.destinationShipped)),
originId: ticket.originId,
destinationId: ticket.destinationId,
originFullPath,
destinationFullPath
});
if (!ticket.originId || !ticket.destinationId) continue;
await models.Sale.updateAll({ticketFk: ticket.originId}, {ticketFk: ticket.destinationId}, myOptions);
if (await models.Ticket.setDeleted(ctx, ticket.originId, myOptions))
await models.Chat.sendCheckingPresence(ctx, ticket.workerFk, message);
if (await models.Ticket.setDeleted(ctx, ticket.originId, myOptions)) {
if (!ticket.salesPersonFk) continue;
const originFullPath = `${url}ticket/${ticket.originId}/summary`;
const destinationFullPath = `${url}ticket/${ticket.destinationId}/summary`;
const message = $t('Ticket merged', {
originDated: dateUtil.toString(new Date(ticket.originShipped)),
destinationDated: dateUtil.toString(new Date(ticket.destinationShipped)),
originId: ticket.originId,
destinationId: ticket.destinationId,
originFullPath,
destinationFullPath
});
await models.Chat.sendCheckingPresence(ctx, ticket.salesPersonFk, message);
}
}
if (tx)
await tx.commit();

View File

@ -28,7 +28,6 @@ module.exports = Self => {
verb: 'POST'
}
});
Self.saveSign = async(ctx, tickets, location, signedTime, options) => {
const models = Self.app.models;
const myOptions = {userId: ctx.req.accessToken.userId};
@ -111,6 +110,12 @@ module.exports = Self => {
scope: {
fields: ['id']
}
},
{
relation: 'zone',
scope: {
fields: ['id', 'zoneFk,', 'name']
}
}]
}, myOptions);
@ -151,6 +156,28 @@ module.exports = Self => {
await Self.rawSql(`CALL vn.ticket_setState(?, ?)`, [ticketId, stateCode], myOptions);
if (stateCode == 'DELIVERED' && ticket.priority) {
const orderState = await models.State.findOne({
where: {code: 'DELIVERED'},
fields: ['id']
}, myOptions);
const ticketIncorrect = await Self.rawSql(`
SELECT t.id
FROM ticket t
JOIN ticketState ts ON ts.ticketFk = t.id
JOIN state s ON s.code = ts.code
WHERE t.routeFk = ?
AND s.\`order\` < ?
AND priority <(SELECT t.priority
FROM ticket t
WHERE t.id = ?)`
, [ticket.routeFk, orderState.id, ticket.id], myOptions);
if (ticketIncorrect?.length > 0)
await sendMail(ctx, ticket.routeFk, ticket.id, ticket.zone().name);
}
if (ticket?.address()?.province()?.country()?.code != 'ES' && ticket.$cmrFk) {
await models.Ticket.saveCmr(ctx, [ticketId], myOptions);
externalTickets.push(ticketId);
@ -163,4 +190,25 @@ module.exports = Self => {
}
await models.Ticket.sendCmrEmail(ctx, externalTickets);
};
async function sendMail(ctx, route, ticket, zoneName) {
const $t = ctx.req.__;
const url = await Self.app.models.Url.getUrl();
const sendTo = 'repartos@verdnatura.es';
const fullUrl = `${url}route/${route}/summary`;
const emailSubject = $t('Incorrect delivery order alert on route', {
route,
zone: zoneName
});
const emailBody = $t('Ticket has been delivered out of order', {
ticket,
fullUrl
});
await Self.app.models.Mail.create({
receiver: sendTo,
subject: emailSubject,
body: emailBody
});
}
};

View File

@ -7,7 +7,7 @@ describe('ticket merge()', () => {
destinationId: 12,
originShipped: Date.vnNew(),
destinationShipped: Date.vnNew(),
workerFk: 1
salesPersonFk: 1
};
it('should merge two tickets', async() => {

View File

@ -1,12 +1,20 @@
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('Ticket saveSign()', () => {
let ctx = {req: {
getLocale: () => {
return 'en';
},
__: () => {},
accessToken: {userId: 9}
}};
}
};
beforeEach(() => {
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
active: ctx
});
});
it(`should throw error if the ticket's alert level is lower than 2`, async() => {
const tx = await models.TicketDms.beginTransaction({});
@ -51,4 +59,46 @@ describe('Ticket saveSign()', () => {
expect(ticketTrackingAfter.name).toBe('Entregado en parte');
});
it('should send an email to notify that the delivery order is not correct', async() => {
const tx = await models.Ticket.beginTransaction({});
const ticketFk = 8;
const priority = 5;
const stateFk = 10;
const stateTicketFk = 2;
const expeditionFk = 11;
const expeditionStateFK = 2;
let mailCountBefore;
let mailCountAfter;
spyOn(models.Dms, 'uploadFile').and.returnValue([{id: 1}]);
const options = {transaction: tx};
const tickets = [ticketFk];
const expedition = await models.Expedition.findById(expeditionFk, null, options);
expedition.updateAttribute('stateTypeFk', expeditionStateFK, options);
const ticket = await models.Ticket.findById(ticketFk, null, options);
ticket.updateAttribute('priority', priority, options);
const filter = {where: {
ticketFk: ticketFk,
stateFk: stateTicketFk}
};
try {
const ticketTracking = await models.TicketTracking.findOne(filter, options);
ticketTracking.updateAttribute('stateFk', stateFk, options);
mailCountBefore = await models.Mail.count(options);
await models.Ticket.saveSign(ctx, tickets, null, null, options);
mailCountAfter = await models.Mail.count(options);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
expect(mailCountAfter).toBeGreaterThan(mailCountBefore);
});
});

View File

@ -0,0 +1,64 @@
const {models} = require('vn-loopback/server/server');
describe('ticketService model ', () => {
const originalTicketFk = 1;
const refundTicketFk = 11;
let tx;
let opts;
let ticketService;
beforeEach(async() => {
tx = await models.Sale.beginTransaction({});
opts = {transaction: tx};
ticketService = await models.TicketService.create({
ticketFk: refundTicketFk,
description: 'test',
quantity: 1,
price: 100,
taxClassFk: 1,
ticketServiceTypeFk: 1
}, opts);
});
afterEach(async() => {
await tx.rollback();
});
describe('TicketService', () => {
it('should allow updating description and quantity for non-refund tickets', async() => {
await ticketService.updateAttributes({
ticketServiceTypeFk: 2,
quantity: 5
}, opts);
const updated = await models.TicketService.findById(ticketService.id, null, opts);
expect(updated.description).not.toBe('test');
expect(updated.quantity).toBe(5);
});
it('should only allow updating description for refund tickets', async() => {
await models.TicketRefund.create({
refundTicketFk,
originalTicketFk
}, opts);
await ticketService.updateAttributes({
ticketServiceTypeFk: 2
}, opts);
try {
await ticketService.updateAttributes({
ticketServiceTypeFk: 3,
quantity: 5
}, opts);
fail('Should have thrown error');
} catch (e) {
expect(e.message).toBe('Only description can be modified in refund tickets');
}
});
});
});

View File

@ -10,9 +10,18 @@ module.exports = Self => {
const isLocked = await models.Ticket.isLocked(ticketId);
if (isLocked)
throw new UserError(`The current ticket can't be modified`);
const isRefund = await models.TicketRefund.findOne({
where: {refundTicketFk: ticketId}
}, {
transaction: ctx.options.transaction
});
if (isRefund && ctx.data && Object.keys(ctx.data).some(field => field !== 'ticketServiceTypeFk'))
throw new UserError('Only description can be modified in refund tickets');
}
if (changes && changes.ticketServiceTypeFk) {
if (changes?.ticketServiceTypeFk) {
const ticketServiceType = await models.TicketServiceType.findById(changes.ticketServiceTypeFk);
changes.description = ticketServiceType.name;
}

View File

@ -1,4 +1,3 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const buildFilter = require('vn-loopback/util/filter').buildFilter;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
@ -91,6 +90,11 @@ module.exports = Self => {
arg: 'landed',
type: 'date',
description: 'The landed date'
},
{
arg: 'awbFk',
type: 'number',
description: 'The awbFk id'
}
],
returns: {
@ -168,14 +172,17 @@ module.exports = Self => {
t.totalEntries,
t.isRaid,
t.daysInForward,
t.awbFk,
am.name agencyModeName,
a.code awbCode,
win.name warehouseInName,
wout.name warehouseOutName,
cnt.code continent
FROM vn.travel t
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
JOIN vn.warehouse win ON win.id = t.warehouseInFk
JOIN vn.warehouse wout ON wout.id = t.warehouseOutFk
FROM travel t
JOIN agencyMode am ON am.id = t.agencyModeFk
JOIN warehouse win ON win.id = t.warehouseInFk
JOIN warehouse wout ON wout.id = t.warehouseOutFk
LEFT JOIN awb a ON a.id = t.awbFk
JOIN warehouse wo ON wo.id = t.warehouseOutFk
JOIN country c ON c.id = wo.countryFk
LEFT JOIN continent cnt ON cnt.id = c.continentFk) AS t`

View File

@ -41,7 +41,9 @@ module.exports = Self => {
* b.stickers)/1000000) AS DECIMAL(10,2)) m3,
TRUNCATE(SUM(b.stickers)/(COUNT( b.id) / COUNT( DISTINCT b.id)),0) hb,
CAST(SUM(b.freightValue*b.quantity) AS DECIMAL(10,2)) freightValue,
CAST(SUM(b.packageValue*b.quantity) AS DECIMAL(10,2)) packageValue
CAST(SUM(b.packageValue*b.quantity) AS DECIMAL(10,2)) packageValue,
e.initialTemperature,
e.finalTemperature
FROM vn.travel t
LEFT JOIN vn.entry e ON t.id = e.travelFk
LEFT JOIN vn.buy b ON b.entryFk = e.id

View File

@ -20,6 +20,9 @@
},
"ratio": {
"type": "number"
},
"hasToDownloadRate": {
"type": "boolean"
}
},
"acls": [

View File

@ -73,6 +73,11 @@ module.exports = Self => {
type: 'String',
description: 'The user email',
http: {source: 'query'}
},
{
arg: 'myTeam',
type: 'boolean',
description: 'Whether to show only tickets for the current logged user team (currently user tickets)'
}
],
returns: {
@ -85,10 +90,21 @@ module.exports = Self => {
}
});
Self.filter = async(ctx, filter) => {
let conn = Self.dataSource.connector;
Self.filter = async(ctx, filter, options) => {
const userId = ctx.req.accessToken.userId;
const conn = Self.dataSource.connector;
const models = Self.app.models;
const args = ctx.args;
let myTeamIds = [];
const myOptions = {};
let where = buildFilter(ctx.args, (param, value) => {
if (typeof options == 'object')
Object.assign(myOptions, options);
if (args.myTeam != null)
myTeamIds = await models.Worker.myTeam(userId);
const where = buildFilter(ctx.args, (param, value) => {
switch (param) {
case 'search':
return /^\d+$/.test(value)
@ -117,12 +133,17 @@ module.exports = Self => {
return {'u.name': {like: `%${value}%`}};
case 'email':
return {'eu.email': {like: `%${value}%`}};
case 'myTeam':
if (value)
return {'c.salesPersonFk': {inq: myTeamIds}};
else
return {'c.salesPersonFk': {nin: myTeamIds}};
}
});
filter = mergeFilters(ctx.args.filter, {where});
filter = mergeFilters(filter, {where});
let stmts = [];
const stmts = [];
let stmt;
stmt = new ParameterizedSQL(
@ -145,11 +166,12 @@ module.exports = Self => {
LEFT JOIN account.emailUser eu ON eu.userFk = u.id`
);
stmt.merge(conn.makeSuffix(filter));
let itemsIndex = stmts.push(stmt) - 1;
stmt.merge(conn.makeWhere(filter.where));
stmts.push(stmt);
let sql = ParameterizedSQL.join(stmts, ';');
let result = await conn.executeStmt(sql);
return itemsIndex === 0 ? result : result[itemsIndex];
const itemsIndex = stmts.push(stmt) - 1;
const sql = ParameterizedSQL.join(stmts, ';');
const result = await conn.executeStmt(sql, myOptions);
return result[itemsIndex];
};
};

View File

@ -0,0 +1,43 @@
module.exports = Self => {
Self.remoteMethod('myTeam', {
description: 'Return the members of the user team',
accessType: 'READ',
accepts: [{
arg: 'userId',
type: 'string',
required: true
}],
returns: {
type: 'string',
root: true
},
http: {
path: `/myTeam`,
verb: 'GET'
}
});
Self.myTeam = async(userId, options) => {
const models = Self.app.models;
const myOptions = {};
const teamMembersId = [];
if (typeof options == 'object')
Object.assign(myOptions, options);
const worker = await models.Worker.findById(userId, {
include: {
relation: 'collegues'
}
}, myOptions);
const collegues = worker.collegues() || [];
for (let collegue of collegues)
teamMembersId.push(collegue.collegueFk);
if (teamMembersId.length == 0)
teamMembersId.push(userId);
return teamMembersId;
};
};

View File

@ -1,25 +1,69 @@
const models = require('vn-loopback/server/server').models;
const app = require('vn-loopback/server/server');
describe('worker filter()', () => {
it('should return 1 result filtering by id', async() => {
let result = await app.models.Worker.filter({args: {filter: {}, search: 1}});
const ctx = beforeAll.getCtx();
expect(result.length).toEqual(1);
expect(result[0].id).toEqual(1);
it('should return 1 result filtering by id', async() => {
const tx = await models.Worker.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {};
const args = {search: 1};
ctx.args = args;
let result = await app.models.Worker.filter(ctx, filter, options);
expect(result.length).toEqual(1);
expect(result[0].id).toEqual(1);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return 1 result filtering by string', async() => {
let result = await app.models.Worker.filter({args: {filter: {}, search: 'administrativeNick'}});
const tx = await models.Worker.beginTransaction({});
expect(result.length).toEqual(1);
expect(result[0].id).toEqual(5);
try {
const options = {transaction: tx};
const filter = {};
const args = {search: 'administrativeNick'};
ctx.args = args;
let result = await app.models.Worker.filter(ctx, filter, options);
expect(result.length).toEqual(1);
expect(result[0].id).toEqual(5);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('should return 2 results filtering by name', async() => {
let result = await app.models.Worker.filter({args: {filter: {}, firstName: 'agency'}});
it('should return 2 result filtering by name', async() => {
const tx = await models.Worker.beginTransaction({});
expect(result.length).toEqual(2);
expect(result[0].nickname).toEqual('agencyNick');
expect(result[1].nickname).toEqual('agencyBossNick');
try {
const options = {transaction: tx};
const filter = {};
const args = {firstName: 'agency'};
ctx.args = args;
let result = await app.models.Worker.filter(ctx, filter, options);
expect(result[0].nickname).toEqual('agencyNick');
expect(result[1].nickname).toEqual('agencyBossNick');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -21,6 +21,7 @@ module.exports = Self => {
require('../methods/worker/isAuthorized')(Self);
require('../methods/worker/setPassword')(Self);
require('../methods/worker/getAvailablePda')(Self);
require('../methods/worker/myTeam')(Self);
Self.validateAsync('fi', tinIsValid, {
message: 'Invalid TIN'

View File

@ -42,6 +42,9 @@
"price": {
"type": "number"
},
"priceOptimum": {
"type": "number"
},
"bonus": {
"type": "number"
},

View File

@ -28,6 +28,9 @@
"price": {
"type": "number"
},
"priceOptimum": {
"type": "number"
},
"bonus": {
"type": "number"
},

View File

@ -1,6 +1,6 @@
{
"name": "salix-back",
"version": "25.02.0",
"version": "25.06.0",
"author": "Verdnatura Levante SL",
"description": "Salix backend",
"license": "GPL-3.0",

View File

@ -1,9 +1,9 @@
WITH tickets AS(
SELECT id, packages, addressFk, weight
FROM ticket
WHERE refFk= ?
SELECT id, addressFk, packages, refFk
FROM vn.ticket
WHERE refFk = ?
), volume AS(
SELECT SUM(volume) volume
SELECT SUM(volume) volume, MAX(weight)weight
FROM tickets t
JOIN vn.saleVolume sv ON sv.ticketFk = t.id
), intrastat AS(
@ -12,10 +12,14 @@ SELECT GROUP_CONCAT(DISTINCT ir.description ORDER BY ir.description SEPARATOR '
JOIN vn.sale s ON t.id = s.ticketFk
JOIN vn.item i ON i.id = s.itemFk
JOIN vn.intrastat ir ON ir.id = i.intrastatFk
)SELECT SUM(t.packages) packages,
a.incotermsFk,
), totalPackages AS(
SELECT SUM(packages)packages
FROM tickets s
)
SELECT tp.packages,
io.incotermsFk,
ic.name incotermsName,
MAX(t.weight) weight,
v.weight weight,
ca.fiscalName customsAgentName,
ca.street customsAgentStreet,
ca.nif customsAgentNif,
@ -23,9 +27,10 @@ SELECT GROUP_CONCAT(DISTINCT ir.description ORDER BY ir.description SEPARATOR '
ca.email customsAgentEmail,
CAST(v.volume AS DECIMAL (10,2)) volume,
i.intrastat
FROM tickets t
JOIN vn.address a ON a.id = t.addressFk
JOIN vn.incoterms ic ON ic.code = a.incotermsFk
LEFT JOIN vn.customsAgent ca ON ca.id = a.customsAgentFk
FROM vn.invoiceOut io
JOIN vn.incoterms ic ON ic.code = io.incotermsFk
LEFT JOIN vn.customsAgent ca ON ca.id = io.customsAgentFk
JOIN volume v
JOIN intrastat i
JOIN totalPackages tp
WHERE `ref` = (SELECT DISTINCT refFk FROM tickets)