WIP: 6802-Clientes-gestionados-por-equipos #2516
|
@ -36,3 +36,7 @@ rules:
|
||||||
jasmine/no-focused-tests: 0
|
jasmine/no-focused-tests: 0
|
||||||
jasmine/prefer-toHaveBeenCalledWith: 0
|
jasmine/prefer-toHaveBeenCalledWith: 0
|
||||||
arrow-spacing: ["error", { "before": true, "after": true }]
|
arrow-spacing: ["error", { "before": true, "after": true }]
|
||||||
|
no-restricted-syntax:
|
||||||
|
- "error"
|
||||||
|
- selector: "NewExpression[callee.name='Date']"
|
||||||
|
message: "Use Date.vnNew() instead of new Date()."
|
||||||
|
|
499
CHANGELOG.md
499
CHANGELOG.md
|
@ -1,3 +1,502 @@
|
||||||
|
# Version 25.00 - 2025-01-14
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- feat: refs #7235 add serialType parameter to getInvoiceDate and implement corresponding tests by:jgallego
|
||||||
|
- feat: refs #7301 update lastEntriesFilter to include landedDate and enhance test cases (origin/7301-removeRedundantInventories) by:pablone
|
||||||
|
- feat: refs #7880 error code and translations by:ivanm
|
||||||
|
- feat: refs #7924 add isCustomInspectionRequired field to item and update related logic by:jgallego
|
||||||
|
- feat: refs #8167 update canBeInvoiced method to include active status check and improve test cases by:jgallego
|
||||||
|
- feat: refs #8167 update locale and improve invoicing logic with error handling by:jgallego
|
||||||
|
- feat: refs #8246 added relation for the front's new field by:Jon
|
||||||
|
- feat: refs #8266 added itemFk and needed fixtures by:jtubau
|
||||||
|
- feat: refs #8324 country unique by:Carlos Andrés
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- feat: refs #8266 added itemFk and needed fixtures by:jtubau
|
||||||
|
- fix: add isCustomInspectionRequired column to item table for customs inspection indication by:jgallego
|
||||||
|
- fix: canBeInvoiced only in makeInvoice by:alexm
|
||||||
|
- fix: hotFix getMondayWeekYear by:alexm
|
||||||
|
- fix: refs #6598 update ACL property assignment by:jorgep
|
||||||
|
- fix: refs #6861 refs#6861 addPrevOK by:sergiodt
|
||||||
|
- fix: refs #7301 remove debug console log and update test cases in lastEntriesFilter by:pablone
|
||||||
|
- fix: refs #7301 update SQL fixtures and improve lastEntriesFilter logic by:pablone
|
||||||
|
|
||||||
|
# Version 24.52 - 2024-01-07
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- chore: pullinfo by:alexm
|
||||||
|
- chore: refs #8002 drop comments by:jorgep
|
||||||
|
- chore: refs #8002 drop useless code by:jorgep
|
||||||
|
- feat: added translations and show error in item-type by:Jon
|
||||||
|
- feat: modified data to be equal as the updated back by:Jon
|
||||||
|
- feat: refs #4460 invoiceIn refund by:Carlos Andrés
|
||||||
|
- feat: refs #4466 invoiceIn refund by:Carlos Andrés
|
||||||
|
- feat: refs #6583 add new opt in where builder by:jorgep
|
||||||
|
- feat: refs #6583 add tests by:jorgep
|
||||||
|
- feat: refs #6583 retrieve cloned sale by:jorgep
|
||||||
|
- feat: refs #6583 rollback by:jorgep
|
||||||
|
- feat: refs #7301 add inventory-config and acl by:pablone
|
||||||
|
- feat: refs #7301 update SQL fixtures and enhance lastEntriesFilter logic by:pablone
|
||||||
|
- feat: refs #7882 Added locationiq service by:guillermo
|
||||||
|
- feat: refs #7882 Added osrm service by:guillermo
|
||||||
|
- feat: refs #7882 Added tests by:guillermo
|
||||||
|
- feat: refs #7882 Fixed problems osrm service by:guillermo
|
||||||
|
- feat: refs #7882 Osrm service by:guillermo
|
||||||
|
- feat: refs #7882 Reequested changes by:guillermo
|
||||||
|
- feat: refs #7882 Requested changes by:guillermo
|
||||||
|
- feat: refs #7936 add back test for updateInvoiceIn by:jorgep
|
||||||
|
- feat: refs #7936 add company filter by:jorgep
|
||||||
|
- feat: refs #7936 add currency check to updateInvoiceIn by:jorgep
|
||||||
|
- feat: refs #7936 add currency handling in invoiceIn trigger by:jorgep
|
||||||
|
- feat: refs #7936 add locale by:jorgep
|
||||||
|
- feat: refs #7936 add minimum due date by:jorgep
|
||||||
|
- feat: refs #7936 add reference rates for currency in fixtures by:jorgep
|
||||||
|
- feat: refs #7936 add save validation by:jorgep
|
||||||
|
- feat: refs #7936 add SiiTypeInvoiceIn model and update invoice correction logic by:jorgep
|
||||||
|
- feat: refs #7936 add tests for invoiceIn by:jorgep
|
||||||
|
- feat: refs #7936 add tests for invoiceIn filter by:jorgep
|
||||||
|
- feat: refs #7936 add validation to InvoiceIn & InvoiceInTax by:jorgep
|
||||||
|
- feat: refs #7936 return country code & is vies fields by:jorgep
|
||||||
|
- feat: refs #8002 adjust to lilium by:jorgep
|
||||||
|
- feat: refs #8002 drop support btn by:jorgep
|
||||||
|
- feat: refs #8174 Changed datatype incompatibility access by:guillermo
|
||||||
|
- feat: refs #8174 Created table sim by:guillermo
|
||||||
|
- feat: refs #8174 create table simsupplier by:Jbreso
|
||||||
|
- feat: refs #8174 fix by:Jbreso
|
||||||
|
- feat: refs#8174 simSupplier by:Jbreso
|
||||||
|
- feat: refs #8190 entry_getCommission by:robert
|
||||||
|
- feat: refs #8190 entry_getCommission change request by:robert
|
||||||
|
- feat: refs #8218 Added time and code in mistakeType by:guillermo
|
||||||
|
- feat: refs #8293 include zone data by:Jtubau
|
||||||
|
- refactor: refs #6583 entry report table style by:jorgep
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- refactor: refs #6583 entry report table style by:jorgep
|
||||||
|
- refactor: refs #6583 use warehouseId var by:jorgep
|
||||||
|
- refactor: refs #7301 update entry and item filter tests to validate results against specific criteria by:pablone
|
||||||
|
- refactor: refs #7882 Added ACL's by:guillermo
|
||||||
|
- refactor: refs #7882 Deleted quadminds files by:guillermo
|
||||||
|
- refactor: refs #7936 add transaction & tests by:jorgep
|
||||||
|
- refactor: refs #7936 remove old trigger and add isRaid column to travel table by:jorgep
|
||||||
|
- refactor: refs #7936 remove schema by:jorgep
|
||||||
|
- refactor: refs #8002 use loop wip by:jorgep
|
||||||
|
- refactor: refs #8004 simplify SQL query by removing redundant aliases by:pablone
|
||||||
|
- refactor: refs #8262 Deprecated inventoryFailure by:guillermo
|
||||||
|
- refactor: refs #8266 changed expedition item name by:Jtubau
|
||||||
|
- refactor: refs #8272 delete bi.rotacion by:ivanm
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- feat: refs #7301 update SQL fixtures and enhance lastEntriesFilter logic by:pablone
|
||||||
|
- feat: refs #7936 add reference rates for currency in fixtures by:jorgep
|
||||||
|
- feat: refs #8174 fix by:Jbreso
|
||||||
|
- fix: 8174 pasar PIN a CHAR by:Jbreso
|
||||||
|
- fix: monitorPayMethodFilter by:carlossa
|
||||||
|
- fix: refs #6389 back by:carlossa
|
||||||
|
- fix: refs #6389 filter by:carlossa
|
||||||
|
- fix: refs #6389 packing by:carlossa
|
||||||
|
- fix: refs #6389 saleMonitor filter by:carlossa
|
||||||
|
- fix: refs #6389 salesFilter by:carlossa
|
||||||
|
- fix: refs #6583 drop focus by:jorgep
|
||||||
|
- fix: refs #6583 update onlyWithDestination logic to handle null values correctly by:jorgep
|
||||||
|
- fix: refs #7028 fix confirm deny by:carlossa
|
||||||
|
- fix: refs #7028 fix pr by:carlossa
|
||||||
|
- fix: refs #7028 fix tback findById by:carlossa
|
||||||
|
- fix: refs #7028 fix userError by:carlossa
|
||||||
|
- fix: refs #7028 remove ifs by:carlossa
|
||||||
|
- fix: refs #7028 requesterId fix by:carlossa
|
||||||
|
- fix: refs #7028 requesterId fix salesPerson by:carlossa
|
||||||
|
- fix: refs #7031 fix vnPrice by:carlossa
|
||||||
|
- fix: refs #7031 remove check by:carlossa
|
||||||
|
- fix: refs #7301 update ACL insertion to use INSERT IGNORE and refine property value by:pablone
|
||||||
|
- fix: refs #7936 add IF NOT EXISTS to isRaid column in travel table by:jorgep
|
||||||
|
- fix: refs #7936 change type by:jorgep
|
||||||
|
- fix: refs #7936 check if insert in hook & change test description by:jorgep
|
||||||
|
- fix: refs #7936 conflicts by:jorgep
|
||||||
|
- fix: refs #7936 locale by:jorgep
|
||||||
|
- fix: refs #7936 update Spanish locale for SII terms by:jorgep
|
||||||
|
- fix: refs #8174 fix by:Jbreso
|
||||||
|
- fix: refs#8174 fix by:Jbreso
|
||||||
|
- fix: refs8174 pasar a char el PIN by:Jbreso
|
||||||
|
- fix: refs #8174 Version by:guillermo
|
||||||
|
- fix: refs #8251 add eng template by:carlossa
|
||||||
|
- fix: refs #8315 fixture claimDevelopment by:alexm
|
||||||
|
|
||||||
|
# Version 24.48 - 2024-11-25
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- feat: refs #4948 Added ticket_selfConsumptionPackaging by:guillermo
|
||||||
|
- feat: refs #6818 add config table by:jorgep
|
||||||
|
- feat: refs #6818 add records by:jorgep
|
||||||
|
- feat: refs #6818 saysimple integration by:jorgep
|
||||||
|
- feat: refs #6845 userInterface by:sergiodt
|
||||||
|
- feat: refs #6869 add back by:jorgep
|
||||||
|
- feat: refs #6869 define model by:jorgep
|
||||||
|
- feat: refs #6869 refs#6869 itemShelving_get (origin/6869-createGetDetails) by:sergiodt
|
||||||
|
- feat: refs #7006 itemTypeLog by:guillermo
|
||||||
|
- feat: refs #7006 itemTypeLog created by:guillermo
|
||||||
|
- feat: refs #7006 Requested changes by:guillermo
|
||||||
|
- feat: refs #7193 added scope in parking model by:Jon
|
||||||
|
- feat: refs #7244 Requested changes by:guillermo
|
||||||
|
- feat: refs #7266 Added details and improvements in item label reports by:guillermo
|
||||||
|
- feat: refs #7266 buyFkForPrint by:sergiodt
|
||||||
|
- feat: refs #7266 First commit by:guillermo
|
||||||
|
- feat: refs #7266 Item label barcode by:guillermo
|
||||||
|
- feat: refs #7266 Item label QR by:guillermo
|
||||||
|
- feat: refs #7266 Item label QR finished by:guillermo
|
||||||
|
- feat: refs #7266 Minor change by:guillermo
|
||||||
|
- feat: refs #7266 Print corrections by:guillermo
|
||||||
|
- feat: refs #7266 Requested changes and improvements by:guillermo
|
||||||
|
- feat: refs #7266 Requested changes and query optimization by:guillermo
|
||||||
|
- feat: refs #7266 Version by:guillermo
|
||||||
|
- feat: refs #7289 #7289 apply option 1 by:Javier Segarra
|
||||||
|
- feat: refs #7289 #7289 remove bad translation by:Javier Segarra
|
||||||
|
- feat: refs #7524 restrict fields by:jorgep
|
||||||
|
- feat: refs #7641 fine tunning by:jorgep
|
||||||
|
- feat: refs #7641 improve style by:jorgep
|
||||||
|
- feat: refs #7743 add simple spec for sendMail by:pablone
|
||||||
|
- feat: refs #7743 add try catch stmt to the test by:pablone
|
||||||
|
- feat: refs #7874 add default type by:jorgep
|
||||||
|
- feat: refs #7874 use name by:jorgep
|
||||||
|
- feat: refs #7920 Added ItemShelving in shelvingLog by:guillermo
|
||||||
|
- feat: refs #7921 refs#7921 sendLostExpedition by:sergiodt
|
||||||
|
- feat: refs #7922 refs #792 scanOrder by:sergiodt
|
||||||
|
- feat: refs #7943 quitar lectura en metodos comunes by:jgallego
|
||||||
|
- feat: refs #7943 return just the required content by:jorgep
|
||||||
|
- feat: refs #7943 usa back con permisos by:jgallego
|
||||||
|
- feat: refs #8020 machineWorkerDeprecated by:sergiodt
|
||||||
|
- feat: refs #8057 Added data updates by:guillermo
|
||||||
|
- feat: refs #8057 Added data updates (origin/8057-geoFk) by:guillermo
|
||||||
|
- feat: refs #8057 Added geoFk columns by:guillermo
|
||||||
|
- feat: refs #8057 Fix version by:guillermo
|
||||||
|
- feat: refs #8057 More precision in getGeo by:guillermo
|
||||||
|
- feat: refs #8057 Requested changes by:guillermo
|
||||||
|
- feat: refs #8071 quitar esquema by:robert
|
||||||
|
- feat: refs #8071 travel_weeklyClone by:robert
|
||||||
|
- feat: refs #8080 Added column comment by:guillermo
|
||||||
|
- feat: refs #8083 add prop by:jorgep
|
||||||
|
- feat: refs #8087 Traspasar redadas a travels by:Carlos Andrés
|
||||||
|
- feat: refs #8099 refs#8099 addComplmentSalary by:sergiodt
|
||||||
|
- feat: refs #8124 Enrutadores nuevos requerimientos by:Carlos Andrés
|
||||||
|
- feat: refs #8124 Enrutadores nuevos requerimientos (origin/8124-enrutadoresNuevosRequerimientos) by:Carlos Andrés
|
||||||
|
- feat: refs #8127 entry_getCommission by:robert
|
||||||
|
- feat: refs #8127 quitar esquemas by:robert
|
||||||
|
- feat: refs #8135 refs#8135 updateTicketACL (origin/8135-ticketACL) by:sergiodt
|
||||||
|
- feat: refs #8143 deprecate recoverPass and sync from account.user by:ivanm
|
||||||
|
- feat: refs #8150 movExpeditions by:sergiodt
|
||||||
|
- feat: refs #8151 Added test by:guillermo
|
||||||
|
- feat: refs #8151 moveExpeditions by:guillermo
|
||||||
|
- feat: refs #8151 Requested changes by:guillermo
|
||||||
|
- feat(Supplier): refs #6828 add companySize by:alexm
|
||||||
|
- refactor: refs #7641 entry report style by:jorgep
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- refactor: refs #6920 add correct role by:alexm
|
||||||
|
- refactor: refs #7242 Deleted select column by:guillermo
|
||||||
|
- refactor: refs #7457 Added from param if not exists by:guillermo
|
||||||
|
- refactor: refs #7641 entry report style by:jorgep
|
||||||
|
- refactor: refs #7715 Deleted hasNewLabelMrwMethod column by:guillermo
|
||||||
|
- refactor: refs #7920 Fix tests by:guillermo
|
||||||
|
- refactor: refs #7920 Fix version by:guillermo
|
||||||
|
- refactor: refs #7920 itemShelvingLog by:guillermo
|
||||||
|
- refactor: refs #7920 Main change by:guillermo
|
||||||
|
- refactor: refs #7920 Major changes by:guillermo
|
||||||
|
- refactor: refs #7920 No changes in itemShelvingLog table by:guillermo
|
||||||
|
- refactor: refs #7920 Requested changes by:guillermo
|
||||||
|
- refactor: refs #7950 Created cmr model (7950-cmrModelUnify) by:guillermo
|
||||||
|
- refactor: refs #7950 Requested changes by:guillermo
|
||||||
|
- refactor: refs #8153 Optimized order_getTax by:guillermo
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- fix: clean deletes also zoneEvent range records by:jgallego
|
||||||
|
- fix: more data for fixture.before by:Pako
|
||||||
|
- fix: refs #4948 Tests by:guillermo
|
||||||
|
- fix: refs #6644 email and translations by:carlossa
|
||||||
|
- fix: refs #6818 add config by:jorgep
|
||||||
|
- fix: refs #6818 add defaultChannel by:jorgep
|
||||||
|
- fix: refs #6818 use right col type by:jorgep
|
||||||
|
- fix: refs #6869 use id as primaryKey by:jorgep
|
||||||
|
- fix: refs #7244 Added collection ACL by:guillermo
|
||||||
|
- fix: refs #7283 item filters by:carlossa
|
||||||
|
- fix: refs #7283 remove by:carlossa
|
||||||
|
- fix: refs #7283 remove tests by:carlossa
|
||||||
|
- fix: refs #7283 tback by:carlossa
|
||||||
|
- fix: refs #7323 add remaining fields (origin/7323-warfix-addRemainingFields) by:jorgep
|
||||||
|
- fix: refs #7457 add with on select to reduce by:pablone
|
||||||
|
- fix: refs #7457 empty commit for gitea by:pablone
|
||||||
|
- fix: refs #7457 error on empty from param and add translate by:pablone
|
||||||
|
- fix: refs #7457 remove group by calc time reduce bellow 1s by:pablone
|
||||||
|
- fix: refs #7457 remove translate and use param definition for restriction by:pablone
|
||||||
|
- fix: refs #7641 align columns by:jorgep
|
||||||
|
- fix: refs #7641 drop boilerplate code by:jorgep
|
||||||
|
- fix: refs #7920 refs#7920 itemShelvingLog by:sergiodt
|
||||||
|
- fix: refs #8153 Version by:guillermo
|
||||||
|
- revert cd7ed6987a88e00275b562d3248f368b6333620c by:Javier Segarra
|
||||||
|
|
||||||
|
# Version 24.38 - 2024-09-17
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- chore: refs #7323 filter data by:jorgep
|
||||||
|
- chore: refs #7323 fix test by:jorgep
|
||||||
|
- chore: refs #7323 worker changes by:jorgep
|
||||||
|
- chore: refs #7323 worker changes wip by:jorgep
|
||||||
|
- chore: refs #7524 add select limit by:jorgep
|
||||||
|
- feat(AccessToken&ACL): refs #7547 upgrade security by:alexm
|
||||||
|
- feat: deleted code and redirect to Lilium by:Jon
|
||||||
|
- feat: refs #4515 New throw buy_checkItem by:guillermo
|
||||||
|
- feat: refs #6650 Added saleGroupLog by:guillermo
|
||||||
|
- feat: refs #6650 new itemShelvingLog by:guillermo
|
||||||
|
- feat: refs #6760 refs #actualiza campo nickname by:jgallego
|
||||||
|
- feat: refs #7277 fdescribe by:jgallego
|
||||||
|
- feat: refs #7277 fit by:jgallego
|
||||||
|
- feat: refs #7277 refundInvoices by:jgallego
|
||||||
|
- feat: refs #7277 test with warehouse by:jgallego
|
||||||
|
- feat: refs #7277 traducciones by:jgallego
|
||||||
|
- feat: refs #7277 transfer addressFk by:jgallego
|
||||||
|
- feat: refs #7532 Requested changes by:guillermo
|
||||||
|
- feat: refs #7564 Added proc by:guillermo
|
||||||
|
- feat: refs #7564 Added ticket_setVolumeItemCost by:guillermo
|
||||||
|
- feat: refs #7564 Added volume column by:guillermo
|
||||||
|
- feat: refs #7564 Fix version by:guillermo
|
||||||
|
- feat: refs #7564 Requested changes by:guillermo
|
||||||
|
- feat: refs #7615 setDeleted by:robert
|
||||||
|
- feat: refs #7650 Added no transfer lines to inventory entry and fixtures by:guillermo
|
||||||
|
- feat: refs #7650 Fix tests by:guillermo
|
||||||
|
- feat: refs #7747 Delete buyUltimate and buyUltimateFromInterval by:ivanm
|
||||||
|
- feat: refs #7759 Changed defined only of vn objects by:guillermo
|
||||||
|
- feat: refs #7759 Changed definer root to vn-admin by:guillermo
|
||||||
|
- feat: refs #7759 Changed name by:guillermo
|
||||||
|
- feat: refs #7759 Deleted version 11163-maroonEucalyptus by:guillermo
|
||||||
|
- feat: refs #7759 Revoke routine grants vn by:guillermo
|
||||||
|
- feat: refs #7811 Added comment by:guillermo
|
||||||
|
- feat: refs #7811 Added new params in datasources.json by:guillermo
|
||||||
|
- feat: refs #7898 Add column "floor" in vn.parking by:ivanm
|
||||||
|
- feat: refs #7898 Modify default by:ivanm
|
||||||
|
- feat: refs #7905 Added new method getBuysCsv by:guillermo
|
||||||
|
- feat: refs #7905 Added param toCsv by:guillermo
|
||||||
|
- feat: refs #7938 remove unnecessary insert in clientLog by:alexm
|
||||||
|
- feat: refs #7953 pullinfo (7953-devToTest_2438) by:alexm
|
||||||
|
- feat(salix): #7671 define isDestiny field in model by:Javier Segarra
|
||||||
|
- feat(salix): refs #7896 update version and changelog (origin/7896_down_devToTest_2436) by:Javier Segarra
|
||||||
|
- feat(salix): refs #7905 #7905 use getBuys toCSV flattened by:Javier Segarra
|
||||||
|
- feat(ssalix): refs #7671 #7671 checkDates by:Javier Segarra
|
||||||
|
- feat(ssalix): refs #7671 #7671 checkDates to present by:Javier Segarra
|
||||||
|
- feat: ticket 215005 Changed acl show transferClient by:guillermo
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- perf: refs #7671 improve showBadDates by:Javier Segarra
|
||||||
|
- perf(salix): refs #7671 #7671 imrpove and revert where changes by:Javier Segarra
|
||||||
|
- refactor: deleted e2e & added back descriptor and summary by:Jon
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- chore: refs #7323 fix test by:jorgep
|
||||||
|
- feat: refs #7650 Added no transfer lines to inventory entry and fixtures by:guillermo
|
||||||
|
- fix by:guillermo
|
||||||
|
- fixes: refs #7760 collection problems by:Carlos Andrés
|
||||||
|
- fix merge dev (7407-workerMedical) by:alexm
|
||||||
|
- fix: refs #6727 No delete log tables data in clean procedures by:guillermo
|
||||||
|
- fix: refs #6897 back and tests by:carlossa
|
||||||
|
- fix: refs #6897 back by:carlossa
|
||||||
|
- fix: refs #6897 fix filter by:carlossa
|
||||||
|
- fix: refs #6897 fix json by:carlossa
|
||||||
|
- fix: refs #6897 travel filter by:carlossa
|
||||||
|
- fix: refs #6897 error test by:jgallego
|
||||||
|
- fix: refs #7323 fetch from right source by:jorgep
|
||||||
|
- fix: refs #7564 Deleted query by:guillermo
|
||||||
|
- fix: refs #7759 Added user 'vn'@'localhost' & grants by:guillermo
|
||||||
|
- fix: refs #7760 collection problems by:Carlos Andrés
|
||||||
|
- fix: refs #7760 tmp.ticketIPT by:Carlos Andrés
|
||||||
|
- fix: refs #7905 added comments to flatten.js by:guillermo
|
||||||
|
- fix: refs ##7905 Handle error by:guillermo
|
||||||
|
- fix(salix): refs #7905 #7905 use right fn to flatten data by:Javier Segarra
|
||||||
|
- perf(salix): refs #7671 #7671 imrpove and revert where changes by:Javier Segarra
|
||||||
|
- refs #6898 fix supplier remove by:carlossa
|
||||||
|
- refs #7407 fix acls fixtures by:carlossa
|
||||||
|
- test: fix connections e2e (7547-accessToken-security) by:alexm
|
||||||
|
- test: refs #7277 fix test proposal by:Javier Segarra
|
||||||
|
- test(salix): refs #7671 #7671 improve and revert where changes by:Javier Segarra
|
||||||
|
|
||||||
|
# Version 24.36 - 2024-09-03
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- chore: refs #7524 WIP limit call by:jorgep
|
||||||
|
- chore: refs #7524 modify ormConfig table col (origin/7524-warmfix-modifyColumn) by:jorgep
|
||||||
|
- feat(update-user): refs #7848 add twoFactor by:alexm
|
||||||
|
- feat: #3199 Requested changes by:guillermo
|
||||||
|
- feat: refs #3199 Added more scopes ticket_recalcByScope by:guillermo
|
||||||
|
- feat: refs #3199 Added one more scope ticket_recalcByScope by:guillermo
|
||||||
|
- feat: refs #3199 Created ticket_recalcItemTaxCountryByScope by:guillermo
|
||||||
|
- feat: refs #3199 Requested changes by:guillermo
|
||||||
|
- feat: refs #7346 add multiple feature by:jgallego
|
||||||
|
- feat: refs #7346 backTest checks new implementation by:jgallego
|
||||||
|
- feat: refs #7346 mas intuitivo by:jgallego
|
||||||
|
- feat: refs #7514 Changes to put srt log (origin/7514-srtLog) by:guillermo
|
||||||
|
- feat: refs #7524 add default limit (origin/7524-limitSelect) by:jorgep
|
||||||
|
- feat: refs #7524 add mock limit on find query by:jorgep
|
||||||
|
- feat: refs #7524 wip remote hooks by:jorgep
|
||||||
|
- feat: refs #7562 Requested changes by:guillermo
|
||||||
|
- feat: refs #7567 Changed time to call event by:guillermo
|
||||||
|
- feat: refs #7567 Requested changes by:guillermo
|
||||||
|
- feat: refs #7710 pr revision by:jgallego
|
||||||
|
- feat: refs #7710 test fixed (origin/7710-cloneWithTicketPackaging, 7710-cloneWithTicketPackaging) by:jgallego
|
||||||
|
- feat: refs #7712 Fix by:guillermo
|
||||||
|
- feat: refs #7712 Unify by:guillermo
|
||||||
|
- feat: refs #7712 sizeLimit (origin/7712-sizeLimit) by:guillermo
|
||||||
|
- feat: refs #7758 Add code mandateType and accountDetailType by:ivanm
|
||||||
|
- feat: refs #7758 Modify code lowerCamelCase and UNIQUE by:ivanm
|
||||||
|
- feat: refs #7758 accountDetailType fix deploy error by:ivanm
|
||||||
|
- feat: refs #7784 Changes in entry-order-pdf by:guillermo
|
||||||
|
- feat: refs #7784 Requested changes by:guillermo
|
||||||
|
- feat: refs #7799 Added Fk in vn.item.itemPackingTypeFk by:guillermo
|
||||||
|
- feat: refs #7800 Added company Fk by:guillermo
|
||||||
|
- feat: refs #7842 Added editorFk in vn.host by:guillermo
|
||||||
|
- feat: refs #7860 Update new packagings (origin/7860-newPackaging) by:guillermo
|
||||||
|
- feat: refs #7862 roadmap new fields by:ivanm
|
||||||
|
- feat: refs #7882 Added quadMindsConfig table by:guillermo
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- refactor: refs #7567 Fix and improvement by:guillermo
|
||||||
|
- refactor: refs #7567 Minor change by:guillermo
|
||||||
|
- refactor: refs #7756 Fix tests by:guillermo
|
||||||
|
- refactor: refs #7798 Drop bi.Greuges_comercial_detail by:guillermo
|
||||||
|
- refactor: refs #7848 adapt to lilium by:alexm
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- feat: refs #7710 test fixed (origin/7710-cloneWithTicketPackaging, 7710-cloneWithTicketPackaging) by:jgallego
|
||||||
|
- feat: refs #7758 accountDetailType fix deploy error by:ivanm
|
||||||
|
- fix(salix): #7283 ItemFixedPrice duplicated (origin/7283_itemFixedPrice_duplicated) by:Javier Segarra
|
||||||
|
- fix: refs #7346 minor error (origin/7346, 7346) by:jgallego
|
||||||
|
- fix: refs #7355 remove and tests accounts (origin/7355-accountMigration2) by:carlossa
|
||||||
|
- fix: refs #7355 remove and tests accounts by:carlossa
|
||||||
|
- fix: refs #7524 default limit select by:jorgep
|
||||||
|
- fix: refs #7756 Foreign keys invoiceOut (origin/7756-fixRefFk) by:guillermo
|
||||||
|
- fix: refs #7756 id 0 by:guillermo
|
||||||
|
- fix: refs #7800 tpvMerchantEnable PRIMARY KEY (origin/7800-tpvMerchantEnable) by:guillermo
|
||||||
|
- fix: refs #7800 tpvMerchantEnable PRIMARY KEY by:guillermo
|
||||||
|
- fix: refs #7916 itemShelving_transfer (origin/test, test) by:guillermo
|
||||||
|
- fix: refs #pako Deleted duplicated version by:guillermo
|
||||||
|
|
||||||
|
# Version 24.34 - 2024-08-20
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- #6900 feat: clear empty by:jorgep
|
||||||
|
- #6900 feat: empty commit by:jorgep
|
||||||
|
- chore: refs #6900 beautify code by:jorgep
|
||||||
|
- chore: refs #6989 add config model by:jorgep
|
||||||
|
- feat workerActivity refs #6078 by:sergiodt
|
||||||
|
- feat: #6453 Refactor (origin/6453-orderConfirm) by:guillermo
|
||||||
|
- feat: #6453 Rollback always split by itemPackingType by:guillermo
|
||||||
|
- feat: deleted worker module code & redirect to Lilium by:Jon
|
||||||
|
- feat: refs #6453 Added new ticket search by:guillermo
|
||||||
|
- feat: refs #6453 Fixes by:guillermo
|
||||||
|
- feat: refs #6453 Minor changes by:guillermo
|
||||||
|
- feat: refs #6453 Requested changes by:guillermo
|
||||||
|
- feat: refs #6900 drop section by:jorgep
|
||||||
|
- feat: refs #7283 order by desc date by:jorgep
|
||||||
|
- feat: refs #7323 add locale by:jorgep
|
||||||
|
- feat: refs #7323 redirect to lilium by:jorgep
|
||||||
|
- feat: refs #7646 delete scannableCodeType by:robert
|
||||||
|
- feat: refs #7713 Created ACLLog by:guillermo
|
||||||
|
- feat: refs #7774 (origin/7774-ticket_cloneWeekly) by:robert
|
||||||
|
- feat: refs #7774 #7774 Changes ticket_cloneWeekly by:guillermo
|
||||||
|
- feat: refs #7774 ticket_cloneWeekly by:robert
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- refactor: refs #6453 Major changes by:guillermo
|
||||||
|
- refactor: refs #6453 Minor changes by:guillermo
|
||||||
|
- refactor: refs #6453 order_confirmWithUser by:guillermo
|
||||||
|
- refactor: refs #7646 #7646 Deleted scannable* variables productionConfig by:guillermo
|
||||||
|
- refactor: refs #7820 Deprecated silexACL by:guillermo
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- #6900 fix: #6900 rectificative filter by:jorgep
|
||||||
|
- #6900 fix: empty commit by:jorgep
|
||||||
|
- fix(orders_filter): add sourceApp accepts by:alexm
|
||||||
|
- fix: refs #6130 commit lint by:pablone
|
||||||
|
- fix: refs #6453 order_confirmWithUser by:guillermo
|
||||||
|
- fix: refs #7283 sql by:jorgep
|
||||||
|
- fix: refs #7713 ACL Log by:guillermo
|
||||||
|
- test: fix claim descriptor redirect to lilium by:alexm
|
||||||
|
- test: fix ticket redirect to lilium by:alexm
|
||||||
|
- test: fix ticket sale e2e by:alexm
|
||||||
|
|
||||||
|
# Version 24.32 - 2024-08-06
|
||||||
|
|
||||||
|
### Added 🆕
|
||||||
|
|
||||||
|
- chore: refs #7197 add supplierActivityFk filter by:jorgep
|
||||||
|
- feat checkExpeditionPrintOut refs #7751 by:sergiodt
|
||||||
|
- feat(defaulter_filter): add department by:alexm
|
||||||
|
- feat: redirect to lilium page not found by:alexm
|
||||||
|
- feat: refactor buyUltimate refs #7736 by:Carlos Andrés
|
||||||
|
- feat: refs #6403 add delete by:pablone
|
||||||
|
- feat: refs #7126 Added manaClaim calc by:guillermo
|
||||||
|
- feat: refs #7126 Refactor and added columns in bs.waste table & proc by:guillermo
|
||||||
|
- feat: refs #7197 filter by correcting by:jorgep
|
||||||
|
- feat: refs #7297 add new columns by:pablone
|
||||||
|
- feat: refs #7356 new parameters in sql for Weekly tickets front by:Jon
|
||||||
|
- feat: refs #7401 redirect lilium by:pablone
|
||||||
|
- feat: refs #7511 Fix tests by:guillermo
|
||||||
|
- feat: refs #7511 Rename to multiConfig tables by:guillermo
|
||||||
|
- feat: refs #7589 Added display (item_valuateInventory) by:guillermo
|
||||||
|
- feat: refs #7589 Added vItemTypeFk & vItemCategoryFk (item_valuateInventory) by:guillermo
|
||||||
|
- feat: refs #7681 Changes by:guillermo
|
||||||
|
- feat: refs #7681 Optimization and refactor by:guillermo
|
||||||
|
- feat: refs #7683 drop temporary table by:robert
|
||||||
|
- feat: refs #7683 productionControl by:robert
|
||||||
|
- feat: refs #7728 Added throw due date by:guillermo
|
||||||
|
- feat: refs #7740 Ticket before update added restriction by:guillermo
|
||||||
|
- feat(salix): #7648 Add field for endpoint as buyLabel report by:Javier Segarra
|
||||||
|
- feat(salix): #7648 remove white line by:Javier Segarra
|
||||||
|
- feat: tabla config dias margen vctos. refs #7728 by:Carlos Andrés
|
||||||
|
|
||||||
|
### Changed 📦
|
||||||
|
|
||||||
|
- eat: refactor buyUltimate refs #7736 by:Carlos Andrés
|
||||||
|
- feat: refactor buyUltimate refs #7736 by:Carlos Andrés
|
||||||
|
- feat: refs #7681 Optimization and refactor by:guillermo
|
||||||
|
- refactor: refs #7126 Requested changes by:guillermo
|
||||||
|
- refactor: refs #7511 Minor change by:guillermo
|
||||||
|
- refactor: refs #7640 Multipleinventory available by:guillermo
|
||||||
|
- refactor: refs #7681 Changes by:guillermo
|
||||||
|
- refactor: refs #7681 Requested changes by:guillermo
|
||||||
|
|
||||||
|
### Fixed 🛠️
|
||||||
|
|
||||||
|
- add prefix (hotFix_liliumRedirection) by:alexm
|
||||||
|
- fix(client_filter): add recovery by:alexm
|
||||||
|
- fix: defaulter filter correct sql (6943-fix_defaulter_filter) by:alexm
|
||||||
|
- fix(deletExpeditions): merge test → dev by:guillermo
|
||||||
|
- fix: refs #6403 fix mrw cancel shipment return type by:pablone
|
||||||
|
- fix: refs #7126 Added addressWaste type by:guillermo
|
||||||
|
- fix: refs #7126 Fix by:guillermo
|
||||||
|
- fix: refs #7126 Minor change by:guillermo
|
||||||
|
- fix: refs #7126 Primary key no unique data by:guillermo
|
||||||
|
- fix: refs #7126 Slow update by:guillermo
|
||||||
|
- fix: refs #7511 Minor change by:guillermo
|
||||||
|
- fix: refs #7546 Deleted insert util.binlogQueue by:guillermo
|
||||||
|
- fix: refs #7811 Variables pm2 by:guillermo
|
||||||
|
- fix: without path by:alexm
|
||||||
|
|
||||||
# Version 24.28 - 2024-07-09
|
# Version 24.28 - 2024-07-09
|
||||||
|
|
||||||
### Added 🆕
|
### Added 🆕
|
||||||
|
|
|
@ -7,7 +7,8 @@ def RUN_BUILD
|
||||||
|
|
||||||
def BRANCH_ENV = [
|
def BRANCH_ENV = [
|
||||||
test: 'test',
|
test: 'test',
|
||||||
master: 'production'
|
master: 'production',
|
||||||
|
beta: 'production'
|
||||||
]
|
]
|
||||||
|
|
||||||
node {
|
node {
|
||||||
|
@ -18,7 +19,8 @@ node {
|
||||||
PROTECTED_BRANCH = [
|
PROTECTED_BRANCH = [
|
||||||
'dev',
|
'dev',
|
||||||
'test',
|
'test',
|
||||||
'master'
|
'master',
|
||||||
|
'beta'
|
||||||
].contains(env.BRANCH_NAME)
|
].contains(env.BRANCH_NAME)
|
||||||
|
|
||||||
FROM_GIT = env.JOB_NAME.startsWith('gitea/')
|
FROM_GIT = env.JOB_NAME.startsWith('gitea/')
|
||||||
|
@ -62,6 +64,18 @@ pipeline {
|
||||||
PROJECT_NAME = 'salix'
|
PROJECT_NAME = 'salix'
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
|
stage('Version') {
|
||||||
|
when {
|
||||||
|
expression { RUN_BUILD }
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def packageJson = readJSON file: 'package.json'
|
||||||
|
def version = "${packageJson.version}-build${env.BUILD_ID}"
|
||||||
|
writeFile(file: 'VERSION.txt', text: version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
stage('Install') {
|
stage('Install') {
|
||||||
environment {
|
environment {
|
||||||
NODE_ENV = ''
|
NODE_ENV = ''
|
||||||
|
@ -118,11 +132,10 @@ pipeline {
|
||||||
when {
|
when {
|
||||||
expression { RUN_BUILD }
|
expression { RUN_BUILD }
|
||||||
}
|
}
|
||||||
|
environment {
|
||||||
|
VERSION = readFile 'VERSION.txt'
|
||||||
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
|
||||||
def packageJson = readJSON file: 'package.json'
|
|
||||||
env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
|
|
||||||
}
|
|
||||||
sh 'docker-compose build back'
|
sh 'docker-compose build back'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,11 +169,10 @@ pipeline {
|
||||||
when {
|
when {
|
||||||
expression { RUN_BUILD }
|
expression { RUN_BUILD }
|
||||||
}
|
}
|
||||||
|
environment {
|
||||||
|
VERSION = readFile 'VERSION.txt'
|
||||||
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
|
||||||
def packageJson = readJSON file: 'package.json'
|
|
||||||
env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
|
|
||||||
}
|
|
||||||
sh 'gulp build'
|
sh 'gulp build'
|
||||||
sh 'docker-compose build front'
|
sh 'docker-compose build front'
|
||||||
}
|
}
|
||||||
|
@ -175,12 +187,9 @@ pipeline {
|
||||||
}
|
}
|
||||||
environment {
|
environment {
|
||||||
CREDENTIALS = credentials('docker-registry')
|
CREDENTIALS = credentials('docker-registry')
|
||||||
|
VERSION = readFile 'VERSION.txt'
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
|
||||||
def packageJson = readJSON file: 'package.json'
|
|
||||||
env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
|
|
||||||
}
|
|
||||||
sh 'docker login --username $CREDENTIALS_USR --password $CREDENTIALS_PSW $REGISTRY'
|
sh 'docker login --username $CREDENTIALS_USR --password $CREDENTIALS_PSW $REGISTRY'
|
||||||
sh 'docker-compose push'
|
sh 'docker-compose push'
|
||||||
}
|
}
|
||||||
|
@ -207,11 +216,10 @@ pipeline {
|
||||||
when {
|
when {
|
||||||
expression { FROM_GIT }
|
expression { FROM_GIT }
|
||||||
}
|
}
|
||||||
|
environment {
|
||||||
|
VERSION = readFile 'VERSION.txt'
|
||||||
|
}
|
||||||
steps {
|
steps {
|
||||||
script {
|
|
||||||
def packageJson = readJSON file: 'package.json'
|
|
||||||
env.VERSION = "${packageJson.version}-build${env.BUILD_ID}"
|
|
||||||
}
|
|
||||||
withKubeConfig([
|
withKubeConfig([
|
||||||
serverUrl: "$KUBERNETES_API",
|
serverUrl: "$KUBERNETES_API",
|
||||||
credentialsId: 'kubernetes',
|
credentialsId: 'kubernetes',
|
||||||
|
|
|
@ -32,8 +32,7 @@ RUN apt-get update \
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends \
|
&& apt-get install -y --no-install-recommends \
|
||||||
samba-common-bin samba-dsdb-modules\
|
samba-common-bin samba-dsdb-modules\
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
&& npm -g install pm2
|
|
||||||
|
|
||||||
# Salix
|
# Salix
|
||||||
|
|
||||||
|
@ -55,7 +54,4 @@ COPY \
|
||||||
README.md \
|
README.md \
|
||||||
./
|
./
|
||||||
|
|
||||||
CMD ["pm2-runtime", "./back/process.yml"]
|
CMD ["node", "--tls-min-v1.0", "--openssl-legacy-provider", "./loopback/server/server.js"]
|
||||||
|
|
||||||
HEALTHCHECK --interval=15s --timeout=10s \
|
|
||||||
CMD curl -f http://localhost:3000/api/Applications/status || exit 1
|
|
|
@ -27,38 +27,46 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.sendCheckingPresence = async(ctx, recipientId, message) => {
|
Self.sendCheckingPresence = async(ctx, recipientId, message) => {
|
||||||
if (!recipientId) return false;
|
|
||||||
const models = Self.app.models;
|
|
||||||
|
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
const sender = await models.VnUser.findById(userId, {fields: ['id']});
|
|
||||||
const recipient = await models.VnUser.findById(recipientId, null);
|
|
||||||
|
|
||||||
// Prevent sending messages to yourself
|
|
||||||
if (recipientId == userId) return false;
|
|
||||||
if (!recipient)
|
|
||||||
throw new Error(`Could not send message "${message}" to worker id ${recipientId} from user ${userId}`);
|
|
||||||
|
|
||||||
if (!isProduction())
|
|
||||||
message = `[Test:Environment to user ${userId}] ` + message;
|
|
||||||
|
|
||||||
const chat = await models.Chat.create({
|
|
||||||
senderFk: sender.id,
|
|
||||||
recipient: `@${recipient.name}`,
|
|
||||||
dated: Date.vnNew(),
|
|
||||||
checkUserStatus: 1,
|
|
||||||
message: message,
|
|
||||||
status: 'sending',
|
|
||||||
attempts: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Self.sendCheckingUserStatus(chat);
|
const models = Self.app.models;
|
||||||
await Self.updateChat(chat, 'sent');
|
const sender = await models.VnUser.findById(userId, {fields: ['id']});
|
||||||
} catch (error) {
|
const error = `Could not send message from user ${userId}`;
|
||||||
await Self.updateChat(chat, 'error', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
if (!recipientId) throw new Error(error);
|
||||||
|
const recipient = await models.VnUser.findById(recipientId, null);
|
||||||
|
if (!recipient)
|
||||||
|
throw new Error(error);
|
||||||
|
|
||||||
|
// Prevent sending messages to yourself
|
||||||
|
if (recipientId == userId) return false;
|
||||||
|
|
||||||
|
if (!isProduction())
|
||||||
|
message = `[Test:Environment to user ${userId}] ` + message;
|
||||||
|
|
||||||
|
const chat = await models.Chat.create({
|
||||||
|
senderFk: sender.id,
|
||||||
|
recipient: `@${recipient.name}`,
|
||||||
|
dated: Date.vnNew(),
|
||||||
|
checkUserStatus: 1,
|
||||||
|
message: message,
|
||||||
|
status: 'sending',
|
||||||
|
attempts: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Self.sendCheckingUserStatus(chat);
|
||||||
|
await Self.updateChat(chat, 'sent');
|
||||||
|
} catch (error) {
|
||||||
|
await Self.updateChat(chat, 'error', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
await Self.rawSql(`
|
||||||
|
INSERT INTO util.debug (variable, value)
|
||||||
|
VALUES ('sendCheckingPresence_error', ?)
|
||||||
|
`, [`User: ${userId}, recipient: ${recipientId}, message: ${message}, error: ${e}`]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,9 +20,14 @@ module.exports = Self => {
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const [, , [{collectionFk}]] =
|
const randStr = Math.random().toString(36).substring(3);
|
||||||
await Self.rawSql('CALL vn.collection_assign(?, @vCollectionFk); SELECT @vCollectionFk collectionFk',
|
const result = await Self.rawSql(`
|
||||||
[userId], myOptions);
|
CALL vn.collection_assign(?, @vCollectionFk);
|
||||||
|
SELECT @vCollectionFk ?
|
||||||
|
`, [userId, randStr], myOptions);
|
||||||
|
|
||||||
|
// Por si entra en SELECT FOR UPDATE una o varias veces
|
||||||
|
const collectionFk = result.find(item => item[0]?.[randStr] !== undefined)?.[0]?.[randStr];
|
||||||
|
|
||||||
if (!collectionFk) throw new UserError('There are not picking tickets');
|
if (!collectionFk) throw new UserError('There are not picking tickets');
|
||||||
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
|
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
|
||||||
|
|
|
@ -19,8 +19,15 @@ module.exports = Self => {
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
const [info, info2, [{'@vCollectionFk': collectionFk}]] = await Self.rawSql(
|
|
||||||
'CALL vn.collection_getAssigned(?, @vCollectionFk);SELECT @vCollectionFk', [userId], myOptions);
|
const randStr = Math.random().toString(36).substring(3);
|
||||||
|
const result = await Self.rawSql(`
|
||||||
|
CALL vn.collection_getAssigned(?, @vCollectionFk);
|
||||||
|
SELECT @vCollectionFk ?
|
||||||
|
`, [userId, randStr], myOptions);
|
||||||
|
|
||||||
|
const collectionFk = result.find(item => item[0]?.[randStr] !== undefined)?.[0]?.[randStr];
|
||||||
|
|
||||||
if (!collectionFk) throw new UserError('There are not picking tickets');
|
if (!collectionFk) throw new UserError('There are not picking tickets');
|
||||||
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
|
await Self.rawSql('CALL vn.collection_printSticker(?, NULL)', [collectionFk], myOptions);
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,8 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getSales = async(ctx, collectionOrTicketFk, print, source, options) => {
|
Self.getSales = async(ctx, collectionOrTicketFk, print, source, options) => {
|
||||||
const models = Self.app.models;
|
|
||||||
const userId = ctx.req.accessToken.userId;
|
const userId = ctx.req.accessToken.userId;
|
||||||
const myOptions = {userId};
|
const myOptions = {userId};
|
||||||
const $t = ctx.req.__;
|
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
@ -64,7 +62,7 @@ module.exports = Self => {
|
||||||
let observations = ticket.observaciones.split(' ');
|
let observations = ticket.observaciones.split(' ');
|
||||||
|
|
||||||
for (let observation of observations) {
|
for (let observation of observations) {
|
||||||
const salesDepartment = ticket.salesDepartmentFk;
|
const salesDepartment = ticket.departmentFk;
|
||||||
if (observation.startsWith('#') || observation.startsWith('@')) {
|
if (observation.startsWith('#') || observation.startsWith('@')) {
|
||||||
await models.Chat.send(ctx,
|
await models.Chat.send(ctx,
|
||||||
observation,
|
observation,
|
||||||
|
@ -145,15 +143,15 @@ module.exports = Self => {
|
||||||
|
|
||||||
async function getBarcodes(ticketId, options) {
|
async function getBarcodes(ticketId, options) {
|
||||||
const query =
|
const query =
|
||||||
`SELECT s.id movementId,
|
`SELECT s.id movementId,
|
||||||
b.code,
|
b.code,
|
||||||
c.id
|
c.id
|
||||||
FROM vn.sale s
|
FROM vn.sale s
|
||||||
LEFT JOIN vn.itemBarcode b ON b.itemFk = s.itemFk
|
LEFT JOIN vn.itemBarcode b ON b.itemFk = s.itemFk
|
||||||
LEFT JOIN vn.buy c ON c.itemFk = s.itemFk
|
LEFT JOIN vn.buy c ON c.itemFk = s.itemFk
|
||||||
LEFT JOIN vn.entry e ON e.id = c.entryFk
|
LEFT JOIN vn.entry e ON e.id = c.entryFk
|
||||||
LEFT JOIN vn.travel tr ON tr.id = e.travelFk
|
LEFT JOIN vn.travel tr ON tr.id = e.travelFk
|
||||||
WHERE s.ticketFk = ?
|
WHERE s.ticketFk = ?
|
||||||
AND tr.landed >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)`;
|
AND tr.landed >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR)`;
|
||||||
return Self.rawSql(query, [ticketId], options);
|
return Self.rawSql(query, [ticketId], options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const sales = await Self.rawSql(`
|
const sales = await Self.rawSql(`
|
||||||
SELECT s.ticketFk,
|
SELECT s.ticketFk,
|
||||||
|
NULL ticketOrder,
|
||||||
sgd.saleGroupFk,
|
sgd.saleGroupFk,
|
||||||
s.id saleFk,
|
s.id saleFk,
|
||||||
s.itemFk,
|
s.itemFk,
|
||||||
|
@ -57,28 +58,33 @@ module.exports = Self => {
|
||||||
ROW_NUMBER () OVER (PARTITION BY s.id ORDER BY pickingOrder) currentItemShelving,
|
ROW_NUMBER () OVER (PARTITION BY s.id ORDER BY pickingOrder) currentItemShelving,
|
||||||
COUNT(*) OVER (PARTITION BY s.id ORDER BY s.id) totalItemShelving,
|
COUNT(*) OVER (PARTITION BY s.id ORDER BY s.id) totalItemShelving,
|
||||||
sh.code,
|
sh.code,
|
||||||
IFNULL(p2.code, p.code) parkingCode,
|
p2.code parkingCodePrevia,
|
||||||
IFNULL(p2.pickingOrder, p.pickingOrder) pickingOrder,
|
p2.pickingOrder pickingOrderPrevia,
|
||||||
|
p.code parkingCode,
|
||||||
|
p.pickingOrder pickingOrder,
|
||||||
iss.id itemShelvingSaleFk,
|
iss.id itemShelvingSaleFk,
|
||||||
iss.isPicked
|
iss.isPicked,
|
||||||
|
iss.itemShelvingFk,
|
||||||
|
st.code stateCode
|
||||||
FROM ticketCollection tc
|
FROM ticketCollection tc
|
||||||
LEFT JOIN collection c ON c.id = tc.collectionFk
|
LEFT JOIN collection c ON c.id = tc.collectionFk
|
||||||
JOIN ticket t ON t.id = tc.ticketFk
|
JOIN sale s ON s.ticketFk = tc.ticketFk
|
||||||
JOIN sale s ON s.ticketFk = t.id
|
|
||||||
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
|
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
|
||||||
LEFT JOIN saleGroup sg ON sg.id = sgd.saleGroupFk
|
LEFT JOIN saleGroup sg ON sg.id = sgd.saleGroupFk
|
||||||
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
|
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
|
||||||
JOIN item i ON i.id = s.itemFk
|
JOIN item i ON i.id = s.itemFk
|
||||||
JOIN itemShelvingSale iss ON iss.saleFk = s.id
|
JOIN itemShelvingSale iss ON iss.saleFk = s.id
|
||||||
LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
|
LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
|
||||||
LEFT JOIN shelving sh ON sh.code = ish.shelvingFk
|
LEFT JOIN shelving sh ON sh.id = ish.shelvingFk
|
||||||
LEFT JOIN parking p ON p.id = sh.parkingFk
|
LEFT JOIN parking p ON p.id = sh.parkingFk
|
||||||
LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk
|
LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk
|
||||||
LEFT JOIN origin o ON o.id = i.originFk
|
LEFT JOIN origin o ON o.id = i.originFk
|
||||||
|
LEFT JOIN state st ON st.id = sg.stateFk
|
||||||
WHERE tc.collectionFk = ?
|
WHERE tc.collectionFk = ?
|
||||||
GROUP BY s.id, ish.id, p.code, p2.code
|
GROUP BY s.id, ish.id, p.code, p2.code
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT s.ticketFk,
|
SELECT s.ticketFk,
|
||||||
|
DENSE_RANK() OVER (ORDER BY ss.id),
|
||||||
sgd.saleGroupFk,
|
sgd.saleGroupFk,
|
||||||
s.id saleFk,
|
s.id saleFk,
|
||||||
s.itemFk,
|
s.itemFk,
|
||||||
|
@ -96,25 +102,29 @@ module.exports = Self => {
|
||||||
ROW_NUMBER () OVER (PARTITION BY s.id ORDER BY p.pickingOrder),
|
ROW_NUMBER () OVER (PARTITION BY s.id ORDER BY p.pickingOrder),
|
||||||
COUNT(*) OVER (PARTITION BY s.id ORDER BY s.id) ,
|
COUNT(*) OVER (PARTITION BY s.id ORDER BY s.id) ,
|
||||||
sh.code,
|
sh.code,
|
||||||
IFNULL(p2.code, p.code),
|
p2.code,
|
||||||
IFNULL(p2.pickingOrder, p.pickingOrder),
|
p2.pickingOrder,
|
||||||
|
p.code,
|
||||||
|
p.pickingOrder,
|
||||||
iss.id itemShelvingSaleFk,
|
iss.id itemShelvingSaleFk,
|
||||||
iss.isPicked
|
iss.isPicked,
|
||||||
|
iss.itemShelvingFk,
|
||||||
|
st.code stateCode
|
||||||
FROM sectorCollection sc
|
FROM sectorCollection sc
|
||||||
JOIN sectorCollectionSaleGroup ss ON ss.sectorCollectionFk = sc.id
|
JOIN sectorCollectionSaleGroup ss ON ss.sectorCollectionFk = sc.id
|
||||||
JOIN saleGroup sg ON sg.id = ss.saleGroupFk
|
JOIN saleGroup sg ON sg.id = ss.saleGroupFk
|
||||||
JOIN ticket t ON t.id = sg.ticketFk
|
LEFT JOIN saleGroupDetail sgd ON sgd.saleGroupFk = sg.id
|
||||||
JOIN sale s ON s.ticketFk = t.id
|
JOIN sale s ON s.id = sgd.saleFk
|
||||||
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
|
|
||||||
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
|
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
|
||||||
JOIN item i ON i.id = s.itemFk
|
JOIN item i ON i.id = s.itemFk
|
||||||
JOIN itemShelvingSale iss ON iss.saleFk = s.id
|
JOIN itemShelvingSale iss ON iss.saleFk = s.id
|
||||||
LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
|
LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
|
||||||
LEFT JOIN shelving sh ON sh.code = ish.shelvingFk
|
LEFT JOIN shelving sh ON sh.id = ish.shelvingFk
|
||||||
LEFT JOIN parking p ON p.id = sh.parkingFk
|
LEFT JOIN parking p ON p.id = sh.parkingFk
|
||||||
LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk
|
LEFT JOIN itemColor ic ON ic.itemFk = s.itemFk
|
||||||
LEFT JOIN origin o ON o.id = i.originFk
|
LEFT JOIN origin o ON o.id = i.originFk
|
||||||
WHERE sc.id = ?
|
LEFT JOIN state st ON st.id = sg.stateFk
|
||||||
|
WHERE sc.id = ?
|
||||||
AND sgd.saleGroupFk
|
AND sgd.saleGroupFk
|
||||||
GROUP BY s.id, ish.id, p.code, p2.code`, [id, id], myOptions);
|
GROUP BY s.id, ish.id, p.code, p2.code`, [id, id], myOptions);
|
||||||
if (print)
|
if (print)
|
||||||
|
@ -132,7 +142,7 @@ module.exports = Self => {
|
||||||
$t('The ticket is in preparation', {
|
$t('The ticket is in preparation', {
|
||||||
ticketId: ticketId,
|
ticketId: ticketId,
|
||||||
ticketUrl: `${url}ticket/${ticketId}/summary`,
|
ticketUrl: `${url}ticket/${ticketId}/summary`,
|
||||||
salesDepartmentId: ticket.salesDepartmentFk
|
salesDepartmentId: ticket.departmentFk
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,10 @@ describe('ticket assign()', () => {
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when there is not picking tickets', async() => {
|
it('should throw an error when there are no picking tickets', async() => {
|
||||||
try {
|
try {
|
||||||
await models.Collection.assign(ctx, options);
|
await models.Collection.assign(ctx, options);
|
||||||
|
fail('Expected an error to be thrown, but none was thrown.');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
expect(e.message).toEqual('There are not picking tickets');
|
expect(e.message).toEqual('There are not picking tickets');
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,7 @@ describe('ticket assignCollection()', () => {
|
||||||
args: {}
|
args: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({active: ctx.req});
|
||||||
active: ctx.req
|
|
||||||
});
|
|
||||||
|
|
||||||
options = {transaction: tx};
|
options = {transaction: tx};
|
||||||
tx = await models.Sale.beginTransaction({});
|
tx = await models.Sale.beginTransaction({});
|
||||||
|
@ -25,7 +23,7 @@ describe('ticket assignCollection()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(async() => {
|
afterEach(async() => {
|
||||||
await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when there is not picking tickets', async() => {
|
it('should throw an error when there is not picking tickets', async() => {
|
||||||
|
|
|
@ -38,7 +38,7 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
arg: 'hasFile',
|
arg: 'hasFile',
|
||||||
type: 'Boolean',
|
type: 'Boolean',
|
||||||
description: 'True if has an attached file'
|
description: 'True if has the original in paper'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'hasFileAttached',
|
arg: 'hasFileAttached',
|
||||||
|
|
|
@ -4,21 +4,45 @@ module.exports = Self => {
|
||||||
/**
|
/**
|
||||||
* Returns basic headers
|
* Returns basic headers
|
||||||
*
|
*
|
||||||
* @param {string} cookie - The docuware cookie
|
|
||||||
* @return {object} - The headers
|
* @return {object} - The headers
|
||||||
*/
|
*/
|
||||||
Self.getOptions = async() => {
|
Self.getOptions = async() => {
|
||||||
const docuwareConfig = await Self.app.models.DocuwareConfig.findOne();
|
const docuwareConfig = await Self.app.models.DocuwareConfig.findOne();
|
||||||
|
const now = Date.vnNow();
|
||||||
|
let {url, username, password, token, expired} = docuwareConfig;
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV && (!expired || expired < now + 60)) {
|
||||||
|
const {data: {IdentityServiceUrl}} = await axios.get(`${url}/Home/IdentityServiceInfo`);
|
||||||
|
const {data: {token_endpoint}} = await axios.get(`${IdentityServiceUrl}/.well-known/openid-configuration`);
|
||||||
|
const {data} = await axios.post(token_endpoint, {
|
||||||
|
grant_type: 'password',
|
||||||
|
scope: 'docuware.platform',
|
||||||
|
client_id: 'docuware.platform.net.client',
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
}, {headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
|
}});
|
||||||
|
|
||||||
|
const newToken = data.access_token;
|
||||||
|
token = data.token_type + ' ' + newToken;
|
||||||
|
await docuwareConfig.updateAttributes({
|
||||||
|
token,
|
||||||
|
expired: now + data.expires_in
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Cookie': docuwareConfig.cookie
|
'Authorization': token
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
url: docuwareConfig.url,
|
url,
|
||||||
headers
|
headers
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,87 +2,54 @@ const axios = require('axios');
|
||||||
const models = require('vn-loopback/server/server').models;
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
describe('Docuware core', () => {
|
describe('Docuware core', () => {
|
||||||
beforeAll(() => {
|
const fileCabinetCode = 'deliveryNote';
|
||||||
|
beforeAll(async() => {
|
||||||
process.env.NODE_ENV = 'testing';
|
process.env.NODE_ENV = 'testing';
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
const docuwareInfo = await models.Docuware.findOne({
|
||||||
delete process.env.NODE_ENV;
|
where: {
|
||||||
});
|
code: fileCabinetCode
|
||||||
|
}
|
||||||
describe('getOptions()', () => {
|
|
||||||
it('should return url and headers', async() => {
|
|
||||||
const result = await models.Docuware.getOptions();
|
|
||||||
|
|
||||||
expect(result.url).toBeDefined();
|
|
||||||
expect(result.headers).toBeDefined();
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('getDialog()', () => {
|
spyOn(axios, 'get').and.callFake(url => {
|
||||||
it('should return dialogId', async() => {
|
if (url.includes('IdentityServiceInfo')) return {data: {IdentityServiceUrl: 'IdentityServiceUrl'}};
|
||||||
const dialogs = {
|
if (url.includes('IdentityServiceUrl')) return {data: {token_endpoint: 'token_endpoint'}};
|
||||||
data: {
|
if (url.includes('dialogs')) {
|
||||||
Dialog: [
|
return {
|
||||||
{
|
data: {
|
||||||
DisplayName: 'find',
|
Dialog: [
|
||||||
Id: 'getDialogTest'
|
{
|
||||||
}
|
DisplayName: 'find',
|
||||||
]
|
Id: 'getDialogTest'
|
||||||
}
|
}
|
||||||
};
|
]
|
||||||
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
}
|
||||||
const result = await models.Docuware.getDialog('deliveryNote', 'find', 'randomFileCabinetId');
|
};
|
||||||
|
}
|
||||||
|
|
||||||
expect(result).toEqual('getDialogTest');
|
if (url.includes('FileCabinets')) {
|
||||||
});
|
return {data: {
|
||||||
});
|
|
||||||
|
|
||||||
describe('getFileCabinet()', () => {
|
|
||||||
it('should return fileCabinetId', async() => {
|
|
||||||
const code = 'deliveryNote';
|
|
||||||
const docuwareInfo = await models.Docuware.findOne({
|
|
||||||
where: {
|
|
||||||
code
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const dialogs = {
|
|
||||||
data: {
|
|
||||||
FileCabinet: [
|
FileCabinet: [
|
||||||
{
|
{
|
||||||
Name: docuwareInfo.fileCabinetName,
|
Name: docuwareInfo.fileCabinetName,
|
||||||
Id: 'getFileCabinetTest'
|
Id: 'getFileCabinetTest'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}};
|
||||||
};
|
}
|
||||||
spyOn(axios, 'get').and.returnValue(new Promise(resolve => resolve(dialogs)));
|
|
||||||
const result = await models.Docuware.getFileCabinet(code);
|
|
||||||
|
|
||||||
expect(result).toEqual('getFileCabinetTest');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('get()', () => {
|
|
||||||
it('should return data without parse', async() => {
|
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
|
||||||
const data = {
|
|
||||||
data: {
|
|
||||||
id: 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
|
||||||
const result = await models.Docuware.get('deliveryNote');
|
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return data with parse', async() => {
|
spyOn(axios, 'post').and.callFake(url => {
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
if (url.includes('token_endpoint')) {
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
return {data: {
|
||||||
const data = {
|
access_token: 'access_token',
|
||||||
data: {
|
token_type: 'bearer',
|
||||||
|
expires_in: 10000
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
if (url.includes('DialogExpression')) {
|
||||||
|
return {data: {
|
||||||
Items: [{
|
Items: [{
|
||||||
Fields: [
|
Fields: [
|
||||||
{
|
{
|
||||||
|
@ -103,12 +70,52 @@ describe('Docuware core', () => {
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
delete process.env.NODE_ENV;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getOptions()', () => {
|
||||||
|
it('should return url and headers', async() => {
|
||||||
|
const result = await models.Docuware.getOptions();
|
||||||
|
|
||||||
|
expect(result.url).toBeDefined();
|
||||||
|
expect(result.headers).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Dialog()', () => {
|
||||||
|
it('should return dialogId', async() => {
|
||||||
|
const result = await models.Docuware.getDialog('deliveryNote', 'find', 'randomFileCabinetId');
|
||||||
|
|
||||||
|
expect(result).toEqual('getDialogTest');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getFileCabinet()', () => {
|
||||||
|
it('should return fileCabinetId', async() => {
|
||||||
|
const result = await models.Docuware.getFileCabinet(fileCabinetCode);
|
||||||
|
|
||||||
|
expect(result).toEqual('getFileCabinetTest');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('get()', () => {
|
||||||
|
it('should return data without parse', async() => {
|
||||||
|
const [result] = await models.Docuware.get('deliveryNote');
|
||||||
|
|
||||||
|
expect(result.firstRequiredField).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return data with parse', async() => {
|
||||||
const parse = {
|
const parse = {
|
||||||
'firstRequiredField': 'id',
|
'firstRequiredField': 'id',
|
||||||
'secondRequiredField': 'name',
|
'secondRequiredField': 'name',
|
||||||
};
|
};
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
|
||||||
const [result] = await models.Docuware.get('deliveryNote', null, parse);
|
const [result] = await models.Docuware.get('deliveryNote', null, parse);
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
expect(result.id).toEqual(1);
|
||||||
|
@ -119,17 +126,14 @@ describe('Docuware core', () => {
|
||||||
|
|
||||||
describe('getById()', () => {
|
describe('getById()', () => {
|
||||||
it('should return data', async() => {
|
it('should return data', async() => {
|
||||||
spyOn(models.Docuware, 'getFileCabinet').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
spyOn(models.Docuware, 'get');
|
||||||
spyOn(models.Docuware, 'getDialog').and.returnValue((new Promise(resolve => resolve(Math.random()))));
|
await models.Docuware.getById('deliveryNote', 1);
|
||||||
const data = {
|
|
||||||
data: {
|
|
||||||
id: 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spyOn(axios, 'post').and.returnValue(new Promise(resolve => resolve(data)));
|
|
||||||
const result = await models.Docuware.getById('deliveryNote', 1);
|
|
||||||
|
|
||||||
expect(result.id).toEqual(1);
|
expect(models.Docuware.get).toHaveBeenCalledWith(
|
||||||
|
'deliveryNote',
|
||||||
|
{condition: [Object({DBName: 'N__ALBAR_N', Value: [1]})]},
|
||||||
|
undefined
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -143,7 +143,7 @@ module.exports = Self => {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
'X-File-ModifiedDate': Date.vnNew(),
|
'X-File-ModifiedDate': Date.vnNew(),
|
||||||
'Cookie': docuwareOptions.headers.headers.Cookie,
|
'Authorization': docuwareOptions.headers.headers.Authorization,
|
||||||
...data.getHeaders()
|
...data.getHeaders()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx, userId: ctx.req.accessToken.userId};
|
const options = {transaction: tx, userId: ctx.req.accessToken.userId};
|
||||||
const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileConfig', null, options);
|
const files = await Self.rawSql('SELECT name, checksum, keyValue FROM edi.fileMultiConfig', null, options);
|
||||||
|
|
||||||
const updatableFiles = [];
|
const updatableFiles = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
|
@ -54,7 +54,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const tables = await Self.rawSql(`
|
const tables = await Self.rawSql(`
|
||||||
SELECT fileName, toTable, file
|
SELECT fileName, toTable, file
|
||||||
FROM edi.tableConfig
|
FROM edi.tableMultiConfig
|
||||||
WHERE file IN (?)`, [fileNames], options);
|
WHERE file IN (?)`, [fileNames], options);
|
||||||
|
|
||||||
for (const table of tables) {
|
for (const table of tables) {
|
||||||
|
@ -85,9 +85,9 @@ module.exports = Self => {
|
||||||
for (const file of updatableFiles) {
|
for (const file of updatableFiles) {
|
||||||
console.log(`Updating file ${file.name} checksum...`);
|
console.log(`Updating file ${file.name} checksum...`);
|
||||||
await Self.rawSql(`
|
await Self.rawSql(`
|
||||||
UPDATE edi.fileConfig
|
UPDATE edi.fileMultiConfig
|
||||||
SET checksum = ?
|
SET checksum = ?
|
||||||
WHERE name = ?`,
|
WHERE name = ?`,
|
||||||
[file.checksum, file.name], options);
|
[file.checksum, file.name], options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
await Self.rawSql(sqlTemplate, [filePath], options);
|
await Self.rawSql(sqlTemplate, [filePath], options);
|
||||||
await Self.rawSql(`
|
await Self.rawSql(`
|
||||||
UPDATE edi.tableConfig
|
UPDATE edi.tableMultiConfig
|
||||||
SET updated = ?
|
SET updated = ?
|
||||||
WHERE fileName = ?
|
WHERE fileName = ?
|
||||||
`, [Date.vnNew(), baseName], options);
|
`, [Date.vnNew(), baseName], options);
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
const {models} = require('vn-loopback/server/server');
|
|
||||||
|
|
||||||
describe('machineWorker updateInTime()', () => {
|
|
||||||
const itBoss = 104;
|
|
||||||
const davidCharles = 1106;
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
|
||||||
ctx = {
|
|
||||||
req: {
|
|
||||||
accessToken: {},
|
|
||||||
headers: {origin: 'http://localhost'},
|
|
||||||
__: value => value
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if the plate does not exist', async() => {
|
|
||||||
const tx = await models.MachineWorker.beginTransaction({});
|
|
||||||
const options = {transaction: tx};
|
|
||||||
const plate = 'RE-123';
|
|
||||||
ctx.req.accessToken.userId = 1106;
|
|
||||||
try {
|
|
||||||
await models.MachineWorker.updateInTime(ctx, plate, options);
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
const error = e;
|
|
||||||
|
|
||||||
expect(error.message).toContain('the plate does not exist');
|
|
||||||
await tx.rollback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should grab a machine where is not in use', async() => {
|
|
||||||
const tx = await models.MachineWorker.beginTransaction({});
|
|
||||||
const options = {transaction: tx};
|
|
||||||
const plate = 'RE-003';
|
|
||||||
ctx.req.accessToken.userId = 1107;
|
|
||||||
try {
|
|
||||||
const totalBefore = await models.MachineWorker.find(null, options);
|
|
||||||
await models.MachineWorker.updateInTime(ctx, plate, options);
|
|
||||||
const totalAfter = await models.MachineWorker.find(null, options);
|
|
||||||
|
|
||||||
expect(totalAfter.length).toEqual(totalBefore.length + 1);
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('less than 12h', () => {
|
|
||||||
const plate = 'RE-001';
|
|
||||||
it('should trow an error if it is not himself', async() => {
|
|
||||||
const tx = await models.MachineWorker.beginTransaction({});
|
|
||||||
const options = {transaction: tx};
|
|
||||||
ctx.req.accessToken.userId = davidCharles;
|
|
||||||
|
|
||||||
try {
|
|
||||||
await models.MachineWorker.updateInTime(ctx, plate, options);
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
const error = e;
|
|
||||||
|
|
||||||
expect(error.message).toContain('This machine is already in use');
|
|
||||||
await tx.rollback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw an error if it is himself with a different machine', async() => {
|
|
||||||
const tx = await models.MachineWorker.beginTransaction({});
|
|
||||||
const options = {transaction: tx};
|
|
||||||
ctx.req.accessToken.userId = itBoss;
|
|
||||||
const plate = 'RE-003';
|
|
||||||
try {
|
|
||||||
await models.MachineWorker.updateInTime(ctx, plate, options);
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
const error = e;
|
|
||||||
|
|
||||||
expect(error.message).toEqual('You are already using a machine');
|
|
||||||
await tx.rollback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should set the out time if it is himself', async() => {
|
|
||||||
const tx = await models.MachineWorker.beginTransaction({});
|
|
||||||
const options = {transaction: tx};
|
|
||||||
ctx.req.accessToken.userId = itBoss;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const isNotParked = await models.MachineWorker.findOne({
|
|
||||||
where: {workerFk: itBoss}
|
|
||||||
}, options);
|
|
||||||
await models.MachineWorker.updateInTime(ctx, plate, options);
|
|
||||||
const isParked = await models.MachineWorker.findOne({
|
|
||||||
where: {workerFk: itBoss}
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
expect(isNotParked.outTime).toBeNull();
|
|
||||||
expect(isParked.outTime).toBeDefined();
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('equal or more than 12h', () => {
|
|
||||||
const plate = 'RE-002';
|
|
||||||
it('should set the out time and grab the machine', async() => {
|
|
||||||
const tx = await models.MachineWorker.beginTransaction({});
|
|
||||||
const options = {transaction: tx};
|
|
||||||
ctx.req.accessToken.userId = davidCharles;
|
|
||||||
const filter = {
|
|
||||||
where: {workerFk: davidCharles, machineFk: 2}
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
const isNotParked = await models.MachineWorker.findOne(filter, options);
|
|
||||||
const totalBefore = await models.MachineWorker.find(null, options);
|
|
||||||
await models.MachineWorker.updateInTime(ctx, plate, options);
|
|
||||||
const isParked = await models.MachineWorker.findOne(filter, options);
|
|
||||||
const totalAfter = await models.MachineWorker.find(null, options);
|
|
||||||
|
|
||||||
expect(isNotParked.outTime).toBeNull();
|
|
||||||
expect(isParked.outTime).toBeDefined();
|
|
||||||
expect(totalAfter.length).toEqual(totalBefore.length + 1);
|
|
||||||
await tx.rollback();
|
|
||||||
} catch (e) {
|
|
||||||
await tx.rollback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,77 +0,0 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethodCtx('updateInTime', {
|
|
||||||
description: 'Updates the corresponding registry if the worker has been registered in the last few hours',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [
|
|
||||||
{
|
|
||||||
arg: 'plate',
|
|
||||||
type: 'string',
|
|
||||||
}
|
|
||||||
],
|
|
||||||
http: {
|
|
||||||
path: `/updateInTime`,
|
|
||||||
verb: 'POST'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.updateInTime = async(ctx, plate, options) => {
|
|
||||||
const models = Self.app.models;
|
|
||||||
const userId = ctx.req.accessToken.userId;
|
|
||||||
const $t = ctx.req.__;
|
|
||||||
|
|
||||||
let tx;
|
|
||||||
const myOptions = {};
|
|
||||||
|
|
||||||
if (typeof options == 'object')
|
|
||||||
Object.assign(myOptions, options);
|
|
||||||
|
|
||||||
if (!myOptions.transaction) {
|
|
||||||
tx = await Self.beginTransaction({});
|
|
||||||
myOptions.transaction = tx;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const machine = await models.Machine.findOne({
|
|
||||||
fields: ['id', 'plate'],
|
|
||||||
where: {plate}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
if (!machine)
|
|
||||||
throw new UserError($t('the plate does not exist', {plate}));
|
|
||||||
|
|
||||||
const machineWorker = await Self.findOne({
|
|
||||||
where: {
|
|
||||||
or: [{machineFk: machine.id}, {workerFk: userId}],
|
|
||||||
outTime: null,
|
|
||||||
}
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const {maxHours} = await models.MachineWorkerConfig.findOne({fields: ['maxHours']}, myOptions);
|
|
||||||
const hoursDifference = (Date.vnNow() - machineWorker?.inTime?.getTime() ?? 0) / (60 * 60 * 1000);
|
|
||||||
|
|
||||||
if (machineWorker) {
|
|
||||||
const isHimself = userId == machineWorker.workerFk;
|
|
||||||
const isSameMachine = machine.id == machineWorker.machineFk;
|
|
||||||
|
|
||||||
if (hoursDifference < maxHours && !isHimself)
|
|
||||||
throw new UserError($t('This machine is already in use.'));
|
|
||||||
|
|
||||||
if (hoursDifference < maxHours && isHimself && !isSameMachine)
|
|
||||||
throw new UserError($t('You are already using a machine'));
|
|
||||||
|
|
||||||
await machineWorker.updateAttributes({
|
|
||||||
outTime: Date.vnNew()
|
|
||||||
}, myOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!machineWorker || hoursDifference >= maxHours)
|
|
||||||
await models.MachineWorker.create({machineFk: machine.id, workerFk: userId}, myOptions);
|
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
|
||||||
} catch (e) {
|
|
||||||
if (tx) await tx.rollback();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -2,7 +2,7 @@
|
||||||
<soap:Header>
|
<soap:Header>
|
||||||
<mrw:AuthInfo>
|
<mrw:AuthInfo>
|
||||||
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
||||||
<mrw:CodigoAbonado><%= mrw.subscriberCode %></mrw:CodigoAbonado>
|
<mrw:CodigoAbonado><%= clientType %></mrw:CodigoAbonado>
|
||||||
<mrw:CodigoDepartamento/>
|
<mrw:CodigoDepartamento/>
|
||||||
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
||||||
<mrw:Password><%= mrw.password %></mrw:Password>
|
<mrw:Password><%= mrw.password %></mrw:Password>
|
||||||
|
|
|
@ -13,7 +13,7 @@ module.exports = Self => {
|
||||||
required: true
|
required: true
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['object'],
|
type: 'boolean',
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -24,12 +24,13 @@ module.exports = Self => {
|
||||||
|
|
||||||
Self.cancelShipment = async expeditionFk => {
|
Self.cancelShipment = async expeditionFk => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
|
||||||
const mrw = await models.MrwConfig.findOne();
|
const mrw = await models.MrwConfig.findOne();
|
||||||
const {externalId} = await models.Expedition.findById(expeditionFk);
|
const {externalId} = await models.Expedition.findById(expeditionFk);
|
||||||
|
const clientType = await models.MrwConfig.getClientType(expeditionFk);
|
||||||
const template = fs.readFileSync(__dirname + '/cancelShipment.ejs', 'utf-8');
|
const template = fs.readFileSync(__dirname + '/cancelShipment.ejs', 'utf-8');
|
||||||
const renderedXml = ejs.render(template, {mrw, externalId});
|
const renderedXml = ejs.render(template, {mrw, externalId, clientType});
|
||||||
|
|
||||||
|
await Self.rawSql('CALL util.debugAdd(?,?);', ['cancelShipment', renderedXml]);
|
||||||
const response = await axios.post(mrw.url, renderedXml, {
|
const response = await axios.post(mrw.url, renderedXml, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/soap+xml; charset=utf-8'
|
'Content-Type': 'application/soap+xml; charset=utf-8'
|
||||||
|
@ -37,8 +38,11 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const xmlString = response.data;
|
const xmlString = response.data;
|
||||||
|
await Self.rawSql('CALL util.debugAdd(?,?);', ['cancelShipmentResponse', xmlString]);
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
|
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');
|
||||||
return xmlDoc.getElementsByTagName('Mensaje')[0].textContent;
|
|
||||||
|
const result = xmlDoc.getElementsByTagName('Mensaje')[0].textContent;
|
||||||
|
return ['no se ha encontrado', 'se ha cancelado correctamente'].some(res => result.toLowerCase().includes(res));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<soap:Header>
|
<soap:Header>
|
||||||
<mrw:AuthInfo>
|
<mrw:AuthInfo>
|
||||||
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
||||||
<mrw:CodigoAbonado><%= expeditionData.clientType %></mrw:CodigoAbonado>
|
<mrw:CodigoAbonado><%= clientType %></mrw:CodigoAbonado>
|
||||||
<mrw:CodigoDepartamento/>
|
<mrw:CodigoDepartamento/>
|
||||||
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
||||||
<mrw:Password><%= mrw.password %></mrw:Password>
|
<mrw:Password><%= mrw.password %></mrw:Password>
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
</mrw:Direccion>
|
</mrw:Direccion>
|
||||||
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
|
<mrw:Nif><%= expeditionData.fi %></mrw:Nif>
|
||||||
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
|
<mrw:Nombre><%= expeditionData.clientName %></mrw:Nombre>
|
||||||
<mrw:Telefono><%= expeditionData.phone %></mrw:Telefono>
|
<mrw:Telefono><%= expeditionData.mobile %></mrw:Telefono>
|
||||||
<mrw:Observaciones><%= expeditionData.deliveryObservation %></mrw:Observaciones>
|
<mrw:Observaciones><%= expeditionData.deliveryObservation %></mrw:Observaciones>
|
||||||
</mrw:DatosEntrega>
|
</mrw:DatosEntrega>
|
||||||
<mrw:DatosServicio>
|
<mrw:DatosServicio>
|
||||||
|
|
|
@ -22,6 +22,7 @@ module.exports = Self => {
|
||||||
Self.createShipment = async expeditionFk => {
|
Self.createShipment = async expeditionFk => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const mrw = await Self.getConfig();
|
const mrw = await Self.getConfig();
|
||||||
|
const clientType = await models.MrwConfig.getClientType(expeditionFk);
|
||||||
|
|
||||||
const today = Date.vnNew();
|
const today = Date.vnNew();
|
||||||
const [hours, minutes] = mrw?.expeditionDeadLine ? mrw.expeditionDeadLine.split(':').map(Number) : [0, 0];
|
const [hours, minutes] = mrw?.expeditionDeadLine ? mrw.expeditionDeadLine.split(':').map(Number) : [0, 0];
|
||||||
|
@ -46,14 +47,13 @@ module.exports = Self => {
|
||||||
co.code countryCode,
|
co.code countryCode,
|
||||||
c.fi,
|
c.fi,
|
||||||
c.name clientName,
|
c.name clientName,
|
||||||
c.phone,
|
IFNULL(a.mobile, c.mobile) mobile,
|
||||||
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
|
DATE_FORMAT(t.shipped, '%d/%m/%Y') created,
|
||||||
t.shipped,
|
t.shipped,
|
||||||
CONCAT( e.ticketFk, LPAD(e.counter, mc.counterWidth, '0')) reference,
|
CONCAT( e.ticketFk, LPAD(e.counter, mc.counterWidth, '0')) reference,
|
||||||
LPAD(IF(mw.serviceType IS NULL, ms.serviceType, mw.serviceType), mc.serviceTypeWidth, '0') serviceType,
|
LPAD(IF(mw.serviceType IS NULL, ms.serviceType, mw.serviceType), mc.serviceTypeWidth, '0') serviceType,
|
||||||
IF(mw.weekdays, 'S', 'N') weekDays,
|
IF(mw.weekdays, 'S', 'N') weekDays,
|
||||||
oa.description deliveryObservation,
|
ta.description deliveryObservation
|
||||||
LPAD(ms.clientType, mc.clientTypeWidth, '0') clientType
|
|
||||||
FROM expedition e
|
FROM expedition e
|
||||||
JOIN ticket t ON e.ticketFk = t.id
|
JOIN ticket t ON e.ticketFk = t.id
|
||||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||||
|
@ -62,9 +62,8 @@ module.exports = Self => {
|
||||||
AND mw.weekDays & (1 << WEEKDAY(t.landed))
|
AND mw.weekDays & (1 << WEEKDAY(t.landed))
|
||||||
JOIN client c ON t.clientFk = c.id
|
JOIN client c ON t.clientFk = c.id
|
||||||
JOIN address a ON t.addressFk = a.id
|
JOIN address a ON t.addressFk = a.id
|
||||||
LEFT JOIN addressObservation oa ON oa.addressFk = a.id
|
LEFT JOIN ticketObservation ta ON ta.ticketFk = t.id
|
||||||
LEFT JOIN observationType ot ON ot.id = oa.observationTypeFk
|
AND ta.observationTypeFk IN (SELECT id FROM observationType ot WHERE ot.code = 'agency')
|
||||||
AND ot.code = 'delivery'
|
|
||||||
JOIN province p ON a.provinceFk = p.id
|
JOIN province p ON a.provinceFk = p.id
|
||||||
JOIN country co ON co.id = p.countryFk
|
JOIN country co ON co.id = p.countryFk
|
||||||
JOIN mrwConfig mc
|
JOIN mrwConfig mc
|
||||||
|
@ -73,22 +72,19 @@ module.exports = Self => {
|
||||||
|
|
||||||
const [expeditionData] = await Self.rawSql(query, [expeditionFk]);
|
const [expeditionData] = await Self.rawSql(query, [expeditionFk]);
|
||||||
|
|
||||||
if (!expeditionData)
|
|
||||||
throw new UserError(`This expedition is not a MRW shipment`);
|
|
||||||
|
|
||||||
if (expeditionData?.shipped.setHours(0, 0, 0, 0) < today.setHours(0, 0, 0, 0))
|
if (expeditionData?.shipped.setHours(0, 0, 0, 0) < today.setHours(0, 0, 0, 0))
|
||||||
throw new UserError(`This ticket has a shipped date earlier than today`);
|
throw new UserError(`This ticket has a shipped date earlier than today`);
|
||||||
|
|
||||||
const shipmentResponse = await Self.sendXmlDoc(
|
const shipmentResponse = await Self.sendXmlDoc(
|
||||||
__dirname + `/createShipment.ejs`,
|
__dirname + `/createShipment.ejs`,
|
||||||
{mrw, expeditionData},
|
{mrw, expeditionData, clientType},
|
||||||
'application/soap+xml'
|
'application/soap+xml'
|
||||||
);
|
);
|
||||||
const shipmentId = Self.getTextByTag(shipmentResponse, 'NumeroEnvio');
|
const shipmentId = Self.getTextByTag(shipmentResponse, 'NumeroEnvio');
|
||||||
|
|
||||||
if (!shipmentId) throw new UserError(Self.getTextByTag(shipmentResponse, 'Mensaje'));
|
if (!shipmentId) throw new UserError(Self.getTextByTag(shipmentResponse, 'Mensaje'));
|
||||||
|
|
||||||
const file = await models.MrwConfig.getLabel(shipmentId);
|
const file = await models.MrwConfig.getLabel(shipmentId, clientType);
|
||||||
|
|
||||||
return {shipmentId, file};
|
return {shipmentId, file};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<soapenv:Header>
|
<soapenv:Header>
|
||||||
<mrw:AuthInfo>
|
<mrw:AuthInfo>
|
||||||
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
|
||||||
<mrw:CodigoAbonado><%= mrw.subscriberCode %></mrw:CodigoAbonado>
|
<mrw:CodigoAbonado><%= clientType %></mrw:CodigoAbonado>
|
||||||
<mrw:CodigoDepartamento/>
|
<mrw:CodigoDepartamento/>
|
||||||
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
<mrw:UserName><%= mrw.user %></mrw:UserName>
|
||||||
<mrw:Password><%= mrw.password %></mrw:Password>
|
<mrw:Password><%= mrw.password %></mrw:Password>
|
||||||
|
|
|
@ -6,7 +6,13 @@ module.exports = Self => {
|
||||||
arg: 'shipmentId',
|
arg: 'shipmentId',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true
|
required: true
|
||||||
}],
|
},
|
||||||
|
{
|
||||||
|
arg: 'clientType',
|
||||||
|
type: 'string',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
root: true
|
root: true
|
||||||
|
@ -17,10 +23,14 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getLabel = async shipmentId => {
|
Self.getLabel = async(shipmentId, clientType) => {
|
||||||
const mrw = await Self.getConfig();
|
const mrw = await Self.getConfig();
|
||||||
|
|
||||||
const getLabelResponse = await Self.sendXmlDoc(__dirname + `/getLabel.ejs`, {mrw, shipmentId}, 'text/xml');
|
const getLabelResponse = await Self.sendXmlDoc(
|
||||||
|
__dirname + `/getLabel.ejs`,
|
||||||
|
{mrw, shipmentId, clientType},
|
||||||
|
'text/xml'
|
||||||
|
);
|
||||||
|
|
||||||
return Self.getTextByTag(getLabelResponse, 'EtiquetaFile');
|
return Self.getTextByTag(getLabelResponse, 'EtiquetaFile');
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,9 +12,8 @@ const ticket1 = {
|
||||||
'addressFk': 1,
|
'addressFk': 1,
|
||||||
'agencyModeFk': 999
|
'agencyModeFk': 999
|
||||||
};
|
};
|
||||||
|
let expedition;
|
||||||
const expedition1 = {
|
const expedition1 = {
|
||||||
'id': 17,
|
|
||||||
'agencyModeFk': 999,
|
'agencyModeFk': 999,
|
||||||
'ticketFk': 44,
|
'ticketFk': 44,
|
||||||
'freightItemFk': 71,
|
'freightItemFk': 71,
|
||||||
|
@ -40,17 +39,14 @@ describe('MRWConfig createShipment()', () => {
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await models.MrwService.create(
|
||||||
|
{'agencyModeCodeFk': 'mrw', 'clientType': '000001', 'serviceType': 105, 'kg': 10}
|
||||||
|
);
|
||||||
|
|
||||||
await createMrwConfig();
|
await createMrwConfig();
|
||||||
|
|
||||||
await models.Application.rawSql(
|
|
||||||
`INSERT INTO vn.mrwService
|
|
||||||
SET agencyModeCodeFk = 'mrw',
|
|
||||||
clientType = 1,
|
|
||||||
serviceType = 1,
|
|
||||||
kg = 1`, null
|
|
||||||
);
|
|
||||||
await models.Ticket.create(ticket1);
|
await models.Ticket.create(ticket1);
|
||||||
await models.Expedition.create(expedition1);
|
expedition = await models.Expedition.create(expedition1);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async() => {
|
afterAll(async() => {
|
||||||
|
@ -82,7 +78,8 @@ describe('MRWConfig createShipment()', () => {
|
||||||
'user': 'user',
|
'user': 'user',
|
||||||
'password': 'password',
|
'password': 'password',
|
||||||
'franchiseCode': 'franchiseCode',
|
'franchiseCode': 'franchiseCode',
|
||||||
'subscriberCode': 'subscriberCode'
|
'subscriberCode': 'subscriberCode',
|
||||||
|
'clientTypeWidth': 6
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +92,7 @@ describe('MRWConfig createShipment()', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should create a shipment and return a base64Binary label', async() => {
|
it('should create a shipment and return a base64Binary label', async() => {
|
||||||
const {file} = await models.MrwConfig.createShipment(expedition1.id);
|
const {file} = await models.MrwConfig.createShipment(expedition.id);
|
||||||
|
|
||||||
expect(file).toEqual(mockBase64Binary);
|
expect(file).toEqual(mockBase64Binary);
|
||||||
});
|
});
|
||||||
|
@ -103,7 +100,7 @@ describe('MRWConfig createShipment()', () => {
|
||||||
it('should fail if mrwConfig has no data', async() => {
|
it('should fail if mrwConfig has no data', async() => {
|
||||||
let error;
|
let error;
|
||||||
await models.MrwConfig.destroyAll();
|
await models.MrwConfig.destroyAll();
|
||||||
await models.MrwConfig.createShipment(expedition1.id).catch(e => {
|
await models.MrwConfig.createShipment(expedition.id).catch(e => {
|
||||||
error = e;
|
error = e;
|
||||||
}).finally(async() => {
|
}).finally(async() => {
|
||||||
expect(error.message).toEqual(`MRW service is not configured`);
|
expect(error.message).toEqual(`MRW service is not configured`);
|
||||||
|
@ -115,10 +112,10 @@ describe('MRWConfig createShipment()', () => {
|
||||||
|
|
||||||
it('should fail if expeditionFk is not a MrwExpedition', async() => {
|
it('should fail if expeditionFk is not a MrwExpedition', async() => {
|
||||||
let error;
|
let error;
|
||||||
await models.MrwConfig.createShipment(undefined).catch(e => {
|
await models.MrwConfig.createShipment(15).catch(e => {
|
||||||
error = e;
|
error = e;
|
||||||
}).finally(async() => {
|
}).finally(async() => {
|
||||||
expect(error.message).toEqual(`This expedition is not a MRW shipment`);
|
expect(error.message).toEqual(`ClientType not available`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -128,7 +125,7 @@ describe('MRWConfig createShipment()', () => {
|
||||||
yesterday.setDate(yesterday.getDate() - 1);
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
|
||||||
await models.Ticket.updateAll({id: ticket1.id}, {shipped: yesterday});
|
await models.Ticket.updateAll({id: ticket1.id}, {shipped: yesterday});
|
||||||
await models.MrwConfig.createShipment(expedition1.id).catch(e => {
|
await models.MrwConfig.createShipment(expedition.id).catch(e => {
|
||||||
error = e;
|
error = e;
|
||||||
}).finally(async() => {
|
}).finally(async() => {
|
||||||
expect(error.message).toEqual(`This ticket has a shipped date earlier than today`);
|
expect(error.message).toEqual(`This ticket has a shipped date earlier than today`);
|
||||||
|
@ -138,7 +135,7 @@ describe('MRWConfig createShipment()', () => {
|
||||||
|
|
||||||
it('should send mail if you are past the dead line and is not notified today', async() => {
|
it('should send mail if you are past the dead line and is not notified today', async() => {
|
||||||
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: null});
|
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: null});
|
||||||
await models.MrwConfig.createShipment(expedition1.id);
|
await models.MrwConfig.createShipment(expedition.id);
|
||||||
const notification = await getLastNotification();
|
const notification = await getLastNotification();
|
||||||
|
|
||||||
expect(notification.notificationFk).toEqual(filter.notificationFk);
|
expect(notification.notificationFk).toEqual(filter.notificationFk);
|
||||||
|
@ -146,7 +143,7 @@ describe('MRWConfig createShipment()', () => {
|
||||||
|
|
||||||
it('should send mail if you are past the dead line and it is notified from another day', async() => {
|
it('should send mail if you are past the dead line and it is notified from another day', async() => {
|
||||||
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: new Date()});
|
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: new Date()});
|
||||||
await models.MrwConfig.createShipment(expedition1.id);
|
await models.MrwConfig.createShipment(expedition.id);
|
||||||
const notification = await getLastNotification();
|
const notification = await getLastNotification();
|
||||||
|
|
||||||
expect(notification.notificationFk).toEqual(filter.notificationFk);
|
expect(notification.notificationFk).toEqual(filter.notificationFk);
|
||||||
|
@ -154,7 +151,7 @@ describe('MRWConfig createShipment()', () => {
|
||||||
|
|
||||||
it('should not send mail if you are past the dead line and it is notified', async() => {
|
it('should not send mail if you are past the dead line and it is notified', async() => {
|
||||||
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: Date.vnNew()});
|
await models.MrwConfig.updateAll({id: 1}, {expeditionDeadLine: '10:00:00', notified: Date.vnNew()});
|
||||||
await models.MrwConfig.createShipment(expedition1.id);
|
await models.MrwConfig.createShipment(expedition.id);
|
||||||
const notification = await getLastNotification();
|
const notification = await getLastNotification();
|
||||||
|
|
||||||
expect(notification).toEqual(null);
|
expect(notification).toEqual(null);
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
const axios = require('axios');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('optimize', {
|
||||||
|
description: 'Return optimized coords',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'addressIds',
|
||||||
|
type: 'array',
|
||||||
|
required: true
|
||||||
|
}, {
|
||||||
|
arg: 'firstAddressId',
|
||||||
|
type: 'number',
|
||||||
|
required: false
|
||||||
|
}, {
|
||||||
|
arg: 'lastAddressId',
|
||||||
|
type: 'number',
|
||||||
|
required: false
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/optimize`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.optimize = async(addressIds, firstAddressId, lastAddressId) => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
try {
|
||||||
|
const osrmConfig = await models.OsrmConfig.findOne();
|
||||||
|
if (!osrmConfig) throw new UserError(`OSRM service is not configured`);
|
||||||
|
|
||||||
|
let coords = [];
|
||||||
|
if (firstAddressId) {
|
||||||
|
const address = await models.Address.findById(firstAddressId);
|
||||||
|
if (address.latitude && address.longitude) {
|
||||||
|
coords.push({
|
||||||
|
addressId: address.id,
|
||||||
|
latitude: address.latitude.toFixed(6),
|
||||||
|
longitude: address.longitude.toFixed(6)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const addressId of addressIds) {
|
||||||
|
const address = await models.Address.findById(addressId);
|
||||||
|
if (address.latitude && address.longitude) {
|
||||||
|
coords.push({
|
||||||
|
addressId,
|
||||||
|
latitude: address.latitude.toFixed(6),
|
||||||
|
longitude: address.longitude.toFixed(6)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastAddressId) {
|
||||||
|
const firstAddress = await models.Address.findById(lastAddressId);
|
||||||
|
if (firstAddress.latitude && firstAddress.longitude) {
|
||||||
|
coords.push({
|
||||||
|
addressId: firstAddress.id,
|
||||||
|
latitude: firstAddress.latitude.toFixed(6),
|
||||||
|
longitude: firstAddress.longitude.toFixed(6)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!coords.length) throw new UserError('No address has coordinates');
|
||||||
|
|
||||||
|
const concatCoords = coords
|
||||||
|
.map(coord => `${coord.longitude},${coord.latitude}`)
|
||||||
|
.join(';');
|
||||||
|
const response = await axios.post(`
|
||||||
|
${osrmConfig.url}/trip/v1/driving/${concatCoords}?source=first&destination=last&roundtrip=true
|
||||||
|
`);
|
||||||
|
const tolerance = osrmConfig.tolerance;
|
||||||
|
for (const waypoint of response.data.waypoints) {
|
||||||
|
const longitude = waypoint.location[0];
|
||||||
|
const latitude = waypoint.location[1];
|
||||||
|
|
||||||
|
const matchedAddress = coords.find(coord =>
|
||||||
|
coord.position === undefined &&
|
||||||
|
Math.abs(coord.latitude - latitude) <= tolerance &&
|
||||||
|
Math.abs(coord.longitude - longitude) <= tolerance
|
||||||
|
);
|
||||||
|
if (matchedAddress)
|
||||||
|
matchedAddress.position = waypoint.waypoint_index;
|
||||||
|
}
|
||||||
|
coords.sort((a, b) => {
|
||||||
|
const posA = a.position !== undefined ? a.position : Infinity;
|
||||||
|
const posB = b.position !== undefined ? b.position : Infinity;
|
||||||
|
return posA - posB;
|
||||||
|
});
|
||||||
|
|
||||||
|
return coords;
|
||||||
|
} catch (err) {
|
||||||
|
switch (err.response?.data?.code) {
|
||||||
|
case 'NoTrips':
|
||||||
|
throw new UserError('No trips found because input coordinates are not connected');
|
||||||
|
case 'NotImplemented':
|
||||||
|
throw new UserError('This request is not supported');
|
||||||
|
case 'InvalidOptions':
|
||||||
|
throw new UserError('Invalid options or too many coordinates');
|
||||||
|
default:
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,33 @@
|
||||||
|
const models = require('vn-loopback/server/server').models;
|
||||||
|
|
||||||
|
describe('osrmConfig optimize()', function() {
|
||||||
|
it('should send coords, receive OSRM response, and return a correctly ordered result', async function() {
|
||||||
|
const result = await models.OsrmConfig.optimize([4, 3], 1, 2);
|
||||||
|
|
||||||
|
// Verifications
|
||||||
|
expect(Array.isArray(result)).toBe(true);
|
||||||
|
expect(result.length).toBe(4);
|
||||||
|
|
||||||
|
// Check the order
|
||||||
|
expect(result[0].addressId).toBe(1);
|
||||||
|
expect(result[1].addressId).toBe(4);
|
||||||
|
expect(result[2].addressId).toBe(3);
|
||||||
|
expect(result[3].addressId).toBe(2);
|
||||||
|
|
||||||
|
// Check the coordinates format
|
||||||
|
expect(result[0].latitude).toBe('10.111111');
|
||||||
|
expect(result[0].longitude).toBe('-74.111111');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if no addresses are provided', async function() {
|
||||||
|
let error;
|
||||||
|
try {
|
||||||
|
await models.OsrmConfig.optimize([], null);
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(error).toBeDefined();
|
||||||
|
expect(error.message).toBe('No address has coordinates');
|
||||||
|
});
|
||||||
|
});
|
|
@ -29,35 +29,34 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.sendToSupport = async(ctx, reason, additionalData) => {
|
Self.sendToSupport = async(ctx, reason, additionalData) => {
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
const emailUser =
|
const emailUser =
|
||||||
await Self.app.models.EmailUser.findById(ctx.req.accessToken.userId, {fields: ['email']});
|
await Self.app.models.EmailUser.findById(userId, {fields: ['email']});
|
||||||
|
|
||||||
let html = `<strong>Motivo</strong>:<br/>${reason}<br/>`;
|
let html = `<h2>Motivo: ${reason}</h2>`;
|
||||||
html += `<strong>Usuario</strong>:<br/>${ctx.req.accessToken.userId} ${emailUser.email}<br/>`;
|
html += `<h3>Usuario: ${userId} ${emailUser.email}</h3>`;
|
||||||
|
html += `<h3>Additional Data:</h3>`;
|
||||||
|
html += '<ul>';
|
||||||
|
for (const [key, val] of Object.entries(additionalData)) {
|
||||||
|
if (key !== 'config') html += `<li>${key}: ${parse(val)}</li>`;
|
||||||
|
else {
|
||||||
|
html += `<li>${key}:</li><ul style="list-style-type: square;">`;
|
||||||
|
for (const [confKey, confVal] of Object.entries(val))
|
||||||
|
html += `<li>${confKey}: ${parse(confVal)}</li>`;
|
||||||
|
html += '</ul>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html += '</ul>';
|
||||||
|
|
||||||
delete additionalData.backError.config.headers.Authorization;
|
const {message, path, name} = additionalData;
|
||||||
const httpRequest = JSON.parse(additionalData?.httpRequest);
|
|
||||||
|
|
||||||
if (httpRequest)
|
|
||||||
delete httpRequest.config.headers.Authorization;
|
|
||||||
additionalData.httpRequest = httpRequest;
|
|
||||||
|
|
||||||
for (const data in additionalData)
|
|
||||||
html += `<strong>${data}</strong>:<br/>${tryParse(additionalData[data])}<br/>`;
|
|
||||||
|
|
||||||
const subjectReason = httpRequest?.data?.error;
|
|
||||||
await smtp.send({
|
await smtp.send({
|
||||||
to: `${config.app.reportEmail}, ${emailUser.email}`,
|
to: `${config.app.reportEmail}, ${emailUser.email}`,
|
||||||
subject:
|
subject: `[Support-Salix] ${path} ${name}: ${message}`,
|
||||||
'[Support-Salix] ' +
|
|
||||||
additionalData?.frontPath + ' ' +
|
|
||||||
subjectReason?.name + ':' +
|
|
||||||
subjectReason?.message,
|
|
||||||
html
|
html
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function tryParse(value) {
|
function parse(value) {
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
value = JSON.parse(value);
|
value = JSON.parse(value);
|
||||||
|
|
|
@ -11,13 +11,6 @@ module.exports = Self => {
|
||||||
arg: 'filter',
|
arg: 'filter',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||||
http: {source: 'query'}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
arg: 'search',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Value to filter',
|
|
||||||
http: {source: 'query'}
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -29,13 +22,11 @@ module.exports = Self => {
|
||||||
verb: 'GET',
|
verb: 'GET',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Self.filter = async(ctx, filter, options) => {
|
Self.filter = async(filter = {}, options) => {
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
filter = ctx?.filter ?? {};
|
|
||||||
|
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
const where = buildFilter(filter?.where, (param, value) => {
|
const where = buildFilter(filter?.where, (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
|
@ -50,31 +41,33 @@ module.exports = Self => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}) ?? {};
|
}) ?? {};
|
||||||
delete ctx.filter.where;
|
delete filter.where;
|
||||||
|
|
||||||
const stmts = [];
|
const stmts = [];
|
||||||
let stmt;
|
let stmt;
|
||||||
stmt = new ParameterizedSQL(`
|
stmt = new ParameterizedSQL(`
|
||||||
SELECT
|
SELECT
|
||||||
pc.townFk,
|
pc.townFk,
|
||||||
t.provinceFk,
|
t.provinceFk,
|
||||||
p.countryFk,
|
p.countryFk,
|
||||||
pc.code,
|
pc.code,
|
||||||
t.name as town,
|
t.name as town,
|
||||||
p.name as province,
|
p.name as province,
|
||||||
c.name country
|
c.name country
|
||||||
FROM
|
FROM
|
||||||
postCode pc
|
postCode pc
|
||||||
JOIN town t on t.id = pc.townFk
|
JOIN town t on t.id = pc.townFk
|
||||||
JOIN province p on p.id = t.provinceFk
|
JOIN province p on p.id = t.provinceFk
|
||||||
JOIN country c on c.id = p.countryFk
|
JOIN country c on c.id = p.countryFk
|
||||||
`);
|
`);
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix({where, ...ctx}));
|
stmt.merge(conn.makeSuffix({where}));
|
||||||
|
stmt.merge(conn.makeLimit(filter));
|
||||||
const itemsIndex = stmts.push(stmt) - 1;
|
const itemsIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
const sql = ParameterizedSQL.join(stmts, ';');
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
const result = await conn.executeStmt(sql, myOptions);
|
const result = await conn.executeStmt(sql, myOptions);
|
||||||
|
|
||||||
return itemsIndex === 0 ? result : result[itemsIndex];
|
return itemsIndex === 0 ? result : result[itemsIndex];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,12 +6,9 @@ describe('Postcode filter()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ctx = {
|
const results = await models.Postcode.filter({
|
||||||
filter: {
|
|
||||||
},
|
|
||||||
limit: 1
|
limit: 1
|
||||||
};
|
}, options);
|
||||||
const results = await models.Postcode.filter(ctx, options);
|
|
||||||
|
|
||||||
expect(results.length).toEqual(1);
|
expect(results.length).toEqual(1);
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
@ -26,16 +23,13 @@ describe('Postcode filter()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ctx = {
|
const results = await models.Postcode.filter({
|
||||||
filter: {
|
where: {
|
||||||
where: {
|
search: 46,
|
||||||
search: 46,
|
}
|
||||||
}
|
}, options);
|
||||||
},
|
|
||||||
};
|
|
||||||
const results = await models.Postcode.filter(ctx, options);
|
|
||||||
|
|
||||||
expect(results.length).toEqual(4);
|
expect(results.length).toEqual(5);
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
@ -48,14 +42,9 @@ describe('Postcode filter()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ctx = {
|
const results = await models.Postcode.filter({where: {
|
||||||
filter: {
|
search: 'Alz',
|
||||||
where: {
|
}}, options);
|
||||||
search: 'Alz',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const results = await models.Postcode.filter(ctx, options);
|
|
||||||
|
|
||||||
expect(results.length).toEqual(1);
|
expect(results.length).toEqual(1);
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
@ -70,16 +59,11 @@ describe('Postcode filter()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ctx = {
|
const results = await models.Postcode.filter({where: {
|
||||||
filter: {
|
search: 'one',
|
||||||
where: {
|
}}, options);
|
||||||
search: 'one',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const results = await models.Postcode.filter(ctx, options);
|
|
||||||
|
|
||||||
expect(results.length).toEqual(4);
|
expect(results.length).toEqual(5);
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
@ -92,14 +76,11 @@ describe('Postcode filter()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ctx = {
|
const results = await models.Postcode.filter({
|
||||||
filter: {
|
where: {
|
||||||
where: {
|
search: 'Ec',
|
||||||
search: 'Ec',
|
}
|
||||||
}
|
}, options);
|
||||||
},
|
|
||||||
};
|
|
||||||
const results = await models.Postcode.filter(ctx, options);
|
|
||||||
|
|
||||||
expect(results.length).toEqual(1);
|
expect(results.length).toEqual(1);
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
|
|
|
@ -22,7 +22,7 @@ module.exports = Self => {
|
||||||
const url = await Self.app.models.Url.findOne({
|
const url = await Self.app.models.Url.findOne({
|
||||||
where: {
|
where: {
|
||||||
appName,
|
appName,
|
||||||
environment: process.env.NODE_ENV || 'dev'
|
environment: process.env.NODE_ENV || 'development'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return url?.url;
|
return url?.url;
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.renderer = async (expeditionFk) => {
|
Self.renderer = async expeditionFk => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
|
||||||
const viaexpressConfig = await models.ViaexpressConfig.findOne({
|
const viaexpressConfig = await models.ViaexpressConfig.findOne({
|
||||||
|
@ -109,7 +109,7 @@ module.exports = Self => {
|
||||||
const ticket = expedition.ticket();
|
const ticket = expedition.ticket();
|
||||||
const sender = ticket.company().client();
|
const sender = ticket.company().client();
|
||||||
const shipped = ticket.shipped.toISOString();
|
const shipped = ticket.shipped.toISOString();
|
||||||
const isInterdia = (ticket.agencyModeFk === viaexpressConfig.agencyModeFk)
|
const isInterdia = (ticket.agencyModeFk === viaexpressConfig.agencyModeFk);
|
||||||
const data = {
|
const data = {
|
||||||
viaexpressConfig,
|
viaexpressConfig,
|
||||||
sender,
|
sender,
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('killSession', {
|
||||||
|
description: 'Kill session',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'userId',
|
||||||
|
type: 'integer',
|
||||||
|
description: 'The user id',
|
||||||
|
required: true,
|
||||||
|
}, {
|
||||||
|
arg: 'created',
|
||||||
|
type: 'date',
|
||||||
|
description: 'The created time',
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
accessType: 'WRITE',
|
||||||
|
http: {
|
||||||
|
path: `/killSession`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.killSession = async function(ctx, userId, created) {
|
||||||
|
await Self.app.models.VnUser.userSecurity(ctx, ctx.req.accessToken.userId);
|
||||||
|
const tokens = await Self.app.models.AccessToken.find({where: {userId, created}});
|
||||||
|
if (!tokens?.length) return;
|
||||||
|
for (const token of tokens)
|
||||||
|
await Self.app.models.AccessToken.deleteById(token.id);
|
||||||
|
};
|
||||||
|
};
|
|
@ -19,7 +19,7 @@ module.exports = Self => {
|
||||||
if (acl.principalType == 'ROLE' && acl.permission == 'ALLOW') {
|
if (acl.principalType == 'ROLE' && acl.permission == 'ALLOW') {
|
||||||
const staticAcl = {
|
const staticAcl = {
|
||||||
model: model.name,
|
model: model.name,
|
||||||
property: '*',
|
property: acl.property,
|
||||||
accessType: acl.accessType,
|
accessType: acl.accessType,
|
||||||
permission: acl.permission,
|
permission: acl.permission,
|
||||||
principalType: acl.principalType,
|
principalType: acl.principalType,
|
||||||
|
|
|
@ -30,16 +30,10 @@ module.exports = Self => {
|
||||||
|
|
||||||
// Schedule to remove current token
|
// Schedule to remove current token
|
||||||
setTimeout(async() => {
|
setTimeout(async() => {
|
||||||
let exists;
|
|
||||||
try {
|
try {
|
||||||
exists = await models.AccessToken.findById(token.id);
|
await Self.logout(token.id);
|
||||||
exists && await Self.logout(token.id);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// FIXME: Crash if do throw new Error(error)
|
||||||
console.error(error);
|
|
||||||
const body = {error: error.message, now: Date.now(), userId: token?.userId ?? null, exists};
|
|
||||||
await handleError(body);
|
|
||||||
throw new Error(error);
|
|
||||||
}
|
}
|
||||||
}, courtesyTime * 1000);
|
}, courtesyTime * 1000);
|
||||||
|
|
||||||
|
@ -53,14 +47,20 @@ module.exports = Self => {
|
||||||
|
|
||||||
return {id: accessToken.id, ttl: accessToken.ttl};
|
return {id: accessToken.id, ttl: accessToken.ttl};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const body = {error: error.message, now: Date.now(), userId: token?.userId ?? null, createTokenOptions, isNotExceeded};
|
const body = {
|
||||||
await handleError(body);
|
error: error.message,
|
||||||
|
userId: token?.userId ?? null,
|
||||||
|
token: token?.id,
|
||||||
|
scopes: token?.scopes,
|
||||||
|
createTokenOptions,
|
||||||
|
isNotExceeded
|
||||||
|
};
|
||||||
|
await handleError(JSON.stringify(body));
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
async function handleError(body, tag = 'renewToken') {
|
async function handleError(body) {
|
||||||
body = JSON.stringify(body);
|
await models.Application.rawSql('CALL util.debugAdd(?,?);', ['renewToken', body]);
|
||||||
await models.Application.rawSql('CALL util.debugAdd(?,?);', [tag, body]);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,9 @@ module.exports = Self => {
|
||||||
if (vnUser.twoFactor === 'email') {
|
if (vnUser.twoFactor === 'email') {
|
||||||
const $ = Self.app.models;
|
const $ = Self.app.models;
|
||||||
|
|
||||||
const code = String(Math.floor(Math.random() * 999999));
|
const min = 100000;
|
||||||
|
const max = 999999;
|
||||||
|
const code = String(Math.floor(Math.random() * (max - min + 1)) + min);
|
||||||
const maxTTL = ((60 * 1000) * 5); // 5 min
|
const maxTTL = ((60 * 1000) * 5); // 5 min
|
||||||
await $.AuthCode.upsertWithWhere({userFk: vnUser.id}, {
|
await $.AuthCode.upsertWithWhere({userFk: vnUser.id}, {
|
||||||
userFk: vnUser.id,
|
userFk: vnUser.id,
|
||||||
|
|
|
@ -72,9 +72,9 @@ describe('Renew Token', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(error).toBeDefined();
|
expect(error).toBeDefined();
|
||||||
const query = 'SELECT * FROM util.debug';
|
|
||||||
|
|
||||||
const debugLog = await models.Application.rawSql(query, null);
|
const query = 'SELECT * FROM util.debug WHERE variable = "renewToken"';
|
||||||
|
const debugLog = await models.Application.rawSql(query);
|
||||||
|
|
||||||
expect(debugLog.length).toEqual(1);
|
expect(debugLog.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,8 +22,12 @@ module.exports = Self => {
|
||||||
description: 'The user email'
|
description: 'The user email'
|
||||||
}, {
|
}, {
|
||||||
arg: 'lang',
|
arg: 'lang',
|
||||||
type: 'string',
|
type: 'any',
|
||||||
description: 'The user lang'
|
description: 'The user lang'
|
||||||
|
}, {
|
||||||
|
arg: 'twoFactor',
|
||||||
|
type: 'any',
|
||||||
|
description: 'The user twoFactor'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
http: {
|
http: {
|
||||||
|
@ -32,8 +36,8 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.updateUser = async(ctx, id, name, nickname, email, lang) => {
|
Self.updateUser = async(ctx, id, name, nickname, email, lang, twoFactor) => {
|
||||||
await Self.userSecurity(ctx, id);
|
await Self.userSecurity(ctx, id);
|
||||||
await Self.upsertWithWhere({id}, {name, nickname, email, lang});
|
await Self.upsertWithWhere({id}, {name, nickname, email, lang, twoFactor});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,7 @@ module.exports = Self => {
|
||||||
fields: ['name', 'twoFactor']
|
fields: ['name', 'twoFactor']
|
||||||
}, myOptions);
|
}, myOptions);
|
||||||
|
|
||||||
if (user.name !== username)
|
if (user.name.toLowerCase() !== username.toLowerCase())
|
||||||
throw new UserError('Authentication failed');
|
throw new UserError('Authentication failed');
|
||||||
|
|
||||||
await authCode.destroy(myOptions);
|
await authCode.destroy(myOptions);
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('add', {
|
||||||
|
description: 'Add activity if the activity is different or is the same but have exceed time for break',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'code',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Code for activity'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'model',
|
||||||
|
type: 'string',
|
||||||
|
description: 'Origin model from insert'
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
http: {
|
||||||
|
path: `/add`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.add = async(ctx, code, model, options) => {
|
||||||
|
const userId = ctx.req.accessToken.userId;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
return await Self.rawSql(`
|
||||||
|
INSERT INTO workerActivity (workerFk, workerActivityTypeFk, model)
|
||||||
|
SELECT ?, ?, ?
|
||||||
|
FROM workerTimeControlConfig wtcc
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT wa.workerFk,
|
||||||
|
wa.created,
|
||||||
|
wat.code
|
||||||
|
FROM workerActivity wa
|
||||||
|
LEFT JOIN workerActivityType wat ON wat.code = wa.workerActivityTypeFk
|
||||||
|
WHERE wa.workerFk = ?
|
||||||
|
ORDER BY wa.created DESC
|
||||||
|
LIMIT 1
|
||||||
|
) sub ON TRUE
|
||||||
|
WHERE sub.workerFk IS NULL
|
||||||
|
OR sub.code <> ?
|
||||||
|
OR TIMESTAMPDIFF(SECOND, sub.created, util.VN_NOW()) > wtcc.dayBreak;`
|
||||||
|
, [userId, code, model, userId, code], myOptions);
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
const {models} = require('vn-loopback');
|
||||||
|
|
||||||
|
describe('workerActivity insert()', () => {
|
||||||
|
const ctx = beforeAll.getCtx(1106);
|
||||||
|
|
||||||
|
it('should insert in workerActivity', async() => {
|
||||||
|
const tx = await models.WorkerActivity.beginTransaction({});
|
||||||
|
let count = 0;
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await models.WorkerActivityType.create(
|
||||||
|
{'code': 'TEST', 'description': 'TEST'}, options
|
||||||
|
);
|
||||||
|
|
||||||
|
await models.WorkerActivity.add(ctx, 'TEST', 'APP', options);
|
||||||
|
|
||||||
|
count = await models.WorkerActivity.count(
|
||||||
|
{'workerFK': 1106}, options
|
||||||
|
);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(count).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
|
@ -28,6 +28,9 @@
|
||||||
"Company": {
|
"Company": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"Config": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Continent": {
|
"Continent": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
@ -76,21 +79,21 @@
|
||||||
"ImageCollectionSize": {
|
"ImageCollectionSize": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"ImageConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"ImageContainer": {
|
"ImageContainer": {
|
||||||
"dataSource": "imageStorage"
|
"dataSource": "imageStorage"
|
||||||
},
|
},
|
||||||
"Language": {
|
"Language": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"OsrmConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Machine": {
|
"Machine": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"MachineWorker": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"MachineWorkerConfig": {
|
|
||||||
"dataSource": "vn"
|
|
||||||
},
|
|
||||||
"MobileAppVersionControl": {
|
"MobileAppVersionControl": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
@ -115,6 +118,9 @@
|
||||||
"NotificationSubscription": {
|
"NotificationSubscription": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"OrmConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Province": {
|
"Province": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
@ -124,9 +130,15 @@
|
||||||
"Payment": {
|
"Payment": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"PbxConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Postcode": {
|
"Postcode": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"Prefix": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"ReferenceRate": {
|
"ReferenceRate": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
@ -136,6 +148,12 @@
|
||||||
"StarredModule": {
|
"StarredModule": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"SaySimpleCountry": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"SaySimpleConfig": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"TempContainer": {
|
"TempContainer": {
|
||||||
"dataSource": "tempStorage"
|
"dataSource": "tempStorage"
|
||||||
},
|
},
|
||||||
|
@ -166,9 +184,15 @@
|
||||||
"PrintConfig": {
|
"PrintConfig": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"QueueMember": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"ViaexpressConfig": {
|
"ViaexpressConfig": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"VnToken": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"VnUser": {
|
"VnUser": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
@ -192,5 +216,8 @@
|
||||||
},
|
},
|
||||||
"RouteConfig": {
|
"RouteConfig": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"MrwService": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,6 +16,10 @@
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
"hasDailyInvoice": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Indicates if the autonomy has daily invoice enabled"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
@ -40,4 +44,4 @@
|
||||||
"permission": "ALLOW"
|
"permission": "ALLOW"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "Config",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "config"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"inventoried": {
|
||||||
|
"type": "date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$authenticated",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -28,6 +28,10 @@
|
||||||
},
|
},
|
||||||
"continentFk": {
|
"continentFk": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
|
},
|
||||||
|
"hasDailyInvoice": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Indicates if the autonomy has daily invoice enabled"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
@ -40,6 +44,11 @@
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Continent",
|
"model": "Continent",
|
||||||
"foreignKey": "continentFk"
|
"foreignKey": "continentFk"
|
||||||
|
},
|
||||||
|
"saySimpleCountry": {
|
||||||
|
"type": "hasOne",
|
||||||
|
"model": "SaySimpleCountry",
|
||||||
|
"foreignKey": "countryFk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"acls": [
|
"acls": [
|
||||||
|
@ -50,4 +59,4 @@
|
||||||
"permission": "ALLOW"
|
"permission": "ALLOW"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "salix.defaultViewConfig"
|
"table": "salix.defaultViewMultiConfig"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -16,17 +16,17 @@
|
||||||
"url": {
|
"url": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"cookie": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"expired":{
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"acls": [
|
|
||||||
{
|
|
||||||
"property": "*",
|
|
||||||
"accessType": "*",
|
|
||||||
"principalType": "ROLE",
|
|
||||||
"principalId": "$everyone",
|
|
||||||
"permission": "ALLOW"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "ImageConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "hedera.imageConfig"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$authenticated",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
"name": "MachineWorkerConfig",
|
|
||||||
"base": "VnModel",
|
|
||||||
"options": {
|
|
||||||
"mysql": {
|
|
||||||
"table": "vn.machineWorkerConfig"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "number",
|
|
||||||
"id": true
|
|
||||||
},
|
|
||||||
"maxHours": {
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
module.exports = Self => {
|
|
||||||
require('../methods/machine-worker/updateInTime')(Self);
|
|
||||||
};
|
|
|
@ -1,33 +0,0 @@
|
||||||
{
|
|
||||||
"name": "MachineWorker",
|
|
||||||
"base": "VnModel",
|
|
||||||
"options": {
|
|
||||||
"mysql": {
|
|
||||||
"table": "vn.machineWorker"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "number",
|
|
||||||
"id": true
|
|
||||||
},
|
|
||||||
"workerFk": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"machineFk": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"inTime": {
|
|
||||||
"type": "date",
|
|
||||||
"mysql": {
|
|
||||||
"columnName": "inTimed"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"outTime": {
|
|
||||||
"type": "date",
|
|
||||||
"mysql": {
|
|
||||||
"columnName": "outTimed"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -31,5 +31,30 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
return parser.parseFromString(data.data, 'text/xml');
|
return parser.parseFromString(data.data, 'text/xml');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Self.getClientType = async function(expeditionFk) {
|
||||||
|
if (!expeditionFk) throw new UserError(`No expeditionFk defined`);
|
||||||
|
|
||||||
|
const {clientTypeWidth} = await Self.getConfig();
|
||||||
|
const result = await Self.app.models.Expedition.findById(expeditionFk,
|
||||||
|
{include: [{
|
||||||
|
relation: 'ticket',
|
||||||
|
scope: {
|
||||||
|
include: {
|
||||||
|
relation: 'agencyMode',
|
||||||
|
scope: {
|
||||||
|
include: {
|
||||||
|
relation: 'mrwService',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]}
|
||||||
|
);
|
||||||
|
const clientType = result?.ticket()?.agencyMode()?.mrwService()?.clientType;
|
||||||
|
if (!clientType || !clientTypeWidth) throw new UserError(`ClientType not available`);
|
||||||
|
|
||||||
|
return clientType.toString().padStart(clientTypeWidth, '0');
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,9 @@
|
||||||
},
|
},
|
||||||
"notified":{
|
"notified":{
|
||||||
"type": "date"
|
"type": "date"
|
||||||
|
},
|
||||||
|
"clientTypeWidth": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "MrwService",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "mrwService"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"agencyModeCodeFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"clientType": {
|
||||||
|
"type": "number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"serviceType": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"kg": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"agency": {
|
||||||
|
"type": "hasOne",
|
||||||
|
"model": "AgencyMode",
|
||||||
|
"foreignKey": "code"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "OrmConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "ormConfig"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"selectLimit": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"accessType": "*",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$authenticated",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/osrm-config/optimize')(Self);
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"name": "OsrmConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "osrmConfig"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true,
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"tolerance": {
|
||||||
|
"type": "number",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"name": "PbxConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "pbx.config"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"defaultPrefix": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"property": "*",
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "employee",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -9,7 +9,8 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"id": true,
|
"id": true,
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
@ -47,4 +48,4 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"name": "Prefix",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "pbx.prefix"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"country": {
|
||||||
|
"type": "string",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"prefix": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"property": "*",
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "employee",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -20,6 +20,9 @@
|
||||||
},
|
},
|
||||||
"backupPrinterNotificationDelay": {
|
"backupPrinterNotificationDelay": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"itemOrderReviewHours": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,6 +16,9 @@
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
|
},
|
||||||
|
"autonomyFk": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
@ -55,4 +58,4 @@
|
||||||
"permission": "ALLOW"
|
"permission": "ALLOW"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"name": "QueueMember",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "pbx.queueMember"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"queue": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"extension": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"queueRelation": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Queue",
|
||||||
|
"foreignKey": "queue",
|
||||||
|
"primaryKey": "name"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"property": "*",
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "employee",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "SaySimpleConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "saySimpleConfig"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"defaultChannel": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$authenticated",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"name": "SaySimpleCountry",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "saySimpleCountry"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"countryFk": {
|
||||||
|
"type": "number",
|
||||||
|
"id": true
|
||||||
|
},
|
||||||
|
"channel": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [
|
||||||
|
{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$authenticated",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -12,7 +12,8 @@
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
@ -54,4 +55,4 @@
|
||||||
"fields": ["id", "name", "provinceFk"]
|
"fields": ["id", "name", "provinceFk"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "userConfig"
|
"table": "userMultiConfig"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
const vnModel = require('vn-loopback/common/models/vn-model');
|
||||||
|
module.exports = function(Self) {
|
||||||
|
vnModel(Self);
|
||||||
|
require('../methods/vn-token/killSession')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"name": "VnToken",
|
||||||
|
"base": "AccessToken",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "salix.AccessToken"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"created": {
|
||||||
|
"type": "date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"user": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "VnUser",
|
||||||
|
"foreignKey": "userId"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hidden": ["id"]
|
||||||
|
}
|
|
@ -101,9 +101,10 @@ module.exports = function(Self) {
|
||||||
const headers = httpRequest.headers;
|
const headers = httpRequest.headers;
|
||||||
const origin = headers.origin;
|
const origin = headers.origin;
|
||||||
|
|
||||||
const defaultHash = '/reset-password?access_token=$token$';
|
const defaultHash = '!/reset-password?access_token=$token$';
|
||||||
const recoverHashes = {
|
const recoverHashes = {
|
||||||
hedera: 'verificationToken=$token$'
|
hedera: '!verificationToken=$token$',
|
||||||
|
lilium: '/resetPassword?access_token=$token$'
|
||||||
};
|
};
|
||||||
|
|
||||||
const app = info.options?.app;
|
const app = info.options?.app;
|
||||||
|
@ -115,7 +116,7 @@ module.exports = function(Self) {
|
||||||
const params = {
|
const params = {
|
||||||
recipient: info.email,
|
recipient: info.email,
|
||||||
lang: user.lang,
|
lang: user.lang,
|
||||||
url: origin + '/#!' + recoverHash
|
url: origin + '/#' + recoverHash
|
||||||
};
|
};
|
||||||
|
|
||||||
const options = Object.assign({}, info.options);
|
const options = Object.assign({}, info.options);
|
||||||
|
|
|
@ -165,7 +165,8 @@
|
||||||
"hasGrant",
|
"hasGrant",
|
||||||
"realm",
|
"realm",
|
||||||
"email",
|
"email",
|
||||||
"emailVerified"
|
"emailVerified",
|
||||||
|
"twoFactor"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
"isManaged": {
|
"isManaged": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"isDestiny": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"countryFk": {
|
"countryFk": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/workerActivity/add')(Self);
|
||||||
|
};
|
|
@ -22,18 +22,18 @@
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"workerFk": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Worker",
|
||||||
|
"foreignKey": "workerFk"
|
||||||
},
|
},
|
||||||
"relations": {
|
"workerActivityTypeFk": {
|
||||||
"workerFk": {
|
"type": "belongsTo",
|
||||||
"type": "belongsTo",
|
"model": "WorkerActivityType",
|
||||||
"model": "Worker",
|
"foreignKey": "workerActivityTypeFk"
|
||||||
"foreignKey": "workerFk"
|
|
||||||
},
|
|
||||||
"workerActivityTypeFk": {
|
|
||||||
"type": "belongsTo",
|
|
||||||
"model": "WorkerActivityType",
|
|
||||||
"foreignKey": "workerActivityTypeFk"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
apps:
|
|
||||||
- script: ./loopback/server/server.js
|
|
||||||
name: salix-back
|
|
||||||
instances: 1
|
|
||||||
max_restarts: 3
|
|
||||||
restart_delay: 15000
|
|
||||||
node_args: --tls-min-v1.0 --openssl-legacy-provider
|
|
|
@ -9,7 +9,7 @@
|
||||||
},
|
},
|
||||||
"vn": {
|
"vn": {
|
||||||
"view": {
|
"view": {
|
||||||
"expeditionPallet_Print": "ced2b84a114fcb99fce05f0c34f4fc03f3fa387bef92621be1bc306608a84345"
|
"expeditionPallet_Print": "04fc5f2967ce53bfbb85f7f48b9a3dca4a4f7111ac41e1775f4cc7d6538774b2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1 +1,14 @@
|
||||||
-- Executed before dump
|
-- Executed before dump
|
||||||
|
|
||||||
|
CREATE USER 'vn'@'localhost';
|
||||||
|
|
||||||
|
GRANT SELECT,
|
||||||
|
INSERT,
|
||||||
|
UPDATE,
|
||||||
|
DELETE,
|
||||||
|
DROP,
|
||||||
|
CREATE TEMPORARY TABLES,
|
||||||
|
EXECUTE,
|
||||||
|
EVENT,
|
||||||
|
TRIGGER
|
||||||
|
ON *.* TO 'vn'@'localhost';
|
||||||
|
|
|
@ -10,9 +10,6 @@ SET foreign_key_checks = 0;
|
||||||
INSERT INTO util.config (id, environment, mockTime, mockUtcTime, mockEnabled)
|
INSERT INTO util.config (id, environment, mockTime, mockUtcTime, mockEnabled)
|
||||||
VALUES (1, 'local', '2001-01-01 12:00:00', '2001-01-01 11:00:00', TRUE);
|
VALUES (1, 'local', '2001-01-01 12:00:00', '2001-01-01 11:00:00', TRUE);
|
||||||
|
|
||||||
INSERT INTO util.binlogQueue (code,logName, `position`)
|
|
||||||
VALUES ('mylogger', 'bin.000001', 4);
|
|
||||||
|
|
||||||
/* #5483
|
/* #5483
|
||||||
INSERT INTO vn.entryConfig (defaultEntry, mailToNotify, inventorySupplierFk, maxLockTime, defaultSupplierFk)
|
INSERT INTO vn.entryConfig (defaultEntry, mailToNotify, inventorySupplierFk, maxLockTime, defaultSupplierFk)
|
||||||
VALUES(1, NULL, 1, 300, 1);
|
VALUES(1, NULL, 1, 300, 1);
|
||||||
|
@ -314,5 +311,4 @@ INSERT INTO mysql.roles_mapping (`User`, `Host`, `Role`, `Admin_option`)
|
||||||
SELECT SUBSTR(`User`, @prefixLen + 1), `Host`, `Role`, `Admin_option`
|
SELECT SUBSTR(`User`, @prefixLen + 1), `Host`, `Role`, `Admin_option`
|
||||||
FROM mysql.roles_mapping
|
FROM mysql.roles_mapping
|
||||||
WHERE `User` LIKE @prefixedLike AND `Host` = @genRoleHost;
|
WHERE `User` LIKE @prefixedLike AND `Host` = @genRoleHost;
|
||||||
|
|
||||||
FLUSH PRIVILEGES;
|
FLUSH PRIVILEGES;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,8 +7,7 @@ AS SELECT `u`.`id` AS `id`,
|
||||||
`u`.`email` AS `email`,
|
`u`.`email` AS `email`,
|
||||||
`u`.`nickname` AS `nickname`,
|
`u`.`nickname` AS `nickname`,
|
||||||
`u`.`lang` AS `lang`,
|
`u`.`lang` AS `lang`,
|
||||||
`u`.`role` AS `role`,
|
`u`.`role` AS `role`
|
||||||
`u`.`recoverPass` AS `recoverPass`
|
|
||||||
FROM `account`.`user` `u`
|
FROM `account`.`user` `u`
|
||||||
WHERE `u`.`name` = `myUser_getName`()
|
WHERE `u`.`name` = `myUser_getName`()
|
||||||
WITH CASCADED CHECK OPTION
|
WITH CASCADED CHECK OPTION
|
||||||
|
|
|
@ -1,52 +1,52 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`analisis_ventas_update`()
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`analisis_ventas_update`()
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE vLastMonth DATE;
|
DECLARE vLastMonth DATE;
|
||||||
|
|
||||||
SET vLastMonth = util.firstDayOfMonth(TIMESTAMPADD(MONTH, -1, util.VN_CURDATE()));
|
SET vLastMonth = util.firstDayOfMonth(TIMESTAMPADD(MONTH, -1, util.VN_CURDATE()));
|
||||||
|
|
||||||
DELETE FROM analisis_ventas
|
DELETE FROM analisis_ventas
|
||||||
WHERE Año > YEAR(vLastMonth)
|
WHERE Año > YEAR(vLastMonth)
|
||||||
OR (Año = YEAR(vLastMonth) AND Mes >= MONTH(vLastMonth));
|
OR (Año = YEAR(vLastMonth) AND Mes >= MONTH(vLastMonth));
|
||||||
|
|
||||||
INSERT INTO analisis_ventas (
|
INSERT INTO analisis_ventas (
|
||||||
Familia,
|
Familia,
|
||||||
Reino,
|
Reino,
|
||||||
salesDepartmentFk,
|
departmentFk,
|
||||||
Comprador,
|
Comprador,
|
||||||
Provincia,
|
Provincia,
|
||||||
almacen,
|
almacen,
|
||||||
Año,
|
Año,
|
||||||
Mes,
|
Mes,
|
||||||
Semana,
|
Semana,
|
||||||
Vista,
|
Vista,
|
||||||
Importe
|
Importe
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
it.name,
|
it.name,
|
||||||
ic.name,
|
ic.name,
|
||||||
c.salesDepartmentFk,
|
c.departmentFk,
|
||||||
w.code,
|
w.code,
|
||||||
p.name,
|
p.name,
|
||||||
wa.name,
|
wa.name,
|
||||||
tm.year,
|
tm.year,
|
||||||
tm.month,
|
tm.month,
|
||||||
tm.week,
|
tm.week,
|
||||||
dm.description,
|
dm.description,
|
||||||
bt.importe
|
bt.importe
|
||||||
FROM bs.ventas bt
|
FROM bs.ventas bt
|
||||||
LEFT JOIN vn.itemType it ON it.id = bt.tipo_id
|
LEFT JOIN vn.itemType it ON it.id = bt.tipo_id
|
||||||
LEFT JOIN vn.itemCategory ic ON ic.id = it.categoryFk
|
LEFT JOIN vn.itemCategory ic ON ic.id = it.categoryFk
|
||||||
LEFT JOIN vn.client c on c.id = bt.Id_Cliente
|
LEFT JOIN vn.client c on c.id = bt.Id_Cliente
|
||||||
LEFT JOIN vn.worker w ON w.id = it.workerFk
|
LEFT JOIN vn.worker w ON w.id = it.workerFk
|
||||||
JOIN vn.time tm ON tm.dated = bt.fecha
|
JOIN vn.time tm ON tm.dated = bt.fecha
|
||||||
JOIN vn.sale s ON s.id = bt.Id_Movimiento
|
JOIN vn.sale s ON s.id = bt.Id_Movimiento
|
||||||
LEFT JOIN vn.ticket t ON t.id = s.ticketFk
|
LEFT JOIN vn.ticket t ON t.id = s.ticketFk
|
||||||
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
|
JOIN vn.agencyMode am ON am.id = t.agencyModeFk
|
||||||
LEFT JOIN vn.deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
LEFT JOIN vn.deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||||
LEFT JOIN vn.address a ON a.id = t.addressFk
|
LEFT JOIN vn.address a ON a.id = t.addressFk
|
||||||
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
LEFT JOIN vn.province p ON p.id = a.provinceFk
|
||||||
LEFT JOIN vn.warehouse wa ON wa.id = t.warehouseFk
|
LEFT JOIN vn.warehouse wa ON wa.id = t.warehouseFk
|
||||||
WHERE bt.fecha >= vLastMonth AND ic.merchandise;
|
WHERE bt.fecha >= vLastMonth AND ic.merchandise;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`clean`()
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`clean`()
|
||||||
BEGIN
|
BEGIN
|
||||||
DECLARE vDateShort DATETIME;
|
DECLARE vDateShort DATETIME;
|
||||||
DECLARE vDateLong DATETIME;
|
DECLARE vDateLong DATETIME;
|
||||||
|
@ -15,5 +15,5 @@ BEGIN
|
||||||
|
|
||||||
DELETE FROM bi.defaulters WHERE `date` < vDateLong;
|
DELETE FROM bi.defaulters WHERE `date` < vDateLong;
|
||||||
DELETE FROM bi.defaulting WHERE `date` < vDateLong;
|
DELETE FROM bi.defaulting WHERE `date` < vDateLong;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -11,33 +11,33 @@ BEGIN
|
||||||
WITH todayDefaulters AS(
|
WITH todayDefaulters AS(
|
||||||
SELECT client, amount, defaulterSince
|
SELECT client, amount, defaulterSince
|
||||||
FROM bi.defaulters
|
FROM bi.defaulters
|
||||||
WHERE date = vDated
|
WHERE date = vDated
|
||||||
AND hasChanged
|
AND hasChanged
|
||||||
), yesterdayDefaulters AS(
|
), yesterdayDefaulters AS(
|
||||||
SELECT client, amount
|
SELECT client, amount
|
||||||
FROM bi.defaulters
|
FROM bi.defaulters
|
||||||
WHERE date = vDated - INTERVAL 1 DAY
|
WHERE date = vDated - INTERVAL 1 DAY
|
||||||
), newDefaulters AS(
|
), newDefaulters AS(
|
||||||
SELECT td.client,
|
SELECT td.client,
|
||||||
td.amount todayAmount,
|
td.amount todayAmount,
|
||||||
yd.amount yesterdayAmount,
|
yd.amount yesterdayAmount,
|
||||||
ROUND(yd.amount - td.amount, 2) difference,
|
ROUND(yd.amount - td.amount, 2) difference,
|
||||||
defaulterSince
|
defaulterSince
|
||||||
FROM todayDefaulters td
|
FROM todayDefaulters td
|
||||||
JOIN yesterdayDefaulters yd ON yd.client = td.client
|
JOIN yesterdayDefaulters yd ON yd.client = td.client
|
||||||
WHERE td.amount > 0
|
WHERE td.amount > 0
|
||||||
HAVING difference <> 0
|
HAVING difference <> 0
|
||||||
) SELECT nd.client,
|
) SELECT nd.client,
|
||||||
nd.todayAmount,
|
nd.todayAmount,
|
||||||
nd.yesterdayAmount,
|
nd.yesterdayAmount,
|
||||||
nd.difference,
|
nd.difference,
|
||||||
nd.defaulterSince,
|
nd.defaulterSince,
|
||||||
c.name Cliente,
|
c.name Cliente,
|
||||||
d.name salesDepartmentName,
|
d.name salesDepartmentName,
|
||||||
c.payMethodFk pay_met_id,
|
c.payMethodFk pay_met_id,
|
||||||
c.dueDay Vencimiento
|
c.dueDay Vencimiento
|
||||||
FROM newDefaulters nd
|
FROM newDefaulters nd
|
||||||
LEFT JOIN vn.client c ON c.id = nd.client
|
LEFT JOIN vn.client c ON c.id = nd.client
|
||||||
LEFT JOIN vn.department d ON d.id = c.salesDepartmentFk;
|
LEFT JOIN vn.department d ON d.id = c.departmentFk;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`facturacion_media_anual_update`()
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bi`.`facturacion_media_anual_update`()
|
||||||
BEGIN
|
BEGIN
|
||||||
TRUNCATE TABLE bs.clientAnnualConsumption;
|
TRUNCATE TABLE bs.clientAnnualConsumption;
|
||||||
|
|
||||||
|
@ -12,5 +12,5 @@ BEGIN
|
||||||
GROUP BY clientFk, year, month
|
GROUP BY clientFk, year, month
|
||||||
) vol
|
) vol
|
||||||
GROUP BY clientFk;
|
GROUP BY clientFk;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -19,14 +19,14 @@ BEGIN
|
||||||
bultos)
|
bultos)
|
||||||
SELECT r.id,
|
SELECT r.id,
|
||||||
r.agencyModeFk,
|
r.agencyModeFk,
|
||||||
r.created,
|
r.dated,
|
||||||
SUM(sv.volume / ebv.m3)
|
SUM(sv.volume / ebv.m3)
|
||||||
FROM vn.route r
|
FROM vn.route r
|
||||||
JOIN vn.ticket t ON t.routeFk = r.id
|
JOIN vn.ticket t ON t.routeFk = r.id
|
||||||
LEFT JOIN vn.`zone` z ON z.id = t.zoneFk
|
LEFT JOIN vn.`zone` z ON z.id = t.zoneFk
|
||||||
JOIN vn.saleVolume sv ON sv.ticketFk = t.id
|
JOIN vn.saleVolume sv ON sv.ticketFk = t.id
|
||||||
JOIN vn.expeditionBoxVol ebv ON ebv.code = 'transportBox'
|
JOIN vn.expeditionBoxVol ebv ON ebv.code = 'transportBox'
|
||||||
WHERE r.created BETWEEN vDatedFrom AND vDatedTo
|
WHERE r.dated BETWEEN vDatedFrom AND vDatedTo
|
||||||
AND z.isVolumetric
|
AND z.isVolumetric
|
||||||
GROUP BY r.id;
|
GROUP BY r.id;
|
||||||
|
|
||||||
|
@ -38,12 +38,12 @@ BEGIN
|
||||||
Bultos)
|
Bultos)
|
||||||
SELECT r.id,
|
SELECT r.id,
|
||||||
r.agencyModeFk,
|
r.agencyModeFk,
|
||||||
r.created,
|
r.dated,
|
||||||
SUM(t.packages)
|
SUM(t.packages)
|
||||||
FROM vn.route r
|
FROM vn.route r
|
||||||
JOIN vn.ticket t ON t.routeFk = r.id
|
JOIN vn.ticket t ON t.routeFk = r.id
|
||||||
LEFT JOIN vn.`zone` z ON z.id = t.zoneFk
|
LEFT JOIN vn.`zone` z ON z.id = t.zoneFk
|
||||||
WHERE r.created BETWEEN vDatedFrom AND vDatedTo
|
WHERE r.dated BETWEEN vDatedFrom AND vDatedTo
|
||||||
AND NOT z.isVolumetric
|
AND NOT z.isVolumetric
|
||||||
GROUP BY r.id
|
GROUP BY r.id
|
||||||
ON DUPLICATE KEY UPDATE Bultos = Bultos + VALUES(Bultos);
|
ON DUPLICATE KEY UPDATE Bultos = Bultos + VALUES(Bultos);
|
||||||
|
@ -60,7 +60,7 @@ BEGIN
|
||||||
JOIN vn.component c ON c.id = sc.componentFk
|
JOIN vn.component c ON c.id = sc.componentFk
|
||||||
JOIN vn.componentType ct ON ct.id = c.typeFk
|
JOIN vn.componentType ct ON ct.id = c.typeFk
|
||||||
WHERE ct.code = 'freight'
|
WHERE ct.code = 'freight'
|
||||||
AND r.created BETWEEN vDatedFrom AND vDatedTo
|
AND r.dated BETWEEN vDatedFrom AND vDatedTo
|
||||||
GROUP BY r.id
|
GROUP BY r.id
|
||||||
) sub ON sub.routeFk = r.Id_Ruta
|
) sub ON sub.routeFk = r.Id_Ruta
|
||||||
SET r.practico = IFNULL(sub.totalPractice / r.Bultos, 0);
|
SET r.practico = IFNULL(sub.totalPractice / r.Bultos, 0);
|
||||||
|
@ -77,7 +77,7 @@ BEGIN
|
||||||
JOIN vn.address ad ON ad.id = t.addressFk
|
JOIN vn.address ad ON ad.id = t.addressFk
|
||||||
JOIN vn.client c ON c.id = ad.clientFk
|
JOIN vn.client c ON c.id = ad.clientFk
|
||||||
LEFT JOIN vn.`zone` z ON z.id = t.zoneFk
|
LEFT JOIN vn.`zone` z ON z.id = t.zoneFk
|
||||||
WHERE r.created BETWEEN vDatedFrom AND vDatedTo
|
WHERE r.dated BETWEEN vDatedFrom AND vDatedTo
|
||||||
AND NOT z.isVolumetric
|
AND NOT z.isVolumetric
|
||||||
GROUP BY t.routeFk
|
GROUP BY t.routeFk
|
||||||
) sub ON r.Id_Ruta = sub.routeFk
|
) sub ON r.Id_Ruta = sub.routeFk
|
||||||
|
@ -93,7 +93,7 @@ BEGIN
|
||||||
JOIN vn.saleVolume sf ON sf.ticketFk = t.id
|
JOIN vn.saleVolume sf ON sf.ticketFk = t.id
|
||||||
JOIN vn.client c ON c.id = t.clientFk
|
JOIN vn.client c ON c.id = t.clientFk
|
||||||
JOIN vn.`zone` z ON z.id = t.zoneFk
|
JOIN vn.`zone` z ON z.id = t.zoneFk
|
||||||
WHERE r.created BETWEEN vDatedFrom AND vDatedTo
|
WHERE r.dated BETWEEN vDatedFrom AND vDatedTo
|
||||||
AND z.isVolumetric
|
AND z.isVolumetric
|
||||||
GROUP BY t.routeFk
|
GROUP BY t.routeFk
|
||||||
) sub ON r.Id_Ruta = sub.routeFk
|
) sub ON r.Id_Ruta = sub.routeFk
|
||||||
|
@ -108,7 +108,7 @@ BEGIN
|
||||||
JOIN vn.route r ON r.id = t.routeFk
|
JOIN vn.route r ON r.id = t.routeFk
|
||||||
JOIN vn.greuge g ON g.ticketFk = t.id
|
JOIN vn.greuge g ON g.ticketFk = t.id
|
||||||
JOIN vn.greugeType gt ON gt.id = g.greugeTypeFk
|
JOIN vn.greugeType gt ON gt.id = g.greugeTypeFk
|
||||||
WHERE r.created BETWEEN vDatedFrom AND vDatedTo
|
WHERE r.dated BETWEEN vDatedFrom AND vDatedTo
|
||||||
AND gt.code = 'freightDifference'
|
AND gt.code = 'freightDifference'
|
||||||
GROUP BY t.routeFk
|
GROUP BY t.routeFk
|
||||||
) sub ON r.Id_Ruta = sub.routeFk
|
) sub ON r.Id_Ruta = sub.routeFk
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost`
|
|
||||||
SQL SECURITY DEFINER
|
|
||||||
VIEW `bi`.`rotacion`
|
|
||||||
AS SELECT `ic`.`itemFk` AS `Id_Article`,
|
|
||||||
`ic`.`warehouseFk` AS `warehouse_id`,
|
|
||||||
`ic`.`quantity` AS `total`,
|
|
||||||
`ic`.`rotation` AS `rotacion`,
|
|
||||||
`ic`.`cm3` AS `cm3`,
|
|
||||||
`ic`.`storage` AS `almacenaje`,
|
|
||||||
`ic`.`handling` AS `manipulacion`,
|
|
||||||
`ic`.`extraCharge` AS `auxiliar`,
|
|
||||||
`ic`.`wasted` AS `mermas`,
|
|
||||||
`ic`.`cm3delivery` AS `cm3reparto`,
|
|
||||||
`ic`.`grams` AS `grams`
|
|
||||||
FROM `vn`.`itemCost` `ic`
|
|
|
@ -33,8 +33,8 @@ BEGIN
|
||||||
END
|
END
|
||||||
FROM vn.client c
|
FROM vn.client c
|
||||||
JOIN vn.country co ON co .id = c.countryFk
|
JOIN vn.country co ON co .id = c.countryFk
|
||||||
JOIN vn.department w ON w.id = c.salesDepartmentFk
|
JOIN vn.department w ON w.id = c.departmentFk
|
||||||
JOIN vn.departmentMana dm ON dm.salesDepartmentFk = c.salesDepartmentFk
|
JOIN vn.departmentMana dm ON dm.departmentFk = c.departmentFk
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT c.id, DATE(MAX(t.shipped)) lastShipped
|
SELECT c.id, DATE(MAX(t.shipped)) lastShipped
|
||||||
FROM vn.client c
|
FROM vn.client c
|
||||||
|
|
|
@ -33,7 +33,7 @@ BEGIN
|
||||||
END
|
END
|
||||||
FROM vn.client c
|
FROM vn.client c
|
||||||
JOIN vn.country co ON co .id = c.countryFk
|
JOIN vn.country co ON co .id = c.countryFk
|
||||||
JOIN vn.departmentMana dm ON dm.salesDepartmentFk = c.salesDepartmentFk
|
JOIN vn.departmentMana dm ON dm.departmentFk = c.departmentFk
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT c.id, DATE(MAX(t.shipped)) lastShipped
|
SELECT c.id, DATE(MAX(t.shipped)) lastShipped
|
||||||
FROM vn.client c
|
FROM vn.client c
|
||||||
|
|
|
@ -6,25 +6,27 @@ BLOCK1: BEGIN
|
||||||
DECLARE vShipped DATE;
|
DECLARE vShipped DATE;
|
||||||
DECLARE vPreviousShipped DATE;
|
DECLARE vPreviousShipped DATE;
|
||||||
DECLARE vDone boolean;
|
DECLARE vDone boolean;
|
||||||
DECLARE cur cursor for
|
|
||||||
|
DECLARE cur CURSOR FOR
|
||||||
SELECT clientFk, firstShipped
|
SELECT clientFk, firstShipped
|
||||||
FROM bs.clientNewBorn;
|
FROM bs.clientNewBorn;
|
||||||
|
|
||||||
DECLARE continue HANDLER FOR NOT FOUND SET vDone = TRUE;
|
DECLARE continue HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||||
SET vDone := FALSE;
|
SET vDone := FALSE;
|
||||||
|
|
||||||
DELETE FROM bs.clientNewBorn WHERE isModified = FALSE;
|
DELETE FROM bs.clientNewBorn WHERE isModified = FALSE;
|
||||||
|
|
||||||
INSERT INTO clientNewBorn(clientFk, firstShipped, lastShipped)
|
INSERT INTO clientNewBorn(clientFk, firstShipped, lastShipped)
|
||||||
SELECT c.id, MAX(t.shipped), MAX(t.shipped)
|
SELECT c.id, DATE(MAX(t.shipped)), DATE(MAX(t.shipped))
|
||||||
FROM vn.client c
|
FROM vn.client c
|
||||||
JOIN vn.ticket t on t.clientFk = c.id
|
JOIN vn.ticket t ON t.clientFk = c.id
|
||||||
LEFT JOIN clientNewBorn cb on cb.clientFk = c.id
|
LEFT JOIN clientNewBorn cb ON cb.clientFk = c.id
|
||||||
WHERE t.shipped BETWEEN TIMESTAMPADD(YEAR, -1, util.VN_CURDATE()) AND util.VN_CURDATE() AND cb.isModified is null
|
WHERE t.shipped BETWEEN util.VN_CURDATE() - INTERVAL 1 YEAR
|
||||||
GROUP BY c.id;
|
AND util.VN_CURDATE()
|
||||||
|
AND cb.isModified IS NULL
|
||||||
|
GROUP BY c.id;
|
||||||
|
|
||||||
OPEN cur;
|
OPEN cur;
|
||||||
|
|
||||||
LOOP1: LOOP
|
LOOP1: LOOP
|
||||||
SET vDone := FALSE;
|
SET vDone := FALSE;
|
||||||
FETCH cur INTO vClientFk, vShipped;
|
FETCH cur INTO vClientFk, vShipped;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root``localhost` PROCEDURE `bs`.`comparativeCampaign`(vDateFrom DATE, vDateTo DATE)
|
CREATE OR REPLACE DEFINER=`root``localhost` PROCEDURE `bs`.`comparativeCampaign`(vDateFrom DATE, vDateTo DATE)
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT deparmentName,
|
SELECT deparmentName,
|
||||||
id clientFk,
|
id clientFk,
|
||||||
name clientName,
|
name clientName,
|
||||||
CAST(SUM(previousAmmount) AS DECIMAL(10, 0)) previousAmmount,
|
CAST(SUM(previousAmmount) AS DECIMAL(10, 0)) previousAmmount,
|
||||||
CAST(SUM(currentAmmount) AS DECIMAL(10, 0)) currentAmmount
|
CAST(SUM(currentAmmount) AS DECIMAL(10, 0)) currentAmmount
|
||||||
FROM ((SELECT
|
FROM ((SELECT
|
||||||
d.name deparmentName,
|
d.name deparmentName,
|
||||||
c.id,
|
c.id,
|
||||||
c.name,
|
c.name,
|
||||||
|
@ -14,12 +14,12 @@ BEGIN
|
||||||
0 currentAmmount
|
0 currentAmmount
|
||||||
FROM sale s
|
FROM sale s
|
||||||
JOIN vn.`client` c ON s.clientFk = c.id
|
JOIN vn.`client` c ON s.clientFk = c.id
|
||||||
JOIN vn.department d ON d.id = c.salesDepartmentFk
|
JOIN vn.department d ON d.id = c.departmentFk
|
||||||
WHERE s.dated BETWEEN DATE_ADD(vDateFrom, INTERVAL - 1 YEAR)
|
WHERE s.dated BETWEEN DATE_ADD(vDateFrom, INTERVAL - 1 YEAR)
|
||||||
AND DATE_ADD(vDateTo, INTERVAL - 1 YEAR)
|
AND DATE_ADD(vDateTo, INTERVAL - 1 YEAR)
|
||||||
GROUP BY d.id, s.clientFk)
|
GROUP BY d.id, s.clientFk)
|
||||||
UNION ALL
|
UNION ALL
|
||||||
(SELECT
|
(SELECT
|
||||||
d.name deparmentName,
|
d.name deparmentName,
|
||||||
c.id,
|
c.id,
|
||||||
c.name,
|
c.name,
|
||||||
|
@ -28,12 +28,12 @@ BEGIN
|
||||||
FROM vn.sale s
|
FROM vn.sale s
|
||||||
JOIN vn.ticket t ON t.id = s.ticketFk
|
JOIN vn.ticket t ON t.id = s.ticketFk
|
||||||
JOIN vn.client c ON c.id = t.clientFk
|
JOIN vn.client c ON c.id = t.clientFk
|
||||||
JOIN vn.department d ON d.id = c.salesDepartmentFk
|
JOIN vn.department d ON d.id = c.departmentFk
|
||||||
WHERE t.shipped BETWEEN vDateFrom AND vDateTo
|
WHERE t.shipped BETWEEN vDateFrom AND vDateTo
|
||||||
GROUP BY d.id, c.id)
|
GROUP BY d.id, c.id)
|
||||||
) comparative
|
) comparative
|
||||||
GROUP BY deparmentName, id
|
GROUP BY deparmentName, id
|
||||||
HAVING previousAmmount OR currentAmmount
|
HAVING previousAmmount OR currentAmmount
|
||||||
ORDER BY deparmentName, id;
|
ORDER BY deparmentName, id;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -32,7 +32,7 @@ BEGIN
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tVisible
|
CREATE OR REPLACE TEMPORARY TABLE tVisible
|
||||||
SELECT itemFk, SUM(visible) totalVisible
|
SELECT itemFk, SUM(visible) totalVisible
|
||||||
FROM vn.itemShelving ish
|
FROM vn.itemShelving ish
|
||||||
JOIN vn.shelving sh ON sh.code = ish.shelvingFk
|
JOIN vn.shelving sh ON sh.id = ish.shelvingFk
|
||||||
JOIN vn.parking p ON p.id = sh.parkingFk
|
JOIN vn.parking p ON p.id = sh.parkingFk
|
||||||
JOIN vn.sector sc ON sc.id = p.sectorFk
|
JOIN vn.sector sc ON sc.id = p.sectorFk
|
||||||
WHERE sc.warehouseFk = vWarehouseFk
|
WHERE sc.warehouseFk = vWarehouseFk
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`manaSpellers_actualize`()
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`manaSpellers_actualize`()
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Recalcula el valor del campo con el modificador de precio
|
* Recalcula el valor del campo con el modificador de precio
|
||||||
* para el componente de maná automático.
|
* para el componente de maná automático.
|
||||||
*/
|
*/
|
||||||
UPDATE vn.departmentMana dm
|
UPDATE vn.departmentMana dm
|
||||||
JOIN (
|
JOIN (
|
||||||
SELECT c.lastSalesDepartmentFk,
|
SELECT c.lastdepartmentFk,
|
||||||
FLOOR(SUM(s.amount) / 12) amount
|
FLOOR(SUM(s.amount) / 12) amount
|
||||||
FROM salesByClientDepartment s
|
FROM salesByClientDepartment s
|
||||||
JOIN vn.client c ON c.id = s.clientFk
|
JOIN vn.client c ON c.id = s.clientFk
|
||||||
WHERE s.dated BETWEEN util.VN_CURDATE() - INTERVAL 1 YEAR AND util.VN_CURDATE()
|
WHERE s.dated BETWEEN util.VN_CURDATE() - INTERVAL 1 YEAR AND util.VN_CURDATE()
|
||||||
GROUP BY c.lastSalesDepartmentFk
|
GROUP BY c.lastdepartmentFk
|
||||||
)avgPortfolioWeight ON avgPortfolioWeight.lastSalesDepartmentFk = dm.salesDepartmentFk
|
)avgPortfolioWeight ON avgPortfolioWeight.lastdepartmentFk = dm.departmentFk
|
||||||
JOIN vn.salesDepartmentConfig sdc
|
JOIN vn.salesDepartmentConfig sdc
|
||||||
SET dm.pricesModifierRate =
|
SET dm.pricesModifierRate =
|
||||||
IFNULL(
|
IFNULL(
|
||||||
GREATEST(
|
GREATEST(
|
||||||
sdc.manaMinRate,
|
sdc.manaMinRate,
|
||||||
LEAST(
|
LEAST(
|
||||||
sdc.manaMaxRate,
|
sdc.manaMaxRate,
|
||||||
ROUND( - dm.amount / avgPortfolioWeight.amount, 3)
|
ROUND( - dm.amount / avgPortfolioWeight.amount, 3)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`nightTask_launchAll`()
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`nightTask_launchAll`()
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Runs all nightly tasks.
|
* Runs all nightly tasks.
|
||||||
|
@ -76,5 +76,5 @@ BEGIN
|
||||||
END IF;
|
END IF;
|
||||||
END LOOP;
|
END LOOP;
|
||||||
CLOSE vQueue;
|
CLOSE vQueue;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`porfolio_add`()
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`porfolio_add`()
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
* Inserta en la tabla @bs.portfolio las ventas desde el año pasado
|
* Inserta en la tabla @bs.portfolio las ventas desde el año pasado
|
||||||
* agrupadas por equipo, año y mes
|
* agrupadas por equipo, año y mes
|
||||||
*/
|
*/
|
||||||
DECLARE vYear INT DEFAULT YEAR(util.VN_CURDATE()) - 1;
|
DECLARE vYear INT DEFAULT YEAR(util.VN_CURDATE()) - 1;
|
||||||
|
|
||||||
CALL util.time_generate(
|
CALL util.time_generate(
|
||||||
MAKEDATE(vYear, 1),
|
MAKEDATE(vYear, 1),
|
||||||
(SELECT MAX(dated) FROM sale)
|
(SELECT MAX(dated) FROM sale)
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO portfolio(yeared, monthed , saleDepartmentFk, Amount)
|
INSERT INTO portfolio(yeared, monthed , saleDepartmentFk, Amount)
|
||||||
SELECT t.`year`, t.`month`, w.code, SUM(s.amount)
|
SELECT t.`year`, t.`month`, w.code, SUM(s.amount)
|
||||||
FROM tmp.time t
|
FROM tmp.time t
|
||||||
JOIN sale s on t.dated = s.dated
|
JOIN sale s on t.dated = s.dated
|
||||||
JOIN vn.client c on c.id = s.clientFk
|
JOIN vn.client c on c.id = s.clientFk
|
||||||
JOIN vn.department d ON d.id = c.salesDepartmentFk
|
JOIN vn.department d ON d.id = c.departmentFk
|
||||||
GROUP BY d.id, t.`year`, t.`month`;
|
GROUP BY d.id, t.`year`, t.`month`;
|
||||||
|
|
||||||
DROP TEMPORARY TABLE tmp.time;
|
DROP TEMPORARY TABLE tmp.time;
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ BEGIN
|
||||||
/**
|
/**
|
||||||
* Agrupa las ventas por cliente/departamento/fecha en la tabla bs.salesByClientDepartment
|
* Agrupa las ventas por cliente/departamento/fecha en la tabla bs.salesByClientDepartment
|
||||||
* El asociación cliente/comercial/fecha, se mantiene correcta en el tiempo
|
* El asociación cliente/comercial/fecha, se mantiene correcta en el tiempo
|
||||||
*
|
*
|
||||||
* @param vDatedFrom el cálculo se realizará desde la fecha introducida hasta ayer
|
* @param vDatedFrom el cálculo se realizará desde la fecha introducida hasta ayer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -17,22 +17,22 @@ BEGIN
|
||||||
equalizationTax = 0,
|
equalizationTax = 0,
|
||||||
amountNewBorn = 0
|
amountNewBorn = 0
|
||||||
WHERE dated BETWEEN vDatedFrom AND util.yesterday();
|
WHERE dated BETWEEN vDatedFrom AND util.yesterday();
|
||||||
|
|
||||||
INSERT INTO salesByClientDepartment(
|
INSERT INTO salesByClientDepartment(
|
||||||
dated,
|
dated,
|
||||||
salesDepartmentFk,
|
departmentFk,
|
||||||
clientFk,
|
clientFk,
|
||||||
amount,
|
amount,
|
||||||
equalizationTax)
|
equalizationTax)
|
||||||
SELECT s.dated,
|
SELECT s.dated,
|
||||||
c.salesDepartmentFk,
|
c.departmentFk,
|
||||||
s.clientFk,
|
s.clientFk,
|
||||||
SUM(s.amount),
|
SUM(s.amount),
|
||||||
SUM(s.surcharge)
|
SUM(s.surcharge)
|
||||||
FROM sale s
|
FROM sale s
|
||||||
JOIN vn.client c on s.clientFk = c.id
|
JOIN vn.client c on s.clientFk = c.id
|
||||||
WHERE s.dated BETWEEN vDatedFrom AND util.yesterday()
|
WHERE s.dated BETWEEN vDatedFrom AND util.yesterday()
|
||||||
GROUP BY s.dated, c.salesDepartmentFk, s.clientFk
|
GROUP BY s.dated, c.departmentFk, s.clientFk
|
||||||
ON DUPLICATE KEY UPDATE amount= VALUES(amount),
|
ON DUPLICATE KEY UPDATE amount= VALUES(amount),
|
||||||
equalizationTax= VALUES(equalizationTax);
|
equalizationTax= VALUES(equalizationTax);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`salesByItemTypeDay_addLauncher`()
|
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `bs`.`salesByItemTypeDay_addLauncher`()
|
||||||
BEGIN
|
BEGIN
|
||||||
CALL bs.salesByItemTypeDay_add(util.VN_CURDATE() - INTERVAL 30 DAY, util.VN_CURDATE());
|
CALL bs.salesByItemTypeDay_add(util.VN_CURDATE() - INTERVAL 30 DAY, util.VN_CURDATE());
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue