diff --git a/resources/queries/targetedms/InstrumentBilling.sql b/resources/queries/targetedms/InstrumentBilling.sql index d9cb727f5..fba7ba8ee 100644 --- a/resources/queries/targetedms/InstrumentBilling.sql +++ b/resources/queries/targetedms/InstrumentBilling.sql @@ -32,5 +32,5 @@ SELECT ((TIMESTAMPDIFF('SQL_TSI_HOUR', StartTime, EndTime) * Fee + ir.rateType.setupFee) * PercentPayment / 100) AS AmountBilled FROM targetedms.InstrumentSchedule i -INNER JOIN targetedms.InstrumentRate ir ON i.Instrument = ir.Instrument -INNER JOIN targetedms.InstrumentUsagePayment iup ON i.Id = iup.InstrumentScheduleId \ No newline at end of file +INNER JOIN targetedms.InstrumentUsagePayment iup ON i.Id = iup.InstrumentScheduleId +INNER JOIN targetedms.InstrumentRate ir ON i.Instrument = ir.Instrument AND iup.PaymentMethod.RateType = ir.rateType \ No newline at end of file diff --git a/resources/schemas/dbscripts/postgresql/targetedms-26.000-26.001.sql b/resources/schemas/dbscripts/postgresql/targetedms-26.000-26.001.sql new file mode 100644 index 000000000..307cb822b --- /dev/null +++ b/resources/schemas/dbscripts/postgresql/targetedms-26.000-26.001.sql @@ -0,0 +1,33 @@ +-- Add FKs to Containers and delete orphaned rows +DELETE FROM targetedms.instrumentUsagePayment WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.instrumentSchedule WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.projectPaymentMethod WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.projectResearcher WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.msProject WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.instrumentRate WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.msInstrument WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.paymentMethod WHERE Container NOT IN (SELECT EntityId FROM core.Containers); +DELETE FROM targetedms.rateType WHERE Container NOT IN (SELECT EntityId FROM core.Containers); + +ALTER TABLE targetedms.instrumentUsagePayment ADD CONSTRAINT FK_InstrumentUsagePayment_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.msProject ADD CONSTRAINT FK_MSProject_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.projectResearcher ADD CONSTRAINT FK_ProjectResearcher_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.instrumentRate ADD CONSTRAINT FK_InstrumentRate_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.msInstrument ADD CONSTRAINT FK_MSInstrument_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.paymentMethod ADD CONSTRAINT FK_PaymentMethod_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.projectPaymentMethod ADD CONSTRAINT FK_ProjectPaymentMethod_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.instrumentSchedule ADD CONSTRAINT FK_InstrumentSchedule_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); +ALTER TABLE targetedms.rateType ADD CONSTRAINT FK_RateType_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId); + +-- Add a RateType column to paymentMethod, set its values (creating one if needed), and make it not null +ALTER TABLE targetedms.paymentMethod ADD COLUMN RateType INT; +ALTER TABLE targetedms.paymentMethod ADD CONSTRAINT FK_PaymentMethod_RateType FOREIGN KEY (RateType) REFERENCES targetedms.RateType(Id); + +UPDATE targetedms.paymentMethod pm SET RateType = (SELECT MIN(Id) FROM targetedms.RateType rt WHERE rt.Container = pm.Container); + +INSERT INTO targetedms.RateType (Name, Container) + SELECT DISTINCT 'Default', Container FROM targetedms.paymentMethod WHERE RateType IS NULL; + +UPDATE targetedms.paymentMethod pm SET RateType = (SELECT MIN(Id) FROM targetedms.RateType rt WHERE rt.Container = pm.Container) WHERE RateType IS NULL; + +ALTER TABLE targetedms.paymentMethod ALTER COLUMN RateType SET NOT NULL; \ No newline at end of file diff --git a/resources/schemas/targetedms.xml b/resources/schemas/targetedms.xml index ab3cba8e1..2bd32a2d8 100644 --- a/resources/schemas/targetedms.xml +++ b/resources/schemas/targetedms.xml @@ -1823,6 +1823,7 @@ text + diff --git a/src/org/labkey/targetedms/TargetedMSListener.java b/src/org/labkey/targetedms/TargetedMSListener.java index 1bca6867d..dadd3c03b 100644 --- a/src/org/labkey/targetedms/TargetedMSListener.java +++ b/src/org/labkey/targetedms/TargetedMSListener.java @@ -15,17 +15,12 @@ */ package org.labkey.targetedms; -import org.jetbrains.annotations.NotNull; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.SqlExecutor; import org.labkey.api.security.User; import org.labkey.targetedms.parser.speclib.LibSpectrumReader; -import java.beans.PropertyChangeEvent; -import java.util.Collection; -import java.util.Collections; - /** * User: vsharma * Date: 8/22/2014 @@ -33,11 +28,6 @@ */ public class TargetedMSListener implements ContainerManager.ContainerListener { - @Override - public void containerCreated(Container c, User user) - { - } - @Override public void containerDeleted(Container c, User user) { @@ -71,22 +61,15 @@ public void containerDeleted(Container c, User user) new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoQCEmailNotifications() + " WHERE Container = ?", c); new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoInstrumentNickname() + " WHERE Container = ?", c); - } - - @Override - public void containerMoved(Container c, Container oldParent, User user) - { - } - - @NotNull - @Override - public Collection canMove(Container c, Container newParent, User user) - { - return Collections.emptyList(); - } - @Override - public void propertyChange(PropertyChangeEvent evt) - { + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoInstrumentUsagePayment() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoInstrumentSchedule() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoProjectPaymentMethod() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoProjectResearcher() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoMSProject() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoInstrumentRate() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoMSInstrument() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoPaymentMethod() + " WHERE Container = ?", c); + new SqlExecutor(TargetedMSManager.getSchema()).execute("DELETE FROM " + TargetedMSManager.getTableInfoRateType() + " WHERE Container = ?", c); } } diff --git a/src/org/labkey/targetedms/TargetedMSManager.java b/src/org/labkey/targetedms/TargetedMSManager.java index 7af575ee6..2d55db0fd 100644 --- a/src/org/labkey/targetedms/TargetedMSManager.java +++ b/src/org/labkey/targetedms/TargetedMSManager.java @@ -214,6 +214,16 @@ public static SampleFileChromInfo getSampleFileChromInfo(int id, Container c) return new TableSelector(getTableInfoSampleFileChromInfo(), new SimpleFilter(FieldKey.fromParts("Id"), id).addCondition(FieldKey.fromParts("Container"), c), null).getObject(SampleFileChromInfo.class); } + public static TableInfo getTableInfoRateType() + { + return getSchema().getTable(TargetedMSSchema.TABLE_RATE_TYPE); + } + + public static TableInfo getTableInfoInstrumentRate() + { + return getSchema().getTable(TargetedMSSchema.TABLE_INSTRUMENT_RATE); + } + public String getSchemaName() { return TargetedMSSchema.SCHEMA_NAME; diff --git a/src/org/labkey/targetedms/TargetedMSModule.java b/src/org/labkey/targetedms/TargetedMSModule.java index 4b6fcec70..c68243f38 100644 --- a/src/org/labkey/targetedms/TargetedMSModule.java +++ b/src/org/labkey/targetedms/TargetedMSModule.java @@ -231,7 +231,7 @@ public String getName() @Override public Double getSchemaVersion() { - return 26.000; + return 26.001; } @Override diff --git a/src/org/labkey/targetedms/query/SimpleTargetedMSTable.java b/src/org/labkey/targetedms/query/SimpleTargetedMSTable.java index 50bc9e16f..72688f558 100644 --- a/src/org/labkey/targetedms/query/SimpleTargetedMSTable.java +++ b/src/org/labkey/targetedms/query/SimpleTargetedMSTable.java @@ -15,6 +15,7 @@ public SimpleTargetedMSTable(String name, TargetedMSSchema schema, ContainerFilt { super(schema, TargetedMSSchema.getSchema().getTable(name), cf); wrapAllColumns(true); + TargetedMSTable.fixupLookups(this); } @Override diff --git a/test/src/org/labkey/test/tests/targetedms/InstrumentSchedulingTest.java b/test/src/org/labkey/test/tests/targetedms/InstrumentSchedulingTest.java index 6afba133b..50fdd277a 100644 --- a/test/src/org/labkey/test/tests/targetedms/InstrumentSchedulingTest.java +++ b/test/src/org/labkey/test/tests/targetedms/InstrumentSchedulingTest.java @@ -111,15 +111,15 @@ private void doInit() throws IOException, CommandException InsertRowsCommand rateTypeInsert = new InsertRowsCommand("targetedms", "rateType"); rateTypeInsert.setRows(Arrays.asList( Map.of("Name", "DefaultRate", "SetupFee", 50), - Map.of("Name", "BigSpenderRate", "SetupFee", 50) + Map.of("Name", "BigSpenderRate", "SetupFee", 66) )); List> rateTypes = rateTypeInsert.execute(createDefaultConnection(), getProjectName()).getRows(); InsertRowsCommand paymentMethodInsert = new InsertRowsCommand("targetedms", "paymentMethod"); paymentMethodInsert.setRows(Arrays.asList( - Map.of("UWBudgetNumber", "1111", "Name", PAYMENT_METHOD_1), - Map.of("UWBudgetNumber", "2222", "Name", PAYMENT_METHOD_2), - Map.of("UWBudgetNumber", "3333", "Name", PAYMENT_METHOD_3) // Intentionally not associated with a project + Map.of("UWBudgetNumber", "1111", "Name", PAYMENT_METHOD_1, "RateType", rateTypes.get(0).get("Id")), + Map.of("UWBudgetNumber", "2222", "Name", PAYMENT_METHOD_2, "RateType", rateTypes.get(1).get("Id")), + Map.of("UWBudgetNumber", "3333", "Name", PAYMENT_METHOD_3, "RateType", rateTypes.get(0).get("Id")) // Intentionally not associated with a project )); List> paymentMethods = paymentMethodInsert.execute(createDefaultConnection(), getProjectName()).getRows(); @@ -142,7 +142,9 @@ private void doInit() throws IOException, CommandException InsertRowsCommand instrumentRateInsert = new InsertRowsCommand("targetedms", "instrumentRate"); instrumentRateInsert.setRows(Arrays.asList( Map.of("Instrument", instruments.get(0).get("Id"), "rateType", rateTypes.get(0).get("Id"), "fee", 100), - Map.of("Instrument", instruments.get(1).get("Id"), "rateType", rateTypes.get(1).get("Id"), "fee", 110) + Map.of("Instrument", instruments.get(0).get("Id"), "rateType", rateTypes.get(1).get("Id"), "fee", 211), + Map.of("Instrument", instruments.get(1).get("Id"), "rateType", rateTypes.get(0).get("Id"), "fee", 100), + Map.of("Instrument", instruments.get(1).get("Id"), "rateType", rateTypes.get(1).get("Id"), "fee", 330) )); List> instrumentRates = instrumentRateInsert.execute(createDefaultConnection(), getProjectName()).getRows(); } @@ -301,11 +303,12 @@ public void testSchedule() throws IOException, CommandException waitAndClickAndWait(Locator.linkWithText("Instrument billing report")); assertTextPresent("$950.00", 8); // Two rows, one for each of the two payment methods - assertTextPresent("$3,680.00", 2); + assertTextPresent("$3,350.00", 1); + assertTextPresent("$10,956.00", 1); assertTextPresent(PAYMENT_METHOD_1, 5); assertTextPresent(PAYMENT_METHOD_2, 1); - // Verify the 40/60 split - assertTextPresent("$1,472.00", "$2,208.00"); + // Verify the 40/60 split (though odd since they're different rate types) + assertTextPresent("$1,340.00", "$6,573.60"); goToDashboard(); clickAndWait(Locator.linkWithText("Monthly instrument billing report")); @@ -314,7 +317,7 @@ public void testSchedule() throws IOException, CommandException clickButton("Submit"); // Only some hours should be in the range for this billing report assertTextPresent("17.0", 2); - assertTextPresent("$748.00", "$1,122.00"); + assertTextPresent("$680.00", "$3,366.00"); } private void attemptScheduleInsertExpectingFailure(Map row, String expected) throws IOException