Skip to content

Commit

Permalink
Merge pull request #119 from OHDSI/cost-definition
Browse files Browse the repository at this point in the history
Cost definition
  • Loading branch information
bradanton authored Sep 10, 2024
2 parents 9e00212 + 4b709f8 commit b3d5e9f
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ public override Attrition Build(ChunkData data, KeyMasterOffsetManager o)
[.. conditionOccurrences], [.. procedureOccurrences], [.. observations], [.. measurements],
[.. visitOccurrences.Values], [.. visitDetails], null, [.. deviceExposure], null, null);

foreach (var c in CostRaw)
ChunkData.AddCostData(c);

Complete = true;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<QueryDefinition>
<Query>
SELECT cost_id
, cost_event_id
, cost_domain_id
, cost_type_concept_id
, currency_concept_id
, total_charge
, total_cost
, total_paid

, paid_by_payer
, paid_by_patient
, paid_patient_copay
, paid_patient_coinsurance
, paid_patient_deductible
, paid_by_primary
, paid_ingredient_cost
, paid_dispensing_fee

, payer_plan_period_id

, amount_allowed
, revenue_code_concept_id
, revenue_code_source_value
, drg_concept_id
, drg_source_value
, coalesce(po.person_id, o.person_id, d.person_id, dev.person_id, m.person_id, v.person_id) person_id
FROM {sc}.cost
left join {sc}.procedure_occurrence po on cost_domain_id = 'Procedure' and cost_event_id = po.procedure_occurrence_id
left join {sc}.observation o on cost_domain_id = 'Observation' and cost_event_id = o.observation_id
left join {sc}.drug_exposure d on cost_domain_id = 'Drug' and cost_event_id = d.drug_exposure_id
left join {sc}.device_exposure dev on cost_domain_id = 'Device' and cost_event_id = dev.device_exposure_id
left join {sc}.measurement m on cost_domain_id = 'Measurement' and cost_event_id = m.measurement_id
left join {sc}.visit_occurrence v on cost_domain_id = 'Visit' and cost_event_id = v.visit_occurrence_id
JOIN {ch_sc}._chunks ch ON ch.ChunkId = {0} AND coalesce(po.person_id, o.person_id, d.person_id, dev.person_id, m.person_id, v.person_id) = ch.PERSON_ID
order by 1
</Query>
<Costs>
<CostRawDefinition>
<PersonId>person_id</PersonId>

<Id>cost_id</Id>
<EventId>cost_event_id</EventId>
<DomainId>cost_domain_id</DomainId>
<TypeConceptId>cost_type_concept_id</TypeConceptId>
<CurrencyConceptId>currency_concept_id</CurrencyConceptId>
<TotalCharge>total_charge</TotalCharge>
<TotalCost>total_cost</TotalCost>
<TotalPaid>total_paid</TotalPaid>

<PaidByPayer>paid_by_payer</PaidByPayer>
<PaidByPatient>paid_by_patient</PaidByPatient>
<PaidPatientCopay>paid_patient_copay</PaidPatientCopay>
<PaidPatientCoinsurance>paid_patient_coinsurance</PaidPatientCoinsurance>
<PaidPatientDeductible>paid_patient_deductible</PaidPatientDeductible>
<PaidIngredientCost>paid_ingredient_cost</PaidIngredientCost>
<PaidDispensingFee>paid_dispensing_fee</PaidDispensingFee>

<PayerPlanPeriodId>payer_plan_period_id</PayerPlanPeriodId>

<AmountAllowed>amount_allowed</AmountAllowed>

<RevenueCodeConceptId>revenue_code_concept_id</RevenueCodeConceptId>
<RevenueCodeSourceValue>revenue_code_source_value</RevenueCodeSourceValue>

<DrgConceptId>drg_concept_id</DrgConceptId>
<DrgSourceValue>drg_source_value</DrgSourceValue>
</CostRawDefinition>
</Costs>
</QueryDefinition>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<ItemGroup>
<None Remove="Transformation\CDM\Batch.sql" />
<None Remove="Transformation\CDM\Definitions\Condition_occurrence.xml" />
<None Remove="Transformation\CDM\Definitions\Cost.xml" />
<None Remove="Transformation\CDM\Definitions\Death.xml" />
<None Remove="Transformation\CDM\Definitions\Device_exposure.xml" />
<None Remove="Transformation\CDM\Definitions\Drug_exposure.xml" />
Expand Down Expand Up @@ -303,6 +304,9 @@
<EmbeddedResource Include="Transformation\CDM\Definitions\Condition_occurrence.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Transformation\CDM\Definitions\Cost.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Transformation\CDM\Definitions\Death.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public interface IPersonBuilder

void AddObservationPeriod(EraEntity data);

void AddCost(Cost data);

//void Build(ChunkData chunkData);
Attrition Build(ChunkData data, KeyMasterOffsetManager offset);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class PersonBuilder : IPersonBuilder
protected List<DeviceExposure> DeviceExposureRaw = [];
protected List<DeviceCost> DeviceCostRaw = [];

protected List<Cost> CostRaw = [];

protected List<DrugExposure> DrugForEra = [];
protected List<ConditionOccurrence> ConditionForEra = [];
protected List<Note> NoteRecords = [];
Expand Down Expand Up @@ -226,6 +228,9 @@ public void Reset()

EpisodeRecords.Clear();
EpisodeRecords = null;

CostRaw.Clear();
CostRaw = null;
}

protected virtual bool AddCost(long eventId, Func<ICostV5, Cost> createCost, IEntity entity, ICostV5 entityCost)
Expand All @@ -239,6 +244,11 @@ protected virtual bool AddCost(long eventId, Func<ICostV5, Cost> createCost, IEn
return ChunkData.AddCostData(cost);
}

public void AddCost(Cost data)
{
CostRaw.Add(data);
}

public ChunkData Result => ChunkData;

public bool Complete { get; set; }
Expand Down Expand Up @@ -922,6 +932,9 @@ public virtual Attrition Build(ChunkData data, KeyMasterOffsetManager o)
AddToChunk(person, death, observationPeriods, payerPlanPeriods, drugExposures,
conditionOccurrences, procedureOccurrences, observations, measurements,
[.. visitOccurrences.Values], visitDetails, cohort, deviceExposure, notes, episode);

foreach(var c in CostRaw)
ChunkData.AddCostData(c);

Complete = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,41 @@ public object GetValue(int i)
switch (i)
{
case 0:
{
if (_enumerator.Current.Id.HasValue)
return _enumerator.Current.Id.Value;

return _offset.GetId(_enumerator.Current.PersonId,
_enumerator.Current.CostId); //TODO VisitCostOffset -> CostOffset
return _offset.GetId(_enumerator.Current.PersonId, _enumerator.Current.CostId);
}

case 1:
{
if (_enumerator.Current.Domain == "Procedure" && !_offset
.GetKeyOffset(_enumerator.Current.PersonId).ProcedureOccurrenceIdChanged)
return _enumerator.Current.EventId;

if (_enumerator.Current.Domain == "Visit" && !_offset
.GetKeyOffset(_enumerator.Current.PersonId).VisitOccurrenceIdChanged)
return _enumerator.Current.EventId;
if (_enumerator.Current.Domain == "Observation" && !_offset
.GetKeyOffset(_enumerator.Current.PersonId).ObservationIdChanged)
return _enumerator.Current.EventId;

return _offset.GetId(_enumerator.Current.PersonId, _enumerator.Current.EventId);
if (_enumerator.Current.Domain == "Drug" && !_offset
.GetKeyOffset(_enumerator.Current.PersonId).DrugExposureIdChanged)
return _enumerator.Current.EventId;

if (_enumerator.Current.Domain == "Device" && !_offset
.GetKeyOffset(_enumerator.Current.PersonId).DeviceExposureIdChanged)
return _enumerator.Current.EventId;

if (_enumerator.Current.Domain == "Measurement" && !_offset
.GetKeyOffset(_enumerator.Current.PersonId).MeasurementIdChanged)
return _enumerator.Current.EventId;

if (_enumerator.Current.Domain == "Visit" && !_offset
.GetKeyOffset(_enumerator.Current.PersonId).VisitOccurrenceIdChanged)
return _enumerator.Current.EventId;

return _offset.GetId(_enumerator.Current.PersonId, _enumerator.Current.EventId);
}
case 2:
return _enumerator.Current.Domain;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using org.ohdsi.cdm.framework.common.Builder;
using org.ohdsi.cdm.framework.common.Extensions;
using org.ohdsi.cdm.framework.common.Omop;
using System.Data;

namespace org.ohdsi.cdm.framework.common.Definitions
{
public class CostRawDefinition : EntityDefinition
{
public string TypeConceptId { get; set; }

public string EventId { get; set; }
public string DomainId { get; set; }
public string CurrencyConceptId { get; set; }
public string TotalCharge { get; set; }
public string TotalCost { get; set; }
public string TotalPaid { get; set; }


public string PaidByPayer { get; set; }
public string PaidByPatient { get; set; }
public string PaidPatientCopay { get; set; }
public string PaidPatientCoinsurance { get; set; }
public string PaidPatientDeductible { get; set; }
public string PaidIngredientCost { get; set; }
public string PaidDispensingFee { get; set; }

public string PayerPlanPeriodId { get; set; }

public string AmountAllowed { get; set; }

public string RevenueCodeConceptId { get; set; }
public string RevenueCodeSourceValue { get; set; }

public string DrgConceptId { get; set; }
public string DrgSourceValue { get; set; }


public IEnumerable<Cost> GetCost(Concept concept, IDataRecord reader,
KeyMasterOffsetManager offset)
{
var presonId = reader.GetLong(PersonId);
yield return new Cost(presonId.Value)
{
Id = reader.GetLong(Id),

PersonId = presonId.Value,
TypeId = reader.GetLong(TypeConceptId),

EventId = reader.GetLong(EventId) ?? 0,
Domain = reader.GetString(DomainId),
CurrencyConceptId = reader.GetLong(CurrencyConceptId) ?? 0,
TotalCharge = reader.GetDecimal(TotalCharge),
TotalCost = reader.GetDecimal(TotalCost),
TotalPaid = reader.GetDecimal(TotalPaid),

PaidByPayer = reader.GetDecimal(PaidByPayer),
PaidByPatient = reader.GetDecimal(PaidByPatient),
PaidPatientCopay = reader.GetDecimal(PaidPatientCopay),
PaidPatientCoinsurance = reader.GetDecimal(PaidPatientCoinsurance),
PaidPatientDeductible = reader.GetDecimal(PaidPatientDeductible),
PaidIngredientCost = reader.GetDecimal(PaidIngredientCost),
PaidDispensingFee = reader.GetDecimal(PaidDispensingFee),

PayerPlanPeriodId = reader.GetLong(PayerPlanPeriodId),

AmountAllowed = reader.GetDecimal(AmountAllowed),

RevenueCodeConceptId = reader.GetLong(RevenueCodeConceptId),
RevenueCodeSourceValue = reader.GetString(RevenueCodeSourceValue),

DrgConceptId = reader.GetLong(DrgConceptId),
DrgSourceValue = reader.GetString(DrgSourceValue)
};
}

public override IEnumerable<IEntity> GetConcepts(Concept concept, IDataRecord reader, KeyMasterOffsetManager offset)
{
throw new NotImplementedException("CostDefinitionRaw.GetConcepts()");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ public class QueryDefinition
public EpisodeEventDefinition[] EpisodeEvents { get; set; }
public ObservationPeriodDefinition[] ObservationPeriods { get; set; }

public CostRawDefinition[] Costs { get; set; }

private static readonly string[] separator = [","];

public void RowProcessed()
Expand Down Expand Up @@ -261,6 +263,11 @@ public string GetPersonIdFieldName()
return ObservationPeriods[0].PersonId;
}

if (Costs != null && Costs.Length != 0)
{
return Costs[0].PersonId;
}

throw new Exception("Cant find PersonId FieldName " + this.FileName);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
{
public class Cost(long personId)
{
public long? Id { get; set; }
public long CostId { get; set; }

public long PersonId { get; set; } = personId;
public string Domain { get; set; }
public long CostId { get; set; }

public long EventId { get; set; }

public long? TypeId { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ private void Watchdog_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
AddEntity(qd, qd.Note, reader, recordGuid, personIdsToSave);
AddEntity(qd, qd.Episodes, reader, recordGuid, personIdsToSave);
AddEntity(qd, qd.ObservationPeriods, reader, recordGuid, personIdsToSave);
AddEntity(qd, qd.Costs, reader, recordGuid, personIdsToSave);

if (reader.Paused)
break;
Expand Down Expand Up @@ -650,6 +651,15 @@ private void AddEntity(QueryDefinition queryDefinition, IEnumerable<EntityDefini
_personBuilders[op.PersonId].Value.AddObservationPeriod(op);
}
}
else if (d is CostRawDefinition)
{
foreach (var c in ((CostRawDefinition)d).GetCost(conceptDef, reader, _offsetManager))
{
if (c == null) continue;

_personBuilders[c.PersonId].Value.AddCost(c);
}
}
else
{
foreach (var entity in d.GetConcepts(conceptDef, reader, _offsetManager))
Expand Down

0 comments on commit b3d5e9f

Please sign in to comment.