Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capacities and occupancies for service and program occurrences #117

Open
wants to merge 46 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
0a2ca21
Changes to list overview in Clients and Need Occurences
Damon-D-Ma Jan 15, 2024
830c727
Revert local backend index.js changes
Damon-D-Ma Jan 15, 2024
735256f
Base Code for Service Waitlist Type
Damon-D-Ma Feb 2, 2024
e91597d
Completed Service Waitlist Feature
Damon-D-Ma Feb 12, 2024
1739f27
Add capacity to service and program occurrences
htysc Feb 25, 2024
a1ec584
Add occupancy to service and program occurrences
htysc Mar 1, 2024
9910ac4
Add occurrence status (string for now)
htysc Mar 2, 2024
69de1f4
Use options for program and service occurrences
htysc Mar 2, 2024
92e6d45
Let capacities be unlimited
htysc Mar 2, 2024
6b2e375
Set occupancy to 0 on creation
htysc Mar 2, 2024
2839427
Bugfix on NumberField & partial CO deletion.
LesterLyu Mar 4, 2024
193163b
Registration statuses
htysc Mar 5, 2024
dd34179
Customized service registration status options
htysc Mar 5, 2024
652e572
Customized program registration status options
htysc Mar 5, 2024
d95b58a
Registration status option fixes
htysc Mar 5, 2024
74adf7a
Service registration status backend (except for waitlists)
htysc Mar 6, 2024
76a096f
Merge branch 'master' into capacities
htysc Mar 6, 2024
fa09dde
Fix bugs
htysc Mar 6, 2024
07bb558
Program registration status backend (except for waitlists)
htysc Mar 6, 2024
0f232af
Fix bugs
htysc Mar 6, 2024
a660b8d
Update waitlist TODOs
htysc Mar 6, 2024
00dd1f3
Updates to Waitlist + New Entry Model
Damon-D-Ma Mar 6, 2024
708cbf0
Added Required Functions to Manipulate Service Waitlists
Damon-D-Ma Mar 7, 2024
f926dc1
Fix occupancy update bug
htysc Mar 11, 2024
ea4ef26
Added auto-create waitlist for serviceOccurrence
Damon-D-Ma Mar 12, 2024
1e55e15
Updated waitlistEntryModel
Damon-D-Ma Mar 12, 2024
fa466b4
Forgot to fix import statements
Damon-D-Ma Mar 12, 2024
cb0d9dd
Changes to backend waitlistEntry Components
Damon-D-Ma Mar 12, 2024
cf4e8a6
Changes to waitlistEntry Structure
Damon-D-Ma Mar 12, 2024
45ce943
Forgot to Rename serviceWaitlist Attribute
Damon-D-Ma Mar 12, 2024
b34b528
Updated waitlist functions
Damon-D-Ma Mar 12, 2024
23f989b
Implemented Changes From Code Review
Damon-D-Ma Mar 15, 2024
5b67143
More Fixes From Code Review
Damon-D-Ma Mar 15, 2024
ca862ae
Created Models for program waitlists + entries
Damon-D-Ma Mar 15, 2024
bc88bed
Added Program Waitlists
Damon-D-Ma Mar 15, 2024
2eb86a4
Use waitlist functions (not fully tested yet)
htysc Mar 15, 2024
e19c7b6
Fix bugs
htysc Mar 18, 2024
63b4839
Implement service occurrence capacity change checks
htysc Mar 18, 2024
1c99ac1
Waitlists for program occurrences
htysc Mar 18, 2024
5c40d5f
Fix bug
htysc Mar 18, 2024
8c1a524
Added functionality for programWaitlist, code style changes
Damon-D-Ma Mar 20, 2024
ec1832e
Fix bugs
htysc Mar 20, 2024
5422bce
Prevent updating a registration's occurrence
htysc Mar 20, 2024
194de23
Added New General FAQ Guide for Codebase Newcomers
Damon-D-Ma Mar 22, 2024
8c94e97
Guide got ignored by gitignore for some reason
Damon-D-Ma Mar 22, 2024
6d91055
Merge branch 'master' into capacities
LesterLyu Mar 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if (isProduction)

const config = {
graphdb: {
addr: isProduction ? 'http://localhost:7200' : `http://${isDocker ? 'host.docker.internal' : 'localhost'}:7200`,
addr: isProduction ? 'http://127.0.0.1:7200' : `http://${isDocker ? 'host.docker.internal' : '127.0.0.1'}:7200`,
repositoryName: process.env.GRAPHDB_REPO || (process.env.test ? "snmiTest" : "snmi")
},
mongodb: {
Expand Down
3 changes: 3 additions & 0 deletions backend/loaders/express.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ app.use('/public', partnerNetworkPublicRoute);
await initOptions('Appointment Statuses',
["Requested", "Confirmed", "Cancelled", "Fulfilled", "Client No Show", "Postponed"],
'AppointmentStatus', 'appointmentStatus');
await initOptions('Service and Program Registration Statuses',
["Registered", "Not Registered", "Waitlisted"],
'RegistrationStatus', 'registrationStatus');
})()


Expand Down
2 changes: 2 additions & 0 deletions backend/models/program/programOccurrence.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const GDBProgramOccurrenceModel = createGraphDBModel({
needSatisfiers: {type: [GDBNeedSatisfierModel], internalKey: ':hasNeedSatisfier'},
// needSatisfierOccurrence: {type: [GDBNeedSatisfierOccurrenceModel], internalKey: ':hasNeedSatisfierOccurrence', onDelete: DeleteType.CASCADE},
description: {type: String, internalKey: 'cids:hasDescription'},
capacity: {type: Number, internalKey: ':hasCapacity'},
occupancy: {type: Number, internalKey: ':hasOccupancy'},
characteristicOccurrences: {type: [GDBCOModel], internalKey: ':hasCharacteristicOccurrence'}
}, {
rdfTypes: [':ProgramOccurrence'], name: 'programOccurrence'
Expand Down
18 changes: 18 additions & 0 deletions backend/models/program/programWaitlist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const {createGraphDBModel, DeleteType, Types} = require("graphdb-utils");

//These might need tweaking, need to figure out what things we need for this model
const {GDBProgramOccurrenceModel} = require("./programOccurrence");
const {GDBProgramWaitlistEntryModel} = require("./programWaitlistEntry");

const GDBProgramWaitlistModel = createGraphDBModel({
waitlist: {type: [GDBProgramWaitlistEntryModel], internalKey: ':hasWaitlist'},
programOccurrence: {type: GDBProgramOccurrenceModel, internalKey: ':hasProgramOccurrence'},
},
{
rdfTypes: [':ProgramWaitlist'], name: 'programWaitlist'
}

);
module.exports = {
GDBProgramWaitlistModel
}
16 changes: 16 additions & 0 deletions backend/models/program/programWaitlistEntry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const {createGraphDBModel, DeleteType, Types} = require("graphdb-utils");
const {GDBProgramRegistrationModel} = require("../programRegistration");

const GDBProgramWaitlistEntryModel = createGraphDBModel({
programRegistration: {type: GDBProgramRegistrationModel, internalKey: ':hasProgramRegistration'},
priority: {type: Number, internalKey: ':hasPriority'},
date: {type: Date, internalKey: ':hasDate'},
},
{
rdfTypes: [':ProgramWaitlistEntry'], name: 'programWaitlistEntry'
}

);
module.exports = {
GDBProgramWaitlistEntryModel
}
3 changes: 2 additions & 1 deletion backend/models/programRegistration.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {createGraphDBModel, DeleteType, Types, getGraphDBModel} = require("graphdb-utils");
const {createGraphDBModel, DeleteType, Types} = require("graphdb-utils");
const {GDBProgramOccurrenceModel} = require("./program/programOccurrence");
const {GDBClientModel} = require("./ClientFunctionalities/client");
const {GDBReferralModel} = require("./referral");
Expand All @@ -13,6 +13,7 @@ const GDBProgramRegistrationModel = createGraphDBModel({
client: {type: GDBClientModel, internalKey: ':hasClient'},
referral: {type: GDBReferralModel, internalKey: ':hasReferral'},
appointment: {type: GDBAppointmentModel, internalKey: ':hasAppointment'},
status: {type: String, internalKey: ':hasRegistrationStatus'},
characteristicOccurrences: {type: [GDBCOModel], internalKey: ':hasCharacteristicOccurrence'},
address: {type: GDBAddressModel, internalKey: 'ic:hasAddress', onDelete: DeleteType.CASCADE},
}, {
Expand Down
2 changes: 2 additions & 0 deletions backend/models/service/serviceOccurrence.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const GDBServiceOccurrenceModel = createGraphDBModel({
needSatisfiers: {type: [GDBNeedSatisfierModel], internalKey: ':hasNeedSatisfier'},
// needSatisfierOccurrence: {type: [GDBNeedSatisfierOccurrenceModel], internalKey: ':hasNeedSatisfierOccurrence', onDelete: DeleteType.CASCADE},
description: {type: String, internalKey: 'cids:hasDescription'},
capacity: {type: Number, internalKey: ':hasCapacity'},
occupancy: {type: Number, internalKey: ':hasOccupancy'},
characteristicOccurrences: {type: [GDBCOModel], internalKey: ':hasCharacteristicOccurrence'}
}, {
rdfTypes: [':ServiceOccurrence'], name: 'serviceOccurrence'
Expand Down
18 changes: 18 additions & 0 deletions backend/models/service/serviceWaitlist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const {createGraphDBModel, DeleteType, Types} = require("graphdb-utils");

//These might need tweaking, need to figure out what things we need for this model
const {GDBServiceOccurrenceModel} = require("./serviceOccurrence");
const {GDBServiceWaitlistEntryModel} = require("./serviceWaitlistEntry");

const GDBServiceWaitlistModel = createGraphDBModel({
waitlist: {type: [GDBServiceWaitlistEntryModel], internalKey: ':hasWaitlist'},
serviceOccurrence: {type: GDBServiceOccurrenceModel, internalKey: ':hasServiceOccurrence'},
},
{
rdfTypes: [':ServiceWaitlist'], name: 'serviceWaitlist'
}

);
module.exports = {
GDBServiceWaitlistModel
}
16 changes: 16 additions & 0 deletions backend/models/service/serviceWaitlistEntry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const {createGraphDBModel, DeleteType, Types} = require("graphdb-utils");
const { GDBServiceRegistrationModel } = require("../serviceRegistration");

const GDBServiceWaitlistEntryModel = createGraphDBModel({
serviceRegistration: {type: GDBServiceRegistrationModel, internalKey: ':hasServiceRegistration'},
priority: {type: Number, internalKey: ':hasPriority'},
date: {type: Date, internalKey: ':hasDate'},
},
{
rdfTypes: [':ServiceWaitlistEntry'], name: 'serviceWaitlistEntry'
}
);

module.exports = {
GDBServiceWaitlistEntryModel
}
1 change: 1 addition & 0 deletions backend/models/serviceRegistration.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const GDBServiceRegistrationModel = createGraphDBModel({
client: {type: GDBClientModel, internalKey: ':hasClient'},
referral: {type: GDBReferralModel, internalKey: ':hasReferral'},
appointment: {type: GDBAppointmentModel, internalKey: ':hasAppointment'},
status: {type: String, internalKey: ':hasRegistrationStatus'},
characteristicOccurrences: {type: [GDBCOModel], internalKey: ':hasCharacteristicOccurrence'},
address: {type: GDBAddressModel, internalKey: 'ic:hasAddress', onDelete: DeleteType.CASCADE},
}, {
Expand Down
31 changes: 31 additions & 0 deletions backend/services/characteristics/predefined/general.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,35 @@ module.exports = [{
fieldType: FieldTypes.NumberField,
},
},
{
name: 'Capacity',
description: 'The capacity of a program or service occurrence.',
predefinedProperty: 'http://snmi#hasCapacity',
implementation: {
label: 'Capacity',
valueDataType: 'xsd:number',
fieldType: FieldTypes.NumberField,
},
},
{
name: 'Occupancy',
description: 'The current occupancy of a program or service occurrence.',
predefinedProperty: 'http://snmi#hasOccupancy',
implementation: {
label: 'Occupancy',
valueDataType: 'xsd:number',
fieldType: FieldTypes.NumberField,
},
},
{
name: 'Registration Status',
description: 'The status of a program or service registration.',
predefinedProperty: 'http://snmi#hasRegistrationStatus',
implementation: {
label: 'Registration Status',
valueDataType: 'xsd:string',
fieldType: FieldTypes.SingleSelectField,
optionsFromClass: ':RegistrationStatus'
}
},
]
74 changes: 74 additions & 0 deletions backend/services/characteristics/predefined/internalTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,80 @@ module.exports = [
}
},

// below are for service waitlist
{
name: 'waitlistForServiceWaitlist',
predefinedProperty: 'http://snmi#hasWaitlist',
formType: 'serviceWaitlist',
implementation: {
label: 'Waitlist',
valueDataType: 'owl:NamedIndividual',
fieldType: FieldTypes.MultiSelectField,
optionsFromClass: 'http://snmi#ServiceWaitlistEntry'
}
},
{
name: 'serviceOccurrenceForServiceWaitlist',
predefinedProperty: 'http://snmi#hasServiceOccurrence',
formType: 'serviceWaitlist',
implementation: {
label: 'Service Occurrence',
valueDataType: 'owl:NamedIndividual',
fieldType: FieldTypes.SingleSelectField,
optionsFromClass: 'http://snmi#ServiceOccurrence'
}
},

// below are for service waitlist entry
{
name: 'serviceRegistrationForServiceWaitlistEntry',
predefinedProperty: 'http://snmi#hasServiceRegistration',
formType: 'serviceWaitlistEntry',
implementation: {
label: 'Service Registration',
valueDataType: 'owl:NamedIndividual',
fieldType: FieldTypes.SingleSelectField,
optionsFromClass: 'http://snmi#ServiceRegistration'
}
},

// below are for program waitlist
{
name: 'waitlistForProgramWaitlist',
predefinedProperty: 'http://snmi#hasWaitlist',
formType: 'programWaitlist',
implementation: {
label: 'Waitlist',
valueDataType: 'owl:NamedIndividual',
fieldType: FieldTypes.MultiSelectField,
optionsFromClass: 'http://snmi#ProgramWaitlistEntry'
}
},
{
name: 'programOccurrenceForProgramWaitlist',
predefinedProperty: 'http://snmi#hasProgramOccurrence',
formType: 'programWaitlist',
implementation: {
label: 'Program Occurrence',
valueDataType: 'owl:NamedIndividual',
fieldType: FieldTypes.SingleSelectField,
optionsFromClass: 'http://snmi#ProgramOccurrence'
}
},

// below are for program waitlist entry
{
name: 'programRegistrationForProgramWaitlistEntry',
predefinedProperty: 'http://snmi#hasProgramRegistration',
formType: 'programWaitlistEntry',
implementation: {
label: 'Program Registration',
valueDataType: 'owl:NamedIndividual',
fieldType: FieldTypes.SingleSelectField,
optionsFromClass: 'http://snmi#ProgramRegistration'
}
},

// below are for program Provision
{
name: 'needOccurrenceForProgramProvision',
Expand Down
28 changes: 27 additions & 1 deletion backend/services/genericData/checkers.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
const {GDBCharacteristicModel} = require("../../models");
const {Server400Error} = require("../../utils");
const {PredefinedCharacteristics} = require("../characteristics");

function noQuestion(characteristics, questions) {
if (Object.keys(questions).length > 0)
throw new Server400Error('Service should not contain question.');
}

module.exports = {noQuestion}
function checkCapacityNonNegative(characteristics, questions, fields) {
const capacityId = Object.keys(characteristics).find(id => characteristics[id].name === 'Capacity');
if (!!capacityId) {
if (fields['characteristic_' + capacityId] < 0) {
throw new Server400Error('Capacity must be zero or greater.');
}
}
}

// Prevent overwriting the read-only occupancy characteristic
function unsetOccupancy(characteristics, questions, fields) {
const occupancyId = PredefinedCharacteristics['Occupancy']._id;
delete characteristics[occupancyId];
delete fields[`characteristic_${occupancyId}`];
}

async function setOccupancy(characteristics, questions, fields) {
const occupancyId = PredefinedCharacteristics['Occupancy']._id;
const occupancyCharacteristic = await GDBCharacteristicModel.findOne({_id: occupancyId},
{populates: ['implementation']});
characteristics[occupancyId] = occupancyCharacteristic;
fields[`characteristic_${occupancyId}`] = '0';
}

module.exports = {noQuestion, checkCapacityNonNegative, unsetOccupancy, setOccupancy}
Loading