Closed josh-griffin closed 3 years ago
Potential issues:
SensorLog
class - if not needing any helper properties, move to indexSensor
class - potentially a different methodFrom PR: #1358
Some things to potentially revist, just some initial thoughts returning back to this work!
SyncModal
- Should this just be a different modal? Thinking maybe we could have a temperature icon next to the sync icon and open a TemperatureSyncModal
? CustomerRequisitionPage
- expansion: Can quite easily use something similar to the current StockPage
(Small black box coming up from the bottom with details, scrollable) - but there has been talk about have a similar more generic solution for other pages (bought up from IC requirements wanting so much extra detail, and no columns). Maybe we could come up with a solution which was generic throughout the app, which can just show some details of a row without impacting too much on the user. We could then hide a lot more detail in thereQ: Why not just merge what we already had (in exactly the same way that we had it), with code changes to fit in with new/existing data table ?
A: It's not a prototype anymore, what we merge into develop would be MVP. We have a chance to reconsider a few of the following (and we have some experience to back it up)
NOTE
: we are not thinking of migrating all data for existing prototype sites, they of course should still work (shouldn't need to reconfigure sensors/fridge), but will have different data structure and existing data might be lost (basically we want to minimise effort needed to make existing sites work and are willing to compromise loosing data in prototype sites)
Q: Same why not keep as is ? A: There is quite a bit of aggregation logic on mobile end that is perhaps excessive. It makes code digestion very difficult. Also existing way might not scale. So requirement here are:
BlueMeastro tempo disc temperature logger is quite sensitive to ambient temperature, and it's not suspended in liquid, so every time fridge is opened, temperature reading jumps to room temperature quite quickly, to avoid this we configure device to record temperature every 5 minutes and aggregated minimum temperature from 4 reading into one (so one record every 20 minutes).
We do further aggregations for temperature records that are not 'in breach' (every 8 hours take max and min temperature log).
There is another table, sensorLogItemLineJoin, which is a join of each itemLines temperature expose
We don't currently clean up temperature logs (sensorLogs).
We only have two VVM statuses (fail pass, ass oppose to 4 stages of VVM)
VVM Status changes are recorded via transactions.
Prerequisite
-> How does UI performs when displaying the same graph but data is aggregated on the go ? (instead of aggregating daily max mins from 8 hour intervals, aggregating a whole month worth of 30mins intervals)
TODO, below is just summary write it out, and who are the stakeholders here, should we ask the actual users ?
Notes:
First aggregation should be every 30 mins ?
Yup. Shouldn't change to much with this alone so can lock it in I reckon.
Have two tables (rather then status) for sensorLogs table ?
Don't think we talked about this but I think it's a good idea. What would you call them, though? 🤣
Have historic VVM status item batch table (duplicate record if batch is split)
Definitely. First thoughts:
Have historic location item batch table (duplicate records if batch is split)
Definitely. First thoughts:
StoreID
on the batch? Location?Above table makes sensorLogItemLineJoin obsolete Wipe temperature log data Renaming tables -> sensorLogs to temperatureLogs ?
Makes sense to me
Item
as a vaccine better then current way.
Personally I don't like using "type" string fields - but I think its maybe the best way?UI
Vaccine specific stock take (which is the manage stock page in vaccine module, but 'batch grained')
So just making just the one page with rows as per batch. Don't show vaccines in normal stocktake page (when vaccine module enabled)
Breach modal, do we really need affected batches there ?
nope! 🤣
VVM stages, can you choose from list of VVM stages as per the VVM ?
Will be wicked - I don't wanna make svg's though 🤣
Do we want buttons in Vaccine Module that do the same thing as in navigator ?
I don't!
Actions that I can see to take from here:
SensorLog
renamingLocationLog
instead of SensorLogItemLineJoin
VVMStatus
log tableSensorLog
tablesBreachModal
SyncModal
I think thats it?
I think if there are decisions we are not 100% on, we can make the decision now by taking the path of the least work? i.e. breach modal and item batches -> no batches (less work)?
Thanks Josh, that list of actionables look pretty complete, we can't forget about the desktop Tupaia push though (i guess that's under Determine if any desktop decisions have been made
), it would be good to add that to a list of today's discussions.
UPDATE:
SensorLog
rename to TemperatureLog
SensorLogItemLineJoin
replaced with a location log tableVVM Status
table for a batchSensorLogs
split into three tables: RawSensorLog
, TemperatureLog
and BreachLog
RawSensorLog
to TemperatureLog
)isVaccine
field on Item
BreachModal
doesn't need to display item batches in a breach anymoreTemperatureSync
modal seperate from the regular SyncModal
. Adding an additional button in the NavigationBar
when vaccines are enabled.TemperatureLog
schemaRawSensorLog
schemaBreachLog
schemaLocation log
schemaVVM Status
schemaSchema candidates:
TemperatureLog
:
BreachLogID
field on desktopisMaxLog
or type
(max
or min
)?BreachLog
:
StartTime
and endTime
add some logic needed for potentially not much use?RawSensorLog
:
VVM Status
:
optionID
?Location log
:
optionID
?Options for calculating the exact quantity of a batch at the time of a temperature log:
ItemBatchLocationMovement
(?) record for every trans_line
for that batch, with a quantity
field on the ItemBatchLocationMovement
record.
TemperatureLog
timestamp, but before the next TemperatureLog
timestampinTime
and outTime
on the ItemBatchLocationMovement
for the time it was created and the time the next record was created. This would make finding the correct record easier.trans_line
for the batch it is for when finalising (would this work? heh) or confirmed for CI's?? I guess this doesn't work if you allow for editing stuff from before...TemperatureLog
. This might not be too bad, as you could just do a single reverse ledger for the most recent TemperatureLog
and store the quantities for all the temperature logs you're calculating for as you do a single iteration (this is what we're doing now. Except we're doing a reverse ledger for every batch, for every sensor log. Oops)EDIT: Unless we have aggregation - I believe we need to do a reverse ledger. The inTime
and outTime
will help with the query for where exactly a batch was:
Without:
ItemBatchLocationMovement
for an ItemBatch
.ItemBatchLocationMovement
of that ItemBatch
which is <
the TemperatureLog.timestamp
ItemBatchLocationMovement
from before the TemperatureLog
and take the most recent (TL1)ItemBatchLocationMovement
of that ItemBatch
for any Location
which is >
the TemperatureLog.timestamp
[Is the batch in another location]ItemBatchLocationMovement
from after the TemperatureLog
and take the oldest (TL2).
.ItemBatchLocationMovement
which is >= the time on TL1 and < TL2With:
ItemBatchLocationMovement
whos inTime
<= TemperatureLog.timestamp
and outTime
> TemperatureLog.timestamp
outTime
of the most recent ItemBatchLocationMovement
with the current time when creating a new ItemBatchLocationMovement
Have done a bit of a brain dump here: https://drive.google.com/file/d/1AGvM3oC1KcOf5ko4U94iDVBz1jZ4tCWo/view?usp=sharing
Will clean it up and put it in a doc
Some more questions:
Sensor
link to BOTH the RawSensorLog
AND TemperatureLog
? Or is finding the TemperatureLog
through the Location
all good? Then should we just remove currentTemperature
on Sensor
and derive that from the TemperatureLog
s?Location
field on BreachLog
? I think it's maybe a bit nicer than getting it through the TemperatureLog
s?or with X = 30
X = 50
X = 50 is about where it starts to slow down quite a bit. Wouldn't really want to go past about X = 75.
@andreievg
Regarding the current plan with locations and vvm status': (Just using VVM status as an example, although it applies similarly for Locations)
ItemBatch
has many related VaccineVialMonitorStatus
recordsStocktake
), you want to also have the ability to alter the VVM status as it arrives.TransactionBatch
recordsTransactionBatch
record, you need to store the VVM Status against the TransactionBatch
- and then when finalising, make the change to the underlying ItemBatch
record.So the question: What do you store against the TransactionBatch
. A VaccineVialMonitorStatus
? If you do, you need a TransactionBatchID
and StocktakeBatchID
on the VaccineVialMonitorStatus
schema. Just create a VaccineVialMonitorStatus
for the underlying ItemBatch
even before finalizing? Doesn't seem quite right.. Maybe a VVMStatus
string field on StocktakeBatch
and TransactionBatch
? Seems pretty hacky? Could have an additional table.. which stores a VVM Status (i.e. would have 4 system data records for level 1, 2, 3, 4. Then the TransactionBatch
is related to that record, and when finalized you can create the log record safely. Essentially this is what would happen with Location
s.
Example:
Unfortunately this is slightly more complicated than initially discussed, but I think it's a pretty robust and flexible design!
@joshxg, would status
on VaccineVialMontiorStatusLog
would also solve the problem ?
@andreievg I dont see how, sorry?
@joshxg, very true, I should have explained better. Was kind of meaning put some sort of status on VaccineVialMonitorStatusLog to know it's 'active' or 'finalised', (not sure if we need the intermediary table in that case). But while thinking on that front, the itemBathId could be null until transaction/stocktakeBatch is finalised.
Something like this:
What do you think ? (reduces redundancy ?)
I think this is described in my comment above but you still need a StocktakeBatchID
and TransactionBatchID
FK's on VaccineVialMonitorStatusLog
(I mean sure you can have them without but that is starting to get quite hacky) then you don't really need the level
.
But IMO this is a lot of messing around to avoid adding a table. It's very similar to aggregation
field on original SensorLog
imo.
I think it's more complicated and doesn't reduce redundancy at all - actually with the two extra ID fields increases redundancy. I think on the surface it seems less complicated because there is one less table, but I think it's more complicated because it's not very intuitive and is fighting against a relational data model in a relation database?
Hmm, now i am confused. Why do you need StocktakeBatchID
and TransactionBatchID
, if StocktakeBatch and TransactionBatch related to VVMStatusLog via vaccineVialMonitorStatusLog
(would be vaccineVialMonitorStatusLogID
on server) ?
I am not seeing the difference between relating Stocktake/TransactionBatch to VaccineVialMonitorStatus
vs VaccineVialMonitorStatusLog
ohh right so the itemBatch
is null
, until after the status changes then the itemBatch
gets assigned. I thought it would be assigned to the transactionBatch
or StocktakeBatch
and then a new one for the ItemBatch
.. so I thought it would need to be assigned to at least one thing.
Ok, so yeah I suppose you don't need a TransactionBatchID
or StocktakeBatchID
- I still think this is quite a lot more complicated then my solution (I think evidence is us both getting confused!) Once we start getting into this status fields and assigning nulls etc it really doesn't become simpler - if that's the goal of the alternative then I don't think it's worth it?
I actually misinterpreted your original solution, was just writing to comment further and looked at it again, yeah your solution sounds like a good way to do it.
@andreievg
Couple of things for clarification
Let me know what you think with the following:
Location_type
[I think you've expressed concerns about this]
Location_type.config
field to store { maxBreach: { minTemp, duration, maxTemp }, minBreach: {minTemp, duration, maxTemp } }
vaccine_fridge
or something?Item
isVaccine
field for vaccine items (upgrade code to set this??)For identification of breach
I am still not 100% sure when to use object fields vs tables tbh, saying that though it's a lot quicker to just add a config field. Either way i think instead of maxBreach
and minBreach
it should just be an array of fromTemp, toTemp (or minTemp and maxTemp) <- the reason being we can be flexible if another 'breach' criteria is added (i.e. temp goes way way high or low, duration can be minimal)
So two options I think:
Table temperatureBreachConfiguration
? (locationTypeID
, minTemp, maxTemp, duration)
Object on locationType
.
Kind of leaning toward structured approach now (with tables)
Location_type
I think I was concerned because l was still thinking about prototype. There was no way to select a location type when fridge was created. And I think there was a search on locations where location type has description with fridge
in it (and only those locations are shown as options for vaccine item).
I guess the issue for me is how do we link items with suitable locations. There is a mechanism for this in Desktop right now, but that uses item_store_join.restricted_location_type_id, so needs to be configured per store per item, not ideal in my view, would rather add restrictedLocationTypeID
to actual 'item' table ? (would require assigning item a location type after desktop is upgraded, and resyncing items with location type to mobile when mobile is upgraded)
If we add locationType for a fridge in migration code, then when 'isVaccine' is chosen for a vaccine, we can make sure it is auto assigned a locationType
Btw I see no use cases where item_store_join.restricted_location_type_id needs to be used for item (wonder why it's done that way)
Item is Vaccine Sound like isVaccine is a good option, not sure if we can do migration for this, i think it would need to be manually configured by user and of course when mobile is upgraded make sure to resync items with isVaccine = true.
For identification of breach
oo I like the table for breach identification.
The only thing I am thinking of where there might be something to solve is for example determining a hot/cold breach to be able to colour the line on the breach red or blue? The only solution here I think is to hard code a temperature value .. lets say.. 5 - and then if the temperature is under 5, use a blue line, otherwise red.
We couldn't use a code
or something as I guess these are user-defined on the server, so we don't know the code? Oooor, we can do some hardcoding and say that a breach config must be a 'hot' or 'cold' breach, maybe allow each config to choose a colour..? [Brings up a very interesting discussion about having tables/records be 'user-defined', but having hard-coded records .. i.e. invad [name]
]
Location_type
Before I respond to this I think I need some more info on what you mean by "I guess the issue for me is how do we link items with suitable locations. "
Item is Vaccine
Cool - my reservation with this is just 'when does it stop' .. i.e. do we have isPill
, isLiquid
, isMaterial
, isPlastic
.. etc (maybe these are bad examples but hopefully you understand!) .. so I don't know when to 'stop'.. but I think the only way to stop this is to have a itemCategoryZZZ
field (another one) which is hardcoded itemCategoryZZZ
records..?
Wow color in the breachConfig ! That's a great idea, I was just thinking we use the Temperature_min and Temperature on location_type to figure it out but I am pretty sure it would work well if we add color to breachConfig. (btw breachConfig can be assigned to the 'breach').
Brings up a very interesting discussion about having tables/records be 'user-defined', but having hard-coded records
Yeah, although in this case it's maybe 'pre-defined' rather then hard-coded ?
Cool - my reservation with this is just 'when does it stop' .. i.e. do we have isPill, isLiquid, isMaterial, isPlastic .. etc (maybe these are bad examples but hopefully you understand!) .. so I don't know when to 'stop'.. but I think the only way to stop this is to have a itemCategoryZZZ field (another one) which is hardcoded itemCategoryZZZ records..?
I guess what we are trying to do is add a behaviour to this particular item. Awhile ago I as thinking of a structure where most of those properties are controlled by a 'tag' and there would be user defined 'tags' and hard coded tags that alter app behaviour. You could also have 'tag' category, where only one tag out of a group that can be attached to an entity (i.e. unit/or form) (but i think that's getting off topic, isVaccine should be sufficient for now)
Before I respond to this I think I need some more info on what you mean by "I guess the issue for me is how do we link items with suitable locations. "
So, a where house can have multiple locations and multiple location types, i.e. in Vanuatu there are currently two location_types ('safe' and 'fridge'). Consider a small warehouse with multiple fridges and a safe and a shelves. We have 'vaccines' that go into fridges only, we have things like 'morphine' that needs to be kept in a safe, and everything else can go in other locations. Usually locations are used to identify where 'things' are in on a rack, so that the picker knows where to look for things or where to place things. So potentially there could be quite a few locations of different 'location_types', so how do we know what list to have in UI when choosing location for a batch ? (in mobile VM prototype we currently look for location with locationType.description contains fridge, that's pretty hacky, so thought if we could associated item with a locationType, then it becomes pretty easy and structure
ok sweet!
Item.isVaccine
✅ TemperatureBreachConfiguration
: (locationTypeID, minTemp, maxTemp, duration, colour)
✅ what list to have in UI when choosing location for a batch
ahhh ok - I'm a bit slow but I understand now!
Sounds like another need for a bulk config setting interface :trollface: Where are most of the fields for item_store_join
even edited? I like the default_location_id
field.. that could be super nice.
I think in general it might actually be a bit better to set a lot of details on a per-store basis.. except.. sync and the amount of records it creates.. :( The bright side being (hopefully, I haven't checked) that item_store_join
surely only syncs to the sites where the store is? Buut.. on second thought - I suppose item_store_join
is store data? so it shouldn't be edited on the server? I was thinking you could just have an object in desktop in the [item]input
form and that would update all the item_store_join
records.. then you can edit them individually on a store/satellite, if you need. That would give the greatest flexibility, but also breaks 'sync rules' :(
I think it's a really good idea.. should probably try to use the item_store_join
way since its there already? Maybe a default_location_type
on item
could help?
No sync rules broken btw, even though item_store_join
is store specific, they are like preferences, controlled by main server.
So the confusion for me is, item
is editable on server, but some things in the item input are actually for currently logged in store:
check out bottom of the screenshot, this is how you set item_store_join.restricted_location_type_id
in desktop:
Sounds like another need for a bulk config setting interface
You are on point, not slow at all.
was thinking you could just have an object in desktop in the [item]input form and that would update all
Great, so if you look at the screenshot, if Restricted to
is changed to Restricted to in Store {current store name}:
and then add another one Restricted to in All Stores:
Maybe a default_location_type on item could help?
Perhaps should be named default_restricted_location_type ? That would be that one Restricted to in All Stores:
?
If we want to overwrite the default one, then we can set Restricted to in Store..
in item.input, which will set it on item_store_join.
And in UI, when we select location, we first look at item_store_join, then item ?
There is actually very limited places where this is used in mSupply desktop, so easy to change.
All sounds really good to me!
And in UI, when we select location, we first look at item_store_join, then item ?
Just this one: Would it be easier that when you change Restricted to in all stores
- that this updates all [item_store_join]
for the item
? Then, when you make a new item_store_join
when you add visibility, the default is to have the item.default_restricted_location_type
be set to the new item_store_join
?
So I am having trouble communicating the difference so hopefully this all makes sense. But basically from what I understand your suggesting:
AllStores
just changes item.restricted..
item_store_join
have item_store_join.restricted..
set to the item.restricted..
.ForStore
changes item_store_join
I think making it so
AllStores
just changes item.restricted..
AND changes all item_store_join.restricted
to the new locationType
. This is because I think the use cases are
For 1 - if you have some stores who have set a location type themselves, then to change it for everyone you have to change it individually for every store if you don't change the item_store_join
when you change the all stores
location type. For 2 - If you change it for everyone, it means everyone - so to change it again for individual stores you have to go back and change it again.
Hopefully that makes sense? Also there is the added benefit of only ever checking item_store_join
, rather than item_store_join
then item
I guess the question is:
Yes -> Then have to do it the way i've described No -> Don't technically need a field on item or another drop down, just "Apply location restriction to all stores" button/checkbox ?
Or we can combine both methods, in that case, two drop downs and a checkbox. What you reckon ?
"Do we want to persist individually configured item_store_join settings when changing the global item one ?"
ugh that's the sentence I was trying to write in my paragraphs 🤣
I think your idea for the checkbox is nice - or a pref? Or just a dialog when changing in the interface..? "Do you want to apply this change to all stores?" Then we can still just use the item_store_join
I guess the simplest would be a dialog, when value in list box changes.
@andreievg
Just been thinking about doses column again.. we said don’t have it adjust quantity and quantity not to adjust doses or enforce limits etc other than what we have now. I'm thinking if we don't, we will need to show an amount of doses column, won't we?
@joshxg, how hard would it be to add an on focus change event (on top of on data change)?
Actually what I was thinking about won't help, am i correct to say that on focus change fires after on button click (if say you change quantity and without exiting the cell press finalise) ?
@andreievg
yup it'll be the same behaviour as what it used to be - button click before on losing focus. I think having two columns which are 'dependent' or 'coupled' is really annoying.. same thing for reasons.. and even the stocktake item/batch quantity columns .. it's not the greatest user experience :(
Trying to think a little outside the box on this one.. the 'easy' solutions are for a 'doses' column to show the item.doses
field, or to 'couple' the columns... What about if the quantity column is actually for doses for a vaccine item? So you enter number of doses and it sets doses
, but also sets numberOfPacks
equal to the minimum number of packs...? For example, 2 doses per vial.. enter 17
.. doses
is set to 17
and numberOfPacks
set to 9
.. but only display 17
.. so just one column?
Or.. the little bottom modal popup thing that we use on the current stock page (and soon to be requisition page), could show the item.doses
rather than showing a column? Or, it could show numberOfPacks
for a vaccine item if the normal column was actually for doses for a vaccine item...?
hmm, I like where you going but the main idea behind doses during issue was to be able to figure out 'open vial wastage', or how many doses were actually used for a vial. I remember our main issue was with minimum doses = numberOfPacks (say 10 doses per quantity), so when you enter quantity = 10, and then enter like 100 doses, but want to change to say 19 doses, it goes all haywire (when zero is removed, it would go to 1, which would be auto set to 10, which is the minimum number of doses for quantity 10).
Maybe we don't worry about minimum doses, just restrict by max ? So then the idea would be: when quantities are changed, change doses to dose per vial * quantity, when doses are changed, restrict max allowed doses per quantity, but don't worry about minimum ?
Most vaccines btw are 1 vial = 1 dose, there are a couple with more then 1, say BCG = 10 doses per vial.
I think having two columns which are 'dependent' or 'coupled' is really annoying
I agree, what you reckon, in ideal world when one tries to finalise and things are missing or incorrect, each 'wrong' thing is highlighted, with maybe exclamation mark you can press (when you press it it tells you what is wrong) ?
Maybe we don't worry about minimum doses, just restrict by max ?
Yeah that'll work too, nice.
I agree, what you reckon, in ideal world when one tries to finalise and things are missing or incorrect, each 'wrong' thing is highlighted, with maybe exclamation mark you can press (when you press it it tells you what is wrong) ?
even showing the indication that something is wrong after losing focus is good, I think!
@andreievg
Do you think auto-applying a vvm status is a good idea? We have added a level
field - so maybe applying the lowest level
vvm status after batches are synced for a SI
, and when adding a StocktakeBatch
/TransactionBatch
, auto-apply it there?
@joshxg, sounds good to me.
Update:
@joshxg off for the remainder of this week and part-time for a bit, so will go ahead and pick up the remaining mobile issues.
@Chris-Petty going to take care of the main desktop UI: https://github.com/sussol/msupply/issues/6089, https://github.com/sussol/msupply/issues/6116.
To ensure sufficient time and to ensure compatibility, all vaccines work is targetted for desktop v12
, as the PR deadline for v11
is too close. This gives plenty of time for development + testing + documentation.
I'm so sick of this issue - I'm gonna close and use #3161 for new additions..!
Description
Vaccine module integration and slight refactor into current develop
Previous epic: https://github.com/sussol/org-issues/issues/23
Context
The Vaccine module was never merged into the code base, and now the current branch is very far behind master. Needs to be redone. It is in production in Solomon Islands and Vanuatu.
Update (13/05):
Vaccines is the main feature for
v6
. Main feature branch merged intodevelop
to get everything up-to-date and to get a head start on integration testing. All future vaccines work should be based off/merged intodevelop
.INFORMATION
Vaccine work has been merged into the main
develop
branch.Old feature branches:
TAG which is deployed in Vannuatu & Solomon Islands: https://github.com/openmsupply/mobile/commits/v2.2.0-RC4
TASKS
I've written the issues quite vague and non-specific as more specific details may not be needed dependent on the tissue and reviewer. Can provide far greater detail on a specific issue when needed!!
Tasks will be separated between back-end logic and front-end UI to try to avoid as much blocking as possible. Setup issues should likely all be done before others.
Each grouping will most likely need to be done roughly in this order
SETUP
LocationType
&Sensor
typesLocation
&ItemBatchLocationMovement
data typesItem
&..Batch
data types fordoses
VaccineVialMonitorStatus
&VaccineVialMonitorStatusLog
data typesBACKEND
Sensor
methodsItem
methodsItemBatch
methodsStocktakeBatch
methodsTransactionBatch
methodsLocation
methodsBreachLog
methodsFRONTEND
HazardPoint
widgetVaccineVialMonitorStatus
iconsFridgeDisplay
componentVaccineModuleAdminPage
componentVaccineModulePage
componentBreachModal
componentTemperatureSyncModal
componentDESKTOP
TESTING
CustomerRequisitionPage
CustomerInvoicePage
SupplierInvoicePage
VaccineModulePage
VaccineAdminPage
VaccineStockPage
VaccineItemPage
DOCUMENTATION
beginnings of documentation is here:
Design documents:
To be written 'draft like' as features are completed: