Compare commits
9 Commits
e620397938
...
0ddf67d815
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ddf67d815 | |||
| 147d189a81 | |||
| e9ff8bb4cb | |||
| 78a5a4a398 | |||
| 66ae443fb8 | |||
| 8f22165951 | |||
| cc3657f66f | |||
| 6392441f1b | |||
| 5eac14062f |
72
CHANGELOG.md
72
CHANGELOG.md
@@ -1,5 +1,77 @@
|
|||||||
# All Changes to LST can be found below.
|
# All Changes to LST can be found below.
|
||||||
|
|
||||||
|
## [1.6.0](https://git.tuffraid.net/cowch/lst/compare/v1.5.0...v1.6.0) (2025-10-26)
|
||||||
|
|
||||||
|
|
||||||
|
### 📝 Testing Code
|
||||||
|
|
||||||
|
* **dock schedule fail:** failed attempt ad doing a dock schedule but leaving in here ([817a5c6](https://git.tuffraid.net/cowch/lst/commits/817a5c6876b338e4e0347eed94d0c2d9507e7ba3))
|
||||||
|
|
||||||
|
|
||||||
|
### 📈 Project changes
|
||||||
|
|
||||||
|
* **added biome linter in:** added in biom linter to assist ([2023c2f](https://git.tuffraid.net/cowch/lst/commits/2023c2fc35f8d57a6884d82b3710a03f3ccc57e7))
|
||||||
|
* **app:** config changes to bruno and incoming sqls ([f264c98](https://git.tuffraid.net/cowch/lst/commits/f264c98fbfccd4f1eb6dfdcb28b69903711a9e2b))
|
||||||
|
* **settings:** settings for biome ([dfff8fc](https://git.tuffraid.net/cowch/lst/commits/dfff8fc1667a5199a9f92bdbf7df1a1b19606b82))
|
||||||
|
|
||||||
|
|
||||||
|
### 📚 Documentation
|
||||||
|
|
||||||
|
* **api:** bruno endpoint saves ([705f29e](https://git.tuffraid.net/cowch/lst/commits/705f29e908b75e8ba8d09a9fc4a2b5745460babb))
|
||||||
|
* **bruno:** preprint in app added ([a2a8e0e](https://git.tuffraid.net/cowch/lst/commits/a2a8e0ef9f7086ba9d32bc4ec05a61e6904bfecc))
|
||||||
|
|
||||||
|
|
||||||
|
### 🛠️ Code Refactor
|
||||||
|
|
||||||
|
* **biome:** format changes ([dbe84d5](https://git.tuffraid.net/cowch/lst/commits/dbe84d5325291fb51f971426ec521c91eafa3537))
|
||||||
|
* **biome:** formats from biome ([27fa456](https://git.tuffraid.net/cowch/lst/commits/27fa45614e604a768c49dc4489fbf7a671364a7b))
|
||||||
|
* **biome:** more format changes ([255ceaa](https://git.tuffraid.net/cowch/lst/commits/255ceaab856e72435bbc3ebad37fb82c036f5208))
|
||||||
|
* **front end:** login fixes to account for the forced password change ([e99c409](https://git.tuffraid.net/cowch/lst/commits/e99c409cad049f781d4a52864f40264146a2bb49))
|
||||||
|
* **frontend:** tempt to stop the popup when redrected or coming to the page with no auth ([0fd777c](https://git.tuffraid.net/cowch/lst/commits/0fd777ccbdab2e8de8dcc02c134e01390bbc0d0a))
|
||||||
|
* **login:** added in a check for lastlogin and force reset password ([17e13d4](https://git.tuffraid.net/cowch/lst/commits/17e13d4604787d1473ae1e24ad4e9479087f6dce))
|
||||||
|
* **material checks:** added proper logging to capture it all for auditing later ([26b769f](https://git.tuffraid.net/cowch/lst/commits/26b769f4776df2833e3f27b02e5eedbc9f8693a6))
|
||||||
|
* **old app:** login migration to new app ([eb3fa4d](https://git.tuffraid.net/cowch/lst/commits/eb3fa4dd528427da49e2212bfa304ef9cdb06cc2))
|
||||||
|
* **plc connection zechetti:** added in more logging due to a weird issue with line 7 not sendin ([38edc62](https://git.tuffraid.net/cowch/lst/commits/38edc6214b353841a3414a66553446d4008ad54a))
|
||||||
|
* **printdelay:** added in a change to allow override the actualy time ([c59b6a1](https://git.tuffraid.net/cowch/lst/commits/c59b6a1ec27ecb8e5b6b08c8db7aee5bcb060801))
|
||||||
|
* **stats:** added in ram useage to the stats ([b9b0cd5](https://git.tuffraid.net/cowch/lst/commits/b9b0cd5c7010726532ef56ddab714308c8045b94))
|
||||||
|
* **wrapper:** changes to allow both controller and app to connect via wss:// ([da11270](https://git.tuffraid.net/cowch/lst/commits/da1127057cd766ec72316dee1ffcb11aed77904b))
|
||||||
|
|
||||||
|
|
||||||
|
### 🌟 Enhancements
|
||||||
|
|
||||||
|
* **admin:** users and roles added to the frontend to manage easier ([2142c06](https://git.tuffraid.net/cowch/lst/commits/2142c06ac3900aa70f1cf672b5a64102ed1c574f))
|
||||||
|
* **app:** order schdeuler ([94e1198](https://git.tuffraid.net/cowch/lst/commits/94e1198f6305751af7662a63e0ac21ac04f805d1))
|
||||||
|
* **frontend:** migrated old > new silo adjustments ([425f8f5](https://git.tuffraid.net/cowch/lst/commits/425f8f5f71d1dae1cf3a5d0307b3a2faeadb54b5))
|
||||||
|
* **labeling:** added printers and machine and other data for preprinting ([953af5e](https://git.tuffraid.net/cowch/lst/commits/953af5e0fea4cf0738a2bbfd3ee6ec46182b83dd))
|
||||||
|
* **labels:** added listener for old app to push all labels to the new app ([af079b8](https://git.tuffraid.net/cowch/lst/commits/af079b83069560f0a0d6f19c396a8238fba25e94))
|
||||||
|
* **migration:** dashboard migrated over ([2206a4d](https://git.tuffraid.net/cowch/lst/commits/2206a4d4baefdd770c83a03d68c9f5ac8f55a4c3))
|
||||||
|
* **migration:** dm moved ([ac9670d](https://git.tuffraid.net/cowch/lst/commits/ac9670d55340a3cc8e45d13ac1c09a056d06d1dd))
|
||||||
|
* **migration:** moved barcode generator ([fd9d774](https://git.tuffraid.net/cowch/lst/commits/fd9d774772aabb63fd69fe70302444fd2088d960))
|
||||||
|
* **migration:** moved changed log and properly added in the link to it ([0fe0a8f](https://git.tuffraid.net/cowch/lst/commits/0fe0a8f56a9833de1de4f8ba49f1d06b31e42ee8))
|
||||||
|
* **migration:** moved helper commands ([39c31aa](https://git.tuffraid.net/cowch/lst/commits/39c31aa1ec61231737cc4e7c3c33331ab562a808))
|
||||||
|
* **migration:** moved material helper over ([1da7b14](https://git.tuffraid.net/cowch/lst/commits/1da7b145a942dd64891511a8a63160748800de87))
|
||||||
|
* **migration:** moved ocp, ocme, wrapper stuff ([4ca20a0](https://git.tuffraid.net/cowch/lst/commits/4ca20a085efcb795bc312abff649a53132deac05))
|
||||||
|
* **migration:** moved rfid page ([f90a975](https://git.tuffraid.net/cowch/lst/commits/f90a975a5020a262109552019a13ead71271396c))
|
||||||
|
* **preprint:** added in preprint function to help with operations planning constraints ([282eab0](https://git.tuffraid.net/cowch/lst/commits/282eab01e15f81bcc407f45f1f3ffff056e0f27a))
|
||||||
|
* **settings:** added in settings ([a09ad87](https://git.tuffraid.net/cowch/lst/commits/a09ad8773c77b7b23ce98b3b3f6ce6122842f3ff))
|
||||||
|
* **v1 logger:** added in a logger to monitor the old app ([1d79195](https://git.tuffraid.net/cowch/lst/commits/1d79195d89cc31192c9998ef2b2f8ea501aff41e))
|
||||||
|
|
||||||
|
|
||||||
|
### 🐛 Bug fixes
|
||||||
|
|
||||||
|
* **admin:** corrections to sending over to test server for updates ([7964cda](https://git.tuffraid.net/cowch/lst/commits/7964cda197e42f2eadea3e636c2d910cb34c97bc))
|
||||||
|
* **barcodes:** moved to correct folder ([6a84da4](https://git.tuffraid.net/cowch/lst/commits/6a84da411770986f6f4c2088ebae169c688b28c1))
|
||||||
|
* **controller:** changed to actaully update both main and old app ([0d1f963](https://git.tuffraid.net/cowch/lst/commits/0d1f96333b11e6a2323e25552c10cc85d3c425af))
|
||||||
|
* **controller:** fix for updating iowa2 server ([358c41d](https://git.tuffraid.net/cowch/lst/commits/358c41deb41d418c5b1c6040269f2ed74e1782ff))
|
||||||
|
* **dmbuttons:** missed the uncomment here ([e620397](https://git.tuffraid.net/cowch/lst/commits/e62039793870a4d4b1f67adf256a9db2f6027e37))
|
||||||
|
* **loginform:** bug where the reset errror was not properly coming over ([414a21a](https://git.tuffraid.net/cowch/lst/commits/414a21a28719b50f61cc41056efc9b599491e048))
|
||||||
|
* **loginform:** error with password reset ([eae9436](https://git.tuffraid.net/cowch/lst/commits/eae9436f6d3aa8424043a426d5bbcc764967b3b6))
|
||||||
|
* **misc:** changes to several files for formatting ([b102112](https://git.tuffraid.net/cowch/lst/commits/b102112228bbf58b12bbca19cdf99483517b784d))
|
||||||
|
* **ocme:** corrected the urls for ocme ([f078cd6](https://git.tuffraid.net/cowch/lst/commits/f078cd6ceb9039e1f6e9b31f3e33ad446e65dd87))
|
||||||
|
* **old app:** correction for dev redirect if on localhost to be proper now ([70a2ff5](https://git.tuffraid.net/cowch/lst/commits/70a2ff5e845d9a8c460f4810f8de741fae32ad96))
|
||||||
|
* **printers:** missing logs for errors ([43abbd5](https://git.tuffraid.net/cowch/lst/commits/43abbd53f421988a13cbf8974a49d5ae5cbba1b9))
|
||||||
|
* **silos:** added only active machines, and ordered by location in asending ([d46ef92](https://git.tuffraid.net/cowch/lst/commits/d46ef922f3a6ddc36d5ddfcd94d424745f473a16))
|
||||||
|
|
||||||
## [1.5.0](https://git.tuffraid.net/cowch/lst/compare/v1.4.0...v1.5.0) (2025-10-07)
|
## [1.5.0](https://git.tuffraid.net/cowch/lst/compare/v1.4.0...v1.5.0) (2025-10-07)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
meta {
|
||||||
|
name: CreateSilo Adjustment
|
||||||
|
type: http
|
||||||
|
seq: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{url}}/lst/old/api/logistics/createsiloadjustment
|
||||||
|
body: json
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"warehouseId": 51,
|
||||||
|
"quantity": 60575,
|
||||||
|
"laneId": 31717,
|
||||||
|
"username":"matthes01"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
8
LogisticsSupportTool_API_DOCS/LstV2/ocp/folder.bru
Normal file
8
LogisticsSupportTool_API_DOCS/LstV2/ocp/folder.bru
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
meta {
|
||||||
|
name: ocp
|
||||||
|
seq: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
auth {
|
||||||
|
mode: inherit
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
meta {
|
||||||
|
name: Update Printers
|
||||||
|
type: http
|
||||||
|
seq: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get {
|
||||||
|
url: {{url}}/lst/old/api/ocp/updateprinters
|
||||||
|
body: none
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
meta {
|
||||||
|
name: printers
|
||||||
|
seq: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
auth {
|
||||||
|
mode: inherit
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
meta {
|
||||||
|
name: Change user password
|
||||||
|
type: http
|
||||||
|
seq: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
patch {
|
||||||
|
url: {{url}}/lst/api/admin/users/changePassword/:userId
|
||||||
|
body: json
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
params:path {
|
||||||
|
userId: 0hlO48C7Jw1J804FxrCnonKjQ2zh48R6
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"password":"nova0511"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
25
LogisticsSupportTool_API_DOCS/app/admin/User/Create user.bru
Normal file
25
LogisticsSupportTool_API_DOCS/app/admin/User/Create user.bru
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
meta {
|
||||||
|
name: Create user
|
||||||
|
type: http
|
||||||
|
seq: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
url: {{url}}/lst/api/admin/users
|
||||||
|
body: none
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"username":"matthes01",
|
||||||
|
"name":"blake",
|
||||||
|
"email":"blake.matthes@alpla.com",
|
||||||
|
"password":"nova0511"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
26
LogisticsSupportTool_API_DOCS/app/admin/User/Delete User.bru
Normal file
26
LogisticsSupportTool_API_DOCS/app/admin/User/Delete User.bru
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
meta {
|
||||||
|
name: Delete User
|
||||||
|
type: http
|
||||||
|
seq: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
delete {
|
||||||
|
url: {{url}}/lst/api/admin/users/delete/:userId
|
||||||
|
body: json
|
||||||
|
auth: inherit
|
||||||
|
}
|
||||||
|
|
||||||
|
params:path {
|
||||||
|
userId: 0hlO48C7Jw1J804FxrCnonKjQ2zh48R6
|
||||||
|
}
|
||||||
|
|
||||||
|
body:json {
|
||||||
|
{
|
||||||
|
"password":"nova0511"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
settings {
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
}
|
||||||
@@ -21,4 +21,5 @@ body:json {
|
|||||||
|
|
||||||
settings {
|
settings {
|
||||||
encodeUrl: true
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ meta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
patch {
|
patch {
|
||||||
url: {{url}}/lst/api/admin/:userID/grant
|
url: {{url}}/lst/api/admin/users/:userID/grant
|
||||||
body: json
|
body: json
|
||||||
auth: inherit
|
auth: inherit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ meta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
patch {
|
patch {
|
||||||
url: {{url}}/lst/api/admin/:userID/revoke
|
url: {{url}}/lst/api/admin/users/:userID/revoke
|
||||||
body: json
|
body: json
|
||||||
auth: inherit
|
auth: inherit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
vars {
|
vars {
|
||||||
url: https://usmcd1vms036.alpla.net
|
url: http://localhost:4200
|
||||||
session_cookie:
|
session_cookie:
|
||||||
urlv2: http://localhost:3000
|
urlv2: http://localhost:3000
|
||||||
jwtV2:
|
jwtV2:
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const main = async () => {
|
|||||||
app.use(
|
app.use(
|
||||||
basePath + "/old",
|
basePath + "/old",
|
||||||
createProxyMiddleware({
|
createProxyMiddleware({
|
||||||
target: `http://localhost:3000`,
|
target: `http://localhost:${process.env.V1PORT || "3000"}`, // change this to pull from the correct port
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: (path, req) => {
|
pathRewrite: (path, req) => {
|
||||||
// Remove the basePath + '/old' prefix from the path dynamically
|
// Remove the basePath + '/old' prefix from the path dynamically
|
||||||
@@ -113,7 +113,9 @@ const main = async () => {
|
|||||||
"http://localhost:4173",
|
"http://localhost:4173",
|
||||||
"http://localhost:4200",
|
"http://localhost:4200",
|
||||||
"http://localhost:3000",
|
"http://localhost:3000",
|
||||||
|
"http://localhost:3001",
|
||||||
"http://localhost:4000",
|
"http://localhost:4000",
|
||||||
|
"http://localhost:4001",
|
||||||
env.BETTER_AUTH_URL, // prod
|
env.BETTER_AUTH_URL, // prod
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
42
app/src/internal/admin/controller/users/newUser.ts
Normal file
42
app/src/internal/admin/controller/users/newUser.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import type { User } from "better-auth";
|
||||||
|
import { DrizzleQueryError } from "drizzle-orm";
|
||||||
|
import { auth } from "../../../../pkg/auth/auth.js";
|
||||||
|
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
||||||
|
|
||||||
|
export type NewUser = {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
username: string;
|
||||||
|
statusCode: number;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createNewUser = async (userData: NewUser) => {
|
||||||
|
const { data, error } = await tryCatch(
|
||||||
|
auth.api.createUser({
|
||||||
|
body: {
|
||||||
|
email: userData.email, // required
|
||||||
|
password: userData.password, // required
|
||||||
|
name: userData.username, // required
|
||||||
|
role: "user",
|
||||||
|
data: { username: userData.username },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
if (error instanceof DrizzleQueryError) {
|
||||||
|
// @ts-ignore
|
||||||
|
if (error?.cause.message.includes("unique constraint")) {
|
||||||
|
return {
|
||||||
|
statusCode: 400,
|
||||||
|
message: `${userData.username} already exists`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
import type { Express, Request, Response } from "express";
|
import type { Express, Request, Response } from "express";
|
||||||
import { requireAuth } from "../../pkg/middleware/authMiddleware.js";
|
import { requireAuth } from "../../pkg/middleware/authMiddleware.js";
|
||||||
import { mainServerSync } from "./controller/servers/matchServers.js";
|
import { mainServerSync } from "./controller/servers/matchServers.js";
|
||||||
//admin routes
|
|
||||||
import users from "./routes/getUserRoles.js";
|
|
||||||
import grantRoles from "./routes/grantRole.js";
|
|
||||||
import revokeRoles from "./routes/revokeRole.js";
|
|
||||||
import servers from "./routes/servers/serverRoutes.js";
|
import servers from "./routes/servers/serverRoutes.js";
|
||||||
|
//admin routes
|
||||||
|
import users from "./routes/users/userRoutes.js";
|
||||||
|
|
||||||
export const setupAdminRoutes = (app: Express, basePath: string) => {
|
export const setupAdminRoutes = (app: Express, basePath: string) => {
|
||||||
app.use(
|
app.use(
|
||||||
@@ -15,22 +13,10 @@ export const setupAdminRoutes = (app: Express, basePath: string) => {
|
|||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
basePath + "/api/admin/users",
|
basePath + "/api/admin/users",
|
||||||
requireAuth("user", ["systemAdmin"]), // will pass bc system admin but this is just telling us we need this
|
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
||||||
users,
|
users,
|
||||||
);
|
);
|
||||||
|
|
||||||
app.use(
|
|
||||||
basePath + "/api/admin",
|
|
||||||
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
|
||||||
grantRoles,
|
|
||||||
);
|
|
||||||
|
|
||||||
app.use(
|
|
||||||
basePath + "/api/admin",
|
|
||||||
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
|
||||||
revokeRoles,
|
|
||||||
);
|
|
||||||
|
|
||||||
// run the sync only on startup
|
// run the sync only on startup
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
mainServerSync();
|
mainServerSync();
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
import { Router } from "express";
|
|
||||||
import type { Request, Response } from "express";
|
|
||||||
import { tryCatch } from "../../../pkg/utils/tryCatch.js";
|
|
||||||
import { db } from "../../../pkg/db/db.js";
|
|
||||||
import { user } from "../../../pkg/db/schema/auth-schema.js";
|
|
||||||
import { userRoles } from "../../../pkg/db/schema/user_roles.js";
|
|
||||||
|
|
||||||
const router = Router();
|
|
||||||
|
|
||||||
router.post("/", async (req: Request, res: Response) => {
|
|
||||||
// should get all users
|
|
||||||
const { data: users, error: userError } = await tryCatch(
|
|
||||||
db.select().from(user)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (userError) {
|
|
||||||
return res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: "Failed to get users",
|
|
||||||
error: userError,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// should get all roles
|
|
||||||
|
|
||||||
const { data: userRole, error: userRoleError } = await tryCatch(
|
|
||||||
db.select().from(userRoles)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (userRoleError) {
|
|
||||||
return res.status(500).json({
|
|
||||||
success: false,
|
|
||||||
message: "Failed to get userRoless",
|
|
||||||
error: userRoleError,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the roles and return
|
|
||||||
|
|
||||||
const usersWithRoles = users.map((user) => {
|
|
||||||
const roles = userRole
|
|
||||||
.filter((ur) => ur.userId === user.id)
|
|
||||||
.map((ur) => ({ module: ur.module, role: ur.role }));
|
|
||||||
|
|
||||||
return { ...user, roles };
|
|
||||||
});
|
|
||||||
|
|
||||||
return res
|
|
||||||
.status(200)
|
|
||||||
.json({ success: true, message: "User data", data: usersWithRoles });
|
|
||||||
});
|
|
||||||
|
|
||||||
export default router;
|
|
||||||
25
app/src/internal/admin/routes/users/changeUserPassword.ts
Normal file
25
app/src/internal/admin/routes/users/changeUserPassword.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { type Request, type Response, Router } from "express";
|
||||||
|
import { auth } from "../../../../pkg/auth/auth.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.patch("/:userId", async (req: Request, res: Response) => {
|
||||||
|
const userId = req.params.userId;
|
||||||
|
const cookieHeader = req.headers.cookie ?? "";
|
||||||
|
const authorization = req.headers.authorization ?? "";
|
||||||
|
|
||||||
|
const data = await auth.api.setUserPassword({
|
||||||
|
body: {
|
||||||
|
newPassword: req.body.password, // required
|
||||||
|
userId: userId, // required
|
||||||
|
},
|
||||||
|
// This endpoint requires session cookies.
|
||||||
|
headers: {
|
||||||
|
cookie: cookieHeader,
|
||||||
|
authorization,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ message: "Password was just changed." });
|
||||||
|
});
|
||||||
|
export default router;
|
||||||
20
app/src/internal/admin/routes/users/createUser.ts
Normal file
20
app/src/internal/admin/routes/users/createUser.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { type Request, type Response, Router } from "express";
|
||||||
|
import { createNewUser, type NewUser } from "../../controller/users/newUser.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.post("/", async (req: Request, res: Response) => {
|
||||||
|
const body = req.body;
|
||||||
|
const user = (await createNewUser(body)) as NewUser;
|
||||||
|
|
||||||
|
if (user?.statusCode === 400) {
|
||||||
|
return res.status(user?.statusCode).json({
|
||||||
|
message: user?.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json({ message: `${body.username}, was just created` });
|
||||||
|
});
|
||||||
|
export default router;
|
||||||
24
app/src/internal/admin/routes/users/deleteUser.ts
Normal file
24
app/src/internal/admin/routes/users/deleteUser.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { type Request, type Response, Router } from "express";
|
||||||
|
import { auth } from "../../../../pkg/auth/auth.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.delete("/:userId", async (req: Request, res: Response) => {
|
||||||
|
const userId = req.params.userId;
|
||||||
|
const cookieHeader = req.headers.cookie ?? "";
|
||||||
|
const authorization = req.headers.authorization ?? "";
|
||||||
|
|
||||||
|
const data = await auth.api.removeUser({
|
||||||
|
body: {
|
||||||
|
userId: userId, // required
|
||||||
|
},
|
||||||
|
// This endpoint requires session cookies.
|
||||||
|
headers: {
|
||||||
|
cookie: cookieHeader,
|
||||||
|
authorization,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ message: "User was just deleted." });
|
||||||
|
});
|
||||||
|
export default router;
|
||||||
25
app/src/internal/admin/routes/users/getActiveSessions.ts
Normal file
25
app/src/internal/admin/routes/users/getActiveSessions.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { type Request, type Response, Router } from "express";
|
||||||
|
import { auth } from "../../../../pkg/auth/auth.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.patch("/:userId", async (req: Request, res: Response) => {
|
||||||
|
const userId = req.params.userId;
|
||||||
|
const cookieHeader = req.headers.cookie ?? "";
|
||||||
|
const authorization = req.headers.authorization ?? "";
|
||||||
|
|
||||||
|
const data = await auth.api.setUserPassword({
|
||||||
|
body: {
|
||||||
|
newPassword: req.body.password, // required
|
||||||
|
userId: userId, // required
|
||||||
|
},
|
||||||
|
// This endpoint requires session cookies.
|
||||||
|
headers: {
|
||||||
|
cookie: cookieHeader,
|
||||||
|
authorization,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.status(200).json({ message: "Password was just changed." });
|
||||||
|
});
|
||||||
|
export default router;
|
||||||
52
app/src/internal/admin/routes/users/getUserRoles.ts
Normal file
52
app/src/internal/admin/routes/users/getUserRoles.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import type { Request, Response } from "express";
|
||||||
|
import { Router } from "express";
|
||||||
|
import { db } from "../../../../pkg/db/db.js";
|
||||||
|
import { user } from "../../../../pkg/db/schema/auth-schema.js";
|
||||||
|
import { userRoles } from "../../../../pkg/db/schema/user_roles.js";
|
||||||
|
import { tryCatch } from "../../../../pkg/utils/tryCatch.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.post("/", async (req: Request, res: Response) => {
|
||||||
|
// should get all users
|
||||||
|
const { data: users, error: userError } = await tryCatch(
|
||||||
|
db.select().from(user),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (userError) {
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to get users",
|
||||||
|
error: userError,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// should get all roles
|
||||||
|
|
||||||
|
const { data: userRole, error: userRoleError } = await tryCatch(
|
||||||
|
db.select().from(userRoles),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (userRoleError) {
|
||||||
|
return res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to get userRoless",
|
||||||
|
error: userRoleError,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the roles and return
|
||||||
|
|
||||||
|
const usersWithRoles = users.map((user) => {
|
||||||
|
const roles = userRole
|
||||||
|
.filter((ur) => ur.userId === user.id)
|
||||||
|
.map((ur) => ({ module: ur.module, role: ur.role }));
|
||||||
|
|
||||||
|
return { ...user, roles };
|
||||||
|
});
|
||||||
|
|
||||||
|
return res
|
||||||
|
.status(200)
|
||||||
|
.json({ success: true, message: "User data", data: usersWithRoles });
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { db } from "../../../pkg/db/db.js";
|
import { db } from "../../../../pkg/db/db.js";
|
||||||
import { userRoles } from "../../../pkg/db/schema/user_roles.js";
|
import { userRoles } from "../../../../pkg/db/schema/user_roles.js";
|
||||||
import { createLogger } from "../../../pkg/logger/logger.js";
|
import { createLogger } from "../../../../pkg/logger/logger.js";
|
||||||
import { tryCatch } from "../../../pkg/utils/tryCatch.js";
|
|
||||||
|
|
||||||
const roleSchema = z.object({
|
const roleSchema = z.object({
|
||||||
module: z.enum([
|
module: z.enum([
|
||||||
@@ -2,10 +2,9 @@ import { and, eq } from "drizzle-orm";
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Router } from "express";
|
import { Router } from "express";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { db } from "../../../pkg/db/db.js";
|
import { db } from "../../../../pkg/db/db.js";
|
||||||
import { userRoles } from "../../../pkg/db/schema/user_roles.js";
|
import { userRoles } from "../../../../pkg/db/schema/user_roles.js";
|
||||||
import { createLogger } from "../../../pkg/logger/logger.js";
|
import { createLogger } from "../../../../pkg/logger/logger.js";
|
||||||
import { tryCatch } from "../../../pkg/utils/tryCatch.js";
|
|
||||||
|
|
||||||
const roleSchema = z.object({
|
const roleSchema = z.object({
|
||||||
module: z.enum([
|
module: z.enum([
|
||||||
51
app/src/internal/admin/routes/users/userRoutes.ts
Normal file
51
app/src/internal/admin/routes/users/userRoutes.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { fromNodeHeaders } from "better-auth/node";
|
||||||
|
import type { Request, Response } from "express";
|
||||||
|
import { Router } from "express";
|
||||||
|
import { auth } from "../../../../pkg/auth/auth.js";
|
||||||
|
import { requireAuth } from "../../../../pkg/middleware/authMiddleware.js";
|
||||||
|
import changePassword from "./changeUserPassword.js";
|
||||||
|
import createUser from "./createUser.js";
|
||||||
|
import deleteUser from "./deleteUser.js";
|
||||||
|
import users from "./getUserRoles.js";
|
||||||
|
import grantRoles from "./grantRole.js";
|
||||||
|
import revokeRoles from "./revokeRole.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.use(
|
||||||
|
"/",
|
||||||
|
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
||||||
|
grantRoles,
|
||||||
|
);
|
||||||
|
|
||||||
|
router.use(
|
||||||
|
"/new",
|
||||||
|
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
||||||
|
createUser,
|
||||||
|
);
|
||||||
|
|
||||||
|
router.use(
|
||||||
|
"/",
|
||||||
|
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
||||||
|
revokeRoles,
|
||||||
|
);
|
||||||
|
|
||||||
|
router.use(
|
||||||
|
"/",
|
||||||
|
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
||||||
|
users,
|
||||||
|
);
|
||||||
|
|
||||||
|
router.use(
|
||||||
|
"/changePassword",
|
||||||
|
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
||||||
|
changePassword,
|
||||||
|
);
|
||||||
|
|
||||||
|
router.use(
|
||||||
|
"/delete",
|
||||||
|
requireAuth("user", ["systemAdmin", "admin"]), // will pass bc system admin but this is just telling us we need this
|
||||||
|
deleteUser,
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -1,89 +1,93 @@
|
|||||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
|
||||||
import { db } from "../db/db.js";
|
|
||||||
import { username, admin, apiKey, jwt } from "better-auth/plugins";
|
|
||||||
import { betterAuth } from "better-auth";
|
import { betterAuth } from "better-auth";
|
||||||
import * as rawSchema from "../db/schema/auth-schema.js";
|
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||||
|
import { admin, apiKey, jwt, username } from "better-auth/plugins";
|
||||||
import type { User } from "better-auth/types";
|
import type { User } from "better-auth/types";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
|
import { db } from "../db/db.js";
|
||||||
|
import * as rawSchema from "../db/schema/auth-schema.js";
|
||||||
import { sendEmail } from "../utils/mail/sendMail.js";
|
import { sendEmail } from "../utils/mail/sendMail.js";
|
||||||
|
|
||||||
export const schema = {
|
export const schema = {
|
||||||
user: rawSchema.user,
|
user: rawSchema.user,
|
||||||
session: rawSchema.session,
|
session: rawSchema.session,
|
||||||
account: rawSchema.account,
|
account: rawSchema.account,
|
||||||
verification: rawSchema.verification,
|
verification: rawSchema.verification,
|
||||||
jwks: rawSchema.jwks,
|
jwks: rawSchema.jwks,
|
||||||
apiKey: rawSchema.apikey, // 🔑 rename to apiKey
|
apiKey: rawSchema.apikey, // 🔑 rename to apiKey
|
||||||
};
|
};
|
||||||
const RESET_EXPIRY_SECONDS = 3600; // 1 hour
|
const RESET_EXPIRY_SECONDS = 3600; // 1 hour
|
||||||
|
|
||||||
export const auth = betterAuth({
|
export const auth = betterAuth({
|
||||||
database: drizzleAdapter(db, {
|
database: drizzleAdapter(db, {
|
||||||
provider: "pg",
|
provider: "pg",
|
||||||
schema,
|
schema,
|
||||||
}),
|
}),
|
||||||
trustedOrigins: [
|
trustedOrigins: [
|
||||||
"*.alpla.net",
|
"*.alpla.net",
|
||||||
"http://localhost:5173",
|
"http://localhost:5173",
|
||||||
"http://localhost:5500",
|
"http://localhost:5500",
|
||||||
"http://localhost:4200",
|
"http://localhost:4200",
|
||||||
"http://localhost:4000",
|
"http://localhost:4000",
|
||||||
],
|
],
|
||||||
appName: "lst",
|
appName: "lst",
|
||||||
emailAndPassword: {
|
emailAndPassword: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
minPasswordLength: 8, // optional config
|
minPasswordLength: 8, // optional config
|
||||||
resetPasswordTokenExpirySeconds: RESET_EXPIRY_SECONDS, // time in seconds
|
resetPasswordTokenExpirySeconds: RESET_EXPIRY_SECONDS, // time in seconds
|
||||||
sendResetPassword: async ({ user, token }) => {
|
sendResetPassword: async ({ user, token }) => {
|
||||||
const frontendUrl = `${process.env.BETTER_AUTH_URL}/lst/app/user/resetpassword?token=${token}`;
|
const frontendUrl = `${process.env.BETTER_AUTH_URL}/lst/app/user/resetpassword?token=${token}`;
|
||||||
const expiryMinutes = Math.floor(RESET_EXPIRY_SECONDS / 60);
|
const expiryMinutes = Math.floor(RESET_EXPIRY_SECONDS / 60);
|
||||||
const expiryText =
|
const expiryText =
|
||||||
expiryMinutes >= 60
|
expiryMinutes >= 60
|
||||||
? `${expiryMinutes / 60} hour${
|
? `${expiryMinutes / 60} hour${expiryMinutes === 60 ? "" : "s"}`
|
||||||
expiryMinutes === 60 ? "" : "s"
|
: `${expiryMinutes} minutes`;
|
||||||
}`
|
const emailData = {
|
||||||
: `${expiryMinutes} minutes`;
|
email: user.email,
|
||||||
const emailData = {
|
subject: "LST- Forgot password request",
|
||||||
email: user.email,
|
template: "forgotPassword",
|
||||||
subject: "LST- Forgot password request",
|
context: {
|
||||||
template: "forgotPassword",
|
username: user.name,
|
||||||
context: {
|
email: user.email,
|
||||||
username: user.name,
|
url: frontendUrl,
|
||||||
email: user.email,
|
expiry: expiryText,
|
||||||
url: frontendUrl,
|
},
|
||||||
expiry: expiryText,
|
};
|
||||||
},
|
await sendEmail(emailData);
|
||||||
};
|
},
|
||||||
await sendEmail(emailData);
|
// onPasswordReset: async ({ user }, request) => {
|
||||||
},
|
// // your logic here
|
||||||
// onPasswordReset: async ({ user }, request) => {
|
// console.log(`Password for user ${user.email} has been reset.`);
|
||||||
// // your logic here
|
// },
|
||||||
// console.log(`Password for user ${user.email} has been reset.`);
|
},
|
||||||
// },
|
plugins: [
|
||||||
},
|
//jwt({ jwt: { expirationTime: "1h" } }),
|
||||||
plugins: [
|
apiKey(),
|
||||||
//jwt({ jwt: { expirationTime: "1h" } }),
|
admin(),
|
||||||
apiKey(),
|
username(),
|
||||||
admin(),
|
],
|
||||||
username(),
|
session: {
|
||||||
],
|
expiresIn: 60 * 60,
|
||||||
session: {
|
updateAge: 60 * 5,
|
||||||
expiresIn: 60 * 60,
|
freshAge: 60 * 2,
|
||||||
updateAge: 60 * 5,
|
cookieCache: {
|
||||||
freshAge: 60 * 2,
|
enabled: true,
|
||||||
cookieCache: {
|
maxAge: 5 * 60,
|
||||||
enabled: true,
|
},
|
||||||
maxAge: 5 * 60, // Cache duration in seconds
|
},
|
||||||
},
|
cookie: {
|
||||||
},
|
path: "/lst/app",
|
||||||
events: {
|
sameSite: "lax",
|
||||||
async onSignInSuccess({ user }: { user: User }) {
|
secure: false,
|
||||||
await db
|
httpOnly: true,
|
||||||
.update(schema.user)
|
},
|
||||||
.set({ lastLogin: new Date() })
|
events: {
|
||||||
.where(eq(schema.user.id, user.id));
|
async onSignInSuccess({ user }: { user: User }) {
|
||||||
},
|
await db
|
||||||
},
|
.update(schema.user)
|
||||||
|
.set({ lastLogin: new Date() })
|
||||||
|
.where(eq(schema.user.id, user.id));
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Auth = typeof auth;
|
export type Auth = typeof auth;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { redirect, useNavigate, useRouter } from "@tanstack/react-router";
|
import { redirect, useNavigate, useRouter } from "@tanstack/react-router";
|
||||||
import { createAuthClient } from "better-auth/client";
|
import { createAuthClient } from "better-auth/client";
|
||||||
import { usernameClient } from "better-auth/client/plugins";
|
import { adminClient, usernameClient } from "better-auth/client/plugins";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { api } from "./axiosAPI";
|
import { api } from "./axiosAPI";
|
||||||
@@ -112,7 +112,7 @@ export async function checkUserAccess({
|
|||||||
// ---- BETTER AUTH CLIENT ----
|
// ---- BETTER AUTH CLIENT ----
|
||||||
export const authClient = createAuthClient({
|
export const authClient = createAuthClient({
|
||||||
baseURL: `${window.location.origin}/lst/api/auth`,
|
baseURL: `${window.location.origin}/lst/api/auth`,
|
||||||
plugins: [usernameClient()],
|
plugins: [usernameClient(), adminClient()],
|
||||||
options: {
|
options: {
|
||||||
autoPopup: false,
|
autoPopup: false,
|
||||||
requireAuth: false,
|
requireAuth: false,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default function ExpandedRow({ row }: { row: any }) {
|
|||||||
// user,
|
// user,
|
||||||
// });
|
// });
|
||||||
try {
|
try {
|
||||||
const result = await api.patch(`/api/admin/${user.id}/grant`, {
|
const result = await api.patch(`/api/admin/users/${user.id}/grant`, {
|
||||||
module: module,
|
module: module,
|
||||||
role: role,
|
role: role,
|
||||||
});
|
});
|
||||||
@@ -83,7 +83,7 @@ export default function ExpandedRow({ row }: { row: any }) {
|
|||||||
|
|
||||||
const onDeleteRole = async (module: string) => {
|
const onDeleteRole = async (module: string) => {
|
||||||
try {
|
try {
|
||||||
const result = await api.patch(`/api/admin/${user.id}/revoke`, {
|
const result = await api.patch(`/api/admin/users/${user.id}/revoke`, {
|
||||||
module: module,
|
module: module,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
Sidebar,
|
Sidebar,
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
SidebarFooter,
|
SidebarFooter,
|
||||||
|
SidebarMenuButton,
|
||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
SidebarTrigger,
|
SidebarTrigger,
|
||||||
} from "../../../../../components/ui/sidebar";
|
} from "../../../../../components/ui/sidebar";
|
||||||
@@ -51,7 +52,9 @@ export function AppSidebar() {
|
|||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
<SidebarFooter>
|
<SidebarFooter>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<Link to={"/changelog"}>Changelog</Link>
|
<SidebarMenuButton asChild>
|
||||||
|
<Link to={"/changelog"}>Changelog</Link>
|
||||||
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
<SidebarTrigger />
|
<SidebarTrigger />
|
||||||
</SidebarFooter>
|
</SidebarFooter>
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export default function MaterialHelperPage() {
|
||||||
|
return <div>materialHelperPage</div>;
|
||||||
|
}
|
||||||
@@ -7,10 +7,11 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { CardContent, CardFooter, CardHeader } from "@/components/ui/card";
|
import { CardContent, CardFooter, CardHeader } from "@/components/ui/card";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
import { useAuth } from "@/lib/authClient";
|
||||||
import { LstCard } from "../../extendedUi/LstCard";
|
import { LstCard } from "../../extendedUi/LstCard";
|
||||||
|
|
||||||
export default function Comment(data: any) {
|
export default function Comment(data: any) {
|
||||||
const token = localStorage.getItem("auth_token");
|
const { session } = useAuth();
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -27,8 +28,8 @@ export default function Comment(data: any) {
|
|||||||
{
|
{
|
||||||
comment: value.comment,
|
comment: value.comment,
|
||||||
key: data.id.split("&")[1].replace("amp;", ""),
|
key: data.id.split("&")[1].replace("amp;", ""),
|
||||||
|
username: session?.user.username,
|
||||||
},
|
},
|
||||||
{ headers: { Authorization: `Bearer ${token}` } },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res.data.success) {
|
if (res.data.success) {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ export default function SiloCard(data: any) {
|
|||||||
quantity: parseFloat(value.newLevel),
|
quantity: parseFloat(value.newLevel),
|
||||||
warehouseId: silo.WarehouseID,
|
warehouseId: silo.WarehouseID,
|
||||||
laneId: silo.LocationID,
|
laneId: silo.LocationID,
|
||||||
|
username: session?.user.username,
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,153 +1,143 @@
|
|||||||
import { Button } from "@/components/ui/button";
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogFooter,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "@/components/ui/dialog";
|
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Label } from "@/components/ui/label";
|
|
||||||
|
|
||||||
import { useForm } from "@tanstack/react-form";
|
import { useForm } from "@tanstack/react-form";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
} from "@/components/ui/dialog";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Label } from "@/components/ui/label";
|
||||||
|
|
||||||
export default function ExportInventoryData() {
|
export default function ExportInventoryData() {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
|
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
age: "",
|
age: "",
|
||||||
},
|
},
|
||||||
onSubmit: async ({ value }) => {
|
onSubmit: async ({ value }) => {
|
||||||
setSaving(true);
|
setSaving(true);
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(
|
const res = await axios.get(
|
||||||
`/api/logistics/getcyclecount?age=${value.age}`,
|
`/lst/old/api/logistics/getcyclecount?age=${value.age}`,
|
||||||
{
|
{
|
||||||
responseType: "blob",
|
responseType: "blob",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const blob = new Blob([res.data], {
|
const blob = new Blob([res.data], {
|
||||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
});
|
});
|
||||||
|
|
||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
link.href = window.URL.createObjectURL(blob);
|
link.href = window.URL.createObjectURL(blob);
|
||||||
link.download = `CycleCount-${format(new Date(Date.now()), "M-d-yyyy")}.xlsx`; // You can make this dynamic
|
link.download = `CycleCount-${format(new Date(Date.now()), "M-d-yyyy")}.xlsx`; // You can make this dynamic
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
link.click();
|
link.click();
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
window.URL.revokeObjectURL(link.href);
|
window.URL.revokeObjectURL(link.href);
|
||||||
toast.success(`File Downloaded`);
|
toast.success(`File Downloaded`);
|
||||||
setSaving(false);
|
setSaving(false);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
form.reset();
|
form.reset();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
console.log(`There was an error getting cycle counts.`);
|
console.log(`There was an error getting cycle counts.`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Dialog
|
<Dialog
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(isOpen) => {
|
onOpenChange={(isOpen) => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
form.reset();
|
form.reset();
|
||||||
}
|
}
|
||||||
setOpen(isOpen);
|
setOpen(isOpen);
|
||||||
// toast.message("Model was something", {
|
// toast.message("Model was something", {
|
||||||
// description: isOpen ? "Modal is open" : "Modal is closed",
|
// description: isOpen ? "Modal is open" : "Modal is closed",
|
||||||
// });
|
// });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button variant="outline">Export Inventory Check</Button>
|
<Button variant="outline">Export Inventory Check</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="sm:max-w-[425px]">
|
<DialogContent className="sm:max-w-[425px]">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Export Inventory lane check</DialogTitle>
|
<DialogTitle>Export Inventory lane check</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
Exports all lanes based on the age you enter, except
|
Exports all lanes based on the age you enter, except empty lanes.
|
||||||
empty lanes.
|
</DialogDescription>
|
||||||
</DialogDescription>
|
</DialogHeader>
|
||||||
</DialogHeader>
|
<form
|
||||||
<form
|
onSubmit={(e) => {
|
||||||
onSubmit={(e) => {
|
e.preventDefault();
|
||||||
e.preventDefault();
|
e.stopPropagation();
|
||||||
e.stopPropagation();
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<div>
|
||||||
<div>
|
<>
|
||||||
<>
|
<form.Field
|
||||||
<form.Field
|
name="age"
|
||||||
name="age"
|
// validators={{
|
||||||
// validators={{
|
// // We can choose between form-wide and field-specific validators
|
||||||
// // We can choose between form-wide and field-specific validators
|
// onChange: ({ value }) =>
|
||||||
// onChange: ({ value }) =>
|
// value.length > 3
|
||||||
// value.length > 3
|
// ? undefined
|
||||||
// ? undefined
|
// : "Username must be longer than 3 letters",
|
||||||
// : "Username must be longer than 3 letters",
|
// }}
|
||||||
// }}
|
children={(field) => {
|
||||||
children={(field) => {
|
return (
|
||||||
return (
|
<div className="m-2 min-w-48 max-w-96 p-2 flex flex-row">
|
||||||
<div className="m-2 min-w-48 max-w-96 p-2 flex flex-row">
|
<Label htmlFor="active">Age</Label>
|
||||||
<Label htmlFor="active">
|
<Input
|
||||||
Age
|
className="ml-2"
|
||||||
</Label>
|
name={field.name}
|
||||||
<Input
|
onBlur={field.handleBlur}
|
||||||
className="ml-2"
|
type="number"
|
||||||
name={field.name}
|
onChange={(e) => field.handleChange(e.target.value)}
|
||||||
onBlur={field.handleBlur}
|
/>
|
||||||
type="number"
|
</div>
|
||||||
onChange={(e) =>
|
);
|
||||||
field.handleChange(
|
}}
|
||||||
e.target.value
|
/>
|
||||||
)
|
</>
|
||||||
}
|
</div>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<div className="flex justify-end mt-2">
|
<div className="flex justify-end mt-2">
|
||||||
<Button onClick={() => setOpen(false)}>
|
<Button onClick={() => setOpen(false)}>Close</Button>
|
||||||
Close
|
<Button
|
||||||
</Button>
|
type="submit"
|
||||||
<Button
|
disabled={saving}
|
||||||
type="submit"
|
onClick={form.handleSubmit}
|
||||||
disabled={saving}
|
>
|
||||||
onClick={form.handleSubmit}
|
{saving ? (
|
||||||
>
|
<>
|
||||||
{saving ? (
|
<span>Saving....</span>
|
||||||
<>
|
</>
|
||||||
<span>Saving....</span>
|
) : (
|
||||||
</>
|
<span>Save setting</span>
|
||||||
) : (
|
)}
|
||||||
<span>Save setting</span>
|
</Button>
|
||||||
)}
|
</div>
|
||||||
</Button>
|
</DialogFooter>
|
||||||
</div>
|
</form>
|
||||||
</DialogFooter>
|
</DialogContent>
|
||||||
</form>
|
</Dialog>
|
||||||
</DialogContent>
|
</div>
|
||||||
</Dialog>
|
);
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { useAuth, useLogout } from "../../../lib/authClient";
|
|||||||
import { AddCards } from "./-components/dashboard/AddCards";
|
import { AddCards } from "./-components/dashboard/AddCards";
|
||||||
import { AppSidebar } from "./-components/layout/lst-sidebar";
|
import { AppSidebar } from "./-components/layout/lst-sidebar";
|
||||||
import DMButtons from "./-components/logistics/dm/DMButtons";
|
import DMButtons from "./-components/logistics/dm/DMButtons";
|
||||||
|
import ExportInventoryData from "./-components/logistics/warehouse/ExportInventoryData";
|
||||||
|
|
||||||
export const Route = createFileRoute("/_old/old")({
|
export const Route = createFileRoute("/_old/old")({
|
||||||
component: RouteComponent,
|
component: RouteComponent,
|
||||||
@@ -39,7 +40,7 @@ function RouteComponent() {
|
|||||||
{location.pathname === "/lst/app/old" ||
|
{location.pathname === "/lst/app/old" ||
|
||||||
(location.pathname === "/lst/app/old/" && (
|
(location.pathname === "/lst/app/old/" && (
|
||||||
<div className="m-auto pr-2 flex flex-row gap-2">
|
<div className="m-auto pr-2 flex flex-row gap-2">
|
||||||
{/* <ExportInventoryData /> */}
|
<ExportInventoryData />
|
||||||
<AddCards />
|
<AddCards />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ const { sign, verify } = jwt;
|
|||||||
|
|
||||||
export const authMiddleware: MiddlewareHandler = async (c, next) => {
|
export const authMiddleware: MiddlewareHandler = async (c, next) => {
|
||||||
console.log("middleware checked");
|
console.log("middleware checked");
|
||||||
const cookieHeader = c.req.header("Cookie");
|
// const cookieHeader = c.req.header("Cookie");
|
||||||
if (!cookieHeader) return c.json({ error: "Unauthorized" }, 401);
|
// if (!cookieHeader) return c.json({ error: "Unauthorized" }, 401);
|
||||||
|
|
||||||
const res = await axios.get(`${process.env.LST_BASE_URL}/api/user/me`, {
|
// const res = await axios.get(`${process.env.LST_BASE_URL}/api/user/me`, {
|
||||||
headers: { Cookie: cookieHeader },
|
// headers: { Cookie: cookieHeader },
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (res.status === 401) return c.json({ error: "Unauthorized" }, 401);
|
// if (res.status === 401) return c.json({ error: "Unauthorized" }, 401);
|
||||||
|
|
||||||
//const user = await resp.json();
|
// //const user = await resp.json();
|
||||||
c.set("user", res.data.user);
|
// c.set("user", res.data.user);
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -84,26 +84,26 @@ interface UserRole {
|
|||||||
|
|
||||||
const hasCorrectRole = (requiredRole: string[], module: string) =>
|
const hasCorrectRole = (requiredRole: string[], module: string) =>
|
||||||
createMiddleware(async (c, next) => {
|
createMiddleware(async (c, next) => {
|
||||||
const cookieHeader = c.req.header("Cookie");
|
// const cookieHeader = c.req.header("Cookie");
|
||||||
if (!cookieHeader) return c.json({ error: "Unauthorized" }, 401);
|
// if (!cookieHeader) return c.json({ error: "Unauthorized" }, 401);
|
||||||
|
|
||||||
const res = await axios.get(`${process.env.LST_BASE_URL}/api/user/roles`, {
|
// const res = await axios.get(`${process.env.LST_BASE_URL}/api/user/roles`, {
|
||||||
headers: { Cookie: cookieHeader },
|
// headers: { Cookie: cookieHeader },
|
||||||
});
|
// });
|
||||||
|
|
||||||
const currentRoles: UserRole[] = res.data.data;
|
// const currentRoles: UserRole[] = res.data.data;
|
||||||
const canAccess = currentRoles.some(
|
// const canAccess = currentRoles.some(
|
||||||
(r) => r.module === module && requiredRole.includes(r.role),
|
// (r) => r.module === module && requiredRole.includes(r.role),
|
||||||
);
|
// );
|
||||||
if (!canAccess) {
|
// if (!canAccess) {
|
||||||
return c.json(
|
// return c.json(
|
||||||
{
|
// {
|
||||||
error: "Unauthorized",
|
// error: "Unauthorized",
|
||||||
message: `You do not have access to ${module}`,
|
// message: `You do not have access to ${module}`,
|
||||||
},
|
// },
|
||||||
400,
|
// 400,
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ app.openapi(
|
|||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
//return apiReturn(c, true, access?.message, access?.data, 200);
|
//return apiReturn(c, true, access?.message, access?.data, 200);
|
||||||
const createSiloAdj = await createSiloAdjustment(data, c.get("user"));
|
const createSiloAdj = await createSiloAdjustment(data, data.username);
|
||||||
|
|
||||||
return c.json(
|
return c.json(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ app.openapi(
|
|||||||
adjId,
|
adjId,
|
||||||
data.comment,
|
data.comment,
|
||||||
data.key,
|
data.key,
|
||||||
c.get("user"),
|
data.username,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(addComment);
|
console.log(addComment);
|
||||||
|
|||||||
@@ -6,289 +6,273 @@ import { machineCheck } from "../../../sqlServer/querys/ocp/machineId.js";
|
|||||||
import { mmQuery } from "../../../sqlServer/querys/ocp/mainMaterial.js";
|
import { mmQuery } from "../../../sqlServer/querys/ocp/mainMaterial.js";
|
||||||
|
|
||||||
export const isMainMatStaged = async (lot: any) => {
|
export const isMainMatStaged = async (lot: any) => {
|
||||||
const set = serverSettings.length === 0 ? [] : serverSettings;
|
const set = serverSettings.length === 0 ? [] : serverSettings;
|
||||||
// make staged false by deefault and error logged if theres an issue
|
// make staged false by deefault and error logged if theres an issue
|
||||||
let isStaged = { message: "Material is staged", success: true };
|
let isStaged = { message: "Material is staged", success: true };
|
||||||
|
|
||||||
const { data, error } = (await tryCatch(
|
const { data, error } = (await tryCatch(
|
||||||
query(
|
query(
|
||||||
machineCheck.replace("where Active = 1 and [Location] = [loc]", ""),
|
machineCheck.replace("where Active = 1 and [Location] = [loc]", ""),
|
||||||
"check machine needs mm"
|
"check machine needs mm",
|
||||||
)
|
),
|
||||||
)) as any;
|
)) as any;
|
||||||
|
|
||||||
const machine = data.data.filter(
|
const machine = data.data.filter(
|
||||||
(m: any) => m.HumanReadableId === lot.machineID
|
(m: any) => m.HumanReadableId === lot.machineID,
|
||||||
);
|
);
|
||||||
// we have a check on ksc side to ignore the tetra machine for now as its not updating in 2.0
|
// we have a check on ksc side to ignore the tetra machine for now as its not updating in 2.0
|
||||||
if (!machine[0].StagingMainMaterialMandatory) {
|
if (!machine[0].StagingMainMaterialMandatory) {
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`The machine dose not require mm to print and book in.`
|
`The machine dose not require mm to print and book in.`,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
message: "Machine dose not require material to be staged",
|
message: "Machine dose not require material to be staged",
|
||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// strangly the lot is not always sending over in slc so adding this in for now to see what line is cauing this issue
|
// strangly the lot is not always sending over in slc so adding this in for now to see what line is cauing this issue
|
||||||
if (!lot) {
|
if (!lot) {
|
||||||
createLog(
|
createLog("info", "mainMaterial", "ocp", "No lot was passed correctly.");
|
||||||
"info",
|
return isStaged;
|
||||||
"mainMaterial",
|
}
|
||||||
"ocp",
|
|
||||||
"No lot was passed correctly."
|
|
||||||
);
|
|
||||||
return isStaged;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof lot !== "object" || lot === null || Array.isArray(lot)) {
|
if (typeof lot !== "object" || lot === null || Array.isArray(lot)) {
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`The lot sent over is not an object: ${JSON.stringify(lot)}`
|
`The lot sent over is not an object: ${JSON.stringify(lot)}`,
|
||||||
);
|
);
|
||||||
return isStaged;
|
return isStaged;
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateQuery = mmQuery.replaceAll("[lotNumber]", lot.lot);
|
const updateQuery = mmQuery.replaceAll("[lotNumber]", lot.lot);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const r: any = await query(updateQuery, "Main Material Check");
|
const r: any = await query(updateQuery, "Main Material Check");
|
||||||
|
|
||||||
const res: any = r.data;
|
const res: any = r.data;
|
||||||
|
|
||||||
// if (res[0].Staged >= 1) {
|
// if (res[0].Staged >= 1) {
|
||||||
// isStaged = true;
|
// isStaged = true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
type CheckConditionArgs = {
|
type CheckConditionArgs = {
|
||||||
results: any[];
|
results: any[];
|
||||||
filterFn: (n: any) => boolean;
|
filterFn: (n: any) => boolean;
|
||||||
failCondition: (n: any) => boolean;
|
failCondition: (n: any) => boolean;
|
||||||
failMessage: string;
|
failMessage: string;
|
||||||
successMessage: string;
|
successMessage: string;
|
||||||
lot: { lot: string | number };
|
lot: { lot: string | number };
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkCondition = ({
|
const checkCondition = ({
|
||||||
results,
|
results,
|
||||||
filterFn,
|
filterFn,
|
||||||
failCondition,
|
failCondition,
|
||||||
failMessage,
|
failMessage,
|
||||||
successMessage,
|
successMessage,
|
||||||
lot,
|
lot,
|
||||||
}: CheckConditionArgs): { message: string; success: boolean } => {
|
}: CheckConditionArgs): { message: string; success: boolean } => {
|
||||||
const subset = results.filter(filterFn);
|
const subset = results.filter(filterFn);
|
||||||
|
|
||||||
if (subset.some(failCondition)) {
|
if (subset.some(failCondition)) {
|
||||||
const failing = subset.filter(failCondition);
|
const failing = subset.filter(failCondition);
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`lot: ${lot.lot}, is missing: ${failing
|
`lot: ${lot.lot}, is missing: ${failing
|
||||||
.map(
|
.map(
|
||||||
(o: any) =>
|
(o: any) =>
|
||||||
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`
|
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`,
|
||||||
)
|
)
|
||||||
.join(",\n ")} ${failMessage}`
|
.join(",\n ")} ${failMessage}`,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
message: `lot: ${lot.lot}, is missing: ${failing
|
message: `lot: ${lot.lot}, is missing: ${failing
|
||||||
.map(
|
.map(
|
||||||
(o: any) =>
|
(o: any) =>
|
||||||
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`
|
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`,
|
||||||
)
|
)
|
||||||
.join(",\n ")} ${failMessage}`,
|
.join(",\n ")} ${failMessage}`,
|
||||||
success: false,
|
success: false,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`lot: ${lot.lot}, ${JSON.stringify(results)}`
|
`lot: ${lot.lot}, ${JSON.stringify(results)}`,
|
||||||
);
|
);
|
||||||
return { message: successMessage, success: true };
|
return { message: successMessage, success: true };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
createLog("info", "mainMaterial", "ocp", `Maint material query ran.`);
|
createLog("info", "mainMaterial", "ocp", `Maint material query ran.`);
|
||||||
|
|
||||||
const mainMaterial = res.find((n: any) => n.IsMainMaterial);
|
const mainMaterial = res.find((n: any) => n.IsMainMaterial);
|
||||||
if (mainMaterial?.noMMShortage === "noMM") {
|
if (mainMaterial?.Staged === 1) {
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`Main material: ${mainMaterial.MaterialHumanReadableId} - ${mainMaterial.MaterialDescription}: is not staged for ${lot.lot}`
|
`Main material: ${mainMaterial.MaterialHumanReadableId} - ${mainMaterial.MaterialDescription}: is staged for ${lot.lot}`,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
message: `Main material: ${mainMaterial.MaterialHumanReadableId} - ${mainMaterial.MaterialDescription}: is not staged for ${lot.lot}`,
|
message: `Main material: ${mainMaterial.MaterialHumanReadableId} - ${mainMaterial.MaterialDescription}: is staged for ${lot.lot}`,
|
||||||
success: false,
|
success: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (mainMaterial?.noMMShortage === "noMM") {
|
||||||
|
createLog(
|
||||||
|
"info",
|
||||||
|
"mainMaterial",
|
||||||
|
"ocp",
|
||||||
|
`Main material: ${mainMaterial.MaterialHumanReadableId} - ${mainMaterial.MaterialDescription}: is not staged for ${lot.lot}`,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
message: `Main material: ${mainMaterial.MaterialHumanReadableId} - ${mainMaterial.MaterialDescription}: is not staged for ${lot.lot}`,
|
||||||
|
success: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// we need to filter the color stuff and then look for includes instead of a standard name. this way we can capture a everything and not a single type
|
// we need to filter the color stuff and then look for includes instead of a standard name. this way we can capture a everything and not a single type
|
||||||
// for manual consume color if active to check colors
|
// for manual consume color if active to check colors
|
||||||
const checkColorSetting = set.filter((n) => n.name === "checkColor");
|
const checkColorSetting = set.filter((n) => n.name === "checkColor");
|
||||||
|
|
||||||
// 2. Auto color
|
// 2. Auto color
|
||||||
if (checkColorSetting[0].value === "1") {
|
if (checkColorSetting[0].value === "1") {
|
||||||
// auto check
|
// auto check
|
||||||
// 2. Auto color
|
// 2. Auto color
|
||||||
const autoColor = checkCondition({
|
const autoColor = checkCondition({
|
||||||
results: res,
|
results: res,
|
||||||
lot,
|
lot,
|
||||||
filterFn: (n) =>
|
filterFn: (n) =>
|
||||||
n.isManual &&
|
n.isManual &&
|
||||||
!("noPKGAutoShortage" in n) &&
|
!("noPKGAutoShortage" in n) &&
|
||||||
!("noPKGManualShortage" in n), // pool = non-main, auto
|
!("noPKGManualShortage" in n), // pool = non-main, auto
|
||||||
failCondition: (n) => n.autoConsumeCheck === "autoConsumeNOK", // column = autoConsumeCheck
|
failCondition: (n) => n.autoConsumeCheck === "autoConsumeNOK", // column = autoConsumeCheck
|
||||||
failMessage: "for autoconsume",
|
failMessage: "for autoconsume",
|
||||||
successMessage: "auto color is good",
|
successMessage: "auto color is good",
|
||||||
});
|
});
|
||||||
if (!autoColor.success) return autoColor;
|
if (!autoColor.success) return autoColor;
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`Auto Color: ${JSON.stringify(autoColor)}`
|
`Auto Color: ${JSON.stringify(autoColor)}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// 3. Manual color
|
// 3. Manual color
|
||||||
const manualColor = checkCondition({
|
const manualColor = checkCondition({
|
||||||
results: res,
|
results: res,
|
||||||
lot,
|
lot,
|
||||||
filterFn: (n) =>
|
filterFn: (n) =>
|
||||||
!n.IsMainMaterial &&
|
!n.IsMainMaterial &&
|
||||||
n.isManual &&
|
n.isManual &&
|
||||||
!("noPKGAutoShortage" in n) &&
|
!("noPKGAutoShortage" in n) &&
|
||||||
!("noPKGManualShortage" in n), // pool = non-main, manual
|
!("noPKGManualShortage" in n), // pool = non-main, manual
|
||||||
failCondition: (n) => n.noManualShortage === "noOK", // column = noManualShortage
|
failCondition: (n) => n.noManualShortage === "noOK", // column = noManualShortage
|
||||||
failMessage: "for manual material",
|
failMessage: "for manual material",
|
||||||
successMessage: "manual color is good",
|
successMessage: "manual color is good",
|
||||||
});
|
});
|
||||||
if (!manualColor.success) return manualColor;
|
if (!manualColor.success) return manualColor;
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`Manual Color: ${JSON.stringify(manualColor)}`
|
`Manual Color: ${JSON.stringify(manualColor)}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
createLog(
|
createLog("info", "mainMaterial", "ocp", "Color check is not active.");
|
||||||
"info",
|
}
|
||||||
"mainMaterial",
|
|
||||||
"ocp",
|
|
||||||
"Color check is not active."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// // if we want to check the packaging
|
// // if we want to check the packaging
|
||||||
const checkPKGSetting = set.filter((n) => n.name === "checkPKG");
|
const checkPKGSetting = set.filter((n) => n.name === "checkPKG");
|
||||||
if (checkPKGSetting[0].value === "1") {
|
if (checkPKGSetting[0].value === "1") {
|
||||||
const pkgAuto = checkCondition({
|
const pkgAuto = checkCondition({
|
||||||
results: res,
|
results: res,
|
||||||
lot,
|
lot,
|
||||||
filterFn: (n) =>
|
filterFn: (n) =>
|
||||||
!n.IsMainMaterial &&
|
!n.IsMainMaterial && !n.isManual && "noPKGAutoShortage" in n,
|
||||||
!n.isManual &&
|
failCondition: (n) => n.noPKGAutoShortage === "noAutoPkg",
|
||||||
"noPKGAutoShortage" in n,
|
failMessage: "for pkg",
|
||||||
failCondition: (n) => n.noPKGAutoShortage === "noAutoPkg",
|
successMessage: "auto PKG is good",
|
||||||
failMessage: "for pkg",
|
});
|
||||||
successMessage: "auto PKG is good",
|
if (!pkgAuto.success) return pkgAuto;
|
||||||
});
|
createLog(
|
||||||
if (!pkgAuto.success) return pkgAuto;
|
"info",
|
||||||
createLog(
|
"mainMaterial",
|
||||||
"info",
|
"ocp",
|
||||||
"mainMaterial",
|
`PKG Auto: ${JSON.stringify(pkgAuto)}`,
|
||||||
"ocp",
|
);
|
||||||
`PKG Auto: ${JSON.stringify(pkgAuto)}`
|
// 5. Packaging manual
|
||||||
);
|
const pkgManual = checkCondition({
|
||||||
// 5. Packaging manual
|
results: res,
|
||||||
const pkgManual = checkCondition({
|
lot,
|
||||||
results: res,
|
filterFn: (n) =>
|
||||||
lot,
|
!n.IsMainMaterial && n.isManual && "noPKGManualShortage" in n,
|
||||||
filterFn: (n) =>
|
failCondition: (n) => n.noPKGManualShortage === "noManPkg",
|
||||||
!n.IsMainMaterial &&
|
failMessage: "for pkg",
|
||||||
n.isManual &&
|
successMessage: "manual PKG is good",
|
||||||
"noPKGManualShortage" in n,
|
});
|
||||||
failCondition: (n) => n.noPKGManualShortage === "noManPkg",
|
|
||||||
failMessage: "for pkg",
|
|
||||||
successMessage: "manual PKG is good",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!pkgManual.success) return pkgManual;
|
if (!pkgManual.success) return pkgManual;
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"mainMaterial",
|
"mainMaterial",
|
||||||
"ocp",
|
"ocp",
|
||||||
`PKG Manual: ${JSON.stringify(pkgManual)}`
|
`PKG Manual: ${JSON.stringify(pkgManual)}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
createLog(
|
createLog("info", "mainMaterial", "ocp", "PKG check is not active.");
|
||||||
"info",
|
}
|
||||||
"mainMaterial",
|
|
||||||
"ocp",
|
|
||||||
"PKG check is not active."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// manual pkg
|
// manual pkg
|
||||||
if (checkPKGSetting[0].value === "1") {
|
if (checkPKGSetting[0].value === "1") {
|
||||||
const packagingCheck = res.filter(
|
const packagingCheck = res.filter(
|
||||||
(n: any) =>
|
(n: any) =>
|
||||||
!n.IsMainMaterial &&
|
!n.IsMainMaterial && n.isManual && "noPKGManualShortage" in n,
|
||||||
n.isManual &&
|
);
|
||||||
"noPKGManualShortage" in n
|
if (
|
||||||
);
|
packagingCheck.some((n: any) => n.noPKGManualShortage === "noManPkg")
|
||||||
if (
|
) {
|
||||||
packagingCheck.some(
|
createLog(
|
||||||
(n: any) => n.noPKGManualShortage === "noManPkg"
|
"info",
|
||||||
)
|
"mainMaterial",
|
||||||
) {
|
"ocp",
|
||||||
createLog(
|
`lot: ${lot.lot}, is missing: ${packagingCheck
|
||||||
"info",
|
.map(
|
||||||
"mainMaterial",
|
(o: any) =>
|
||||||
"ocp",
|
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`,
|
||||||
`lot: ${lot.lot}, is missing: ${packagingCheck
|
)
|
||||||
.map(
|
.join(",\n ")} for pkg`,
|
||||||
(o: any) =>
|
);
|
||||||
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`
|
return (isStaged = {
|
||||||
)
|
message: `lot: ${lot.lot}, is missing: ${packagingCheck
|
||||||
.join(",\n ")} for pkg`
|
.map(
|
||||||
);
|
(o: any) =>
|
||||||
return (isStaged = {
|
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`,
|
||||||
message: `lot: ${lot.lot}, is missing: ${packagingCheck
|
)
|
||||||
.map(
|
.join(",\n ")} for pkg`,
|
||||||
(o: any) =>
|
success: false,
|
||||||
`${o.MaterialHumanReadableId} - ${o.MaterialDescription}`
|
});
|
||||||
)
|
}
|
||||||
.join(",\n ")} for pkg`,
|
} else {
|
||||||
success: false,
|
createLog("info", "mainMaterial", "ocp", "PKG check is not active.");
|
||||||
});
|
}
|
||||||
}
|
} catch (err) {
|
||||||
} else {
|
createLog(
|
||||||
createLog(
|
"error",
|
||||||
"info",
|
"mainMaterial",
|
||||||
"mainMaterial",
|
"ocp",
|
||||||
"ocp",
|
`Error from running the Main Material query: ${err}`,
|
||||||
"PKG check is not active."
|
);
|
||||||
);
|
}
|
||||||
}
|
return isStaged;
|
||||||
} catch (err) {
|
|
||||||
createLog(
|
|
||||||
"error",
|
|
||||||
"mainMaterial",
|
|
||||||
"ocp",
|
|
||||||
`Error from running the Main Material query: ${err}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return isStaged;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,285 +1,275 @@
|
|||||||
import net from "net";
|
|
||||||
import { pausePrinter } from "../../utils/pausePrinter.js";
|
|
||||||
import { addHours, differenceInSeconds } from "date-fns";
|
import { addHours, differenceInSeconds } from "date-fns";
|
||||||
import { printerUpdate } from "./printerStatUpdate.js";
|
import net from "net";
|
||||||
|
import { timeZoneFix } from "../../../../globalUtils/timeZoneFix.js";
|
||||||
import { createLog } from "../../../logger/logger.js";
|
import { createLog } from "../../../logger/logger.js";
|
||||||
|
import { pausePrinter } from "../../utils/pausePrinter.js";
|
||||||
import { unPausePrinter } from "../../utils/unpausePrinter.js";
|
import { unPausePrinter } from "../../utils/unpausePrinter.js";
|
||||||
|
|
||||||
import { labelingProcess } from "../labeling/labelProcess.js";
|
import { labelingProcess } from "../labeling/labelProcess.js";
|
||||||
import { timeZoneFix } from "../../../../globalUtils/timeZoneFix.js";
|
|
||||||
import { autoLabelCreated } from "../labeling/labelRatio.js";
|
import { autoLabelCreated } from "../labeling/labelRatio.js";
|
||||||
|
import { printerUpdate } from "./printerStatUpdate.js";
|
||||||
|
|
||||||
let logLevel: string = process.env.LOG_LEVEL || "info";
|
let logLevel: string = process.env.LOG_LEVEL || "info";
|
||||||
let errorCheck = false;
|
let errorCheck = false;
|
||||||
export const printerStatus = async (p: any) => {
|
export const printerStatus = async (p: any) => {
|
||||||
/**
|
/**
|
||||||
* Checks each printer to see what the current state is
|
* Checks each printer to see what the current state is
|
||||||
*/
|
*/
|
||||||
createLog("debug", "ocp", "ocp", `Printer cycling`);
|
createLog("debug", "ocp", "ocp", `Printer cycling`);
|
||||||
|
|
||||||
const printer = new net.Socket();
|
const printer = new net.Socket();
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
// connect to the printer, and check its status
|
// connect to the printer, and check its status
|
||||||
printer.connect(p.port, p.ipAddress, async () => {
|
printer.connect(p.port, p.ipAddress, async () => {
|
||||||
// write the message to the printer below gives us a feedback of the printer
|
// write the message to the printer below gives us a feedback of the printer
|
||||||
printer.write("~HS");
|
printer.write("~HS");
|
||||||
});
|
});
|
||||||
|
|
||||||
// read the data from the printer
|
// read the data from the printer
|
||||||
printer.on("data", async (data) => {
|
printer.on("data", async (data) => {
|
||||||
const res = data.toString();
|
const res = data.toString();
|
||||||
|
|
||||||
// turn the data into an array to make it more easy to deal with
|
// turn the data into an array to make it more easy to deal with
|
||||||
const tmp = res.split(",");
|
const tmp = res.split(",");
|
||||||
|
|
||||||
//--------------- time stuff-----------------------------------------------------------------
|
//--------------- time stuff-----------------------------------------------------------------
|
||||||
// get last time printed
|
// get last time printed
|
||||||
const lastTime = new Date(p.lastTimePrinted).toISOString();
|
const lastTime = new Date(p.lastTimePrinted).toISOString();
|
||||||
// console.log(lastTime);
|
// console.log(lastTime);
|
||||||
|
|
||||||
// current time?
|
// current time?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* add the time zone to the settings db
|
* add the time zone to the settings db
|
||||||
*/
|
*/
|
||||||
// const currentTime = addHours(
|
// const currentTime = addHours(
|
||||||
// new Date(Date.now()),
|
// new Date(Date.now()),
|
||||||
// -6
|
// -6
|
||||||
// ).toISOString();
|
// ).toISOString();
|
||||||
|
|
||||||
const currentTime = timeZoneFix();
|
const currentTime = timeZoneFix();
|
||||||
|
|
||||||
let timeBetween = 0;
|
let timeBetween = 0;
|
||||||
// if this is our first time printing pause the printer to start the timer, else we just update the time between timer
|
// if this is our first time printing pause the printer to start the timer, else we just update the time between timer
|
||||||
if (lastTime === undefined) {
|
if (lastTime === undefined) {
|
||||||
printer.end();
|
printer.end();
|
||||||
printerUpdate(p, 8);
|
printerUpdate(p, 8);
|
||||||
pausePrinter(p);
|
pausePrinter(p);
|
||||||
resolve({ success: true, message: "First Time printing" });
|
resolve({ success: true, message: "First Time printing" });
|
||||||
} else {
|
} else {
|
||||||
timeBetween = differenceInSeconds(currentTime, lastTime);
|
timeBetween = differenceInSeconds(currentTime, lastTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- end time ---
|
// --- end time ---
|
||||||
|
|
||||||
// --- printer logic ---
|
// --- printer logic ---
|
||||||
createLog(
|
createLog(
|
||||||
"debug",
|
"debug",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name}: timeBetween: ${timeBetween}, delay ${parseInt(
|
`${p.name}: timeBetween: ${timeBetween}, delay ${parseInt(
|
||||||
p.printDelay
|
p.printDelay,
|
||||||
)}, ${currentTime}... ${lastTime}`
|
)}, ${currentTime}... ${lastTime}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (tmp[2] === "0" && tmp[4] !== "000") {
|
if (tmp[2] === "0" && tmp[4] !== "000") {
|
||||||
// unpaused and printing labels - reset timer
|
// unpaused and printing labels - reset timer
|
||||||
createLog(
|
createLog(
|
||||||
"debug",
|
"info",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`Unpaused and printing labels, time remaing ${differenceInSeconds(
|
`Unpaused and printing labels, time remaing ${differenceInSeconds(
|
||||||
parseInt(p.printDelay),
|
parseInt(p.printDelay),
|
||||||
timeBetween
|
timeBetween,
|
||||||
)}`
|
)}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// update last time printed in the array
|
// update last time printed in the array
|
||||||
printerUpdate(p, 1);
|
printerUpdate(p, 1);
|
||||||
} else if (tmp[2] === "1" && tmp[4] !== "000") {
|
} else if (tmp[2] === "1" && tmp[4] !== "000") {
|
||||||
// was paused or label sent from somewhere else
|
// was paused or label sent from somewhere else
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${
|
`${
|
||||||
p.name
|
p.name
|
||||||
} paused to soon, unpausing, remaining time: ${differenceInSeconds(
|
} paused to soon, unpausing, remaining time: ${differenceInSeconds(
|
||||||
parseInt(p.printDelay),
|
parseInt(p.printDelay),
|
||||||
timeBetween
|
timeBetween,
|
||||||
)}`
|
)}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// reset the timer for this printer as well other labels shouldnt be sent but if we send them ok
|
// reset the timer for this printer as well other labels shouldnt be sent but if we send them ok
|
||||||
printerUpdate(p, 2);
|
printerUpdate(p, 2);
|
||||||
|
|
||||||
unPausePrinter(p);
|
unPausePrinter(p);
|
||||||
} else if (tmp[2] === "0" && timeBetween < parseInt(p.printDelay)) {
|
} else if (tmp[2] === "0" && timeBetween < parseInt(p.printDelay)) {
|
||||||
// was unpaused to soon so repause it
|
// was unpaused to soon so repause it
|
||||||
createLog(
|
createLog(
|
||||||
"debug",
|
"info",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name} Unpaused before the time allowed, time left ${
|
`${p.name} Unpaused before the time allowed, time left ${
|
||||||
differenceInSeconds(parseInt(p.printDelay), timeBetween) //seconds
|
differenceInSeconds(parseInt(p.printDelay), timeBetween) //seconds
|
||||||
}`
|
}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
printerUpdate(p, 3);
|
printerUpdate(p, 3);
|
||||||
pausePrinter(p);
|
pausePrinter(p);
|
||||||
} else if (tmp[2] === "0" && timeBetween > parseInt(p.printDelay)) {
|
} else if (tmp[2] === "0" && timeBetween > parseInt(p.printDelay)) {
|
||||||
// its been long enough we can print a label
|
// its been long enough we can print a label
|
||||||
createLog(
|
createLog(
|
||||||
"debug",
|
"info",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name} Allowed time passed and printing new label`
|
`${p.name} Allowed time passed and printing new label`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// update last time printed in the array
|
// update last time printed in the array
|
||||||
printerUpdate(p, 4);
|
printerUpdate(p, 4);
|
||||||
|
|
||||||
// sending over for labeling.
|
// sending over for labeling.
|
||||||
labelingProcess({ printer: p });
|
labelingProcess({ printer: p });
|
||||||
autoLabelCreated();
|
autoLabelCreated();
|
||||||
} else if (tmp[2] === "0") {
|
} else if (tmp[2] === "0") {
|
||||||
// printer was unpaused for the first time or made it here
|
// printer was unpaused for the first time or made it here
|
||||||
createLog(
|
createLog("info", "ocp", "ocp", `${p.name} Frist time printing`);
|
||||||
"debug",
|
|
||||||
"ocp",
|
|
||||||
"ocp",
|
|
||||||
`${p.name} Frist time printing`
|
|
||||||
);
|
|
||||||
|
|
||||||
// add the time and printer
|
// add the time and printer
|
||||||
printerUpdate(p, 4);
|
printerUpdate(p, 4);
|
||||||
|
|
||||||
// sending over for labeling.
|
// sending over for labeling.
|
||||||
labelingProcess({ printer: p });
|
labelingProcess({ printer: p });
|
||||||
autoLabelCreated();
|
autoLabelCreated();
|
||||||
} else if (tmp[2] === "1") {
|
} else if (tmp[2] === "1") {
|
||||||
// printer is paused and waiting
|
// printer is paused and waiting
|
||||||
createLog(
|
createLog("debug", "ocp", "ocp", `${p.name} paused and waiting`);
|
||||||
"debug",
|
|
||||||
"ocp",
|
|
||||||
"ocp",
|
|
||||||
`${p.name} paused and waiting`
|
|
||||||
);
|
|
||||||
|
|
||||||
printerUpdate(p, 6);
|
printerUpdate(p, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.end();
|
printer.end();
|
||||||
|
|
||||||
resolve({ success: true, message: "Print cycle completed." });
|
resolve({ success: true, message: "Print cycle completed." });
|
||||||
});
|
});
|
||||||
|
|
||||||
// as a safety destory it if its still there
|
// as a safety destory it if its still there
|
||||||
printer.on("end", () => {
|
printer.on("end", () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!printer.destroyed) {
|
if (!printer.destroyed) {
|
||||||
createLog(
|
createLog(
|
||||||
"info",
|
"info",
|
||||||
"printerState",
|
"printerState",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name}: was force closed, during normal cycle counting`
|
`${p.name}: was force closed, during normal cycle counting`,
|
||||||
);
|
);
|
||||||
printer.destroy();
|
printer.destroy();
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
printer.on("error", async (error: any) => {
|
printer.on("error", async (error: any) => {
|
||||||
// just going to say theres an error with the printer
|
// just going to say theres an error with the printer
|
||||||
//console.log(error.code);
|
//console.log(error.code);
|
||||||
if (error.code.includes("ETIMEDOUT") && !errorCheck) {
|
if (error.code.includes("ETIMEDOUT") && !errorCheck) {
|
||||||
createLog("error", "ocp", "ocp", `${p.name} is offline`);
|
createLog("error", "ocp", "ocp", `${p.name} is offline`);
|
||||||
|
|
||||||
await printerUpdate(p, 9);
|
await printerUpdate(p, 9);
|
||||||
errorCheck = true;
|
errorCheck = true;
|
||||||
printer.end();
|
printer.end();
|
||||||
|
|
||||||
resolve({
|
resolve({
|
||||||
success: false,
|
success: false,
|
||||||
message: "The printer is offline.",
|
message: "The printer is offline.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!error.code.includes("ETIMEDOUT") && !errorCheck) {
|
if (!error.code.includes("ETIMEDOUT") && !errorCheck) {
|
||||||
createLog(
|
createLog(
|
||||||
"error",
|
"error",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name} encountered an error: ${error}`
|
`${p.name} encountered an error: ${error}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await printerUpdate(p, 7);
|
await printerUpdate(p, 7);
|
||||||
errorCheck = true;
|
errorCheck = true;
|
||||||
|
|
||||||
// send log data
|
// send log data
|
||||||
// fake line
|
// fake line
|
||||||
printer.end();
|
printer.end();
|
||||||
resolve({
|
resolve({
|
||||||
success: false,
|
success: false,
|
||||||
message: "There was an error with the printer.",
|
message: "There was an error with the printer.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const autoLabelingStats = async (p: any) => {
|
export const autoLabelingStats = async (p: any) => {
|
||||||
/**
|
/**
|
||||||
* Checks autolabeling printers just to see what they are doing.
|
* Checks autolabeling printers just to see what they are doing.
|
||||||
*/
|
*/
|
||||||
createLog("debug", "ocp", "ocp", `Printer cycling`);
|
createLog("debug", "ocp", "ocp", `Printer cycling`);
|
||||||
|
|
||||||
const printer = new net.Socket();
|
const printer = new net.Socket();
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
// connect to the printer, and check its status
|
// connect to the printer, and check its status
|
||||||
printer.connect(p.port, p.ipAddress, async () => {
|
printer.connect(p.port, p.ipAddress, async () => {
|
||||||
// write the message to the printer below gives us a feedback of the printer
|
// write the message to the printer below gives us a feedback of the printer
|
||||||
printer.write("~HS");
|
printer.write("~HS");
|
||||||
});
|
});
|
||||||
|
|
||||||
// read the data from the printer
|
// read the data from the printer
|
||||||
printer.on("data", async (data) => {
|
printer.on("data", async (data) => {
|
||||||
const res = data.toString();
|
const res = data.toString();
|
||||||
|
|
||||||
// turn the data into an array to make it more easy to deal with
|
// turn the data into an array to make it more easy to deal with
|
||||||
const tmp = res.split(",");
|
const tmp = res.split(",");
|
||||||
|
|
||||||
if (tmp[4] !== "000") {
|
if (tmp[4] !== "000") {
|
||||||
// unpaused and printing labels - reset timer
|
// unpaused and printing labels - reset timer
|
||||||
createLog("debug", "ocp", "ocp", `Printing Labels`);
|
createLog("debug", "ocp", "ocp", `Printing Labels`);
|
||||||
|
|
||||||
// update last time printed in the array
|
// update last time printed in the array
|
||||||
printerUpdate(p, 1);
|
printerUpdate(p, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp[4] === "000") {
|
if (tmp[4] === "000") {
|
||||||
// unpaused and printing labels - reset timer
|
// unpaused and printing labels - reset timer
|
||||||
createLog("debug", "ocp", "ocp", `Printing Labels`);
|
createLog("debug", "ocp", "ocp", `Printing Labels`);
|
||||||
|
|
||||||
// update last time printed in the array
|
// update last time printed in the array
|
||||||
printerUpdate(p, 5);
|
printerUpdate(p, 5);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
printer.on("error", async (error) => {
|
printer.on("error", async (error) => {
|
||||||
// just going to say theres an error with the printer
|
// just going to say theres an error with the printer
|
||||||
console.log(error);
|
console.log(error);
|
||||||
if (!errorCheck) {
|
if (!errorCheck) {
|
||||||
createLog(
|
createLog(
|
||||||
"error",
|
"error",
|
||||||
"ocp",
|
"ocp",
|
||||||
"ocp",
|
"ocp",
|
||||||
`${p.name}, encountered an error: ${error}`
|
`${p.name}, encountered an error: ${error}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await printerUpdate(p, 7);
|
await printerUpdate(p, 7);
|
||||||
errorCheck = true;
|
errorCheck = true;
|
||||||
|
|
||||||
// send log data
|
// send log data
|
||||||
// fake line
|
// fake line
|
||||||
printer.end();
|
printer.end();
|
||||||
resolve({
|
resolve({
|
||||||
success: false,
|
success: false,
|
||||||
message: "There was an error with the printer.",
|
message: "There was an error with the printer.",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "lst",
|
"name": "lst",
|
||||||
"version": "1.5.0",
|
"version": "1.6.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lst",
|
"name": "lst",
|
||||||
"version": "1.5.0",
|
"version": "1.6.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dotenvx/dotenvx": "^1.51.0",
|
"@dotenvx/dotenvx": "^1.51.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lst",
|
"name": "lst",
|
||||||
"version": "1.5.0",
|
"version": "1.6.0",
|
||||||
"description": "Logistics support tool - the place where the support happens.",
|
"description": "Logistics support tool - the place where the support happens.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user