Compare commits
71 Commits
dev
...
b4e0f4c666
| Author | SHA1 | Date | |
|---|---|---|---|
| b4e0f4c666 | |||
| db66302415 | |||
| 90e9bb0ff6 | |||
| bd11feb136 | |||
| 96e7f742fe | |||
| eb051d51f2 | |||
| 7a1a4773e7 | |||
| 878e650e62 | |||
| a31e7ea163 | |||
| 04aa943920 | |||
| af076b8e27 | |||
| c0a0589b3c | |||
| 509ef84726 | |||
| 5ab813f378 | |||
| 5d61eb879e | |||
| 2d4b1db5f4 | |||
| 58f7b4322d | |||
| 3b5e82fdc1 | |||
| f9cd3fb881 | |||
| 51267f5202 | |||
| ceaa25f31e | |||
| 416254353c | |||
| 7f946c095b | |||
| c2aa69ab0a | |||
| 250988800e | |||
| cacfd6d2e0 | |||
| 8d2721b0c2 | |||
| 36cdc7b4bf | |||
| 4d4d6fc7a4 | |||
| 030f9f9aac | |||
| 9e9a56cbb1 | |||
| b01980e1c5 | |||
| fe0c500dcf | |||
| 8a040d15db | |||
| f90066c090 | |||
| 04eb2e3e14 | |||
| 90fb0d364d | |||
| e6e1cecce3 | |||
| 73aa95a693 | |||
| b9f19095cb | |||
| dcb56d4274 | |||
| bc1821132e | |||
| 2551d6c907 | |||
| adf0880659 | |||
| 5149de3199 | |||
| c71b514d9a | |||
| 9254e52808 | |||
| b8c028a6c1 | |||
| 529e922485 | |||
| 5201012235 | |||
| abe53b8f5d | |||
| 836f3e294b | |||
| 96abef762b | |||
| 2c227f9428 | |||
| 46647687dc | |||
| cb01ef1af1 | |||
| b3b5fcec65 | |||
| 3a4dc47a36 | |||
| 63177b523e | |||
| e1cad027d2 | |||
| c1cc355f4f | |||
| 5ed67f3fc0 | |||
| 57e82d2360 | |||
| 9395ec6cd4 | |||
| 0475bb30f9 | |||
| 6843368c36 | |||
| 335ea2deca | |||
| 96814c1115 | |||
| 6dd9ed848b | |||
| 0c5fc1dfb0 | |||
| 5886bea85d |
50
.vscode/settings.json
vendored
50
.vscode/settings.json
vendored
@@ -1,26 +1,28 @@
|
||||
{
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
|
||||
"editor.formatOnSave": true,
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[json]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[graphql]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[handlebars]": {
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"workbench.colorTheme": "Default Dark+",
|
||||
"prettier.tabWidth": 4,
|
||||
"terminal.integrated.env.windows": {},
|
||||
"editor.formatOnSave": true,
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[json]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[graphql]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[handlebars]": {
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
}
|
||||
|
||||
95
CHANGELOG.md
95
CHANGELOG.md
@@ -1,5 +1,100 @@
|
||||
# All CHanges to LST can be found below.
|
||||
|
||||
## [2.10.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.9.0...v2.10.0) (2025-03-27)
|
||||
|
||||
|
||||
### 📝 Testing Code
|
||||
|
||||
* **ocme:** lots of changes to get it working in production ([6dd9ed8](https://git.tuffraid.net/cowch/lstV2/commits/6dd9ed848bc7d4e8a62778cfe36f89e077187157))
|
||||
|
||||
|
||||
### 📈 Project changes
|
||||
|
||||
* **lst:** changes made to the settings file to work across all pvs ([5149de3](https://git.tuffraid.net/cowch/lstV2/commits/5149de3199d3aaf349b8a4c99d5db83f8d04ae49))
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **logistics:** correction to the lane grab ([2d4b1db](https://git.tuffraid.net/cowch/lstV2/commits/2d4b1db5f4697770aee8829764bd85643893d3e8))
|
||||
* **lst:** missing , in versionRc ([c35726b](https://git.tuffraid.net/cowch/lstV2/commits/c35726bf5ccd6565abda37c6618a34e975e70d41))
|
||||
* **ocme:** corrections to posting data for the response was added ([dcb56d4](https://git.tuffraid.net/cowch/lstV2/commits/dcb56d427458c774b462e78daba6fee4afefd525))
|
||||
* **ocme:** fixed some import errors ([b01980e](https://git.tuffraid.net/cowch/lstV2/commits/b01980e1c5a8833b25ea557a2da07b74560526e3))
|
||||
* **ocme:** fixed the camera routes ([51267f5](https://git.tuffraid.net/cowch/lstV2/commits/51267f5202ceebe1c31c819395e1588d47657c38))
|
||||
* **servers:** fixed the weird conflict import that happened ([8a040d1](https://git.tuffraid.net/cowch/lstV2/commits/8a040d15dbf5de5fbb9949b7834c39b93b145aa7))
|
||||
|
||||
|
||||
### 📝 Chore
|
||||
|
||||
* bump build number to 50 ([9bdca33](https://git.tuffraid.net/cowch/lstV2/commits/9bdca3317c7c213f9c5853222eafe1ab028b5f64))
|
||||
* **release:** bump build number to 52 ([5886bea](https://git.tuffraid.net/cowch/lstV2/commits/5886bea85da30fe43635e05de1e9bc4f5789fa64))
|
||||
* **release:** bump build number to 55 ([0c5fc1d](https://git.tuffraid.net/cowch/lstV2/commits/0c5fc1dfb0a8bee5cf7414733a555fe1b5888b8e))
|
||||
* **release:** bump build number to 56 ([335ea2d](https://git.tuffraid.net/cowch/lstV2/commits/335ea2deca54dacda2117849104bf4c24faee3e8))
|
||||
* **release:** bump build number to 57 ([6843368](https://git.tuffraid.net/cowch/lstV2/commits/6843368c3682bb56e5ce4aafbb18367e96a6016e))
|
||||
* **release:** bump build number to 58 ([0475bb3](https://git.tuffraid.net/cowch/lstV2/commits/0475bb30f9d6d4e2d132b15b24d9ab225d8de3b9))
|
||||
* **release:** bump build number to 59 ([9395ec6](https://git.tuffraid.net/cowch/lstV2/commits/9395ec6cd4483f52fcca949a95a4ceecaa843f65))
|
||||
* **release:** bump build number to 60 ([57e82d2](https://git.tuffraid.net/cowch/lstV2/commits/57e82d23603622c301c7e6d636f9cec07d44e0b2))
|
||||
* **release:** bump build number to 61 ([5ed67f3](https://git.tuffraid.net/cowch/lstV2/commits/5ed67f3fc0f99ca5344da8b73fd005184b89670b))
|
||||
* **release:** bump build number to 62 ([c1cc355](https://git.tuffraid.net/cowch/lstV2/commits/c1cc355f4f4e74c3897cada64d961b28d24c07b2))
|
||||
* **release:** bump build number to 63 ([e1cad02](https://git.tuffraid.net/cowch/lstV2/commits/e1cad027d2714ddf3289e31b5c3bbb96306f1f56))
|
||||
* **release:** bump build number to 64 ([63177b5](https://git.tuffraid.net/cowch/lstV2/commits/63177b523e2dd1fabefe52f52dd3c6b3fcff9bcf))
|
||||
* **release:** bump build number to 65 ([3a4dc47](https://git.tuffraid.net/cowch/lstV2/commits/3a4dc47a368bb20f622b7e4647337c5e68150db9))
|
||||
* **release:** bump build number to 66 ([b3b5fce](https://git.tuffraid.net/cowch/lstV2/commits/b3b5fcec651e2bc585ecd4be03be4288867b214f))
|
||||
* **release:** bump build number to 67 ([cb01ef1](https://git.tuffraid.net/cowch/lstV2/commits/cb01ef1af17e9c83753e09a1528e6140a4104273))
|
||||
* **release:** bump build number to 68 ([4664768](https://git.tuffraid.net/cowch/lstV2/commits/46647687dc9938ecf6e72a63f15afc0e29bebcc4))
|
||||
* **release:** bump build number to 69 ([2c227f9](https://git.tuffraid.net/cowch/lstV2/commits/2c227f94287a6ce9c06b0a41772085ba1f4f0cd3))
|
||||
* **release:** bump build number to 70 ([96abef7](https://git.tuffraid.net/cowch/lstV2/commits/96abef762b77361c857642a33acfb69c0bc00666))
|
||||
* **release:** bump build number to 71 ([836f3e2](https://git.tuffraid.net/cowch/lstV2/commits/836f3e294b4d92673388023503e409592ef95ba3))
|
||||
* **release:** bump build number to 72 ([abe53b8](https://git.tuffraid.net/cowch/lstV2/commits/abe53b8f5d9bfbf517c7f56c5d4df2e4586aedbd))
|
||||
* **release:** bump build number to 73 ([5201012](https://git.tuffraid.net/cowch/lstV2/commits/5201012235181975cb89aee8dbc644ca4aa42210))
|
||||
* **release:** bump build number to 74 ([529e922](https://git.tuffraid.net/cowch/lstV2/commits/529e922485303251349c081ad8b2e9bee08dd420))
|
||||
* **release:** bump build number to 75 ([b8c028a](https://git.tuffraid.net/cowch/lstV2/commits/b8c028a6c1fa54afeb049fd42e666bc40690aa4e))
|
||||
* **release:** bump build number to 76 ([9254e52](https://git.tuffraid.net/cowch/lstV2/commits/9254e528086b95ada8c9dc4468f4fbb5b39fbd68))
|
||||
* **release:** bump build number to 77 ([4d4d6fc](https://git.tuffraid.net/cowch/lstV2/commits/4d4d6fc7a4885b4b1652ac125a2b39b8325b0d6e))
|
||||
* **release:** bump build number to 78 ([36cdc7b](https://git.tuffraid.net/cowch/lstV2/commits/36cdc7b4bf3bf90a785bab4d9892e65f84cb162a))
|
||||
* **release:** bump build number to 79 ([8d2721b](https://git.tuffraid.net/cowch/lstV2/commits/8d2721b0c2f6255affcd9ec08427e1b4e6771107))
|
||||
* **release:** bump build number to 80 ([cacfd6d](https://git.tuffraid.net/cowch/lstV2/commits/cacfd6d2e0e11ab7dbc5cb443a58df7bf8d2b8bb))
|
||||
* **release:** bump build number to 81 ([2509888](https://git.tuffraid.net/cowch/lstV2/commits/250988800e1429a1f46005ae54a2a07d31fac3a8))
|
||||
* **release:** bump build number to 82 ([c2aa69a](https://git.tuffraid.net/cowch/lstV2/commits/c2aa69ab0a2f925944abd1b78af6a8698249bff8))
|
||||
* **release:** bump build number to 83 ([7f946c0](https://git.tuffraid.net/cowch/lstV2/commits/7f946c095b8c0208c97bd1bb2c33cf466a04d125))
|
||||
* **release:** bump build number to 84 ([4162543](https://git.tuffraid.net/cowch/lstV2/commits/416254353cd0a926aaf14c343db2ad18f025b230))
|
||||
* **release:** bump build number to 85 ([5d61eb8](https://git.tuffraid.net/cowch/lstV2/commits/5d61eb879e102939df56928cd8d57eda561aabca))
|
||||
* **release:** bump build number to 86 ([5ab813f](https://git.tuffraid.net/cowch/lstV2/commits/5ab813f37894136549de0a05e5b4e2491220d16d))
|
||||
* **release:** bump build number to 87 ([509ef84](https://git.tuffraid.net/cowch/lstV2/commits/509ef8472688ba655c524a1068c3721559f5da11))
|
||||
* **release:** bump build number to 88 ([c0a0589](https://git.tuffraid.net/cowch/lstV2/commits/c0a0589b3c860ae8202a5dd230c18a3463cce857))
|
||||
* **release:** bump build number to 89 ([af076b8](https://git.tuffraid.net/cowch/lstV2/commits/af076b8e27b599c479e4e51f38487cf4cb3cfa34))
|
||||
* **release:** bump build number to 90 ([04aa943](https://git.tuffraid.net/cowch/lstV2/commits/04aa9439205f12bfe10b3fdf76a211a7b8178ac1))
|
||||
* **release:** bump build number to 91 ([a31e7ea](https://git.tuffraid.net/cowch/lstV2/commits/a31e7ea1634fd6b10e22dff4ba93157c2be711ac))
|
||||
* **release:** bump build number to 92 ([878e650](https://git.tuffraid.net/cowch/lstV2/commits/878e650e6237345d825632dff0387a89c7eee088))
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **logistics:** added in return material by lane name and gets lane id ([58f7b43](https://git.tuffraid.net/cowch/lstV2/commits/58f7b4322d3e523620f827a580ff5534b0be5f6c))
|
||||
* **notify:** intial nofity system added to monitor crashes and rfid wrapper ([eb051d5](https://git.tuffraid.net/cowch/lstV2/commits/eb051d51f21b1ad617851fa3f4a1b8ba2f4fe4ac))
|
||||
* **ocme:** manual camera trigger for the wrapper added ([bc18211](https://git.tuffraid.net/cowch/lstV2/commits/bc1821132e30be6b3a36bae63ce52fd4007f74dd))
|
||||
* **ocp:** add lots with scroll view was added ([9e9a56c](https://git.tuffraid.net/cowch/lstV2/commits/9e9a56cbb15782770daf7e4ab08b31ad23df6c27))
|
||||
* **ocp:** added in printers get and add ([f90066c](https://git.tuffraid.net/cowch/lstV2/commits/f90066c09020ebac03a93059c8e41f8531812c8a))
|
||||
* **ocp:** added labeling logs in ([ceaa25f](https://git.tuffraid.net/cowch/lstV2/commits/ceaa25f31e6da526abd0350881e21984c66b455a))
|
||||
* **ocp:** added wrappercard into the mix ([3b5e82f](https://git.tuffraid.net/cowch/lstV2/commits/3b5e82fdc122824b4f59f00f2ed59b90813694ba))
|
||||
* **ocp:** create and book in plus dyco controller implemented ([7a1a477](https://git.tuffraid.net/cowch/lstV2/commits/7a1a4773e71cab93f36071530dbb5561e7592ec7))
|
||||
* **ocp:** prodlink check added ([f9cd3fb](https://git.tuffraid.net/cowch/lstV2/commits/f9cd3fb8815635fdd0736b573dec86d14b24a6a7))
|
||||
* **server:** clearn up code ([fe0c500](https://git.tuffraid.net/cowch/lstV2/commits/fe0c500dcfe317b3f67d67474fda7cf6872f3f37))
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **frontend:** prettier change to formatting ([c71b514](https://git.tuffraid.net/cowch/lstV2/commits/c71b514d9add69c63e608b22bd8a936fa770b167))
|
||||
* **ocme:** clean up on the getInfo endpoint ([b9f1909](https://git.tuffraid.net/cowch/lstV2/commits/b9f19095cbd86569b58bec99575d924db997e385))
|
||||
* **ocme:** cleaup on pickedup ([73aa95a](https://git.tuffraid.net/cowch/lstV2/commits/73aa95a6937129a36f6ece10ef8d6fd5f01a2b27))
|
||||
* **ocme:** corrections to endpoints to work with ocnme as intneeded ([e6e1cec](https://git.tuffraid.net/cowch/lstV2/commits/e6e1cecce33b3c8cd94cf6372601c92f268b12a5))
|
||||
* **ocme:** removed some info logs as ocme calls alot ([96e7f74](https://git.tuffraid.net/cowch/lstV2/commits/96e7f742fe68cc98de3039bd3dbfb2d27f6d7204))
|
||||
* **ocp:** moved printers to there own folder to keep everything clean ([030f9f9](https://git.tuffraid.net/cowch/lstV2/commits/030f9f9aacdfcca1298a26be4442f5629626ba79))
|
||||
* **rfid:** refactored station 3 (lines) and complete logic ([bd11feb](https://git.tuffraid.net/cowch/lstV2/commits/bd11feb1365ffb058283eb9384684c199ef9fd21))
|
||||
* **rfid:** refactored the way the wrapper works to indlude backup dyco plan ([90e9bb0](https://git.tuffraid.net/cowch/lstV2/commits/90e9bb0ff6a2f598b055fae931a0d3c78f93e868))
|
||||
* **server:** changed to log only when in dev, and removed the redirect of the url ([adf0880](https://git.tuffraid.net/cowch/lstV2/commits/adf08806593fdcd3a3d9d0a6d07f0262501e21ad))
|
||||
* **tcpserver:** just the tcp server doing something ([04eb2e3](https://git.tuffraid.net/cowch/lstV2/commits/04eb2e3e145ba99b330ab627fcd9bae436e17fcf))
|
||||
* **updateserver:** removed ocme from starting back up as it was migrated ([2551d6c](https://git.tuffraid.net/cowch/lstV2/commits/2551d6c9074a0338224d81e690600a7a4b9c9777))
|
||||
|
||||
## [2.9.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.8.0...v2.9.0) (2025-03-23)
|
||||
|
||||
|
||||
|
||||
17
database/migrations/0026_daily_the_twelve.sql
Normal file
17
database/migrations/0026_daily_the_twelve.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
CREATE TABLE "printers" (
|
||||
"printer_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"humanReadableId" text,
|
||||
"name" text NOT NULL,
|
||||
"ipAddress" text,
|
||||
"port" numeric NOT NULL,
|
||||
"status" text,
|
||||
"statusText" text NOT NULL,
|
||||
"lastTimePrinted" text,
|
||||
"assigned" boolean DEFAULT false NOT NULL,
|
||||
"remark" text,
|
||||
"monitorState" boolean DEFAULT false NOT NULL,
|
||||
"add_Date" timestamp DEFAULT now(),
|
||||
"upd_date" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "humanReadableId" ON "printers" USING btree ("name");
|
||||
3
database/migrations/0027_needy_sleepwalker.sql
Normal file
3
database/migrations/0027_needy_sleepwalker.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE "printers" ALTER COLUMN "statusText" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "printers" ALTER COLUMN "assigned" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "printers" ALTER COLUMN "monitorState" DROP NOT NULL;
|
||||
1
database/migrations/0028_fast_wong.sql
Normal file
1
database/migrations/0028_fast_wong.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "printers" ALTER COLUMN "port" DROP NOT NULL;
|
||||
2
database/migrations/0029_giant_blue_blade.sql
Normal file
2
database/migrations/0029_giant_blue_blade.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
DROP INDEX "humanReadableId";--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "humanReadableId" ON "printers" USING btree ("humanReadableId");
|
||||
4
database/migrations/0030_conscious_cable.sql
Normal file
4
database/migrations/0030_conscious_cable.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
CREATE TABLE "prodlabels" (
|
||||
"label_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"runningNr" integer NOT NULL
|
||||
);
|
||||
7
database/migrations/0031_loud_alex_power.sql
Normal file
7
database/migrations/0031_loud_alex_power.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE "prodlabels" ADD COLUMN "printerID" integer;--> statement-breakpoint
|
||||
ALTER TABLE "prodlabels" ADD COLUMN "printerName" text;--> statement-breakpoint
|
||||
ALTER TABLE "prodlabels" ADD COLUMN "line" integer;--> statement-breakpoint
|
||||
ALTER TABLE "prodlabels" ADD COLUMN "status" text;--> statement-breakpoint
|
||||
ALTER TABLE "prodlabels" ADD COLUMN "add_date" timestamp;--> statement-breakpoint
|
||||
ALTER TABLE "prodlabels" ADD COLUMN "upd_date" timestamp;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "runningNr" ON "prodlabels" USING btree ("runningNr");
|
||||
1168
database/migrations/meta/0026_snapshot.json
Normal file
1168
database/migrations/meta/0026_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1168
database/migrations/meta/0027_snapshot.json
Normal file
1168
database/migrations/meta/0027_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1168
database/migrations/meta/0028_snapshot.json
Normal file
1168
database/migrations/meta/0028_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1168
database/migrations/meta/0029_snapshot.json
Normal file
1168
database/migrations/meta/0029_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1194
database/migrations/meta/0030_snapshot.json
Normal file
1194
database/migrations/meta/0030_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1246
database/migrations/meta/0031_snapshot.json
Normal file
1246
database/migrations/meta/0031_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -183,6 +183,48 @@
|
||||
"when": 1742655504936,
|
||||
"tag": "0025_amusing_sugar_man",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 26,
|
||||
"version": "7",
|
||||
"when": 1742914066219,
|
||||
"tag": "0026_daily_the_twelve",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 27,
|
||||
"version": "7",
|
||||
"when": 1742917145140,
|
||||
"tag": "0027_needy_sleepwalker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 28,
|
||||
"version": "7",
|
||||
"when": 1742917676211,
|
||||
"tag": "0028_fast_wong",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 29,
|
||||
"version": "7",
|
||||
"when": 1742917978318,
|
||||
"tag": "0029_giant_blue_blade",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 30,
|
||||
"version": "7",
|
||||
"when": 1742938986653,
|
||||
"tag": "0030_conscious_cable",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 31,
|
||||
"version": "7",
|
||||
"when": 1742939306614,
|
||||
"tag": "0031_loud_alex_power",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
42
database/schema/printers.ts
Normal file
42
database/schema/printers.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import {
|
||||
text,
|
||||
pgTable,
|
||||
numeric,
|
||||
index,
|
||||
timestamp,
|
||||
boolean,
|
||||
uuid,
|
||||
uniqueIndex,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
|
||||
import { z } from "zod";
|
||||
|
||||
export const printers = pgTable(
|
||||
"printers",
|
||||
{
|
||||
printer_id: uuid("printer_id").defaultRandom().primaryKey(),
|
||||
humanReadableId: text("humanReadableId"),
|
||||
name: text("name").notNull(),
|
||||
ipAddress: text("ipAddress"),
|
||||
port: numeric("port"),
|
||||
status: text("status"),
|
||||
statusText: text("statusText"),
|
||||
lastTimePrinted: text("lastTimePrinted"),
|
||||
assigned: boolean("assigned").default(false),
|
||||
remark: text("remark"),
|
||||
monitorState: boolean("monitorState").default(false),
|
||||
add_Date: timestamp("add_Date").defaultNow(),
|
||||
upd_date: timestamp("upd_date").defaultNow(),
|
||||
},
|
||||
(table) => [
|
||||
//uniqueIndex("emailUniqueIndex").on(sql`lower(${table.email})`),
|
||||
uniqueIndex("humanReadableId").on(table.humanReadableId),
|
||||
]
|
||||
);
|
||||
|
||||
// Schema for inserting a user - can be used to validate API requests
|
||||
// export const insertRolesSchema = createInsertSchema(roles, {
|
||||
// name: z.string().min(3, {message: "Role name must be more than 3 letters"}),
|
||||
// });
|
||||
// Schema for selecting a Expenses - can be used to validate API responses
|
||||
export const selectRolesSchema = createSelectSchema(printers);
|
||||
30
database/schema/prodLabels.ts
Normal file
30
database/schema/prodLabels.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import {
|
||||
integer,
|
||||
pgTable,
|
||||
uuid,
|
||||
uniqueIndex,
|
||||
text,
|
||||
timestamp,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { createSelectSchema } from "drizzle-zod";
|
||||
|
||||
export const prodlabels = pgTable(
|
||||
"prodlabels",
|
||||
{
|
||||
label_id: uuid("label_id").defaultRandom().primaryKey(),
|
||||
printerID: integer("printerID"),
|
||||
printerName: text("printerName"),
|
||||
line: integer("line"),
|
||||
runningNr: integer("runningNr").notNull(),
|
||||
status: text("status"),
|
||||
add_user: text("add_user").default("lst"),
|
||||
add_date: timestamp("add_date").defaultNow(),
|
||||
upd_date: timestamp("upd_date").defaultNow(),
|
||||
},
|
||||
(table) => [
|
||||
//uniqueIndex("emailUniqueIndex").on(sql`lower(${table.email})`),
|
||||
uniqueIndex("runningNr").on(table.runningNr),
|
||||
]
|
||||
);
|
||||
|
||||
export const prodlabelsSchema = createSelectSchema(prodlabels);
|
||||
32
frontend/package-lock.json
generated
32
frontend/package-lock.json
generated
@@ -16,6 +16,7 @@
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||
"@radix-ui/react-label": "^2.1.2",
|
||||
"@radix-ui/react-popover": "^1.1.6",
|
||||
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-separator": "^1.1.2",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
@@ -1740,6 +1741,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-scroll-area": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.3.tgz",
|
||||
"integrity": "sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@radix-ui/number": "1.1.0",
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"@radix-ui/react-use-layout-effect": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-select": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
||||
"@radix-ui/react-label": "^2.1.2",
|
||||
"@radix-ui/react-popover": "^1.1.6",
|
||||
"@radix-ui/react-scroll-area": "^1.2.3",
|
||||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-separator": "^1.1.2",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
|
||||
131
frontend/src/components/ocme/WrapperCard.tsx
Normal file
131
frontend/src/components/ocme/WrapperCard.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import axios from "axios";
|
||||
import { LstCard } from "../extendedUI/LstCard";
|
||||
import { Button } from "../ui/button";
|
||||
import { ScrollArea } from "../ui/scroll-area";
|
||||
import { Skeleton } from "../ui/skeleton";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "../ui/table";
|
||||
import { toast } from "sonner";
|
||||
|
||||
const currentPallets = [
|
||||
{ key: "line", label: "Line" },
|
||||
{ key: "runningNr", label: "Running #" },
|
||||
{ key: "upd_date", label: "Date Scanned" },
|
||||
{ key: "waitingfor", label: "Waiting For" },
|
||||
{ key: "clear", label: "Clear" },
|
||||
];
|
||||
|
||||
const currentTags = [
|
||||
{ key: "line", label: "Line" },
|
||||
{ key: "printerName", label: "Printer" },
|
||||
{ key: "runningNr", label: "Running #" },
|
||||
{ key: "upd_date", label: "Label date" },
|
||||
{ key: "status", label: "Label Status" },
|
||||
];
|
||||
export default function WrapperManualTrigger() {
|
||||
const cameraTrigger = async () => {
|
||||
try {
|
||||
const res = await axios.get("/ocme/api/v1/manualCameraTrigger");
|
||||
|
||||
if (res.data.success) {
|
||||
toast.success(res.data.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!res.data.success) {
|
||||
toast.error(res.data.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
//stoast.success(error.data.message);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<LstCard className="m-2 p-2">
|
||||
<ScrollArea className="max-h-[200px]">
|
||||
<span>Wrapper Pallet Info</span>
|
||||
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{currentPallets.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{Array(3)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
<ScrollArea className="max-h-[200px]">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{currentTags.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{Array(3)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
<div>
|
||||
<hr />
|
||||
<p className="text-center mb-3">Manual Triggers</p>
|
||||
<div className="flex flex-row justify-between">
|
||||
<Button onClick={cameraTrigger}>Camera</Button>
|
||||
<Button>Rfid</Button>
|
||||
</div>
|
||||
</div>
|
||||
</LstCard>
|
||||
);
|
||||
}
|
||||
@@ -1,14 +1,27 @@
|
||||
import {toast} from "sonner";
|
||||
import {LstCard} from "../extendedUI/LstCard";
|
||||
import {Button} from "../ui/button";
|
||||
import {Input} from "../ui/input";
|
||||
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "../ui/table";
|
||||
import {Skeleton} from "../ui/skeleton";
|
||||
import { toast } from "sonner";
|
||||
import { LstCard } from "../extendedUI/LstCard";
|
||||
import { Button } from "../ui/button";
|
||||
import { Input } from "../ui/input";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "../ui/table";
|
||||
import { Skeleton } from "../ui/skeleton";
|
||||
//import CycleCountLog from "./CycleCountLog";
|
||||
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue} from "../ui/select";
|
||||
import {Controller, useForm} from "react-hook-form";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "../ui/select";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import axios from "axios";
|
||||
import {useState} from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function OcmeCycleCount() {
|
||||
const token = localStorage.getItem("auth_token");
|
||||
@@ -18,7 +31,7 @@ export default function OcmeCycleCount() {
|
||||
register,
|
||||
handleSubmit,
|
||||
//watch,
|
||||
formState: {errors},
|
||||
formState: { errors },
|
||||
reset,
|
||||
control,
|
||||
} = useForm();
|
||||
@@ -29,7 +42,7 @@ export default function OcmeCycleCount() {
|
||||
toast.success(`Cycle count started`);
|
||||
try {
|
||||
const res = await axios.post("/ocme/api/v1/cyclecount", data, {
|
||||
headers: {Authorization: `Bearer ${token}`},
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
toast.success(res.data.message);
|
||||
setData(res.data.data);
|
||||
@@ -45,20 +58,25 @@ export default function OcmeCycleCount() {
|
||||
<div className="flex flex-row w-screen">
|
||||
<div className="m-2 w-5/6">
|
||||
<LstCard>
|
||||
<p className="ml-2">Please enter the name or laneID you want to cycle count.</p>
|
||||
<p className="ml-2">
|
||||
Please enter the name or laneID you want to cycle count.
|
||||
</p>
|
||||
<div>
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="flex justify-between">
|
||||
<div className="m-2 flex flex-row">
|
||||
<Input
|
||||
placeholder="enter lane: L064"
|
||||
className={errors.lane ? "border-red-500" : ""}
|
||||
className={
|
||||
errors.lane ? "border-red-500" : ""
|
||||
}
|
||||
aria-invalid={!!errors.lane}
|
||||
{...register("lane", {
|
||||
required: true,
|
||||
minLength: {
|
||||
value: 3,
|
||||
message: "The lane is too short!",
|
||||
message:
|
||||
"The lane is too short!",
|
||||
},
|
||||
})}
|
||||
/>
|
||||
@@ -68,25 +86,39 @@ export default function OcmeCycleCount() {
|
||||
name="laneType"
|
||||
defaultValue={""}
|
||||
render={({
|
||||
field: {onChange},
|
||||
field: { onChange },
|
||||
fieldState: {},
|
||||
//formState,
|
||||
}) => (
|
||||
<Select onValueChange={onChange}>
|
||||
<Select
|
||||
onValueChange={onChange}
|
||||
>
|
||||
<SelectTrigger className="w-[180px]">
|
||||
<SelectValue placeholder="Select name or id" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="name">Name</SelectItem>
|
||||
<SelectItem value="laneId">Lane ID</SelectItem>
|
||||
<SelectItem value="name">
|
||||
Name
|
||||
</SelectItem>
|
||||
<SelectItem value="laneId">
|
||||
Lane ID
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Button className="m-2" type="submit" disabled={counting}>
|
||||
{counting ? <span>Counting...</span> : <span>CycleCount</span>}
|
||||
<Button
|
||||
className="m-2"
|
||||
type="submit"
|
||||
disabled={counting}
|
||||
>
|
||||
{counting ? (
|
||||
<span>Counting...</span>
|
||||
) : (
|
||||
<span>CycleCount</span>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -108,41 +140,43 @@ export default function OcmeCycleCount() {
|
||||
{data.length === 0 ? (
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
) : (
|
||||
<>
|
||||
{data.map((i: any) => {
|
||||
let classname = ``;
|
||||
if (i.info === "Quality Check Required") {
|
||||
if (
|
||||
i.info === "Quality Check Required"
|
||||
) {
|
||||
classname = `bg-red-500`;
|
||||
}
|
||||
if (i.info === "Sent to Inv") {
|
||||
@@ -150,24 +184,46 @@ export default function OcmeCycleCount() {
|
||||
}
|
||||
return (
|
||||
<TableRow key={i.runningNumber}>
|
||||
<TableCell className={`font-medium ${classname}`}>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.alpla_laneID}
|
||||
</TableCell>
|
||||
<TableCell className={`font-medium ${classname}`}>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.alpla_laneDescription}
|
||||
</TableCell>
|
||||
<TableCell className={`font-medium ${classname}`}>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.Article}
|
||||
</TableCell>
|
||||
<TableCell className={`font-medium ${classname}`}>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.alpla_laneDescription}
|
||||
</TableCell>
|
||||
<TableCell className={`font-medium ${classname}`}>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.runningNumber}
|
||||
</TableCell>
|
||||
<TableCell className={`font-medium ${classname}`}>{i.ocme}</TableCell>
|
||||
<TableCell className={`font-medium ${classname}`}>{i.stock}</TableCell>
|
||||
<TableCell className={`font-medium ${classname}`}>{i.info}</TableCell>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.ocme}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.stock}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={`font-medium ${classname}`}
|
||||
>
|
||||
{i.info}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
import {LstCard} from "@/components/extendedUI/LstCard";
|
||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
|
||||
import {Skeleton} from "@/components/ui/skeleton";
|
||||
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
// import {useSessionStore} from "@/lib/store/sessionStore";
|
||||
// import {useSettingStore} from "@/lib/store/useSettings";
|
||||
import {useQuery} from "@tanstack/react-query";
|
||||
import {getlabels} from "@/utils/querys/production/labels";
|
||||
import {format} from "date-fns";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getlabels } from "@/utils/querys/production/labels";
|
||||
import { format } from "date-fns";
|
||||
|
||||
const labelLogs = [
|
||||
{key: "line", label: "Line"},
|
||||
{key: "printerName", label: "Printer"},
|
||||
{key: "runningNr", label: "Running #"},
|
||||
{key: "upd_date", label: "Label date"},
|
||||
{key: "status", label: "Label Status"},
|
||||
{ key: "line", label: "Line" },
|
||||
{ key: "printerName", label: "Printer" },
|
||||
{ key: "runningNr", label: "Running #" },
|
||||
{ key: "upd_date", label: "Label date" },
|
||||
{ key: "status", label: "Label Status" },
|
||||
//{key: "reprint", label: "Reprint"}, // removing the reprint button for now until repritning is working as intended
|
||||
];
|
||||
export default function LabelLog() {
|
||||
const {data, isError, isLoading} = useQuery(getlabels("4"));
|
||||
const { data, isError, isLoading } = useQuery(getlabels("4"));
|
||||
//const {user} = useSessionStore();
|
||||
//const {settings} = useSettingStore();
|
||||
//const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
||||
@@ -40,33 +47,33 @@ export default function LabelLog() {
|
||||
|
||||
<TableBody>
|
||||
{Array(7)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const labelData = data ? data : [];
|
||||
return (
|
||||
<LstCard className="m-2 p-2 min-h-2/5">
|
||||
<p className="text-center">Labels for the last 2 hours</p>
|
||||
@@ -82,39 +89,47 @@ export default function LabelLog() {
|
||||
<>
|
||||
<TableBody>
|
||||
{Array(7)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</>
|
||||
) : (
|
||||
<TableBody>
|
||||
{data?.map((label: any) => (
|
||||
{labelData.map((label: any) => (
|
||||
<TableRow key={label.runningNr}>
|
||||
<TableCell className="font-medium">{label.line}</TableCell>
|
||||
<TableCell className="font-medium">{label.printerName}</TableCell>
|
||||
<TableCell className="font-medium">{label.runningNr}</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{label.line}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{label.printerName}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{label.runningNr}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{format(label.upd_date, "M/d/yyyy hh:mm")}
|
||||
</TableCell>
|
||||
<TableCell className="font-medium">{label.status}</TableCell>
|
||||
<TableCell className="font-medium">
|
||||
{label.status}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
import {LstCard} from "@/components/extendedUI/LstCard";
|
||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
|
||||
import {Skeleton} from "@/components/ui/skeleton";
|
||||
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
|
||||
import {useSessionStore} from "@/lib/store/sessionStore";
|
||||
import {useSettingStore} from "@/lib/store/useSettings";
|
||||
import {LotType} from "@/types/lots";
|
||||
import {getlots} from "@/utils/querys/production/lots";
|
||||
import {useQuery} from "@tanstack/react-query";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { useSessionStore } from "@/lib/store/sessionStore";
|
||||
import { useSettingStore } from "@/lib/store/useSettings";
|
||||
import { LotType } from "@/types/lots";
|
||||
import { getlots } from "@/utils/querys/production/lots";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import ManualPrint from "./ManualPrinting/ManualPrint";
|
||||
import ManualPrintForm from "./ManualPrinting/ManualPrintForm";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
|
||||
let lotColumns = [
|
||||
{
|
||||
@@ -57,12 +65,12 @@ let lotColumns = [
|
||||
// },
|
||||
];
|
||||
export default function Lots() {
|
||||
const {data, isError, isLoading} = useQuery(getlots());
|
||||
const {user} = useSessionStore();
|
||||
const {settings} = useSettingStore();
|
||||
const { data, isError, isLoading } = useQuery(getlots());
|
||||
const { user } = useSessionStore();
|
||||
const { settings } = useSettingStore();
|
||||
const server = settings.filter((n) => n.name === "server")[0]?.value || "";
|
||||
|
||||
console.log(server);
|
||||
console.log(data);
|
||||
|
||||
const roles = ["admin", "manager", "operator"];
|
||||
|
||||
@@ -83,140 +91,167 @@ export default function Lots() {
|
||||
if (isError) {
|
||||
return (
|
||||
<div className="m-2 p-2 min-h-2/5">
|
||||
<LstCard>
|
||||
<p className="text-center">Current Assigned lots</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{lotColumns.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<ScrollArea className="max-h-1/2 rounded-md border p-4">
|
||||
<LstCard>
|
||||
<p className="text-center">Current Assigned lots</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{lotColumns.map((l) => (
|
||||
<TableHead key={l.key}>
|
||||
{l.label}
|
||||
</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</LstCard>
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</LstCard>
|
||||
</ScrollArea>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LstCard className="m-2 p-2 min-h-2/5">
|
||||
<p className="text-center">Current Assigned lots</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{lotColumns.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<ScrollArea className="h-[400px]">
|
||||
<p className="text-center">Current Assigned lots</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{lotColumns.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</>
|
||||
) : (
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
{data?.map((lot: LotType) => (
|
||||
<TableRow key={lot.LabelOnlineID}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
{lot.MachineLocation}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.AV}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.Alias}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.LOT}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.ProlinkLot}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.PlannedQTY}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.Produced}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.Remaining}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
<TableCell className="font-medium">
|
||||
{lot.overPrinting}
|
||||
</TableCell>
|
||||
{user && roles.includes(user.role) && (
|
||||
<>
|
||||
{server === "usday1vms006" ||
|
||||
server === "localhost" ? (
|
||||
<>
|
||||
<TableCell className="flex justify-center">
|
||||
<ManualPrintForm
|
||||
lot={lot}
|
||||
/>
|
||||
</TableCell>
|
||||
</>
|
||||
) : (
|
||||
<TableCell className="flex justify-center">
|
||||
<ManualPrint lot={lot} />
|
||||
</TableCell>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</>
|
||||
) : (
|
||||
<TableBody>
|
||||
{data?.map((lot: LotType) => (
|
||||
<TableRow key={lot.LabelOnlineID}>
|
||||
<TableCell className="font-medium">{lot.MachineLocation}</TableCell>
|
||||
<TableCell className="font-medium">{lot.AV}</TableCell>
|
||||
<TableCell className="font-medium">{lot.Alias}</TableCell>
|
||||
<TableCell className="font-medium">{lot.LOT}</TableCell>
|
||||
<TableCell className="font-medium">{lot.ProlinkLot}</TableCell>
|
||||
<TableCell className="font-medium">{lot.PlannedQTY}</TableCell>
|
||||
<TableCell className="font-medium">{lot.Produced}</TableCell>
|
||||
<TableCell className="font-medium">{lot.Remaining}</TableCell>
|
||||
<TableCell className="font-medium">{lot.overPrinting}</TableCell>
|
||||
{user && roles.includes(user.role) && (
|
||||
<>
|
||||
{server === "usday1vms006" || server === "localhost" ? (
|
||||
<>
|
||||
<TableCell className="flex justify-center">
|
||||
<ManualPrintForm lot={lot} />
|
||||
</TableCell>
|
||||
</>
|
||||
) : (
|
||||
<TableCell className="flex justify-center">
|
||||
<ManualPrint lot={lot} />
|
||||
</TableCell>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
)}
|
||||
</Table>
|
||||
)}
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
</LstCard>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import WrapperManualTrigger from "@/components/ocme/WrapperCard";
|
||||
import LabelLog from "./LabelLog";
|
||||
import Lots from "./Lots";
|
||||
import OcpLogs from "./OcpLogs";
|
||||
import PrinterStatus from "./PrinterStatus";
|
||||
import { useSettingStore } from "@/lib/store/useSettings";
|
||||
|
||||
export default function OCPPage() {
|
||||
const { settings } = useSettingStore();
|
||||
|
||||
const server = settings.filter((n) => n.plantToken === "usday1");
|
||||
return (
|
||||
<div className="h-dvh w-full overflow-hidden">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
@@ -21,8 +26,15 @@ export default function OCPPage() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-1/6">
|
||||
<PrinterStatus />
|
||||
<div className="w-1/6 flex flex-col">
|
||||
{server && (
|
||||
<div>
|
||||
<WrapperManualTrigger />
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<PrinterStatus />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import {LstCard} from "@/components/extendedUI/LstCard";
|
||||
import {Skeleton} from "@/components/ui/skeleton";
|
||||
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
|
||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
|
||||
let printerCols = [
|
||||
{
|
||||
@@ -19,34 +27,37 @@ let printerCols = [
|
||||
export default function PrinterStatus() {
|
||||
return (
|
||||
<LstCard className="m-2 p-2">
|
||||
<p className="text-center">Printer Status</p>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{printerCols.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<ScrollArea className="max-h-[300px]">
|
||||
<p className="text-center">Printer Status</p>
|
||||
|
||||
<TableBody>
|
||||
{Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
{printerCols.map((l) => (
|
||||
<TableHead key={l.key}>{l.label}</TableHead>
|
||||
))}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{Array(5)
|
||||
.fill(0)
|
||||
.map((_, i) => (
|
||||
<TableRow key={i}>
|
||||
<TableCell className="font-medium">
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Skeleton className="h-4" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</ScrollArea>
|
||||
</LstCard>
|
||||
);
|
||||
}
|
||||
|
||||
56
frontend/src/components/ui/scroll-area.tsx
Normal file
56
frontend/src/components/ui/scroll-area.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import * as React from "react"
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
function ScrollArea({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.Root
|
||||
data-slot="scroll-area"
|
||||
className={cn("relative", className)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
data-slot="scroll-area-viewport"
|
||||
className="ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] focus-visible:ring-4 focus-visible:outline-1"
|
||||
>
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
<ScrollBar />
|
||||
<ScrollAreaPrimitive.Corner />
|
||||
</ScrollAreaPrimitive.Root>
|
||||
)
|
||||
}
|
||||
|
||||
function ScrollBar({
|
||||
className,
|
||||
orientation = "vertical",
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||
data-slot="scroll-area-scrollbar"
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"flex touch-none p-px transition-colors select-none",
|
||||
orientation === "vertical" &&
|
||||
"h-full w-2.5 border-l border-l-transparent",
|
||||
orientation === "horizontal" &&
|
||||
"h-2.5 flex-col border-t border-t-transparent",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.ScrollAreaThumb
|
||||
data-slot="scroll-area-thumb"
|
||||
className="bg-border relative flex-1 rounded-full"
|
||||
/>
|
||||
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
)
|
||||
}
|
||||
|
||||
export { ScrollArea, ScrollBar }
|
||||
@@ -1,4 +1,4 @@
|
||||
import {queryOptions} from "@tanstack/react-query";
|
||||
import { queryOptions } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
|
||||
export function getlabels(hours: string) {
|
||||
@@ -13,7 +13,7 @@ export function getlabels(hours: string) {
|
||||
}
|
||||
|
||||
const fetchSettings = async (hours: string) => {
|
||||
const {data} = await axios.get(`/api/v1/ocp/labels?hours=${hours}`);
|
||||
const { data } = await axios.get(`/api/ocp/getlabels?hours=${hours}`);
|
||||
// if we are not localhost ignore the devDir setting.
|
||||
//const url: string = window.location.host.split(":")[0];
|
||||
return data.data ?? [];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {queryOptions} from "@tanstack/react-query";
|
||||
import { queryOptions } from "@tanstack/react-query";
|
||||
import axios from "axios";
|
||||
|
||||
export function getlots() {
|
||||
@@ -13,7 +13,7 @@ export function getlots() {
|
||||
}
|
||||
|
||||
const fetchSettings = async () => {
|
||||
const {data} = await axios.get("/api/v1/ocp/lots");
|
||||
const { data } = await axios.get("/api/ocp/getlots");
|
||||
// if we are not localhost ignore the devDir setting.
|
||||
//const url: string = window.location.host.split(":")[0];
|
||||
let lotData = data.data;
|
||||
|
||||
365
package-lock.json
generated
365
package-lock.json
generated
@@ -1,25 +1,28 @@
|
||||
{
|
||||
"name": "lstv2",
|
||||
"version": "2.9.0",
|
||||
"version": "2.10.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "lstv2",
|
||||
"version": "2.9.0",
|
||||
"version": "2.10.0",
|
||||
"dependencies": {
|
||||
"@dotenvx/dotenvx": "^1.39.0",
|
||||
"@hono/node-server": "^1.14.0",
|
||||
"@hono/zod-openapi": "^0.19.2",
|
||||
"@scalar/hono-api-reference": "^0.7.2",
|
||||
"@types/jsonwebtoken": "^9.0.9",
|
||||
"@types/nodemailer-express-handlebars": "^4.0.5",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.8.4",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"date-fns": "^4.1.0",
|
||||
"drizzle-kit": "^0.30.5",
|
||||
"drizzle-orm": "^0.41.0",
|
||||
"drizzle-zod": "^0.7.0",
|
||||
"fast-xml-parser": "^5.0.9",
|
||||
"fs-extra": "^11.3.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mssql": "^11.0.1",
|
||||
"nodemailer": "^6.10.0",
|
||||
@@ -30,6 +33,7 @@
|
||||
"pino-pretty": "^13.0.0",
|
||||
"postgres": "^3.4.5",
|
||||
"rimraf": "^6.0.1",
|
||||
"st-ethernet-ip": "^2.7.3",
|
||||
"ws": "^8.18.1",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
@@ -40,12 +44,11 @@
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/mssql": "^9.1.7",
|
||||
"@types/node": "^22.13.11",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/pg": "^8.11.11",
|
||||
"@types/ws": "^8.18.0",
|
||||
"concurrently": "^9.1.2",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"drizzle-kit": "^0.30.5",
|
||||
"fs-extra": "^11.3.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"tsx": "^4.19.3",
|
||||
"typescript": "^5.8.2"
|
||||
@@ -520,7 +523,6 @@
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
|
||||
"integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@ecies/ciphers": {
|
||||
@@ -542,7 +544,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz",
|
||||
"integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==",
|
||||
"deprecated": "Merged into tsx: https://tsx.is",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "~0.18.20",
|
||||
@@ -556,7 +557,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -573,7 +573,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -590,7 +589,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -607,7 +605,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -624,7 +621,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -641,7 +637,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -658,7 +653,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -675,7 +669,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -692,7 +685,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -709,7 +701,6 @@
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -726,7 +717,6 @@
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -743,7 +733,6 @@
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -760,7 +749,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -777,7 +765,6 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -794,7 +781,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -811,7 +797,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -828,7 +813,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -845,7 +829,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -862,7 +845,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -879,7 +861,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -896,7 +877,6 @@
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -913,7 +893,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -927,7 +906,6 @@
|
||||
"version": "0.18.20",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
|
||||
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
@@ -966,7 +944,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz",
|
||||
"integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==",
|
||||
"deprecated": "Merged into tsx: https://tsx.is",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@esbuild-kit/core-utils": "^3.3.2",
|
||||
@@ -980,7 +957,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -997,7 +973,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1014,7 +989,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1031,7 +1005,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1048,7 +1021,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1065,7 +1037,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1082,7 +1053,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1099,7 +1069,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1116,7 +1085,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1133,7 +1101,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1150,7 +1117,6 @@
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1167,7 +1133,6 @@
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1184,7 +1149,6 @@
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1201,7 +1165,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1218,7 +1181,6 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1235,7 +1197,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1252,7 +1213,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1286,7 +1246,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1320,7 +1279,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1337,7 +1295,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1354,7 +1311,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1371,7 +1327,6 @@
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1388,7 +1343,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1592,7 +1546,6 @@
|
||||
"version": "3.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.9.2.tgz",
|
||||
"integrity": "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog==",
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@scalar/core": {
|
||||
@@ -1682,6 +1635,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/express-handlebars": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-handlebars/-/express-handlebars-5.3.1.tgz",
|
||||
"integrity": "sha512-DSzaERLO4gHb8AqnrL58jzSDyT0yDdl6HqDc+bGz1Hf0nrG1FK30nHGzv8NBEGR8QV9eUGB/YaE0Qj3NjF7siw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/fs-extra": {
|
||||
"version": "11.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
|
||||
@@ -1754,6 +1713,25 @@
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/nodemailer": {
|
||||
"version": "6.4.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.17.tgz",
|
||||
"integrity": "sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/nodemailer-express-handlebars": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/nodemailer-express-handlebars/-/nodemailer-express-handlebars-4.0.5.tgz",
|
||||
"integrity": "sha512-SuSYGNQPGtgMkDlQTO7zacXDENqQR3QXW1Ip5PvvookodvUKCbNVRF1tisY3Bgew1h8Wjfsf6dPQ5E45pJ1bJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/express-handlebars": "^5",
|
||||
"@types/nodemailer": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/normalize-package-data": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
|
||||
@@ -2085,7 +2063,6 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bundle-name": {
|
||||
@@ -2113,6 +2090,24 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
|
||||
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.0",
|
||||
"es-define-property": "^1.0.0",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
@@ -2126,6 +2121,22 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bound": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"get-intrinsic": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
@@ -2993,7 +3004,6 @@
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
||||
"integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
@@ -3060,6 +3070,26 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deep-equal": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz",
|
||||
"integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-arguments": "^1.1.1",
|
||||
"is-date-object": "^1.0.5",
|
||||
"is-regex": "^1.1.4",
|
||||
"object-is": "^1.1.5",
|
||||
"object-keys": "^1.1.1",
|
||||
"regexp.prototype.flags": "^1.5.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/default-browser": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
|
||||
@@ -3101,6 +3131,23 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/define-lazy-prop": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
|
||||
@@ -3113,6 +3160,23 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/define-properties": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
|
||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
"object-keys": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -3261,7 +3325,6 @@
|
||||
"version": "0.30.5",
|
||||
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.30.5.tgz",
|
||||
"integrity": "sha512-l6dMSE100u7sDaTbLczibrQZjA35jLsHNqIV+jmhNVO3O8jzM6kywMOmV9uOz9ZVSCMPQhAZEFjL/qDPVrqpUA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@drizzle-team/brocli": "^0.10.2",
|
||||
@@ -3536,7 +3599,6 @@
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
|
||||
"integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
@@ -3575,7 +3637,6 @@
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz",
|
||||
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
@@ -3894,7 +3955,6 @@
|
||||
"version": "11.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
|
||||
"integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
@@ -3936,11 +3996,19 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/functions-have-names": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
|
||||
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gel": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gel/-/gel-2.0.1.tgz",
|
||||
"integrity": "sha512-gfem3IGvqKqXwEq7XseBogyaRwGsQGuE7Cw/yQsjLGdgiyqX92G1xENPCE0ltunPGcsJIa6XBOTx/PK169mOqw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@petamoriken/float16": "^3.8.7",
|
||||
@@ -3961,7 +4029,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
|
||||
"integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
@@ -3974,7 +4041,6 @@
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
|
||||
"integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
|
||||
"devOptional": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
@@ -3984,7 +4050,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
|
||||
"integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
|
||||
"devOptional": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^3.1.1"
|
||||
@@ -4122,7 +4187,6 @@
|
||||
"version": "4.10.0",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
|
||||
"integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
@@ -4381,6 +4445,18 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
@@ -4724,6 +4800,31 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/int64-buffer": {
|
||||
"version": "0.99.1007",
|
||||
"resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.99.1007.tgz",
|
||||
"integrity": "sha512-XDBEu44oSTqlvCSiOZ/0FoUkpWu/vwjJLGSKDabNISPQNZ5wub1FodGHBljRsrR0IXRPq7SslshZYMuA55CgTQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arguments": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
|
||||
"integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
@@ -4747,6 +4848,22 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-date-object": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
|
||||
"integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-docker": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
|
||||
@@ -4852,6 +4969,24 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-regex": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
|
||||
"integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"gopd": "^1.2.0",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
@@ -5030,7 +5165,6 @@
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
@@ -5817,6 +5951,31 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/object-is": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
|
||||
"integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.7",
|
||||
"define-properties": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/object-treeify": {
|
||||
"version": "1.1.33",
|
||||
"resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz",
|
||||
@@ -6757,6 +6916,26 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/regexp.prototype.flags": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
|
||||
"integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.8",
|
||||
"define-properties": "^1.2.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"set-function-name": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
@@ -6828,7 +7007,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||
@@ -6965,6 +7143,38 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-name": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
|
||||
"integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"functions-have-names": "^1.2.3",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@@ -6990,7 +7200,6 @@
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
|
||||
"integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -7033,7 +7242,6 @@
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
@@ -7105,6 +7313,18 @@
|
||||
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/st-ethernet-ip": {
|
||||
"version": "2.7.3",
|
||||
"resolved": "https://registry.npmjs.org/st-ethernet-ip/-/st-ethernet-ip-2.7.3.tgz",
|
||||
"integrity": "sha512-pc7cjrLwlZGzezuqEThensjk8o9lvI73xlNf4Ufzsfl51Akfe8Td9RdQJPWaAjaCCYV3h0pgRp5NrudgKCMBww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dateformat": "^3.0.3",
|
||||
"deep-equal": "^1.1.1",
|
||||
"int64-buffer": "^0.99.1007",
|
||||
"task-easy": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/standard-version": {
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz",
|
||||
@@ -7306,6 +7526,12 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/task-easy": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/task-easy/-/task-easy-0.2.1.tgz",
|
||||
"integrity": "sha512-VMYezcVhfyaTkc3cWf4sSQG6YgYBdiNCAg4iXuUWRGB7tp7A/rZA9Nter0ZIG5chSoidLS0VWf87koFD9XHwDg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tedious": {
|
||||
"version": "18.6.1",
|
||||
"resolved": "https://registry.npmjs.org/tedious/-/tedious-18.6.1.tgz",
|
||||
@@ -7988,7 +8214,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
|
||||
16
package.json
16
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "lstv2",
|
||||
"version": "2.9.0",
|
||||
"version": "2.10.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "concurrently -n \"server,frontend\" -c \"#007755,#2f6da3\" \"npm run dev:server\" \"cd frontend && npm run dev\"",
|
||||
@@ -9,7 +9,7 @@
|
||||
"dev:dbgen": " drizzle-kit generate --config=drizzle-dev.config.ts",
|
||||
"dev:dbmigrate": " drizzle-kit migrate --config=drizzle-dev.config.ts",
|
||||
"build": "npm run build:server && npm run build:frontend",
|
||||
"build:server": "rimraf dist && tsc --build && npm run copy:scripts",
|
||||
"build:server": "rimraf dist && tsc --build && npm run copy:scripts && xcopy server\\services\\notifications\\utils\\views\\ dist\\server\\services\\notifications\\utils\\views\\ /E /I /Y",
|
||||
"build:frontend": "cd frontend && npm run build",
|
||||
"copy:scripts": "tsx server/scripts/copyScripts.ts",
|
||||
"copy:servers": "xcopy server\\services\\server\\utils\\serverData.json dist\\server\\services\\server\\utils /E /I /Y",
|
||||
@@ -21,7 +21,8 @@
|
||||
"deploy": "standard-version --conventional-commits && npm run prodBuild",
|
||||
"zipServer": "dotenvx run -f .env -- tsx server/scripts/zipUpBuild.ts \"C:\\Users\\matthes01\\Documents\\lstv2\"",
|
||||
"v1Build": "cd C:\\Users\\matthes01\\Documents\\logisticsSupportTool && npm run oldBuilder",
|
||||
"prodBuild": "npm run v1Build && powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2\" && npm run zipServer",
|
||||
"scriptBuild": "powershell -ExecutionPolicy Bypass -File server/scripts/build.ps1 -dir \"C:\\Users\\matthes01\\Documents\\lstv2-dev\"",
|
||||
"prodBuild": "npm run v1Build && npm run zipServer",
|
||||
"commit": "cz",
|
||||
"prodinstall": "npm i --omit=dev && npm run db:migrate",
|
||||
"checkupdates": "npx npm-check-updates"
|
||||
@@ -32,7 +33,7 @@
|
||||
}
|
||||
},
|
||||
"admConfig": {
|
||||
"build": 50,
|
||||
"build": 93,
|
||||
"oldBuild": "backend-0.1.3.zip"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -42,12 +43,11 @@
|
||||
"@types/js-cookie": "^3.0.6",
|
||||
"@types/mssql": "^9.1.7",
|
||||
"@types/node": "^22.13.11",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/pg": "^8.11.11",
|
||||
"@types/ws": "^8.18.0",
|
||||
"concurrently": "^9.1.2",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"drizzle-kit": "^0.30.5",
|
||||
"fs-extra": "^11.3.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"tsx": "^4.19.3",
|
||||
"typescript": "^5.8.2"
|
||||
@@ -58,13 +58,16 @@
|
||||
"@hono/zod-openapi": "^0.19.2",
|
||||
"@scalar/hono-api-reference": "^0.7.2",
|
||||
"@types/jsonwebtoken": "^9.0.9",
|
||||
"@types/nodemailer-express-handlebars": "^4.0.5",
|
||||
"adm-zip": "^0.5.16",
|
||||
"axios": "^1.8.4",
|
||||
"bcryptjs": "^3.0.2",
|
||||
"date-fns": "^4.1.0",
|
||||
"drizzle-kit": "^0.30.5",
|
||||
"drizzle-orm": "^0.41.0",
|
||||
"drizzle-zod": "^0.7.0",
|
||||
"fast-xml-parser": "^5.0.9",
|
||||
"fs-extra": "^11.3.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mssql": "^11.0.1",
|
||||
"nodemailer": "^6.10.0",
|
||||
@@ -75,6 +78,7 @@
|
||||
"pino-pretty": "^13.0.0",
|
||||
"postgres": "^3.4.5",
|
||||
"rimraf": "^6.0.1",
|
||||
"st-ethernet-ip": "^2.7.3",
|
||||
"ws": "^8.18.1",
|
||||
"zod": "^3.24.2"
|
||||
}
|
||||
|
||||
170
server/index.ts
170
server/index.ts
@@ -1,12 +1,12 @@
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
import { serve } from "@hono/node-server";
|
||||
import { OpenAPIHono } from "@hono/zod-openapi";
|
||||
import { proxy } from "hono/proxy";
|
||||
|
||||
import { serveStatic } from "@hono/node-server/serve-static";
|
||||
import { logger } from "hono/logger";
|
||||
import { cors } from "hono/cors";
|
||||
import { createLog } from "./services/logger/logger.js";
|
||||
import { WebSocketServer } from "ws";
|
||||
|
||||
// custom routes
|
||||
import scalar from "./services/general/route/scalar.js";
|
||||
import system from "./services/server/systemServer.js";
|
||||
@@ -21,7 +21,10 @@ import loggerService from "./services/logger/loggerService.js";
|
||||
import ocpService from "./services/ocp/ocpService.js";
|
||||
import { db } from "../database/dbclient.js";
|
||||
import { settings } from "../database/schema/settings.js";
|
||||
import { count } from "drizzle-orm";
|
||||
import os from "os";
|
||||
import { tryCatch } from "./globalUtils/tryCatch.js";
|
||||
import { sendEmail } from "./services/notifications/controller/sendMail.js";
|
||||
import notify from "./services/notifications/notifyService.js";
|
||||
|
||||
// create the main prodlogin here
|
||||
const username = "lst_user";
|
||||
@@ -29,66 +32,78 @@ const password = "Alpla$$Prod";
|
||||
export const lstAuth = btoa(`${username}:${password}`);
|
||||
|
||||
// checking to make sure we have the settings intialized
|
||||
const serverIntialized = await db.select({ count: count() }).from(settings);
|
||||
const { data: settingsData, error: settingError } = await tryCatch(
|
||||
db.select().from(settings)
|
||||
);
|
||||
|
||||
if (settingError) {
|
||||
throw Error("Error getting settings from the db. critical error.");
|
||||
}
|
||||
|
||||
const serverIntialized: any = settingsData;
|
||||
export const installed =
|
||||
serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development"
|
||||
? false
|
||||
: true;
|
||||
serverIntialized.length === 0 && process.env.NODE_ENV !== "development"
|
||||
? false
|
||||
: true;
|
||||
createLog("info", "LST", "server", `Server is installed: ${installed}`);
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
// middle ware
|
||||
app.use("*", logger());
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
app.use("*", logger());
|
||||
}
|
||||
|
||||
app.use(
|
||||
"*",
|
||||
cors({
|
||||
origin: "*", // Allow all origins
|
||||
allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
|
||||
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
|
||||
//exposeHeaders: ["Content-Length", "X-Kuma-Revision"],
|
||||
credentials: true, // Allow credentials if needed
|
||||
maxAge: 600,
|
||||
})
|
||||
"*",
|
||||
cors({
|
||||
origin: "*", // Allow all origins
|
||||
allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
|
||||
allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
|
||||
//exposeHeaders: ["Content-Length", "X-Kuma-Revision"],
|
||||
credentials: true, // Allow credentials if needed
|
||||
maxAge: 600,
|
||||
})
|
||||
);
|
||||
|
||||
// Middleware to normalize route case
|
||||
app.use("*", async (c, next) => {
|
||||
const lowercasedUrl = c.req.url.toLowerCase();
|
||||
//console.log("Incoming Request:", c.req.url, c.req.method);
|
||||
// If the URL is already lowercase, continue as usual
|
||||
if (c.req.url === lowercasedUrl) {
|
||||
return next();
|
||||
}
|
||||
// app.use("*", async (c, next) => {
|
||||
// // const lowercasedUrl = c.req.url.toLowerCase();
|
||||
// console.log("Incoming Request:", c.req.url, c.req.method);
|
||||
// // // If the URL is already lowercase, continue as usual
|
||||
// // if (c.req.url === lowercasedUrl) {
|
||||
// await next();
|
||||
// // }
|
||||
|
||||
// Otherwise, re-route internally
|
||||
return c.redirect(lowercasedUrl, 308); // 308 preserves the HTTP method
|
||||
});
|
||||
// // // Otherwise, re-route internally
|
||||
// // return c.redirect(lowercasedUrl, 308); // 308 preserves the HTTP method
|
||||
// });
|
||||
|
||||
app.doc("/api/ref", {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
version: "2.0.0",
|
||||
title: "LST API",
|
||||
},
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
version: "2.0.0",
|
||||
title: "LST API",
|
||||
},
|
||||
});
|
||||
|
||||
const routes = [
|
||||
scalar,
|
||||
auth,
|
||||
// apiHits,
|
||||
system,
|
||||
tcpServer,
|
||||
sqlService,
|
||||
logistics,
|
||||
rfid,
|
||||
printers,
|
||||
loggerService,
|
||||
ocpService,
|
||||
scalar,
|
||||
auth,
|
||||
// apiHits,
|
||||
system,
|
||||
tcpServer,
|
||||
sqlService,
|
||||
logistics,
|
||||
rfid,
|
||||
printers,
|
||||
loggerService,
|
||||
ocpService,
|
||||
notify,
|
||||
] as const;
|
||||
|
||||
const appRoutes = routes.forEach((route) => {
|
||||
app.route("/api/", route);
|
||||
app.route("/api/", route);
|
||||
});
|
||||
|
||||
app.route("/ocme/", ocme);
|
||||
@@ -129,48 +144,59 @@ app.use("*", serveStatic({ path: "./frontend/dist/index.html" }));
|
||||
|
||||
// Handle app exit signals
|
||||
process.on("SIGINT", async () => {
|
||||
console.log("\nGracefully shutting down...");
|
||||
//await closePool();
|
||||
process.exit(0);
|
||||
console.log("\nGracefully shutting down...");
|
||||
//await closePool();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on("SIGTERM", async () => {
|
||||
console.log("Received termination signal, closing database...");
|
||||
//await closePool();
|
||||
process.exit(0);
|
||||
console.log("Received termination signal, closing database...");
|
||||
//await closePool();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
process.on("uncaughtException", async (err) => {
|
||||
console.log("Uncaught Exception:", err);
|
||||
//await closePool();
|
||||
process.exit(1);
|
||||
console.log("Uncaught Exception:", err);
|
||||
//await closePool();
|
||||
const emailData = {
|
||||
email: "blake.matthes@alpla.com", // should be moved to the db so it can be reused.
|
||||
subject: `${os.hostname()} has just encountered a crash.`,
|
||||
template: "serverCrash",
|
||||
context: {
|
||||
error: err,
|
||||
plant: `${os.hostname()}`,
|
||||
},
|
||||
};
|
||||
|
||||
await sendEmail(emailData);
|
||||
//process.exit(1);
|
||||
});
|
||||
|
||||
process.on("beforeExit", async () => {
|
||||
console.log("Process is about to exit...");
|
||||
//await closePool();
|
||||
process.exit(0);
|
||||
console.log("Process is about to exit...");
|
||||
//await closePool();
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
const port =
|
||||
process.env.NODE_ENV === "development"
|
||||
? process.env.VITE_SERVER_PORT
|
||||
: process.env.PROD_PORT;
|
||||
process.env.NODE_ENV === "development"
|
||||
? process.env.VITE_SERVER_PORT
|
||||
: process.env.PROD_PORT;
|
||||
|
||||
serve(
|
||||
{
|
||||
fetch: app.fetch,
|
||||
port: Number(port),
|
||||
hostname: "0.0.0.0",
|
||||
},
|
||||
(info) => {
|
||||
createLog(
|
||||
"info",
|
||||
"LST",
|
||||
"server",
|
||||
`Server is running on http://${info.address}:${info.port}`
|
||||
);
|
||||
}
|
||||
{
|
||||
fetch: app.fetch,
|
||||
port: Number(port),
|
||||
hostname: "0.0.0.0",
|
||||
},
|
||||
(info) => {
|
||||
createLog(
|
||||
"info",
|
||||
"LST",
|
||||
"server",
|
||||
`Server is running on http://${info.address}:${info.port}`
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export type AppRoutes = typeof appRoutes;
|
||||
|
||||
@@ -415,10 +415,10 @@ try {
|
||||
Start-Service -DisplayName $serviceLstV2
|
||||
Start-Sleep -Seconds 1
|
||||
Write-Host "$($server) finished updating"
|
||||
if($token -eq "usday1"){
|
||||
Write-Host "Starting $($serviceOcme)"
|
||||
Start-Service -DisplayName $serviceOcme
|
||||
}
|
||||
# if($token -eq "usday1"){
|
||||
# Write-Host "Starting $($serviceOcme)"
|
||||
# Start-Service -DisplayName $serviceOcme
|
||||
# }
|
||||
|
||||
}
|
||||
Invoke-Command -ComputerName $server -ScriptBlock $plantFunness -ArgumentList $server, $token, $location, $buildZip, $buildLoc, $obslst, $obsBuild -Credential $credentials
|
||||
@@ -1,21 +1,24 @@
|
||||
import {spawn} from "child_process";
|
||||
import {getAppInfo} from "../globalUtils/appInfo.js";
|
||||
import {db} from "../../database/dbclient.js";
|
||||
import {serverData} from "../../database/schema/serverData.js";
|
||||
import {eq, sql} from "drizzle-orm";
|
||||
import {createLog} from "../services/logger/logger.js";
|
||||
import { spawn } from "child_process";
|
||||
import { getAppInfo } from "../globalUtils/appInfo.js";
|
||||
import { db } from "../../database/dbclient.js";
|
||||
import { serverData } from "../../database/schema/serverData.js";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { createLog } from "../services/logger/logger.js";
|
||||
|
||||
type UpdateServerResponse = {
|
||||
success: boolean;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export const updateServer = async (devApp: string, server: string | null): Promise<UpdateServerResponse> => {
|
||||
export const updateServer = async (
|
||||
devApp: string,
|
||||
server: string | null
|
||||
): Promise<UpdateServerResponse> => {
|
||||
const app = await getAppInfo(devApp);
|
||||
const serverInfo = await db
|
||||
.select()
|
||||
.from(serverData)
|
||||
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
|
||||
.select()
|
||||
.from(serverData)
|
||||
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
|
||||
|
||||
if (serverInfo.length === 0) {
|
||||
createLog(
|
||||
@@ -26,7 +29,8 @@ export const updateServer = async (devApp: string, server: string | null): Promi
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: "Looks like you are missing the plant token or have entered an incorrect one please try again.",
|
||||
message:
|
||||
"Looks like you are missing the plant token or have entered an incorrect one please try again.",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -77,9 +81,9 @@ export const updateServer = async (devApp: string, server: string | null): Promi
|
||||
const process = spawn("powershell", args);
|
||||
// change the server to upgradeing
|
||||
await db
|
||||
.update(serverData)
|
||||
.set({isUpgrading: true})
|
||||
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
|
||||
.update(serverData)
|
||||
.set({ isUpgrading: true })
|
||||
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
|
||||
//let stdout = "";
|
||||
//let stderr = "";
|
||||
|
||||
@@ -108,9 +112,14 @@ export const updateServer = async (devApp: string, server: string | null): Promi
|
||||
//update the last build.
|
||||
try {
|
||||
await db
|
||||
.update(serverData)
|
||||
.set({lastUpdated: sql`NOW()`, isUpgrading: false})
|
||||
.where(eq(serverData.plantToken, server?.toLowerCase() ?? ""));
|
||||
.update(serverData)
|
||||
.set({ lastUpdated: sql`NOW()`, isUpgrading: false })
|
||||
.where(
|
||||
eq(
|
||||
serverData.plantToken,
|
||||
server?.toLowerCase() ?? ""
|
||||
)
|
||||
);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
@@ -156,17 +165,35 @@ export const updateServer = async (devApp: string, server: string | null): Promi
|
||||
export async function processAllServers(devApp: string) {
|
||||
const servers = await db.select().from(serverData);
|
||||
|
||||
createLog("info", "lst", "serverUpdater", `Running the update on all servers`);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"serverUpdater",
|
||||
`Running the update on all servers`
|
||||
);
|
||||
let count = 1;
|
||||
for (const server of servers) {
|
||||
try {
|
||||
const updateToServer = await updateServer(devApp, server.plantToken);
|
||||
createLog("info", "lst", "serverUpdater", `${server.sName} was updated.`);
|
||||
const updateToServer = await updateServer(
|
||||
devApp,
|
||||
server.plantToken
|
||||
);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"serverUpdater",
|
||||
`${server.sName} was updated.`
|
||||
);
|
||||
count = count + 1;
|
||||
|
||||
//return {success: true, message: `${server.sName} was updated.`, data: updateToServer};
|
||||
} catch (error: any) {
|
||||
createLog("info", "lst", "serverUpdater", `Error updating ${server.sName}: ${error.message}`);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"serverUpdater",
|
||||
`Error updating ${server.sName}: ${error.message}`
|
||||
);
|
||||
//return {success: false, message: `Error updating ${server.sName}: ${error.message}`};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ const updateBuildNumber = (appLock: string) => {
|
||||
// Auto-commit changes
|
||||
execSync("git add package.json");
|
||||
execSync(
|
||||
`git commit -m "build: bump build number to ${pkgJson.admConfig.build}"`
|
||||
`git commit -m "chore(release): bump build number to ${pkgJson.admConfig.build}"`
|
||||
);
|
||||
} else {
|
||||
createLog(
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
|
||||
export const sendEmail = async () => {
|
||||
createLog("info", "lst", "general", "Preparing to send an email");
|
||||
|
||||
// settings
|
||||
};
|
||||
102
server/services/logistics/controller/returnMaterial.ts
Normal file
102
server/services/logistics/controller/returnMaterial.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { ConsoleLogWriter } from "drizzle-orm";
|
||||
import { prodEndpointCreation } from "../../../globalUtils/createUrl.js";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { query } from "../../sqlServer/prodSqlServer.js";
|
||||
import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js";
|
||||
import axios from "axios";
|
||||
import { laneInfo } from "../../sqlServer/querys/materialHelpers/laneInfo.js";
|
||||
import { tryCatch } from "../../../globalUtils/tryCatch.js";
|
||||
|
||||
type Data = {
|
||||
runningNr: string;
|
||||
laneName: string;
|
||||
};
|
||||
export const returnMaterial = async (data: Data, prod: any) => {
|
||||
const { runningNr, laneName } = data;
|
||||
// replace the rn
|
||||
const rnReplace = labelData.replaceAll("[rn]", runningNr);
|
||||
|
||||
// get the lane id by name
|
||||
const laneQuery = laneInfo.replaceAll("[laneName]", laneName);
|
||||
|
||||
let barcode;
|
||||
// get the barcode from the running number
|
||||
try {
|
||||
barcode = await query(rnReplace, "labelData");
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
createLog(
|
||||
"error",
|
||||
prod.user.username,
|
||||
"logistics",
|
||||
`Error getting barcode: ${error}`
|
||||
);
|
||||
}
|
||||
|
||||
const { data: laneData, error: laneError } = await tryCatch(
|
||||
query(laneQuery, "laneInfo")
|
||||
);
|
||||
|
||||
if (laneError) {
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
"The lane you entered is either deactivated or dose not exist.",
|
||||
laneError,
|
||||
};
|
||||
}
|
||||
|
||||
if (!laneData) {
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
"The lane you entered is either deactivated or dose not exist.",
|
||||
};
|
||||
}
|
||||
|
||||
if (laneData.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
"The lane you entered is either deactivated or dose not exist.",
|
||||
};
|
||||
}
|
||||
|
||||
if (barcode.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "The running number you've is not in stock.",
|
||||
};
|
||||
//throw Error("The provided runningNr is not in stock");
|
||||
}
|
||||
// create the url to post
|
||||
const url = await prodEndpointCreation(
|
||||
"/public/v1.0/IssueMaterial/ReturnPartiallyConsumedManualMaterial"
|
||||
);
|
||||
|
||||
const returnSomething = {
|
||||
laneId: laneData[0]?.laneID,
|
||||
barcode: barcode[0]?.barcode,
|
||||
};
|
||||
|
||||
try {
|
||||
const results = await axios.post(url, returnSomething, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Basic ${prod.user.prod}`,
|
||||
},
|
||||
});
|
||||
//console.log(results);
|
||||
return {
|
||||
success: true,
|
||||
message: "Material was returned",
|
||||
status: results.status,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
success: false,
|
||||
status: 200,
|
||||
message: error.response?.data.errors[0].message,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,9 +1,10 @@
|
||||
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
import { OpenAPIHono } from "@hono/zod-openapi";
|
||||
|
||||
import comsumeMaterial from "./route/consumeMaterial.js";
|
||||
import returnMat from "./route/returnMaterial.js";
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const routes = [comsumeMaterial] as const;
|
||||
const routes = [comsumeMaterial, returnMat] as const;
|
||||
|
||||
// app.route("/server", modules);
|
||||
const appRoutes = routes.forEach((route) => {
|
||||
|
||||
70
server/services/logistics/route/returnMaterial.ts
Normal file
70
server/services/logistics/route/returnMaterial.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { authMiddleware } from "../../auth/middleware/authMiddleware.js";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
import { verify } from "hono/jwt";
|
||||
import { returnMaterial } from "../controller/returnMaterial.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const responseSchema = z.object({
|
||||
success: z.boolean().optional().openapi({ example: true }),
|
||||
message: z.string().optional().openapi({ example: "user access" }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["logistics"],
|
||||
summary: "Retrns material based on its running number and laneName",
|
||||
method: "post",
|
||||
path: "/return",
|
||||
middleware: authMiddleware,
|
||||
description:
|
||||
"Provided a running number and Lane to return the material.",
|
||||
responses: {
|
||||
200: {
|
||||
content: { "application/json": { schema: responseSchema } },
|
||||
description: "stopped",
|
||||
},
|
||||
400: {
|
||||
content: { "application/json": { schema: responseSchema } },
|
||||
description: "Failed to stop",
|
||||
},
|
||||
401: {
|
||||
content: { "application/json": { schema: responseSchema } },
|
||||
description: "Failed to stop",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
apiHit(c, { endpoint: "api/sqlProd/close" });
|
||||
const authHeader = c.req.header("Authorization");
|
||||
const token = authHeader?.split("Bearer ")[1] || "";
|
||||
|
||||
try {
|
||||
const payload = await verify(token, process.env.JWT_SECRET!);
|
||||
try {
|
||||
//return apiReturn(c, true, access?.message, access?.data, 200);
|
||||
const data = await c.req.json();
|
||||
const consume = await returnMaterial(data, payload);
|
||||
return c.json(
|
||||
{ success: consume?.success, message: consume?.message },
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
//console.log(error);
|
||||
//return apiReturn(c, false, "Error in setting the user access", error, 400);
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "Missing data please try again",
|
||||
error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
return c.json({ success: false, message: "Unauthorized" }, 401);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
144
server/services/notifications/controller/sendMail.ts
Normal file
144
server/services/notifications/controller/sendMail.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import { tryCatch } from "../../../globalUtils/tryCatch.js";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../database/schema/settings.js";
|
||||
import nodemailer from "nodemailer";
|
||||
import type { Transporter } from "nodemailer";
|
||||
import type SMTPTransport from "nodemailer/lib/smtp-transport/index.js";
|
||||
import type Mail from "nodemailer/lib/mailer/index.js";
|
||||
import type { Address } from "nodemailer/lib/mailer/index.js";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import hbs from "nodemailer-express-handlebars";
|
||||
import { promisify } from "util";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
|
||||
interface HandlebarsMailOptions extends Mail.Options {
|
||||
template: string;
|
||||
context: Record<string, unknown>; // Use a generic object for context
|
||||
}
|
||||
|
||||
interface EmailData {
|
||||
email: string;
|
||||
subject: string;
|
||||
template: string;
|
||||
context: [];
|
||||
}
|
||||
|
||||
export const sendEmail = async (data: any): Promise<any> => {
|
||||
let transporter: Transporter;
|
||||
let fromEmail: string | Address;
|
||||
const { data: settingData, error: settingError } = await tryCatch(
|
||||
db.select().from(settings)
|
||||
);
|
||||
|
||||
if (settingError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error getting the settings.",
|
||||
settingError,
|
||||
};
|
||||
}
|
||||
// get the plantToken
|
||||
const server = settingData.filter((n) => n.name === "server");
|
||||
|
||||
if (
|
||||
server[0].value === "localhost" &&
|
||||
process.env.EMAIL_USER &&
|
||||
process.env.EMAIL_PASSWORD
|
||||
) {
|
||||
transporter = nodemailer.createTransport({
|
||||
service: "gmail",
|
||||
auth: {
|
||||
user: process.env.EMAIL_USER,
|
||||
pass: process.env.EMAIL_PASSWORD,
|
||||
},
|
||||
//debug: true,
|
||||
});
|
||||
|
||||
// update the from email
|
||||
fromEmail = process.env.EMAIL_USER;
|
||||
} else {
|
||||
// convert to the correct plant token.
|
||||
const plantToken = settingData.filter((s) => s.name === "plantToken");
|
||||
|
||||
let host = `${plantToken[0].value}-smtp.alpla.net`;
|
||||
|
||||
const testServers = ["test1", "test2", "test3"];
|
||||
|
||||
if (testServers.includes(plantToken[0].value)) {
|
||||
host = "USMCD1-smtp.alpla.net";
|
||||
}
|
||||
|
||||
if (plantToken[0].value === "usiow2") {
|
||||
host = "USIOW1-smtp.alpla.net";
|
||||
}
|
||||
|
||||
transporter = nodemailer.createTransport({
|
||||
host: host,
|
||||
port: 25,
|
||||
rejectUnauthorized: false,
|
||||
//secure: false,
|
||||
// auth: {
|
||||
// user: "alplaprod",
|
||||
// pass: "obelix",
|
||||
// },
|
||||
debug: true,
|
||||
} as SMTPTransport.Options);
|
||||
|
||||
// update the from email
|
||||
fromEmail = `noreply@alpla.com`;
|
||||
}
|
||||
|
||||
// creating the handlbar options
|
||||
const viewPath = path.resolve(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
"../utils/views/"
|
||||
);
|
||||
|
||||
const handlebarOptions = {
|
||||
viewEngine: {
|
||||
extname: ".hbs",
|
||||
//layoutsDir: path.resolve(viewPath, "layouts"), // Path to layouts directory
|
||||
defaultLayout: "", // Specify the default layout
|
||||
partialsDir: viewPath,
|
||||
},
|
||||
viewPath: viewPath,
|
||||
extName: ".hbs", // File extension for Handlebars templates
|
||||
};
|
||||
|
||||
transporter.use("compile", hbs(handlebarOptions));
|
||||
|
||||
const mailOptions: HandlebarsMailOptions = {
|
||||
from: fromEmail,
|
||||
to: data.email,
|
||||
subject: data.subject,
|
||||
//text: "You will have a reset token here and only have 30min to click the link before it expires.",
|
||||
//html: emailTemplate("BlakesTest", "This is an example with css"),
|
||||
template: data.template, // Name of the Handlebars template (e.g., 'welcome.hbs')
|
||||
context: data.context,
|
||||
};
|
||||
|
||||
// now verify and send the email
|
||||
const sendMailPromise = promisify(transporter.sendMail).bind(transporter);
|
||||
|
||||
try {
|
||||
// Send email and await the result
|
||||
const info = await sendMailPromise(mailOptions);
|
||||
createLog(
|
||||
"info",
|
||||
"notification",
|
||||
"system",
|
||||
`Email was sent to: ${data.email}`
|
||||
);
|
||||
return { success: true, message: "Email sent.", data: info };
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
createLog(
|
||||
"error",
|
||||
"notification",
|
||||
"system",
|
||||
`Error sending Email: ${JSON.stringify(err)}`
|
||||
);
|
||||
return { success: false, message: "Error sending email.", error: err };
|
||||
}
|
||||
};
|
||||
19
server/services/notifications/notifyService.ts
Normal file
19
server/services/notifications/notifyService.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { OpenAPIHono } from "@hono/zod-openapi";
|
||||
|
||||
import sendemail from "./routes/sendMail.js";
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const routes = [sendemail] as const;
|
||||
|
||||
const appRoutes = routes.forEach((route) => {
|
||||
app.route("/notify", route);
|
||||
});
|
||||
|
||||
app.all("/notify/*", (c) => {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "you have encounted a notication route that dose not exist.",
|
||||
});
|
||||
});
|
||||
|
||||
export default app;
|
||||
73
server/services/notifications/routes/sendMail.ts
Normal file
73
server/services/notifications/routes/sendMail.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
// an external way to creating logs
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { responses } from "../../../globalUtils/routeDefs/responses.js";
|
||||
import { authMiddleware } from "../../auth/middleware/authMiddleware.js";
|
||||
import { sendEmail } from "../controller/sendMail.js";
|
||||
import { tryCatch } from "../../../globalUtils/tryCatch.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
const EmailSchema = z
|
||||
.object({
|
||||
email: z.string().email().openapi({ example: "smith@example.come" }),
|
||||
subject: z.string().openapi({ example: "Welcome to LST" }),
|
||||
template: z.string().openapi({ example: "exampleTemplate" }),
|
||||
context: z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
score: z.string().optional(),
|
||||
})
|
||||
.optional()
|
||||
.openapi({}),
|
||||
})
|
||||
.openapi("User");
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["server"],
|
||||
summary: "Returns current active lots that are tech released",
|
||||
method: "post",
|
||||
path: "/sendmail",
|
||||
middleware: authMiddleware,
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": { schema: EmailSchema },
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
const { data: bodyData, error: bodyError } = await tryCatch(
|
||||
c.req.json()
|
||||
);
|
||||
if (bodyError) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "There was an error sending the email",
|
||||
data: bodyError,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
const { data: emailData, error: emailError } = await tryCatch(
|
||||
sendEmail(bodyData)
|
||||
);
|
||||
|
||||
if (emailError) {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "There was an error sending the email",
|
||||
data: emailError,
|
||||
});
|
||||
}
|
||||
|
||||
return c.json({
|
||||
success: emailData.success,
|
||||
message: emailData.message,
|
||||
data: emailData.data,
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
33
server/services/notifications/utils/views/exampleEmail.hbs
Normal file
33
server/services/notifications/utils/views/exampleEmail.hbs
Normal file
@@ -0,0 +1,33 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Order Summary</title>
|
||||
{{> styles}}
|
||||
{{!-- <link rel="stylesheet" href="styles/styles.css" /> --}}
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{name}}, your Order Summary</h1>
|
||||
<p>All,
|
||||
This is an example of the test email
|
||||
</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Item Name</th>
|
||||
<th>Quantity</th>
|
||||
<th>Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each items}}
|
||||
<tr>
|
||||
<td>{{name}}</td>
|
||||
<td>{{quantity}}</td>
|
||||
<td>{{price}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
35
server/services/notifications/utils/views/serverCrash.hbs
Normal file
35
server/services/notifications/utils/views/serverCrash.hbs
Normal file
@@ -0,0 +1,35 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
{{!--<title>Order Summary</title> --}}
|
||||
{{> styles}}
|
||||
<style>
|
||||
pre {
|
||||
background-color: #f8f9fa;
|
||||
color: #d63384;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
white-space: pre-wrap;
|
||||
font-family: monospace;
|
||||
}
|
||||
</style>
|
||||
{{!-- <link rel="stylesheet" href="styles/styles.css" /> --}}
|
||||
</head>
|
||||
<body>
|
||||
<h3>{{plant}},<br/> Has encountered an unexpected error.</h1>
|
||||
<p>
|
||||
Please see below the stack error from the crash.
|
||||
</p>
|
||||
<hr/>
|
||||
<div>
|
||||
<h3>Error Message: </h3>
|
||||
<p>{{error.message}}</p>
|
||||
</div>
|
||||
<hr/>
|
||||
<div>
|
||||
<h3>Stack trace</h3>
|
||||
<pre>{{{error.stack}}}</pre>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
6
server/services/notifications/utils/views/styles.hbs
Normal file
6
server/services/notifications/utils/views/styles.hbs
Normal file
@@ -0,0 +1,6 @@
|
||||
<style>
|
||||
table { width: 100%; background-color: #ffffff; border-collapse: collapse;
|
||||
border-width: 2px; border-color: #14BDEA; border-style: solid; color:
|
||||
#000000; } th, td { border: 1px solid #ddd; padding: 8px; } th {
|
||||
background-color: #f4f4f4; }
|
||||
</style>
|
||||
@@ -0,0 +1,19 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
{{!--<title>Order Summary</title> --}}
|
||||
{{> styles}}
|
||||
{{!-- <link rel="stylesheet" href="styles/styles.css" /> --}}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>All,<br/>
|
||||
There has been {{count}} manual prints in the last {{hours}}.<br/>
|
||||
Please consider checking the reason for this.<br/>
|
||||
Thank you,<br/>
|
||||
LST
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,9 +3,14 @@ import axios from "axios";
|
||||
export const ocmeInv = async (data: any) => {
|
||||
try {
|
||||
const res = await axios.post(
|
||||
"http://usday1vms010:3250/api/v1/getLaneData",
|
||||
{lane: data.lane, laneType: data.laneType},
|
||||
{headers: {"Content-Type": "application/json", Connection: "keep-alive"}}
|
||||
"http://usday1vms010:3250/api/v1/getlanedata",
|
||||
{ lane: data.lane, laneType: data.laneType },
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Connection: "keep-alive",
|
||||
},
|
||||
}
|
||||
);
|
||||
// console.log(res.data.data);
|
||||
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {ocmeData} from "../../../../database/schema/ocme.js";
|
||||
import {differenceInMinutes} from "date-fns";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { ocmeData } from "../../../../database/schema/ocme.js";
|
||||
import { differenceInMinutes } from "date-fns";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export const getInfo = async () => {
|
||||
let ocmeInfo: any = [];
|
||||
try {
|
||||
ocmeInfo = await db.select().from(ocmeData).where(eq(ocmeData.pickedUp, false));
|
||||
ocmeInfo = await db
|
||||
.select()
|
||||
.from(ocmeData)
|
||||
.where(eq(ocmeData.pickedUp, false));
|
||||
|
||||
// add in the time difference
|
||||
ocmeInfo = ocmeInfo.map((o: any) => {
|
||||
const now = new Date(Date.now());
|
||||
const diff = differenceInMinutes(now, o.add_Date!);
|
||||
return {...o, waitingFor: diff};
|
||||
//const strippedDate = o.add_Date.replace("Z", "");
|
||||
const diff = differenceInMinutes(now, o.add_Date);
|
||||
return { ...o, waitingFor: diff };
|
||||
});
|
||||
createLog("info", "ocme", "ocme", `There are ${ocmeInfo.length} pallet(s) to be picked up.`);
|
||||
createLog(
|
||||
"debug",
|
||||
"ocme",
|
||||
"ocme",
|
||||
`There are ${ocmeInfo.length} pallet(s) to be picked up.`
|
||||
);
|
||||
} catch (error) {
|
||||
createLog("error", "ocme", "ocme", "There was an error trying to retrive the ocmeInfo.");
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
"There was an error trying to retrive the ocmeInfo."
|
||||
);
|
||||
throw Error("There was an error trying to retrive the.");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +1,76 @@
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {ocmeData} from "../../../../database/schema/ocme.js";
|
||||
import {createSSCC} from "../../../globalUtils/createSSCC.js";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
import {query} from "../../sqlServer/prodSqlServer.js";
|
||||
import {labelData} from "../../sqlServer/querys/materialHelpers/labelInfo.js";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { ocmeData } from "../../../../database/schema/ocme.js";
|
||||
import { createSSCC } from "../../../globalUtils/createSSCC.js";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { query } from "../../sqlServer/prodSqlServer.js";
|
||||
import { labelData } from "../../sqlServer/querys/materialHelpers/labelInfo.js";
|
||||
|
||||
export const postLabelData = async (data: any) => {
|
||||
// if we have sscc we will do everything here and ignore the rn even it its sent over
|
||||
if (data.sscc && !data.runningNr) {
|
||||
data.runningNr = data.sscc.slice(10, -1);
|
||||
console.log(data);
|
||||
let newData = data;
|
||||
if (Array.isArray(data)) {
|
||||
newData = {
|
||||
sscc: data[1],
|
||||
areaFrom: data[0],
|
||||
completed: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (!data.sscc && !data.runningNr) {
|
||||
// data.runningNr = data.sscc.slice(10, -1);
|
||||
return {success: false, message: "Missing data please try again", data: []};
|
||||
if (newData.sscc && !newData.runningNr) {
|
||||
newData.runningNr = newData.sscc.slice(10, -1);
|
||||
}
|
||||
if (!newData.sscc && !newData.runningNr) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Missing data please try again",
|
||||
data: [],
|
||||
};
|
||||
}
|
||||
|
||||
let label;
|
||||
const filterQuery = labelData.replaceAll("[rn]", data.runningNr);
|
||||
|
||||
const filterQuery = labelData.replaceAll("[rn]", newData.runningNr);
|
||||
try {
|
||||
label = await query(filterQuery, "Label data");
|
||||
} catch (error) {
|
||||
createLog("error", "ocme", "ocme", "There was an error getting the labelData");
|
||||
createLog(
|
||||
"error",
|
||||
"ocme",
|
||||
"ocme",
|
||||
"There was an error getting the labelData"
|
||||
);
|
||||
}
|
||||
const newPost = {
|
||||
sscc: data.sscc ? data.sscc : await createSSCC(data.runningNr),
|
||||
runningNr: data.runningNr,
|
||||
completed: data.completed,
|
||||
lineNum: label[0].machineLocation,
|
||||
areaFrom: data.areaFrom,
|
||||
sscc: newData.sscc ? newData.sscc : await createSSCC(newData.runningNr),
|
||||
runningNr: newData.runningNr,
|
||||
completed: newData.completed ? newData.completed : true,
|
||||
lineNum: label[0]?.machineLocation,
|
||||
areaFrom: newData.areaFrom,
|
||||
pickedUp: false,
|
||||
};
|
||||
|
||||
try {
|
||||
const enterNewData = await db.insert(ocmeData).values(newPost).returning({sscc: ocmeData.sscc});
|
||||
return {success: true, message: "Data was posted to ocme info", data: enterNewData};
|
||||
const enterNewData = await db
|
||||
.insert(ocmeData)
|
||||
.values(newPost)
|
||||
.returning({
|
||||
sscc: ocmeData.sscc,
|
||||
runningNr: ocmeData.runningNr,
|
||||
areaFrom: ocmeData.areaFrom,
|
||||
lineNum: ocmeData.lineNum,
|
||||
completed: ocmeData.completed,
|
||||
pickedUp: ocmeData.pickedUp,
|
||||
});
|
||||
|
||||
//console.log(enterNewData);
|
||||
return {
|
||||
success: true,
|
||||
message: "Data was posted to ocme info",
|
||||
data: enterNewData,
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {success: false, message: "Data was posted to ocme info", data: newPost};
|
||||
//console.log(error);
|
||||
return {
|
||||
success: false,
|
||||
message: "Data was posted to ocme info",
|
||||
data: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
56
server/services/ocme/controller/triggerCamera.ts
Normal file
56
server/services/ocme/controller/triggerCamera.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import net from "net";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../database/schema/settings.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
|
||||
export const triggerScanner = async () => {
|
||||
const camera = new net.Socket();
|
||||
let setting = await db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, "zebraScanners"));
|
||||
if (setting.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Looks like the setting is missing.",
|
||||
};
|
||||
}
|
||||
const scannerData = JSON.parse(setting[0]?.value);
|
||||
let data = scannerData.filter((n: any) => n.name === "wrapper1");
|
||||
|
||||
if (data.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "Looks like the scanner is missing.",
|
||||
};
|
||||
}
|
||||
let port = data[0]?.port;
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
"wrapperScanner",
|
||||
"ocme",
|
||||
`End of line Camera was triggered`
|
||||
);
|
||||
return new Promise((resolve, reject) => {
|
||||
camera.connect(port, data[0].ip, async () => {
|
||||
createLog("info", "wrapperScanner", "ocme", `Triggered`);
|
||||
camera.write("TRIGGER", "utf8");
|
||||
camera.end();
|
||||
resolve({ success: true, message: "Camera was triggered." });
|
||||
});
|
||||
|
||||
camera.on("error", (error) => {
|
||||
createLog("error", "wrapperScanner", "ocme", `${error}`);
|
||||
resolve({
|
||||
success: false,
|
||||
message: `There was an error triggering the camera: ${JSON.stringify(
|
||||
error
|
||||
)}`,
|
||||
});
|
||||
});
|
||||
|
||||
resolve({ success: true, message: "Camera was triggered." });
|
||||
});
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
import { OpenAPIHono } from "@hono/zod-openapi";
|
||||
|
||||
// routes
|
||||
import getInfo from "./route/getInfo.js";
|
||||
@@ -7,35 +7,52 @@ import pickedup from "./route/pickedUp.js";
|
||||
import postsscc from "./route/postSSCC.js";
|
||||
import getShipments from "./route/getShipmentPallets.js";
|
||||
import cycleCount from "./route/cycleCount.js";
|
||||
import {serve} from "@hono/node-server";
|
||||
import {createLog} from "../logger/logger.js";
|
||||
import {db} from "../../../database/dbclient.js";
|
||||
import {settings} from "../../../database/schema/settings.js";
|
||||
import { serve } from "@hono/node-server";
|
||||
import { createLog } from "../logger/logger.js";
|
||||
import { db } from "../../../database/dbclient.js";
|
||||
import { settings } from "../../../database/schema/settings.js";
|
||||
import manualTrigger from "./route/triggerCamera.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
const port = process.env.OCME_PORT;
|
||||
const routes = [getInfo, postRunningNr, postsscc, pickedup, getShipments, cycleCount] as const;
|
||||
const routes = [
|
||||
getInfo,
|
||||
postRunningNr,
|
||||
postsscc,
|
||||
pickedup,
|
||||
getShipments,
|
||||
cycleCount,
|
||||
manualTrigger,
|
||||
] as const;
|
||||
const setting = await db.select().from(settings);
|
||||
|
||||
const isActive = setting.filter((n) => n.name === "ocmeService");
|
||||
const appRoutes = routes.forEach((route) => {
|
||||
app.route("/api/v1", route);
|
||||
app.route("/api/v1", route);
|
||||
});
|
||||
|
||||
app.all("/api/v1/*", (c) => {
|
||||
return c.json({success: false, message: "you have encounted an ocme route that dose not exist."});
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "you have encounted an ocme route that dose not exist.",
|
||||
});
|
||||
});
|
||||
if (port && isActive[0]?.value === "1") {
|
||||
serve(
|
||||
{
|
||||
fetch: app.fetch,
|
||||
port: Number(port),
|
||||
hostname: "0.0.0.0",
|
||||
},
|
||||
(info) => {
|
||||
createLog("info", "LST", "server", `Ocme section is listening on http://${info.address}:${info.port}`);
|
||||
}
|
||||
);
|
||||
serve(
|
||||
{
|
||||
fetch: app.fetch,
|
||||
port: Number(port),
|
||||
hostname: "0.0.0.0",
|
||||
},
|
||||
(info) => {
|
||||
createLog(
|
||||
"info",
|
||||
"LST",
|
||||
"server",
|
||||
`Ocme section is listening on http://${info.address}:${info.port}`
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default app;
|
||||
|
||||
@@ -1,60 +1,71 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import {responses} from "../../../globalUtils/routeDefs/responses.js";
|
||||
import {authMiddleware} from "../../auth/middleware/authMiddleware.js";
|
||||
import {cycleCount} from "../controller/cycleCount.js";
|
||||
import type {User} from "../../../types/users.js";
|
||||
import {verify} from "hono/jwt";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
import { responses } from "../../../globalUtils/routeDefs/responses.js";
|
||||
import { authMiddleware } from "../../auth/middleware/authMiddleware.js";
|
||||
import { cycleCount } from "../controller/cycleCount.js";
|
||||
import type { User } from "../../../types/users.js";
|
||||
import { verify } from "hono/jwt";
|
||||
|
||||
const app = new OpenAPIHono({strict: false});
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
const AddSetting = z.object({
|
||||
lane: z.string().openapi({example: "L064"}),
|
||||
lane: z.string().openapi({ example: "L064" }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Cycle counts a lane based on the lane Alias",
|
||||
method: "post",
|
||||
path: "/cyclecount",
|
||||
middleware: authMiddleware,
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: AddSetting},
|
||||
},
|
||||
},
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Cycle counts a lane based on the lane Alias",
|
||||
method: "post",
|
||||
path: "/cycleCount",
|
||||
middleware: authMiddleware,
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": { schema: AddSetting },
|
||||
},
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
apiHit(c, {endpoint: "api/auth/register"});
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
const body = await c.req.json();
|
||||
},
|
||||
},
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
apiHit(c, { endpoint: "api/auth/register" });
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
const body = await c.req.json();
|
||||
|
||||
const authHeader = c.req.header("Authorization");
|
||||
const authHeader = c.req.header("Authorization");
|
||||
|
||||
const token = authHeader?.split("Bearer ")[1] || "";
|
||||
let user: User;
|
||||
const token = authHeader?.split("Bearer ")[1] || "";
|
||||
let user: User;
|
||||
|
||||
try {
|
||||
const payload = await verify(token, process.env.JWT_SECRET!);
|
||||
user = payload.user as User;
|
||||
} catch (error) {
|
||||
return c.json({message: "Unauthorized"}, 401);
|
||||
}
|
||||
|
||||
try {
|
||||
const cycleData = await cycleCount(body, user);
|
||||
return c.json({success: true, message: `${body.lane} was just cycle counted.`, data: cycleData}, 200);
|
||||
} catch (error) {
|
||||
return c.json(
|
||||
{success: false, message: `There was an error cycle counting ${body.lane}`, data: error},
|
||||
400
|
||||
);
|
||||
}
|
||||
try {
|
||||
const payload = await verify(token, process.env.JWT_SECRET!);
|
||||
user = payload.user as User;
|
||||
} catch (error) {
|
||||
return c.json({ message: "Unauthorized" }, 401);
|
||||
}
|
||||
|
||||
try {
|
||||
const cycleData = await cycleCount(body, user);
|
||||
return c.json(
|
||||
{
|
||||
success: true,
|
||||
message: `${body.lane} was just cycle counted.`,
|
||||
data: cycleData,
|
||||
},
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: `There was an error cycle counting ${body.lane}`,
|
||||
data: error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
|
||||
@@ -1,80 +1,36 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {getInfo} from "../controller/getInfo.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { getInfo } from "../controller/getInfo.js";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
import { responses } from "../../../globalUtils/routeDefs/responses.js";
|
||||
|
||||
const app = new OpenAPIHono({strict: false});
|
||||
|
||||
const AddSetting = z.object({
|
||||
name: z.string().openapi({example: "server"}),
|
||||
value: z.string().openapi({example: "localhost"}),
|
||||
description: z.string().openapi({example: "The server we are going to connect to"}),
|
||||
roles: z.string().openapi({example: "admin"}),
|
||||
module: z.string().openapi({example: "production"}),
|
||||
});
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Get all current info",
|
||||
method: "get",
|
||||
path: "/getinfo",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: AddSetting},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
path: "/getInfo",
|
||||
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
apiHit(c, {endpoint: "api/auth/register"});
|
||||
apiHit(c, { endpoint: "api/auth/register" });
|
||||
try {
|
||||
return c.json({success: true, message: "Ocme Info", data: await getInfo()}, 200);
|
||||
return c.json(
|
||||
{ success: true, message: "Ocme Info", data: await getInfo() },
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400);
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "There was an error getting ocmeInfo data",
|
||||
data: error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,94 +1,114 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import {getShipmentPallets} from "../controller/getShipmentPallets.js";
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
import { getShipmentPallets } from "../controller/getShipmentPallets.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const ShipmentID = z.object({
|
||||
shipmentID: z.string().optional().openapi({example: "14558"}),
|
||||
shipmentID: z.string().optional().openapi({ example: "14558" }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/getshipmentpallets",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: ShipmentID},
|
||||
},
|
||||
},
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/GetShipmentPallets",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": { schema: ShipmentID },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: true }),
|
||||
message: z.string().openapi({ example: "Starter" }),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/getshipmentpallets", lastBody: data});
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: false }),
|
||||
message: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Internal Server error" }),
|
||||
data: z.array(z.object({})).optional().openapi({ example: [] }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, { endpoint: "api/ocme/getshipmentpallets", lastBody: data });
|
||||
|
||||
if (!data.shipmentID) {
|
||||
return c.json(
|
||||
{success: false, message: "You are missing the shipment id please try again.", data: []},
|
||||
400
|
||||
);
|
||||
}
|
||||
console.log;
|
||||
|
||||
const shiptmentData = await getShipmentPallets(data.shipmentID);
|
||||
if (!data.shipmentID) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "You are missing the shipment id please try again.",
|
||||
data: [],
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
|
||||
return c.json(
|
||||
{success: shiptmentData.success, message: shiptmentData.message, data: shiptmentData.data ?? []},
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting the shipment data.", data: error}, 400);
|
||||
}
|
||||
const shiptmentData = await getShipmentPallets(data.shipmentID);
|
||||
|
||||
return c.json(
|
||||
{
|
||||
success: shiptmentData.success,
|
||||
message: shiptmentData.message,
|
||||
data: shiptmentData.data ?? [],
|
||||
},
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "There was an error getting the shipment data.",
|
||||
data: error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
|
||||
@@ -1,89 +1,114 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {postLabelData} from "../controller/postRunningNr.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import {pickedup} from "../controller/pickedup.js";
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { postLabelData } from "../controller/postRunningNr.js";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
import { pickedup } from "../controller/pickedup.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const PostRunningNr = z.object({
|
||||
sscc: z.string().optional().openapi({example: "00090103830005710997"}),
|
||||
runningNr: z.string().optional().openapi({example: "localhost"}),
|
||||
areaFrom: z.string().optional().openapi({example: "The server we are going to connect to"}),
|
||||
completed: z.boolean().optional().openapi({example: true}),
|
||||
all: z.boolean().optional().openapi({example: false}),
|
||||
sscc: z.string().optional().openapi({ example: "00090103830005710997" }),
|
||||
runningNr: z.string().optional().openapi({ example: "localhost" }),
|
||||
areaFrom: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "The server we are going to connect to" }),
|
||||
completed: z.boolean().optional().openapi({ example: true }),
|
||||
all: z.boolean().optional().openapi({ example: false }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Picks up a pallet in the system.",
|
||||
method: "patch",
|
||||
description:
|
||||
"removes the pallet(s) from showing as needed to be picked up, we clear everything related to the pallet number to reduce the risk of a mix, passing `all` will just clear everything that is pending.",
|
||||
path: "/pickedup",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: PostRunningNr},
|
||||
},
|
||||
},
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Picks up a pallet in the system.",
|
||||
method: "patch",
|
||||
description:
|
||||
"removes the pallet(s) from showing as needed to be picked up, we clear everything related to the pallet number to reduce the risk of a mix, passing `all` will just clear everything that is pending.",
|
||||
path: "/pickedUp",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": { schema: PostRunningNr },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
500: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: true }),
|
||||
message: z.string().openapi({ example: "Starter" }),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/pickedup", lastBody: data});
|
||||
const postPallet = await pickedup(data);
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data}, 200);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400);
|
||||
}
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: false }),
|
||||
message: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Internal Server error" }),
|
||||
data: z.array(z.object({})).optional().openapi({ example: [] }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
500: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
message: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Internal Server error" }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, { endpoint: "api/ocme/pickedup", lastBody: data });
|
||||
const postPallet = await pickedup(data);
|
||||
return c.json(
|
||||
{
|
||||
success: postPallet.success,
|
||||
message: postPallet.message,
|
||||
data: postPallet.data,
|
||||
},
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "There was an error getting ocmeInfo data",
|
||||
data: error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
|
||||
@@ -1,86 +1,106 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {getInfo} from "../controller/getInfo.js";
|
||||
import {postLabelData} from "../controller/postRunningNr.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { getInfo } from "../controller/getInfo.js";
|
||||
import { postLabelData } from "../controller/postRunningNr.js";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const PostRunningNr = z.object({
|
||||
sscc: z.string().optional().openapi({example: "00090103830005710997"}),
|
||||
runningNr: z.string().optional().openapi({example: "localhost"}),
|
||||
areaFrom: z.string().optional().openapi({example: "The server we are going to connect to"}),
|
||||
completed: z.boolean().optional().openapi({example: true}),
|
||||
sscc: z.string().optional().openapi({ example: "00090103830005710997" }),
|
||||
runningNr: z.string().optional().openapi({ example: "localhost" }),
|
||||
areaFrom: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "The server we are going to connect to" }),
|
||||
completed: z.boolean().optional().openapi({ example: true }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/postrunningnumber",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: PostRunningNr},
|
||||
},
|
||||
},
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/postRunningNumber",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": { schema: PostRunningNr },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: true }),
|
||||
message: z.string().openapi({ example: "Starter" }),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/postRunningNumber", lastBody: data});
|
||||
const postPallet = await postLabelData(data);
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data ?? []}, 200);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400);
|
||||
}
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: false }),
|
||||
message: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Internal Server error" }),
|
||||
data: z.array(z.object({})).optional().openapi({ example: [] }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, { endpoint: "api/ocme/postRunningNumber", lastBody: data });
|
||||
const postPallet = await postLabelData(data);
|
||||
return c.json(
|
||||
{
|
||||
success: postPallet.success,
|
||||
message: postPallet.message,
|
||||
data: postPallet.data ?? [],
|
||||
},
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "There was an error getting ocmeInfo data",
|
||||
data: error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
|
||||
@@ -1,86 +1,106 @@
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {getInfo} from "../controller/getInfo.js";
|
||||
import {postLabelData} from "../controller/postRunningNr.js";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { getInfo } from "../controller/getInfo.js";
|
||||
import { postLabelData } from "../controller/postRunningNr.js";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const PostRunningNr = z.object({
|
||||
sscc: z.string().optional().openapi({example: "00090103830005710997"}),
|
||||
runningNr: z.string().optional().openapi({example: "localhost"}),
|
||||
areaFrom: z.string().optional().openapi({example: "The server we are going to connect to"}),
|
||||
completed: z.boolean().optional().openapi({example: true}),
|
||||
sscc: z.string().optional().openapi({ example: "00090103830005710997" }),
|
||||
runningNr: z.string().optional().openapi({ example: "localhost" }),
|
||||
areaFrom: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "The server we are going to connect to" }),
|
||||
completed: z.boolean().optional().openapi({ example: true }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/postsscc",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": {schema: PostRunningNr},
|
||||
},
|
||||
},
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Post New running number to be picked up.",
|
||||
method: "post",
|
||||
path: "/postSSCC",
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
"application/json": { schema: PostRunningNr },
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: true}),
|
||||
message: z.string().openapi({example: "Starter"}),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({example: false}),
|
||||
message: z.string().optional().openapi({example: "Internal Server error"}),
|
||||
data: z.array(z.object({})).optional().openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: true }),
|
||||
message: z.string().openapi({ example: "Starter" }),
|
||||
// data: z
|
||||
// .array(z.object({sscc: z.string().optional()}))
|
||||
// .optional()
|
||||
// .openapi({example: []}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, {endpoint: "api/ocme/postRunningNumber", lastBody: data});
|
||||
const postPallet = await postLabelData(data);
|
||||
return c.json({success: postPallet.success, message: postPallet.message, data: postPallet.data ?? []}, 200);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error getting ocmeInfo data", data: error}, 400);
|
||||
}
|
||||
description: "Response message",
|
||||
},
|
||||
400: {
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: z.object({
|
||||
success: z.boolean().openapi({ example: false }),
|
||||
message: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Internal Server error" }),
|
||||
data: z.array(z.object({})).optional().openapi({ example: [] }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
description: "Internal Server Error",
|
||||
},
|
||||
// 401: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Unauthenticated"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Unauthorized",
|
||||
// },
|
||||
// 500: {
|
||||
// content: {
|
||||
// "application/json": {
|
||||
// schema: z.object({message: z.string().optional().openapi({example: "Internal Server error"})}),
|
||||
// },
|
||||
// },
|
||||
// description: "Internal Server Error",
|
||||
// },
|
||||
},
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
try {
|
||||
const data = await c.req.json();
|
||||
apiHit(c, { endpoint: "api/ocme/postRunningNumber", lastBody: data });
|
||||
const postPallet = await postLabelData(data);
|
||||
return c.json(
|
||||
{
|
||||
success: postPallet.success,
|
||||
message: postPallet.message,
|
||||
data: postPallet.data ?? [],
|
||||
},
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "There was an error getting ocmeInfo data",
|
||||
data: error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
|
||||
28
server/services/ocme/route/triggerCamera.ts
Normal file
28
server/services/ocme/route/triggerCamera.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { getInfo } from "../controller/getInfo.js";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
import { responses } from "../../../globalUtils/routeDefs/responses.js";
|
||||
import { triggerScanner } from "../controller/triggerCamera.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocme"],
|
||||
summary: "Triggers the camera at the end of the dyco.",
|
||||
method: "get",
|
||||
path: "/manualCameraTrigger",
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
// make sure we have a vaid user being accessed thats really logged in
|
||||
apiHit(c, { endpoint: "api/auth/register" });
|
||||
const manualTrigger: any = await triggerScanner();
|
||||
console.log(manualTrigger);
|
||||
return c.json({
|
||||
success: manualTrigger.success,
|
||||
message: manualTrigger.message,
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
89
server/services/ocp/controller/labeling/bookIn.ts
Normal file
89
server/services/ocp/controller/labeling/bookIn.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import axios from "axios";
|
||||
import { prodEndpointCreation } from "../../../../globalUtils/createUrl.js";
|
||||
import { lstAuth } from "../../../../index.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { prodlabels } from "../../../../../database/schema/prodLabels.js";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
|
||||
export const bookInLabel = async (data: any) => {
|
||||
// update sscc so we can book in
|
||||
const SSCC = data.SSCC.slice(2);
|
||||
// api url
|
||||
const url = await prodEndpointCreation("public/v1.0/Warehousing/BookIn");
|
||||
|
||||
// create bookin
|
||||
const newBookin = {
|
||||
scannerId: 777,
|
||||
sscc: SSCC,
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await axios.post(url, newBookin, {
|
||||
headers: {
|
||||
Authorization: `Basic ${lstAuth}`,
|
||||
accept: "text/plain",
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.Result !== 0) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${data.printer.name}, Error:${res.data.Message}`
|
||||
);
|
||||
//printerUpdate(data.printer, 7, "Error while booking in.");
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error booking in the label.",
|
||||
data: res.data,
|
||||
};
|
||||
}
|
||||
|
||||
// update the label.
|
||||
try {
|
||||
await db
|
||||
.update(prodlabels)
|
||||
.set({
|
||||
status: "Booked in",
|
||||
upd_date: sql`NOW()`,
|
||||
})
|
||||
.where(
|
||||
eq(prodlabels.runningNr, parseInt(data.SSCC.slice(10, -1)))
|
||||
);
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Error creating new runningNumber in the DB.`
|
||||
);
|
||||
}
|
||||
|
||||
// label was booked in
|
||||
createLog(
|
||||
"info",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${parseInt(data.SSCC.slice(10, -1))}, was just booked in`
|
||||
);
|
||||
return {
|
||||
success: true,
|
||||
message: `${parseInt(data.SSCC.slice(10, -1))}, was just booked in`,
|
||||
};
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${data.printer.name}, "Error: ${error}`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error booking in the label.",
|
||||
data: error,
|
||||
};
|
||||
}
|
||||
};
|
||||
158
server/services/ocp/controller/labeling/createLabel.ts
Normal file
158
server/services/ocp/controller/labeling/createLabel.ts
Normal file
@@ -0,0 +1,158 @@
|
||||
import { eq, gte, sql } from "drizzle-orm";
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { printers } from "../../../../../database/schema/printers.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import { prodEndpointCreation } from "../../../../globalUtils/createUrl.js";
|
||||
import { settings } from "../../../../../database/schema/settings.js";
|
||||
import { lstAuth } from "../../../../index.js";
|
||||
import axios from "axios";
|
||||
import { prodlabels } from "../../../../../database/schema/prodLabels.js";
|
||||
|
||||
export const createLabel = async (data: any, userPrinted: any) => {
|
||||
createLog("info", "labeling", "ocp", `Label being created`);
|
||||
|
||||
const { data: printer, error: printerError } = await tryCatch(
|
||||
db
|
||||
.select()
|
||||
.from(printers)
|
||||
.where(eq(printers.humanReadableId, data.printerID))
|
||||
);
|
||||
const { data: settingsData, error: settingsError } = await tryCatch(
|
||||
db.select().from(settings)
|
||||
);
|
||||
if (printerError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error getting the printer.",
|
||||
printerError,
|
||||
};
|
||||
}
|
||||
|
||||
if (settingsError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error getting the printer.",
|
||||
settingsError,
|
||||
};
|
||||
}
|
||||
|
||||
const url = await prodEndpointCreation(
|
||||
"/public/v1.0/Warehousing/GenerateAndPrintLabelExtended"
|
||||
);
|
||||
const plantToken = settingsData.filter((n) => n.name === "plantToken");
|
||||
const newLabel = {
|
||||
scannerId: 99,
|
||||
lotNr: data.LOT,
|
||||
machineId: data.machineID,
|
||||
printerId: data.printerID,
|
||||
//layoutId: cartonCustomers.includes(data.CustomerId.toString()) ? data.cartonLabel : data.palletLabel,
|
||||
layoutId:
|
||||
plantToken[0].value === "usksc1"
|
||||
? data.cartonLabel
|
||||
: data.palletLabel,
|
||||
//numberOfCopies: cartonCustomers.includes(data.CustomerId.toString()) ? data.cartonCopies : data.pallerCopies,
|
||||
numberOfCopies:
|
||||
plantToken[0].value === "usksc1"
|
||||
? data.cartonCopies
|
||||
: data.pallerCopies,
|
||||
};
|
||||
|
||||
// create the label
|
||||
// create the label with the data we have
|
||||
try {
|
||||
const res = await axios.post(url, newLabel, {
|
||||
headers: {
|
||||
Authorization: `Basic ${lstAuth}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
// error handling
|
||||
if (res.data.Result != 0) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${data.MachineDescription}, has an error while printing: Error: ${res.data.Message}.`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
mesasge: `${data.MachineDescription}, has an error while printing`,
|
||||
data: res.data,
|
||||
};
|
||||
}
|
||||
|
||||
// save the data to lst db (only saved for x time see the db clean up functions)
|
||||
let newlabel = res.data;
|
||||
|
||||
try {
|
||||
await db.insert(prodlabels).values({
|
||||
printerID: parseInt(printer[0]?.humanReadableId!, 10),
|
||||
runningNr: parseInt(newlabel.SSCC.slice(10, -1)),
|
||||
printerName: printer[0].name.toLowerCase(),
|
||||
line: data.MachineLocation,
|
||||
status: "printed",
|
||||
add_user: userPrinted || "LST_System",
|
||||
});
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Error creating new runningNumber in the DB.`
|
||||
);
|
||||
}
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`New label was created for: ${
|
||||
data.MachineDescription
|
||||
}, Running number: ${parseInt(newlabel.SSCC.slice(10, -1))}`
|
||||
);
|
||||
|
||||
const returnData = {
|
||||
...newlabel,
|
||||
printer,
|
||||
};
|
||||
|
||||
// check if we can remove labels or not
|
||||
deleteLabels();
|
||||
return { sucess: true, message: "Label created", data: returnData }; // returning label data to be able to book in if active
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"info",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${printer[0].name}, "Error: ${error}`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error creating the label",
|
||||
data: error,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// run the label delete process we want to delate them older than 90 days right now
|
||||
const deleteLabels = async () => {
|
||||
/**
|
||||
* Deletes labels older than 90 days from lst... all label data can be found in alpla prod.
|
||||
*/
|
||||
try {
|
||||
await db
|
||||
.delete(prodlabels)
|
||||
.where(
|
||||
gte(prodlabels.upd_date, sql.raw(`NOW() - INTERVAL '90 days'`))
|
||||
);
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Error deleting labels older than 90 days`
|
||||
);
|
||||
}
|
||||
};
|
||||
32
server/services/ocp/controller/labeling/getLabels.ts
Normal file
32
server/services/ocp/controller/labeling/getLabels.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { desc, lte, sql } from "drizzle-orm";
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { prodlabels } from "../../../../../database/schema/prodLabels.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
export const getLabels = async (hours: string) => {
|
||||
const { data: labelInfo, error: labelError } = await tryCatch(
|
||||
db
|
||||
.select()
|
||||
.from(prodlabels)
|
||||
.where(
|
||||
lte(
|
||||
prodlabels.upd_date,
|
||||
sql.raw(`NOW() - INTERVAL '${hours} hours'`)
|
||||
)
|
||||
)
|
||||
.orderBy(desc(prodlabels.upd_date))
|
||||
);
|
||||
|
||||
if (labelError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error getting the labels",
|
||||
data: [labelError],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "Current labels order by upd_Date.",
|
||||
data: labelInfo,
|
||||
};
|
||||
};
|
||||
236
server/services/ocp/controller/labeling/labelProcess.ts
Normal file
236
server/services/ocp/controller/labeling/labelProcess.ts
Normal file
@@ -0,0 +1,236 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { printers } from "../../../../../database/schema/printers.js";
|
||||
import { settings } from "../../../../../database/schema/settings.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import { getLots } from "../lots/lots.js";
|
||||
import { getMac } from "../specialProcesses/utils/getMachineId.js";
|
||||
import { billingCheck } from "../specialProcesses/billingCheck/billingCheck.js";
|
||||
import { isMainMatStaged } from "../materials/mainMaterial.js";
|
||||
import { firstLotLabel } from "../specialProcesses/lotChangeLabel/lotCHangeLabel.js";
|
||||
import { prolinkCheck } from "../lots/prolinkCheck.js";
|
||||
import { createLabel } from "./createLabel.js";
|
||||
import { bookInLabel } from "./bookIn.js";
|
||||
import { delieryInhouse } from "../specialProcesses/inhouse/inhouseDelivery.js";
|
||||
|
||||
interface Printer {
|
||||
name: string;
|
||||
// Add any other expected properties
|
||||
}
|
||||
|
||||
export const labelingProcess = async ({
|
||||
line = null as string | null,
|
||||
printer = null as Printer | null,
|
||||
userPrinted = null,
|
||||
rfidTag = null,
|
||||
} = {}) => {
|
||||
/**
|
||||
* Creates a label once all logic is passed
|
||||
*/
|
||||
let filteredLot: any = [];
|
||||
createLog("debug", "labeling", "ocp", `Starting labeling process`);
|
||||
const { data: settingData, error: settingError } = await tryCatch(
|
||||
db.select().from(settings)
|
||||
);
|
||||
|
||||
if (settingError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error getting the settings.",
|
||||
settingError,
|
||||
};
|
||||
}
|
||||
// get the plantToken
|
||||
const plantToken = settingData.filter((n) => n.name === "plantToken");
|
||||
|
||||
// get the current lots
|
||||
const lots = await getLots();
|
||||
|
||||
// if we got a line passed over we need to get the machine id from this.
|
||||
if (line) {
|
||||
const macId = await getMac(line);
|
||||
|
||||
// filter out the lot for the line
|
||||
filteredLot = lots.data.filter((l: any) => l.machineId === macId);
|
||||
|
||||
if (filteredLot.length === 0) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`There is not a lot assigned to ${macId[0].Name}.`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `There is not a lot assigned to ${macId[0].Name}.`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// if we came from a printer
|
||||
if (printer) {
|
||||
// filter the lot based on the printerID
|
||||
// console.log(printer);
|
||||
filteredLot = lots.data.filter((l: any) => l.printerID === printer);
|
||||
if (filteredLot.length === 0) {
|
||||
// console.log(`There is not a lot assigned to ${printer.name}`);
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`There is not a lot assigned to ${printer.name}`
|
||||
);
|
||||
//printerUpdate(printer, 7, `There is no lot assigned to this printer.`);
|
||||
return {
|
||||
success: false,
|
||||
message: `There is not a lot assigned to ${printer.name}.`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The checks we do before we can actually print a label will take place meow.
|
||||
*
|
||||
*/
|
||||
|
||||
// if the plant does not want to have dual printing and we have >2 assigned well return and send error.
|
||||
let dualPrinting = settingData.filter((d) => d.name === "dualPrinting")[0]
|
||||
?.value;
|
||||
|
||||
if (filteredLot.length > 1 && dualPrinting === "0") {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${printer?.name}, has more than one lot assigned to it, and dual printing shut off.`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `${printer?.name}, has more than one lot assigned to it, and dual printing shut off.`,
|
||||
};
|
||||
}
|
||||
|
||||
if (filteredLot.length > 1 && dualPrinting === "1") {
|
||||
// send over for dual printing processing
|
||||
createLog(
|
||||
"info",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${printer?.name}, being sent over for dual printing processing.`
|
||||
);
|
||||
// process what line to print the label for and return the lot info and change filteredLot to returned one.
|
||||
//filteredLot = await dualPrintingProcess(filteredLot);
|
||||
}
|
||||
|
||||
// if there are more than 2 lots it might be an auto labeler, autolabeler will be defined by its id for now only dayton
|
||||
if (filteredLot.length > 2 && plantToken[0].value !== "usday1") {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${printer?.name}, has more than 2 lot assigned to it, and not in ${plantToken[0].value}`
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
message: `${printer?.name}, has more than 2 lot assigned to it, and not in ${plantToken[0].value}`,
|
||||
};
|
||||
}
|
||||
|
||||
// special process for florence
|
||||
const isBillingTime = await billingCheck();
|
||||
|
||||
if (isBillingTime) {
|
||||
// billing is inside the window we dont want to bill now.
|
||||
return {
|
||||
success: false,
|
||||
message: "Billing time cant print.",
|
||||
};
|
||||
}
|
||||
|
||||
// check mm is good
|
||||
const mmStaged = await isMainMatStaged(filteredLot[0]);
|
||||
|
||||
if (!mmStaged) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Main material is not prepaired for lot ${filteredLot[0].lot}`
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// comment only but will check for color
|
||||
createLog(
|
||||
"info",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Remaining pallets for: ${filteredLot[0].MachineDescription} is ${filteredLot[0].Remaining}`
|
||||
);
|
||||
|
||||
// do we want to over run
|
||||
if (filteredLot[0].overPrinting === "no" && filteredLot[0].Remaining <= 0) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Over Printing on ${filteredLot[0].MachineDescription} is not allowed please change the lot`
|
||||
);
|
||||
// for slc we want to run the first label for henkel
|
||||
firstLotLabel(filteredLot[0]);
|
||||
return {
|
||||
success: false,
|
||||
message: `Over Printing on ${filteredLot[0].MachineDescription} is not allowed please change the lot`,
|
||||
};
|
||||
}
|
||||
|
||||
// prolink check by lot
|
||||
const prolink = await prolinkCheck(filteredLot[0].lot);
|
||||
|
||||
if (!prolink) {
|
||||
//console.error(`Prolink does not match for ${filteredLot[0].MachineDescription}`);
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Prolink does not match for ${filteredLot[0].MachineDescription}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
createLog("info", "labeling", "ocp", `Is prolink good? ${prolink}`);
|
||||
|
||||
// create the label
|
||||
const label = await createLabel(filteredLot[0], userPrinted);
|
||||
|
||||
if (!label.success) {
|
||||
return { sucess: false, message: label.message, data: label.data };
|
||||
}
|
||||
|
||||
// send over to be booked in if we can do it.
|
||||
const bookin = settingData.filter((s) => s.name === "bookin");
|
||||
|
||||
if (bookin[0].value === "1") {
|
||||
const book = await bookInLabel(label.data);
|
||||
} else {
|
||||
createLog("info", "labeling", "ocp", "Bookin is turned off.");
|
||||
|
||||
// will add later!!! :P
|
||||
}
|
||||
|
||||
// inhouse - if the inhouse funtion is turned on we will deliver to inhouse as long as we did not hit an error state
|
||||
const inhouseDelivery = settingData.filter(
|
||||
(s) => s.name === "inhouseDelivery"
|
||||
);
|
||||
if (inhouseDelivery[0].value === "1") {
|
||||
const deliverPallet = await delieryInhouse(label);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "Label fully processed.",
|
||||
data: label.data,
|
||||
};
|
||||
};
|
||||
23
server/services/ocp/controller/lots/lots.ts
Normal file
23
server/services/ocp/controller/lots/lots.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { query } from "../../../sqlServer/prodSqlServer.js";
|
||||
import { lotQuery } from "../../../sqlServer/querys/ocp/lots.js";
|
||||
|
||||
export const getLots = async () => {
|
||||
const { data: lotInfo, error: lotError } = await tryCatch(
|
||||
query(lotQuery, "Alplalabel online lots")
|
||||
);
|
||||
|
||||
if (lotError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error getting the lots",
|
||||
data: lotError,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "Current active lots that are technically released.",
|
||||
data: lotInfo,
|
||||
};
|
||||
};
|
||||
68
server/services/ocp/controller/lots/prolinkCheck.ts
Normal file
68
server/services/ocp/controller/lots/prolinkCheck.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../../database/schema/settings.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import { query } from "../../../sqlServer/prodSqlServer.js";
|
||||
import { prolinkQuery } from "../../../sqlServer/querys/ocp/prolinkCheck.js";
|
||||
|
||||
// check the if the lot matches
|
||||
export const prolinkCheck = async (lot: any) => {
|
||||
const { data, error: settingError } = await tryCatch(
|
||||
db.select().from(settings)
|
||||
);
|
||||
|
||||
if (settingError) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocp",
|
||||
"ocp",
|
||||
`There was an error getting the settings.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const settingData: any = data;
|
||||
const plantToken = settingData.filter(
|
||||
(s: any) => s.name === "plantToken"
|
||||
)[0].value;
|
||||
const prolinkCheck = settingData.filter(
|
||||
(s: any) => s.name === "prolinkCheck"
|
||||
)[0].value;
|
||||
|
||||
// if we want to ignore prolink check it will be disabled and then just return a pass as true
|
||||
if (prolinkCheck === "0") {
|
||||
createLog(
|
||||
"info",
|
||||
"ocp",
|
||||
"ocp",
|
||||
`Prolink Check is disabled skipping check.`
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
// run the query
|
||||
try {
|
||||
const prolink = await query(prolinkQuery, "Prolink Checks");
|
||||
|
||||
//console.log(lot);
|
||||
// filter out the lot
|
||||
const filterdLot = prolink.filter(
|
||||
(p: any) => p.AlplaLabelOnline === lot
|
||||
);
|
||||
|
||||
//console.log(filterdLot);
|
||||
if (filterdLot[0].LotCheck === "Good") {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
createLog(
|
||||
"error",
|
||||
"ocp",
|
||||
"ocp",
|
||||
`Error from running the Prolink Check query: ${err}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -1,20 +1,44 @@
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {manualPrinting} from "../../../../database/schema/ocpManualPrint.js";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { manualPrinting } from "../../../../database/schema/ocpManualPrint.js";
|
||||
import { tryCatch } from "../../../globalUtils/tryCatch.js";
|
||||
|
||||
export const manualPrint = async (data: any) => {
|
||||
export const manualPrint = async (manualPrint: any) => {
|
||||
/**
|
||||
* add the reason we did a manual print.
|
||||
*/
|
||||
|
||||
const manualPrintData = {
|
||||
line: data.line,
|
||||
printReason: data.printReason,
|
||||
initials: data.initials,
|
||||
additionalComments: data?.additionalComments,
|
||||
line: manualPrint.line,
|
||||
printReason: manualPrint.printReason,
|
||||
initials: manualPrint.initials,
|
||||
additionalComments: manualPrint?.additionalComments,
|
||||
add_user: "lst",
|
||||
};
|
||||
|
||||
try {
|
||||
const manualPrint = await db.insert(manualPrinting).values(manualPrintData);
|
||||
} catch (error) {}
|
||||
const { data, error } = await tryCatch(
|
||||
db
|
||||
.insert(manualPrinting)
|
||||
.values(manualPrintData)
|
||||
.returning({
|
||||
line: manualPrinting.line,
|
||||
printReason: manualPrinting.printReason,
|
||||
initials: manualPrinting.initials,
|
||||
additionalComments: manualPrinting?.additionalComments,
|
||||
add_user: manualPrinting.add_user,
|
||||
})
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error posting the manualPrintData",
|
||||
data: error,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "There was an error posting the manualPrintData",
|
||||
data,
|
||||
};
|
||||
};
|
||||
|
||||
38
server/services/ocp/controller/materials/mainMaterial.ts
Normal file
38
server/services/ocp/controller/materials/mainMaterial.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import { query } from "../../../sqlServer/prodSqlServer.js";
|
||||
import { mmQuery } from "../../../sqlServer/querys/ocp/mainMaterial.js";
|
||||
|
||||
export const isMainMatStaged = async (lot: any) => {
|
||||
// make staged false by deefault and error logged if theres an issue
|
||||
let isStaged = false;
|
||||
|
||||
// strangly the lot is not always sending over in slc so adding this in for now to see what line is cauing this issue
|
||||
if (!lot) {
|
||||
return isStaged;
|
||||
}
|
||||
|
||||
const updateQuery = mmQuery.replaceAll("[lotNumber]", lot.lot);
|
||||
|
||||
try {
|
||||
const res = await query(updateQuery, "Main Material Check");
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
"mainMaterial",
|
||||
"ocp",
|
||||
`MainMaterial results: ${JSON.stringify(res)}`
|
||||
);
|
||||
|
||||
if (res[0].Staged >= 1) {
|
||||
isStaged = true;
|
||||
}
|
||||
} catch (err) {
|
||||
createLog(
|
||||
"error",
|
||||
"mainMaterial",
|
||||
"ocp",
|
||||
`Error from running the Main Material query: ${err}`
|
||||
);
|
||||
}
|
||||
return isStaged;
|
||||
};
|
||||
21
server/services/ocp/controller/printers/getPrinters.ts
Normal file
21
server/services/ocp/controller/printers/getPrinters.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { printers } from "../../../../../database/schema/printers.js";
|
||||
|
||||
export const getPrinters = async () => {
|
||||
const currentTime = new Date(Date.now());
|
||||
|
||||
const { data: printerData, error: printerError } = await tryCatch(
|
||||
db.select().from(printers)
|
||||
);
|
||||
|
||||
if (printerError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "there was an error getting the printers",
|
||||
data: printerError,
|
||||
};
|
||||
}
|
||||
|
||||
return { success: true, message: "Printers", data: printerData };
|
||||
};
|
||||
84
server/services/ocp/controller/printers/updatePrinters.ts
Normal file
84
server/services/ocp/controller/printers/updatePrinters.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { printers } from "../../../../../database/schema/printers.js";
|
||||
import axios from "axios";
|
||||
|
||||
import { sql } from "drizzle-orm";
|
||||
import { prodEndpointCreation } from "../../../../globalUtils/createUrl.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { lstAuth } from "../../../../index.js";
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
|
||||
export const updatePrinters = async () => {
|
||||
const currentTime = new Date(Date.now());
|
||||
|
||||
// get the printers from prod
|
||||
let url = await prodEndpointCreation(
|
||||
"/public/v1.0/Administration/Printers"
|
||||
);
|
||||
|
||||
const { data: prodPrinters, error: prodError } = await tryCatch(
|
||||
axios.get(url, {
|
||||
headers: {
|
||||
Authorization: `Basic ${lstAuth}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
if (prodError) {
|
||||
console.log(prodError);
|
||||
return {
|
||||
success: false,
|
||||
message: "there was an error getting the printers.",
|
||||
data: prodError,
|
||||
};
|
||||
}
|
||||
|
||||
// do the printer update into our db
|
||||
const prodPrinterInfo = prodPrinters.data;
|
||||
|
||||
for (let i = 0; i < prodPrinterInfo.length; i++) {
|
||||
const printerStuff: any = {
|
||||
humanReadableId: prodPrinterInfo[i].humanReadableId,
|
||||
name: prodPrinterInfo[i].name,
|
||||
ipAddress: prodPrinterInfo[i].ipAddress,
|
||||
port: prodPrinterInfo[i].port,
|
||||
remark: prodPrinterInfo[i].remark,
|
||||
};
|
||||
const { data, error } = await tryCatch(
|
||||
db
|
||||
.insert(printers)
|
||||
.values(printerStuff)
|
||||
.onConflictDoUpdate({
|
||||
target: printers.humanReadableId,
|
||||
set: {
|
||||
//humanReadableId: prodPrinterInfo[i].humanReadableId,
|
||||
name: prodPrinterInfo[i].name,
|
||||
ipAddress: prodPrinterInfo[i].ipAddress,
|
||||
port: prodPrinterInfo[i].port,
|
||||
remark: prodPrinterInfo[i].remark,
|
||||
upd_date: sql`NOW()`,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
if (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"ocp",
|
||||
`${
|
||||
prodPrinterInfo[i].name
|
||||
} encoutered and error adding/updating ${JSON.stringify(error)}`
|
||||
);
|
||||
}
|
||||
createLog(
|
||||
"debug",
|
||||
"lst",
|
||||
"ocp",
|
||||
`${prodPrinterInfo[i].name} were just added/updated.`
|
||||
);
|
||||
}
|
||||
|
||||
return { success: true, message: "Printers were just added or updated." };
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../../../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../../../database/schema/settings.js";
|
||||
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../../../logger/logger.js";
|
||||
|
||||
const st = 5;
|
||||
const sm = 55;
|
||||
const et = 6;
|
||||
const em = 5;
|
||||
|
||||
export const billingCheck = async () => {
|
||||
const now = new Date();
|
||||
const startTime = new Date();
|
||||
const endTime = new Date();
|
||||
|
||||
let isOutsideBilling = false;
|
||||
const { data, error } = await tryCatch(db.select().from(settings));
|
||||
if (error) {
|
||||
return { success: false, message: "Error in getting settings." };
|
||||
}
|
||||
const plant = data.filter((n) => n.name === "plantToken");
|
||||
// set everything up
|
||||
startTime.setHours(st, sm, 0, 0);
|
||||
endTime.setHours(et, em, 0, 0);
|
||||
|
||||
if (plant[0].value === "usflo1") {
|
||||
if (now >= startTime && now <= endTime) {
|
||||
createLog(
|
||||
"warn",
|
||||
"specialProcess",
|
||||
"ocp",
|
||||
`You are inside the billing window no labels will print! please wait`
|
||||
);
|
||||
isOutsideBilling = true;
|
||||
} else {
|
||||
createLog(
|
||||
"info",
|
||||
"specialProcess",
|
||||
"ocp",
|
||||
"Out side billing window ok to print"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
createLog(
|
||||
"debug",
|
||||
"specialProcess",
|
||||
"ocp",
|
||||
"This plant dose not check for billing"
|
||||
);
|
||||
}
|
||||
|
||||
return isOutsideBilling;
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Controller, Tag } from "st-ethernet-ip";
|
||||
import { createLog } from "../../../../logger/logger.js";
|
||||
import { labelerTagRead } from "./plcTags/labelerTag.js";
|
||||
import { palletSendTag } from "./plcTags/palletSendTag.js";
|
||||
|
||||
let PLC = new Controller();
|
||||
let isDycoRunning = false;
|
||||
|
||||
// PLC address
|
||||
let plcAddress = "10.44.5.4";
|
||||
|
||||
// Initialize the interval variable outside the function
|
||||
let plcCycle: any;
|
||||
let plcInterval = 500;
|
||||
|
||||
// Create Tag Instances
|
||||
const labelerTag: any = new Tag("labeler.line_info");
|
||||
const palletSend = new Tag("Zone_6.Ready_to_Send");
|
||||
const strapperError = new Tag("Zone_3.Strapper_Faulted");
|
||||
|
||||
export const dycoConnect = async () => {
|
||||
// if we crash or start over reset the timers so we dont get duplicates
|
||||
clearInterval(plcCycle);
|
||||
if (isDycoRunning)
|
||||
return { success: false, message: "Dyco is already connected." };
|
||||
|
||||
// Remove all listeners before adding a new one to prevent memory leaks
|
||||
PLC.removeAllListeners("error");
|
||||
|
||||
try {
|
||||
await PLC.connect(plcAddress, 0).then(async () => {
|
||||
createLog("info", "dyco", "ocp", `We are connected to the dyco.`);
|
||||
isDycoRunning = true;
|
||||
let buffer = "";
|
||||
plcCycle = setInterval(async () => {
|
||||
await PLC.readTag(labelerTag);
|
||||
await PLC.readTag(palletSend);
|
||||
|
||||
// send the labeler tag data over
|
||||
labelerTagRead(labelerTag);
|
||||
|
||||
// send the end of line check over.
|
||||
palletSendTag(palletSend);
|
||||
}, 500);
|
||||
});
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"dyco",
|
||||
"ocp",
|
||||
`There was an error in the dyco: ${error}`
|
||||
);
|
||||
isDycoRunning = false;
|
||||
}
|
||||
};
|
||||
|
||||
export const closeDyco = async () => {
|
||||
if (!isDycoRunning)
|
||||
return { success: false, message: "Dyco is not connected." };
|
||||
|
||||
console.log(`Closing the connection`);
|
||||
try {
|
||||
await PLC.disconnect();
|
||||
isDycoRunning = false;
|
||||
return {
|
||||
success: true,
|
||||
message: "Dyco Connection is now closed.",
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error closing the dyco connection.",
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import { db } from "../../../../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../../../../database/schema/settings.js";
|
||||
import { tryCatch } from "../../../../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../../../../logger/logger.js";
|
||||
import { readTags } from "../../../../../rfid/controller/readTags.js";
|
||||
import { labelingProcess } from "../../../labeling/labelProcess.js";
|
||||
|
||||
let lastProcessedTimestamp = 0;
|
||||
|
||||
export const labelerTagRead = async (tagData: any) => {
|
||||
/**
|
||||
* Reads the tag data from the Dyco PLC and processes it based on the feedback.
|
||||
*/
|
||||
// Convert tag data buffer to a string and extract numeric values
|
||||
const buffer = Buffer.from(tagData.value);
|
||||
const numericString = buffer.toString("utf8").replace(/[^0-9#]/g, "");
|
||||
|
||||
// Ignore empty or invalid tag data
|
||||
if (numericString === "#") {
|
||||
return;
|
||||
}
|
||||
|
||||
const tagTime = new Date(tagData.state.timestamp).getTime();
|
||||
// get the settings
|
||||
const { data: settingData, error: settingError } = await tryCatch(
|
||||
db.select().from(settings)
|
||||
);
|
||||
|
||||
if (settingError) {
|
||||
createLog(
|
||||
"error",
|
||||
"dyco",
|
||||
"ocp",
|
||||
"There was an error getting the settings"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// check the dyco settings
|
||||
const dycoPrint = settingData.filter((n) => n.name === "dycoPrint");
|
||||
// Only process if this is a new timestamp within the last 5 seconds
|
||||
if (tagTime !== lastProcessedTimestamp && Date.now() - tagTime <= 5000) {
|
||||
lastProcessedTimestamp = tagTime;
|
||||
//console.log(numericString, tagData.state.timestamp);
|
||||
if (dycoPrint[0].value === "1") {
|
||||
createLog("info", "dyco", "ocp", "Dyco will be printing the label");
|
||||
// send over to print.
|
||||
labelingProcess({ line: numericString });
|
||||
}
|
||||
|
||||
if (dycoPrint[0].value === "0") {
|
||||
createLog(
|
||||
"info",
|
||||
"dyco",
|
||||
"ocp",
|
||||
"Rfid system is contorlling the printing"
|
||||
);
|
||||
// trigger the reader so we can get the label from the tag readers.
|
||||
await readTags("wrapper1");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* setting to switch between rfid and dyco labeling
|
||||
*/
|
||||
@@ -0,0 +1,54 @@
|
||||
import { createLog } from "../../../../../logger/logger.js";
|
||||
import { pickedup } from "../../../../../ocme/controller/pickedup.js";
|
||||
import { triggerScanner } from "../../../../../ocme/controller/triggerCamera.js";
|
||||
|
||||
let lastProcessedTimestamp = 0;
|
||||
|
||||
export const palletSendTag = async (tagData: any) => {
|
||||
/**
|
||||
* Reads the tag data from the Dyco PLC and processes it based on the feedback.
|
||||
* We will only trigger the camera and removal of pending tags
|
||||
*/
|
||||
|
||||
const tagTime = new Date(tagData.state.timestamp).getTime();
|
||||
|
||||
// Only process if this is a new timestamp within the last 5 seconds
|
||||
if (
|
||||
tagTime !== lastProcessedTimestamp &&
|
||||
Date.now() - tagTime <= 5000 &&
|
||||
tagData.value
|
||||
) {
|
||||
lastProcessedTimestamp = tagTime;
|
||||
//console.log(tagData.state.timestamp);
|
||||
createLog(
|
||||
"info",
|
||||
"dyco",
|
||||
"ocp",
|
||||
`Station 6 is ${tagData.value ? "full" : "empty"}`
|
||||
);
|
||||
|
||||
// take the picture
|
||||
setTimeout(async () => {
|
||||
const scan: any = await triggerScanner();
|
||||
if (!scan.success) {
|
||||
createLog(
|
||||
"error",
|
||||
"dyco",
|
||||
"ocp",
|
||||
`Scanner failed to take a picture trying one more time in 10 seconds`
|
||||
);
|
||||
setTimeout(async () => {
|
||||
await triggerScanner();
|
||||
}, 10 * 1000);
|
||||
}
|
||||
}, 15 * 1000);
|
||||
}
|
||||
|
||||
if (
|
||||
tagTime !== lastProcessedTimestamp &&
|
||||
Date.now() - tagTime <= 5000 &&
|
||||
!tagData.value
|
||||
) {
|
||||
await pickedup({ runningNr: 1234, all: true });
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import axios from "axios";
|
||||
import { prodEndpointCreation } from "../../../../../globalUtils/createUrl.js";
|
||||
import { lstAuth } from "../../../../../index.js";
|
||||
import { createLog } from "../../../../logger/logger.js";
|
||||
import { db } from "../../../../../../database/dbclient.js";
|
||||
import { prodlabels } from "../../../../../../database/schema/prodLabels.js";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
|
||||
export const delieryInhouse = async (data: any) => {
|
||||
// update sscc so we can book in
|
||||
const SSCC = data.SSCC.slice(2);
|
||||
// api url
|
||||
const url = await prodEndpointCreation(
|
||||
"/public/v1.0/Warehousing/InhouseDelivery"
|
||||
);
|
||||
|
||||
// create bookin
|
||||
const newDelivery = {
|
||||
scannerId: 99,
|
||||
sscc: SSCC,
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await axios.post(url, newDelivery, {
|
||||
headers: {
|
||||
Authorization: `Basic ${lstAuth}`,
|
||||
accept: "text/plain",
|
||||
},
|
||||
});
|
||||
|
||||
if (res.data.Result !== 0) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${data.printer.name}, Error:${res.data.Message}`
|
||||
);
|
||||
//printerUpdate(data.printer, 7, "Error while deliverying inhouse.");
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `${data.printer.name} had an error while trying to deliver.`,
|
||||
data: res.data,
|
||||
};
|
||||
} // label was just delivered
|
||||
createLog(
|
||||
"info",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${parseInt(data.SSCC.slice(10, -1))}, was just delivered`
|
||||
);
|
||||
|
||||
try {
|
||||
await db
|
||||
.update(prodlabels)
|
||||
.set({
|
||||
status: "Delivered",
|
||||
upd_date: sql`NOW()`,
|
||||
})
|
||||
.where(
|
||||
eq(prodlabels.runningNr, parseInt(data.SSCC.slice(10, -1)))
|
||||
);
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`Error updating ${parseInt(data.SSCC.slice(10, -1))} in the DB.`
|
||||
);
|
||||
return {
|
||||
success: true,
|
||||
message: `Error updating ${parseInt(
|
||||
data.SSCC.slice(10, -1)
|
||||
)} in the DB.`,
|
||||
data: error,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
createLog(
|
||||
"error",
|
||||
"labeling",
|
||||
"ocp",
|
||||
`${data.printer.name}, "Error: ${error}`
|
||||
);
|
||||
return {
|
||||
success: true,
|
||||
message: `Error deliverying ${parseInt(data.SSCC.slice(10, -1))}.`,
|
||||
data: error,
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
import { db } from "../../../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../../../database/schema/settings.js";
|
||||
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../../../logger/logger.js";
|
||||
import { query } from "../../../../sqlServer/prodSqlServer.js";
|
||||
|
||||
export const firstLotLabel = async (lot: any) => {
|
||||
/*
|
||||
currently this is only requested by slc
|
||||
|
||||
when a lot is finished and not set to over run we will trigger this function to insert data into the custom T_firstLotLabel table.
|
||||
|
||||
in nice label we look for unique id to run the process and then if the add date is older than 7 days we delete it for tracablility purpose.
|
||||
|
||||
we will also only do this for specific customers currently henkel is the requested.
|
||||
*/
|
||||
|
||||
/* work on the server side
|
||||
new table created in the _cus db
|
||||
CREATE TABLE T_firstLotLabel
|
||||
(
|
||||
ID INT IDENTITY(1,1) PRIMARY KEY,
|
||||
printerName varchar(max),
|
||||
add_date datetime
|
||||
-- Add other columns here as needed
|
||||
);
|
||||
the nicelabel trigger to be activated.
|
||||
*/
|
||||
const { data: settingData, error: settingError } = await tryCatch(
|
||||
db.select().from(settings)
|
||||
);
|
||||
|
||||
if (settingError) {
|
||||
return {
|
||||
success: false,
|
||||
message: "There was an error getting the settings.",
|
||||
settingError,
|
||||
};
|
||||
}
|
||||
// get the plantToken
|
||||
const plantToken = settingData.filter((n) => n.name === "plantToken");
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
"ocp",
|
||||
"ocp",
|
||||
`Checking if we can create the first label lot.`
|
||||
);
|
||||
|
||||
if (plantToken[0].value === "usslc1") {
|
||||
const newLabel = `insert into T_firstLotLabel (printerName, add_date) VALUES('${lot.PrinterName}', getdate())`;
|
||||
|
||||
// if (lot.CustomerId === 40) {
|
||||
createLog(
|
||||
"info",
|
||||
"ocp",
|
||||
"ocp",
|
||||
`Creating first lot label for ${lot.MachineDescription}`
|
||||
);
|
||||
await query(newLabel, "newLotLabel");
|
||||
|
||||
createLog(
|
||||
"info",
|
||||
"ocp",
|
||||
"ocp",
|
||||
`Was created for ${lot.MachineDescription}`
|
||||
);
|
||||
//}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import { db } from "../../../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../../../database/schema/settings.js";
|
||||
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
|
||||
import { createLog } from "../../../../logger/logger.js";
|
||||
import { query } from "../../../../sqlServer/prodSqlServer.js";
|
||||
import { machineCheck } from "../../../../sqlServer/querys/ocp/machineId.js";
|
||||
|
||||
export const getMac = async (machine: string) => {
|
||||
let updateQuery = machineCheck.replaceAll("[loc]", machine);
|
||||
|
||||
// create blank lots in case there is an error and dose not work
|
||||
let mac = [];
|
||||
|
||||
try {
|
||||
mac = await query(updateQuery, "Machine id check");
|
||||
// console.log("Machine data", mac); // removed due to swr being activated
|
||||
} catch (err) {
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"ocp",
|
||||
`Error with Machine id Check query: ${err}`
|
||||
);
|
||||
}
|
||||
|
||||
return mac;
|
||||
};
|
||||
@@ -1,14 +1,33 @@
|
||||
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
import { OpenAPIHono } from "@hono/zod-openapi";
|
||||
|
||||
// routes
|
||||
import manualLabelLog from "./routes/manualPrintLog.js";
|
||||
|
||||
import {db} from "../../../database/dbclient.js";
|
||||
import {settings} from "../../../database/schema/settings.js";
|
||||
import getPrinters from "./routes/printers/getPritners.js";
|
||||
import { db } from "../../../database/dbclient.js";
|
||||
import { settings } from "../../../database/schema/settings.js";
|
||||
import updateprinters from "./routes/printers/updatePrinters.js";
|
||||
import { updatePrinters } from "./controller/printers/updatePrinters.js";
|
||||
import getLots from "./routes/lots/getLots.js";
|
||||
import getLabels from "./routes/labeling/getLabels.js";
|
||||
import { dycoConnect } from "./controller/specialProcesses/dyco/plcConnection.js";
|
||||
import dycoCon from "./routes/specialProcesses/dyco/connection.js";
|
||||
import dycoClose from "./routes/specialProcesses/dyco/closeConnection.js";
|
||||
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
const routes = [manualLabelLog] as const;
|
||||
const routes = [
|
||||
manualLabelLog,
|
||||
//printer
|
||||
getPrinters,
|
||||
updateprinters,
|
||||
// lots
|
||||
getLots,
|
||||
// labeling
|
||||
getLabels,
|
||||
//dyco
|
||||
dycoCon,
|
||||
dycoClose,
|
||||
] as const;
|
||||
const setting = await db.select().from(settings);
|
||||
|
||||
const appRoutes = routes.forEach((route) => {
|
||||
@@ -16,7 +35,20 @@ const appRoutes = routes.forEach((route) => {
|
||||
});
|
||||
|
||||
app.all("/ocp/*", (c) => {
|
||||
return c.json({success: false, message: "You have encounters a ocp route that dose not exist."});
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "You have encounters a ocp route that dose not exist.",
|
||||
});
|
||||
});
|
||||
|
||||
// run the printer update on restart just to keep everything good
|
||||
setTimeout(() => {
|
||||
updatePrinters();
|
||||
}, 3 * 1000);
|
||||
|
||||
// do the intnal connection to the dyco
|
||||
setTimeout(() => {
|
||||
dycoConnect();
|
||||
}, 3 * 1000);
|
||||
|
||||
export default app;
|
||||
|
||||
37
server/services/ocp/routes/labeling/getLabels.ts
Normal file
37
server/services/ocp/routes/labeling/getLabels.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
// an external way to creating logs
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { getLabels } from "../../controller/labeling/getLabels.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocp"],
|
||||
summary: "Returns current active lots that are tech released",
|
||||
method: "get",
|
||||
path: "/getlabels",
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
const hours = c.req.query("hours");
|
||||
const { data: labelData, error: labelError } = await tryCatch(
|
||||
getLabels(hours ?? "2")
|
||||
);
|
||||
|
||||
if (labelError) {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "There was an error getting the printers",
|
||||
});
|
||||
}
|
||||
|
||||
return c.json({
|
||||
success: labelData.success,
|
||||
message: labelData.message,
|
||||
data: labelData.data,
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
35
server/services/ocp/routes/lots/getLots.ts
Normal file
35
server/services/ocp/routes/lots/getLots.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
// an external way to creating logs
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { getPrinters } from "../../controller/printers/getPrinters.js";
|
||||
import { getLots } from "../../controller/lots/lots.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocp"],
|
||||
summary: "Returns current active lots that are tech released",
|
||||
method: "get",
|
||||
path: "/getlots",
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
const { data: lotData, error: lotError } = await tryCatch(getLots());
|
||||
|
||||
if (lotError) {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "There was an error getting the printers",
|
||||
});
|
||||
}
|
||||
|
||||
return c.json({
|
||||
success: lotData.success,
|
||||
message: lotData.message,
|
||||
data: lotData.data,
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
@@ -1,18 +1,21 @@
|
||||
// an external way to creating logs
|
||||
import {createRoute, OpenAPIHono, z} from "@hono/zod-openapi";
|
||||
import {apiHit} from "../../../globalUtils/apiHits.js";
|
||||
import {responses} from "../../../globalUtils/routeDefs/responses.js";
|
||||
import type {User} from "../../../types/users.js";
|
||||
import {verify} from "hono/jwt";
|
||||
import {manualPrint} from "../controller/manualLabelLog.js";
|
||||
import {authMiddleware} from "../../auth/middleware/authMiddleware.js";
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { apiHit } from "../../../globalUtils/apiHits.js";
|
||||
import { responses } from "../../../globalUtils/routeDefs/responses.js";
|
||||
import type { User } from "../../../types/users.js";
|
||||
import { verify } from "hono/jwt";
|
||||
import { manualPrint } from "../controller/manualLabelLog.js";
|
||||
import { authMiddleware } from "../../auth/middleware/authMiddleware.js";
|
||||
|
||||
const app = new OpenAPIHono({strict: false});
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
const CreateLog = z.object({
|
||||
line: z.string().openapi({example: "info"}),
|
||||
initials: z.string().openapi({example: "server"}),
|
||||
printReason: z.string().openapi({example: "This is a new log posted"}),
|
||||
additionalComments: z.string().optional().openapi({example: "Some reason why we did this."}),
|
||||
line: z.string().openapi({ example: "info" }),
|
||||
initials: z.string().openapi({ example: "server" }),
|
||||
printReason: z.string().openapi({ example: "This is a new log posted" }),
|
||||
additionalComments: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Some reason why we did this." }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
@@ -24,32 +27,33 @@ app.openapi(
|
||||
//middleware: authMiddleware,
|
||||
//description: "This might be a temp soltuin during the transtion between versions",
|
||||
request: {
|
||||
body: {content: {"application/json": {schema: CreateLog}}},
|
||||
body: { content: { "application/json": { schema: CreateLog } } },
|
||||
},
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
const body = await c.req.json();
|
||||
apiHit(c, {endpoint: `api/logger/logs/id`});
|
||||
// const authHeader = c.req.header("Authorization");
|
||||
|
||||
// const token = authHeader?.split("Bearer ")[1] || "";
|
||||
// let user: User;
|
||||
|
||||
// try {
|
||||
// const payload = await verify(token, process.env.JWT_SECRET!);
|
||||
// user = payload.user as User;
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// return c.json({message: "Unauthorized"}, 401);
|
||||
// }
|
||||
|
||||
apiHit(c, { endpoint: `api/logger/logs/id` });
|
||||
try {
|
||||
//const data = {...body, add_user: user.username};
|
||||
await manualPrint(body);
|
||||
return c.json({success: true, message: "Manual Print was added.", data: []}, 200);
|
||||
const printLog: any = await manualPrint(body);
|
||||
return c.json(
|
||||
{
|
||||
success: printLog.success,
|
||||
message: printLog.message,
|
||||
data: printLog.data ?? [],
|
||||
},
|
||||
200
|
||||
);
|
||||
} catch (error) {
|
||||
return c.json({success: false, message: "There was an error clearing the log.", data: error}, 400);
|
||||
return c.json(
|
||||
{
|
||||
success: false,
|
||||
message: "There was an error clearing the log.",
|
||||
data: error,
|
||||
},
|
||||
400
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
50
server/services/ocp/routes/printers/getPritners.ts
Normal file
50
server/services/ocp/routes/printers/getPritners.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
// an external way to creating logs
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { getPrinters } from "../../controller/printers/getPrinters.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
const CreateLog = z.object({
|
||||
line: z.string().openapi({ example: "info" }),
|
||||
initials: z.string().openapi({ example: "server" }),
|
||||
printReason: z.string().openapi({ example: "This is a new log posted" }),
|
||||
additionalComments: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Some reason why we did this." }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocp"],
|
||||
summary: "Prints a label.",
|
||||
method: "get",
|
||||
path: "/getprinters",
|
||||
//middleware: authMiddleware,
|
||||
//description: "This might be a temp soltuin during the transtion between versions",
|
||||
request: {
|
||||
body: { content: { "application/json": { schema: CreateLog } } },
|
||||
},
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
const { data: printData, error: printError } = await tryCatch(
|
||||
getPrinters()
|
||||
);
|
||||
|
||||
if (printError) {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "There was an error getting the printers",
|
||||
});
|
||||
}
|
||||
|
||||
return c.json({
|
||||
success: printData.success,
|
||||
message: printData.message,
|
||||
data: printData.data,
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
50
server/services/ocp/routes/printers/updatePrinters.ts
Normal file
50
server/services/ocp/routes/printers/updatePrinters.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
// an external way to creating logs
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { responses } from "../../../../globalUtils/routeDefs/responses.js";
|
||||
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
|
||||
import { updatePrinters } from "../../controller/printers/updatePrinters.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
const CreateLog = z.object({
|
||||
line: z.string().openapi({ example: "info" }),
|
||||
initials: z.string().openapi({ example: "server" }),
|
||||
printReason: z.string().openapi({ example: "This is a new log posted" }),
|
||||
additionalComments: z
|
||||
.string()
|
||||
.optional()
|
||||
.openapi({ example: "Some reason why we did this." }),
|
||||
});
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocp"],
|
||||
summary: "Prints a label.",
|
||||
method: "get",
|
||||
path: "/updateprinters",
|
||||
//middleware: authMiddleware,
|
||||
//description: "This might be a temp soltuin during the transtion between versions",
|
||||
request: {
|
||||
body: { content: { "application/json": { schema: CreateLog } } },
|
||||
},
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
const { data: printData, error: printError } = await tryCatch(
|
||||
updatePrinters()
|
||||
);
|
||||
|
||||
if (printError) {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "There was an error getting the printers",
|
||||
});
|
||||
}
|
||||
|
||||
return c.json({
|
||||
success: printData.success,
|
||||
message: printData.message,
|
||||
data: printData.data,
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
@@ -0,0 +1,56 @@
|
||||
// an external way to creating logs
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { responses } from "../../../../../globalUtils/routeDefs/responses.js";
|
||||
import { authMiddleware } from "../../../../auth/middleware/authMiddleware.js";
|
||||
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
|
||||
import { closeDyco } from "../../../controller/specialProcesses/dyco/plcConnection.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocp:dyco"],
|
||||
summary: "Disconnect to the dyco.",
|
||||
method: "get",
|
||||
path: "/dycodisconnect",
|
||||
middleware: authMiddleware,
|
||||
description:
|
||||
"Use this when you just want to stop the entire thing due to an error or what not.",
|
||||
// request: {
|
||||
// body: {content: {"application/json": {schema: CreateLog}}},
|
||||
// },
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
//const body = await c.req.json();
|
||||
//apiHit(c, {endpoint: `api/logger/logs/id`});
|
||||
// const authHeader = c.req.header("Authorization");
|
||||
|
||||
// const token = authHeader?.split("Bearer ")[1] || "";
|
||||
// let user: User;
|
||||
|
||||
// try {
|
||||
// const payload = await verify(token, process.env.JWT_SECRET!);
|
||||
// user = payload.user as User;
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// return c.json({message: "Unauthorized"}, 401);
|
||||
// }
|
||||
|
||||
const { data, error } = await tryCatch(closeDyco());
|
||||
|
||||
if (error) {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "Error in connecting to dyco",
|
||||
data: error,
|
||||
});
|
||||
}
|
||||
const getData: any = data;
|
||||
return c.json({
|
||||
success: getData?.success,
|
||||
message: getData?.message,
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
@@ -0,0 +1,56 @@
|
||||
// an external way to creating logs
|
||||
import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
|
||||
import { responses } from "../../../../../globalUtils/routeDefs/responses.js";
|
||||
import { authMiddleware } from "../../../../auth/middleware/authMiddleware.js";
|
||||
import { tryCatch } from "../../../../../globalUtils/tryCatch.js";
|
||||
import { dycoConnect } from "../../../controller/specialProcesses/dyco/plcConnection.js";
|
||||
|
||||
const app = new OpenAPIHono({ strict: false });
|
||||
|
||||
app.openapi(
|
||||
createRoute({
|
||||
tags: ["ocp:dyco"],
|
||||
summary: "Connects to the dyco.",
|
||||
method: "get",
|
||||
path: "/dycoconnect",
|
||||
middleware: authMiddleware,
|
||||
//description: "This might be a temp soltuin during the transtion between versions",
|
||||
// request: {
|
||||
// body: {content: {"application/json": {schema: CreateLog}}},
|
||||
// },
|
||||
responses: responses(),
|
||||
}),
|
||||
async (c) => {
|
||||
//const body = await c.req.json();
|
||||
//apiHit(c, {endpoint: `api/logger/logs/id`});
|
||||
// const authHeader = c.req.header("Authorization");
|
||||
|
||||
// const token = authHeader?.split("Bearer ")[1] || "";
|
||||
// let user: User;
|
||||
|
||||
// try {
|
||||
// const payload = await verify(token, process.env.JWT_SECRET!);
|
||||
// user = payload.user as User;
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// return c.json({message: "Unauthorized"}, 401);
|
||||
// }
|
||||
|
||||
const { data, error } = await tryCatch(dycoConnect());
|
||||
const dataError: any = error;
|
||||
if (error) {
|
||||
return c.json({
|
||||
success: false,
|
||||
message: "Error in connecting to dyco",
|
||||
data: dataError?.data,
|
||||
});
|
||||
}
|
||||
const getData: any = data;
|
||||
return c.json({
|
||||
success: getData?.success,
|
||||
message: getData?.message,
|
||||
data: getData.data ?? [],
|
||||
});
|
||||
}
|
||||
);
|
||||
export default app;
|
||||
@@ -1,8 +1,8 @@
|
||||
import axios from "axios";
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {rfidReaders} from "../../../../database/schema/rfidReaders.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { rfidReaders } from "../../../../database/schema/rfidReaders.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
const authData = btoa("admin:Zebra123!");
|
||||
let token: string;
|
||||
@@ -12,10 +12,18 @@ export const readTags = async (reader: string) => {
|
||||
/**
|
||||
* Start the read for x seconds then auto stop it
|
||||
*/
|
||||
|
||||
const readers = await db.select().from(rfidReaders).where(eq(rfidReaders.active, true));
|
||||
createLog("info", "rfid", "rfid", `Read was just triggered from ${reader}`);
|
||||
const readers = await db
|
||||
.select()
|
||||
.from(rfidReaders)
|
||||
.where(eq(rfidReaders.active, true));
|
||||
if (readers.length === 0) {
|
||||
createLog("error", "rfid", "rfid", `There are no active readers right now maybe one forgot to be activated`);
|
||||
createLog(
|
||||
"error",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`There are no active readers right now maybe one forgot to be activated`
|
||||
);
|
||||
return;
|
||||
}
|
||||
// get the auth token
|
||||
@@ -23,7 +31,7 @@ export const readTags = async (reader: string) => {
|
||||
|
||||
try {
|
||||
const res = await axios.get(`https://${ip}/cloud/localRestLogin`, {
|
||||
headers: {Authorization: `Basic ${authData}`},
|
||||
headers: { Authorization: `Basic ${authData}` },
|
||||
});
|
||||
token = res.data.message;
|
||||
// start the read
|
||||
@@ -47,7 +55,7 @@ const startRead = async () => {
|
||||
`https://${ip}/cloud/start`,
|
||||
{},
|
||||
{
|
||||
headers: {Authorization: `Bearer ${token}`},
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
|
||||
@@ -67,7 +75,12 @@ const startRead = async () => {
|
||||
startRead();
|
||||
}, 1000);
|
||||
}
|
||||
createLog("error", "rfid", "rfid", `There was an error Starting the read: ${error.response.data.message}`);
|
||||
createLog(
|
||||
"error",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`There was an error Starting the read: ${error.response.data.message}`
|
||||
);
|
||||
}
|
||||
};
|
||||
const stopRead = async () => {
|
||||
@@ -76,10 +89,15 @@ const stopRead = async () => {
|
||||
`https://${ip}/cloud/stop`,
|
||||
{},
|
||||
{
|
||||
headers: {Authorization: `Bearer ${token}`},
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
} catch (error: any) {
|
||||
createLog("error", "rfid", "rfid", `There was an error Stopping the read: ${error.response.data.message}`);
|
||||
createLog(
|
||||
"error",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`There was an error Stopping the read: ${error.response.data.message}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Phase 2 we will generate a label to be reprinted at staion 4
|
||||
*/
|
||||
|
||||
import {createLog} from "../../../logger/logger.js";
|
||||
import type {TagData} from "../tagData.js";
|
||||
import {tagStuff} from "../tags/crudTag.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import type { TagData } from "../tagData.js";
|
||||
import { tagStuff } from "../tags/crudTag.js";
|
||||
|
||||
export const station3Tags = async (tagData: TagData[]) => {
|
||||
// make sure we only have one tag or dont update
|
||||
@@ -17,11 +17,25 @@ export const station3Tags = async (tagData: TagData[]) => {
|
||||
`There are ${tagData.length} tags, and ${tagData[0].reader} only allows 1 tag to create a label.`
|
||||
);
|
||||
// get tag data
|
||||
tagStuff(tagData);
|
||||
|
||||
for (let i = 0; i < tagData.length; i++) {
|
||||
const tag = {
|
||||
...tagData[i],
|
||||
runningNr: 0,
|
||||
lastareaIn: "NeedsChecked",
|
||||
};
|
||||
tagStuff([tag]);
|
||||
}
|
||||
} else {
|
||||
//console.log("Generate the label and link it to the tag.");
|
||||
const tagdata = await tagStuff(tagData);
|
||||
const tag = { ...tagData[0], runningNr: 0 };
|
||||
const tagdata = await tagStuff([tag]);
|
||||
|
||||
createLog("info", "rfid", "rfid", "Generate a label and link it to this tag.");
|
||||
createLog(
|
||||
"debug",
|
||||
"rfid",
|
||||
"rfid",
|
||||
"Generate a label and link it to this tag."
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,12 +2,34 @@
|
||||
* Phase 1 we will just follow the logic of printing a label when we are told requested to based on this tag.
|
||||
* Phase 2 we will just reprint the tag that was generated at the line
|
||||
*/
|
||||
|
||||
import {createLog} from "../../../logger/logger.js";
|
||||
import type {TagData} from "../tagData.js";
|
||||
import {tagStuff} from "../tags/crudTag.js";
|
||||
import os from "os";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
import { labelingProcess } from "../../../ocp/controller/labeling/labelProcess.js";
|
||||
import type { TagData } from "../tagData.js";
|
||||
import { tagStuff } from "../tags/crudTag.js";
|
||||
import { sendEmail } from "../../../notifications/controller/sendMail.js";
|
||||
|
||||
export const wrapperStuff = async (tagData: TagData[]) => {
|
||||
if (tagData[0]?.lastareaIn === "NeedsChecked") {
|
||||
createLog(
|
||||
"error",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`The tags on this pallet need to be checked as it was flagged as more than 1 tag number. please validate and looks at both sides.`
|
||||
);
|
||||
|
||||
// just making sure we clear out the running number if one really came over.
|
||||
for (let i = 0; i < tagData.length; i++) {
|
||||
const tag = { ...tagData[i], runningNr: 0 };
|
||||
tagStuff([tag]);
|
||||
}
|
||||
monitorChecks();
|
||||
return {
|
||||
success: false,
|
||||
message:
|
||||
"The tags on this pallet need to be checked as it was flagged as more than 1 tag number. please validate and looks at both sides.",
|
||||
};
|
||||
}
|
||||
if (tagData.length != 1) {
|
||||
createLog(
|
||||
"error",
|
||||
@@ -15,32 +37,123 @@ export const wrapperStuff = async (tagData: TagData[]) => {
|
||||
"rfid",
|
||||
`There are ${tagData.length} tags and this ${tagData[0].reader} only allows 1 tag to create a label.`
|
||||
);
|
||||
tagStuff(tagData);
|
||||
const tag = { ...tagData[0], runningNr: 0 };
|
||||
tagStuff([tag]);
|
||||
monitorChecks();
|
||||
} else {
|
||||
if (!tagData) {
|
||||
createLog("error", "rfid", "rfid", `No tagData was grabbed.`);
|
||||
monitorChecks();
|
||||
}
|
||||
const tagdata = await tagStuff(tagData);
|
||||
|
||||
/**
|
||||
* we want to make sure this pallet came from a line as its last spot if not we need to have a manual check.
|
||||
*/
|
||||
const station3 = tagdata.some((n: any) => n.lastareaIn.includes("line3"));
|
||||
|
||||
if (!station3) {
|
||||
const lines = tagdata[0]?.lastareaIn.includes("line3");
|
||||
|
||||
if (!lines) {
|
||||
createLog(
|
||||
"error",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`${tagdata.tag}, Did not come from a line please check the pallet and manually print the label.`
|
||||
`${tagdata[0].tag}, Did not come from a line please check the pallet and manually print the label.`
|
||||
);
|
||||
monitorChecks();
|
||||
|
||||
return {
|
||||
success: false,
|
||||
message: `${tagdata[0].tag}, Did not come from a line please check the pallet and manually print the label.`,
|
||||
};
|
||||
|
||||
// when we manually run again we want to make sure we read from the 3rd antenna this way we do not get the wrong info.
|
||||
// more testing will need to be done on this.
|
||||
}
|
||||
|
||||
// check if a running number exists
|
||||
if (station3.runningNumber) {
|
||||
createLog("info", "rfid", "rfid", `Reprint label ${station3.runningNumber}`);
|
||||
if (lines[0].runningNumber) {
|
||||
createLog(
|
||||
"info",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`Reprint label ${lines[0].runningNumber}`
|
||||
);
|
||||
} else {
|
||||
createLog("info", "rfid", "rfid", `A new labels will be created and linked to this ${tagdata.tag} tag`);
|
||||
createLog(
|
||||
"info",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`A new label will be created and linked to this ${tagdata[0].tag} tag`
|
||||
);
|
||||
|
||||
// get the actaul line number from the last area in
|
||||
const lineNum = parseInt(
|
||||
tagdata[0]?.lastareaIn.repalceAll("line3", "")
|
||||
);
|
||||
createLog(
|
||||
"info",
|
||||
"rfid",
|
||||
"rfid",
|
||||
`Line to be checked for printing: ${lineNum}`
|
||||
);
|
||||
|
||||
const genlabel = await labelingProcess({
|
||||
line: lineNum.toString(),
|
||||
});
|
||||
|
||||
if (genlabel?.success) {
|
||||
// update the tag and add the label into it
|
||||
const createPrintData = {
|
||||
...tagData[0],
|
||||
runnungNr: parseInt(genlabel.data?.SSCC.slice(10, -1)),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const monitorErrorTags: any = [];
|
||||
const monitorChecks = () => {
|
||||
/**
|
||||
* If we have to check more than 10 tags in an hour send an email to alert everyone.
|
||||
*/
|
||||
const now = new Date(Date.now()).getTime();
|
||||
monitorErrorTags.push({ timestamp: now });
|
||||
|
||||
// remove if creater than 1 hour
|
||||
const removalTiming = now - 1 * 60 * 60 * 1000; // 1 hour
|
||||
while (
|
||||
monitorErrorTags > 0 &&
|
||||
monitorErrorTags[0].timestamp < removalTiming
|
||||
) {
|
||||
monitorErrorTags.shift();
|
||||
}
|
||||
|
||||
if (monitorErrorTags > 10) {
|
||||
// send the email.
|
||||
const emailData = {
|
||||
email: "blake.matthes@alpla.com", // should be moved to the db so it can be reused.
|
||||
subject: `${os.hostname()} has had ${monitorErrorTags}.`,
|
||||
template: "toManyManualPrints",
|
||||
context: {
|
||||
count: monitorErrorTags,
|
||||
hours: "1",
|
||||
},
|
||||
};
|
||||
|
||||
sendEmail(emailData);
|
||||
}
|
||||
};
|
||||
|
||||
// if (
|
||||
// !Array.isArray(tagdata) &&
|
||||
// tagdata?.some((n: any) => n.lastareaIn.includes("line3"))
|
||||
// ) {
|
||||
// createLog(
|
||||
// "error",
|
||||
// "rfid",
|
||||
// "rfid",
|
||||
// `Data passed over is not an array.`
|
||||
// );
|
||||
// return;
|
||||
// }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {station3Tags} from "./stations/station3.js";
|
||||
import {wrapperStuff} from "./stations/wrappers.js";
|
||||
import { station3Tags } from "./stations/station3.js";
|
||||
import { wrapperStuff } from "./stations/wrappers.js";
|
||||
|
||||
export type TagData = {
|
||||
tagHex: string;
|
||||
@@ -8,6 +8,7 @@ export type TagData = {
|
||||
timeStamp: Date;
|
||||
antenna: number;
|
||||
tagStrength: number;
|
||||
lastareaIn?: string;
|
||||
};
|
||||
export const tagData = async (data: TagData[]) => {
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {eq} from "drizzle-orm";
|
||||
import {db} from "../../../../../database/dbclient.js";
|
||||
import {rfidTags} from "../../../../../database/schema/rfidTags.js";
|
||||
import type {TagData} from "../tagData.js";
|
||||
import {createLog} from "../../../logger/logger.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../../../../../database/dbclient.js";
|
||||
import { rfidTags } from "../../../../../database/schema/rfidTags.js";
|
||||
import type { TagData } from "../tagData.js";
|
||||
import { createLog } from "../../../logger/logger.js";
|
||||
|
||||
type ReturnTag = {
|
||||
success: boolean;
|
||||
@@ -22,7 +22,7 @@ export const tagStuff = async (tagData: TagData[]): Promise<any> => {
|
||||
tagHex: tagData[i].tagHex,
|
||||
tag: tagData[i].tag,
|
||||
lastRead: new Date(tagData[i].timeStamp),
|
||||
counts: [{area: tagData[i].reader, timesHere: 1}], //jsonb("counts").notNull(), //.default([{area: 1, timesHere: 5}]).notNull(),
|
||||
counts: [{ area: tagData[i].reader, timesHere: 1 }], //jsonb("counts").notNull(), //.default([{area: 1, timesHere: 5}]).notNull(),
|
||||
lastareaIn: tagData[i].reader,
|
||||
antenna: tagData[i].antenna,
|
||||
tagStrength: tagData[i].tagStrength,
|
||||
@@ -36,30 +36,37 @@ export const tagStuff = async (tagData: TagData[]): Promise<any> => {
|
||||
lastareaIn: rfidTags.lastareaIn,
|
||||
});
|
||||
createLog("info", "rfid", "rfid", `Tags were jusdt updated.`);
|
||||
return {success: true, tag};
|
||||
return { success: true, tag };
|
||||
} catch (error) {
|
||||
createLog("error", "rfid", "rfid", `${JSON.stringify(error)}`);
|
||||
return {success: false, error};
|
||||
return { success: false, error };
|
||||
}
|
||||
} else {
|
||||
// update tag
|
||||
//console.log("Updating existing tag");
|
||||
// make sure we actually have an array here
|
||||
const countsArray = (tag[0]?.counts as {area: string; timesHere: number}[]) ?? [];
|
||||
const countsArray =
|
||||
(tag[0]?.counts as { area: string; timesHere: number }[]) ?? [];
|
||||
|
||||
// check if the reader exists on the array
|
||||
const areaExists = countsArray.some((t) => t.area === tagData[0].reader);
|
||||
const areaExists = countsArray.some(
|
||||
(t) => t.area === tagData[0].reader
|
||||
);
|
||||
|
||||
// run the update on the array
|
||||
const updateCount = areaExists
|
||||
? countsArray.map((t) => {
|
||||
if (t.area === tagData[0].reader) {
|
||||
return {...t, timesHere: t.timesHere + 1};
|
||||
return { ...t, timesHere: t.timesHere + 1 };
|
||||
} else {
|
||||
return {...t, area: tagData[i].reader, timesHere: 1};
|
||||
return {
|
||||
...t,
|
||||
area: tagData[i].reader,
|
||||
timesHere: 1,
|
||||
};
|
||||
}
|
||||
})
|
||||
: [...countsArray, {area: tagData[i].reader, timesHere: 1}];
|
||||
: [...countsArray, { area: tagData[i].reader, timesHere: 1 }];
|
||||
|
||||
const updateTag = {
|
||||
lastRead: new Date(tagData[i].timeStamp),
|
||||
@@ -70,17 +77,21 @@ export const tagStuff = async (tagData: TagData[]): Promise<any> => {
|
||||
};
|
||||
|
||||
try {
|
||||
await db.update(rfidTags).set(updateTag).where(eq(rfidTags.tagHex, tagData[0].tagHex)).returning({
|
||||
tag: rfidTags.tag,
|
||||
runningNumber: rfidTags.runningNumber,
|
||||
counts: rfidTags.counts,
|
||||
lastareaIn: rfidTags.lastareaIn,
|
||||
});
|
||||
await db
|
||||
.update(rfidTags)
|
||||
.set(updateTag)
|
||||
.where(eq(rfidTags.tagHex, tagData[0].tagHex))
|
||||
.returning({
|
||||
tag: rfidTags.tag,
|
||||
runningNumber: rfidTags.runningNumber,
|
||||
counts: rfidTags.counts,
|
||||
lastareaIn: rfidTags.lastareaIn,
|
||||
});
|
||||
createLog("info", "rfid", "rfid", `Tags were jusdt updated.`);
|
||||
return {success: true, tag};
|
||||
return { success: true, tag };
|
||||
} catch (error) {
|
||||
createLog("error", "rfid", "rfid", `${JSON.stringify(error)}`);
|
||||
return {success: false, error};
|
||||
return { success: false, error };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,41 @@
|
||||
* this will only run on a server start up
|
||||
*/
|
||||
|
||||
import {db} from "../../../../database/dbclient.js";
|
||||
import {settings} from "../../../../database/schema/settings.js";
|
||||
import { db } from "../../../../database/dbclient.js";
|
||||
import { settings } from "../../../../database/schema/settings.js";
|
||||
|
||||
import {createLog} from "../../logger/logger.js";
|
||||
import { createLog } from "../../logger/logger.js";
|
||||
// "view", "technician", "supervisor","manager", "admin", "systemAdmin"
|
||||
const newSettings = [
|
||||
{name: "server", value: "localhost", description: "Where the app runs at", moduleName: "server"},
|
||||
{name: "serverPort", value: "4400", description: "What are we listening on", moduleName: "server"},
|
||||
{name: "dbUser", value: "alplaprod", description: "What is the db username", moduleName: "server"},
|
||||
{name: "dbPass", value: "b2JlbGl4", description: "What is the db password", moduleName: "server"},
|
||||
{
|
||||
name: "server",
|
||||
value: "localhost",
|
||||
description: "Where the app runs at",
|
||||
moduleName: "server",
|
||||
},
|
||||
{
|
||||
name: "serverPort",
|
||||
value: "4400",
|
||||
description: "What are we listening on",
|
||||
moduleName: "server",
|
||||
},
|
||||
{
|
||||
name: "dbUser",
|
||||
value: "alplaprod",
|
||||
description: "What is the db username",
|
||||
moduleName: "server",
|
||||
},
|
||||
{
|
||||
name: "dbPass",
|
||||
value: "b2JlbGl4",
|
||||
description: "What is the db password",
|
||||
moduleName: "server",
|
||||
},
|
||||
{
|
||||
name: "tcpPort",
|
||||
value: "2222",
|
||||
description: "TCP port for printers to connect send data and the zedra cameras",
|
||||
description:
|
||||
"TCP port for printers to connect send data and the zedra cameras",
|
||||
moduleName: "server",
|
||||
},
|
||||
{
|
||||
@@ -59,13 +80,15 @@ const newSettings = [
|
||||
{
|
||||
name: "ocmeService",
|
||||
value: "0",
|
||||
description: "Is the ocme service enabled. this is gernerally only for Dayton.",
|
||||
description:
|
||||
"Is the ocme service enabled. this is gernerally only for Dayton.",
|
||||
moduleName: "ocme",
|
||||
},
|
||||
{
|
||||
name: "fifoCheck",
|
||||
value: "45",
|
||||
description: "How far back do we want to check for fifo default 45, putting 0 will ignore.",
|
||||
description:
|
||||
"How far back do we want to check for fifo default 45, putting 0 will ignore.",
|
||||
moduleName: "ocme",
|
||||
},
|
||||
{
|
||||
@@ -83,7 +106,8 @@ const newSettings = [
|
||||
{
|
||||
name: "monitorAddress",
|
||||
value: "8",
|
||||
description: "What address is monitored to be limited to the amount of lots that can be added to a truck.",
|
||||
description:
|
||||
"What address is monitored to be limited to the amount of lots that can be added to a truck.",
|
||||
moduleName: "ocme",
|
||||
},
|
||||
{
|
||||
@@ -96,7 +120,8 @@ const newSettings = [
|
||||
{
|
||||
name: "devDir",
|
||||
value: "C:\\Users\\matthes01\\Documents\\lstv2",
|
||||
description: "This is the dev dir and strictly only for updating the servers.",
|
||||
description:
|
||||
"This is the dev dir and strictly only for updating the servers.",
|
||||
moduleName: "server",
|
||||
},
|
||||
{
|
||||
@@ -116,7 +141,30 @@ const newSettings = [
|
||||
{
|
||||
name: "ocpLogsCheck",
|
||||
value: "4",
|
||||
description: "How long do we want to allow logs to show that have not been cleared?",
|
||||
description:
|
||||
"How long do we want to allow logs to show that have not been cleared?",
|
||||
roles: "admin",
|
||||
module: "ocp",
|
||||
},
|
||||
{
|
||||
name: "inhouseDelivery",
|
||||
value: "0",
|
||||
description: "Are we doing auto inhouse delivery?",
|
||||
roles: "admin",
|
||||
module: "ocp",
|
||||
},
|
||||
// dyco settings
|
||||
{
|
||||
name: "dycoConnect",
|
||||
value: "0",
|
||||
description: "Are we running the dyco system?",
|
||||
roles: "admin",
|
||||
module: "ocp",
|
||||
},
|
||||
{
|
||||
name: "dycoPrint",
|
||||
value: "0",
|
||||
description: "Are we using the dyco to get the labels or the rfid?",
|
||||
roles: "admin",
|
||||
module: "ocp",
|
||||
},
|
||||
@@ -129,16 +177,31 @@ export const areSettingsIn = async () => {
|
||||
if (settingsCheck.length !== newSettings.length) {
|
||||
try {
|
||||
const newRole = await db
|
||||
.insert(settings)
|
||||
.values(newSettings)
|
||||
.onConflictDoNothing() // this will only update the ones that are new :D
|
||||
.returning({name: settings.name});
|
||||
createLog("info", "lst", "server", "Settingss were just added due to missing them on server startup");
|
||||
.insert(settings)
|
||||
.values(newSettings)
|
||||
.onConflictDoNothing() // this will only update the ones that are new :D
|
||||
.returning({ name: settings.name });
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"server",
|
||||
"Settingss were just added due to missing them on server startup"
|
||||
);
|
||||
} catch (error) {
|
||||
createLog("error", "lst", "server", "There was an error adding new roles to the db");
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"server",
|
||||
"There was an error adding new roles to the db"
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
createLog("error", "lst", "server", "There was an error getting or adding new Settingss");
|
||||
createLog(
|
||||
"error",
|
||||
"lst",
|
||||
"server",
|
||||
"There was an error getting or adding new Settingss"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export const laneInfo = `
|
||||
select IdLagerAbteilung as laneID,
|
||||
Bezeichnung as laneName
|
||||
from AlplaPROD_test1.dbo.T_LagerAbteilungen
|
||||
where Aktiv = 1
|
||||
and Bezeichnung = '[laneName]'
|
||||
`;
|
||||
55
server/services/sqlServer/querys/ocp/lots.ts
Normal file
55
server/services/sqlServer/querys/ocp/lots.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
export const lotQuery = `
|
||||
select IdMaschinen_ProdPlanung as LabelOnlineID,
|
||||
IdMaschine as machineID,
|
||||
MaschinenStandort as MachineLocation,
|
||||
MaschinenBez as MachineDescription,
|
||||
IdProdPlanung as LOT,
|
||||
prolink.lot as ProlinkLot,
|
||||
IdArtikelvarianten as AV,
|
||||
ArtikelVariantenBez as Alias,
|
||||
convert(varchar, add_date, 20) as Add_Date,
|
||||
Add_user,
|
||||
idEtikettenDrucker as printerID,
|
||||
b.name as PrinterName,
|
||||
CAST(TotalPlannedLoadingUnits as float) as PlannedQTY,
|
||||
CAST(TotalProducedLoadingUnits as float) as Produced,
|
||||
ROUND(CAST(TotalPlannedLoadingUnits as float) - CAST(TotalProducedLoadingUnits as float),2) as Remaining,
|
||||
case
|
||||
-- checks if someone changed the criteria to something else to trigger the over run
|
||||
when x.ProzentReserveAnzahlPaletten > 0 then 'yes'
|
||||
|
||||
-- if the lot has a decimal in it to allow over running with no intervention
|
||||
when CAST(TotalPlannedLoadingUnits as float) - floor(CAST(TotalPlannedLoadingUnits as float)) > 0 then 'yes'
|
||||
else 'no' end as overPrinting,
|
||||
CustomerHumanReadableId as CustomerId,
|
||||
CustomerName as CustomerName,
|
||||
idMaschine as MachineID,
|
||||
prolink.lastProlinkUpdate as lastProlinkUpdate,
|
||||
IdEtikettenLayoutPalette as palletLabel,
|
||||
AnzahlKopienPalette as pallerCopies,
|
||||
IdEtikettenLayoutKarton as cartonLabel,
|
||||
AnzahlKopienKarton as cartonCopies,
|
||||
IsTechnicallyReleased
|
||||
--*
|
||||
from AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen x (nolock)
|
||||
join
|
||||
[test1_AlplaPROD2.0_Read].[productionControlling].[ProducedLot] on
|
||||
x.IdProdPlanung =
|
||||
[test1_AlplaPROD2.0_Read].[productionControlling].[ProducedLot].ProductionLotHumanReadableId
|
||||
left join
|
||||
[test1_AlplaPROD2.0_Read].masterData.Printer as b on
|
||||
x.IdEtikettenDrucker = b.HumanReadableId
|
||||
-- adding in prolink lot
|
||||
left join
|
||||
(SELECT * from (SELECT IdMaschine as prolinkMachineId,
|
||||
Produktionslos as lot,
|
||||
Upd_Date as lastProlinkUpdate,
|
||||
ROW_NUMBER() OVER (PARTITION BY IdMaschine ORDER BY Upd_Date DESC) RN_Prolink
|
||||
FROM AlplaPROD_test1.dbo.T_HistoryProduktionsdaten (nolock)
|
||||
WHERE Upd_Date BETWEEN DATEADD(DD, - 300, getdate()) AND DATEADD(DD, 1, getdate())) p
|
||||
WHERE RN_Prolink = 1
|
||||
) as prolink on
|
||||
x.idMaschine = prolink.prolinkMachineId
|
||||
|
||||
where IsTechnicallyReleased = 1
|
||||
`;
|
||||
9
server/services/sqlServer/querys/ocp/machineId.ts
Normal file
9
server/services/sqlServer/querys/ocp/machineId.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export const machineCheck = `
|
||||
SELECT [HumanReadableId]
|
||||
,[Name]
|
||||
,[Location]
|
||||
,[Active]
|
||||
,[ImportSource]
|
||||
,[StagingMainMaterialMandatory]
|
||||
FROM [test1_AlplaPROD2.0_Read].[masterData].[Machine] (nolock)
|
||||
where Active = 1 and [Location] = [loc]`;
|
||||
17
server/services/sqlServer/querys/ocp/mainMaterial.ts
Normal file
17
server/services/sqlServer/querys/ocp/mainMaterial.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export const mmQuery = `
|
||||
SELECT lot.ProductionLotHumanReadableId,
|
||||
case when SourcingState in (1, 2) then 1
|
||||
when x.ProvidedAmount > 0 then 1
|
||||
when x.EffectiveConsumption > 0 then 1
|
||||
else 0 end as Staged,
|
||||
x.ProvidedAmount as Provided,
|
||||
x.EffectiveConsumption as consumption,
|
||||
x.IsManualProcess as isManual,
|
||||
MaterialHumanReadableId
|
||||
FROM [test1_AlplaPROD2.0_Read].[issueMaterial].[MaterialDemand] x (nolock)
|
||||
left join
|
||||
[test1_AlplaPROD2.0_Read].[issueMaterial].[ProductionLot] as lot on
|
||||
x.ProductionLotId = lot.Id
|
||||
where lot.ProductionLotHumanReadableId = [lotNumber]
|
||||
and IsMainMaterial = 1
|
||||
`;
|
||||
25
server/services/sqlServer/querys/ocp/prolinkCheck.ts
Normal file
25
server/services/sqlServer/querys/ocp/prolinkCheck.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
export const prolinkQuery = `
|
||||
select * from (
|
||||
select *
|
||||
From(select
|
||||
V_Maschinen_ProdPlanungen.MaschinenStandort as Machine,
|
||||
V_Maschinen_ProdPlanungen.IdProdPlanung as AlplaLabelOnline,
|
||||
prolink.lot Prolink,
|
||||
case when AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen.IdProdPlanung <> prolink.lot
|
||||
Then 'IncorrectLot'
|
||||
Else 'Good' end as LotCheck
|
||||
from AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen (nolock)
|
||||
left join
|
||||
(
|
||||
SELECT *
|
||||
FROM (SELECT IdMaschine,
|
||||
Produktionslos as lot,
|
||||
Startzeit as StartTime,
|
||||
Upd_Date,
|
||||
ROW_NUMBER() OVER (PARTITION BY IdMaschine ORDER BY Upd_Date DESC) RN_Prolink
|
||||
FROM AlplaPROD_test1.dbo.T_HistoryProduktionsdaten (nolock)
|
||||
WHERE Upd_Date BETWEEN DATEADD(DD, - 10, getdate()) AND DATEADD(DD, 1, getdate())) a
|
||||
WHERE RN_Prolink = 1
|
||||
) as prolink on AlplaPROD_test1.dbo.V_Maschinen_ProdPlanungen.IdMaschine=prolink.IdMaschine) a
|
||||
) a
|
||||
`;
|
||||
@@ -1,23 +1,28 @@
|
||||
import net from "net";
|
||||
import {OpenAPIHono} from "@hono/zod-openapi";
|
||||
import {createLog} from "../logger/logger.js";
|
||||
import { OpenAPIHono } from "@hono/zod-openapi";
|
||||
import { createLog } from "../logger/logger.js";
|
||||
|
||||
import startTCP from "./route/startServer.js";
|
||||
import stopTCP from "./route/stopServer.js";
|
||||
import restartTCP from "./route/restartServer.js";
|
||||
import {db} from "../../../database/dbclient.js";
|
||||
import {settings} from "../../../database/schema/settings.js";
|
||||
import {eq} from "drizzle-orm";
|
||||
import { db } from "../../../database/dbclient.js";
|
||||
import { settings } from "../../../database/schema/settings.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { postLabelData } from "../ocme/controller/postRunningNr.js";
|
||||
|
||||
let tcpServer: net.Server;
|
||||
let tcpSockets: Set<net.Socket> = new Set();
|
||||
let isServerRunning = false;
|
||||
|
||||
const tcpPort = await db.select().from(settings).where(eq(settings.name, "tcpPort"));
|
||||
const tcpPort = await db
|
||||
.select()
|
||||
.from(settings)
|
||||
.where(eq(settings.name, "tcpPort"));
|
||||
const app = new OpenAPIHono();
|
||||
|
||||
export const startTCPServer = () => {
|
||||
if (isServerRunning) return {success: false, message: "Server is already running"};
|
||||
if (isServerRunning)
|
||||
return { success: false, message: "Server is already running" };
|
||||
|
||||
tcpServer = net.createServer((socket) => {
|
||||
console.log("Client connected");
|
||||
@@ -25,7 +30,19 @@ export const startTCPServer = () => {
|
||||
tcpSockets.add(socket);
|
||||
socket.on("data", (data: Buffer) => {
|
||||
console.log("Received:", data.toString());
|
||||
socket.write("Message received");
|
||||
const parseData = data.toString("utf-8").trimEnd().split(" ");
|
||||
// hb from the scanners
|
||||
if (parseData[0] === "HB") {
|
||||
return;
|
||||
}
|
||||
|
||||
// alert from the printers
|
||||
if (parseData[0] === "ALERT:" || parseData[0] === "ALERT") {
|
||||
return;
|
||||
}
|
||||
|
||||
// from the wrapper send the data
|
||||
postLabelData(parseData);
|
||||
});
|
||||
|
||||
socket.on("end", () => {
|
||||
@@ -40,16 +57,22 @@ export const startTCPServer = () => {
|
||||
});
|
||||
|
||||
tcpServer.listen(tcpPort[0]?.value ?? 2222, () => {
|
||||
createLog("info", "lst", "tcp", `TCP Server listening on port ${tcpPort[0]?.value ?? 2222}`);
|
||||
createLog(
|
||||
"info",
|
||||
"lst",
|
||||
"tcp",
|
||||
`TCP Server listening on port ${tcpPort[0]?.value ?? 2222}`
|
||||
);
|
||||
});
|
||||
|
||||
isServerRunning = true;
|
||||
return {success: true, message: "TCP Server started"};
|
||||
return { success: true, message: "TCP Server started" };
|
||||
};
|
||||
|
||||
// Function to stop the TCP server
|
||||
export const stopTCPServer = () => {
|
||||
if (!isServerRunning) return {success: false, message: "Server is not running"};
|
||||
if (!isServerRunning)
|
||||
return { success: false, message: "Server is not running" };
|
||||
for (const socket of tcpSockets) {
|
||||
socket.destroy();
|
||||
}
|
||||
@@ -58,7 +81,7 @@ export const stopTCPServer = () => {
|
||||
console.log("TCP Server stopped");
|
||||
});
|
||||
isServerRunning = false;
|
||||
return {success: true, message: "TCP Server stopped"};
|
||||
return { success: true, message: "TCP Server stopped" };
|
||||
};
|
||||
|
||||
app.route("/tcpserver/start", startTCP);
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "nodenext",
|
||||
"strict": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["node"],
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "hono/jsx",
|
||||
"outDir": "./dist",
|
||||
"removeComments": true,
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["server", "scripts/**/*.ts"],
|
||||
"exclude": ["node_modules", "frontend", "dist", "testFiles"]
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "nodenext",
|
||||
"strict": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["node"],
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "hono/jsx",
|
||||
"outDir": "./dist",
|
||||
"removeComments": true,
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["server", "scripts/**/*.ts"],
|
||||
"exclude": ["node_modules", "frontend", "dist", "testFiles"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user