diff --git a/src/api-server/controller/simulation/productService.ts b/src/api-server/controller/simulation/productService.ts index 690b117..54f6251 100644 --- a/src/api-server/controller/simulation/productService.ts +++ b/src/api-server/controller/simulation/productService.ts @@ -5,7 +5,7 @@ import EventsDataModel from "../../../shared/model/simulation/eventsDataModel.ts export class ProductFlowservice { static async productAdd(req: Request, res: Response): Promise { try { - const { productName, productId, eventDatas, organization } = req.body; + const { productName, productId, , organization } = req.body; if (!organization) { return res.json({ message: "organization not found" }); } diff --git a/src/shared/services/simulation/productService.ts b/src/shared/services/simulation/productService.ts new file mode 100644 index 0000000..05e20fd --- /dev/null +++ b/src/shared/services/simulation/productService.ts @@ -0,0 +1,375 @@ +import { Mixed } from "mongoose"; +import EventsDataModel from "../../V1Models/Simulation/eventsDataModel.ts"; +import ProductModel from "../../V1Models/Simulation/productModel.ts"; +import { existingProjectById, existingUser } from "../helpers/v1projecthelperFns.ts"; + +interface Iproduct { + productName: string; + productId: string; + eventDatas: { + modelUuid: string + modelName: string + position: [Number] + rotation: [Number] + type: string + speed: string + point: Mixed + points: Mixed + }; + userId: string; + organization: string; + projectId: string; +} +interface IResult { + status: string; + data?: object; +} +interface IEventDataDelete { + productId: string; + modelUuid: string + userId: string; + organization: string; + projectId: string; +} +export const productAdd = async (data: Iproduct): Promise => { + try { + const { productName, productId, eventDatas, projectId, userId, organization } = data + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const existingProduct = await ProductModel(organization).findOne({ + productId: productId, projectId: projectId, + isArchive: false, + }); + if (existingProduct) { + const existingEventData = await EventsDataModel(organization).findOne({ + productId: productId, + projectId: projectId, + modelUuid: eventDatas.modelUuid, + isArchive: false, + }); + if (existingEventData) { + await EventsDataModel(organization).findOneAndUpdate( + { + modelUuid: eventDatas.modelUuid, + productId: productId, + isArchive: false, + }, + { + modelUuid: eventDatas?.modelUuid, + modelName: eventDatas?.modelName, + position: eventDatas?.position, + rotation: eventDatas?.rotation, + type: eventDatas?.type, + speed: eventDatas?.speed, + point: eventDatas?.point, + points: eventDatas?.points, + } + ); + return { + status: "EventData updated successfully" + } + // return res + // .status(200) + // .json({ message: "EventData updated successfully" }); + } else { + await EventsDataModel(organization).create({ + productId: productId, + modelUuid: eventDatas?.modelUuid, + modelName: eventDatas?.modelName, + position: eventDatas?.position, + rotation: eventDatas?.rotation, + type: eventDatas?.type, + speed: eventDatas?.speed, + point: eventDatas?.point, + points: eventDatas?.points, + }); + return { + status: "EventData add successfully" + } + // return res + // .status(201) + // .json({ message: "EventData add successfully" }); + } + } else { + const newProduct = await ProductModel(organization).create({ + productId: productId, + productName: productName, + }); + if (newProduct) { + if (eventDatas) { + await EventsDataModel(organization).create({ + productId: productId, + modelUuid: eventDatas?.modelUuid, + modelName: eventDatas?.modelName, + position: eventDatas?.position, + rotation: eventDatas?.rotation, + type: eventDatas?.type, + speed: eventDatas?.speed, + point: eventDatas?.point, + points: eventDatas?.points, + }); + } + } + return { + status: "Success" + } + // return res + // .status(201) + // .json({ message: "Product created successfully" }); + } + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} +export const getProductDatas = async (data: Iproduct): Promise => { + try { + const { productId, projectId, userId, organization } = data + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const existingProduct = await ProductModel(organization).findOne({ + productId: productId, projectId: projectId, + isArchive: false, + }); + + if (!existingProduct) + return { status: "Product not found" }; + // return res.status(404).json({ message: "Product not found" }); + + const existingEventDatas = await EventsDataModel(organization) + .find({ productId: productId, projectId: projectId }) + .select("-productId"); + return { status: "Success", data: existingEventDatas }; + // return res.status(200).json(existingEventDatas); + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} +export const productDataDelete = async (data: Iproduct): Promise => { + try { + const { productId, projectId, userId, organization } = data + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const existingProduct = await ProductModel(organization).findOne({ + productId: productId, + isArchive: false, + }); + + if (!existingProduct) + return { status: "Product not found" }; + // return res.status(404).json({ message: "Product not found" }); + + await ProductModel(organization).findOneAndUpdate( + { productId: productId, projectId: projectId }, + { + isArchive: true, + }, + { new: true } + ); + const existingEventDatas = await EventsDataModel(organization).find({ + productId: productId, + }); + if (existingEventDatas) { + await EventsDataModel(organization).updateMany( + { productId, projectId }, + { $set: { isArchive: true } } + ); + } + return { + status: "Success", + // data: assetDatas, + }; + // return res.status(201).json({ message: "product deleted successfully" }); + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} +export const EventDataDelete = async (data: IEventDataDelete): Promise => { + try { + const { modelUuid, productId, projectId, userId, organization } = data + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const existingProduct = await ProductModel(organization).findOne({ + productId: productId, projectId: projectId, + isArchive: false, + }); + + if (!existingProduct) + return { status: "Product not found" }; + // return res.status(404).json({ message: "Product not found" }); + await EventsDataModel(organization).findOneAndUpdate( + { productId: productId, projectId: projectId, modelUuid: modelUuid }, + { + isArchive: true, + }, + { new: true } + ); + + // return res + // .status(201) + // .json({ message: "EventData deleted successfully" }); + return { + status: "Success", + // data: assetDatas, + }; + + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} +export const AllProductDatas = async (data: IEventDataDelete): Promise => { + try { + const { projectId, userId, organization } = data + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const existingProduct = await ProductModel(organization).find({ + isArchive: false, + }); + if (!existingProduct) { + // return res.status(404).json({ message: "No products found" }); + return { + status: "No products found", + // data: result, + }; + } + const result = []; + + for (const product of existingProduct) { + const eventDatas = await EventsDataModel(organization) + .find({ projectId: product.projectId, productId: product.productId, isArchive: false }) + .select("-productId -isArchive -createdAt -updatedAt -__v -_id"); + + result.push({ + // product: { + projectId: product.projectId, + productName: product.productName, + productId: product.productId, + eventDatas, + // }, + }); + } + + // return res.status(200).json(result); + return { + status: "Success", + data: result, + }; + + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} +export const productRename = async (data: Iproduct): Promise => { + try { + const { productName, productId, projectId, userId, organization } = data + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const existingProduct = await ProductModel(organization).findOne({ + productId: productId, projectId: projectId, + isArchive: false, + }); + + if (!existingProduct) + return { status: "Product not found" }; + + await ProductModel(organization).findOneAndUpdate( + { productId: productId }, + { + productName: productName, + }, + { new: true } + ); + + // return res.status(201).json({ message: "product Rename successfully" }); + return { + status: "Success", + // data: assetDatas, + }; + + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} \ No newline at end of file diff --git a/src/socket-server/controllers/builder/cameraController.ts b/src/socket-server/controllers/builder/cameraController.ts deleted file mode 100644 index e3dcda1..0000000 --- a/src/socket-server/controllers/builder/cameraController.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { Socket, Server } from "socket.io"; -import { EVENTS } from "../../socket/events.ts"; -import { emitEventResponse } from "../../utils/emitEventResponse.ts"; -import { SetCamera } from "../../../shared/services/builder/cameraService.ts"; -export const SetCameraHandleEvent = async ( event: string,socket: Socket,data: any,) => { - if (event !== EVENTS.setCamera || !data?.organization) return; - const requiredFields = ["userId", "position", "target", "rotation", "organization","projectId","versionId"]; - const missingFields = requiredFields.filter(field => !data?.[field]); - - if (missingFields.length > 0) { - const response = { - success: false, - message: `Missing required field(s): ${missingFields.join(", ")}`, - status: "MissingFields", - socketId: socket.id, - organization: data?.organization ?? "unknown", - }; - - emitEventResponse(socket, data?.organization, EVENTS.cameraCreateResponse, response); - return; - } - const result = await SetCamera(data); - const status = typeof result?.status === "string" ? result.status : "unknown"; - - const messages: Record = { - "Creation Success": { message: "Camera created Successfully" }, - "User not found": { message: "User not found" }, - "Project not found": { message: "Project not found" }, - "Update Success": { message: "Camera updated Successfully" }, - }; -const msg = messages[status] || { message: "Internal server error" }; - const isSuccess = status === "Creation Success" || status === "Update Success"; - - -const response = { - success: status === "Success", - message: msg.message, - status, - socketId: socket.id, - organization: data.organization, - ...(isSuccess && result?.data ? { data: result.data }: {}), - }; - - - const responseEvent = - status === "Creation Success" - ? EVENTS.cameraCreateResponse - : EVENTS.cameraUpdateResponse; - - emitEventResponse(socket, data.organization, responseEvent, response); -} \ No newline at end of file diff --git a/src/socket-server/controllers/simulationController/product-Controller.ts b/src/socket-server/controllers/simulationController/product-Controller.ts new file mode 100644 index 0000000..0738f33 --- /dev/null +++ b/src/socket-server/controllers/simulationController/product-Controller.ts @@ -0,0 +1,278 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { EventDataDelete, productAdd, productDataDelete } from "../../../shared/services/simulation/productService.ts"; +export const productAddHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setAssetModel_v1 || !data?.organization) return; + const requiredFields = [ + "productName", "productId", "eventDatas", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await productAdd(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Product created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "EventData updated successfully": { message: "EventData updated successfully" }, + "EventData add successfully": { message: "EventData add successfully" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const product_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(product_Datas ? { data: product_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) +} +export const productDataDeleteHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setAssetModel_v1 || !data?.organization) return; + const requiredFields = [ + "productId", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await productDataDelete(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Product deleted successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Product not found": { message: "Product not found" }, + + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const product_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(product_Datas ? { data: product_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) +} +export const EventDataDeleteHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setAssetModel_v1 || !data?.organization) return; + const requiredFields = [ + "modelUuid", + "productId", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await EventDataDelete(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "EventData deleted successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Product not found": { message: "Product not found" }, + + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const product_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(product_Datas ? { data: product_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) +} +export const productRenameHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setAssetModel_v1 || !data?.organization) return; + const requiredFields = [ + "productName", + "productId", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await EventDataDelete(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "product Rename successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Product not found": { message: "Product not found" }, + + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const product_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(product_Datas ? { data: product_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/socket/events.ts b/src/socket-server/socket/events.ts index fbe9d8c..0bb6736 100644 --- a/src/socket-server/socket/events.ts +++ b/src/socket-server/socket/events.ts @@ -92,13 +92,13 @@ export const EVENTS = { //3Dwidget - add3DWidget:"v2:viz-3D-widget:add", - widget3DUpdateResponse:"viz-widget3D:response:updates", - update3dPosition:"v2:viz-3D-widget:modifyPositionRotation", - update3dPositionResponse:"viz-widget3D:response:modifyPositionRotation", - delete3DWidget:"v2:viz-3D-widget:delete", - widget3DDeleteResponse:"viz-widget3D:response:delete", -/////////////////........................................................ + add3DWidget: "v2:viz-3D-widget:add", + widget3DUpdateResponse: "viz-widget3D:response:updates", + update3dPosition: "v2:viz-3D-widget:modifyPositionRotation", + update3dPositionResponse: "viz-widget3D:response:modifyPositionRotation", + delete3DWidget: "v2:viz-3D-widget:delete", + widget3DDeleteResponse: "viz-widget3D:response:delete", + /////////////////........................................................ //PROJECT addProject: "v1:project:add", @@ -108,15 +108,15 @@ export const EVENTS = { ProjectUpdate: "v1:project:update", projectUpdateResponse: "v1-project:response:update", -//THREAD -createThread:"v1:thread:create", -ThreadCreateResponse:"v1-thread:response:create", -deleteThread:"v1:thread:delete", -deleteThreadResponse:"v1-thread:response:delete", -addComment:"v1-Comment:response:add", -addCommentResponse:"v1-Comment:response:add", -deleteComment:"v1-Comment:response:delete", -deleteCommentResponse:"v1-Comment:response:delete", + //THREAD + createThread: "v1:thread:create", + ThreadCreateResponse: "v1-thread:response:create", + deleteThread: "v1:thread:delete", + deleteThreadResponse: "v1-thread:response:delete", + addComment: "v1-Comment:response:add", + addCommentResponse: "v1-Comment:response:add", + deleteComment: "v1-Comment:response:delete", + deleteCommentResponse: "v1-Comment:response:delete", //3Dwidget addWidget3D: "v1:viz-3D-widget:add", addWidget3DResponse: "v1:viz-widget3D:response:add",