Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -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> 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 c)
{
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 -> c.hasActiveModuleByName(reg.moduleName()))
.map(Registration::impl)
.findFirst()
.orElse(null);
}

/** @return the inputs to the billing process that are capable of generating charges */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(getContainer());
if (null != processingService)
{
Pair<String,String> previousInvoice = processingService.verifyBillingRunPeriod(getUser(), getContainer(), form.getStartDate(), form.getEndDate());
Expand Down
26 changes: 14 additions & 12 deletions ehr_billing/src/org/labkey/ehr_billing/pipeline/BillingTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@
public class BillingTask extends PipelineJob.Task<BillingTask.Factory>
{
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<AbstractTaskFactorySettings, Factory>
Expand Down Expand Up @@ -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);
Expand All @@ -166,7 +168,7 @@ public RecordedActionSet run() throws PipelineJobException

updateInvoiceTable(billingContainer);

processingService.performAdditionalProcessing(_invoiceId, user, container);
_processingService.performAdditionalProcessing(_invoiceId, user, container);

transaction.commit();
}
Expand Down Expand Up @@ -278,7 +280,7 @@ private String getOrCreateInvoiceRunRecord() throws PipelineJobException
@Nullable
private String getOrCreateInvoiceRecord(Map<String, Object> row, Date endDate) throws PipelineJobException
{
String invoiceNumber = processingService.getInvoiceNum(row, endDate);
String invoiceNumber = _processingService.getInvoiceNum(row, endDate);
if (null != invoiceNumber)
{
try
Expand Down Expand Up @@ -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());
Expand Down