diff --git a/ehr/resources/schemas/dbscripts/sqlserver/ehr-26.001-26.002.sql b/ehr/resources/schemas/dbscripts/sqlserver/ehr-26.001-26.002.sql new file mode 100644 index 000000000..73a819eb9 --- /dev/null +++ b/ehr/resources/schemas/dbscripts/sqlserver/ehr-26.001-26.002.sql @@ -0,0 +1,7 @@ +-- ehr.Project.Created and ehr.Project.Modified are NULL on SQL Server but NOT NULL on PostgreSQL. Set the NULL values +-- and switch the columns to NOT NULL to match PostgreSQL. +UPDATE ehr.Project SET Created = diCreated WHERE Created IS NULL; +UPDATE ehr.Project SET Modified = diModified WHERE Modified IS NULL; + +ALTER TABLE ehr.Project ALTER COLUMN Created DATETIME NOT NULL; +ALTER TABLE ehr.Project ALTER COLUMN Modified DATETIME NOT NULL; diff --git a/ehr/src/org/labkey/ehr/EHRModule.java b/ehr/src/org/labkey/ehr/EHRModule.java index 0f7e34ab1..acb836e9e 100644 --- a/ehr/src/org/labkey/ehr/EHRModule.java +++ b/ehr/src/org/labkey/ehr/EHRModule.java @@ -135,7 +135,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 26.001; + return 26.002; } @Override diff --git a/ehr_billing/api-src/org/labkey/api/ehr_billing/pipeline/InvoicedItemsProcessingService.java b/ehr_billing/api-src/org/labkey/api/ehr_billing/pipeline/InvoicedItemsProcessingService.java index 29d3d1648..10315da25 100644 --- a/ehr_billing/api-src/org/labkey/api/ehr_billing/pipeline/InvoicedItemsProcessingService.java +++ b/ehr_billing/api-src/org/labkey/api/ehr_billing/pipeline/InvoicedItemsProcessingService.java @@ -22,32 +22,45 @@ import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; +import org.labkey.api.module.Module; import org.labkey.api.pipeline.PipelineJobException; import org.labkey.api.query.FieldKey; import org.labkey.api.query.QueryService; import org.labkey.api.security.User; -import org.labkey.api.services.ServiceRegistry; import org.labkey.api.util.Pair; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; /** * Service to get a list of queries to be processed during a Billing Run. The listing is a collection of * BillingPipelineJobProcess objects that define what schema.query to execute and the mapping from that query's * columns to the ehr_billing.invoicedItem table's columns. * Additionally, get center specific generated invoice number. - * - * Currently registered server wide but should allow multiple co-existing services and resolve per container's active modules */ public interface InvoicedItemsProcessingService { + record Registration(String moduleName, InvoicedItemsProcessingService impl){} + + List REGISTRATION_LIST = new CopyOnWriteArrayList<>(); + + static void register(Module module, InvoicedItemsProcessingService impl) + { + REGISTRATION_LIST.add(new Registration(module.getName(), impl)); + } + @Nullable - static InvoicedItemsProcessingService get() + static InvoicedItemsProcessingService get(Container billingContainer) { - return ServiceRegistry.get().getService(InvoicedItemsProcessingService.class); + // Return the service implementation based on the registering module being active in the provided container + return REGISTRATION_LIST.stream() + .filter(reg -> billingContainer.hasActiveModuleByName(reg.moduleName())) + .map(Registration::impl) + .findFirst() + .orElse(null); } /** @return the inputs to the billing process that are capable of generating charges */ diff --git a/ehr_billing/src/org/labkey/ehr_billing/EHR_BillingController.java b/ehr_billing/src/org/labkey/ehr_billing/EHR_BillingController.java index abacf8776..031991db3 100644 --- a/ehr_billing/src/org/labkey/ehr_billing/EHR_BillingController.java +++ b/ehr_billing/src/org/labkey/ehr_billing/EHR_BillingController.java @@ -104,7 +104,7 @@ public ApiResponse execute(BillingPipelineForm form, BindException errors) throw new PipelineJobException("Cannot create a billing run with the same start and end date"); } - InvoicedItemsProcessingService processingService = InvoicedItemsProcessingService.get(); + InvoicedItemsProcessingService processingService = InvoicedItemsProcessingService.get(EHR_BillingManager.get().getBillingContainer(getContainer())); if (null != processingService) { Pair previousInvoice = processingService.verifyBillingRunPeriod(getUser(), getContainer(), form.getStartDate(), form.getEndDate()); diff --git a/ehr_billing/src/org/labkey/ehr_billing/pipeline/BillingTask.java b/ehr_billing/src/org/labkey/ehr_billing/pipeline/BillingTask.java index 908b09837..4e44bf8d5 100644 --- a/ehr_billing/src/org/labkey/ehr_billing/pipeline/BillingTask.java +++ b/ehr_billing/src/org/labkey/ehr_billing/pipeline/BillingTask.java @@ -78,11 +78,13 @@ public class BillingTask extends PipelineJob.Task { private final static DbSchema EHR_BILLING_SCHEMA = EHR_BillingSchema.getInstance().getSchema(); - private final static InvoicedItemsProcessingService processingService = InvoicedItemsProcessingService.get(); + + private final InvoicedItemsProcessingService _processingService; protected BillingTask(Factory factory, PipelineJob job) { super(factory, job); + _processingService = InvoicedItemsProcessingService.get(EHR_BillingManager.get().getBillingContainer(job.getContainer())); } public static class Factory extends AbstractTaskFactory @@ -148,16 +150,16 @@ public RecordedActionSet run() throws PipelineJobException { getOrCreateInvoiceRunRecord(); loadTransactionNumber(); - processingService.setBillingStartDate(getSupport().getStartDate()); + _processingService.setBillingStartDate(getSupport().getStartDate()); if (null != _previousInvoice) { - processingService.processBillingRerun(_invoiceId, _invoiceRowId, getSupport().getStartDate(), getSupport().getEndDate(), getNextTransactionNumber(), user, billingContainer, getJob().getLogger()); + _processingService.processBillingRerun(_invoiceId, _invoiceRowId, getSupport().getStartDate(), getSupport().getEndDate(), getNextTransactionNumber(), user, billingContainer, getJob().getLogger()); } else { - for (BillingPipelineJobProcess process : processingService.getProcessList()) + for (BillingPipelineJobProcess process : _processingService.getProcessList()) { Container billingRunContainer = process.isUseEHRContainer() ? ehrContainer : billingContainer; runProcessing(process, billingRunContainer); @@ -166,7 +168,7 @@ public RecordedActionSet run() throws PipelineJobException updateInvoiceTable(billingContainer); - processingService.performAdditionalProcessing(_invoiceId, user, container); + _processingService.performAdditionalProcessing(_invoiceId, user, container); transaction.commit(); } @@ -278,7 +280,7 @@ private String getOrCreateInvoiceRunRecord() throws PipelineJobException @Nullable private String getOrCreateInvoiceRecord(Map row, Date endDate) throws PipelineJobException { - String invoiceNumber = processingService.getInvoiceNum(row, endDate); + String invoiceNumber = _processingService.getInvoiceNum(row, endDate); if (null != invoiceNumber) { try @@ -499,25 +501,25 @@ private void runProcessing(BillingPipelineJobProcess process, Container billingR // get cost Double unitCost = ci.getUnitCost(); - procedureRow.put(processingService.getUnitCostColName(), unitCost); + procedureRow.put(_processingService.getUnitCostColName(), unitCost); // total cost Double totalCost = unitCost * (Double) procedureRow.get("quantity"); - procedureRow.put(processingService.getTotalCostColName(), totalCost); + procedureRow.put(_processingService.getTotalCostColName(), totalCost); // calculate total cost with additional/other rate (ex. tier rate for WNPRC) Double otherRate = (Double) procedureRow.get("otherRate"); Double unitCostWithOtherRate; double totalCostWithOtherRate; if (null != otherRate && - null != processingService.getAdditionalUnitCostColName() && - null != processingService.getAdditionalTotalCostColName()) + null != _processingService.getAdditionalUnitCostColName() && + null != _processingService.getAdditionalTotalCostColName()) { unitCostWithOtherRate = unitCost + (unitCost * otherRate); - procedureRow.put(processingService.getAdditionalUnitCostColName(), unitCostWithOtherRate); + procedureRow.put(_processingService.getAdditionalUnitCostColName(), unitCostWithOtherRate); totalCostWithOtherRate = unitCostWithOtherRate * (Double) procedureRow.get("quantity"); - procedureRow.put(processingService.getAdditionalTotalCostColName(), totalCostWithOtherRate); + procedureRow.put(_processingService.getAdditionalTotalCostColName(), totalCostWithOtherRate); } } writeToInvoicedItems(process, procedureRows, getSupport());