Compare commits
630 Commits
ecb07c7e7c
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 88b6d0a235 | |||
| 8943407f27 | |||
| 0bbe411db0 | |||
| 99b3ad633c | |||
| c892348d19 | |||
| 360549aaf4 | |||
| bdc1e72fc1 | |||
| 4cae96b1ee | |||
| 1cde8ab2e6 | |||
| 03e8378213 | |||
| 275c93dc79 | |||
| fbb8c21d5c | |||
| dce93d3de2 | |||
| faf4e9f9ab | |||
| a9783a7d35 | |||
| e9ca6dbbb2 | |||
| e996f99400 | |||
| 3b939ff2d3 | |||
| a7ff88025e | |||
| 00899a5b77 | |||
| 99ecf52218 | |||
| a6920d7cd8 | |||
| 788efdf4b3 | |||
| a2a17beeeb | |||
| 6c793c66a4 | |||
| 6918a5a7d4 | |||
| ddd9b0e372 | |||
| 41d921756b | |||
| d86ca7d3bf | |||
| 932a72ba88 | |||
| b9c6d0ba57 | |||
| 592e4c8cd7 | |||
| b772666905 | |||
| a6edcb71bf | |||
| 76d929abea | |||
| da17defe82 | |||
| 669f5ca33f | |||
| b649dca4c9 | |||
| 04b8d041f9 | |||
| 71bc7c29bc | |||
| 79f1f8f91b | |||
| b677bc1498 | |||
| a53915ad8c | |||
| b3ce767b32 | |||
| 6caa5984e7 | |||
| 415d2e4a1d | |||
| 271cdbdbfa | |||
| 796a8dccd2 | |||
| e03e92c18d | |||
| dd2e5d04ae | |||
| 708b57b926 | |||
| 0444da8bbc | |||
| 6d49fae16d | |||
| be8a44f2dc | |||
| a3994a1f69 | |||
| 00eaf62d4c | |||
| 6851777faf | |||
| f9e97fc224 | |||
| 4e3c5e4191 | |||
| 172fd1d5c2 | |||
| 1094de2ebd | |||
| 7462b3d90b | |||
| 2045c13ef2 | |||
| 5fa9e83d5b | |||
| f48c944bd0 | |||
| dddd1d422e | |||
| 8133443ec9 | |||
| 28c7d30c1a | |||
| 57966ac9de | |||
| 6910550de7 | |||
| 1f8b8a7248 | |||
| cfed981928 | |||
| 0efe74d4b1 | |||
| c35db2e209 | |||
| e1cdeb740b | |||
| 3c9e75dc3c | |||
| 64b5b0d248 | |||
| 668eae9719 | |||
| 7cc3778506 | |||
| af47c1582e | |||
| 081572c421 | |||
| c6f6ef6262 | |||
| 34849e15d1 | |||
| 9bd66942f5 | |||
| 795da35141 | |||
| 468f933168 | |||
| 8c296c5b78 | |||
| 53ed2c4e6a | |||
| 0a6ddea8c0 | |||
| df423192bf | |||
| 2f908398bc | |||
| bf8203bbee | |||
| e92eccf785 | |||
| f4f3de49ca | |||
| 788d6367a3 | |||
| 24a97afe06 | |||
| 37f82a9710 | |||
| 369d16018c | |||
| 68901a857a | |||
| 171763184c | |||
| b7de2a8dbe | |||
| e78083f496 | |||
| 3f3b64bf2b | |||
| 123bb127e8 | |||
| 8d6ead3aa1 | |||
| 3148aa79d7 | |||
| 4486fe2436 | |||
| 0ba338d480 | |||
| 846ac479b1 | |||
| 73d38ba3fe | |||
| 27586e923a | |||
| 662a951b98 | |||
| 0c54cecbd4 | |||
| bcf5378966 | |||
| c5668e6cf1 | |||
| 213814b868 | |||
| 7d5b0c46c1 | |||
| 595e22e8e9 | |||
| a6f18554b8 | |||
| 88f61c8eaa | |||
| a183279268 | |||
| 5156c8bf7b | |||
| 4669ff95dc | |||
| ed93992165 | |||
| f16e2bf53b | |||
| a84998438c | |||
| 83469105f0 | |||
| 835ae58f04 | |||
| 1498a19121 | |||
| ca96849991 | |||
| 27b37f9849 | |||
| 7f81a2e09a | |||
| e14abd3644 | |||
| 2ff7b9baf9 | |||
| 8145dc800d | |||
| 6ccf500e5e | |||
| 103171c924 | |||
| 2eb6fa7794 | |||
| 397f1da595 | |||
| 8d63f7f6b0 | |||
| 52345bc94c | |||
| a8a1c1d7fb | |||
| 83ff2641f3 | |||
| 7c48f608bc | |||
| 1802b9ba4e | |||
| 67a12ccc5c | |||
| 15e2a65cbb | |||
| 9e5577e6bb | |||
| c52e2a8671 | |||
| 8f76d6998c | |||
| e209686d3c | |||
| 803c963f96 | |||
| 078f35626b | |||
| 2288884829 | |||
| 69fc7418c9 | |||
| a0179a41ba | |||
| a36552fd9b | |||
| c7bb12822b | |||
| 98a5ca7bb8 | |||
| 74ac2864c9 | |||
| 1f93eca561 | |||
| 1f44750346 | |||
| 0d17fef1a1 | |||
| f574645b44 | |||
| 998e84f564 | |||
| 3e51ebc18b | |||
| 8129dbb787 | |||
| b5561635dd | |||
| ff340161d6 | |||
| 39d0768d50 | |||
| d40ed30f55 | |||
| 8594d72d2c | |||
| 3e680a5a50 | |||
| e1113c49b3 | |||
| e964bb70ae | |||
| f01b6941ba | |||
| e78f3ffdb5 | |||
| 713df0b615 | |||
| f2615fbcea | |||
| 4f7d6fe4af | |||
| 96a3fd451b | |||
| d1befadd1c | |||
| fa99eb41dd | |||
| 11cc3662cf | |||
| d9a2f90056 | |||
| 23ee0468ad | |||
| 83ba84cf6f | |||
| 96d2a25081 | |||
| d54f85cf3d | |||
| 371870cbe5 | |||
| dd31763fdd | |||
| c9a64e2e7c | |||
| 733603fffa | |||
| bc92f8be0e | |||
| 9ced82b154 | |||
| d9bc68d6ac | |||
| 248e4cfeef | |||
| 9707990211 | |||
| 60672ba751 | |||
| 3b8190b080 | |||
| c1577ff432 | |||
| 40b382ca62 | |||
| 1ec3de0f02 | |||
| f5c035081c | |||
| 885e0ce348 | |||
| 7a59da77f2 | |||
| 82fb85ba0d | |||
| 0d263f6941 | |||
| 1762c70859 | |||
| c196b1d612 | |||
| 8926bfde00 | |||
| 256405b5a5 | |||
| eecf35fc9c | |||
| 700b18160c | |||
| 2dd6947bd6 | |||
| fe8ab62e94 | |||
| a0d476042b | |||
| 8e99a2e5e5 | |||
| 4b9f96f3b0 | |||
| 390107a1fb | |||
| e3a4ef7a80 | |||
| c224e30b8d | |||
| 16b710dc91 | |||
| a9e788f438 | |||
| 3aa4191b0f | |||
| 260d513ee3 | |||
| e9f729d5e2 | |||
| e43ac65d04 | |||
| 5199a9ce69 | |||
| 5ce78222b9 | |||
| 904de61e5a | |||
| c1ed482073 | |||
| f57426cf13 | |||
| 7079b151da | |||
| b87cd8dd7c | |||
| 531b343d17 | |||
| e2b549714c | |||
| e6f3a9b4d0 | |||
| 33295dc3c3 | |||
| 49fd9d65c9 | |||
| 0510f13885 | |||
| 588f264854 | |||
| 8afa4176ef | |||
| 611183fc19 | |||
| c31856ac3e | |||
| 61f0b7f06b | |||
| a7f8e39bac | |||
| 4923b3c698 | |||
| 28f34a6a31 | |||
| b81675e445 | |||
| c6d80dbc8a | |||
| bc54b365ea | |||
| 41308788fd | |||
| d6232cb358 | |||
| d89a336fb1 | |||
| e84ae42c83 | |||
| 6ec8f0863b | |||
| 4f231b343c | |||
| 454039e60c | |||
| c7c148fede | |||
| e30adc6612 | |||
| f7b4de8130 | |||
| 6584b37cb0 | |||
| 6a082d9737 | |||
| 58711becf2 | |||
| f757085fc2 | |||
| 8f5e1cb094 | |||
| 7497ee454c | |||
| c0ede8714c | |||
| 1a6a05112b | |||
| 97c6631eab | |||
| 1ae506939c | |||
| f0294942a7 | |||
| e323607b39 | |||
| df0851414e | |||
| a9b860a34d | |||
| ead35b4360 | |||
| d6b1a75afa | |||
| 1b661a6685 | |||
| f597142ee3 | |||
| 18780d872c | |||
| ba02ee42c5 | |||
| f573f4f721 | |||
| 1d6bf7215b | |||
| e616574fa6 | |||
| 08109f500f | |||
| ab8102afbf | |||
| e13b5a4283 | |||
| 7a4dea9d87 | |||
| a19ac539e7 | |||
| 1c910d80ea | |||
| 56e0f3eb47 | |||
| e50e9af839 | |||
| e34f273acb | |||
| 2c5f8a3a8c | |||
| 9e4729690a | |||
| 26ab6ecd8d | |||
| 05fa774d68 | |||
| b1acd97232 | |||
| edc874c302 | |||
| 4abecd0455 | |||
| 6c7193bc7a | |||
| c6739b6a73 | |||
| 13992bde68 | |||
| 7ed9db1bdb | |||
| f4dd572a8f | |||
| 3b56a5e3e2 | |||
| 2eea2911bc | |||
| c155e89bc7 | |||
| 7d9ea42f8d | |||
| 974f6587fc | |||
| 2ac48138cb | |||
| d6d19f8e5b | |||
| 3cafbd92d0 | |||
| 77d9e5d095 | |||
| 4a02bbc368 | |||
| f75da6525d | |||
| 26ceb95dae | |||
| bd5bad3cba | |||
| c5bd5a7c0a | |||
| 095d724e65 | |||
| 7df512acaa | |||
| 3073df342f | |||
| b9ff0a4138 | |||
| c555172d68 | |||
| e432f0b3ae | |||
| bc25e835b4 | |||
| a71167e598 | |||
| 53945402ce | |||
| aa42819cc1 | |||
| c36e4e66b3 | |||
| 11ae3cc0bc | |||
| f80e742e27 | |||
| 37f2518589 | |||
| 90be86d972 | |||
| 68d75277c2 | |||
| 84aacd5b71 | |||
| c72b4d3261 | |||
| b397fd7f32 | |||
| f90ce8cba7 | |||
| 88c1c29437 | |||
| f7c9f93d30 | |||
| 83f31b97f5 | |||
| b97f8175f9 | |||
| 92901a8762 | |||
| 0071237b24 | |||
| d32289c833 | |||
| 3c45010b26 | |||
| 4927428607 | |||
| 04298c9f54 | |||
| 6759a1bf8f | |||
| 92624cbac9 | |||
| f79ff26958 | |||
| e865c1dcaf | |||
| 99ad79c662 | |||
| 3283972809 | |||
| 1cb285bea8 | |||
| 4f5d5faecb | |||
| def97360be | |||
| a1229b4dee | |||
| 8d04c8f7de | |||
| 27eb96cc15 | |||
| 4187264e30 | |||
| bade51d57d | |||
| 078c2ec12f | |||
| 292eb324c5 | |||
| 51e6864868 | |||
| 0caf8094de | |||
| 92c8fc2554 | |||
| ed777437eb | |||
| 353960bd26 | |||
| 6156a1a5bb | |||
| 826c44c996 | |||
| aadf255e34 | |||
| 60690d2df4 | |||
| c31dc523e7 | |||
| caec533279 | |||
| 146832b569 | |||
| 0207e15f38 | |||
| 2701f18eec | |||
| 091305ea9f | |||
| b8e904b7c9 | |||
| 990e0a9aa4 | |||
| f9fa5defa3 | |||
| 136bf9820d | |||
| ab23dcdfb8 | |||
| e1332e754a | |||
| 879172d9cd | |||
| bcede5be86 | |||
| 853f0848a1 | |||
| b1856d9155 | |||
| 7b60ddcadf | |||
| 12d0c6923d | |||
| 678f2ebde0 | |||
| c26c907431 | |||
| 72a9ca5f87 | |||
| 94c3bb73b3 | |||
| c0560770da | |||
| 63179e71cc | |||
| 8d8fdefce8 | |||
| 1bfe923379 | |||
| 956a376d13 | |||
| d29de68608 | |||
| 5301575f92 | |||
| bcde9a7d45 | |||
| 37a4b83f8d | |||
| ad4c9502fa | |||
| ed44b11e5c | |||
| 89ce8f2299 | |||
| 29e0347f84 | |||
| a4dab55f7a | |||
| f5f376bc2e | |||
| c9d2782241 | |||
| 18d5988f8f | |||
| deb8196093 | |||
| 058e93b79b | |||
| b23c06cba6 | |||
| 23677efbe5 | |||
| b742698fe0 | |||
| a89087b7fa | |||
| 6651f83da8 | |||
| 788fc5f745 | |||
| 4f8dfeeff6 | |||
| b19fb6aeb6 | |||
| c94f501f95 | |||
| 2672e89005 | |||
| a6844d9455 | |||
| 563aafcf78 | |||
| b8e764ec3f | |||
| 553f76b81a | |||
| 055d11ccac | |||
| 96deca15f0 | |||
| 25cfee58d0 | |||
| 3eb87b5c0b | |||
| 0df1225e2f | |||
| d8b9326e0e | |||
| 67d5a28170 | |||
| 4182ce94c5 | |||
| 23da6c6304 | |||
| a07a9d2145 | |||
| 3687179646 | |||
| fb66a5559f | |||
| 208bbecb96 | |||
| d07d1000c3 | |||
| f8001f2497 | |||
| 8a890182be | |||
| eb1dc06b89 | |||
| 61dccf9dd0 | |||
| c2da6cf4fd | |||
| 1e079e8381 | |||
| f144a0a54c | |||
| 1cd7ec8aff | |||
| 018981cf9e | |||
| 0f44079666 | |||
| 32d011fc98 | |||
| cf8fd9dbb9 | |||
| 1ce0e6195e | |||
| e384640add | |||
| f3bf8a93cc | |||
| f7644b3333 | |||
| 9fbea9ebc8 | |||
| 5885fe8cd2 | |||
| 57ac7a6b8d | |||
| c88fedd75a | |||
| a5f1203a34 | |||
| b96a750e9e | |||
| fb603e74dc | |||
| 2559706510 | |||
| 89812d29a0 | |||
| 9148723607 | |||
| e2fcb09ff9 | |||
| 3ecad39440 | |||
| e9bcf2e21e | |||
| 54a4e008a2 | |||
| 522f313249 | |||
| cfd378dab6 | |||
| 1f0cb98dd8 | |||
| 080087fa0d | |||
| 2fe48097e5 | |||
| a93524a6ac | |||
| defeff3270 | |||
| 78c5da8e81 | |||
| f4a91614c1 | |||
| 2e0d26f2ad | |||
| 9d9a2683fa | |||
| 12ea23c9fb | |||
| 951396cd3c | |||
| fce9c74ead | |||
| a555a8b940 | |||
| 76c60d4a82 | |||
| 83008edf32 | |||
| 336a0343d5 | |||
| 3878211acb | |||
| 401c1899f2 | |||
| a7b3c6a79f | |||
| 87aac10090 | |||
| 5b0cff4d84 | |||
| 1c559c970a | |||
| 60d9fd1f55 | |||
| 9b76b7d023 | |||
| 082b36ba2b | |||
| b9de750668 | |||
| 4e3be2c565 | |||
| 8f828d764a | |||
| 9f68cd2146 | |||
| 3a78f77475 | |||
| 3817c33638 | |||
| ac68a65f5d | |||
| 0c80d3b87d | |||
| e9fd3730d6 | |||
| 0c719dc647 | |||
| ffeeea44c5 | |||
| c75b7c8d54 | |||
| 21bcdde625 | |||
| 6f46f40414 | |||
| 981c04e741 | |||
| a709be838f | |||
| 2921792c0a | |||
| e62b5409af | |||
| 85301bca32 | |||
| 7ed1c32ae9 | |||
| 156cd845e0 | |||
| 2e78d4c5fb | |||
| c71b1038f3 | |||
| e4a972643f | |||
| e6d20508e7 | |||
| 1ceee5e05e | |||
| 9f2baf98b4 | |||
| 99bed6a8aa | |||
| 9953846c7f | |||
| cd3e6c81e4 | |||
| e2152becf7 | |||
| 17af3776d1 | |||
| 75ff724805 | |||
| dbd3f76f02 | |||
| 3e79017afc | |||
| b3b6002d9a | |||
| acf266464a | |||
| bda8ac4119 | |||
| bb57930a88 | |||
| b0f59b6ec8 | |||
| f35c481aec | |||
| 9c8249b2e4 | |||
| 67d47ee030 | |||
| 0e5790702e | |||
| 8494a16c9f | |||
| b74a197778 | |||
| 2bc9e88588 | |||
| 63b59fe5ac | |||
| 3dc14e4097 | |||
| 9bee452446 | |||
| 67ded802bf | |||
| eb0a5d6311 | |||
| c5ebe4e2fa | |||
| 9cea76e01f | |||
| 3cb7fd2e1b | |||
| 1b90129516 | |||
| ead63d4b41 | |||
| 3573fd1a5b | |||
| 0ae8aea3ac | |||
| f74a22bbb1 | |||
| afa80114fb | |||
| 46f8d6cde6 | |||
| f272cf9ad9 | |||
| e81a6456d8 | |||
| 97cf624440 | |||
| e0df6b8cd7 | |||
| c248cc0129 | |||
| 57d3727f49 | |||
| 5a48dcf553 | |||
| eac7444038 | |||
| b290b21ca2 | |||
| 86905b591b | |||
| 28b050859a | |||
| 3c9e627021 | |||
| 7152e72822 | |||
| a03130a961 | |||
| aea06c12a0 | |||
| 4f1d83137b | |||
| 72a3292633 | |||
| 174a6c0adc | |||
| 556aaa381d | |||
| 5f7915b81f | |||
| 613a486160 | |||
| caccaf143c | |||
| 2a7eb26e6b | |||
| 844f337f6c | |||
| 4e1f7d4040 | |||
| 8786681923 | |||
| a3732c0208 | |||
| abc39634fb | |||
| dd7299ad76 | |||
| 2343f9387a | |||
| 9a6cec65cd | |||
| 92dc3855b9 | |||
| 6334efe093 | |||
| e9cb3e5db4 | |||
| 8422955d39 | |||
| 06d2f1464b | |||
| a1d526bd52 | |||
| 6ef9626cb7 | |||
| 55cc694a0e | |||
| 3b8296dd54 | |||
| c39a12759f | |||
| 7b0a1d08d2 | |||
| 925776b634 | |||
| 789ea31948 | |||
| f8ba05fbae | |||
| 44f418cfbc | |||
| d65450d5ee | |||
| 8240e9c5d3 | |||
| bb6d1c3bff | |||
| f44e5a87e7 | |||
| b42b8a4c83 | |||
| c741274ffa | |||
| 93693d3093 | |||
| fd49280313 | |||
| 39e5929b46 | |||
| 53520845a8 | |||
| 4fe7eed8ef | |||
| c397e56407 | |||
| ea0610c86b | |||
| 09fd408f6c | |||
| 96c1e4d28a | |||
| 0d4a5ca396 | |||
| 9011b9cb64 | |||
| bc519bcfeb | |||
| f0a1a7ada2 | |||
| 42dcd93d19 | |||
| fdd2024b84 |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -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
|
||||
@@ -150,3 +154,7 @@ dist
|
||||
.pnp.*
|
||||
|
||||
backend-0.1.3.zip
|
||||
BulkForecastTemplate
|
||||
BulkOrdersTemplate
|
||||
check.json
|
||||
server/services/ocp/controller/materials/materialcheck.bak
|
||||
|
||||
8
.includes
Normal file
8
.includes
Normal file
@@ -0,0 +1,8 @@
|
||||
database
|
||||
dist
|
||||
frontend/dist
|
||||
CHANGELOG.md
|
||||
drizzle.config.ts
|
||||
package.json
|
||||
package-lock.json
|
||||
README.md
|
||||
483
CHANGELOG.md
483
CHANGELOG.md
@@ -1,5 +1,488 @@
|
||||
# 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)
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **apihits:** so i can see if what end points are being used and when and how often ([9d9a268](https://git.tuffraid.net/cowch/lstV2/commits/9d9a2683fada6143b96b1d0f92b53a56879f1d45))
|
||||
* **datamart:** new query to check if the city state will be valid to process in tms ([78c5da8](https://git.tuffraid.net/cowch/lstV2/commits/78c5da8e81fb2075a05028546ea9c2fcfcc0fe05))
|
||||
* **dm:** added in p&g to the list ([b96a750](https://git.tuffraid.net/cowch/lstV2/commits/b96a750e9e7aa119b3f45840c6f976eb519eb4fc))
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **abbott orders:** working on times coming over as yesterday ([a5f1203](https://git.tuffraid.net/cowch/lstV2/commits/a5f1203a34f85a29c4bc516e0e1aa9d5ab1956d3))
|
||||
* **dm:** added day and hour to abbott truck to over come the weird posting issue ([cf8fd9d](https://git.tuffraid.net/cowch/lstV2/commits/cf8fd9dbb92f1584d901ea50476500261d1f81b0))
|
||||
* **lots:** if no lot assigned dont spam ([c88fedd](https://git.tuffraid.net/cowch/lstV2/commits/c88fedd75aaa3d063f8eed798168882b718d70c9))
|
||||
* **lots:** if no lots are assigned or released correct so nothing is posted ([080087f](https://git.tuffraid.net/cowch/lstV2/commits/080087fa0dc9968168b3f353bfe754b618ae315e))
|
||||
* **serverdata:** changed dayton to be 24 hour shipping and added marktree ([2e0d26f](https://git.tuffraid.net/cowch/lstV2/commits/2e0d26f2adbfe52803a8777eeeb387aa165c64b2))
|
||||
* **ti:** added some catches for the remark just being there and incorrect scac ([32d011f](https://git.tuffraid.net/cowch/lstV2/commits/32d011fc989311cb76a11fed2a6c03e6d301ba31))
|
||||
|
||||
|
||||
### 📝 Testing Code
|
||||
|
||||
* **old bols:** added the query to check for old bols ([0f44079](https://git.tuffraid.net/cowch/lstV2/commits/0f44079666f21106c6a0abf1f9f528ad5883967f))
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **datamart:** added product family to the article query ([f4a9161](https://git.tuffraid.net/cowch/lstV2/commits/f4a91614c1b7acb51bf5855551ea9ca0324888ac))
|
||||
* **macrotemplate:** bumped the version 2.7 > 2.8 ([1ce0e61](https://git.tuffraid.net/cowch/lstV2/commits/1ce0e6195e384683ee7c22f15cc1281cdd09cedd))
|
||||
* **master serverdata:** updated iowa city with a header info for remarks ([57ac7a6](https://git.tuffraid.net/cowch/lstV2/commits/57ac7a6b8d379b1babdb5ca02b81f0d6918ee242))
|
||||
* **printerdata:** changed change to have a static orderby so it dose not jump all over ([5885fe8](https://git.tuffraid.net/cowch/lstV2/commits/5885fe8cd2e68cc976a22640550556bb045b3048))
|
||||
* **serverdata:** corrected iowa2 data so it passes over to tms correctly ([1f0cb98](https://git.tuffraid.net/cowch/lstV2/commits/1f0cb98dd82096210122a376de97a64d7396ea87))
|
||||
* **ti import:** made a change to look at the loading date vs the delivery date ([fb603e7](https://git.tuffraid.net/cowch/lstV2/commits/fb603e74dc014ac04678d5dcd1ca8a2405437622))
|
||||
* **ti:** changes to post based on loading date not delivery date ([018981c](https://git.tuffraid.net/cowch/lstV2/commits/018981cf9e0d8bdc8132f4819abdb7bb745b543a))
|
||||
|
||||
## [2.20.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.19.0...v2.20.0) (2025-05-13)
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **bookin route:** endpoint point for bookin ([b9de750](https://git.tuffraid.net/cowch/lstV2/commits/b9de75066865d140494fc9a96a9b2809a9162117))
|
||||
* **helpercommand:** bookin pallets ([3a78f77](https://git.tuffraid.net/cowch/lstV2/commits/3a78f774751d8080d0c27eaf52c230fca67c175f))
|
||||
* **helpercommand:** helpercommand page ([4e3be2c](https://git.tuffraid.net/cowch/lstV2/commits/4e3be2c56503e8a9f42d80832ae038aeeeb96170))
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **serverdata:** added in citystate to change based on the json ([9b76b7d](https://git.tuffraid.net/cowch/lstV2/commits/9b76b7d023feb7f1ada5602c87d3e6ba062a087e))
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **createurl:** add catches for when server not installed ([8f828d7](https://git.tuffraid.net/cowch/lstV2/commits/8f828d764a09be9b5fb7726468afdd6fda3fd8aa))
|
||||
* **manual print:** missing role added ([9f68cd2](https://git.tuffraid.net/cowch/lstV2/commits/9f68cd2146c8dc9b62cec42661527cd88f63eccc))
|
||||
* **open orders:** made a change to correct the date being off by 1 day ([60d9fd1](https://git.tuffraid.net/cowch/lstV2/commits/60d9fd1f559f23a7b40b8426cac619106aac6991))
|
||||
* **server data:** corrected st to st. for ti intergration ([082b36b](https://git.tuffraid.net/cowch/lstV2/commits/082b36ba2be7243179b1399126161878d23bc3a2))
|
||||
|
||||
## [2.19.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.18.0...v2.19.0) (2025-05-02)
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **fakeedi updates:** corrected an issue where multi orders would not update if 1 release was used ([7ed1c32](https://git.tuffraid.net/cowch/lstV2/commits/7ed1c32ae919baf5c1d4cf464a5d0d6057b456fb))
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **loreal:** vmi file can be sent over now ([a709be8](https://git.tuffraid.net/cowch/lstV2/commits/a709be838f65a750065269b4dd83a4ffd64c2feb))
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **blocking notification:** changed to look at the latest blocking order and only pull 1 at a t ([981c04e](https://git.tuffraid.net/cowch/lstV2/commits/981c04e7417cbdfb549d60a316d618b07e8eff8c))
|
||||
* **blocking query:** changes made to only show 1 bo at a atime ([21bcdde](https://git.tuffraid.net/cowch/lstV2/commits/21bcdde625d953a53630f1345f68ab6c06b68aa6))
|
||||
* **iowa1 and stp1:** now activated with ti ([6f46f40](https://git.tuffraid.net/cowch/lstV2/commits/6f46f40414efde78e2843c5b7b52b06f12336973))
|
||||
* **serverdata:** updated mcd and dayton for tms ([e4a9726](https://git.tuffraid.net/cowch/lstV2/commits/e4a972643fcba842ed39a8ad58d3a9355db150ab))
|
||||
|
||||
|
||||
### 📝 Testing Code
|
||||
|
||||
* **fifo index:** started process for fifo index ([c75b7c8](https://git.tuffraid.net/cowch/lstV2/commits/c75b7c8d54f10763a874ecf7a8501dbc177a8e71))
|
||||
|
||||
## [2.18.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.17.0...v2.18.0) (2025-04-29)
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **sql:** improved the return function to show data [] when not connected, prevents crashes ([ead63d4](https://git.tuffraid.net/cowch/lstV2/commits/ead63d4b4124b070679e6e781555047a8e4c5ad5))
|
||||
* **swagger:** changes to the link so it opens in a new window ([b0f59b6](https://git.tuffraid.net/cowch/lstV2/commits/b0f59b6ec80a4dbd8304dd0018b56d0273600203))
|
||||
* **tcp:** added in a destory function to make sure we always disconnect from the tcp device ([1b90129](https://git.tuffraid.net/cowch/lstV2/commits/1b901295164f37ec9620f48a06c188140d5fb89c))
|
||||
* **time:** more time changes to fix 24 hour format ([3cb7fd2](https://git.tuffraid.net/cowch/lstV2/commits/3cb7fd2e1b49425a9ad6e7ffab9c1c11fbc6b593))
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **dm:** added in so test and dev see everything always ([63b59fe](https://git.tuffraid.net/cowch/lstV2/commits/63b59fe5ac5a3c79df3a1760afbeb835280f2052))
|
||||
* **fakeedi:** fake edi macro update implemented ([3e79017](https://git.tuffraid.net/cowch/lstV2/commits/3e79017afc4764ce41bbbf7a2a0cc9ffaf8111ac))
|
||||
* **ocme:** added in option to manually add running number if camera isnt working ([9cea76e](https://git.tuffraid.net/cowch/lstV2/commits/9cea76e01fca91aaf5d2d9a520184429a9936737))
|
||||
* **swagger link:** added in prod swagger link to admin panel ([67d47ee](https://git.tuffraid.net/cowch/lstV2/commits/67d47ee0309ba74b0e2f0edf613e98542d2e918b))
|
||||
|
||||
|
||||
### 📝 Testing Code
|
||||
|
||||
* **outbound:** test for outbound deliveryes edit ([75ff724](https://git.tuffraid.net/cowch/lstV2/commits/75ff7248057211a588c30794be27af25a09e3487))
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **abbott orders:** corrected the ignore function for already in progress orders ([2bc9e88](https://git.tuffraid.net/cowch/lstV2/commits/2bc9e88588b564e0728ab66c95d1597ed7da7656))
|
||||
* **abbott:** fix to properly remove the space in the middle of the po ([17af377](https://git.tuffraid.net/cowch/lstV2/commits/17af3776d1964325dcc5af231187011195752ae7))
|
||||
* **blocking orders:** removed some console logs ([9953846](https://git.tuffraid.net/cowch/lstV2/commits/9953846c7f8ed25108211362b014eb66e6b94c89))
|
||||
* **datamart:** corrected endpoins due to recent sql changes ([b74a197](https://git.tuffraid.net/cowch/lstV2/commits/b74a197778065c53be1e0e94e5b6b7f8ce11d069))
|
||||
* **datamart:** fixed to open order to show the correct customer release number ([cd3e6c8](https://git.tuffraid.net/cowch/lstV2/commits/cd3e6c81e417287f4dcab7bbdbd2dda97c5c0a43))
|
||||
* **datamart:** typo in the get delivery by date range ([dbd3f76](https://git.tuffraid.net/cowch/lstV2/commits/dbd3f76f022f0c5ca26d27d4b6357fd5c731f88d))
|
||||
* **lots:** missed .data on the lotInfo return ([eb0a5d6](https://git.tuffraid.net/cowch/lstV2/commits/eb0a5d63115d6f1d33835fb995ed65249400269f))
|
||||
* **mmstaged check:** changes to prevent crash where lot sent over is not an object ([c5ebe4e](https://git.tuffraid.net/cowch/lstV2/commits/c5ebe4e2fa414540f9cac1babc52c3d1c6a4f2f7))
|
||||
* **ocme counts:** corrected the reset on the tpye select to always clear out ([3dc14e4](https://git.tuffraid.net/cowch/lstV2/commits/3dc14e40970bab6a4ed9a26ceb8785349a9bb50d))
|
||||
* **openorders:** changes to prevent and error during the get request due to missing data ([9c8249b](https://git.tuffraid.net/cowch/lstV2/commits/9c8249b2e492fa30492c48bdd6f06407abe21a38))
|
||||
* **ppoo:** changes to prevent blank screen ([f35c481](https://git.tuffraid.net/cowch/lstV2/commits/f35c481aeccbe86285c4c2849c77decf3db44513))
|
||||
* **stock silo data:** correction to how the data comes abck to us ([99bed6a](https://git.tuffraid.net/cowch/lstV2/commits/99bed6a8aafa82e6cd6d1649e7af6570c95144ba))
|
||||
* **submodules:** correction to the role name so its now roles and properly updates ([e2152be](https://git.tuffraid.net/cowch/lstV2/commits/e2152becf73218b38d730834e1d9cbf8172f00c7))
|
||||
|
||||
## [2.17.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.16.1...v2.17.0) (2025-04-23)
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **profile updates:** added a link to the profile change email ([5a48dcf](https://git.tuffraid.net/cowch/lstV2/commits/5a48dcf55379aa1b622bfef6efbc1c66e7ada74e))
|
||||
* **profile:** changed to patch vs posting ([57d3727](https://git.tuffraid.net/cowch/lstV2/commits/57d3727f490bf020044287dbc63f3f6268467de2))
|
||||
|
||||
|
||||
### 📝 Testing Code
|
||||
|
||||
* **forecast:** loreal forecast starting ([c248cc0](https://git.tuffraid.net/cowch/lstV2/commits/c248cc012946dcfe1afb24724075180b6bccbf03))
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **build:** removed v1 from being built in ([a03130a](https://git.tuffraid.net/cowch/lstV2/commits/a03130a961bab430a1352a88ab8dda058f3b5ef6))
|
||||
* **dm:** buttons to the nav bar if customs are made ([3c9e627](https://git.tuffraid.net/cowch/lstV2/commits/3c9e627021b31d6ba711324c00ca6514a4ab7b89))
|
||||
* **dm:** standard forecast and orders in ([28b0508](https://git.tuffraid.net/cowch/lstV2/commits/28b050859a190c6cebbd0e524999c0a9c5b61bf0))
|
||||
* **lst:** removed v1 from the update ([b290b21](https://git.tuffraid.net/cowch/lstV2/commits/b290b21ca2ace219f508ac2c97c85f062d1f4c2a))
|
||||
* **orders:** energizer orders in ([e0df6b8](https://git.tuffraid.net/cowch/lstV2/commits/e0df6b8cd7bfe07415b7d0d074cb4b60c94f2b44))
|
||||
* **password change:** added in password link to email and change in lst ([86905b5](https://git.tuffraid.net/cowch/lstV2/commits/86905b591ba9891cfdd1d0d8a02d78781179e488))
|
||||
* **registerpage:** added in but hidden ([7152e72](https://git.tuffraid.net/cowch/lstV2/commits/7152e72822aecf5de6a9ac32057b8f9a26bb3907))
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **lot assignment:** removed the return i had oops ([97cf624](https://git.tuffraid.net/cowch/lstV2/commits/97cf624440d5631494109054505b58c8ee91dd48))
|
||||
* **register:** typo ([eac7444](https://git.tuffraid.net/cowch/lstV2/commits/eac74440386c6e83655e18096a3da476865259f0))
|
||||
|
||||
### [2.16.1](https://git.tuffraid.net/cowch/lstV2/compare/v2.16.0...v2.16.1) (2025-04-23)
|
||||
|
||||
## [2.16.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.15.0...v2.16.0) (2025-04-22)
|
||||
|
||||
|
||||
### 🚀 Performance
|
||||
|
||||
* **db:** better control over how we stay connected ([2eafbdf](https://git.tuffraid.net/cowch/lstV2/commits/2eafbdf45eb0725b04de1ab71492a3ef57645e72))
|
||||
|
||||
|
||||
### 🌟 Enhancements
|
||||
|
||||
* **abbott import:** custom abbott import with time and date correction ([07c0be0](https://git.tuffraid.net/cowch/lstV2/commits/07c0be0ea161763dc9fccf510156ab115aca02a9))
|
||||
* **bulk orders:** standard template created ([632e079](https://git.tuffraid.net/cowch/lstV2/commits/632e07967aaf60deb6425ac27ffc2274ce770907))
|
||||
* **dm:** added import and exports plus first custom for dayton ([8422955](https://git.tuffraid.net/cowch/lstV2/commits/8422955d3988da835738c6af334a946b079aecaf))
|
||||
* **forecast:** migrated forecast over ([dcfa96b](https://git.tuffraid.net/cowch/lstV2/commits/dcfa96b710333f96857a398aea9d8a694993e4ae))
|
||||
* **manual print options:** added in block for printing and new log type ([af8d53c](https://git.tuffraid.net/cowch/lstV2/commits/af8d53cac1cb95c917ac5084e8d61849b441757e))
|
||||
* **ocme cycle counts:** tracking of cycle counts and when they were done ([95ca2ff](https://git.tuffraid.net/cowch/lstV2/commits/95ca2ff2b3bab09bfb1d72a7ec3f7dff72bd8d0f))
|
||||
* **ocme:** cycle count added to db will add to front end later for users to inspect ([fbc2282](https://git.tuffraid.net/cowch/lstV2/commits/fbc2282aee4e559ffc5c9a596264e50dddecaf3e))
|
||||
* **openorders:** new open order card and page ([9cb8ca6](https://git.tuffraid.net/cowch/lstV2/commits/9cb8ca681309716479ddf741e0aeef7027685ef2))
|
||||
* **quality:** addpallet and cycle pallets added ([c25c2d0](https://git.tuffraid.net/cowch/lstV2/commits/c25c2d006a491150b37a67d89673ba4228262c0a))
|
||||
* **standard orders in:** multi customer orders in plus ignore already started ([68ccf23](https://git.tuffraid.net/cowch/lstV2/commits/68ccf2382bcc698c8d5a898d75b94f2db94af572))
|
||||
|
||||
|
||||
### 📝 Testing Code
|
||||
|
||||
* **rfid:** more rfid work and tested working ([a68a3ba](https://git.tuffraid.net/cowch/lstV2/commits/a68a3ba640b26ae91e322169740aa196e0ac8871))
|
||||
* **time:** more time testing ([6334efe](https://git.tuffraid.net/cowch/lstV2/commits/6334efe0930af9227706a1c52d068d3c7ee45dd4))
|
||||
|
||||
|
||||
### 🛠️ Code Refactor
|
||||
|
||||
* **bulk orders:** improvments and changes that i wanted in but missed ([ecb07c7](https://git.tuffraid.net/cowch/lstV2/commits/ecb07c7e7cbca9b486dfdcad17cdbfb8a057fe3f))
|
||||
* **cards:** messing with the time in the cards ([5cdca0a](https://git.tuffraid.net/cowch/lstV2/commits/5cdca0a41f8147b7d9d4e0b5f4474a3cf98c7cf1))
|
||||
* **dm:** repaced the orders in image with the new updated one ([06d2f14](https://git.tuffraid.net/cowch/lstV2/commits/06d2f1464bac83aa5ce30ae7635e5d718f9d9056))
|
||||
* **inventory card:** change to 15min check ([2d39f93](https://git.tuffraid.net/cowch/lstV2/commits/2d39f93e42350699711642e74b97fca7624d6f21))
|
||||
* **inventory card:** changed to 500 by default so we can scroll ([9a6cec6](https://git.tuffraid.net/cowch/lstV2/commits/9a6cec65cd74168a1bbe3dc8fc865db71958f87b))
|
||||
* **lots:** changed the way the time looks ([26798ca](https://git.tuffraid.net/cowch/lstV2/commits/26798ca14087b0c2173a8adcb851c71d4c2c4616))
|
||||
* **ocme:** moved the server port to the app vs ocme ([2343f93](https://git.tuffraid.net/cowch/lstV2/commits/2343f9387a39e6272de9e889d459b61085c7bc97))
|
||||
* **ocp:** resizbale with scrollling added makes more easy to review if table overflows ([d0a19b5](https://git.tuffraid.net/cowch/lstV2/commits/d0a19b55892c3f00adef4d267482fa1e905b9655))
|
||||
* **serverdata:** changed all server ports to 3000 ([dd7299a](https://git.tuffraid.net/cowch/lstV2/commits/dd7299ad76e802fabf2acefc049840a62ec814af))
|
||||
* **services:** removed some comments that were no longer needed ([2ffc3cc](https://git.tuffraid.net/cowch/lstV2/commits/2ffc3cc24291434f7ea765e487525c7c9388e0b7))
|
||||
* **standard in:** returns the orders in success or failed and why ([085dc64](https://git.tuffraid.net/cowch/lstV2/commits/085dc64db9615d291f45fa29513f904b8ee1b4b0))
|
||||
* **updater:** removed v1 from restarting ([8c5c9fd](https://git.tuffraid.net/cowch/lstV2/commits/8c5c9fd24402fcfb419306ed42dc15aea4ca87ed))
|
||||
* **v1 cleanup:** added in removal of localstoage items from v1 ([f44e5a8](https://git.tuffraid.net/cowch/lstV2/commits/f44e5a87e7dfa9f577c7dfad38a07cecb1ae8f49))
|
||||
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
* **macrotemplate:** bump version so everyone gets the new sheety ([abc3963](https://git.tuffraid.net/cowch/lstV2/commits/abc39634fb3b951c7e94e6f82b459ae46466e813))
|
||||
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
* **auth:** corrected to remove localstorage ([e780a24](https://git.tuffraid.net/cowch/lstV2/commits/e780a24a8ab1170dd5c79c82f1c64f3c24712740))
|
||||
* **blocking notification:** added throw error so i get an email when it errors ([a3732c0](https://git.tuffraid.net/cowch/lstV2/commits/a3732c02082e110c6447c5a686c5d945c19e4832))
|
||||
* **log cleanup:** corrected the level look at ([8240e9c](https://git.tuffraid.net/cowch/lstV2/commits/8240e9c5d313326fb1d168a2820810c7c4747013))
|
||||
* **lots errors:** fixes to prevent crashes when sql server not connected ([d5114ba](https://git.tuffraid.net/cowch/lstV2/commits/d5114ba2435ecb90a1f307c2e3c3d8dcf3dbf8a3))
|
||||
* **lst:** removed console log on useraccess ([92dc385](https://git.tuffraid.net/cowch/lstV2/commits/92dc3855b943252cba96c5e5f982c364155f6a47))
|
||||
* **manual print form:** corrected typos and name ([e9cb3e5](https://git.tuffraid.net/cowch/lstV2/commits/e9cb3e5db4e29efc583822c2c2ce0703ebcffb2c))
|
||||
* **ocme:** added in field catch ([917090e](https://git.tuffraid.net/cowch/lstV2/commits/917090eaa9540a0997553ff176bcf6852907c769))
|
||||
* **ocme:** cycle counts on an empty stock row would crash corrected so this wont happen ([d65450d](https://git.tuffraid.net/cowch/lstV2/commits/d65450d5ee5e488766323c40fb782b4d5133afd9))
|
||||
* **ocp page:** changed to localhost for dev it was showing the card twice ([c79496e](https://git.tuffraid.net/cowch/lstV2/commits/c79496eaac76f3423f2ac66b07d5f7783d41569b))
|
||||
* **time:** changes the labeling time to be our db version ([bb6d1c3](https://git.tuffraid.net/cowch/lstV2/commits/bb6d1c3bffa21a00b30d0e5d418b337c5ee1dcaf))
|
||||
|
||||
## [2.15.0](https://git.tuffraid.net/cowch/lstV2/compare/v2.14.0...v2.15.0) (2025-04-14)
|
||||
|
||||
|
||||
|
||||
177
README.md
177
README.md
@@ -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": "" }]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
11
database/migrations/0053_short_colleen_wing.sql
Normal file
11
database/migrations/0053_short_colleen_wing.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE "apiHits" (
|
||||
"ip" text,
|
||||
"endpoint" text,
|
||||
"action" text,
|
||||
"lastBody" text,
|
||||
"stats" text,
|
||||
"add_date" timestamp DEFAULT now(),
|
||||
"upd_date" timestamp DEFAULT now()
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "endpoint" ON "apiHits" USING btree ("endpoint","ip");
|
||||
1
database/migrations/0054_careless_ultron.sql
Normal file
1
database/migrations/0054_careless_ultron.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "apiHits" ADD COLUMN "apiHit_id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL;
|
||||
1
database/migrations/0055_sudden_frank_castle.sql
Normal file
1
database/migrations/0055_sudden_frank_castle.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "apiHits" ALTER COLUMN "stats" SET DATA TYPE integer;
|
||||
1
database/migrations/0056_breezy_inertia.sql
Normal file
1
database/migrations/0056_breezy_inertia.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "apiHits" DROP COLUMN "stats";
|
||||
1
database/migrations/0057_orange_lady_deathstrike.sql
Normal file
1
database/migrations/0057_orange_lady_deathstrike.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "apiHits" ADD COLUMN "stats" integer;
|
||||
1
database/migrations/0058_cultured_argent.sql
Normal file
1
database/migrations/0058_cultured_argent.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "apiHits" ALTER COLUMN "stats" SET DEFAULT 1;
|
||||
1
database/migrations/0059_calm_energizer.sql
Normal file
1
database/migrations/0059_calm_energizer.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "apiHits" DROP COLUMN "lastBody";
|
||||
1
database/migrations/0060_daffy_overlord.sql
Normal file
1
database/migrations/0060_daffy_overlord.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "apiHits" ADD COLUMN "lastBody" jsonb;
|
||||
11
database/migrations/0061_mature_the_stranger.sql
Normal file
11
database/migrations/0061_mature_the_stranger.sql
Normal 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");
|
||||
16
database/migrations/0062_narrow_silver_centurion.sql
Normal file
16
database/migrations/0062_narrow_silver_centurion.sql
Normal 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
|
||||
);
|
||||
5
database/migrations/0063_powerful_revanche.sql
Normal file
5
database/migrations/0063_powerful_revanche.sql
Normal 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;
|
||||
1
database/migrations/0064_aberrant_blindfold.sql
Normal file
1
database/migrations/0064_aberrant_blindfold.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "invHistoricalData" ALTER COLUMN "avaliable_QTY" SET DATA TYPE text;
|
||||
13
database/migrations/0065_nappy_talos.sql
Normal file
13
database/migrations/0065_nappy_talos.sql
Normal 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");
|
||||
7
database/migrations/0066_nosy_dark_beast.sql
Normal file
7
database/migrations/0066_nosy_dark_beast.sql
Normal 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()
|
||||
);
|
||||
1
database/migrations/0067_shallow_trish_tilby.sql
Normal file
1
database/migrations/0067_shallow_trish_tilby.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "printerData" ADD COLUMN "processes" jsonb DEFAULT '[]'::jsonb;
|
||||
1
database/migrations/0068_last_caretaker.sql
Normal file
1
database/migrations/0068_last_caretaker.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "rfidTags" RENAME COLUMN "timeStamp" TO "lastRead";
|
||||
2
database/migrations/0069_chemical_maximus.sql
Normal file
2
database/migrations/0069_chemical_maximus.sql
Normal 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;
|
||||
10
database/migrations/0070_brief_mephisto.sql
Normal file
10
database/migrations/0070_brief_mephisto.sql
Normal 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");
|
||||
2
database/migrations/0071_fantastic_old_lace.sql
Normal file
2
database/migrations/0071_fantastic_old_lace.sql
Normal 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();
|
||||
3
database/migrations/0072_round_black_knight.sql
Normal file
3
database/migrations/0072_round_black_knight.sql
Normal 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;
|
||||
1844
database/migrations/meta/0053_snapshot.json
Normal file
1844
database/migrations/meta/0053_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1851
database/migrations/meta/0054_snapshot.json
Normal file
1851
database/migrations/meta/0054_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1851
database/migrations/meta/0055_snapshot.json
Normal file
1851
database/migrations/meta/0055_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1845
database/migrations/meta/0056_snapshot.json
Normal file
1845
database/migrations/meta/0056_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1851
database/migrations/meta/0057_snapshot.json
Normal file
1851
database/migrations/meta/0057_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1852
database/migrations/meta/0058_snapshot.json
Normal file
1852
database/migrations/meta/0058_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1846
database/migrations/meta/0059_snapshot.json
Normal file
1846
database/migrations/meta/0059_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1852
database/migrations/meta/0060_snapshot.json
Normal file
1852
database/migrations/meta/0060_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
1925
database/migrations/meta/0061_snapshot.json
Normal file
1925
database/migrations/meta/0061_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2023
database/migrations/meta/0062_snapshot.json
Normal file
2023
database/migrations/meta/0062_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2023
database/migrations/meta/0063_snapshot.json
Normal file
2023
database/migrations/meta/0063_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2023
database/migrations/meta/0064_snapshot.json
Normal file
2023
database/migrations/meta/0064_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2113
database/migrations/meta/0065_snapshot.json
Normal file
2113
database/migrations/meta/0065_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2159
database/migrations/meta/0066_snapshot.json
Normal file
2159
database/migrations/meta/0066_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2166
database/migrations/meta/0067_snapshot.json
Normal file
2166
database/migrations/meta/0067_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2166
database/migrations/meta/0068_snapshot.json
Normal file
2166
database/migrations/meta/0068_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2180
database/migrations/meta/0069_snapshot.json
Normal file
2180
database/migrations/meta/0069_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2250
database/migrations/meta/0070_snapshot.json
Normal file
2250
database/migrations/meta/0070_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2252
database/migrations/meta/0071_snapshot.json
Normal file
2252
database/migrations/meta/0071_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2252
database/migrations/meta/0072_snapshot.json
Normal file
2252
database/migrations/meta/0072_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -372,6 +372,146 @@
|
||||
"when": 1744685129838,
|
||||
"tag": "0052_dark_human_torch",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 53,
|
||||
"version": "7",
|
||||
"when": 1747355241210,
|
||||
"tag": "0053_short_colleen_wing",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 54,
|
||||
"version": "7",
|
||||
"when": 1747355689811,
|
||||
"tag": "0054_careless_ultron",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 55,
|
||||
"version": "7",
|
||||
"when": 1747355837326,
|
||||
"tag": "0055_sudden_frank_castle",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 56,
|
||||
"version": "7",
|
||||
"when": 1747355877490,
|
||||
"tag": "0056_breezy_inertia",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 57,
|
||||
"version": "7",
|
||||
"when": 1747355892746,
|
||||
"tag": "0057_orange_lady_deathstrike",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 58,
|
||||
"version": "7",
|
||||
"when": 1747356938396,
|
||||
"tag": "0058_cultured_argent",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 59,
|
||||
"version": "7",
|
||||
"when": 1747357471279,
|
||||
"tag": "0059_calm_energizer",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 60,
|
||||
"version": "7",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,21 +1,30 @@
|
||||
import {pgTable, text, timestamp} from "drizzle-orm/pg-core";
|
||||
import {createSelectSchema} from "drizzle-zod";
|
||||
import {
|
||||
integer,
|
||||
jsonb,
|
||||
pgTable,
|
||||
text,
|
||||
timestamp,
|
||||
uniqueIndex,
|
||||
uuid,
|
||||
} from "drizzle-orm/pg-core";
|
||||
import { createSelectSchema } from "drizzle-zod";
|
||||
|
||||
export const apiHits = pgTable(
|
||||
"apiHits",
|
||||
{
|
||||
apiHit_id: uuid("apiHit_id").defaultRandom().primaryKey(),
|
||||
ip: text("ip"),
|
||||
endpoint: text("endpoint"),
|
||||
action: text("action"),
|
||||
lastBody: text("lastBody"),
|
||||
stats: text("stats"),
|
||||
lastBody: jsonb("lastBody"),
|
||||
stats: integer("stats").default(1),
|
||||
add_date: timestamp().defaultNow(),
|
||||
upd_date: timestamp().defaultNow(),
|
||||
}
|
||||
// (table) => [
|
||||
// // uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
|
||||
// uniqueIndex("role_name").on(table.name),
|
||||
// ]
|
||||
},
|
||||
(table) => [
|
||||
// uniqueIndex('emailUniqueIndex').on(sql`lower(${table.email})`),
|
||||
uniqueIndex("endpoint").on(table.endpoint, table.ip),
|
||||
]
|
||||
);
|
||||
|
||||
// Schema for inserting a user - can be used to validate API requests
|
||||
|
||||
25
database/schema/commandLog.ts
Normal file
25
database/schema/commandLog.ts
Normal 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);
|
||||
@@ -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})`),
|
||||
|
||||
40
database/schema/fifoIndex.ts
Normal file
40
database/schema/fifoIndex.ts
Normal 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);
|
||||
0
database/schema/forkliftHours.ts
Normal file
0
database/schema/forkliftHours.ts
Normal file
0
database/schema/forkliftLeases.ts
Normal file
0
database/schema/forkliftLeases.ts
Normal file
0
database/schema/forklifts.ts
Normal file
0
database/schema/forklifts.ts
Normal file
41
database/schema/historicalINV.ts
Normal file
41
database/schema/historicalINV.ts
Normal 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);
|
||||
@@ -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(),
|
||||
},
|
||||
|
||||
38
database/schema/prodPermissions.ts
Normal file
38
database/schema/prodPermissions.ts
Normal 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
32
database/schema/ratios.ts
Normal 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);
|
||||
@@ -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})`),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
},
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
26
dotnetwrapper/Program.cs
Normal 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();
|
||||
23
dotnetwrapper/Properties/launchSettings.json
Normal file
23
dotnetwrapper/Properties/launchSettings.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
dotnetwrapper/appsettings.json
Normal file
9
dotnetwrapper/appsettings.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
27
dotnetwrapper/lst-wrapper.csproj
Normal file
27
dotnetwrapper/lst-wrapper.csproj
Normal 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>
|
||||
24
dotnetwrapper/lst-wrapper.sln
Normal file
24
dotnetwrapper/lst-wrapper.sln
Normal 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
|
||||
3865
frontend/package-lock.json
generated
3865
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 73 KiB |
BIN
frontend/public/imgs/ordersInExample.png
Normal file
BIN
frontend/public/imgs/ordersInExample.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
225
frontend/src/components/admin/prodUser/ProdUserCard.tsx
Normal file
225
frontend/src/components/admin/prodUser/ProdUserCard.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 ?? "")
|
||||
|
||||
@@ -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={{
|
||||
|
||||
213
frontend/src/components/auth/Register.tsx
Normal file
213
frontend/src/components/auth/Register.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
import { LstCard } from "../extendedUI/LstCard";
|
||||
import { CardHeader } from "../ui/card";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { Label } from "../ui/label";
|
||||
import { Input } from "../ui/input";
|
||||
import { Button } from "../ui/button";
|
||||
import { useForm } from "@tanstack/react-form";
|
||||
import { Separator } from "../ui/separator";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
export default function RegisterForm() {
|
||||
const navigate = useNavigate();
|
||||
const [registering, setRegistering] = useState(false);
|
||||
const form = useForm({
|
||||
defaultValues: {
|
||||
username: "",
|
||||
password: "",
|
||||
email: "",
|
||||
},
|
||||
onSubmit: async ({ value }) => {
|
||||
setRegistering(true);
|
||||
try {
|
||||
const res = await axios.post("/api/auth/register", value);
|
||||
|
||||
if (res.data.success) {
|
||||
navigate({ to: "/login" });
|
||||
form.reset();
|
||||
toast.success(
|
||||
`${value.username} was just created please login`
|
||||
);
|
||||
setRegistering(false);
|
||||
}
|
||||
|
||||
if (!res.data.success) {
|
||||
toast.error(res.data.message);
|
||||
setRegistering(false);
|
||||
}
|
||||
} catch (error) {
|
||||
//console.log(error);
|
||||
toast.error("There was an error registering");
|
||||
setRegistering(false);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="ml-[25%]">
|
||||
<LstCard className="p-3 w-96">
|
||||
<CardHeader>
|
||||
<div>
|
||||
<p className="text-2xl">Login to register</p>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<hr className="rounded"></hr>
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Separator />
|
||||
<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" className="mb-2">
|
||||
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>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Separator />
|
||||
<form.Field
|
||||
name="email"
|
||||
validators={{
|
||||
// We can choose between form-wide and field-specific validators
|
||||
onChange: ({ value }) =>
|
||||
value.length > 3
|
||||
? undefined
|
||||
: "You must enter a valid email",
|
||||
}}
|
||||
children={(field) => {
|
||||
return (
|
||||
<div className="m-2 min-w-48 max-w-96 p-2">
|
||||
<Label htmlFor="email" className="mb-2">
|
||||
Alpla Email
|
||||
</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>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Separator className="m-2" />
|
||||
<p>
|
||||
Your password Should be your windows password, as this
|
||||
is how you will interact with alplaprod
|
||||
</p>
|
||||
<form.Field
|
||||
name="password"
|
||||
// We can choose between form-wide and field-specific validators
|
||||
validators={{
|
||||
onChangeAsyncDebounceMs: 500,
|
||||
onChangeAsync: ({ value }) => {
|
||||
// if (
|
||||
// window.location.pathname.includes(
|
||||
// "/users"
|
||||
// ) &&
|
||||
// value.length === 0
|
||||
// ) {
|
||||
// return;
|
||||
// }
|
||||
if (value.length < 4) {
|
||||
return "Password must be at least 4 characters long.";
|
||||
}
|
||||
|
||||
if (!/[A-Z]/.test(value)) {
|
||||
return "Password must contain at least one uppercase letter.";
|
||||
}
|
||||
|
||||
if (!/[a-z]/.test(value)) {
|
||||
return "Password must contain at least one lower case letter.";
|
||||
}
|
||||
|
||||
if (!/[0-9]/.test(value)) {
|
||||
return "Password must contain at least one number.";
|
||||
}
|
||||
|
||||
if (
|
||||
!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(
|
||||
value
|
||||
)
|
||||
) {
|
||||
return "Password must contain at least one special character.";
|
||||
}
|
||||
},
|
||||
}}
|
||||
children={(field) => {
|
||||
return (
|
||||
<div className="m-2 min-w-48 max-w-96 p-2">
|
||||
<Label htmlFor="password1" className="mb-2">
|
||||
Password
|
||||
</Label>
|
||||
<Input
|
||||
name={field.name}
|
||||
value={field.state.value}
|
||||
onBlur={field.handleBlur}
|
||||
type="password"
|
||||
onChange={(e) =>
|
||||
field.handleChange(e.target.value)
|
||||
}
|
||||
/>
|
||||
{field.state.meta.errors.length ? (
|
||||
<em>
|
||||
{field.state.meta.errors.join(",")}
|
||||
</em>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<div className="mt-4 ml-4 flex justify-end">
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={form.handleSubmit}
|
||||
disabled={registering}
|
||||
>
|
||||
Register
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function MaterialCheck() {
|
||||
return <div>MaterialCheck</div>;
|
||||
}
|
||||
211
frontend/src/components/eom/materialsData/MaterialData.tsx
Normal file
211
frontend/src/components/eom/materialsData/MaterialData.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
CollapsibleTrigger,
|
||||
} from "../../ui/collapsible";
|
||||
import { useSubModuleStore } from "@/lib/store/useSubModuleStore";
|
||||
import { useSettingStore } from "@/lib/store/useSettings";
|
||||
|
||||
const iconMap: any = {
|
||||
ShieldCheck: ShieldCheck,
|
||||
@@ -41,6 +42,9 @@ const iconMap: any = {
|
||||
|
||||
export function AdminSideBar() {
|
||||
const { subModules } = useSubModuleStore();
|
||||
const { settings } = useSettingStore();
|
||||
|
||||
const plantToken = settings.filter((n) => n.name === "plantToken");
|
||||
|
||||
const items = subModules.filter((m) => m.moduleName === "admin");
|
||||
return (
|
||||
@@ -87,7 +91,10 @@ export function AdminSideBar() {
|
||||
>
|
||||
<a
|
||||
href={
|
||||
i.link
|
||||
i.name ===
|
||||
"Swagger"
|
||||
? `https://${plantToken[0].value}prod.alpla.net/application/swagger/index.html`
|
||||
: i.link
|
||||
}
|
||||
target={
|
||||
i.newWindow
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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>
|
||||
))}
|
||||
|
||||
165
frontend/src/components/logistics/barcodeGenerator/BGPage.tsx
Normal file
165
frontend/src/components/logistics/barcodeGenerator/BGPage.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
65
frontend/src/components/logistics/dm/DMButtons.tsx
Normal file
65
frontend/src/components/logistics/dm/DMButtons.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import ForecastImport from "./ForecastImport";
|
||||
import OrderImport from "./OrderImport";
|
||||
import { useSettingStore } from "@/lib/store/useSettings";
|
||||
|
||||
export default function DMButtons() {
|
||||
const { settings } = useSettingStore();
|
||||
const testServers = ["test1", "test2", "test3"];
|
||||
const plantToken = settings.filter((n) => n.name === "plantToken");
|
||||
//console.log(plantToken);
|
||||
return (
|
||||
<div className="flex flex-row-reverse gap-1">
|
||||
<OrderImport fileType={"macro"} name={"Macro Import"} />
|
||||
{/* dev and testserver sees all */}
|
||||
{testServers.includes(plantToken[0]?.value) && (
|
||||
<div className="flex flex-row gap-2">
|
||||
<OrderImport
|
||||
fileType={"abbott"}
|
||||
name={"Abbott truck list"}
|
||||
/>
|
||||
<OrderImport
|
||||
fileType={"energizer"}
|
||||
name={"Energizer Truck List"}
|
||||
/>
|
||||
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
|
||||
<ForecastImport fileType={"pg"} name={"P&G"} />
|
||||
</div>
|
||||
)}
|
||||
{plantToken[0]?.value === "usday1" && (
|
||||
<div className="flex flex-row gap-2">
|
||||
<OrderImport
|
||||
fileType={"abbott"}
|
||||
name={"Abbott truck list"}
|
||||
/>
|
||||
<OrderImport
|
||||
fileType={"energizer"}
|
||||
name={"Energizer Truck List"}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{plantToken[0]?.value === "usflo1" && (
|
||||
<div className="flex flex-row gap-2">
|
||||
<ForecastImport fileType={"loreal"} name={"VMI Import"} />
|
||||
</div>
|
||||
)}
|
||||
{plantToken[0]?.value === "usstp1" && (
|
||||
<div className="flex flex-row gap-2"></div>
|
||||
)}
|
||||
{plantToken[0]?.value === "usiow1" && (
|
||||
<div className="flex flex-row gap-2">
|
||||
<ForecastImport fileType={"pg"} name={"P&G"} />
|
||||
</div>
|
||||
)}
|
||||
{plantToken[0]?.value === "usiow2" && (
|
||||
<div className="flex flex-row gap-2">
|
||||
<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>
|
||||
);
|
||||
}
|
||||
69
frontend/src/components/logistics/dm/ForecastImport.tsx
Normal file
69
frontend/src/components/logistics/dm/ForecastImport.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import axios from "axios";
|
||||
import { useRef, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export default function ForecastImport(props: any) {
|
||||
const fileInputRef: any = useRef(null);
|
||||
const [posting, setPosting] = useState(false);
|
||||
const token = localStorage.getItem("auth_token");
|
||||
//const [fileType, setFileType] = useState("");
|
||||
const importOrders = async (e: any) => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) {
|
||||
toast.error("Missing file please try again");
|
||||
setPosting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// create the form data with the correct fileType
|
||||
const formData = new FormData();
|
||||
formData.append("postForecast", e.target.files[0]);
|
||||
formData.append("fileType", props.fileType); // extra field
|
||||
// console.log(formData);
|
||||
toast.success("Import started.");
|
||||
try {
|
||||
const response = await axios.post(
|
||||
"/api/logistics/postforecastin",
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
//console.log("Upload successful:", response.data);
|
||||
toast.success(response?.data?.message);
|
||||
fileInputRef.current.value = null;
|
||||
setPosting(false);
|
||||
// toast.success(
|
||||
// "File Uploaded, please validate processing in alplaprod 2.0"
|
||||
// );
|
||||
setPosting(false);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toast.error("Upload failed");
|
||||
}
|
||||
setPosting(false);
|
||||
};
|
||||
|
||||
const handleButtonClick = () => {
|
||||
setPosting(true);
|
||||
fileInputRef.current.click();
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={handleButtonClick} disabled={posting}>
|
||||
{props.name}
|
||||
</Button>
|
||||
<input
|
||||
type="file"
|
||||
accept=".xlsx, .xls, .xlsm"
|
||||
ref={fileInputRef}
|
||||
style={{ display: "none" }}
|
||||
onChange={importOrders}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
64
frontend/src/components/logistics/dm/OrderImport.tsx
Normal file
64
frontend/src/components/logistics/dm/OrderImport.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import axios from "axios";
|
||||
import { useRef, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export default function OrderImport(props: any) {
|
||||
const fileInputRef: any = useRef(null);
|
||||
const [posting, setPosting] = useState(false);
|
||||
const token = localStorage.getItem("auth_token");
|
||||
//const [fileType, setFileType] = useState("");
|
||||
const importOrders = async (e: any) => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) {
|
||||
toast.error("Missing file please try again");
|
||||
setPosting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// create the form data with the correct fileType
|
||||
const formData = new FormData();
|
||||
formData.append("postOrders", e.target.files[0]);
|
||||
formData.append("fileType", props.fileType); // extra field
|
||||
|
||||
try {
|
||||
const response = await axios.post(
|
||||
"/api/logistics/postbulkorders",
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
//console.log("Upload successful:", response.data);
|
||||
toast.success(response?.data?.message);
|
||||
fileInputRef.current.value = null;
|
||||
setPosting(false);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toast.error("Upload failed");
|
||||
}
|
||||
setPosting(false);
|
||||
};
|
||||
|
||||
const handleButtonClick = () => {
|
||||
setPosting(true);
|
||||
fileInputRef.current.click();
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={handleButtonClick} disabled={posting}>
|
||||
{props.name}
|
||||
</Button>
|
||||
<input
|
||||
type="file"
|
||||
accept=".xlsx, .xls, .xlsm"
|
||||
ref={fileInputRef}
|
||||
style={{ display: "none" }}
|
||||
onChange={importOrders}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import axios from "axios";
|
||||
import { format } from "date-fns";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export default function StandardForecastTemplate() {
|
||||
const [template, setTemplate] = useState(false);
|
||||
const getTemplate = async () => {
|
||||
setTemplate(true);
|
||||
try {
|
||||
const res = await axios.get(`/api/logistics/bulkforcasttemplate`, {
|
||||
responseType: "blob",
|
||||
});
|
||||
|
||||
const blob = new Blob([res.data], {
|
||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
});
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
link.download = `ForecastTemplate-${format(new Date(Date.now()), "M-d-yyyy")}.xlsx`; // You can make this dynamic
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
|
||||
// Clean up
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(link.href);
|
||||
toast.success(`Forecast template`);
|
||||
setTemplate(false);
|
||||
} catch (error) {
|
||||
setTemplate(false);
|
||||
toast.error("There was an error getting the template");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Button onClick={getTemplate} disabled={template}>
|
||||
Standard Forecast Template
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import axios from "axios";
|
||||
import { format } from "date-fns";
|
||||
import { useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export default function StandardOrderTemplate() {
|
||||
const [template, setTemplate] = useState(false);
|
||||
const getTemplate = async () => {
|
||||
setTemplate(true);
|
||||
try {
|
||||
const res = await axios.get(`/api/logistics/bulkorderstemplate`, {
|
||||
responseType: "blob",
|
||||
});
|
||||
|
||||
const blob = new Blob([res.data], {
|
||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
});
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
link.download = `BulkOrderTemplate-${format(new Date(Date.now()), "M-d-yyyy")}.xlsx`; // You can make this dynamic
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
|
||||
// Clean up
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(link.href);
|
||||
toast.success(`Bulk Order template`);
|
||||
setTemplate(false);
|
||||
} catch (error) {
|
||||
setTemplate(false);
|
||||
toast.error("There was an error getting the tempalte");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Button onClick={getTemplate} disabled={template}>
|
||||
Standard Order Template
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
152
frontend/src/components/logistics/dm/dmPage.tsx
Normal file
152
frontend/src/components/logistics/dm/dmPage.tsx
Normal file
@@ -0,0 +1,152 @@
|
||||
import { LstCard } from "@/components/extendedUI/LstCard";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import OrderImport from "./OrderImport";
|
||||
import StandardOrderTemplate from "./StandardOrderTemplate";
|
||||
import ForecastImport from "./ForecastImport";
|
||||
import StandardForecastTemplate from "./StandardForecastTemplate";
|
||||
|
||||
export default function DmPage() {
|
||||
return (
|
||||
<div className="flex flex-row gap-2">
|
||||
<LstCard className="w-1/2">
|
||||
<div className="w-96">
|
||||
<h4 className="text-center underline text-2xl">
|
||||
Simple instructions for creating/updating orders
|
||||
</h4>
|
||||
<div className="flex flex-row gap-3 m-1">
|
||||
<OrderImport
|
||||
fileType={"standard"}
|
||||
name={"Standard Order Import"}
|
||||
/>
|
||||
<StandardOrderTemplate />
|
||||
</div>
|
||||
<Separator />
|
||||
</div>
|
||||
|
||||
<ul className="list-disc mr-2">
|
||||
<li>
|
||||
Download the standard template if you have not yet done
|
||||
so, Above click Standard Order Template.
|
||||
</li>
|
||||
<li>
|
||||
Add in the orders like you see in the example below.
|
||||
</li>
|
||||
<li>
|
||||
When updating orders you are required to have the
|
||||
customerOrderNumber, customerLineNumber, and
|
||||
customerReleaseNumber. Quatity and dates can change.
|
||||
</li>
|
||||
<li>
|
||||
Once you have all the orders entered, click Standard
|
||||
Order Import
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Separator className="my-4" />
|
||||
<div className="m-5">
|
||||
<h4 className="text-center underline text-2xl">
|
||||
Some notes to consider
|
||||
</h4>
|
||||
|
||||
<ul className="list-disc mr-2">
|
||||
<li>
|
||||
No longer need to add in the invoice id, we take the
|
||||
default one.
|
||||
</li>
|
||||
<li>
|
||||
You can have as many customers you want in the file
|
||||
and in any order.
|
||||
</li>
|
||||
<li>
|
||||
Orders created Manually, can not be updated with
|
||||
this process.
|
||||
</li>
|
||||
<li>
|
||||
If you desire you can send up to 1000 orders at one
|
||||
time... or more....
|
||||
</li>
|
||||
<li>
|
||||
Customer mappings can be added, this means that you
|
||||
can upload your customer file and it will parse
|
||||
onces mapped, you need to request this.
|
||||
</li>
|
||||
<li>
|
||||
Custom imports will be at the top right under
|
||||
custom, here you will just upload the customer file
|
||||
once mapped.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Separator className="my-4" />
|
||||
<p className="text-center underline text-2xl">Example order</p>
|
||||
<div className="flex justify-center">
|
||||
<img
|
||||
src="/imgs/ordersInExample.png"
|
||||
alt="orders in example"
|
||||
className="w-[680px] h-[280px]"
|
||||
/>
|
||||
</div>
|
||||
</LstCard>
|
||||
<LstCard className="w-1/2">
|
||||
<div className="w-96">
|
||||
<h4 className="text-center underline text-2xl">
|
||||
Simple instructions for creating forecast
|
||||
</h4>
|
||||
<div className="flex flex-row gap-3 m-1">
|
||||
<ForecastImport
|
||||
fileType={"standard"}
|
||||
name={"Standard Forecast Import"}
|
||||
/>
|
||||
<StandardForecastTemplate />
|
||||
<Separator className="my-4" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-5">
|
||||
<ul className="list-disc mr-2">
|
||||
<li>
|
||||
Download the template if you have not yet done so.
|
||||
</li>
|
||||
<li>
|
||||
Add in the forecast like you see in the example
|
||||
below.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Once you have all the forecast enters click the
|
||||
upload button on the top right
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<Separator className="my-4" />
|
||||
<div className="m-5">
|
||||
<h4 className="text-center underline text-2xl">
|
||||
Some notes to consider.
|
||||
</h4>
|
||||
<ul className="list-disc mr-2">
|
||||
<li>You can only use one customer at a time.</li>
|
||||
|
||||
<li>
|
||||
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" />
|
||||
<p className="text-center underline text-2xl">
|
||||
Example forecast
|
||||
</p>
|
||||
<div className="flex justify-center">
|
||||
<img
|
||||
src="/imgs/exampleforecast.png"
|
||||
alt="orders in example"
|
||||
className="w-[480px] h-[280px]"
|
||||
/>
|
||||
</div>
|
||||
</LstCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
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 Bookin() {
|
||||
const [bookingIn, setBookingIn] = useState(false);
|
||||
const form = useForm({
|
||||
defaultValues: { runningNr: " " },
|
||||
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>Book in a pallet by running number</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>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<div className="flex mt-2 justify-end">
|
||||
<Button
|
||||
onClick={form.handleSubmit}
|
||||
disabled={bookingIn}
|
||||
>
|
||||
Book in
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</form>
|
||||
</LstCard>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user