Compare commits

...

450 Commits

Author SHA1 Message Date
88b6d0a235 Merge pull request 'migration' (#51) from migration into main
Reviewed-on: #51
2025-09-19 22:18:40 -05:00
8943407f27 feat(finaly): the final push before moving all to the new lst 2025-09-19 22:16:47 -05:00
0bbe411db0 feat(docs): added in link to the main docs and to the material xfer 2025-09-19 07:56:43 -05:00
99b3ad633c fix(materials): changes for consuming peices vs units 2025-09-18 11:00:54 -05:00
c892348d19 refactor(manual print): added a min length of 10 characters 2025-09-18 11:00:18 -05:00
360549aaf4 fix(consume material): changes made to remove the rest of the auth needs 2025-09-18 10:59:55 -05:00
bdc1e72fc1 refactor(frontend): comment required now when doing manual labels 2025-09-17 20:02:14 -05:00
4cae96b1ee refactor(detach): just a log to monitor better 2025-09-11 06:42:31 -05:00
1cde8ab2e6 fix(mm query): more changes to the material query to please more plants 2025-09-11 06:42:02 -05:00
03e8378213 fix(inhouse): changes to no longer error 2025-09-11 06:39:36 -05:00
275c93dc79 refactor(detach silo): changes to now show the error in the console in the browser 2025-09-11 06:39:07 -05:00
fbb8c21d5c feat(loreal forecast): added in an email to be sent when we are missing skus 2025-09-11 06:38:36 -05:00
dce93d3de2 ci(release): bump build number to 652 2025-09-11 06:32:08 -05:00
faf4e9f9ab ci(release): bump build number to 651 2025-09-11 06:30:48 -05:00
a9783a7d35 ci(release): bump build number to 650 2025-09-10 11:15:07 -05:00
e9ca6dbbb2 ci(release): bump build number to 649 2025-09-10 11:13:59 -05:00
e996f99400 ci(release): bump build number to 648 2025-09-10 06:59:19 -05:00
3b939ff2d3 ci(release): bump build number to 647 2025-09-09 21:21:08 -05:00
a7ff88025e chore(release): 2.27.0 2025-09-09 21:20:39 -05:00
00899a5b77 fix(materials): more fixes to try and please all plants to use this version and not call me 2025-09-09 21:20:23 -05:00
99ecf52218 fix(label query): fixes to only pull in active layouts 2025-09-09 21:19:39 -05:00
a6920d7cd8 ci(release): bump build number to 645 2025-09-09 17:52:15 -05:00
788efdf4b3 ci(release): bump build number to 644 2025-09-09 17:40:05 -05:00
a2a17beeeb ci(release): bump build number to 643 2025-09-09 17:28:29 -05:00
6c793c66a4 ci(release): bump build number to 642 2025-09-09 15:57:41 -05:00
6918a5a7d4 ci(release): bump build number to 641 2025-09-09 09:12:18 -05:00
ddd9b0e372 ci(release): bump build number to 640 2025-09-09 07:48:24 -05:00
41d921756b ci(release): bump build number to 638 2025-09-08 19:16:44 -05:00
d86ca7d3bf ci(release): bump build number to 636 2025-09-08 13:30:05 -05:00
932a72ba88 fix(db): changes to the user so it deletes correctly 2025-09-07 15:38:27 -05:00
b9c6d0ba57 ci(release): bump build number to 622 2025-09-06 16:33:56 -05:00
592e4c8cd7 ci(release): bump build number to 621 2025-09-06 16:02:36 -05:00
b772666905 ci(release): bump build number to 620 2025-09-06 14:56:05 -05:00
a6edcb71bf ci(release): bump build number to 619 2025-09-06 14:51:26 -05:00
76d929abea ci(release): bump build number to 618 2025-09-06 14:43:44 -05:00
da17defe82 ci(release): bump build number to 617 2025-09-06 14:37:44 -05:00
669f5ca33f ci(release): bump build number to 616 2025-09-06 14:31:51 -05:00
b649dca4c9 ci(release): bump build number to 615 2025-09-06 14:28:44 -05:00
04b8d041f9 ci(release): bump build number to 611 2025-09-06 09:24:09 -05:00
71bc7c29bc ci(release): bump build number to 610 2025-09-06 09:22:13 -05:00
79f1f8f91b fix(article check): corrected the query to not have a specfic plant in it 2025-09-06 09:04:00 -05:00
b677bc1498 refactor(rfid): changes to show all tags vs only 3 if there are more 2025-09-06 09:03:35 -05:00
a53915ad8c fix(material check): split manual material out of the mm to properly catch it 2025-09-06 09:03:11 -05:00
b3ce767b32 fix(bookin): corrections to only show the message on error vs the json 2025-09-06 09:02:42 -05:00
6caa5984e7 fix(eomservice): changes to stop a crash incase the sql returned nothing due to start up 2025-09-06 09:02:09 -05:00
415d2e4a1d fix(register): changes to not give everyone system admin 2025-09-06 09:01:42 -05:00
271cdbdbfa refactor(cosume): changes to allow non logged in users to use this function 2025-09-06 09:01:12 -05:00
796a8dccd2 refactor(silo card): changes to allow viewers to see and able to attach and detach 2025-09-06 09:00:46 -05:00
e03e92c18d ci(build): changes to build then copy to new version being rewritten 2025-09-06 09:00:11 -05:00
dd2e5d04ae ci(release): bump build number to 609 2025-09-06 08:54:39 -05:00
708b57b926 ci(release): bump build number to 608 2025-09-06 08:50:28 -05:00
0444da8bbc ci(release): bump build number to 607 2025-09-06 08:34:18 -05:00
6d49fae16d ci(release): bump build number to 602 2025-09-05 09:55:52 -05:00
be8a44f2dc ci(release): bump build number to 601 2025-09-05 09:52:25 -05:00
a3994a1f69 ci(release): bump build number to 600 2025-09-05 09:45:02 -05:00
00eaf62d4c ci(release): bump build number to 600 2025-09-05 09:44:58 -05:00
6851777faf ci(release): bump build number to 599 2025-09-05 09:43:27 -05:00
f9e97fc224 ci(release): bump build number to 598 2025-09-05 09:43:25 -05:00
4e3c5e4191 ci(release): bump build number to 595 2025-09-05 08:28:25 -05:00
172fd1d5c2 ci(release): bump build number to 594 2025-09-05 08:28:22 -05:00
1094de2ebd ci(release): bump build number to 593 2025-09-05 08:23:59 -05:00
7462b3d90b ci(release): bump build number to 592 2025-09-05 08:23:56 -05:00
2045c13ef2 ci(release): bump build number to 591 2025-09-05 08:22:41 -05:00
5fa9e83d5b ci(release): bump build number to 590 2025-09-05 08:22:39 -05:00
f48c944bd0 ci(release): bump build number to 589 2025-09-05 07:50:36 -05:00
dddd1d422e ci(release): bump build number to 588 2025-09-04 13:12:21 -05:00
8133443ec9 ci(release): bump build number to 587 2025-09-03 10:56:13 -05:00
28c7d30c1a ci(release): bump build number to 586 2025-09-03 10:54:37 -05:00
57966ac9de refactor(mm query): changes to the query to see pkg and materials properly and not duplicates 2025-09-01 11:08:47 -05:00
6910550de7 fix(main material check): corrections to properly ignore pkg during color checks 2025-09-01 11:08:16 -05:00
1f8b8a7248 fix(bookin): corrected the bookin in error response
this could still print a label if the system detects the material properly but some other issue with
alplaprod happened
2025-09-01 11:05:36 -05:00
cfed981928 refactor(sql): articles added in UOM 2025-09-01 11:02:32 -05:00
0efe74d4b1 ci(release): bump build number to 585 2025-09-01 07:31:05 -05:00
c35db2e209 ci(release): bump build number to 584 2025-08-29 19:01:12 -05:00
e1cdeb740b ci(release): bump build number to 583 2025-08-29 18:57:25 -05:00
3c9e75dc3c ci(release): bump build number to 582 2025-08-29 18:32:34 -05:00
64b5b0d248 ci(release): bump build number to 581 2025-08-29 11:37:47 -05:00
668eae9719 ci(release): bump build number to 580 2025-08-29 11:31:22 -05:00
7cc3778506 feat(eom): lastSales, lastPurch added to be pulled with new template 2025-08-29 11:26:26 -05:00
af47c1582e ci(release): bump build number to 579 2025-08-29 08:59:50 -05:00
081572c421 ci(release): bump build number to 578 2025-08-28 11:09:44 -05:00
c6f6ef6262 fix(frontend): typos 2025-08-28 10:56:49 -05:00
34849e15d1 ci(release): bump build number to 577 2025-08-28 10:19:10 -05:00
9bd66942f5 chore(release): 2.26.0 2025-08-28 10:18:13 -05:00
795da35141 ci(release): bump build number to 576 2025-08-28 10:17:15 -05:00
468f933168 fix(eom stats): corrections to the eom inv stuff to be proper tiems 2025-08-28 10:15:41 -05:00
8c296c5b78 test(forklifts): forklift starting process 2025-08-28 10:15:13 -05:00
53ed2c4e6a feat(materials): added in a bigger window on eom transfer lots 2025-08-28 10:14:41 -05:00
0a6ddea8c0 refactor(materials): changes to allow exact and eom transfers 2025-08-27 17:17:32 -05:00
df423192bf refactor(labeling): moved bookin fails inside bookin as it could be off 2025-08-27 17:17:03 -05:00
2f908398bc ci(release): bump build number to 575 2025-08-27 16:08:58 -05:00
bf8203bbee ci(release): bump build number to 574 2025-08-27 15:50:49 -05:00
e92eccf785 ci(release): bump build number to 573 2025-08-27 14:43:04 -05:00
f4f3de49ca fix(material check): alt mm causing issues and utilizing an 80% to just be ok 2025-08-25 18:34:09 -05:00
788d6367a3 refactor(labeling): removed the wrong import 2025-08-25 15:47:18 -05:00
24a97afe06 fix(fake edi): removed console log 2025-08-25 14:40:21 -05:00
37f82a9710 refactor(tms intergration): corrected how we added gl coding 2025-08-25 14:39:54 -05:00
369d16018c fix(bookin): corrected the error received from the book in fail 2025-08-25 14:38:00 -05:00
68901a857a fix(dm): corrected the remark section so its properly sent over 2025-08-25 14:09:13 -05:00
171763184c ci(release): bump build number to 572 2025-08-25 13:58:47 -05:00
b7de2a8dbe ci(release): bump build number to 571 2025-08-25 13:15:06 -05:00
e78083f496 ci(release): bump build number to 570 2025-08-25 12:18:17 -05:00
3f3b64bf2b ci(release): bump build number to 569 2025-08-25 12:15:27 -05:00
123bb127e8 ci(release): bump build number to 568 2025-08-21 07:33:43 -05:00
8d6ead3aa1 fix(produser): changes to include DM 2025-08-21 05:55:41 -05:00
3148aa79d7 refactor(materials): changes for permissions on material consume 2025-08-21 05:55:20 -05:00
4486fe2436 fix(ocp): zechetti type correction to include the printer name 2025-08-21 05:54:48 -05:00
0ba338d480 feat(rfid): new check to remove tags that have been at a line longer than 6 hours 2025-08-21 05:18:49 -05:00
846ac479b1 fix(transferlots): missed adding this 2025-08-21 05:14:03 -05:00
73d38ba3fe refactor(notifcations): changed hour to min in ti intergrations 2025-08-21 05:13:34 -05:00
27586e923a feat(ocp): zechetti 1 added in 2025-08-21 05:13:06 -05:00
662a951b98 feat(tms): a clean up function was added to remove releases added as blockers older than 45d 2025-08-21 05:10:25 -05:00
0c54cecbd4 ci(release): bump build number to 567 2025-08-20 20:51:22 -05:00
bcf5378966 ci(release): bump build number to 566 2025-08-20 20:04:51 -05:00
c5668e6cf1 chore(release): 2.25.0 2025-08-20 20:04:05 -05:00
213814b868 ci(release): bump build number to 565 2025-08-20 19:02:42 -05:00
7d5b0c46c1 ci(release): bump build number to 564 2025-08-19 17:37:40 -05:00
595e22e8e9 ci(release): bump build number to 563 2025-08-19 17:04:13 -05:00
a6f18554b8 ci(release): bump build number to 562 2025-08-19 17:00:13 -05:00
88f61c8eaa feat(ocp): materials contorls and transfer to next lot logic 2025-08-19 16:00:49 -05:00
a183279268 ci(release): bump build number to 561 2025-08-17 18:10:25 -05:00
5156c8bf7b ci(release): bump build number to 560 2025-08-14 09:32:25 -05:00
4669ff95dc ci(release): bump build number to 559 2025-08-13 22:52:44 -05:00
ed93992165 ci(release): bump build number to 558 2025-08-13 16:32:23 -05:00
f16e2bf53b ci(release): bump build number to 557 2025-08-13 15:50:35 -05:00
a84998438c ci(release): bump build number to 556 2025-08-13 11:33:45 -05:00
83469105f0 ci(release): bump build number to 555 2025-08-12 17:53:08 -05:00
835ae58f04 ci(release): bump build number to 554 2025-08-12 16:26:39 -05:00
1498a19121 ci(release): bump build number to 553 2025-08-12 14:28:42 -05:00
ca96849991 ci(release): bump build number to 552 2025-08-12 13:55:49 -05:00
27b37f9849 ci(release): bump build number to 551 2025-08-12 11:24:50 -05:00
7f81a2e09a ci(release): bump build number to 550 2025-08-11 12:24:30 -05:00
e14abd3644 ci(release): bump build number to 549 2025-08-11 08:22:44 -05:00
2ff7b9baf9 refactor(migrations): not needed but we have it and needed to correct the settings 2025-08-10 18:15:07 -05:00
8145dc800d refactor(siloadjustment): refactored to get the settings from the state vs direct from db 2025-08-10 18:14:38 -05:00
6ccf500e5e feat(prodrole): added in planner role 2025-08-10 18:14:08 -05:00
103171c924 refactor(notifications): refactored the cron job system so we can utilize outside the service 2025-08-10 18:13:32 -05:00
2eb6fa7794 fix(gotransport): error handling so we dont get spammed with errors 2025-08-10 18:12:52 -05:00
397f1da595 fix(inv query): error in improper placed , in the query 2025-08-10 18:12:29 -05:00
8d63f7f6b0 feat(psi): psi querys added and av grab right now 2025-08-10 18:11:57 -05:00
52345bc94c feat(eom): added in hostorical data and deletion for data over 45 days 2025-08-10 18:11:16 -05:00
a8a1c1d7fb ci(release): bump build number to 548 2025-08-09 15:05:59 -05:00
83ff2641f3 ci(release): bump build number to 547 2025-08-09 15:02:21 -05:00
7c48f608bc ci(release): bump build number to 546 2025-08-09 14:58:02 -05:00
1802b9ba4e ci(release): bump build number to 545 2025-08-09 14:41:23 -05:00
67a12ccc5c ci(release): bump build number to 544 2025-08-09 14:28:17 -05:00
15e2a65cbb ci(release): bump build number to 543 2025-08-07 21:18:09 -05:00
9e5577e6bb feat(dm): changes to have a default time if nothing is passed in the excel 2025-08-06 15:25:45 -05:00
c52e2a8671 ci(release): bump build number to 542 2025-08-06 15:19:54 -05:00
8f76d6998c ci(release): bump build number to 541 2025-08-06 15:08:13 -05:00
e209686d3c ci(release): bump build number to 540 2025-08-05 14:50:05 -05:00
803c963f96 fix(https fixes): made it so the settings can be grabbed via https 2025-08-05 14:45:04 -05:00
078f35626b ci(release): bump build number to 539 2025-08-05 14:16:26 -05:00
2288884829 fix(inv cards): correction to properly display the names 2025-08-04 18:12:32 -05:00
69fc7418c9 ci(release): bump build number to 538 2025-08-04 14:41:53 -05:00
a0179a41ba refactor(migration progress): moved to start looking at the go backedn 2025-08-04 12:48:49 -05:00
a36552fd9b fix(dm page): correction to the insturcitons 2025-08-04 12:48:04 -05:00
c7bb12822b fix(dyco): correction to disable the camera if ocme is off 2025-08-04 12:44:03 -05:00
98a5ca7bb8 ci(release): bump build number to 537 2025-08-04 09:48:20 -05:00
74ac2864c9 ci(release): bump build number to 536 2025-08-04 07:56:50 -05:00
1f93eca561 ci(release): bump build number to 535 2025-08-04 06:54:23 -05:00
1f44750346 ci(release): bump build number to 534 2025-07-31 11:58:56 -05:00
0d17fef1a1 fix(mainmaterial check): if the machine dose not require mm to be staged properly ignore 2025-07-31 11:54:40 -05:00
f574645b44 ci(release): bump build number to 533 2025-07-30 19:37:13 -05:00
998e84f564 feat(migration start): this starts the migration of all settings to look at the go backend vs this 2025-07-30 14:34:15 -05:00
3e51ebc18b ci(release): bump build number to 532 2025-07-29 21:11:53 -05:00
8129dbb787 ci(release): bump build number to 531 2025-07-29 20:51:27 -05:00
b5561635dd ci(release): bump build number to 530 2025-07-25 07:33:48 -05:00
ff340161d6 chore(release): 2.24.1 2025-07-25 07:33:03 -05:00
39d0768d50 fix(mm check): correction to know if a machine is required to have mm or not 2025-07-25 07:32:09 -05:00
d40ed30f55 fix(create labels): better logging to know where the error came from 2025-07-25 07:31:43 -05:00
8594d72d2c ci(release): bump build number to 529 2025-07-23 10:11:37 -05:00
3e680a5a50 fix(submodules): correction to accessing when changes made to roles 2025-07-23 10:10:18 -05:00
e1113c49b3 ci(release): bump build number to 528 2025-07-21 15:33:00 -05:00
e964bb70ae ci(release): bump build number to 527 2025-07-21 14:07:39 -05:00
f01b6941ba ci(release): bump build number to 526 2025-07-21 13:53:57 -05:00
e78f3ffdb5 ci(release): bump build number to 525 2025-07-20 08:51:38 -05:00
713df0b615 ci(release): bump build number to 524 2025-07-19 11:06:03 -05:00
f2615fbcea ci(release): bump build number to 523 2025-07-19 11:04:19 -05:00
4f7d6fe4af ci(release): bump build number to 522 2025-07-19 09:41:06 -05:00
96a3fd451b ci(release): bump build number to 521 2025-07-19 09:36:44 -05:00
d1befadd1c ci(release): bump build number to 520 2025-07-19 08:19:56 -05:00
fa99eb41dd ci(release): bump build number to 519 2025-07-19 08:14:19 -05:00
11cc3662cf ci(release): bump build number to 518 2025-07-18 17:15:13 -05:00
d9a2f90056 ci(release): bump build number to 517 2025-07-18 16:44:07 -05:00
23ee0468ad ci(release): bump build number to 516 2025-07-18 16:27:26 -05:00
83ba84cf6f ci(release): bump build number to 515 2025-07-18 16:14:44 -05:00
96d2a25081 ci(release): bump build number to 514 2025-07-18 16:04:01 -05:00
d54f85cf3d ci(release): bump build number to 513 2025-07-18 15:58:43 -05:00
371870cbe5 ci(release): bump build number to 512 2025-07-18 15:47:18 -05:00
dd31763fdd ci(release): bump build number to 511 2025-07-18 15:14:29 -05:00
c9a64e2e7c ci(release): bump build number to 510 2025-07-18 15:11:12 -05:00
733603fffa ci(release): bump build number to 509 2025-07-18 14:50:19 -05:00
bc92f8be0e ci(release): bump build number to 508 2025-07-18 14:47:55 -05:00
9ced82b154 ci(release): bump build number to 507 2025-07-18 14:40:30 -05:00
d9bc68d6ac ci(release): bump build number to 506 2025-07-18 14:13:08 -05:00
248e4cfeef ci(release): bump build number to 505 2025-07-18 13:59:18 -05:00
9707990211 ci(release): bump build number to 504 2025-07-18 13:53:03 -05:00
60672ba751 ci(release): bump build number to 503 2025-07-18 13:26:51 -05:00
3b8190b080 ci(release): bump build number to 502 2025-07-18 12:44:53 -05:00
c1577ff432 ci(release): bump build number to 501 2025-07-18 11:10:43 -05:00
40b382ca62 ci(release): bump build number to 500 2025-07-18 11:00:53 -05:00
1ec3de0f02 ci(release): bump build number to 499 2025-07-18 10:45:37 -05:00
f5c035081c ci(release): bump build number to 498 2025-07-18 10:43:27 -05:00
885e0ce348 ci(release): bump build number to 497 2025-07-18 09:02:37 -05:00
7a59da77f2 ci(release): bump build number to 496 2025-07-18 09:01:15 -05:00
82fb85ba0d ci(release): bump build number to 495 2025-07-18 08:30:11 -05:00
0d263f6941 ci(release): bump build number to 494 2025-07-18 08:16:07 -05:00
1762c70859 ci(release): bump build number to 493 2025-07-18 08:12:21 -05:00
c196b1d612 ci(release): bump build number to 492 2025-07-18 08:09:41 -05:00
8926bfde00 ci(release): bump build number to 491 2025-07-18 08:07:54 -05:00
256405b5a5 ci(release): bump build number to 490 2025-07-18 08:04:32 -05:00
eecf35fc9c ci(release): bump build number to 489 2025-07-18 07:57:26 -05:00
700b18160c ci(release): bump build number to 488 2025-07-18 07:50:57 -05:00
2dd6947bd6 ci(release): bump build number to 487 2025-07-18 07:41:41 -05:00
fe8ab62e94 ci(release): bump build number to 486 2025-07-18 07:17:04 -05:00
a0d476042b ci(release): bump build number to 485 2025-07-18 07:04:55 -05:00
8e99a2e5e5 ci(release): bump build number to 484 2025-07-18 06:53:22 -05:00
4b9f96f3b0 ci(release): bump build number to 483 2025-07-18 06:51:03 -05:00
390107a1fb ci(release): bump build number to 482 2025-07-18 06:44:53 -05:00
e3a4ef7a80 refactor(zip builds): removed the c# wrapper as it wont be used on this build anymore 2025-07-18 06:40:50 -05:00
c224e30b8d revert(mainmaterial): reverted changes to check for machine needing mm 2025-07-18 06:40:15 -05:00
16b710dc91 ci(release): bump build number to 481 2025-07-17 11:55:46 -05:00
a9e788f438 ci(release): bump build number to 480 2025-07-17 10:39:33 -05:00
3aa4191b0f ci(release): bump build number to 479 2025-07-17 10:36:08 -05:00
260d513ee3 ci(release): bump build number to 478 2025-07-17 07:21:51 -05:00
e9f729d5e2 ci(release): bump build number to 477 2025-07-17 07:10:51 -05:00
e43ac65d04 ci(release): bump build number to 476 2025-07-16 09:52:45 -05:00
5199a9ce69 ci(release): bump build number to 475 2025-07-16 09:45:29 -05:00
5ce78222b9 ci(release): bump build number to 474 2025-07-16 09:34:51 -05:00
904de61e5a ci(release): bump build number to 473 2025-07-16 09:31:28 -05:00
c1ed482073 ci(release): bump build number to 472 2025-07-16 09:26:49 -05:00
f57426cf13 refactor(serverdata): moved stp1 to d drive 2025-07-15 15:38:48 -05:00
7079b151da ci(release): bump build number to 471 2025-07-15 08:42:09 -05:00
b87cd8dd7c chore(release): 2.24.0 2025-07-15 08:41:27 -05:00
531b343d17 fix(dm): missing api key call, and better logging on the post orders section 2025-07-15 08:40:38 -05:00
e2b549714c ci(release): bump build number to 470 2025-07-15 08:33:18 -05:00
e6f3a9b4d0 fix(label ratio): missed a manual spot that was not considered 2025-07-15 08:20:03 -05:00
33295dc3c3 fix(rfid): corrections to the manual tag to no fail on manual when a tag already exists but failed 2025-07-15 08:19:36 -05:00
49fd9d65c9 refactor(dyco): pickup changed to let spam again so we dont miss anything 2025-07-15 08:18:50 -05:00
0510f13885 ci(release): bump build number to 469 2025-07-15 08:12:40 -05:00
588f264854 refactor(printers): addedin daily check for printers used to only be on a restart 2025-07-15 06:27:33 -05:00
8afa4176ef ci(release): bump build number to 468 2025-07-14 15:13:38 -05:00
611183fc19 ci(release): bump build number to 467 2025-07-14 14:48:16 -05:00
c31856ac3e ci(release): bump build number to 466 2025-07-14 12:38:59 -05:00
61f0b7f06b feat(labeling): ratios reset for labeling implemeneted 2025-07-14 12:37:38 -05:00
a7f8e39bac refactor(rfid): ratio resets implemeneted 2025-07-14 12:36:36 -05:00
4923b3c698 ci(release): bump build number to 465 2025-07-14 12:22:12 -05:00
28f34a6a31 ci(release): bump build number to 464 2025-07-14 12:14:34 -05:00
b81675e445 ci(release): bump build number to 463 2025-07-14 10:23:22 -05:00
c6d80dbc8a fix(rfid reader): ratio to be fixed 2 digits so it dose not span across the entire page 2025-07-14 10:19:34 -05:00
bc54b365ea refactor(consume material): changes to use api vs prod user 2025-07-14 10:18:59 -05:00
41308788fd feat(labelratio): new feature to monitor label ratio from auto and manual
this was designed more for dayton but could be used for all plants
2025-07-14 10:18:23 -05:00
d6232cb358 ci(release): bump build number to 462 2025-07-14 10:13:08 -05:00
d89a336fb1 ci(release): bump build number to 461 2025-07-14 09:40:41 -05:00
e84ae42c83 ci(release): bump build number to 460 2025-07-14 09:35:44 -05:00
6ec8f0863b ci(release): bump build number to 459 2025-07-14 09:19:38 -05:00
4f231b343c ci(release): bump build number to 458 2025-07-12 22:16:18 -05:00
454039e60c ci(release): bump build number to 457 2025-07-12 22:09:50 -05:00
c7c148fede ci(release): bump build number to 456 2025-07-11 06:56:14 -05:00
e30adc6612 ci(release): bump build number to 455 2025-07-11 06:49:29 -05:00
f7b4de8130 feat(rfid): front end view of the readers and there status 2025-07-10 21:29:01 -05:00
6584b37cb0 ci(release): bump build number to 454 2025-07-10 20:52:29 -05:00
6a082d9737 feat(rfid): more rfid topics while monitoring the system run 2025-07-10 20:09:35 -05:00
58711becf2 refactor(mm check): added in a check that if we dont need mm we return mm checked 2025-07-10 20:08:45 -05:00
f757085fc2 refactor(ocp page): changes to the layout so it can better be moved for the tiles 2025-07-10 20:07:59 -05:00
8f5e1cb094 refactor(wrapper card): changes to include the rfid and remove the manual trigger as no one used it 2025-07-10 20:07:35 -05:00
7497ee454c feat(rfid): added in manual trigger for rfid reader at the wrapper 2025-07-10 20:07:10 -05:00
c0ede8714c feat(readers): added in good and bad reads to monitor eff 2025-07-10 20:06:31 -05:00
1a6a05112b fix(db): lastRead column was named incorrectly 2025-07-10 20:06:05 -05:00
97c6631eab ci(release): bump build number to 453 2025-07-10 20:04:31 -05:00
1ae506939c ci(release): bump build number to 452 2025-07-10 19:56:21 -05:00
f0294942a7 ci(release): bump build number to 451 2025-07-10 14:42:37 -05:00
e323607b39 ci(release): bump build number to 450 2025-07-10 14:32:25 -05:00
df0851414e ci(release): bump build number to 449 2025-07-10 14:13:05 -05:00
a9b860a34d ci(release): bump build number to 448 2025-07-10 14:06:37 -05:00
ead35b4360 ci(release): bump build number to 447 2025-07-10 13:52:06 -05:00
d6b1a75afa ci(release): bump build number to 446 2025-07-10 12:25:17 -05:00
1b661a6685 ci(release): bump build number to 445 2025-07-10 12:16:58 -05:00
f597142ee3 ci(release): bump build number to 444 2025-07-10 08:04:44 -05:00
18780d872c ci(release): bump build number to 443 2025-07-10 07:25:23 -05:00
ba02ee42c5 ci(release): bump build number to 442 2025-07-10 07:14:56 -05:00
f573f4f721 ci(release): bump build number to 441 2025-07-10 07:13:51 -05:00
1d6bf7215b ci(release): bump build number to 440 2025-07-09 20:15:37 -05:00
e616574fa6 ci(release): bump build number to 439 2025-07-09 18:24:44 -05:00
08109f500f ci(release): bump build number to 438 2025-07-08 17:36:31 -05:00
ab8102afbf feat(prodroles): new cto role added 2025-07-08 17:35:20 -05:00
e13b5a4283 fix(logs): time crap 2025-07-08 17:28:11 -05:00
7a4dea9d87 fix(rfid): lots of changes to the wrapper area 2025-07-08 17:27:08 -05:00
a19ac539e7 refactor(rfid): reduced teh rssi peak -50 > -40 2025-07-08 17:25:38 -05:00
1c910d80ea fix(rfid): existing tags were trying to be inserted and instead of updating failed corrected 2025-07-08 17:25:09 -05:00
56e0f3eb47 fix(rfid): typos in station 3 logging 2025-07-08 17:24:21 -05:00
e50e9af839 refactor(dyco): change the plc check time from 5 > 8 2025-07-08 17:23:48 -05:00
e34f273acb ci(release): bump build number to 437 2025-07-08 15:11:48 -05:00
2c5f8a3a8c ci(release): bump build number to 436 2025-07-08 15:06:13 -05:00
9e4729690a ci(release): bump build number to 435 2025-07-08 15:03:24 -05:00
26ab6ecd8d ci(release): bump build number to 434 2025-07-07 15:05:44 -05:00
05fa774d68 fix(detach silo): when pressing cancel the detach funciton would not work 2025-06-26 13:45:14 -05:00
b1acd97232 ci(release): bump build number to 433 2025-06-26 13:35:06 -05:00
edc874c302 fix(settings page): error with the store not starting as fast as the page 2025-06-24 15:36:14 -05:00
4abecd0455 feat(prodroles): added in quality manager 2025-06-24 15:25:33 -05:00
6c7193bc7a ci(release): bump build number to 432 2025-06-24 14:52:22 -05:00
c6739b6a73 ci(release): bump build number to 431 2025-06-24 14:40:10 -05:00
13992bde68 ci(release): bump build number to 430 2025-06-24 12:22:17 -05:00
7ed9db1bdb refactor(lim): shipping hours change 2025-06-23 16:47:11 -05:00
f4dd572a8f fix(dashboard): some more rending fixes due to some strange behaivers 2025-06-23 16:46:46 -05:00
3b56a5e3e2 fix(renderfixes): some strange rendering fixes that should have been caught long time ago 2025-06-23 16:46:14 -05:00
2eea2911bc revert(frontend): some pkg reverts due to strange build behaivers 2025-06-23 16:45:22 -05:00
c155e89bc7 refactor(dbscheme): refactoring from opening and saving 2025-06-23 16:44:55 -05:00
7d9ea42f8d ci(release): bump build number to 429 2025-06-23 16:40:28 -05:00
974f6587fc ci(release): bump build number to 428 2025-06-23 12:22:35 -05:00
2ac48138cb feat(silo attached detach): added in silo attach detach setup in the silo card 2025-06-23 12:00:28 -05:00
d6d19f8e5b test(material returns): added type check 2025-06-23 11:59:56 -05:00
3cafbd92d0 fix(ocp page): server info error added check to make sure was there 2025-06-23 11:54:44 -05:00
77d9e5d095 refactor(serverdb): format changes 2025-06-23 11:33:28 -05:00
4a02bbc368 chore(updated packages): all pacakges were just updated 2025-06-23 11:30:41 -05:00
f75da6525d ci(release): bump build number to 427 2025-06-20 12:43:30 -05:00
26ceb95dae refactor(finance query): changes to include article type 2025-06-20 11:19:15 -05:00
bd5bad3cba refactor(server data): changes to bet and stp1 2025-06-20 11:18:55 -05:00
c5bd5a7c0a feat(notify): shortage bookings based on time and article type 2025-06-20 11:18:37 -05:00
095d724e65 feat(notifcations): pallets booked as waste brought back in via cycle count 2025-06-20 11:18:13 -05:00
7df512acaa feat(logistics): get sscc based on runnning number
returns the sscc based on the running number more for support and testing the endpoints
2025-06-20 11:17:39 -05:00
3073df342f refactor(datamart): changes to customer inventory to include specific whse 2025-06-20 11:16:19 -05:00
b9ff0a4138 feat(default accounts): added in a default account run this will create a bunch of system admins 2025-06-20 11:15:39 -05:00
c555172d68 ci(release): bump build number to 426 2025-06-20 08:21:14 -05:00
e432f0b3ae ci(release): bump build number to 425 2025-06-19 16:36:04 -05:00
bc25e835b4 ci(release): bump build number to 424 2025-06-19 07:17:13 -05:00
a71167e598 ci(release): bump build number to 423 2025-06-18 12:16:05 -05:00
53945402ce ci(release): bump build number to 422 2025-06-17 09:01:52 -05:00
aa42819cc1 ci(release): bump build number to 421 2025-06-17 08:57:57 -05:00
c36e4e66b3 ci(release): bump build number to 420 2025-06-17 07:24:11 -05:00
11ae3cc0bc ci(release): bump build number to 419 2025-06-16 19:06:11 -05:00
f80e742e27 chore(release): 2.23.0 2025-06-16 19:04:57 -05:00
37f2518589 refactor(ocme): picked up per location now vs picked up all 2025-06-16 18:30:55 -05:00
90be86d972 feat(datamart): finance inventory audit added 2025-06-16 18:30:05 -05:00
68d75277c2 fix(lots): corrections to role issue where user logged in but no role set yet 2025-06-16 18:28:50 -05:00
84aacd5b71 feat(dotnet): added in wrapper so we could run in iis for ssl :D 2025-06-16 18:27:42 -05:00
c72b4d3261 ci(release): bump build number to 418 2025-06-16 18:26:24 -05:00
b397fd7f32 ci(release): bump build number to 417 2025-06-16 18:16:08 -05:00
f90ce8cba7 ci(release): bump build number to 416 2025-06-16 16:20:13 -05:00
88c1c29437 ci(release): bump build number to 415 2025-06-16 13:38:27 -05:00
f7c9f93d30 ci(release): bump build number to 414 2025-06-16 13:19:34 -05:00
83f31b97f5 ci(release): bump build number to 413 2025-06-16 13:16:38 -05:00
b97f8175f9 ci(release): bump build number to 412 2025-06-16 12:59:04 -05:00
92901a8762 ci(release): bump build number to 412 2025-06-16 12:55:58 -05:00
0071237b24 ci(release): bump build number to 411 2025-06-15 09:10:23 -05:00
d32289c833 refactor(ocme): changes in the pickup to no longer handle all but specific area 2025-06-13 08:39:20 -05:00
3c45010b26 fix(produser): changes to get correct response from errors 2025-06-13 08:35:59 -05:00
4927428607 ci(release): bump build number to 410 2025-06-13 08:29:37 -05:00
04298c9f54 ci(release): bump build number to 409 2025-06-13 08:12:39 -05:00
6759a1bf8f ci(release): bump build number to 408 2025-06-13 07:03:45 -05:00
92624cbac9 ci(release): bump build number to 407 2025-06-13 06:35:46 -05:00
f79ff26958 refactor(picked up pallets): changes to start picking up only area from spot 2025-06-12 21:13:25 -05:00
e865c1dcaf test(added in commands): relocate and updated to remove 2025-06-12 21:12:15 -05:00
99ad79c662 feat(produser): added in the function to create a standard user based on there username 2025-06-12 21:10:46 -05:00
3283972809 test(return preforms): start to preform return 2025-06-12 21:09:10 -05:00
1cb285bea8 refactor(printers): added in processes for the upcoming reprint function 2025-06-12 21:08:38 -05:00
4f5d5faecb ci(release): bump build number to 406 2025-06-12 20:18:06 -05:00
def97360be ci(release): bump build number to 405 2025-06-12 12:56:46 -05:00
a1229b4dee ci(release): bump build number to 404 2025-06-12 12:53:54 -05:00
8d04c8f7de ci(release): bump build number to 403 2025-06-12 11:00:25 -05:00
27eb96cc15 ci(release): bump build number to 402 2025-06-12 10:45:05 -05:00
4187264e30 ci(release): bump build number to 401 2025-06-12 06:26:05 -05:00
bade51d57d ci(release): bump build number to 400 2025-06-11 21:07:14 -05:00
078c2ec12f feat(helpercommands): added in helpercommnands link 2025-06-11 20:57:10 -05:00
292eb324c5 feat(prod roles): added in quality tech and plant manager 2025-06-11 20:54:09 -05:00
51e6864868 refactor(serverdata): changes to limas tms data and activation 2025-06-11 20:53:40 -05:00
0caf8094de refactor(command log): added in the command log tracking into the 3 we currently have 2025-06-11 20:53:17 -05:00
92c8fc2554 refactor(forcast): changes to consider a plants different addresses 2025-06-11 20:51:43 -05:00
ed777437eb refactor(bookin card): changes to move the button to the right side 2025-06-11 20:51:10 -05:00
353960bd26 feat(new command): helper command to remove as non reusable pallets 2025-06-11 20:50:43 -05:00
6156a1a5bb feat(common commands): added in a common commands just the barecode 2025-06-11 20:49:18 -05:00
826c44c996 fix(removed roles): changes to remove the roles and use userRoles instead 2025-06-11 20:47:43 -05:00
aadf255e34 feat(command log): added new log for all commands used 2025-06-11 20:46:21 -05:00
60690d2df4 ci(release): bump build number to 399 2025-06-11 19:54:31 -05:00
c31dc523e7 ci(release): bump build number to 398 2025-06-11 16:31:41 -05:00
caec533279 ci(release): bump build number to 397 2025-06-11 15:58:33 -05:00
146832b569 ci(release): bump build number to 396 2025-06-11 15:27:06 -05:00
0207e15f38 ci(release): bump build number to 395 2025-06-11 14:40:56 -05:00
2701f18eec ci(release): bump build number to 394 2025-06-11 12:11:31 -05:00
091305ea9f ci(release): bump build number to 393 2025-06-11 11:13:35 -05:00
b8e904b7c9 ci(release): bump build number to 392 2025-06-11 11:02:33 -05:00
990e0a9aa4 ci(release): bump build number to 391 2025-06-11 10:55:09 -05:00
f9fa5defa3 ci(release): bump build number to 390 2025-06-10 16:35:13 -05:00
136bf9820d feat(produser): added in prodSupervisor to the list 2025-06-10 16:23:47 -05:00
ab23dcdfb8 feat(nofitication): bow2 henkel orders
this is a special requet for inhouse when a new incoming goods it grabbed
2025-06-10 16:23:25 -05:00
e1332e754a fix(forecast): changes to png to allow different address id for the portal
closes #21
2025-06-10 16:15:51 -05:00
879172d9cd ci(release): bump build number to 389 2025-06-10 16:07:26 -05:00
bcede5be86 ci(release): bump build number to 388 2025-06-10 15:58:24 -05:00
853f0848a1 ci(release): bump build number to 387 2025-06-10 12:06:40 -05:00
b1856d9155 ci(release): bump build number to 386 2025-06-10 11:58:03 -05:00
7b60ddcadf fix(datamart): fix for delivery date by range error for hardcoded date 2025-06-10 11:47:55 -05:00
12d0c6923d fix(notification template): forgot to remove a end time field data 2025-06-09 19:31:34 -05:00
678f2ebde0 ci(release): bump build number to 385 2025-06-09 19:28:31 -05:00
c26c907431 chore(release): 2.22.0 2025-06-09 19:27:48 -05:00
72a9ca5f87 fix(produser): changes for planning default user 2025-06-09 19:27:27 -05:00
94c3bb73b3 fix(notifications): changes to help improve the downtime check for greater than x only while active 2025-06-09 19:26:36 -05:00
c0560770da ci(release): bump build number to 384 2025-06-09 19:08:39 -05:00
63179e71cc ci(release): bump build number to 383 2025-06-09 19:02:42 -05:00
8d8fdefce8 ci(release): bump build number to 382 2025-06-09 18:34:57 -05:00
1bfe923379 ci(release): bump build number to 381 2025-06-09 18:27:31 -05:00
956a376d13 ci(release): bump build number to 380 2025-06-09 17:06:02 -05:00
d29de68608 ci(release): bump build number to 379 2025-06-09 16:49:14 -05:00
5301575f92 ci(release): bump build number to 378 2025-06-09 16:45:25 -05:00
bcde9a7d45 test(fifo index): testing for fifo indexing 2025-06-09 16:44:05 -05:00
37a4b83f8d fix(printers): removed the printer default time during update 2025-06-09 16:43:45 -05:00
ad4c9502fa feat(produser): added the ability to add a prod user by default roles and update if already there 2025-06-09 16:42:49 -05:00
ed44b11e5c ci(release): bump build number to 377 2025-06-09 13:01:19 -05:00
89ce8f2299 ci(release): bump build number to 376 2025-06-09 12:53:04 -05:00
29e0347f84 feat(server service): added in start stop and restart from vms036 2025-06-09 11:42:27 -05:00
a4dab55f7a ci(release): bump build number to 375 2025-06-09 10:40:20 -05:00
f5f376bc2e ci(release): bump build number to 374 2025-06-09 10:07:20 -05:00
c9d2782241 ci(release): bump build number to 373 2025-06-09 09:23:31 -05:00
18d5988f8f ci(release): bump build number to 372 2025-06-09 09:21:06 -05:00
deb8196093 ci(release): bump build number to 371 2025-06-09 08:34:05 -05:00
058e93b79b ci(release): bump build number to 370 2025-06-09 08:11:16 -05:00
b23c06cba6 fix(labeling process): build failed due to bad return function updated and rebuilt 2025-06-05 10:51:17 -05:00
23677efbe5 refactor(readme): put the install in the readme now 2025-06-05 10:50:47 -05:00
b742698fe0 ci(release): bump build number to 369 2025-06-05 01:30:33 -05:00
a89087b7fa test(iis test): testing to put lst in iis to get ssl :D 2025-06-05 01:26:47 -05:00
6651f83da8 fix(notify): fix for scac code when there is more characters after the split 2025-06-05 01:26:17 -05:00
788fc5f745 fix(ocp): possible fix for slc and crashing during mm check 2025-06-05 01:25:33 -05:00
4f8dfeeff6 ci(release): bump build number to 368 2025-06-03 01:53:16 -05:00
b19fb6aeb6 refactor(historical eom): added logging to know when it fires off 2025-05-31 02:17:54 -05:00
c94f501f95 fix(quality notification): corrected the name in the logging 2025-05-31 02:17:25 -05:00
2672e89005 feat(barcode gen): added in lane exports both single and multiple intial release 2025-05-31 02:17:00 -05:00
a6844d9455 ci(release): bump build number to 367 2025-05-31 02:05:47 -05:00
563aafcf78 ci(release): bump build number to 366 2025-05-29 11:58:08 -05:00
b8e764ec3f ci(release): bump build number to 365 2025-05-29 11:02:42 -05:00
553f76b81a ci(release): bump build number to 364 2025-05-29 10:57:01 -05:00
055d11ccac ci(release): bump build number to 363 2025-05-29 09:52:41 -05:00
96deca15f0 feat(eom): added in historical inv data split accordingly 2025-05-28 17:01:22 -05:00
25cfee58d0 ci(release): bump build number to 362 2025-05-28 16:26:56 -05:00
3eb87b5c0b ci(release): bump build number to 361 2025-05-28 15:27:09 -05:00
0df1225e2f ci(release): bump build number to 360 2025-05-28 15:21:45 -05:00
d8b9326e0e ci(release): bump build number to 359 2025-05-28 14:55:10 -05:00
67d5a28170 refactor(forecast notes): added in a note about needing to be default address 2025-05-28 11:53:32 -05:00
4182ce94c5 feat(pg forcast): added to ksc 2025-05-28 11:51:36 -05:00
23da6c6304 feat(datamart): included fifoindex monitor 2025-05-28 11:51:15 -05:00
a07a9d2145 ci(release): bump build number to 358 2025-05-28 09:53:53 -05:00
3687179646 ci(release): bump build number to 357 2025-05-27 16:18:16 -05:00
fb66a5559f refactor(query check): refactoring query data for edi in orders 2025-05-27 15:02:04 -05:00
208bbecb96 fix(serverdata): added in server data street address update 2025-05-27 15:01:27 -05:00
d07d1000c3 test(fifo index): running fifo index data on 2 servers as a trial to validate data 2025-05-27 15:01:07 -05:00
f8001f2497 ci(release): bump build number to 356 2025-05-27 14:43:01 -05:00
8a890182be ci(release): bump build number to 355 2025-05-27 13:52:13 -05:00
eb1dc06b89 ci(release): bump build number to 354 2025-05-27 13:30:47 -05:00
61dccf9dd0 fix(scac check): changes to also ignore if user put in [ 2025-05-23 12:11:08 -05:00
c2da6cf4fd feat(fakeedi): added in remark to the templates 2025-05-23 12:10:43 -05:00
1e079e8381 refactor(bet server data): changes to email and phone number 2025-05-23 12:10:10 -05:00
308 changed files with 40489 additions and 4937 deletions

7
.gitignore vendored
View File

@@ -11,6 +11,10 @@ backend-0.1.2-218.zip
backend-0.1.2.zip
postgresql-17.2-3-windows-x64.exe
jsTesting
dotnetwrapper/bin
dotnetwrapper/obj
dotnetwrapper/wwwroot
prodBuild
# ---> Node
@@ -151,3 +155,6 @@ dist
backend-0.1.3.zip
BulkForecastTemplate
BulkOrdersTemplate
check.json
server/services/ocp/controller/materials/materialcheck.bak

8
.includes Normal file
View File

@@ -0,0 +1,8 @@
database
dist
frontend/dist
CHANGELOG.md
drizzle.config.ts
package.json
package-lock.json
README.md

View File

@@ -1,5 +1,271 @@
# All CHanges to LST can be found below.
## [2.27.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.26.0...v2.27.0) (2025-09-10)
### 🌟 Enhancements
* **eom:** lastSales, lastPurch added to be pulled with new template ([7cc3778](https://git.tuffraid.net/cowch/lstV2/commits/7cc3778506fc92392ca8431aee0edb203861e10d))
### 🛠️ Code Refactor
* **cosume:** changes to allow non logged in users to use this function ([271cdbd](https://git.tuffraid.net/cowch/lstV2/commits/271cdbdbfa2478ecf56e9b01a4474508acacda2e))
* **mm query:** changes to the query to see pkg and materials properly and not duplicates ([57966ac](https://git.tuffraid.net/cowch/lstV2/commits/57966ac9de72543014451b7ccd75539296ccaa51))
* **rfid:** changes to show all tags vs only 3 if there are more ([b677bc1](https://git.tuffraid.net/cowch/lstV2/commits/b677bc14981faff30c91f6ffe4602319dd3c6016))
* **silo card:** changes to allow viewers to see and able to attach and detach ([796a8dc](https://git.tuffraid.net/cowch/lstV2/commits/796a8dccd2807890abdff7c8dacf8b2246eb265e))
* **sql:** articles added in UOM ([cfed981](https://git.tuffraid.net/cowch/lstV2/commits/cfed981928a56389e09ef428c43ceabc1caec28e))
### 🐛 Bug fixes
* **article check:** corrected the query to not have a specfic plant in it ([79f1f8f](https://git.tuffraid.net/cowch/lstV2/commits/79f1f8f91ba33533de7f4a7cc91503cfd8dd4ce5))
* **bookin:** corrected the bookin in error response ([1f8b8a7](https://git.tuffraid.net/cowch/lstV2/commits/1f8b8a7248c11c7e264c8c5ae7c042c5a0878c46))
* **bookin:** corrections to only show the message on error vs the json ([b3ce767](https://git.tuffraid.net/cowch/lstV2/commits/b3ce767b323c990c0ccf35ad6c2c67136a27272e))
* **db:** changes to the user so it deletes correctly ([932a72b](https://git.tuffraid.net/cowch/lstV2/commits/932a72ba884673471f0056e721cc3f2c8e34b4f3))
* **eomservice:** changes to stop a crash incase the sql returned nothing due to start up ([6caa598](https://git.tuffraid.net/cowch/lstV2/commits/6caa5984e7a3e7b48b119c176835663ffec71151))
* **frontend:** typos ([c6f6ef6](https://git.tuffraid.net/cowch/lstV2/commits/c6f6ef626295f452cdf26f6776b74cfb3b1a10f5))
* **label query:** fixes to only pull in active layouts ([99ecf52](https://git.tuffraid.net/cowch/lstV2/commits/99ecf52218556e048ba9262e74f9b3d020dea31d))
* **main material check:** corrections to properly ignore pkg during color checks ([6910550](https://git.tuffraid.net/cowch/lstV2/commits/6910550de769dce04b1045f96ab19cf7b8d1ef8c))
* **material check:** split manual material out of the mm to properly catch it ([a53915a](https://git.tuffraid.net/cowch/lstV2/commits/a53915ad8cbec5bd8d6ba4643c460ad0162249e2))
* **materials:** more fixes to try and please all plants to use this version and not call me ([00899a5](https://git.tuffraid.net/cowch/lstV2/commits/00899a5b778eab792b350a0b47589de1524d91c8))
* **register:** changes to not give everyone system admin ([415d2e4](https://git.tuffraid.net/cowch/lstV2/commits/415d2e4a1d851cc46ac64ffc814a280a02293bbc))
## [2.26.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.25.0...v2.26.0) (2025-08-28)
### 🛠️ Code Refactor
* **labeling:** moved bookin fails inside bookin as it could be off ([df42319](https://git.tuffraid.net/cowch/lstV2/commits/df423192bfc5e2389872147e92b7d22e648a2927))
* **labeling:** removed the wrong import ([788d636](https://git.tuffraid.net/cowch/lstV2/commits/788d6367a380a81722a76bd6adbe18831d88eeb5))
* **materials:** changes for permissions on material consume ([3148aa7](https://git.tuffraid.net/cowch/lstV2/commits/3148aa79d73823499824cc0601fcabec97bb4f9d))
* **materials:** changes to allow exact and eom transfers ([0a6ddea](https://git.tuffraid.net/cowch/lstV2/commits/0a6ddea8c0d2773aba00266df7e2839879d10cb1))
* **notifcations:** changed hour to min in ti intergrations ([73d38ba](https://git.tuffraid.net/cowch/lstV2/commits/73d38ba3fe7ab4d5ca3a4a1e1c99fdd7bf5e92dc))
* **tms intergration:** corrected how we added gl coding ([37f82a9](https://git.tuffraid.net/cowch/lstV2/commits/37f82a9710cf20e6d0d056893c9da43c70b9e619))
### 🌟 Enhancements
* **materials:** added in a bigger window on eom transfer lots ([53ed2c4](https://git.tuffraid.net/cowch/lstV2/commits/53ed2c4e6a0d3fafafbcb655b5d06cff6324363d))
* **ocp:** zechetti 1 added in ([27586e9](https://git.tuffraid.net/cowch/lstV2/commits/27586e923a106f2b8dd804e9c8292edd5d009cf0))
* **rfid:** new check to remove tags that have been at a line longer than 6 hours ([0ba338d](https://git.tuffraid.net/cowch/lstV2/commits/0ba338d48037f7def74196ca3f41de5807e2cb31))
* **tms:** a clean up function was added to remove releases added as blockers older than 45d ([662a951](https://git.tuffraid.net/cowch/lstV2/commits/662a951b9871d5dfc21f01a76ba23be77b475757))
### 📝 Testing Code
* **forklifts:** forklift starting process ([8c296c5](https://git.tuffraid.net/cowch/lstV2/commits/8c296c5b783f42f85c30a955d6e9d540c50dcfbe))
### 🐛 Bug fixes
* **bookin:** corrected the error received from the book in fail ([369d160](https://git.tuffraid.net/cowch/lstV2/commits/369d16018c8be9fdb936afbc3749b3f9fcea58c8))
* **dm:** corrected the remark section so its properly sent over ([68901a8](https://git.tuffraid.net/cowch/lstV2/commits/68901a857ae5161f024da9cdefc0a981a4907205))
* **eom stats:** corrections to the eom inv stuff to be proper tiems ([468f933](https://git.tuffraid.net/cowch/lstV2/commits/468f933168cc40be0c1b159c31948a2c97600390))
* **fake edi:** removed console log ([24a97af](https://git.tuffraid.net/cowch/lstV2/commits/24a97afe064d5c44872e24e6e3299ed5f2977a78))
* **material check:** alt mm causing issues and utilizing an 80% to just be ok ([f4f3de4](https://git.tuffraid.net/cowch/lstV2/commits/f4f3de49cae277ffa158116d1802495b27fa8e75))
* **ocp:** zechetti type correction to include the printer name ([4486fe2](https://git.tuffraid.net/cowch/lstV2/commits/4486fe24362b4811d7cff0467c7f2f85e0c9e3c4))
* **produser:** changes to include DM ([8d6ead3](https://git.tuffraid.net/cowch/lstV2/commits/8d6ead3aa11aed95ffa3537fbe72cfa9bbceb380))
* **transferlots:** missed adding this ([846ac47](https://git.tuffraid.net/cowch/lstV2/commits/846ac479b1bf211a7891ae362525ea14580ff0cc))
## [2.25.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.24.1...v2.25.0) (2025-08-21)
### 🐛 Bug fixes
* **dm page:** correction to the insturcitons ([a36552f](https://git.tuffraid.net/cowch/lstV2/commits/a36552fd9b9c77f8ecee8b36f45e613383841f95))
* **dyco:** correction to disable the camera if ocme is off ([c7bb128](https://git.tuffraid.net/cowch/lstV2/commits/c7bb12822b13c0c1c929d2c8a9ab150cd0feeff2))
* **gotransport:** error handling so we dont get spammed with errors ([2eb6fa7](https://git.tuffraid.net/cowch/lstV2/commits/2eb6fa77946d5f8572ffc5baa47da602482bce2b))
* **https fixes:** made it so the settings can be grabbed via https ([803c963](https://git.tuffraid.net/cowch/lstV2/commits/803c963f964f26095b2aa6a7d0a60e03615d4c17))
* **inv cards:** correction to properly display the names ([2288884](https://git.tuffraid.net/cowch/lstV2/commits/22888848291aa3df4ebbdd224656731fbb305fa7))
* **inv query:** error in improper placed , in the query ([397f1da](https://git.tuffraid.net/cowch/lstV2/commits/397f1da595fd8a1e1c2a630a3650eb8715604c82))
* **mainmaterial check:** if the machine dose not require mm to be staged properly ignore ([0d17fef](https://git.tuffraid.net/cowch/lstV2/commits/0d17fef1a1c75dd0f27988fd2e3527b508b915cb))
### 🛠️ Code Refactor
* **migration progress:** moved to start looking at the go backedn ([a0179a4](https://git.tuffraid.net/cowch/lstV2/commits/a0179a41bac93d2a7320802e9d70aa966ed79ae4))
* **migrations:** not needed but we have it and needed to correct the settings ([2ff7b9b](https://git.tuffraid.net/cowch/lstV2/commits/2ff7b9baf9ca288f8a33bec3ab1a2ba331ace6b9))
* **notifications:** refactored the cron job system so we can utilize outside the service ([103171c](https://git.tuffraid.net/cowch/lstV2/commits/103171c924a9de78b0a7600abb455fdd6f4bfea1))
* **siloadjustment:** refactored to get the settings from the state vs direct from db ([8145dc8](https://git.tuffraid.net/cowch/lstV2/commits/8145dc800dced31860a926c80eca72cb39433b29))
### 🌟 Enhancements
* **dm:** changes to have a default time if nothing is passed in the excel ([9e5577e](https://git.tuffraid.net/cowch/lstV2/commits/9e5577e6bb4ff3b6c4004288e177fbab322a4b44))
* **eom:** added in hostorical data and deletion for data over 45 days ([52345bc](https://git.tuffraid.net/cowch/lstV2/commits/52345bc94c9e8abc82150fb371a9ba0d0757f16a))
* **migration start:** this starts the migration of all settings to look at the go backend vs this ([998e84f](https://git.tuffraid.net/cowch/lstV2/commits/998e84f5648148c9a94df7177a3d311e16bf4614))
* **ocp:** materials contorls and transfer to next lot logic ([88f61c8](https://git.tuffraid.net/cowch/lstV2/commits/88f61c8eaa32a581094b04b5e18c654040dbeb92))
* **prodrole:** added in planner role ([6ccf500](https://git.tuffraid.net/cowch/lstV2/commits/6ccf500e5eb82125f7bcd3d764282a4b8a750be9))
* **psi:** psi querys added and av grab right now ([8d63f7f](https://git.tuffraid.net/cowch/lstV2/commits/8d63f7f6b0981d604b628ff2f710b8eb41d32837))
### [2.24.1](https://git.tuffraid.net/cowch/lstV2/compare/v2.24.0...v2.24.1) (2025-07-25)
### 🛠️ Code Refactor
* **serverdata:** moved stp1 to d drive ([f57426c](https://git.tuffraid.net/cowch/lstV2/commits/f57426cf13b11b357a1436317f592286084e0fb1))
* **zip builds:** removed the c# wrapper as it wont be used on this build anymore ([e3a4ef7](https://git.tuffraid.net/cowch/lstV2/commits/e3a4ef7a804390cf1e381766baf7baf60b873a57))
### 🐛 Bug fixes
* **create labels:** better logging to know where the error came from ([d40ed30](https://git.tuffraid.net/cowch/lstV2/commits/d40ed30f55b1fb1a3c7a4ecde6dc40c535f3c0ed))
* **mm check:** correction to know if a machine is required to have mm or not ([39d0768](https://git.tuffraid.net/cowch/lstV2/commits/39d0768d503c415b5d1ca845db2a292613f4fbed))
* **submodules:** correction to accessing when changes made to roles ([3e680a5](https://git.tuffraid.net/cowch/lstV2/commits/3e680a5a503761a4a358b4a62e07c4aa545a6f10))
## [2.24.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.23.0...v2.24.0) (2025-07-15)
### 📝 Chore
* **updated packages:** all pacakges were just updated ([4a02bbc](https://git.tuffraid.net/cowch/lstV2/commits/4a02bbc3686f6ed150f1f22146c924aacf1f6b1b))
### 📝 Testing Code
* **material returns:** added type check ([d6d19f8](https://git.tuffraid.net/cowch/lstV2/commits/d6d19f8e5b81d34652c9b7421cb934a81ef03136))
### 🌟 Enhancements
* **default accounts:** added in a default account run this will create a bunch of system admins ([b9ff0a4](https://git.tuffraid.net/cowch/lstV2/commits/b9ff0a4138843e191351f2bcec75e8305a78d6f2))
* **labeling:** ratios reset for labeling implemeneted ([61f0b7f](https://git.tuffraid.net/cowch/lstV2/commits/61f0b7f06b8f0a811387dc3f17fcacb00804d146))
* **labelratio:** new feature to monitor label ratio from auto and manual ([4130878](https://git.tuffraid.net/cowch/lstV2/commits/41308788fdc5e918450db0721199bd4ac7da17e7))
* **logistics:** get sscc based on runnning number ([7df512a](https://git.tuffraid.net/cowch/lstV2/commits/7df512acaa3a2b3cc30131d61563580c124d4f05))
* **notifcations:** pallets booked as waste brought back in via cycle count ([095d724](https://git.tuffraid.net/cowch/lstV2/commits/095d724e65f211253ccdb075a2afb3c5ad267932))
* **notify:** shortage bookings based on time and article type ([c5bd5a7](https://git.tuffraid.net/cowch/lstV2/commits/c5bd5a7c0a074ac1b94fa5435992f2b9a8e65132))
* **prodroles:** added in quality manager ([4abecd0](https://git.tuffraid.net/cowch/lstV2/commits/4abecd045556c98b42cd6ac132958a32a3279a54))
* **prodroles:** new cto role added ([ab8102a](https://git.tuffraid.net/cowch/lstV2/commits/ab8102afbfc62ba41de38c021ab7c0a78e972a90))
* **readers:** added in good and bad reads to monitor eff ([c0ede87](https://git.tuffraid.net/cowch/lstV2/commits/c0ede8714cd99e9b92b4169b9eaf90de3e1d46ab))
* **rfid:** added in manual trigger for rfid reader at the wrapper ([7497ee4](https://git.tuffraid.net/cowch/lstV2/commits/7497ee454c792fabe2c5bd0427f63e725b4a781e))
* **rfid:** front end view of the readers and there status ([f7b4de8](https://git.tuffraid.net/cowch/lstV2/commits/f7b4de813051f1bd28fea98c6473a156024b1a1c))
* **rfid:** more rfid topics while monitoring the system run ([6a082d9](https://git.tuffraid.net/cowch/lstV2/commits/6a082d97375be872ecec33c2045d37c8368d790a))
* **silo attached detach:** added in silo attach detach setup in the silo card ([2ac4813](https://git.tuffraid.net/cowch/lstV2/commits/2ac48138cba961fc09853ab16b4bb2f1dc2972f0))
### 🛠️ Code Refactor
* **consume material:** changes to use api vs prod user ([bc54b36](https://git.tuffraid.net/cowch/lstV2/commits/bc54b365ea9472170a1d22364ac3d9b635175386))
* **datamart:** changes to customer inventory to include specific whse ([3073df3](https://git.tuffraid.net/cowch/lstV2/commits/3073df342ff2ede979d2e7f4b2bb16dacb99c093))
* **dbscheme:** refactoring from opening and saving ([c155e89](https://git.tuffraid.net/cowch/lstV2/commits/c155e89bc7e62a4beb09b4978445075c088d0133))
* **dyco:** change the plc check time from 5 > 8 ([e50e9af](https://git.tuffraid.net/cowch/lstV2/commits/e50e9af839caf9aca8bf71419433bee41702a656))
* **dyco:** pickup changed to let spam again so we dont miss anything ([49fd9d6](https://git.tuffraid.net/cowch/lstV2/commits/49fd9d65c9cf23c1524ec2d4c16628cb742a6077))
* **finance query:** changes to include article type ([26ceb95](https://git.tuffraid.net/cowch/lstV2/commits/26ceb95daefa1615dbc4e41f68763283c1ae91a3))
* **lim:** shipping hours change ([7ed9db1](https://git.tuffraid.net/cowch/lstV2/commits/7ed9db1bdb2c5a1fee867d1501fc909f47e8ddaf))
* **mm check:** added in a check that if we dont need mm we return mm checked ([58711be](https://git.tuffraid.net/cowch/lstV2/commits/58711becf2eec518ebca9a0239c2b97f23b38372))
* **ocp page:** changes to the layout so it can better be moved for the tiles ([f757085](https://git.tuffraid.net/cowch/lstV2/commits/f757085fc2936c929fbfce19e9784ab14654193d))
* **printers:** addedin daily check for printers used to only be on a restart ([588f264](https://git.tuffraid.net/cowch/lstV2/commits/588f264854a5898f633114032398608985e4371c))
* **rfid:** ratio resets implemeneted ([a7f8e39](https://git.tuffraid.net/cowch/lstV2/commits/a7f8e39bac684b94a68ed484987b9c6c1693e3ec))
* **rfid:** reduced teh rssi peak -50 > -40 ([a19ac53](https://git.tuffraid.net/cowch/lstV2/commits/a19ac539e7e65741858730e2089517756962c558))
* **server data:** changes to bet and stp1 ([bd5bad3](https://git.tuffraid.net/cowch/lstV2/commits/bd5bad3cba587f53c8c6e31555c6433620c7a474))
* **serverdb:** format changes ([77d9e5d](https://git.tuffraid.net/cowch/lstV2/commits/77d9e5d095a1f31fcbdd094b2dd39b89ddabce87))
* **wrapper card:** changes to include the rfid and remove the manual trigger as no one used it ([8f5e1cb](https://git.tuffraid.net/cowch/lstV2/commits/8f5e1cb0948354d13b7def478226e3e82b377829))
### 🐛 Bug fixes
* **dashboard:** some more rending fixes due to some strange behaivers ([f4dd572](https://git.tuffraid.net/cowch/lstV2/commits/f4dd572a8f8889c5938145ef9d74621da27ae206))
* **db:** lastRead column was named incorrectly ([1a6a051](https://git.tuffraid.net/cowch/lstV2/commits/1a6a05112b869358b3f2e87e688670ab95eb27a7))
* **detach silo:** when pressing cancel the detach funciton would not work ([05fa774](https://git.tuffraid.net/cowch/lstV2/commits/05fa774d68c5bb006dd7fb317138bbc630a1cf55))
* **dm:** missing api key call, and better logging on the post orders section ([531b343](https://git.tuffraid.net/cowch/lstV2/commits/531b343d17a0706bb18f8c7fc047422c5348fb92))
* **label ratio:** missed a manual spot that was not considered ([e6f3a9b](https://git.tuffraid.net/cowch/lstV2/commits/e6f3a9b4d07765264d788a261a7b10c731d19987))
* **logs:** time crap ([e13b5a4](https://git.tuffraid.net/cowch/lstV2/commits/e13b5a42836f337607f2fc0fd359c3f8cfdf4443))
* **ocp page:** server info error added check to make sure was there ([3cafbd9](https://git.tuffraid.net/cowch/lstV2/commits/3cafbd92d0d1fd6dbdb8d92cfa811b9eaa7c60d0))
* **renderfixes:** some strange rendering fixes that should have been caught long time ago ([3b56a5e](https://git.tuffraid.net/cowch/lstV2/commits/3b56a5e3e2d37858be4c4ce08f33abbf31f141d0))
* **rfid reader:** ratio to be fixed 2 digits so it dose not span across the entire page ([c6d80db](https://git.tuffraid.net/cowch/lstV2/commits/c6d80dbc8a0dcb5a8b219913c9dec1065208012e))
* **rfid:** corrections to the manual tag to no fail on manual when a tag already exists but failed ([33295dc](https://git.tuffraid.net/cowch/lstV2/commits/33295dc3c39569d818d4c7245390891e34080c9d))
* **rfid:** existing tags were trying to be inserted and instead of updating failed corrected ([1c910d8](https://git.tuffraid.net/cowch/lstV2/commits/1c910d80ead6b9196dd4181534c6044a007e81b5))
* **rfid:** lots of changes to the wrapper area ([7a4dea9](https://git.tuffraid.net/cowch/lstV2/commits/7a4dea9d87fa15def544d810b8da422acd142e6c))
* **rfid:** typos in station 3 logging ([56e0f3e](https://git.tuffraid.net/cowch/lstV2/commits/56e0f3eb47a1c34b9b07121bc6189e793e08eea5))
* **settings page:** error with the store not starting as fast as the page ([edc874c](https://git.tuffraid.net/cowch/lstV2/commits/edc874c302a8693b5d7a3abdb98cd95f44134e49))
## [2.23.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.22.0...v2.23.0) (2025-06-17)
### 📝 Testing Code
* **added in commands:** relocate and updated to remove ([e865c1d](https://git.tuffraid.net/cowch/lstV2/commits/e865c1dcaf8e9ee3710f8d9f65e95118bb3fa3e7))
* **return preforms:** start to preform return ([3283972](https://git.tuffraid.net/cowch/lstV2/commits/328397280954fbf6668e2014b0ce28c885ee417d))
### 🐛 Bug fixes
* **datamart:** fix for delivery date by range error for hardcoded date ([7b60ddc](https://git.tuffraid.net/cowch/lstV2/commits/7b60ddcadf0b6b6e9c9d4e7efd928cf48bcfee0f))
* **forecast:** changes to png to allow different address id for the portal ([e1332e7](https://git.tuffraid.net/cowch/lstV2/commits/e1332e754a163bfc882ffb54e6e2bd741579fad1)), closes [#21](https://git.tuffraid.net/cowch/lstV2/issues/21)
* **lots:** corrections to role issue where user logged in but no role set yet ([68d7527](https://git.tuffraid.net/cowch/lstV2/commits/68d75277c2490cd25c6f52dd18663fba0c5cd932))
* **notification template:** forgot to remove a end time field data ([12d0c69](https://git.tuffraid.net/cowch/lstV2/commits/12d0c6923d1b177d60bf34b5c70168d0e7eb982d))
* **produser:** changes to get correct response from errors ([3c45010](https://git.tuffraid.net/cowch/lstV2/commits/3c45010b268ba9aaa0b0b165a8ac06d7d58de9ad))
* **removed roles:** changes to remove the roles and use userRoles instead ([826c44c](https://git.tuffraid.net/cowch/lstV2/commits/826c44c9967130f26ddbcfc2e8f4d43673819a71))
### 🌟 Enhancements
* **command log:** added new log for all commands used ([aadf255](https://git.tuffraid.net/cowch/lstV2/commits/aadf255e343bb10bed399f6db20671b15e88ce8a))
* **common commands:** added in a common commands just the barecode ([6156a1a](https://git.tuffraid.net/cowch/lstV2/commits/6156a1a5bb6ce2dfd160a7877c4cb1d8c91fac3f))
* **datamart:** finance inventory audit added ([90be86d](https://git.tuffraid.net/cowch/lstV2/commits/90be86d972d4660d87e0b8f41e7f2b1a22838e9c))
* **dotnet:** added in wrapper so we could run in iis for ssl :D ([84aacd5](https://git.tuffraid.net/cowch/lstV2/commits/84aacd5b71b0efab36eb91c0ba7f2d362dd6b736))
* **helpercommands:** added in helpercommnands link ([078c2ec](https://git.tuffraid.net/cowch/lstV2/commits/078c2ec12f3a08094d661d1839373b9adf00f07d))
* **new command:** helper command to remove as non reusable pallets ([353960b](https://git.tuffraid.net/cowch/lstV2/commits/353960bd267e55b24c59a4a654cc37411c9986c7))
* **nofitication:** bow2 henkel orders ([ab23dcd](https://git.tuffraid.net/cowch/lstV2/commits/ab23dcdfb81fddf6881ddaa17111c8115c7002b0))
* **prod roles:** added in quality tech and plant manager ([292eb32](https://git.tuffraid.net/cowch/lstV2/commits/292eb324c549c6febc58af8b0a587d241d458c9e))
* **produser:** added in prodSupervisor to the list ([136bf98](https://git.tuffraid.net/cowch/lstV2/commits/136bf9820d6df837c1db37b4e38bcdd9375730d3))
* **produser:** added in the function to create a standard user based on there username ([99ad79c](https://git.tuffraid.net/cowch/lstV2/commits/99ad79c662cfeddd78bc86792852e8e97b14e287))
### 🛠️ Code Refactor
* **bookin card:** changes to move the button to the right side ([ed77743](https://git.tuffraid.net/cowch/lstV2/commits/ed777437eb6b5a9d8b179c8182883dac3c731683))
* **command log:** added in the command log tracking into the 3 we currently have ([0caf809](https://git.tuffraid.net/cowch/lstV2/commits/0caf8094de588e64b3dcda99d023d39e62bbbf5a))
* **forcast:** changes to consider a plants different addresses ([92c8fc2](https://git.tuffraid.net/cowch/lstV2/commits/92c8fc25544f4b56fde1348d7040498bd650dcb1))
* **ocme:** changes in the pickup to no longer handle all but specific area ([d32289c](https://git.tuffraid.net/cowch/lstV2/commits/d32289c8337eed71d5abb29d0dd8c8741af52ac9))
* **ocme:** picked up per location now vs picked up all ([37f2518](https://git.tuffraid.net/cowch/lstV2/commits/37f2518589935788c142965dff1ff5b9fb6ab902))
* **picked up pallets:** changes to start picking up only area from spot ([f79ff26](https://git.tuffraid.net/cowch/lstV2/commits/f79ff26958c7f3e4560da73d2a5fb0fd9a6443e6))
* **printers:** added in processes for the upcoming reprint function ([1cb285b](https://git.tuffraid.net/cowch/lstV2/commits/1cb285bea86828d0f3fa7cc42a25495681b0e336))
* **serverdata:** changes to limas tms data and activation ([51e6864](https://git.tuffraid.net/cowch/lstV2/commits/51e68648681981aee393ee9c1a729534b9a3983a))
## [2.22.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.21.0...v2.22.0) (2025-06-10)
### 🛠️ Code Refactor
* **bet server data:** changes to email and phone number ([1e079e8](https://git.tuffraid.net/cowch/lstV2/commits/1e079e8381aa828c110f8e3879c8b79dbb5ff0a4))
* **forecast notes:** added in a note about needing to be default address ([67d5a28](https://git.tuffraid.net/cowch/lstV2/commits/67d5a28170a2b8def348b4d7223ca52c79b8ce3f))
* **historical eom:** added logging to know when it fires off ([b19fb6a](https://git.tuffraid.net/cowch/lstV2/commits/b19fb6aeb652d3269f4b2bf89b12618ff2989975))
* **query check:** refactoring query data for edi in orders ([fb66a55](https://git.tuffraid.net/cowch/lstV2/commits/fb66a5559fc34ebd4f148a10d053ec62d3837768))
* **readme:** put the install in the readme now ([23677ef](https://git.tuffraid.net/cowch/lstV2/commits/23677efbe5a991ed2b06ed280677efe6c4e4d6f2))
### 🌟 Enhancements
* **barcode gen:** added in lane exports both single and multiple intial release ([2672e89](https://git.tuffraid.net/cowch/lstV2/commits/2672e890054cf6b13a519a09c39c37e253fefe1e))
* **datamart:** included fifoindex monitor ([23da6c6](https://git.tuffraid.net/cowch/lstV2/commits/23da6c6304e5f4be42486efcc3a12733b63a4442))
* **eom:** added in historical inv data split accordingly ([96deca1](https://git.tuffraid.net/cowch/lstV2/commits/96deca15f0d3c251793fcd49d224c8c2c40811f8))
* **fakeedi:** added in remark to the templates ([c2da6cf](https://git.tuffraid.net/cowch/lstV2/commits/c2da6cf4fdaee7a6c4ca3b819e9272d5c6f2d58f))
* **pg forcast:** added to ksc ([4182ce9](https://git.tuffraid.net/cowch/lstV2/commits/4182ce94c51b8c34bd724340d22285ce4a0e71e8))
* **produser:** added the ability to add a prod user by default roles and update if already there ([ad4c950](https://git.tuffraid.net/cowch/lstV2/commits/ad4c9502fa5cff5b2b68f4f5ba4eebab019f2b96))
* **server service:** added in start stop and restart from vms036 ([29e0347](https://git.tuffraid.net/cowch/lstV2/commits/29e0347f84c65add15da434a2acdc6c126062518))
### 📝 Testing Code
* **fifo index:** running fifo index data on 2 servers as a trial to validate data ([d07d100](https://git.tuffraid.net/cowch/lstV2/commits/d07d1000c3c3f2f7151032daa4b6da519eab45f3))
* **fifo index:** testing for fifo indexing ([bcde9a7](https://git.tuffraid.net/cowch/lstV2/commits/bcde9a7d45947582c9c0d9b97271c3876c7bd382))
* **iis test:** testing to put lst in iis to get ssl :D ([a89087b](https://git.tuffraid.net/cowch/lstV2/commits/a89087b7fa46378dcb8acda9263ab82e469f53fd))
### 🐛 Bug fixes
* **labeling process:** build failed due to bad return function updated and rebuilt ([b23c06c](https://git.tuffraid.net/cowch/lstV2/commits/b23c06cba6e2d3e437b6fb1350cf8ab47a938e87))
* **notifications:** changes to help improve the downtime check for greater than x only while active ([94c3bb7](https://git.tuffraid.net/cowch/lstV2/commits/94c3bb73b3f52bfa80b1a73808c0c9603d011e24))
* **notify:** fix for scac code when there is more characters after the split ([6651f83](https://git.tuffraid.net/cowch/lstV2/commits/6651f83da8cfef77502e803d2a34d845223b9370))
* **ocp:** possible fix for slc and crashing during mm check ([788fc5f](https://git.tuffraid.net/cowch/lstV2/commits/788fc5f74503f8186e13f7f234685f725e15b308))
* **printers:** removed the printer default time during update ([37a4b83](https://git.tuffraid.net/cowch/lstV2/commits/37a4b83f8dcedcc9ad866880fd2eef35c756d804))
* **produser:** changes for planning default user ([72a9ca5](https://git.tuffraid.net/cowch/lstV2/commits/72a9ca5f87eb100ea9d7e9a71753b3d33611c86a))
* **quality notification:** corrected the name in the logging ([c94f501](https://git.tuffraid.net/cowch/lstV2/commits/c94f501f958980c4b394e4304e29602138c0361d))
* **scac check:** changes to also ignore if user put in [ ([61dccf9](https://git.tuffraid.net/cowch/lstV2/commits/61dccf9dd0bb44cd6e7e376f46fffa461f36f709))
* **serverdata:** added in server data street address update ([208bbec](https://git.tuffraid.net/cowch/lstV2/commits/208bbecb967fc9de76783cf899223d00ac956b0c))
## [2.21.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.20.0...v2.21.0) (2025-05-22)

177
README.md
View File

@@ -1,4 +1,177 @@
# THIS VERSION IS NO LONGER BEING UPDATED PLEASE GO TO THE NEW REPO LINK BELOW
[NEW LST REPO](https://git.tuffraid.net/cowch/lst)
# lstV2
Logistics Support Tool complete rewrite
the rewrite was/is needed due to the learning of all new things over the course of creating this and tools used that the app as become so spagatti its a mess
Logistics Support Tool V2
A support tool to alpla prod please see below for install.
# Install
## Files needed to be downloaded before install.
### To run the server
- [PostgresSQL](https://www.postgresql.org/download/windows/) - current version using is 17
- [NodeJS](https://nodejs.org)
- [NSSM](https://nssm.cc/)
### To manage the server
- [VSCODE](https://code.visualstudio.com/)
- [Postman](https://www.postman.com/downloads/)
## Creating directories needed
- Create a new folder where we will host the server files.
- Copy the nssm.exe into this folder
- Copy the build files to the server (only needed for intial install).
- This will house all the compiles and minified files needed to start the server up, this includes the frontend.
- Save the nssm.exe into this folder as well, this will be used to control the service.
## Do the intial install
### DB instal setup
1. Install postgres
2. Open pgAdmin
3. create a new Database named lst_db
### Intial server setup
1. Open VSCode and navigate to the folder where you extracted the files.
2. Click trusted when it pops up.
3. Open a terminal window inside vscode.
4. Run the install script this will install all dependaceys needed as well as do all the database migrations
```bash
npm run prodinstall
```
Next we want to do an intial build for the db
```bash
npm run build
```
### Create the .env file
In the root of the folder create a new .env file
add in the below and change each setting area that says change me to something that suits your needs
```env
# PORTS
PROD_PORT=4000
# To keep it all simple we will pass VITE to the ports that are used on both sides.
VITE_SERVER_PORT=4000
# logLevel
LOG_LEVEL=info
# Auth stuff
SALTING=12
SECRET=CHANGEME
JWT_SECRET=CHANGEME
JWT_REFRESH_SECRET=CHANGEME
# Expire info plus refresh change as needed
JWT_EXPIRES=60
JWT_REFRESH_THRESHOLD=30
JWT_ACCESS_EXPIRATION="1h"
JWT_REFRESH_EXPIRATION="7d"
# this code will need to be used when a user needs to have access to everything.
SECRETOVERRIDECODE="supersecretKey"
# Database url - please change the password if this is all you changed
DATABASE_URL="postgresql://postgres:PASSWORD@localhost:5432/lst_db"
# This is for usday1 restrictions with the lgvs and customer constraints.
FIFO=100
MAXLOTS=3
```
### Run the start command to get all the basic settings and modules installed
1. Run the below
```bash
npm start
```
This command will start up the server and seed the database.
- Settings will be set here.
- All modules will be added.
2. Press CTRL + C to stop the server.
3. Reopen postgres and review the settings make the changes to match the server your going to be running in.
- Change the server
- change the dbServer
- change plantToken
- then the remaining settings confirm if you need on or want to leave as default.
### Creating first user.
1. Start the server back up.
```bash
npm start
```
2. Open http://[SERVER]:[PORT]/api/docs or postman and create a user.
- Please do not try to manually enter a new user this is due to how the password is hashed, as well as setting systemAdmin for the first user.
- Change the server and port to what you changed in the DB.
3. Stop the server again with CTRL + C.
### Running as a serivice.
You want to CD into the scripts folder.
```bash
cd .\dist\server\scripts\
```
Next use the example command below to get the service up and running.
- Options legend
- serviceName = not recommended to change to reduce issues with the update process
- option = use install for the install, but you can use this script later to stop, start, restart the service.
- appPath = where did you extract the server files
- description = no need to change this unless you want it to be something else
- command = do not change this unless you know what your doing and really need to change this.
```powershell
.\services.ps1 -serviceName "LSTV2" -option "install" -appPath "E:\LST\lstV2" -description "Logistics Support Tool V2" -command "run start"
```
### Adding servers to the mix to update on from the front end
you will need to add your servers into the serverData.json.
when the server starts up it will look at this file and make changes as needed.
below is an example of the server
```JSON
{
"sName": "Kansas City",
"serverDNS": "usksc1vms006",
"plantToken": "usksc1",
"idAddress": "10.42.9.26",
"greatPlainsPlantCode": "85",
"streetAddress": "1800 E 94th St Suite 300",
"cityState": "Kansas City, MO",
"zipcode": "64131",
"contactEmail": "example@example.com",
"contactPhone": "555-555-5555",
"customerTiAcc": "ALPL01KCINT",
"lstServerPort": "4000",
"active": false,
"serverLoc": "E:\\LST\\lstv2",
"oldVersion": "E:\\LST\\lst_backend",
"shippingHours": "[{\"early\": \"06:30\", \"late\": \"23:00\"}]",
"tiPostTime": "[{\"from\": \"24\", \"to\": \"24\"}]",
"otherSettings": [{ "specialInstructions": "" }]
}
```

View File

@@ -0,0 +1,11 @@
CREATE TABLE "fifoIndex" (
"fifoIndex_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"lot" text NOT NULL,
"av" numeric NOT NULL,
"runningNr" numeric NOT NULL,
"prodDate" timestamp NOT NULL,
"fifoFollowed" boolean NOT NULL,
"add_Date" timestamp DEFAULT now()
);
--> statement-breakpoint
CREATE UNIQUE INDEX "fifo_runningNr" ON "fifoIndex" USING btree ("runningNr");

View File

@@ -0,0 +1,16 @@
CREATE TABLE "invHistoricalData" (
"inv_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"histDate" date NOT NULL,
"plantToken" text,
"article" text NOT NULL,
"articleDescription" text NOT NULL,
"materialType" text,
"total_QTY" integer,
"avaliable_QTY" integer,
"coa_QTY" integer,
"held_QTY" integer,
"consignment" integer,
"location" integer,
"upd_user" text,
"upd_date" timestamp
);

View File

@@ -0,0 +1,5 @@
ALTER TABLE "invHistoricalData" ALTER COLUMN "total_QTY" SET DATA TYPE text;--> statement-breakpoint
ALTER TABLE "invHistoricalData" ALTER COLUMN "coa_QTY" SET DATA TYPE text;--> statement-breakpoint
ALTER TABLE "invHistoricalData" ALTER COLUMN "held_QTY" SET DATA TYPE text;--> statement-breakpoint
ALTER TABLE "invHistoricalData" ALTER COLUMN "consignment" SET DATA TYPE text;--> statement-breakpoint
ALTER TABLE "invHistoricalData" ALTER COLUMN "location" SET DATA TYPE text;

View File

@@ -0,0 +1 @@
ALTER TABLE "invHistoricalData" ALTER COLUMN "avaliable_QTY" SET DATA TYPE text;

View File

@@ -0,0 +1,13 @@
CREATE TABLE "prodPermissions" (
"prodPerm_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text NOT NULL,
"description" text NOT NULL,
"roles" jsonb DEFAULT '[]'::jsonb,
"rolesLegacy" jsonb DEFAULT '[]'::jsonb,
"add_User" text DEFAULT 'LST_System' NOT NULL,
"add_Date" timestamp DEFAULT now(),
"upd_User" text DEFAULT 'LST_System' NOT NULL,
"upd_date" timestamp DEFAULT now()
);
--> statement-breakpoint
CREATE UNIQUE INDEX "prodPermName" ON "prodPermissions" USING btree ("name");

View File

@@ -0,0 +1,7 @@
CREATE TABLE "commandLog" (
"commandLog_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"commandUsed" text NOT NULL,
"bodySent" jsonb DEFAULT '[]'::jsonb,
"reasonUsed" text,
"add_Date" timestamp DEFAULT now()
);

View File

@@ -0,0 +1 @@
ALTER TABLE "printerData" ADD COLUMN "processes" jsonb DEFAULT '[]'::jsonb;

View File

@@ -0,0 +1 @@
ALTER TABLE "rfidTags" RENAME COLUMN "timeStamp" TO "lastRead";

View File

@@ -0,0 +1,2 @@
ALTER TABLE "rfidReaders" ADD COLUMN "goodReads" integer DEFAULT 0;--> statement-breakpoint
ALTER TABLE "rfidReaders" ADD COLUMN "badReads" integer DEFAULT 0;

View File

@@ -0,0 +1,10 @@
CREATE TABLE "labelRatio" (
" ratio_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text DEFAULT 'labels',
"autoLabel" integer DEFAULT 0,
"manualLabel" integer DEFAULT 0,
"lastReset" timestamp DEFAULT now()
);
--> statement-breakpoint
ALTER TABLE "invHistoricalData" ADD COLUMN "lot_number" text;--> statement-breakpoint
CREATE UNIQUE INDEX "labelname" ON "labelRatio" USING btree ("name");

View File

@@ -0,0 +1,2 @@
ALTER TABLE "invHistoricalData" ALTER COLUMN "upd_user" SET DEFAULT 'lst';--> statement-breakpoint
ALTER TABLE "invHistoricalData" ALTER COLUMN "upd_date" SET DEFAULT now();

View File

@@ -0,0 +1,3 @@
ALTER TABLE "userRoles" DROP CONSTRAINT "userRoles_user_id_users_user_id_fk";
--> statement-breakpoint
ALTER TABLE "userRoles" ADD CONSTRAINT "userRoles_user_id_users_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("user_id") ON DELETE cascade ON UPDATE no action;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -428,6 +428,90 @@
"when": 1747357513268,
"tag": "0060_daffy_overlord",
"breakpoints": true
},
{
"idx": 61,
"version": "7",
"when": 1748370693078,
"tag": "0061_mature_the_stranger",
"breakpoints": true
},
{
"idx": 62,
"version": "7",
"when": 1748462132080,
"tag": "0062_narrow_silver_centurion",
"breakpoints": true
},
{
"idx": 63,
"version": "7",
"when": 1748463780733,
"tag": "0063_powerful_revanche",
"breakpoints": true
},
{
"idx": 64,
"version": "7",
"when": 1748464203006,
"tag": "0064_aberrant_blindfold",
"breakpoints": true
},
{
"idx": 65,
"version": "7",
"when": 1749492130639,
"tag": "0065_nappy_talos",
"breakpoints": true
},
{
"idx": 66,
"version": "7",
"when": 1749671243377,
"tag": "0066_nosy_dark_beast",
"breakpoints": true
},
{
"idx": 67,
"version": "7",
"when": 1749744049457,
"tag": "0067_shallow_trish_tilby",
"breakpoints": true
},
{
"idx": 68,
"version": "7",
"when": 1752195741709,
"tag": "0068_last_caretaker",
"breakpoints": true
},
{
"idx": 69,
"version": "7",
"when": 1752195894698,
"tag": "0069_chemical_maximus",
"breakpoints": true
},
{
"idx": 70,
"version": "7",
"when": 1754767718941,
"tag": "0070_brief_mephisto",
"breakpoints": true
},
{
"idx": 71,
"version": "7",
"when": 1754768521841,
"tag": "0071_fantastic_old_lace",
"breakpoints": true
},
{
"idx": 72,
"version": "7",
"when": 1757167736042,
"tag": "0072_round_black_knight",
"breakpoints": true
}
]
}

View File

@@ -0,0 +1,25 @@
import { text, pgTable, timestamp, uuid, jsonb } from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
export const commandLog = pgTable(
"commandLog",
{
commandLog_id: uuid("commandLog_id").defaultRandom().primaryKey(),
commandUsed: text("commandUsed").notNull(),
bodySent: jsonb("bodySent").default([]),
reasonUsed: text("reasonUsed"),
add_at: timestamp("add_Date").defaultNow(),
},
(table) => [
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
// uniqueIndex("role_name").on(table.name),
]
);
// 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(commandLog);

View File

@@ -1,12 +1,43 @@
import {date, pgTable, text} from "drizzle-orm/pg-core";
import {createSelectSchema} from "drizzle-zod";
import {
date,
integer,
pgTable,
text,
timestamp,
uuid,
} from "drizzle-orm/pg-core";
import { createSelectSchema } from "drizzle-zod";
export const eom = pgTable(
"eom",
{
eomMonth: date().notNull(),
article: text().notNull(),
articleDescription: text().notNull(),
eom_id: uuid("eom_id").defaultRandom().primaryKey(),
eomMonth: date("eomMonth").notNull(), // what month are we running in should just be the first of current month
plantToken: text("plantToken"),
article: text("article").notNull(),
articleDescription: text("articleDescription").notNull(),
materialType: text("materialType"),
invStart: integer("invStart"), // this will come from the previous month
invEnd: integer("invEnd"),
intransit: integer("intransit"),
// pass over a calculation for ending inv
purchase: integer("purchase"),
gpRecived: integer("gpRecived"),
// pass calcuation for difference
materialIn: integer("materialIn"), // from other alpla plants
materialOut: integer("materialOut"), // out to other alpla plants
quarantine: integer("quarantine"),
// calcualtion for actaul consumption
prodConsumption: integer("prodConsumption"),
// difference will be a calculated number
// waste will be calculated.
priceKg: text("priceKg"), // will be converted to a float and then calcuated into the data
// loss/gain calcualtion
comments: text("comments"),
weight: text("weight"), // for calculations should be converted to a float
pfc: text("pfc"), // profit center this will belong too.
upd_user: text("upd_user"),
upd_date: timestamp("upd_date"),
}
// (table) => [
// // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),

View File

@@ -0,0 +1,40 @@
import {
text,
pgTable,
numeric,
index,
timestamp,
boolean,
uuid,
uniqueIndex,
jsonb,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
export const fifoIndex = pgTable(
"fifoIndex",
{
fifoIndex_id: uuid("fifoIndex_id").defaultRandom().primaryKey(),
lot: text("lot").notNull(),
av: numeric("av").notNull(),
runningNr: numeric("runningNr").notNull(),
prodDate: timestamp("prodDate").notNull(),
// currentInv: jsonb("currentInv").default([]),
fifoFollowed: boolean("fifoFollowed").notNull(),
add_Date: timestamp("add_Date").defaultNow(),
},
(table) => [
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
// uniqueIndex("role_name").on(table.name),
uniqueIndex("fifo_runningNr").on(table.runningNr),
]
);
// 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(fifoIndex);

View File

View File

View File

View File

@@ -0,0 +1,41 @@
import {
date,
integer,
pgTable,
text,
timestamp,
uuid,
} from "drizzle-orm/pg-core";
import { createSelectSchema } from "drizzle-zod";
export const invHistoricalData = pgTable(
"invHistoricalData",
{
inv_id: uuid("inv_id").defaultRandom().primaryKey(),
histDate: date("histDate").notNull(), // this date should always be yesterday when we post it.
plantToken: text("plantToken"),
article: text("article").notNull(),
articleDescription: text("articleDescription").notNull(),
materialType: text("materialType"),
total_QTY: text("total_QTY"),
avaliable_QTY: text("avaliable_QTY"),
coa_QTY: text("coa_QTY"),
held_QTY: text("held_QTY"),
lot_Number: text("lot_number"),
consignment: text("consignment"),
location: text("location"),
upd_user: text("upd_user").default("lst"),
upd_date: timestamp("upd_date").defaultNow(),
}
// (table) => [
// // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
// uniqueIndex("role_name").on(table.name),
// ]
);
// 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(invHistoricalData);

View File

@@ -7,6 +7,7 @@ import {
boolean,
uuid,
uniqueIndex,
jsonb,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
@@ -26,6 +27,7 @@ export const printerData = pgTable(
remark: text("remark"),
printDelay: numeric("printDelay").default("90"),
monitorState: boolean("monitorState").default(false),
processes: jsonb("processes").default([]),
add_Date: timestamp("add_Date").defaultNow(),
upd_date: timestamp("upd_date").defaultNow(),
},

View File

@@ -0,0 +1,38 @@
import {
text,
pgTable,
timestamp,
uuid,
uniqueIndex,
jsonb,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
export const prodPermissions = pgTable(
"prodPermissions",
{
prodPerm_id: uuid("prodPerm_id").defaultRandom().primaryKey(),
name: text("name").notNull(),
description: text("description").notNull(),
roles: jsonb("roles").default([]),
rolesLegacy: jsonb("rolesLegacy").default([]),
add_User: text("add_User").default("LST_System").notNull(),
add_Date: timestamp("add_Date").defaultNow(),
upd_user: text("upd_User").default("LST_System").notNull(),
upd_date: timestamp("upd_date").defaultNow(),
},
(table) => [
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
uniqueIndex("prodPermName").on(table.name),
]
);
// Schema for inserting a user - can be used to validate API requests
// export const insertUsersSchema = createInsertSchema(prodPermissions, {
// name: z
// .string()
// .min(3, { message: "Role name must be longer than 3 characters" }),
// });
// Schema for selecting a Expenses - can be used to validate API responses
export const selectUsersSchema = createSelectSchema(prodPermissions);

32
database/schema/ratios.ts Normal file
View File

@@ -0,0 +1,32 @@
import {
integer,
jsonb,
pgTable,
text,
timestamp,
uniqueIndex,
uuid,
} from "drizzle-orm/pg-core";
import { createSelectSchema } from "drizzle-zod";
export const labelRatio = pgTable(
"labelRatio",
{
ratio_id: uuid(" ratio_id").defaultRandom().primaryKey(),
name: text("name").default("labels"),
autoLabel: integer("autoLabel").default(0),
manualLabel: integer("manualLabel").default(0),
lastReset: timestamp().defaultNow(),
},
(table) => [
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
uniqueIndex("labelname").on(table.name),
]
);
// 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(labelRatio);

View File

@@ -8,6 +8,7 @@ import {
uuid,
uniqueIndex,
jsonb,
integer,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
@@ -23,6 +24,8 @@ export const rfidReaders = pgTable(
lastTriggerGood: boolean("lastTiggerGood").default(true),
active: boolean("active").default(true),
lastTagScanned: text("lastTagScanned"),
goodReads: integer("goodReads").default(0),
badReads: integer("badReads").default(0),
},
(table) => [
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),

View File

@@ -1,6 +1,14 @@
import {text, pgTable, timestamp, uuid, uniqueIndex, jsonb, integer} from "drizzle-orm/pg-core";
import {createInsertSchema, createSelectSchema} from "drizzle-zod";
import {z} from "zod";
import {
text,
pgTable,
timestamp,
uuid,
uniqueIndex,
jsonb,
integer,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
export const rfidTags = pgTable(
"rfidTags",
@@ -8,7 +16,7 @@ export const rfidTags = pgTable(
rfidTag_id: uuid("rfidTag_id").defaultRandom().primaryKey(),
tagHex: text("tagHex"),
tag: text("tag"),
lastRead: timestamp("timeStamp").defaultNow(),
lastRead: timestamp("lastRead").defaultNow(), // cahnge this and hope we dont loose the data.
counts: jsonb("counts").default([]), // example [{area: Line3.2, count: 1}, {area: line3.1, count: 6}]
lastareaIn: text("lastareaIn").notNull(),
runningNumber: integer("runningNumber"),
@@ -23,8 +31,8 @@ export const rfidTags = pgTable(
);
// Schema for inserting a user - can be used to validate API requests
export const insertRolesSchema = createInsertSchema(rfidTags, {
tagHex: z.string().min(3, {message: "Tag Should have more than 3 characters"}),
});
// export const insertRolesSchema = createInsertSchema(rfidTags, {
// tagHex: z.string().min(3, {message: "Tag Should have more than 3 characters"}),
// });
// Schema for selecting a Expenses - can be used to validate API responses
export const selectRolesSchema = createSelectSchema(rfidTags);

View File

@@ -1,5 +1,15 @@
import {boolean, date, jsonb, numeric, pgTable, text, timestamp, uniqueIndex, uuid} from "drizzle-orm/pg-core";
import {createSelectSchema} from "drizzle-zod";
import {
boolean,
date,
jsonb,
numeric,
pgTable,
text,
timestamp,
uniqueIndex,
uuid,
} from "drizzle-orm/pg-core";
import { createSelectSchema } from "drizzle-zod";
export const serverData = pgTable(
"serverData",
@@ -21,9 +31,13 @@ export const serverData = pgTable(
serverLoc: text("serverLoc"),
oldVersion: text("oldVersion"),
lastUpdated: timestamp("lastUpdated").defaultNow(),
shippingHours: text("shippingHours").default('[{"early": "06:30", "late": "23:00"}]'),
shippingHours: text("shippingHours").default(
'[{"early": "06:30", "late": "23:00"}]'
),
tiPostTime: text("tiPostTime").default('[{"from": "24", "to": "24"}]'),
otherSettings: jsonb("otherSettings").default([{specialInstructions: "something for ti", active: false}]),
otherSettings: jsonb("otherSettings").default([
{ specialInstructions: "something for ti", active: false },
]),
isUpgrading: boolean("isUpgrading").default(false),
},

View File

@@ -1,9 +1,18 @@
import {text, pgTable, numeric, index, timestamp, boolean, uuid, uniqueIndex} from "drizzle-orm/pg-core";
import {createInsertSchema, createSelectSchema} from "drizzle-zod";
import {z} from "zod";
import {users} from "./users.js";
import {roles} from "./roles.js";
import {modules} from "./modules.js";
import {
text,
pgTable,
numeric,
index,
timestamp,
boolean,
uuid,
uniqueIndex,
} from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import { z } from "zod";
import { users } from "./users.js";
import { roles } from "./roles.js";
import { modules } from "./modules.js";
/*
we will add the user
@@ -17,14 +26,14 @@ export const userRoles = pgTable(
"userRoles",
{
user_id: uuid("user_id")
.notNull()
.references(() => users.user_id),
.notNull()
.references(() => users.user_id, { onDelete: "cascade" }),
role_id: uuid("role_id")
.notNull()
.references(() => roles.role_id),
.notNull()
.references(() => roles.role_id),
module_id: uuid("module_id")
.notNull()
.references(() => modules.module_id),
.notNull()
.references(() => modules.module_id),
role: text("role").notNull(), // "view", "technician", "supervisor","manager", "admin", "systemAdmin"
add_User: text("add_User").default("LST_System").notNull(),
add_Date: timestamp("add_Date").defaultNow(),
@@ -33,13 +42,18 @@ export const userRoles = pgTable(
},
(table) => {
// ensures only one user gets permissions to one role
return [uniqueIndex("user_module_unique").on(table.user_id, table.module_id)];
return [
uniqueIndex("user_module_unique").on(
table.user_id,
table.module_id
),
];
}
);
// Schema for inserting a user - can be used to validate API requests
export const insertUserRolesSchema = createInsertSchema(userRoles, {
role: z.string().min(3, {message: "Role must be at least 3 characters"}),
});
// export const insertUserRolesSchema = createInsertSchema(userRoles, {
// role: z.string().min(3, {message: "Role must be at least 3 characters"}),
// });
// Schema for selecting a Expenses - can be used to validate API responses
export const selectUserRolesSchema = createSelectSchema(userRoles);

View File

@@ -1,6 +1,15 @@
import {text, pgTable, numeric, index, timestamp, boolean, uuid, uniqueIndex} from "drizzle-orm/pg-core";
import {createInsertSchema, createSelectSchema} from "drizzle-zod";
import {z} from "zod";
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 users = pgTable(
"users",
@@ -27,10 +36,10 @@ export const users = pgTable(
);
// Schema for inserting a user - can be used to validate API requests
export const insertUsersSchema = createInsertSchema(users, {
username: z.string().min(3, {message: "Username must be at least 3 characters"}),
email: z.string().email({message: "Invalid email"}),
password: z.string().min(8, {message: "Password must be at least 8 characters"}),
});
// export const insertUsersSchema = createInsertSchema(users, {
// username: z.string().min(3, {message: "Username must be at least 3 characters"}),
// email: z.string().email({message: "Invalid email"}),
// password: z.string().min(8, {message: "Password must be at least 8 characters"}),
// });
// Schema for selecting a Expenses - can be used to validate API responses
export const selectUsersSchema = createSelectSchema(users);

26
dotnetwrapper/Program.cs Normal file
View File

@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
// if (!app.Environment.IsDevelopment())
// {
// // app.UseExceptionHandler("/Home/Error");
// // app.UseHsts();
// }
// app.UseHttpsRedirection(); // to force https
app.UseStaticFiles();
app.UseRouting();
app.MapFallbackToFile("index.html");
app.Run();

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:3000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:3000;http://localhost:3000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<Target Name="CopyToProjectWwwRoot" AfterTargets="BuildViteApp">
<ItemGroup>
<ViteDistFiles Include="..\my-vite-app\dist\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(ViteDistFiles)" DestinationFolder="wwwroot\%(RecursiveDir)" />
</Target>
<!-- <Target Name="CopyViteFiles" AfterTargets="Build">
<ItemGroup>
<ViteDistFiles Include="..\my-vite-app\dist\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(ViteDistFiles)" DestinationFolder="$(OutDir)wwwroot\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target> -->
<!-- <ItemGroup>
<Content Include="..\my-vite-app\dist\**" LinkBase="wwwroot" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup> -->
</Project>

View File

@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lst-wrapper", "lst-wrapper.csproj", "{073770C2-0E50-484C-BB72-0A7B602D10B7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{073770C2-0E50-484C-BB72-0A7B602D10B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{073770C2-0E50-484C-BB72-0A7B602D10B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{073770C2-0E50-484C-BB72-0A7B602D10B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{073770C2-0E50-484C-BB72-0A7B602D10B7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {39D31A4B-FECC-425A-9AD5-95EF563F5BE7}
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

View File

@@ -12,66 +12,73 @@
"checkupdates": "npm-check-updates"
},
"dependencies": {
"@hookform/resolvers": "^4.1.3",
"@radix-ui/react-accordion": "^1.2.3",
"@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-collapsible": "^1.1.3",
"@radix-ui/react-dialog": "^1.1.6",
"@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",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-tooltip": "^1.1.8",
"@tailwindcss/vite": "^4.0.15",
"@tanstack/react-form": "^1.2.1",
"@tanstack/react-query": "^5.69.0",
"@tanstack/react-router": "^1.114.27",
"@tanstack/react-table": "^8.21.2",
"@hookform/resolvers": "^5.1.1",
"@radix-ui/react-accordion": "^1.2.11",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.2",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-dialog": "^1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-popover": "^1.1.14",
"@radix-ui/react-scroll-area": "^1.2.9",
"@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.6",
"@radix-ui/react-tabs": "^1.1.12",
"@radix-ui/react-tooltip": "^1.2.7",
"@react-pdf/renderer": "^4.3.0",
"@tailwindcss/vite": "^4.1.10",
"@tanstack/react-form": "^1.12.3",
"@tanstack/react-query": "^5.81.2",
"@tanstack/react-router": "^1.121.34",
"@tanstack/react-table": "^8.21.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"date-fns-tz": "^3.2.0",
"dotenv": "^16.4.7",
"hono": "^4.7.5",
"dotenv": "^16.5.0",
"hono": "^4.8.2",
"js-cookie": "^3.0.5",
"jsbarcode": "^3.12.1",
"jsonwebtoken": "^9.0.2",
"lucide-react": "^0.483.0",
"marked": "^15.0.8",
"lucide-react": "^0.522.0",
"marked": "^15.0.12",
"next-themes": "^0.4.6",
"npm-check-updates": "^17.1.16",
"react": "^19.0.0",
"react-day-picker": "^8.10.1",
"react-dom": "^19.0.0",
"npm-check-updates": "^18.0.1",
"react": "^19.1.0",
"react-barcode": "^1.6.1",
"react-day-picker": "^9.7.0",
"react-dom": "^19.1.0",
"react-grid-layout": "^1.5.1",
"react-hook-form": "^7.54.2",
"react-resizable-panels": "^2.1.7",
"react-hook-form": "^7.58.1",
"react-resizable-panels": "^3.0.3",
"recharts": "^2.15.2",
"sonner": "^2.0.1",
"tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.15",
"sonner": "^2.0.5",
"tailwind-merge": "^3.3.1",
"tailwindcss": "^4.1.10",
"tailwindcss-animate": "^1.0.7",
"zod": "^3.24.2",
"zustand": "^5.0.3"
"zod": "^3.25.67",
"zustand": "^5.0.5"
},
"devDependencies": {
"@eslint/js": "^9.23.0",
"@tanstack/router-devtools": "^1.114.27",
"@tanstack/router-plugin": "^1.114.27",
"@types/react": "^19.0.12",
"@types/react-dom": "^19.0.4",
"@eslint/js": "^9.29.0",
"@tanstack/router-devtools": "^1.121.34",
"@tanstack/router-plugin": "^1.121.34",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@types/react-grid-layout": "^1.3.5",
"@vitejs/plugin-react-swc": "^3.8.1",
"eslint": "^9.23.0",
"@vitejs/plugin-react-swc": "^3.10.2",
"eslint": "^9.29.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^16.0.0",
"typescript": "~5.8.2",
"typescript-eslint": "^8.27.0",
"vite": "^6.2.2"
"eslint-plugin-react-refresh": "^0.4.20",
"globals": "^16.2.0",
"typescript": "~5.8.3",
"typescript-eslint": "^8.35.0",
"vite": "^6.3.5"
},
"overrides": {
"react-is": "^19.0.0-rc-69d4b800-20241021"
}
}

View File

@@ -0,0 +1,225 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { useSessionStore } from "@/lib/store/sessionStore";
import { getProdPerms } from "@/utils/querys/prodUser/getProdPerms";
import { useForm } from "@tanstack/react-form";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
import { toast } from "sonner";
export default function ProdUserCard() {
const { token } = useSessionStore();
const { data, isError, isLoading } = useQuery(getProdPerms(token ?? ""));
const [creating, setCreating] = useState(false);
const form = useForm({
defaultValues: {
username: "",
remark: "",
pcname: "",
role: "",
},
onSubmit: async ({ value }) => {
setCreating(true);
//console.log(value);
if (value.role === "") {
toast.error(
"Role is missing please select a role and try again."
);
}
try {
const res = await axios.post("/api/produser/produser", value, {
headers: { Authorization: `Bearer ${token}` },
});
//console.log(res.data);
if (!res.data.success) {
const errMSG: string = res.data.data.errors
? res.data.data?.errors[0].message
: res.data.data;
toast.error(`${errMSG}`);
setCreating(false);
}
if (res.data.success) {
toast.success(res.data.message);
form.reset();
setCreating(false);
}
} catch (error) {
console.log(error);
setCreating(false);
}
},
});
if (isError)
return (
<>
<p>There was an error loading the prod Perms</p>
</>
);
if (isLoading)
return (
<>
<p>Loading.....</p>
</>
);
return (
<div className="m-4">
<LstCard>
<CardHeader>
<p>Alpla Prod user create/update</p>
</CardHeader>
<div className="m-2">
<p>
Please enter the windows username. <br /> To check the
user head here{" "}
<a
target="_blank"
href="https://alplaservicedesk.service-now.com/sp?id=sc_cat_item&sys_id=0c266831c32f41107cba16c4e40131c0&sysparm_category=564428bdc3eb41107cba16c4e40131f2"
>
<u>Active Directory</u>
</a>
</p>
</div>
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
{/* Windows username */}
<form.Field
name="username"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 3
? undefined
: "Username must be longer than 3 letters",
}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<Label htmlFor="username">Username</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
//type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
{/* Remark for the user */}
<form.Field
name="remark"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 3
? undefined
: "The remark should be longer than 3 letters",
}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<Label htmlFor="remark">Remark</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
//type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
{/* Select the type of role we will be granting/updating */}
<form.Field
name="role"
//listeners={{onChange: ({value})=>{}}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<Label htmlFor={field.name}>
Select role
</Label>
<Select
value={field.state.value}
onValueChange={field.handleChange}
>
<SelectTrigger className="w-[180px]">
<SelectValue
id={field.name}
placeholder="Select Role"
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Roles</SelectLabel>
{data.map((i: any) => {
return (
<SelectItem
key={i.prodPerm_id}
value={i.name}
>
{i.name}
</SelectItem>
);
})}
</SelectGroup>
</SelectContent>
</Select>
</div>
);
}}
/>
<div className="flex justify-end mr-3">
<Button onClick={form.handleSubmit} disabled={creating}>
Submit
</Button>
</div>
</form>
</LstCard>
</div>
);
}

View File

@@ -1,19 +1,72 @@
import {Button} from "@/components/ui/button";
import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip";
import {RotateCcw} from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import axios from "axios";
import { RotateCcw } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
export default function RestartServer(data: any) {
const token = localStorage.getItem("auth_token");
const [disable, setDisable] = useState(false);
const handleRestartServer = async (plant: string) => {
toast.success(`${plant} is being restarted please wait.`);
setDisable(true);
let data: any = {
processType: "restart",
plantToken: plant,
};
const url: string = window.location.host.split(":")[0];
if (url === "localhost" || url === "usmcd1vms036") {
data = { ...data, remote: "true" };
}
//console.log(data);
try {
const res = await axios.post("/api/server/serviceprocess", data, {
headers: { Authorization: `Bearer ${token}` },
});
//console.log(res);
if (res.status === 200) {
setTimeout(() => {
toast.success(`${plant} Has beed restarted.`);
setDisable(false);
}, 3000);
}
} catch (error) {
console.log(error);
}
};
export default function RestartServer() {
return (
<div>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant={"outline"} size={"icon"}>
<Button
variant={"outline"}
size={"icon"}
disabled={disable}
onClick={() =>
handleRestartServer(data.plantData.plantToken)
}
>
<RotateCcw />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Restart Server ... Needs added still</p>
<p>
Restart Server, note you might see the screen error
out for a second
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>

View File

@@ -23,6 +23,7 @@ import { Button } from "@/components/ui/button";
import { getSettings } from "@/utils/querys/settings";
import { toast } from "sonner";
import axios from "axios";
import { useEffect } from "react";
//import { useState } from "react";
export type Servers = {
@@ -46,14 +47,35 @@ export default function ServerPage() {
getServers(token ?? "")
);
const adminModule = modules.filter((n) => n.name === "admin");
const userLevel =
user?.roles?.filter((r) => r.module_id === adminModule[0].module_id) ||
[];
// const adminModule = modules.filter((n) => n.name === "admin");
// const userLevel =
// user?.roles?.filter((r) => r.module_id === adminModule[0].module_id) ||
// [];
if (!adminModule[0]?.roles?.includes(userLevel[0]?.role)) {
router.navigate({ to: "/" });
}
// if (!adminModule[0]?.roles?.includes(userLevel[0]?.role)) {
// console.log("Something failed");
// //router.navigate({ to: "/" });
// }
useEffect(() => {
if (!user || modules.length === 0) return;
const adminModule = modules.find((n) => n.name === "admin");
if (!adminModule) {
console.log("no module loaded");
//router.navigate({ to: "/" });
return;
}
const userLevel =
user?.roles?.filter((r) => r.module_id === adminModule.module_id) ||
[];
if (!adminModule.roles?.includes(userLevel[0]?.role)) {
console.log("Something failed");
//router.navigate({ to: "/" });
}
}, [modules, user, router]);
if (isError) {
return <div>{JSON.stringify(error)}</div>;
@@ -171,11 +193,17 @@ export default function ServerPage() {
server={server}
token={token as string}
/>
<StartServer />
<StartServer
plantData={server}
/>
<StopServer
plantData={server}
/>
<RestartServer />
<RestartServer
plantData={server}
/>
</div>
)}
</TableCell>

View File

@@ -1,19 +1,71 @@
import {Button} from "@/components/ui/button";
import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip";
import {Play} from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import axios from "axios";
import { Play } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
export default function StartServer() {
export default function StartServer(data: any) {
const token = localStorage.getItem("auth_token");
const [disable, setDisable] = useState(false);
const handleStartServer = async (plant: string) => {
toast.success(`${plant} is being started please wait.`);
setDisable(true);
let data: any = {
processType: "start",
plantToken: plant,
};
const url: string = window.location.host.split(":")[0];
if (url === "localhost" || url === "usmcd1vms036") {
data = { ...data, remote: "true" };
}
//console.log(data);
try {
const res = await axios.post("/api/server/serviceprocess", data, {
headers: { Authorization: `Bearer ${token}` },
});
//console.log(res);
if (res.status === 200) {
setTimeout(() => {
toast.success(`${plant} Has beed started.`);
setDisable(false);
}, 3000);
}
} catch (error: any) {
if (error.status === 429) {
toast.error(error.response.data.message);
setDisable(false);
}
}
};
return (
<div>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant={"outline"} size={"icon"}>
<Button
variant={"outline"}
size={"icon"}
disabled={disable}
onClick={() =>
handleStartServer(data.plantData.plantToken)
}
>
<Play />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Start Server ... Needs added still</p>
<p>Start Server</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>

View File

@@ -7,24 +7,40 @@ import {
} from "@/components/ui/tooltip";
import axios from "axios";
import { Octagon } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
export default function StopServer(plantData: any) {
export default function StopServer(data: any) {
const token = localStorage.getItem("auth_token");
const [disable, setDisable] = useState(false);
const handleStopServer = async (plant: string) => {
toast.success(`${plant} is being stopped please wait.`);
setDisable(true);
let data: any = {
processType: "stop",
plantToken: plant,
};
const url: string = window.location.host.split(":")[0];
if (url === "localhost") {
if (url === "localhost" || url === "usmcd1vms036") {
data = { ...data, remote: "true" };
}
//console.log(data);
try {
const res = await axios.post("/api/server/serviceprocess", data, {
headers: { Authorization: `Bearer ${token}` },
});
console.log(res);
//console.log(res);
if (res.status === 200) {
setTimeout(() => {
toast.success(`${plant} Has beed stopped.`);
setDisable(false);
}, 3000);
}
} catch (error) {
console.log(error);
}
@@ -37,15 +53,16 @@ export default function StopServer(plantData: any) {
<Button
variant="destructive"
size={"icon"}
disabled={disable}
onClick={() =>
handleStopServer(plantData.plantToken)
handleStopServer(data.plantData.plantToken)
}
>
<Octagon />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Stop Server ... Needs added still</p>
<p>Stop Server</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>

View File

@@ -1,12 +1,20 @@
import {LstCard} from "@/components/extendedUI/LstCard";
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "@/components/ui/table";
import {useSessionStore} from "@/lib/store/sessionStore";
import {useModuleStore} from "@/lib/store/useModuleStore";
import {useQuery} from "@tanstack/react-query";
import {useRouter} from "@tanstack/react-router";
import {ChangeSetting} from "./SettingForm";
import {getSettings} from "@/utils/querys/settings";
import {Skeleton} from "@/components/ui/skeleton";
import { LstCard } from "@/components/extendedUI/LstCard";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { useSessionStore } from "@/lib/store/sessionStore";
import { useModuleStore } from "@/lib/store/useModuleStore";
import { useQuery } from "@tanstack/react-query";
import { useRouter } from "@tanstack/react-router";
import { ChangeSetting } from "./SettingForm";
import { getSettings } from "@/utils/querys/settings";
import { Skeleton } from "@/components/ui/skeleton";
import { useEffect } from "react";
export type Settings = {
settings_id?: string;
@@ -16,18 +24,33 @@ export type Settings = {
};
export default function SettingsPage() {
const {user, token} = useSessionStore();
const {modules} = useModuleStore();
const { user, token } = useSessionStore();
const { modules } = useModuleStore();
const router = useRouter();
const adminModule = modules.filter((n) => n.name === "admin");
const userLevel = user?.roles.filter((r) => r.module_id === adminModule[0].module_id) || [];
useEffect(() => {
if (!user || modules.length === 0) return;
if (!adminModule[0].roles.includes(userLevel[0]?.role)) {
router.navigate({to: "/"});
}
const adminModule = modules.find((n) => n.name === "admin");
if (!adminModule) {
console.log("no module loaded");
//router.navigate({ to: "/" });
return;
}
const {data, isError, error, isLoading} = useQuery(getSettings(token ?? ""));
const userLevel =
user?.roles?.filter((r) => r.module_id === adminModule.module_id) ||
[];
if (!adminModule.roles?.includes(userLevel[0]?.role)) {
console.log("Something failed");
//router.navigate({ to: "/" });
}
}, [modules, user, router]);
const { data, isError, error, isLoading } = useQuery(
getSettings(token ?? "")
);
// if (isLoading) {
// return <div>Loading.....</div>;
@@ -51,32 +74,38 @@ export default function SettingsPage() {
<>
<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>
</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>
</TableRow>
))}
</TableBody>
</>
) : (
<TableBody>
{data?.map((setting: Settings) => (
<TableRow key={setting.settings_id}>
<TableCell className="font-medium">{setting.name}</TableCell>
<TableCell className="font-medium">{setting.value}</TableCell>
<TableCell className="font-medium">{setting.description}</TableCell>
<TableCell className="font-medium">
{setting.name}
</TableCell>
<TableCell className="font-medium">
{setting.value}
</TableCell>
<TableCell className="font-medium">
{setting.description}
</TableCell>
<TableCell className="font-medium">
<ChangeSetting setting={setting} />
</TableCell>

View File

@@ -15,6 +15,7 @@ import { ChangeSubModule } from "./SubModuleForm";
import { Skeleton } from "@/components/ui/skeleton";
import { getSubModules } from "@/utils/querys/admin/subModules";
import { useEffect } from "react";
export type Settings = {
settings_id?: string;
@@ -28,14 +29,34 @@ export default function SubModulePage() {
const { modules } = useModuleStore();
const router = useRouter();
const adminModule = modules.filter((n) => n.name === "admin");
const userLevel =
user?.roles.filter((r) => r.module_id === adminModule[0].module_id) ||
[];
// const adminModule = modules.filter((n) => n.name === "admin");
// const userLevel =
// user?.roles.filter((r) => r.module_id === adminModule[0].module_id) ||
// [];
if (!adminModule[0].roles.includes(userLevel[0]?.role)) {
router.navigate({ to: "/" });
}
// if (!adminModule[0]?.roles.includes(userLevel[0]?.role)) {
// //router.navigate({ to: "/" });
// }
useEffect(() => {
if (!user || modules.length === 0) return;
const adminModule = modules.find((n) => n.name === "admin");
if (!adminModule) {
console.log("no module loaded");
//router.navigate({ to: "/" });
return;
}
const userLevel =
user?.roles?.filter((r) => r.module_id === adminModule.module_id) ||
[];
if (!adminModule.roles?.includes(userLevel[0]?.role)) {
console.log("Something failed");
//router.navigate({ to: "/" });
}
}, [modules, user, router]);
const { data, isError, error, isLoading } = useQuery(
getSubModules(token ?? "")

View File

@@ -2,15 +2,15 @@ import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
// import {
// Select,
// SelectContent,
// SelectGroup,
// SelectItem,
// SelectLabel,
// SelectTrigger,
// SelectValue,
// } from "@/components/ui/select";
import { DebugButton } from "@/utils/formStuff/debugButton";
import { userFormOptions } from "@/utils/formStuff/options/userformOptions";
@@ -142,7 +142,7 @@ export default function UserCard(data: any) {
);
}}
/>
<form.Field
{/* <form.Field
name="role"
//listeners={{onChange: ({value})=>{}}}
children={(field) => {
@@ -184,7 +184,7 @@ export default function UserCard(data: any) {
</div>
);
}}
/>
/> */}
<form.Field
name="password"
validators={{

View File

@@ -1,25 +1,15 @@
import { useCardStore } from "@/lib/store/useCardStore";
import { useForm } from "@tanstack/react-form";
import { Label } from "../ui/label";
import { Checkbox } from "../ui/checkbox";
import { Input } from "../ui/input";
// import {
// Select,
// SelectContent,
// SelectGroup,
// SelectItem,
// SelectLabel,
// SelectTrigger,
// SelectValue,
// } from "../ui/select";
import { Button } from "../ui/button";
import { useAppForm } from "@/utils/formStuff";
export default function Cards(card: any) {
const { addCard, removeCard, cards } = useCardStore();
let existing: any = cards.filter((n: any) => n.name === card.name);
//console.log(existing);
const form = useForm({
const form = useAppForm({
defaultValues: {
name: existing[0]?.name || card.name,
rowType: existing[0]?.type ?? card.rowType,
@@ -62,7 +52,7 @@ export default function Cards(card: any) {
}}
className="flex flex-row"
>
<form.Field
<form.AppField
name="active"
// validators={{
// // We can choose between form-wide and field-specific validators
@@ -95,83 +85,16 @@ export default function Cards(card: any) {
/>
{!card.inventory && (
<>
<form.Field
<form.AppField
name="age"
// validators={{
// // We can choose between form-wide and field-specific validators
// onChange: ({ value }) =>
// value.length > 3
// ? undefined
// : "Username must be longer than 3 letters",
// }}
children={(field) => {
return (
<div className="m-2 min-w-48 p-2">
<Label htmlFor="active" className="">
Age
</Label>
<Input
name={field.name}
onBlur={field.handleBlur}
value={field.state.value}
type="number"
onChange={(e) =>
field.handleChange(
e.target.value
)
}
/>
</div>
);
}}
children={(field) => (
<field.InputField
label="Age"
inputType="number"
required={true}
/>
)}
/>
{/* <form.Field
name="rowType"
//listeners={{onChange: ({value})=>{}}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<Label htmlFor={field.name}>
Row Type
</Label>
<Select
value={field.state.value}
onValueChange={field.handleChange}
>
<SelectTrigger className="w-[180px]">
<SelectValue
id={field.name}
placeholder="Select Role"
/>
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>
Row Type
</SelectLabel>
<SelectItem value="empty">
Empty
</SelectItem>
<SelectItem value="fg">
Finished Goods
</SelectItem>
<SelectItem value="materials">
Materials
</SelectItem>
<SelectItem value="waste">
Waste
</SelectItem>
<SelectItem value="packaging">
Packaging
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
);
}}
/> */}
</>
)}
<div className="mt-7">

View File

@@ -27,9 +27,10 @@ export default function DashBoard() {
</div>
);
} else {
//console.log(name.split("-")[0], a);
return (
<div key={a.name} className="col-span-3">
<Component age={a.age} type={a.rowType} />
<Component data={a} />
</div>
);
}

View File

@@ -1,131 +1,9 @@
import {useSessionStore} from "@/lib/store/sessionStore";
import {LstCard} from "../extendedUI/LstCard";
import {Tabs, TabsContent, TabsList, TabsTrigger} from "../ui/tabs";
import {useModuleStore} from "@/lib/store/useModuleStore";
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow} from "../ui/table";
import {Skeleton} from "../ui/skeleton";
import {Link, useRouter} from "@tanstack/react-router";
import {Popover, PopoverContent, PopoverTrigger} from "../ui/popover";
import {Button} from "../ui/button";
import {cn} from "@/lib/utils";
import {CalendarIcon} from "lucide-react";
import {format, startOfMonth} from "date-fns";
import {Calendar} from "../ui/calendar";
import {useState} from "react";
import {toast} from "sonner";
import KFP from "./KFP";
import MaterialCheck from "./materialCheck/MaterialCheck";
export default function EomPage() {
const {modules} = useModuleStore();
const {user} = useSessionStore();
const router = useRouter();
const [date, setDate] = useState<Date>();
if (!user) {
router.navigate({to: "/"});
}
const eomMod = modules.filter((m) => m.name === "eom");
// the users current role for eom is?
const role: any = user?.roles.filter((r) => r.module_id === eomMod[0].module_id) || "";
const tabs = [
{key: "kfp", label: "Key Figures", roles: ["admin", "systemAdmin"], content: <KFP />},
{key: "fg", label: "Finished Goods", roles: ["admin", "systemAdmin"], content: <DummyContent />},
{key: "mm", label: "Main Material", roles: ["admin", "systemAdmin"], content: <DummyContent />},
{key: "mb", label: "Master Batch", roles: ["admin", "systemAdmin"], content: <DummyContent />},
{key: "ab", label: "Additive", roles: ["admin", "systemAdmin"], content: <DummyContent />},
{key: "pp", label: "Purchased Preforms", roles: ["admin", "systemAdmin"], content: <DummyContent />},
{key: "pre", label: "Preforms", roles: ["admin", "systemAdmin"], content: <DummyContent />},
{key: "pkg", label: "Packaging", roles: ["admin", "systemAdmin"], content: <DummyContent />},
{key: "ui", label: "Undefined Items", roles: ["admin"], content: <DummyContent />},
];
return (
<div className="m-2 w-screen">
<div className="mb-2 flex flex-row">
<Popover>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"w-[280px] justify-start text-left font-normal",
!date && "text-muted-foreground"
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{date ? format(date, "PPP") : <span>Pick a date</span>}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar mode="single" selected={date} onSelect={setDate} initialFocus />
</PopoverContent>
</Popover>
<div className="ml-2">
<Button onClick={() => toast.success(`Getting data for ${startOfMonth(date!)}-${date}`)}>
<span className="text-sm">Update Data</span>
</Button>
</div>
</div>
<Tabs defaultValue="mm">
<TabsList>
{tabs.map((tab) => {
if (tab.roles.includes(role[0].role))
return <TabsTrigger value={tab.key}>{tab.label}</TabsTrigger>;
})}
</TabsList>
{tabs.map((tab) => {
if (tab.roles.includes(role[0].role))
return <TabsContent value={tab.key}>{tab.content}</TabsContent>;
})}
</Tabs>
<MaterialCheck />
</div>
);
}
function DummyContent() {
return (
<LstCard className="w-5/6">
<Table>
<TableHeader>
<TableRow>
<TableHead>Av</TableHead>
<TableHead>Description</TableHead>
<TableHead>Material Type</TableHead>
<TableHead>Waste</TableHead>
<TableHead>Loss / Gain $$</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Array(10)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium m-2">
<Link to="/article/$av" params={{av: `${i}`}}>
{i}
</Link>
</TableCell>
<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>
);
}

View File

@@ -0,0 +1,3 @@
export default function MaterialCheck() {
return <div>MaterialCheck</div>;
}

View File

@@ -0,0 +1,211 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import { Popover, PopoverTrigger } from "@/components/ui/popover";
import { Skeleton } from "@/components/ui/skeleton";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useSessionStore } from "@/lib/store/sessionStore";
import { useModuleStore } from "@/lib/store/useModuleStore";
import { cn } from "@/lib/utils";
import { PopoverContent } from "@radix-ui/react-popover";
import { Link, useRouter } from "@tanstack/react-router";
import { startOfMonth } from "date-fns";
import { format } from "date-fns-tz";
import { CalendarIcon } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import KFP from "../KFP";
export default function MaterialData() {
const { modules } = useModuleStore();
const { user } = useSessionStore();
const router = useRouter();
const [date, setDate] = useState<Date>();
if (!user) {
router.navigate({ to: "/" });
}
const eomMod = modules.filter((m) => m.name === "eom");
// the users current role for eom is?
const role: any =
user?.roles.filter((r) => r.module_id === eomMod[0].module_id) || "";
const tabs = [
{
key: "kfp",
label: "Key Figures",
roles: ["admin", "systemAdmin"],
content: <KFP />,
},
{
key: "fg",
label: "Finished Goods",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "mm",
label: "Main Material",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "mb",
label: "Master Batch",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "ab",
label: "Additive",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "pp",
label: "Purchased Preforms",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "pre",
label: "Preforms",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "pkg",
label: "Packaging",
roles: ["admin", "systemAdmin"],
content: <DummyContent />,
},
{
key: "ui",
label: "Undefined Items",
roles: ["admin"],
content: <DummyContent />,
},
];
return (
<div className="m-2 w-screen">
<div className="mb-2 flex flex-row">
<Popover>
<PopoverTrigger asChild>
<Button
variant={"outline"}
className={cn(
"w-[280px] justify-start text-left font-normal",
!date && "text-muted-foreground"
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{date ? (
format(date, "PPP")
) : (
<span>Pick a date</span>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
initialFocus
/>
</PopoverContent>
</Popover>
<div className="ml-2">
<Button
onClick={() =>
toast.success(
`Getting data for ${startOfMonth(date!)}-${date}`
)
}
>
<span className="text-sm">Update Data</span>
</Button>
</div>
</div>
<Tabs defaultValue="mm">
<TabsList>
{tabs.map((tab) => {
if (tab.roles.includes(role[0].role))
return (
<TabsTrigger value={tab.key}>
{tab.label}
</TabsTrigger>
);
})}
</TabsList>
{tabs.map((tab) => {
if (tab.roles.includes(role[0].role))
return (
<TabsContent value={tab.key}>
{tab.content}
</TabsContent>
);
})}
</Tabs>
</div>
);
}
function DummyContent() {
return (
<LstCard className="w-5/6">
<Table>
<TableHeader>
<TableRow>
<TableHead>Av</TableHead>
<TableHead>Description</TableHead>
<TableHead>Material Type</TableHead>
<TableHead>Waste</TableHead>
<TableHead>Loss / Gain $$</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Array(10)
.fill(0)
.map((_, i) => (
<TableRow key={i}>
<TableCell className="font-medium m-2">
<Link
to="/article/$av"
params={{ av: `${i}` }}
>
{i}
</Link>
</TableCell>
<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>
);
}

View File

@@ -1,5 +1,10 @@
import {Link} from "@tanstack/react-router";
import {SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem} from "../../ui/sidebar";
import { Link } from "@tanstack/react-router";
import {
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "../../ui/sidebar";
export function Header() {
return (
@@ -9,10 +14,16 @@ export function Header() {
<Link to="/">
<SidebarMenuButton size="lg" asChild>
<div className="flex flex-row">
<img src="/imgs/dkLst.png" alt="Description" className="size-8" />
<img
src={"imgs/dkLst.png"}
alt="Description"
className="size-8"
/>
<div className="flex flex-col gap-0.5 leading-none">
<span className="font-semibold">Logistics Support Tool</span>
<span className="font-semibold">
Logistics Support Tool
</span>
<span className="">v2.0.0</span>
</div>
</div>

View File

@@ -1,4 +1,4 @@
import { Cylinder, Package, Truck } from "lucide-react";
import { Barcode, Cylinder, Package, Truck, Command } from "lucide-react";
import {
SidebarGroup,
SidebarGroupContent,
@@ -15,6 +15,8 @@ const iconMap: any = {
Package: Package,
Truck: Truck,
Cylinder: Cylinder,
Barcode: Barcode,
Command: Command,
};
export function LogisticsSideBar({

View File

@@ -1,4 +1,4 @@
import {Printer} from "lucide-react";
import { Printer, Tag } from "lucide-react";
import {
SidebarGroup,
SidebarGroupContent,
@@ -7,21 +7,36 @@ import {
SidebarMenuButton,
SidebarMenuItem,
} from "../../ui/sidebar";
import {hasPageAccess} from "@/utils/userAccess";
import {User} from "@/types/users";
import { hasPageAccess } from "@/utils/userAccess";
import { User } from "@/types/users";
const items = [
{
title: "One Click Print",
url: "/ocp",
icon: Printer,
role: ["viewer"],
module: "ocp",
active: true,
},
];
export function ProductionSideBar({user, moduleID}: {user: User | null; moduleID: string}) {
export function ProductionSideBar({
user,
moduleID,
}: {
user: User | null;
moduleID: string;
}) {
const url: string = window.location.host.split(":")[0];
const items = [
{
title: "One Click Print",
url: "/ocp",
icon: Printer,
role: ["viewer"],
module: "ocp",
active: true,
},
{
title: "Rfid Readers",
url: "/rfid",
icon: Tag,
role: ["viewer"],
module: "production",
active:
url === "usday1vms006" || url === "localhost" ? true : false,
},
];
return (
<SidebarGroup>
<SidebarGroupLabel>Production</SidebarGroupLabel>
@@ -30,14 +45,15 @@ export function ProductionSideBar({user, moduleID}: {user: User | null; moduleID
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<>
{hasPageAccess(user, item.role, moduleID) && item.active && (
<SidebarMenuButton asChild>
<a href={item.url}>
<item.icon />
<span>{item.title}</span>
</a>
</SidebarMenuButton>
)}
{hasPageAccess(user, item.role, moduleID) &&
item.active && (
<SidebarMenuButton asChild>
<a href={item.url}>
<item.icon />
<span>{item.title}</span>
</a>
</SidebarMenuButton>
)}
</>
</SidebarMenuItem>
))}

View File

@@ -0,0 +1,165 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { CardContent, CardFooter, CardHeader } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { Collapsible, CollapsibleContent } from "@/components/ui/collapsible";
import { getLanes } from "@/utils/querys/logistics/getWarehouseLanes";
import { CollapsibleTrigger } from "@radix-ui/react-collapsible";
import { useQuery } from "@tanstack/react-query";
import { useState } from "react";
import Barcode from "react-barcode";
import { BarcodePDFExport } from "./BarcodeExport";
import { BulkBarcodePDFExport } from "./BulkExport";
import CommonCommands from "./CommonCommands";
export default function BGPage() {
const { data, isError, isLoading } = useQuery(getLanes());
const [checked, setChecked] = useState([]);
if (isLoading) return <div>Loading Data</div>;
if (isError)
return <div>There was an error getting the warehouse lane data.</div>;
/**
* get the warehouse names only
*/
const warhouses = new Map();
data?.forEach((item: any) => {
// if the warhouse is not already included add it to the map
if (!warhouses.has(item.warehouseId)) {
warhouses.set(item.warehouseId, item.warehouseDescription);
}
});
// convert the map to an array
const warehouseArray = Array.from(warhouses).map(([wid, wname]) => ({
warehouseId: wid,
warehouseDescription: wname,
}));
//console.log(warehouseArray);
// handle the onchange
const changeBox = (d: any) => {
setChecked((prev: any) => {
if (prev.includes(d)) {
return prev.filter((name: any) => name !== d);
} else {
return [...prev, d];
}
});
};
return (
<div className="flex flex-row m-2">
<div className="flex flex-row">
<div className="m-2">
<LstCard>
<CardHeader>Warehouse Barcodes</CardHeader>
<CardContent>
{warehouseArray.map((i: any) => {
const lanes = data?.filter(
(wid: any) =>
wid.warehouseId === i.warehouseId
);
return (
<div className="m-2" key={i.warehouseId}>
<Collapsible>
<CollapsibleTrigger>
{i.warehouseDescription}
</CollapsibleTrigger>
<CollapsibleContent>
<div className="ml-2">
{lanes?.map((l: any) => {
return (
<div key={l.laneId}>
<Checkbox
id={
l.laneId
}
// checked={checked.includes(
// l
// )}
onCheckedChange={() =>
changeBox(
l
)
}
/>
<label
id={
l.laneId
}
className="ml-2"
>
{
l.laneDescription
}
</label>
</div>
);
})}
</div>
</CollapsibleContent>
</Collapsible>
</div>
);
})}
</CardContent>
</LstCard>
</div>
{checked.length > 0 && (
<div className="m-2">
<LstCard>
<CardHeader>Current selected lanes</CardHeader>
<CardContent>
{checked.map((c: any) => {
return (
<div
className="flex justify-center"
key={`${c.warehouseId}-${c.laneId}`}
>
<div>
<Barcode
value={`loc#${c.warehouseId}#${c.laneId}`}
width={2}
height={50}
displayValue={false}
/>
<p className="flex justify-center">
Lane: {c.laneDescription}
</p>
</div>
<div className="ml-2 mt-4">
<BarcodePDFExport
barcodeValue={`loc#${c.warehouseId}#${c.laneId}`}
data={c}
/>
</div>
</div>
);
})}
</CardContent>
<CardFooter>
<div className="flex justify-end">
{checked.length > 1 && (
<div>
<BulkBarcodePDFExport
data={checked}
/>
</div>
)}
</div>
</CardFooter>
</LstCard>
</div>
)}
</div>
<div className="m-2">
<CommonCommands />
</div>
</div>
);
}

View File

@@ -0,0 +1,100 @@
import { Button } from "@/components/ui/button";
import {
pdf,
Page,
Text,
View,
Document,
StyleSheet,
Image,
} from "@react-pdf/renderer";
import JsBarcode from "jsbarcode";
export const BarcodePDFExport = ({
barcodeValue,
data,
}: {
barcodeValue: any;
data: any;
}) => {
const generatePDF = () => {
//const barcodeValue = data; // Barcode value
const canvas = document.createElement("canvas");
// Generate barcode on the canvas
JsBarcode(canvas, barcodeValue, {
format: "CODE128",
displayValue: false,
});
// Convert canvas to base64 image data
const barcodeImage = canvas.toDataURL("image/png");
// Define the document styles using @react-pdf/renderer
const styles = StyleSheet.create({
page: {
padding: 30,
},
centerContent: {
display: "flex",
justifyContent: "center", // Center horizontally
alignItems: "center", // Center vertically
flexDirection: "column", // Stack items (barcode and description) vertically
height: "75%", // Ensure the container takes full page height
textAlign: "center",
},
section: {
marginBottom: 10,
textAlign: "center",
},
barcode: {
width: 800, // Width of the barcode
height: 200, // Height of the barcode
marginBottom: 10,
},
description: {
fontSize: 28,
fontWeight: "bold",
marginTop: 10,
marginBottom: 20, // Ensure there's space below the text
},
});
// Create the document
const MyDocument = (
<Document>
<Page style={styles.page} orientation="landscape" size="A4">
<View style={styles.centerContent}>
<View style={styles.section}>
<Image src={barcodeImage} style={styles.barcode} />
</View>
<View style={styles.section}>
<Text style={styles.description}>
Lane: {data.laneDescription}
</Text>
</View>
</View>
</Page>
</Document>
);
// Generate the PDF and trigger download
pdf(MyDocument)
.toBlob()
.then((blob) => {
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = `${data.warehouseDescription}-${data.laneDescription}.pdf`;
link.click();
});
};
return (
<div>
<Button onClick={() => generatePDF()} color="primary">
Export
</Button>
</div>
);
};

View File

@@ -0,0 +1,127 @@
import { Button } from "@/components/ui/button";
import {
pdf,
Page,
Text,
View,
Document,
StyleSheet,
Image,
} from "@react-pdf/renderer";
import JsBarcode from "jsbarcode";
export const BulkBarcodePDFExport = ({ data }: { data: any }) => {
const createBarcode = (barcodeValue: any) => {
//const barcodeValue = data; // Barcode value
const canvas = document.createElement("canvas");
// Generate barcode on the canvas
JsBarcode(canvas, barcodeValue, {
format: "CODE128",
displayValue: false,
});
// Convert canvas to base64 image data
const barcodeImage = canvas.toDataURL("image/png");
return barcodeImage;
};
const generatePDF = () => {
// Define the document styles using @react-pdf/renderer
const styles = StyleSheet.create({
page: {
padding: 30,
},
centerContent: {
display: "flex",
justifyContent: "flex-start", // Center horizontally
alignItems: "center", // Center vertically
flexDirection: "row", // Stack items (barcode and description) vertically
//height: "5%", // Ensure the container takes full page height
textAlign: "center",
},
section: {
marginBottom: 10,
textAlign: "center",
},
barcode: {
width: 275, // Width of the barcode
height: 75, // Height of the barcode
marginBottom: 10,
},
description: {
fontSize: 14,
fontWeight: "bold",
marginTop: 10,
marginBottom: 20, // Ensure there's space below the text
},
headerText: {
fontSize: 28,
fontWeight: "bold",
marginTop: 10,
marginBottom: 20, // Ensure there's space below the text
display: "flex",
justifyContent: "center",
//height: "15%", // Ensure the container takes full page height
textAlign: "center",
},
horizontalLine: {
borderBottom: "#000000",
borderBottomWidth: 1,
},
});
// Create the document
const MyDocument = (
<Document>
<Page style={styles.page} orientation="portrait" size="A4">
<View style={styles.headerText}>
<Text>Multi Lane export.</Text>
</View>
<View style={styles.horizontalLine} />
{data.map((i: any, index: any) => {
return (
<View style={styles.centerContent} key={index}>
<View style={styles.section}>
<Image
src={createBarcode(
`loc#${i.warehouseId}#${i.laneId}`
)}
style={styles.barcode}
/>
</View>
<View style={styles.section}>
<Text style={styles.description}>
Lane: {i.laneDescription}
</Text>
</View>
</View>
);
})}
</Page>
</Document>
);
// Generate the PDF and trigger download
pdf(MyDocument)
.toBlob()
.then((blob) => {
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = `MultipleBarcodes.pdf`;
link.click();
});
};
return (
<div>
<Button onClick={() => generatePDF()} color="primary">
Export All Selected
</Button>
</div>
);
};

View File

@@ -0,0 +1,107 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { CardContent, CardFooter, CardHeader } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import { useState } from "react";
import Barcode from "react-barcode";
import { BarcodePDFExport } from "./BarcodeExport";
import { BulkBarcodePDFExport } from "./BulkExport";
const commoncmd = [
{ name: "Relocate", commandId: 33 },
//-{ name: "Stock in", commandId: 22 },
];
export default function CommonCommands() {
const [checked, setChecked] = useState([]);
// handle the onchange
const changeBox = (d: any) => {
setChecked((prev: any) => {
if (prev.includes(d)) {
return prev.filter((name: any) => name !== d);
} else {
return [...prev, d];
}
});
};
return (
<div>
<div>
<LstCard>
<CardHeader>Common Barcodes</CardHeader>
<CardContent>
{commoncmd.map((i: any) => {
return (
<div className="flex flex-row">
<div>
<Checkbox
id={i.commandId}
// checked={checked.includes(
// l
// )}
onCheckedChange={() => changeBox(i)}
/>
<label
id={i.commandId}
className="ml-2"
>
{i.name}
</label>
</div>
</div>
);
})}
</CardContent>
</LstCard>
</div>
<div>
{checked.length > 0 && (
<div className="m-2">
<LstCard>
<CardHeader>Current selected Barcodes</CardHeader>
<CardContent>
{checked.map((c: any) => {
return (
<div
className="flex justify-center"
key={`${c.name}`}
>
<div>
<Barcode
value={`AlplaPRODcmd${c.commandId}`}
width={2}
height={50}
displayValue={false}
/>
<p className="flex justify-center">
Bacrode: {c.name}
</p>
</div>
<div className="ml-2 mt-4">
<BarcodePDFExport
barcodeValue={`AlplaPRODcmd${c.commandId}`}
data={c}
/>
</div>
</div>
);
})}
</CardContent>
<CardFooter>
<div className="flex justify-end">
{checked.length > 1 && (
<div>
<BulkBarcodePDFExport
data={checked}
/>
</div>
)}
</div>
</CardFooter>
</LstCard>
</div>
)}
</div>
</div>
);
}

View File

@@ -55,6 +55,11 @@ export default function DMButtons() {
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
{plantToken[0]?.value === "usksc1" && (
<div className="flex flex-row gap-2">
<ForecastImport fileType={"pg"} name={"P&G"} />
</div>
)}
</div>
);
}

View File

@@ -26,7 +26,7 @@ export default function DmPage() {
<ul className="list-disc mr-2">
<li>
Download the standard template if you have not yet done
so, top right click standard, then template.
so, Above click Standard Order Template.
</li>
<li>
Add in the orders like you see in the example below.
@@ -37,8 +37,8 @@ export default function DmPage() {
customerReleaseNumber. Quatity and dates can change.
</li>
<li>
Once you have all the orders enters click the upload
button on the top right
Once you have all the orders entered, click Standard
Order Import
</li>
</ul>
@@ -129,6 +129,10 @@ export default function DmPage() {
If you desire you can send up to 1000 orders at one
time...
</li>
<li>
The customer MUST be set as default address in order
for the system to validate the av.
</li>
</ul>
</div>
<Separator className="my-4" />

View File

@@ -1,6 +1,6 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardContent, CardFooter, CardHeader } from "@/components/ui/card";
import { CardContent, CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useForm } from "@tanstack/react-form";
@@ -63,7 +63,7 @@ export default function Bookin() {
}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<div className="">
<Label htmlFor="runningNr" className="mb-2">
Runnning Number
</Label>
@@ -85,9 +85,7 @@ export default function Bookin() {
);
}}
/>
</CardContent>
<CardFooter>
<div className="flex justify-end">
<div className="flex mt-2 justify-end">
<Button
onClick={form.handleSubmit}
disabled={bookingIn}
@@ -95,7 +93,7 @@ export default function Bookin() {
Book in
</Button>
</div>
</CardFooter>
</CardContent>
</form>
</LstCard>
);

View File

@@ -0,0 +1,133 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardContent, CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useForm } from "@tanstack/react-form";
import axios from "axios";
import { useState } from "react";
import { toast } from "sonner";
export default function Relocate() {
const [bookingIn, setBookingIn] = useState(false);
const form = useForm({
defaultValues: { runningNr: " ", lane: "" },
onSubmit: async ({ value }) => {
// Do something with form data
setBookingIn(true);
try {
const res = await axios.post("/api/ocp/bookin", {
runningNr: parseInt(value.runningNr),
});
if (res.data.success) {
toast.success(res.data.message);
form.reset();
setBookingIn(false);
} else {
console.log(res.data.data.errors);
toast.error(res.data.data.errors[0]?.message);
form.reset();
setBookingIn(false);
}
} catch (error) {
console.log(error);
toast.error(
"There was an error booking in pallet please validate you entered the correct info and try again."
);
setBookingIn(false);
}
},
});
return (
<LstCard>
<CardHeader>
<p>Relocate a pallet to another lane</p>
</CardHeader>
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<CardContent>
<form.Field
name="runningNr"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 2
? undefined
: "Please enter a valid running number",
}}
children={(field) => {
return (
<div className="">
<Label htmlFor="runningNr" className="mb-2">
Runnning Number
</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
<form.Field
name="lane"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 2
? undefined
: "Please enter a valid running number",
}}
children={(field) => {
return (
<div className="">
<Label htmlFor="runningNr" className="mb-2">
Enter lane
</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
//type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
<div className="flex mt-2 justify-end">
<Button
onClick={form.handleSubmit}
disabled={bookingIn}
>
Relocate
</Button>
</div>
</CardContent>
</form>
</LstCard>
);
}

View File

@@ -0,0 +1,138 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardContent, CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { useForm } from "@tanstack/react-form";
import axios from "axios";
import { useState } from "react";
import { toast } from "sonner";
export default function RemoveAsNonReusable() {
const [stockOut, setStockOut] = useState(false);
const form = useForm({
defaultValues: { runningNr: " ", reason: " " },
onSubmit: async ({ value }) => {
// Do something with form data
setStockOut(true);
//console.log(value);
try {
const res = await axios.post(
"/api/logistics/removeasreusable",
value // this is basically the data field
);
if (res.data.success) {
toast.success(res.data.message);
form.reset();
setStockOut(false);
} else {
console.log(res.data);
toast.error(res.data?.message);
form.reset();
setStockOut(false);
}
} catch (error: any) {
console.log(error);
toast.error(error.message);
setStockOut(false);
}
},
});
return (
<LstCard>
<CardHeader>
<p>Remove a pallet as non reusable</p>
</CardHeader>
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<CardContent>
<form.Field
name="runningNr"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 2
? undefined
: "Please enter a valid running number",
}}
children={(field) => {
return (
<div className="w-96">
<Label htmlFor="runningNr" className="mb-2">
Runnning Number
</Label>
<Input
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
required
type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<em>
{field.state.meta.errors.join(",")}
</em>
) : null}
</div>
);
}}
/>
<form.Field
name="reason"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 10
? undefined
: "Please enter a valid reason on why you needed to remove this pallet",
}}
children={(field) => {
return (
<div className="">
<Label htmlFor="reason" className="mb-2">
Reason for removing
</Label>
<Textarea
name={field.name}
value={field.state.value}
onBlur={field.handleBlur}
//type="number"
onChange={(e) =>
field.handleChange(e.target.value)
}
/>
{field.state.meta.errors.length ? (
<div className="text-pretty max-w-96">
<em>
{field.state.meta.errors.join(
","
)}
</em>
</div>
) : null}
</div>
);
}}
/>
<div className="flex mt-2 justify-end">
<Button onClick={form.handleSubmit} disabled={stockOut}>
Remove
</Button>
</div>
</CardContent>
</form>
</LstCard>
);
}

View File

@@ -1,9 +1,19 @@
import Bookin from "./commands/Bookin";
import Relocate from "./commands/Relocate";
import RemoveAsNonReusable from "./commands/RemoveAsNonReusable";
export default function HelperPage() {
const url: string = window.location.host.split(":")[0];
return (
<div>
<Bookin />
<div className="flex flex-wrap m-2 justify-center">
<div className="m-1">
<Bookin />
</div>
<div className="m-1">
<RemoveAsNonReusable />
</div>
<div className="m-1">{url === "localhost" && <Relocate />}</div>
</div>
);
}

View File

@@ -1,26 +1,30 @@
import {LstCard} from "@/components/extendedUI/LstCard";
import {Button} from "@/components/ui/button";
import {CardHeader} from "@/components/ui/card";
import {Input} from "@/components/ui/input";
import {Label} from "@/components/ui/label";
import {useSessionStore} from "@/lib/store/sessionStore";
import axios from "axios";
import {useState} from "react";
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {useForm} from "react-hook-form";
import {toast} from "sonner";
import axios from "axios";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
export default function ConsumeMaterial() {
const {register: register1, handleSubmit: handleSubmit1, reset} = useForm();
const {
register: register1,
handleSubmit: handleSubmit1,
reset,
} = useForm();
const [submitting, setSubmitting] = useState(false);
const {token} = useSessionStore();
const handleConsume = async (data: any) => {
setSubmitting(true);
try {
const result = await axios.post(`/api/logistics/consume`, data, {
headers: {Authorization: `Bearer ${token}`},
});
// const result = await axios.post(`/api/logistics/consume`, data, {
// headers: {Authorization: `Bearer ${token}`},
// });
const result = await axios.post(`/api/logistics/consume`, data);
if (result.data.success) {
toast.success(result.data.message);
setSubmitting(false);
@@ -33,12 +37,14 @@ export default function ConsumeMaterial() {
toast.error(result.data.message);
}
} catch (error: any) {
//console.log(error);
console.log(error);
setSubmitting(false);
if (error.status === 401) {
toast.error("Unauthorized to do this task.");
} else {
toast.error("Unexpected error if this continues please constact an admin.");
toast.error(
"Unexpected error if this continues please constact an admin."
);
}
}
};
@@ -53,7 +59,9 @@ export default function ConsumeMaterial() {
<LstCard>
<form onSubmit={handleSubmit1(handleConsume)}>
<div className="m-2">
<Label htmlFor="runningNr">Enter unit running number</Label>
<Label htmlFor="runningNr">
Enter unit running number
</Label>
<Input
className="mt-2"
//defaultValue="634"
@@ -62,7 +70,9 @@ export default function ConsumeMaterial() {
/>
</div>
<div className="m-2">
<Label htmlFor="lotNum">Enter lot number</Label>
<Label htmlFor="lotNum">
Enter lot number
</Label>
<Input
className="mt-2"
//defaultValue="634"
@@ -71,7 +81,12 @@ export default function ConsumeMaterial() {
/>
</div>
<Button className="m-2" color="primary" type="submit" disabled={submitting}>
<Button
className="m-2"
color="primary"
type="submit"
disabled={submitting}
>
Consume materal
</Button>
</form>
@@ -81,12 +96,19 @@ export default function ConsumeMaterial() {
<LstCard>
<div className="w-96 p-1">
<ol>
<li>1. Enter the running number of the material you would like to consume</li>
<li>2. Enter the lot number you will be consuming to</li>
<li>
1. Enter the running number of the
material you would like to consume
</li>
<li>
2. Enter the lot number you will be
consuming to
</li>
<li>3. Press consume material</li>
</ol>
<p className="text-pretty w-96">
*This process is only for barcoded material, if it is set to auto consume you will
*This process is only for barcoded material,
if it is set to auto consume you will
encounter and error.
</p>
</div>

View File

@@ -0,0 +1,160 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useSessionStore } from "@/lib/store/sessionStore";
import axios from "axios";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
export default function PreformReturn() {
const {
register: register1,
handleSubmit: handleSubmit1,
reset,
} = useForm();
const [submitting, setSubmitting] = useState(false);
const { token } = useSessionStore();
const handleConsume = async (data: any) => {
setSubmitting(true);
try {
const result = await axios.post(`/api/logistics/consume`, data, {
headers: { Authorization: `Bearer ${token}` },
});
if (result.data.success) {
toast.success(result.data.message);
setSubmitting(false);
reset();
}
if (!result.data.success) {
//console.log(result.data);
setSubmitting(false);
toast.error(result.data.message);
}
} catch (error: any) {
//console.log(error);
setSubmitting(false);
if (error.status === 401) {
toast.error("Unauthorized to do this task.");
} else {
toast.error(
"Unexpected error if this continues please constact an admin."
);
}
}
};
return (
<div className="m-2">
<LstCard>
<CardHeader>
<p className="text-center text-lg">Preform Return.</p>
</CardHeader>
<div className="flex m-1">
<div className="w-96 m-1">
<LstCard>
<form onSubmit={handleSubmit1(handleConsume)}>
<div className="m-2">
<Label htmlFor="runningNr">
Enter unit running number
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("runningNr")}
/>
</div>
<div className="m-2">
<Label htmlFor="lotNum">
Enter the new wight of the gaylord of
preforms
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("lotNum")}
/>
</div>
<div className="m-2">
<Label htmlFor="lotNum">
Select the printer you would like to
print to
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("lotNum")}
/>
</div>
<div className="m-2">
<Label htmlFor="lotNum">
Select the staging location to be
returned to.
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("lotNum")}
/>
</div>
<div className="m-2">
<Label htmlFor="lotNum">
Select type of material coming back.
</Label>
<Input
className="mt-2"
//defaultValue="634"
type="number"
{...register1("lotNum")}
/>
</div>
<Button
className="m-2"
color="primary"
type="submit"
disabled={submitting}
>
Preform return
</Button>
</form>
</LstCard>
</div>
<div className="m-1 p-1">
<LstCard>
<div className="w-96 p-1">
<ol>
<li>
1. Enter the running number of the
preform cage you would like to return
</li>
<li>
2. Enter the new weight of the gaylord
</li>
<li>
3. Select the printer you would like to
print to
</li>
</ol>
<p className="text-pretty w-96">
*As soon as you press preform return it will
print a new label and return to the staging
location.
</p>
</div>
</LstCard>
</div>
</div>
</LstCard>
</div>
);
}

View File

@@ -0,0 +1,478 @@
import { LstCard } from "@/components/extendedUI/LstCard";
import { Button } from "@/components/ui/button";
import { CardContent, CardHeader } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useAppForm } from "@/utils/formStuff";
import axios from "axios";
import { useState } from "react";
import { toast } from "sonner";
import { Info } from "lucide-react";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { useSettingStore } from "@/lib/store/useSettings";
export default function TransferToNextLot() {
const [gaylordFilled, setGaylordFilled] = useState([0]);
const [actualAmount, setActualAmount] = useState(0);
const [tab, setTab] = useState("esitmate");
const [typeSwitch, setTypeSwitch] = useState(false);
const { settings } = useSettingStore();
const server = settings.filter((n: any) => n.name === "dbServer");
const form = useAppForm({
defaultValues: {
runningNumber: "",
lotNumber: "",
originalAmount: "",
amount: "",
},
onSubmit: async ({ value }) => {
//console.log(transferData);
//toast.success("603468: qty: 361, was transfered to lot:24897");
try {
const res = await axios.post("/api/ocp/materiallottransfer", {
runningNumber: Number(value.runningNumber),
lotNumber: Number(value.lotNumber),
originalAmount: Number(value.originalAmount),
level: Number(
gaylordFilled.length === 1
? 0.25
: gaylordFilled.length === 2
? 0.5
: gaylordFilled.length === 3
? 0.75
: gaylordFilled.length === 4 && 0.95
),
amount: actualAmount,
type: typeSwitch ? "eom" : "lot",
});
if (res.data.success) {
toast.success(`${res.data.message}`);
form.reset();
setGaylordFilled([0]);
setActualAmount(0);
}
//console.log(res.data);
if (!res.data.success) {
toast.error(res.data.message);
}
} catch (error) {
if (error) {
console.log(error);
//toast.error(error)
}
}
},
});
return (
<div>
<LstCard>
<CardHeader>
<p className="text-center text-lg">
Material Transfer to Next lot
</p>
</CardHeader>
<div>
<div className="flex flex-wrap m-2 gap-2">
<div className="flex gap-2">
<div>
<LstCard className="">
<Tabs
defaultValue={tab}
onValueChange={setTab}
>
<TabsList>
<TabsTrigger value="esitmate">
Estimate Amount
</TabsTrigger>
<TabsTrigger value="actual">
Actual Amount
</TabsTrigger>
</TabsList>
<TabsContent value="esitmate">
<div className="grid columns-1">
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(
4
)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled([
1, 2, 3, 4,
])
}
>
<p className="text-center">
Almost full - 95%
</p>
</button>
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(
3
)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled([
1, 2, 3,
])
}
>
<p className="text-center">
About full - 75%
</p>
</button>
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(
2
)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled([1, 2])
}
>
<p className="text-center">
Half full - 50%
</p>
</button>
<button
className={`box-border h-16 w-96 border-3 ${
gaylordFilled.includes(
1
)
? " bg-green-500"
: ""
}`}
onClick={() =>
setGaylordFilled(() => [
1,
])
}
>
<p className="text-center">
Almost empty - 25%
</p>
</button>
</div>
<div className="flex justify-end pr-1">
<Button
onClick={() =>
setGaylordFilled([0])
}
>
Reset Gaylord
</Button>
</div>
</TabsContent>
<TabsContent
value="actual"
className="w-96"
>
<CardHeader>
<p>
Enter the total amount of
the cage/gaylord
</p>
</CardHeader>
<CardContent>
<Input
type="number"
//placeholder="35"
onChange={(e) =>
setActualAmount(
Number(
e.target.value
)
)
}
/>
</CardContent>
</TabsContent>
</Tabs>
</LstCard>
</div>
<div>
<div className="w-96">
<LstCard>
<form
onSubmit={(e) => {
e.preventDefault();
form.handleSubmit();
}}
>
<div className="mt-3 p-2">
<form.AppField
name="runningNumber"
children={(field) => (
<field.InputField
label="Running Number"
inputType="number"
required={true}
/>
)}
/>
</div>
<div className="mt-3 p-2">
<form.AppField
name="lotNumber"
children={(field) => (
<field.InputField
label="Lot Number"
inputType="number"
required={true}
/>
)}
/>
{tab !== "actual" && (
<div className="mt-3 p-2">
<form.AppField
name="originalAmount"
children={(
field
) => (
<field.InputField
label="Orignal Quantity"
inputType="number"
required={
true
}
/>
)}
/>
</div>
)}
</div>
<div className="flex justify-between p-2">
<div className="flex items-center space-x-2">
<Switch
checked={typeSwitch}
onCheckedChange={
setTypeSwitch
}
/>
<span>
{typeSwitch ? (
<div className="flex items-center space-x-2">
<span>
"EOM
Transfer"
</span>
<Tooltip>
<TooltipTrigger>
<Info className="h-[16px] w-[16px]" />
</TooltipTrigger>
<TooltipContent>
<p>
Click
the
toggle
if
you
will
be
transfering
at
EOM,
NOTE:
This
will
trigger
the
delayed
transfer.
</p>
</TooltipContent>
</Tooltip>
</div>
) : (
<div className="flex items-center space-x-2">
<span>
"Lot
Transfer"
</span>
<Tooltip>
<TooltipTrigger>
<Info className="h-[16px] w-[16px]" />
</TooltipTrigger>
<TooltipContent>
<p>
Click
the
toggle
if
you
will
be
transfering
at
EOM,
NOTE:
This
will
trigger
the
delayed
transfer.
</p>
</TooltipContent>
</Tooltip>
</div>
)}
</span>
</div>
<form.AppForm>
<form.SubmitButton>
Transfer To Lot
</form.SubmitButton>
</form.AppForm>
</div>
</form>
</LstCard>
</div>
</div>
</div>
<div>
<LstCard className="p-2">
<CardHeader>
<p className="text-center text-lg">
Moving material to the next lot.
</p>
</CardHeader>
{tab !== "actual" ? (
<div>
<ol>
<li>
1. Grab the gaylord running
number from the gaylord at the
line/next to the tschritter
</li>
<li>
2. Grab the next lot number you
are going to be running (or the
one that state no Main material
prepared)
</li>
<li>
3. Enter the total gaylord
weight (this is how much the
gaylord weighed when it came in
from the supplier.)
</li>
<li>
4. *Click the level of the
gaylord (this is just an
estimate to move to the next
lot.)
</li>
<li>
5. type in running number on the
gaylord.
</li>
<li>
6. Type in the new lot number.
</li>
<li>7. Press "Transfer To Lot"</li>
</ol>
<br></br>
<p>
* to reduce the time needed to get
the lot going we will use an
estimate of how full the gaylord is.
</p>
<p>
NOTE: This is not the return
process, this process will just get
the gaylord to the next lot.
</p>
<br />
{settings.length > 0 && (
<p>
For more in depth instructions
please{" "}
<a
href={`https://${server[0].value}.alpla.net/lst/d/docs/ocp/ocp#tranfer-partial-estimated-quantity-to-the-next-lot`}
target="_blank"
>
<em>CLICK HERE</em>
</a>
</p>
)}
</div>
) : (
<div>
<ol>
<li>
1. Grab the gaylord running
number from the gaylord at the
line/next to the tschritter
</li>
<li>
2. Grab the next lot number you
are going to be running (or the
one that state no Main material
prepared)
</li>
<li>
3. Take the gaylord to the scale
and weight it
</li>
<li>
4. Enter the weight of the
gaylord minus the tar weight.
</li>
<li>
5. type in running number on the
gaylord.
</li>
<li>
6. Type in the new lot number.
</li>
<li>7. Press "Transfer To Lot"</li>
</ol>
<br></br>
<p>
NOTE: This is not the return
process, this process will just get
the gaylord to the next lot.
</p>
<br />
{settings.length > 0 && (
<p>
For more in depth instructions
please{" "}
<a
href={`https://${server[0].value}.alpla.net/lst/d/docs/ocp/ocp#tranfer-partial-estimated-quantity-to-the-next-lot`}
target="_blank"
>
<em>CLICK HERE</em>
</a>
</p>
)}
</div>
)}
</LstCard>
</div>
</div>
</div>
</LstCard>
</div>
);
}

View File

@@ -0,0 +1,31 @@
import { Button } from "@/components/ui/button";
import axios from "axios";
import { toast } from "sonner";
export default function ManualTrigger() {
const rfidReaderTrigger = async () => {
try {
const res = await axios.post("/api/rfid/manualtrigger/wrapper1");
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 (
<div>
<Button onClick={rfidReaderTrigger}>Wrapper 1 RFID</Button>
</div>
);
}

View File

@@ -0,0 +1,163 @@
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { useAppForm } from "@/utils/formStuff";
import { getMachineConnected } from "@/utils/querys/logistics/machineConnected";
import { getMachineNotConnected } from "@/utils/querys/logistics/notConnected";
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
import { useState } from "react";
import { toast } from "sonner";
export function AttachSilo(props: any) {
const [open, setOpen] = useState(false);
const { data, isError, isLoading, refetch } = useQuery(
getMachineNotConnected({
siloID: props.silo.LocationID,
connectionType: "detached",
})
);
const { refetch: attached } = useQuery(
getMachineConnected({
siloID: props.silo.LocationID,
connectionType: "connected",
})
);
const form = useAppForm({
defaultValues: {
laneId: props.silo.LocationID,
productionLotId: "",
machineId: "",
},
onSubmit: async ({ value }) => {
try {
const res = await axios.post(
"/api/logistics/attachsilo",
value
);
if (res.data.success) {
toast.success(res.data.message);
refetch();
attached();
form.reset();
setOpen(!open);
} else {
console.log(res.data);
toast.error(res.data.message);
refetch();
form.reset();
setOpen(!open);
}
} catch (error) {
console.log(error);
toast.error(
"There was an error attaching the silo please try again, if persist please enter a helpdesk ticket."
);
}
},
});
if (isError)
return (
<div>
<p>There was an error loading data</p>
</div>
);
if (isLoading)
return (
<div>
<p>Loading....</p>
</div>
);
// convert the array that comes over to label and value
const tranMachine = data.map((i: any) => ({
value: i.machineId.toString(),
label: i.name,
}));
return (
<Dialog open={open}>
<DialogTrigger asChild>
<Button variant="outline" onClick={() => setOpen(!open)}>
Attach Silo
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<form
onSubmit={(e) => {
e.preventDefault();
form.handleSubmit();
}}
>
<DialogHeader>
<DialogTitle>
Attach silo for: {props.silo.Description}
</DialogTitle>
<DialogDescription>
Enter the new lotnumber, select the machine you
would like to attach.
</DialogDescription>
</DialogHeader>
<div>
<p className="text-sm">
NOTE: If the machine you are trying to attach is not
showing in the drop down this means it is already
attached to this silo.
</p>
</div>
<div className="mt-3">
<form.AppField
name="productionLotId"
children={(field) => (
<field.InputField
label="Lot Number"
inputType="number"
required={true}
/>
)}
/>
</div>
<div className="mt-2">
<form.AppField
name="machineId"
children={(field) => (
<field.SelectField
label="Select Machine"
options={tranMachine}
/>
)}
/>
</div>
<DialogFooter className="mt-2">
<DialogClose asChild>
<Button
variant="outline"
onClick={() => setOpen(!open)}
>
Cancel
</Button>
</DialogClose>
<form.AppForm>
<form.SubmitButton>Attach</form.SubmitButton>
</form.AppForm>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}

View File

@@ -0,0 +1,151 @@
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { useAppForm } from "@/utils/formStuff";
import { getMachineConnected } from "@/utils/querys/logistics/machineConnected";
import { getMachineNotConnected } from "@/utils/querys/logistics/notConnected";
import { useQuery } from "@tanstack/react-query";
import axios from "axios";
import { useState } from "react";
import { toast } from "sonner";
export function DetachSilo(props: any) {
const [open, setOpen] = useState(false);
const { data, isError, isLoading, refetch } = useQuery(
getMachineConnected({
siloID: props.silo.LocationID,
connectionType: "connected",
})
);
const { refetch: notConnected } = useQuery(
getMachineNotConnected({
siloID: props.silo.LocationID,
connectionType: "detached",
})
);
const form = useAppForm({
defaultValues: {
laneId: props.silo.LocationID,
machineId: 0,
},
onSubmit: async ({ value }) => {
try {
const res = await axios.post(
"/api/logistics/detachsilo",
value
);
if (res.status === 200) {
console.log(res.data.data);
toast.success(res.data.message);
refetch();
notConnected();
form.reset();
setOpen(!open);
} else {
console.log(res.data);
toast.error(res.data.message);
refetch();
form.reset();
setOpen(!open);
}
} catch (error) {
console.log(error);
toast.error(
"There was an error detaching the silo please try again, if persist please enter a helpdesk ticket."
);
}
},
});
if (isError)
return (
<div>
<p>There was an error loading data</p>
</div>
);
if (isLoading)
return (
<div>
<p>Loading....</p>
</div>
);
// convert the array that comes over to label and value
const tranMachine = data.map((i: any) => ({
value: i.machineId.toString(),
label: i.name,
}));
return (
<Dialog open={open}>
<DialogTrigger asChild>
<Button
variant="outline"
onClick={() => setOpen(!open)}
disabled={data.length === 0}
>
Detach Silo
</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[425px]">
<form
onSubmit={(e) => {
e.preventDefault();
form.handleSubmit();
}}
>
<DialogHeader>
<DialogTitle>
Attach silo for: {props.silo.Description}
</DialogTitle>
<DialogDescription>
Select the machine you would like to detach.
</DialogDescription>
</DialogHeader>
<div className="grid gap-4">
<div className="grid gap-3">
<div className="mt-2">
<form.AppField
name="machineId"
children={(field) => (
<field.SelectField
label="Select Machine"
options={tranMachine}
/>
)}
/>
</div>
</div>
</div>
<DialogFooter>
<DialogClose asChild>
<Button
variant="outline"
onClick={() => setOpen(!open)}
>
Cancel
</Button>
</DialogClose>
<form.AppForm>
<form.SubmitButton>Detach</form.SubmitButton>
</form.AppForm>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}

View File

@@ -19,13 +19,30 @@ import { CircleAlert } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import ChartData from "./ChartData";
import { AttachSilo } from "./AttachSilo";
import { DetachSilo } from "./DetachSilo";
import { useSessionStore } from "@/lib/store/sessionStore";
import { useModuleStore } from "@/lib/store/useModuleStore";
import { useGetUserRoles } from "@/lib/store/useGetRoles";
export default function SiloCard(data: any) {
const token = localStorage.getItem("auth_token");
const [submitting, setSubmitting] = useState(false);
const { refetch } = useQuery(getStockSilo());
const { user } = useSessionStore();
const { userRoles } = useGetUserRoles();
const { modules } = useModuleStore();
const silo = data.silo;
// roles that can do the silo adjustments
const roles = ["systemAdmin", "technician", "admin", "manager"];
const module = modules.filter((n) => n.name === "logistics");
const accessRoles = userRoles.filter(
(n) => n.module_id === module[0]?.module_id
) as any;
const form = useForm({
defaultValues: {
newLevel: "",
@@ -44,7 +61,7 @@ export default function SiloCard(data: any) {
dataToSubmit,
{ headers: { Authorization: `Bearer ${token}` } }
);
console.log(res.data);
//console.log(res.data);
if (res.data.success) {
toast.success(res.data.message);
@@ -68,6 +85,8 @@ export default function SiloCard(data: any) {
}
},
});
console.log(accessRoles);
return (
<LstCard>
<div className="flex flex-row">
@@ -107,94 +126,115 @@ export default function SiloCard(data: any) {
</ul>
</div>
) : (
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<form.Field
name="newLevel"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 1
? undefined
: "You must enter a value greate than 1",
}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<div className="flex flex-row">
<Label htmlFor="newLevel">
New level
</Label>
<div>
<Disclaimer />
</div>
</div>
<div className="flex flex-row">
<Input
name={field.name}
value={
field.state.value
}
onBlur={
field.handleBlur
}
type="decimal"
onChange={(e) =>
field.handleChange(
e.target.value
)
}
/>
<Button
className="ml-1"
type="submit"
onClick={
form.handleSubmit
}
disabled={submitting}
>
{submitting ? (
<span className="w-24">
Submitting...
</span>
) : (
<span className="w-24">
Submit
</span>
)}
</Button>
</div>
<>
{user &&
roles.includes(accessRoles[0]?.role) && (
<form
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<form.Field
name="newLevel"
validators={{
// We can choose between form-wide and field-specific validators
onChange: ({ value }) =>
value.length > 1
? undefined
: "You must enter a value greate than 1",
}}
children={(field) => {
return (
<div className="m-2 min-w-48 max-w-96 p-2">
<div className="flex flex-row">
<Label htmlFor="newLevel">
New level
</Label>
<div>
<Disclaimer />
</div>
</div>
<div className="flex flex-row">
<Input
name={
field.name
}
value={
field
.state
.value
}
onBlur={
field.handleBlur
}
type="decimal"
onChange={(
e
) =>
field.handleChange(
e
.target
.value
)
}
/>
<Button
className="ml-1"
variant="outline"
type="submit"
onClick={
form.handleSubmit
}
disabled={
submitting
}
>
{submitting ? (
<span className="w-24">
Submitting...
</span>
) : (
<span className="w-24">
Submit
</span>
)}
</Button>
</div>
{field.state.meta.errors
.length ? (
<em>
{field.state.meta.errors.join(
","
)}
</em>
) : null}
</div>
);
}}
/>
</form>
{field.state.meta
.errors
.length ? (
<em>
{field.state.meta.errors.join(
","
)}
</em>
) : null}
</div>
);
}}
/>
</form>
)}
</>
)}
</div>
</LstCard>
<div className="grow max-w-[600px]">
<ChartData laneId={silo.LocationID} />
<div className="flex justify-end m-1">
<Link
to={"/siloAdjustments/$hist"}
params={{ hist: silo.LocationID }}
>
Historical Data
</Link>
<div className="flex justify-end m-1 gap-3">
<AttachSilo silo={silo} />
<DetachSilo silo={silo} />
<Button variant="outline">
<Link
to={"/siloAdjustments/$hist"}
params={{ hist: silo.LocationID }}
>
Historical Data
</Link>
</Button>
</div>
</div>
</div>

View File

@@ -9,8 +9,12 @@ import { useQuery } from "@tanstack/react-query";
//import { toast } from "sonner";
export default function INVCheckCard(props: any) {
//{ style = {} }
const { data, isError, isLoading } = useQuery(getinventoryCheck(props));
const { age, rowType } = props.data;
//console.log(props.data);
const { data, isError, isLoading } = useQuery(
getinventoryCheck({ age: age })
);
if (isLoading) return <div>Loading inventory data...</div>;
if (isError) {
@@ -23,11 +27,11 @@ export default function INVCheckCard(props: any) {
let laneData: any = data;
if (props.type != "") {
laneData = laneData.filter(
(l: any) => l.rowType === props.type.toUpperCase()
(l: any) => l.rowType === rowType.toUpperCase()
);
// age
laneData = laneData.filter((l: any) => l.DaysSinceLast >= props.age);
laneData = laneData.filter((l: any) => l.DaysSinceLast >= age);
}
// const handleCloseCard = () => {
@@ -36,5 +40,5 @@ export default function INVCheckCard(props: any) {
// toast.success("card removed");
// };
return <InvTable columns={invColumns} data={laneData} info={props} />;
return <InvTable columns={invColumns} data={laneData} info={props.data} />;
}

View File

@@ -16,8 +16,7 @@ import { getOcmeInfo } from "@/utils/querys/production/getOcmeInfo";
import { useQuery } from "@tanstack/react-query";
import { format } from "date-fns";
import { Trash } from "lucide-react";
import ManuallyEnterRn from "./ManuallyEnterRn";
import { Separator } from "../ui/separator";
import ManualTrigger from "../logistics/rfid/ManualTrigger";
const currentPallets = [
{ key: "line", label: "Line" },
@@ -160,11 +159,12 @@ export default function WrapperManualTrigger() {
<div>
<hr />
<p className="text-center mb-3">Manual Trigger</p>
{/* <p className="text-center mb-3">Manual Trigger</p>
<ManuallyEnterRn />
<Separator className="m-1" />
<div className="flex flex-row justify-between">
<Separator className="m-1" /> */}
<div className="flex flex-row justify-between m-2">
<Button onClick={cameraTrigger}>Camera</Button>
<ManualTrigger />
</div>
</div>
</LstCard>

View File

@@ -0,0 +1,27 @@
import { getlabelRatio } from "@/utils/querys/production/labelRatio";
import { labelRatioColumns } from "@/utils/tableData/production/labelRatio/labelRatioColumns";
import { LabelRatioTable } from "@/utils/tableData/production/labelRatio/labelRatioData";
import { useQuery } from "@tanstack/react-query";
export default function LabelRatio() {
const { data, isError, isLoading } = useQuery(getlabelRatio());
const ratioData = data ? data : [];
if (isError) {
return <div>Error</div>;
}
if (isLoading) {
return <div>Loading</div>;
}
return (
<div className="m-2">
<LabelRatioTable
columns={labelRatioColumns}
data={ratioData}
//style={style}
/>
</div>
);
}

View File

@@ -17,6 +17,8 @@ import { useQuery } from "@tanstack/react-query";
import ManualPrint from "./ManualPrinting/ManualPrint";
import ManualPrintForm from "./ManualPrinting/ManualPrintForm";
import { ScrollArea } from "@/components/ui/scroll-area";
import { useGetUserRoles } from "@/lib/store/useGetRoles";
import { useModuleStore } from "@/lib/store/useModuleStore";
let lotColumns = [
{
@@ -68,12 +70,21 @@ export default function Lots() {
const { data, isError, isLoading } = useQuery(getlots());
const { user } = useSessionStore();
const { settings } = useSettingStore();
const { userRoles } = useGetUserRoles();
const { modules } = useModuleStore();
const server = settings.filter((n) => n.name === "server")[0]?.value || "";
const roles = ["technician", "admin", "manager", "operator"];
const roles = ["systemAdmin", "technician", "admin", "manager", "operator"];
const lotdata = data ? data : [];
if (user && roles.includes(user.role)) {
const module = modules.filter((n) => n.name === "logistics");
const accessRoles = userRoles.filter(
(n) => n.module_id === module[0]?.module_id
) as any;
if (user && roles.includes(accessRoles[0]?.role)) {
//width = 1280;
const checkCol = lotColumns.some((l) => l.key === "printLabel");
if (!checkCol) {
@@ -230,22 +241,27 @@ export default function Lots() {
<TableCell className="font-medium">
{lot.overPrinting}
</TableCell>
{user && roles.includes(user.role) && (
<>
{server === "usday1vms006" ||
server === "localhost" ? (
<>
{user &&
roles.includes(
accessRoles[0]?.role
) && (
<>
{server === "usday1vms006" ||
server === "localhost" ? (
<>
<TableCell className="flex justify-center">
<ManualPrintForm />
</TableCell>
</>
) : (
<TableCell className="flex justify-center">
<ManualPrintForm />
<ManualPrint
lot={lot}
/>
</TableCell>
</>
) : (
<TableCell className="flex justify-center">
<ManualPrint lot={lot} />
</TableCell>
)}
</>
)}
)}
</>
)}
</TableRow>
))}
</TableBody>

View File

@@ -243,7 +243,8 @@ export default function ManualPrintForm() {
<Textarea
//label="Comments"
placeholder="add more info as needed."
{...register("additionalComments")}
{...(register("additionalComments"),
{ required: true, minLength: 10 })}
/>
</div>

View File

@@ -11,10 +11,12 @@ import {
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable-panels";
import LabelRatio from "./LabelRatio";
export default function OCPPage() {
const { settings } = useSettingStore();
if (settings.length === 0) return;
let server = settings.filter((n) => n.name === "server");
return (
@@ -63,18 +65,32 @@ export default function OCPPage() {
</ResizablePanelGroup>
</ResizablePanel>
<ResizableHandle />
<ResizablePanel defaultSize={25}>
<ResizablePanel className="min-h-[200px] min-w-[200px] max-w-[450px]">
<ResizablePanelGroup
direction="vertical"
autoSaveId="ocpPage"
autoSaveId="ocpPage_vert"
>
{server[0].value === "usday1vms006" && (
<ResizablePanel className="max-h-[300px]">
<ResizablePanel
style={{
overflow: "auto",
scrollbarWidth: "none",
}}
defaultSize={50}
className="min-h-[200px]"
>
<WrapperManualTrigger />
</ResizablePanel>
)}
{server[0].value === "localhost" && (
<ResizablePanel className="max-h-[300px]">
{server[0]?.value === "localhost" && (
<ResizablePanel
className="min-h-[200px]"
style={{
overflow: "auto",
scrollbarWidth: "none",
}}
defaultSize={50}
>
<WrapperManualTrigger />
</ResizablePanel>
)}
@@ -82,6 +98,7 @@ export default function OCPPage() {
<ResizableHandle />
<ResizablePanel>
<PrinterStatus />
<LabelRatio />
</ResizablePanel>
</ResizablePanelGroup>
</ResizablePanel>

View File

@@ -20,6 +20,7 @@ export const SessionProvider = ({
useEffect(() => {
fetchModules();
fetchSettings();
console.log("settings grab ran");
fetchUserRoles();
fetchSubModules();
}, []);

View File

@@ -0,0 +1,28 @@
import { getReaders } from "@/utils/querys/rfid/getReaders";
import { readerColumns } from "@/utils/tableData/rfid/readers/readerColumns";
import { ReaderTable } from "@/utils/tableData/rfid/readers/readerData";
import { useQuery } from "@tanstack/react-query";
export default function RfidPage() {
const { data, isError, isLoading } = useQuery(getReaders());
if (isError) {
return <div>Error</div>;
}
if (isLoading) {
return <div>Loading</div>;
}
return (
<div className="m-2">
<ReaderTable
columns={readerColumns}
data={data.data.sort((a: any, b: any) =>
a.reader.localeCompare(b.reader)
)}
//style={style}
/>
</div>
);
}

View File

@@ -1,73 +1,208 @@
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"
import {
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from "lucide-react"
import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
import { Button, buttonVariants } from "@/components/ui/button"
function Calendar({
className,
classNames,
showOutsideDays = true,
captionLayout = "label",
buttonVariant = "ghost",
formatters,
components,
...props
}: React.ComponentProps<typeof DayPicker>) {
}: React.ComponentProps<typeof DayPicker> & {
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
}) {
const defaultClassNames = getDefaultClassNames()
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
className={cn(
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
className
)}
captionLayout={captionLayout}
formatters={{
formatMonthDropdown: (date) =>
date.toLocaleString("default", { month: "short" }),
...formatters,
}}
classNames={{
months: "flex flex-col sm:flex-row gap-2",
month: "flex flex-col gap-4",
caption: "flex justify-center pt-1 relative items-center w-full",
caption_label: "text-sm font-medium",
nav: "flex items-center gap-1",
nav_button: cn(
buttonVariants({ variant: "outline" }),
"size-7 bg-transparent p-0 opacity-50 hover:opacity-100"
root: cn("w-fit", defaultClassNames.root),
months: cn(
"flex gap-4 flex-col md:flex-row relative",
defaultClassNames.months
),
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-x-1",
head_row: "flex",
head_cell:
"text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: cn(
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-range-end)]:rounded-r-md",
props.mode === "range"
? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
: "[&:has([aria-selected])]:rounded-md"
month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
nav: cn(
"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
defaultClassNames.nav
),
button_previous: cn(
buttonVariants({ variant: buttonVariant }),
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
defaultClassNames.button_previous
),
button_next: cn(
buttonVariants({ variant: buttonVariant }),
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
defaultClassNames.button_next
),
month_caption: cn(
"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
defaultClassNames.month_caption
),
dropdowns: cn(
"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
defaultClassNames.dropdowns
),
dropdown_root: cn(
"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
defaultClassNames.dropdown_root
),
dropdown: cn("absolute inset-0 opacity-0", defaultClassNames.dropdown),
caption_label: cn(
"select-none font-medium",
captionLayout === "label"
? "text-sm"
: "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
defaultClassNames.caption_label
),
table: "w-full border-collapse",
weekdays: cn("flex", defaultClassNames.weekdays),
weekday: cn(
"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
defaultClassNames.weekday
),
week: cn("flex w-full mt-2", defaultClassNames.week),
week_number_header: cn(
"select-none w-(--cell-size)",
defaultClassNames.week_number_header
),
week_number: cn(
"text-[0.8rem] select-none text-muted-foreground",
defaultClassNames.week_number
),
day: cn(
buttonVariants({ variant: "ghost" }),
"size-8 p-0 font-normal aria-selected:opacity-100"
"relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
defaultClassNames.day
),
day_range_start:
"day-range-start aria-selected:bg-primary aria-selected:text-primary-foreground",
day_range_end:
"day-range-end aria-selected:bg-primary aria-selected:text-primary-foreground",
day_selected:
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
day_today: "bg-accent text-accent-foreground",
day_outside:
"day-outside text-muted-foreground aria-selected:text-muted-foreground",
day_disabled: "text-muted-foreground opacity-50",
day_range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
range_start: cn(
"rounded-l-md bg-accent",
defaultClassNames.range_start
),
range_middle: cn("rounded-none", defaultClassNames.range_middle),
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
today: cn(
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
defaultClassNames.today
),
outside: cn(
"text-muted-foreground aria-selected:text-muted-foreground",
defaultClassNames.outside
),
disabled: cn(
"text-muted-foreground opacity-50",
defaultClassNames.disabled
),
hidden: cn("invisible", defaultClassNames.hidden),
...classNames,
}}
components={{
IconLeft: ({ className, ...props }) => (
<ChevronLeft className={cn("size-4", className)} {...props} />
),
IconRight: ({ className, ...props }) => (
<ChevronRight className={cn("size-4", className)} {...props} />
),
Root: ({ className, rootRef, ...props }) => {
return (
<div
data-slot="calendar"
ref={rootRef}
className={cn(className)}
{...props}
/>
)
},
Chevron: ({ className, orientation, ...props }) => {
if (orientation === "left") {
return (
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
)
}
if (orientation === "right") {
return (
<ChevronRightIcon
className={cn("size-4", className)}
{...props}
/>
)
}
return (
<ChevronDownIcon className={cn("size-4", className)} {...props} />
)
},
DayButton: CalendarDayButton,
WeekNumber: ({ children, ...props }) => {
return (
<td {...props}>
<div className="flex size-(--cell-size) items-center justify-center text-center">
{children}
</div>
</td>
)
},
...components,
}}
{...props}
/>
)
}
export { Calendar }
function CalendarDayButton({
className,
day,
modifiers,
...props
}: React.ComponentProps<typeof DayButton>) {
const defaultClassNames = getDefaultClassNames()
const ref = React.useRef<HTMLButtonElement>(null)
React.useEffect(() => {
if (modifiers.focused) ref.current?.focus()
}, [modifiers.focused])
return (
<Button
ref={ref}
variant="ghost"
size="icon"
data-day={day.date.toLocaleDateString()}
data-selected-single={
modifiers.selected &&
!modifiers.range_start &&
!modifiers.range_end &&
!modifiers.range_middle
}
data-range-start={modifiers.range_start}
data-range-end={modifiers.range_end}
data-range-middle={modifiers.range_middle}
className={cn(
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70",
defaultClassNames.day,
className
)}
{...props}
/>
)
}
export { Calendar, CalendarDayButton }

View File

@@ -19,7 +19,10 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-header"
className={cn("flex flex-col gap-1.5 px-6", className)}
className={cn(
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
className
)}
{...props}
/>
)
@@ -45,6 +48,19 @@ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
)
}
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-action"
className={cn(
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
className
)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
@@ -59,10 +75,18 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-footer"
className={cn("flex items-center px-6", className)}
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
{...props}
/>
)
}
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
}

View File

@@ -28,7 +28,7 @@ function PopoverContent({
align={align}
sideOffset={sideOffset}
className={cn(
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-hidden",
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
className
)}
{...props}

View File

@@ -0,0 +1,29 @@
import * as React from "react"
import * as SwitchPrimitive from "@radix-ui/react-switch"
import { cn } from "@/lib/utils"
function Switch({
className,
...props
}: React.ComponentProps<typeof SwitchPrimitive.Root>) {
return (
<SwitchPrimitive.Root
data-slot="switch"
className={cn(
"peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
<SwitchPrimitive.Thumb
data-slot="switch-thumb"
className={cn(
"bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
)}
/>
</SwitchPrimitive.Root>
)
}
export { Switch }

View File

@@ -1,9 +1,8 @@
import axios from "axios";
import {create} from "zustand";
import { create } from "zustand";
interface SettingState {
settings: any[];
fetchSettings: () => Promise<void>;
setSettings: (settings: any[]) => void;
}
@@ -13,17 +12,17 @@ interface FetchModulesResponse {
export const useSettingStore = create<SettingState>()((set) => ({
settings: [],
setSettings: (settings) => set({settings}),
setSettings: (settings) => set({ settings }),
fetchSettings: async () => {
try {
//const response = await axios.get<{data: Setting[]}>(`${process.env.NEXT_PUBLIC_URL}/api/settings/client`);
const response = await axios.get(`/api/server/settings`, {});
const data: FetchModulesResponse = response.data; //await response.json();
//console.log(data);
set({settings: data.data});
set({ settings: data.data });
} catch (error) {
console.error("Failed to fetch settings:", error);
set({settings: []});
set({ settings: [] });
}
},
}));

View File

@@ -1,16 +1,19 @@
import React from "react";
import ReactDOM from "react-dom/client";
import "./styles.css";
import {RouterProvider, createRouter} from "@tanstack/react-router";
import { RouterProvider, createRouter } from "@tanstack/react-router";
// Import the generated route tree
import {routeTree} from "./routeTree.gen";
import {QueryClient, QueryClientProvider} from "@tanstack/react-query";
import { routeTree } from "./routeTree.gen";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
// Create a client
const queryClient = new QueryClient();
// Create a new router instance
const router = createRouter({routeTree});
const router = createRouter({
routeTree,
//basepath: import.meta.env.BASE_URL, // This is the key part!
});
// Register the router instance for type safety
declare module "@tanstack/react-router" {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
import BGPage from "@/components/logistics/barcodeGenerator/BGPage";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/(logistics)/barcodegen/")({
component: RouteComponent,
});
function RouteComponent() {
return (
<div>
<BGPage />
</div>
);
}

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