From 5ba618f471cec02a678c0d22bd6f3d60f8895bc9 Mon Sep 17 00:00:00 2001 From: Brian McGonagill Date: Sat, 24 Jan 2026 13:49:38 -0600 Subject: [PATCH] Many changes aded to system. --- Outline.md | 242 ++++++++++++++++++++ client/AdminMgmt/SysConfig/systemAdmin.html | 67 +++--- client/AdminMgmt/SysConfig/systemAdmin.js | 7 +- client/General/Home/home.html | 2 +- client/General/headerbar.css | 62 +++++ client/General/headerbar.html | 53 +++-- client/General/headerbar.js | 12 +- client/LocationTypes/locationTypeTbl.html | 23 ++ client/LocationTypes/locationTypeTbl.js | 21 ++ client/LocationTypes/locationTypes.html | 21 ++ client/LocationTypes/locationTypes.js | 38 +++ client/Locations/locations.html | 4 + client/Locations/locations.js | 19 ++ client/MainLayout.html | 1 - imports/api/assets.js | 28 +++ imports/api/locationTypes.js | 30 +++ imports/api/locations.js | 16 ++ imports/api/tenants.js | 0 imports/api/userInfo.js | 14 +- lib/route.js | 14 ++ server/methods.js | 7 +- server/publish.js | 16 ++ 22 files changed, 640 insertions(+), 57 deletions(-) create mode 100644 Outline.md create mode 100644 client/General/headerbar.css create mode 100644 client/LocationTypes/locationTypeTbl.html create mode 100644 client/LocationTypes/locationTypeTbl.js create mode 100644 client/LocationTypes/locationTypes.html create mode 100644 client/LocationTypes/locationTypes.js create mode 100644 client/Locations/locations.html create mode 100644 client/Locations/locations.js create mode 100644 imports/api/assets.js create mode 100644 imports/api/locationTypes.js create mode 100644 imports/api/locations.js create mode 100644 imports/api/tenants.js diff --git a/Outline.md b/Outline.md new file mode 100644 index 0000000..9357dbd --- /dev/null +++ b/Outline.md @@ -0,0 +1,242 @@ +### Handled at the master level + +Tenants: + - Tenant 000000: Master Tenant + - Tenant: 000001 - zzzzzz (all other tenants) + - Tenant Name + - Tenant ID + - Tenant Description + - Tenant Email (primary contact) + - Tenant Phone (primary Contact) + + +### Handled at the Tenant Level: + +#### Tenant Locations: + +Any locations defined through a parent - child hierarchy. This can best reflect the actual structure of any location where assets may be located + + ``` + location { + _id: location_id, # req + tenant_id: tenant_id, # req + loc_name: location_name, # req + loc_desc: location_description, + loc_type: code_table, # req + loc_info: { + location_info + }, + loc_is_child: t/f, # req + loc_parent_id: location_id, + } + ``` +__Code Table: location type__ +``` +location_types: { + _id: loc_type_id + loc_type: type, + tenant_id: tenant_id, +} +``` +__Code Table: location info__ +``` +location_details: { + _id: loc_detail_id, + tenant_id: tenant_id, + loc_type: type_id, + loc_detail: detail1, + loc_detail_type: (text, number, t/f, select), + loc_detail_sel_options: { + option: option1, + option: option2, + } +} +``` +---- + +### Assets +An asset is any item, whether permanent fixture, high dollar equiprment, consumable requiring inventory and replenishment, or otherwise. + +``` +item: { + _id: item_id, + tenant_id: tenant_id, + location_id: location_id, + location_path: path / separated / out, + item_name: item name, + item_desc: item desc, + images: { + image_name: image name, + image_storage_location: path to image, + } + item_qty: qunatity, + item_type: code_table, + expiration_date: item_expires + createdDate: new Date(), + createdBy: user_id, + modified: { + modified_on: new Date(), + modified_by: user_id, + modified_reason: text_input, + }, + item_archived: t/f, + item_archive_info: { + archived_on: new Date(), + archived_by: user_id, + archive_reason: text_input, + }, + item_deleted: t/f, + item_delete_info: { + deleted_on: new Date(), + deleted_by: user_id, + deleted_reason: text_input, + }, + item_dispo_info: { + item_dispo: code_table, + dispo_date: new Date(), + dispo_by: user_id, + dispo_reason: text_input, + dispo_description: text_input, + }, + item_barcode: barcode detail (autogenerate 1d), + item_req_inspection: t/f + item_req_inventory: t/f + item_cost: number, + item_value: number, + item_type_attributes: { + item_attribute: { + attribute: entry_type, + attribute: entry_type, + }, + item_attribute: { + attribute: entry_type, + attribute: entry_type, + }, + }. + is_parent_of_multipart_asset: t/f + is_part_of_multipart_asset: t/f + multipart_asset_parent_id +} +``` + +__Code Table: Asset Types__ +``` +asset_types: { + _id: asset_type_id, + tenant_id: tenant_id: + asset_type_name: name, + assett_type_desc: asset_type_description, + asset_type_req_more_details: t/f +} +``` + +__Code Table: Asset Type Details__ +``` +asset_type_details: { + _id: asset_type_details_id, + asset_type_id: asset_type_id, + tenant_id: tenant_id, + detail: detail_to_collect, + field_type: number, text, t/f, select, + asset_type_detail_sel_options: { + option: option1, + option: option2, + } +} +``` +__Code Table: Asset Disposition__ +``` +asset_dispoitions: { + _id: dispo_id, + tenant_id: tenant_id, + disposition: disposition, + is_final: is_a_final_dispo (t/f), + archive_with_this_disp: t/f, +} +``` + +__Code Table: Asset Inspection Types__ +``` +asset_inspection_type: { + _id: inspection_id, + tenant_id: tenant_id, + insp_type_name: name +} +``` + +__Code Table: Asset Inspection Options__ +``` +asset_inspection_name: { + _id: inspection_id, + tenant_id: tenant_id, + insp_name: name, + insp_type: item_inspection_id +} +``` + +__Code Table: Asset Attribute__ +``` +asset_attribute_name: { + _id: attribute_id, + tenant_id: tenant_id, + attribute_name: name, # e.g. color, texture, etc + attribute_req: t/f, + attribute_applies_to_asset_types: +} +``` +---- +## Asset Inspections + +Inspection Type + +Inspection Steps + - Step Type (e.g. pass, fail, measure, grade, etc) + - Step instructions + - Observations + - Evidence (images, notes, video, data, etc.) + +Multi-part Asset Inspection? + +Signature of completion +Signature of acceptance +Signature of reviewer +Singature of secondary inspectors + + + +---- +## Asset Inventory + + +---- +## Asset Movements +Movements covers a wide array of actions, including but not limited to moving an item from 1 place to another, moving an item in a way that the item is used up (e.g. using a needle, flex-cuff, etc), movement for destruction, movement for retirement, etc. These types can be defined by the tenant. + +#### Movement Record + +``` +asset_movement: { + _id: asset_move_id, + tenant_id: tenant_id, + asset_id: asset_id, + movement_type: movement_type_id, + movement_end +} +``` + + +``` +movement_type: { + _id: movement_id, + tenant_id: tenant_id, + movement_name: name, + movement_desc: description, + req_end_location: t/f, + req_usage_qty: t/f, + +} +``` + +---- +## + diff --git a/client/AdminMgmt/SysConfig/systemAdmin.html b/client/AdminMgmt/SysConfig/systemAdmin.html index f5d1798..9d8040f 100644 --- a/client/AdminMgmt/SysConfig/systemAdmin.html +++ b/client/AdminMgmt/SysConfig/systemAdmin.html @@ -1,37 +1,48 @@ diff --git a/client/AdminMgmt/SysConfig/systemAdmin.js b/client/AdminMgmt/SysConfig/systemAdmin.js index bfdf299..a566b05 100644 --- a/client/AdminMgmt/SysConfig/systemAdmin.js +++ b/client/AdminMgmt/SysConfig/systemAdmin.js @@ -1,6 +1,7 @@ +import { Roles } from 'meteor/roles'; +import { FlowRouter } from 'meteor/ostrio:flow-router-extra'; import { SysConfig } from "../../../imports/api/systemConfig"; - Template.systemAdmin.onCreated(function() { this.subscribe("SystemConfig"); this.subscribe("rolesAvailable"); @@ -59,4 +60,8 @@ Template.systemAdmin.events({ updateInfo(); }, + 'click .navSetup' (event) { + let target = event.target.id; + FlowRouter.go('/' + target); + } }); diff --git a/client/General/Home/home.html b/client/General/Home/home.html index b2f89bb..22579ea 100644 --- a/client/General/Home/home.html +++ b/client/General/Home/home.html @@ -1,6 +1,6 @@ diff --git a/imports/api/assets.js b/imports/api/assets.js new file mode 100644 index 0000000..c3339ee --- /dev/null +++ b/imports/api/assets.js @@ -0,0 +1,28 @@ +import { Meteor } from 'meteor/meteor'; +import { Mongo } from 'meteor/mongo'; +import { check } from 'meteor/check'; + +export const Assets = new Mongo.Collection('assets'); + +Assets.allow({ + insert: function(userId, doc){ + // if use id exists, allow insert + return !!userId; + }, +}); + +Meteor.methods({ + async 'add.asset' (assetName { + check(assetName, String); + + if (!this.userId) { + throw new Meteor.Error('You are not allowed to add assets. Make sure you are logged in with valid user credentials.'); + } + + return await Assets.insertAsync({ + assetName: assetName, + tenant_id: "000000", + + }); + }, +}); \ No newline at end of file diff --git a/imports/api/locationTypes.js b/imports/api/locationTypes.js new file mode 100644 index 0000000..d02fef6 --- /dev/null +++ b/imports/api/locationTypes.js @@ -0,0 +1,30 @@ +import { Meteor } from 'meteor/meteor'; +import { Mongo } from 'meteor/mongo'; +import { check } from 'meteor/check'; + +export const LocationTypes = new Mongo.Collection('locationTypes'); + +LocationTypes.allow({ + insert: function(userId, doc){ + // if use id exists, allow insert + return !!userId; + }, +}); + +Meteor.methods({ + async "add.locationType" (typeName, typeDesc) { + check(typeName, String); + check(typeDesc, String); + + if (!this.userId) { + throw new Meteor.Error('You are not allowed to add location types. Make sure you are logged in with valid user credentials.'); + } + + return await LocationTypes.insertAsync({ + locationTypeName: typeName, + locationTypeDesc: typeDesc, + dateAdded: new Date(), + addedBy: this.userId, + }); + } +}); \ No newline at end of file diff --git a/imports/api/locations.js b/imports/api/locations.js new file mode 100644 index 0000000..d7d3233 --- /dev/null +++ b/imports/api/locations.js @@ -0,0 +1,16 @@ +import { Meteor } from 'meteor/meteor'; +import { Mongo } from 'meteor/mongo'; +import { check } from 'meteor/check'; + +export const Locations = new Mongo.Collection('locations'); + +Locations.allow({ + insert: function(userId, doc){ + // if use id exists, allow insert + return !!userId; + }, +}); + +Meteor.methods({ + +}); \ No newline at end of file diff --git a/imports/api/tenants.js b/imports/api/tenants.js new file mode 100644 index 0000000..e69de29 diff --git a/imports/api/userInfo.js b/imports/api/userInfo.js index d055f2b..30a1646 100644 --- a/imports/api/userInfo.js +++ b/imports/api/userInfo.js @@ -6,11 +6,23 @@ export const UserInfo = new Mongo.Collection('userInfo'); UserInfo.allow({ insert: function(userId, doc){ - // if use id exists, allow insert + // if user id exists, allow insert return !!userId; }, }); Meteor.methods({ + async 'addUserToTenant' (userId, tenant_id) { + check(userId, String); + check(tenant_id, String); + if (!this.userId) { + throw new Meteor.Error('You are not allowed to add tenants for users. Make sure you are logged in with valid user credentials.'); + } + + return await UserInfo.insertAsync({ + userId: userId, + tenant_id: tenant_id, + }); + }, }); \ No newline at end of file diff --git a/lib/route.js b/lib/route.js index a000d20..91e1d16 100644 --- a/lib/route.js +++ b/lib/route.js @@ -47,4 +47,18 @@ FlowRouter.route('/userMgmt', { action() { this.render('MainLayout', { main: "userMgmt" }); } +}); + +FlowRouter.route('/locations', { + name: 'locations', + action() { + this.render('MainLayout', { main: "locations" }); + } +}); + +FlowRouter.route('/locationTypes', { + name: 'locationtypes', + action() { + this.render('MainLayout', { main: "locationTypes" }); + } }); \ No newline at end of file diff --git a/server/methods.js b/server/methods.js index 3dc1f43..619e389 100644 --- a/server/methods.js +++ b/server/methods.js @@ -11,9 +11,12 @@ Meteor.methods({ if (user) { let userId = user._id; if (countOfUsers > 1) { - await Roles.addUsersToRolesAsync(userId, role); + let addedRole = await Roles.addUsersToRolesAsync(userId, role); } else if (countOfUsers == 1) { - await Roles.addUsersToRolesAsync(userId, "systemadmin"); + let addedRole = await Roles.addUsersToRolesAsync(userId, "systemadmin"); + if (addedRole) { + await Meteor.callAsync('addUserToTenant', userId, "000001"); + } } else { console.log("The count of users didn't seem to work when adding a new user."); } diff --git a/server/publish.js b/server/publish.js index 14cab75..4ca766b 100644 --- a/server/publish.js +++ b/server/publish.js @@ -2,6 +2,8 @@ import { SysConfig } from "../imports/api/systemConfig"; import { UpdateInfo } from "../imports/api/updateInfo"; import { MScripts } from "../imports/api/mScripts"; import { UserInfo } from "../imports/api/userInfo"; +import { Locations } from "../imports/api/locations"; +import { LocationTypes } from "../imports/api/locationTypes"; import { Roels } from "meteor/roles"; Meteor.publish("SystemConfig", function() { @@ -34,3 +36,17 @@ Meteor.publish(null, function () { } this.ready(); }); + +Meteor.publish("Locations", function () { + if (this.userId) { + return Locations.find({}); + } + this.ready(); +}); + +Meteor.publish("LocationTypes", function () { + if (this.userId) { + return LocationTypes.find({}); + } + this.ready(); +});