Skip to content

Commit 3dd2a5c

Browse files
authored
Add MCC feature to remove missing IDs (#93)
* Function to identify missing MCC IDs
1 parent aabeb71 commit 3dd2a5c

File tree

3 files changed

+201
-11
lines changed

3 files changed

+201
-11
lines changed

mcc/resources/web/mcc/panel/MccImportPanel.js

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,14 @@ Ext4.define('MCC.panel.MccImportPanel', {
652652
parsedRows: parsedRows,
653653
panel: this
654654
}
655+
},{
656+
text: 'Process Missing IDs',
657+
action: this.processMissingIds,
658+
rowData: {
659+
colArray: colArray,
660+
parsedRows: parsedRows,
661+
panel: this
662+
}
655663
}],
656664
columns: columns
657665
});
@@ -663,6 +671,143 @@ Ext4.define('MCC.panel.MccImportPanel', {
663671
}
664672
},
665673

674+
processMissingIds: function(e, dt, node, config) {
675+
Ext4.Msg.wait('Loading...');
676+
677+
var idToColony = {};
678+
var colonyToId = {};
679+
config.rowData.parsedRows.forEach(function(row){
680+
idToColony[row.Id] = row.colony;
681+
682+
if (!colonyToId[row.colony]) {
683+
colonyToId[row.colony] = [];
684+
}
685+
686+
colonyToId[row.colony].push(row.Id);
687+
});
688+
689+
var missingIds = []
690+
var multi = new LABKEY.MultiRequest();
691+
for (var colony in colonyToId) {
692+
multi.add(LABKEY.Query.selectRows, {
693+
schemaName: 'study',
694+
queryName: 'demographics',
695+
columns: 'Id,colony,objectid,lsid,calculated_status',
696+
filterArray: [
697+
LABKEY.Filter.create('colony', colony, LABKEY.Filter.Types.EQUAL),
698+
LABKEY.Filter.create('calculated_status', 'Alive', LABKEY.Filter.Types.EQUAL),
699+
LABKEY.Filter.create('Id', colonyToId[colony].join(';'), LABKEY.Filter.Types.NOT_IN)
700+
],
701+
scope: this,
702+
failure: LDK.Utils.getErrorCallback(),
703+
success: function (results) {
704+
if (results.rows.length) {
705+
missingIds = missingIds.concat(results.rows);
706+
}
707+
}
708+
});
709+
}
710+
711+
multi.send(function(){
712+
Ext4.Msg.hide();
713+
if (missingIds.length) {
714+
Ext4.create('Ext.window.Window', {
715+
bodyStyle: 'padding: 5px;',
716+
width: 500,
717+
modal: true,
718+
title: 'Reconcile Census with Existing IDs',
719+
defaults: {
720+
labelWidth: 200,
721+
width: 450,
722+
},
723+
items: [{
724+
html: 'The following IDs are listed for the indicated colony, but were not in your census. Choose any status updates and hit submit:',
725+
border: false,
726+
style: 'padding-bottom: 10px;'
727+
},{
728+
layout: 'table',
729+
border: false,
730+
columns: 2,
731+
defaults: {
732+
border: false
733+
},
734+
items: config.rowData.panel.getAnimalRows(missingIds)
735+
}],
736+
buttons: [{
737+
text: 'Update IDs',
738+
scope: this,
739+
handler: function(btn) {
740+
var updates = []
741+
btn.up('window').query('combo').forEach(function(f){
742+
if (f.getValue() && f.getValue() !== f.sourceRecord.calculated_status) {
743+
updates.push({
744+
Id: f.sourceRecord.Id,
745+
calculated_status: f.getValue(),
746+
lsid: f.sourceRecord.lsid,
747+
objectid: f.sourceRecord.objectid
748+
});
749+
}
750+
});
751+
752+
if (updates.length) {
753+
Ext4.Msg.wait('Saving...');
754+
LABKEY.Query.updateRows({
755+
schemaName: 'study',
756+
queryName: 'demographics',
757+
rows: updates,
758+
scope: this,
759+
failure: LDK.Utils.getErrorCallback(),
760+
success: function (results) {
761+
Ext4.Msg.hide();
762+
Ext4.Msg.alert('Success', 'Records updated', function(){
763+
btn.up('window').close();
764+
}, this);
765+
}
766+
});
767+
}
768+
else {
769+
Ext4.Msg.alert('No updates', 'No changes, nothing to do');
770+
btn.up('window').close();
771+
}
772+
}
773+
774+
},{
775+
text: 'Cancel',
776+
handler: function(btn) {
777+
btn.up('window').close();
778+
}
779+
}]
780+
}).show();
781+
}
782+
else {
783+
Ext4.Msg.alert('No missing IDs', 'All existing IDs from these colonies were present in this census, nothing to do');
784+
}
785+
}, this);
786+
},
787+
788+
getAnimalRows: function(missingIds) {
789+
var ret = [];
790+
Ext4.Array.forEach(missingIds, function(r){
791+
ret = ret.concat([{
792+
xtype: 'displayfield',
793+
width: 125,
794+
value: r.Id + ' / ' + r.colony
795+
},{
796+
xtype: 'ldk-simplelabkeycombo',
797+
schemaName: 'ehr_lookups',
798+
queryName: 'calculated_status_codes',
799+
displayField: 'code',
800+
valueField: 'code',
801+
forceSelection: true,
802+
sourceRecord: r,
803+
width: 100,
804+
value: r.calculated_status
805+
}]);
806+
});
807+
808+
return(ret);
809+
},
810+
666811
onSubmit: function(e, dt, node, config){
667812
Ext4.Msg.wait('Saving...');
668813
var rawData = config.rowData.parsedRows;

mcc/resources/web/mcc/window/MarkShippedWindow.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,15 +225,16 @@ Ext4.define('MCC.window.MarkShippedWindow', {
225225
}]
226226
});
227227

228-
// And also add an arrival record:
228+
// And also add an arrival record. NOTE: set the date after the departure to get status to update properly
229+
var arrivalDate = new Date(effectiveDate).setMinutes(effectiveDate.getMinutes() + 1);
229230
commands.push({
230231
command: 'insert',
231232
containerPath: targetFolder,
232233
schemaName: 'study',
233234
queryName: 'Arrival',
234235
rows: [{
235236
Id: newId,
236-
date: effectiveDate,
237+
date: arrivalDate,
237238
source: centerName,
238239
QCState: null,
239240
QCStateLabel: 'Completed',

mcc/test/src/org/labkey/test/tests/mcc/MccTest.java

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,31 @@ public class MccTest extends BaseWebDriverTest
5858
@Test
5959
public void testMccModule() throws Exception
6060
{
61-
//doRequestFormTest();
62-
//doRequestFormTestWithFailure();
61+
doRequestFormTest();
62+
doRequestFormTestWithFailure();
6363

64-
//testInvalidId();
64+
testInvalidId();
6565

6666
testAnimalImportAndTransfer();
6767
}
6868

69+
private static final String ANIMAL_DATA_HEADER = "animal ID\tprevious IDs\tsource\t\"DOB\n(MM/DD/YYYY)\"\tsex\tmaternal ID\tpaternal ID\t\"weight(grams)\"\t\"date of weight\n(MM/DD/YY)\"\tU24 status\tavailalble to transfer\tcurrent housing status\tinfant history\tfertility status\tmedical history\n";
70+
71+
private static final String ANIMAL_DATA1 = "Animal1\t\t\t7/10/2011\t0 - male\tDam1\tSire1\t382.8\t5/19/2021\t0 - not assigned to U24 breeding colony\t0 - not available for transfer\t1 - natal family group\t3 - successful rearing of offspring\t2 - successful offspring produced\t0 - naive animal\n";
72+
73+
74+
private static final String ANIMAL_DATA2 = "Animal2\t\t\t6/3/2015\t1 - female\tDam2\tSire2\t361.2\t1/28/2021\t0 - not assigned to U24 breeding colony\t0 - not available for transfer\t2 - active breeding\t3 - successful rearing of offspring\t2 - successful offspring produced\t0 - naive animal\n";
75+
76+
private static final String ANIMAL_DATA3 = "Animal3\t\t\t6/4/2015\t1 - female\tDam2\tSire2\t361.2\t1/28/2021\t0 - not assigned to U24 breeding colony\t0 - not available for transfer\t2 - active breeding\t3 - successful rearing of offspring\t2 - successful offspring produced\t0 - naive animal";
77+
6978
private void testAnimalImportAndTransfer() throws Exception
7079
{
7180
beginAt(getProjectName() + "/Colonies/SNPRC/project-begin.view");
7281
waitAndClickAndWait(Locator.tagWithText("a", "Import Excel-Based Data"));
7382
waitForElement(Locator.tagWithText("label", "Paste Data Below:"));
7483
Ext4FieldRef.getForLabel(this, "Center/Colony Name").setValue("SNPRC");
7584

76-
Ext4FieldRef.getForLabel(this, "Paste Data Below").setValue(
77-
"animal ID\tprevious IDs\tsource\t\"DOB\n(MM/DD/YYYY)\"\tsex\tmaternal ID\tpaternal ID\t\"weight(grams)\"\t\"date of weight\n(MM/DD/YY)\"\tU24 status\tavailalble to transfer\tcurrent housing status\tinfant history\tfertility status\tmedical history\n" +
78-
"Animal1\t\t\t7/10/2011\t0 - male\tDam1\tSire1\t382.8\t5/19/2021\t0 - not assigned to U24 breeding colony\t0 - not available for transfer\t1 - natal family group\t3 - successful rearing of offspring\t2 - successful offspring produced\t0 - naive animal\n" +
79-
"Animal2\t\t\t6/3/2015\t1 - female\tDam2\tSire2\t361.2\t1/28/2021\t0 - not assigned to U24 breeding colony\t0 - not available for transfer\t2 - active breeding\t3 - successful rearing of offspring\t2 - successful offspring produced\t0 - naive animal"
80-
);
85+
Ext4FieldRef.getForLabel(this, "Paste Data Below").setValue(ANIMAL_DATA_HEADER + ANIMAL_DATA1 + ANIMAL_DATA2 + ANIMAL_DATA3);
8186

8287
waitAndClick(Ext4Helper.Locators.ext4Button("Preview"));
8388
waitForElement(Locator.tagWithText("td", "Animal2").withClass("dt-center"));
@@ -180,6 +185,35 @@ private void testAnimalImportAndTransfer() throws Exception
180185
srr.getRows().forEach(row -> {
181186
Assert.assertEquals("Incorrect QCState", "Completed", row.get("QCState/Label"));
182187
});
188+
189+
// Now check status update:
190+
populateLookups("SNPRC"); //status is needed for this to work
191+
beginAt(getProjectName() + "/Colonies/SNPRC/project-begin.view");
192+
waitAndClickAndWait(Locator.tagWithText("a", "Import Excel-Based Data"));
193+
waitForElement(Locator.tagWithText("label", "Paste Data Below:"));
194+
Ext4FieldRef.getForLabel(this, "Center/Colony Name").setValue("SNPRC");
195+
196+
Ext4FieldRef.getForLabel(this, "Paste Data Below").setValue(ANIMAL_DATA_HEADER + ANIMAL_DATA1);
197+
198+
waitAndClick(Ext4Helper.Locators.ext4Button("Preview"));
199+
waitForElement(Locator.tagWithText("td", "Animal1").withClass("dt-center"));
200+
201+
waitAndClick(getButton("Process Missing IDs"));
202+
new Window.WindowFinder(getDriver()).withTitle("Reconcile Census with Existing IDs").waitFor();
203+
String comboQuery = "combo[queryName='calculated_status_codes']";
204+
Ext4ComboRef.waitForComponent(this, comboQuery);
205+
Ext4ComboRef statusCombo = _ext4Helper.queryOne(comboQuery, Ext4ComboRef.class);
206+
statusCombo.setComboByDisplayValue("Unknown");
207+
waitAndClick(Ext4Helper.Locators.ext4Button("Update IDs"));
208+
sleep(100);
209+
new Window.WindowFinder(getDriver()).withTitle("Success").waitFor();
210+
waitAndClick(Ext4Helper.Locators.ext4Button("OK"));
211+
212+
sr = new SelectRowsCommand("study", "demographics");
213+
sr.setColumns(Arrays.asList("Id", "calculated_status"));
214+
sr.setFilters(Arrays.asList(new Filter("Id", "Animal3")));
215+
srr = sr.execute(createDefaultConnection(), getProjectName() + "/Colonies/SNPRC");
216+
Assert.assertEquals("Incorrect status", "Unknown", srr.getRows().get(0).get("calculated_status"));
183217
}
184218

185219
private static class FormElement
@@ -720,6 +754,8 @@ private void doRequestFormTestWithFailure() throws Exception
720754
assertElementNotPresent(getButton("Save"));
721755
assertElementNotPresent(getButton("Submit"));
722756
assertElementNotPresent(getButton("Approve Request"));
757+
758+
stopImpersonating();
723759
}
724760

725761
private FormElement getFormElementByName(String name)
@@ -809,11 +845,19 @@ private void doSetup() throws Exception
809845
}
810846
}
811847

848+
private void populateLookups(String name)
849+
{
850+
beginAt(getProjectName() + "/Colonies/" + name + "/project-begin.view");
851+
waitAndClickAndWait(Locator.tagWithText("a", "Populate Lookups"));
852+
waitAndClick(Ext4Helper.Locators.ext4Button("Populate All"));
853+
waitForElement(Locator.tagWithText("div", "Populate Complete"));
854+
}
855+
812856
private void testInvalidId()
813857
{
814858
beginAt("/mcc/" + getProjectName() + "/animalRequest.view?requestId=foo");
815859

816-
assertElementPresent(Locator.tagWithText("div", "There is no request with id: foo"));
860+
waitForElement(Locator.tagWithText("div", "There is no request with id: foo"));
817861
}
818862

819863

0 commit comments

Comments
 (0)