Skip to content

Commit

Permalink
#main extended US018, cancel dispense and send replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
annemgold committed Jun 17, 2024
1 parent 0b7a77a commit ca4fc1e
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 62 deletions.
3 changes: 3 additions & 0 deletions Lc.Linca.Sdk.Sample/Specs/ActorCare/US007-GetOrderStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ private bool GetProposalStatus()
(results, received) = LincaDataExchange.GetProposalStatus(Connection, $"{LinkedCareSampleClient.CareInformationSystemScaffold.Data.LcIdVogelsang}");
}

// use the following line to run the sequence [01] Immerdar -> [11] Würm -> [18] Klappernder Storch -> [07] Immerdar
// (results, received) = LincaDataExchange.GetProposalStatus(Connection, $"{LinkedCareSampleClient.CareInformationSystemScaffold.Data.LcIdImmerdar001}");

if (received)
{
Console.WriteLine("Get proposal-status succeeded");
Expand Down
22 changes: 0 additions & 22 deletions Lc.Linca.Sdk.Sample/Specs/ActorDoctor/US011-PrescribeAsOrdered.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,6 @@ private bool CreatePrescriptionRecord()
{
Sequence = 1,
Text = "1 Tablette täglich",
Timing = new Timing()
{
Repeat = new()
{
Bounds = new Duration
{
Value = 1,
Code = "d",

},
Frequency = 1,
Period = 1,
PeriodUnit = Timing.UnitsOfTime.D
}
},
DoseAndRate = new()
{
new Dosage.DoseAndRateComponent()
{
Dose = new Quantity(value: 1, unit: "St")
}
}
});

// prescription.InformationSource will be copied from resource in basedOn by the Fhir server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ private bool CreatePrescriptionRecord()


MedicationRequest? proposalsGuenterNotGranpidam = proposals.Find(x => x.Subject.Reference.Contains($"{LinkedCareSampleClient.CareInformationSystemScaffold.Data.ClientIdGuenter}")
&& ! x.Medication.Concept.Coding.First().Display.Contains("Granpidam"));
&& ((x.Medication.Concept.Coding.Count == 0
&& x.Medication.Concept.Text.Contains("Salbe")) || ! x.Medication.Concept.Coding.First().Display.Contains("Granpidam")));

if (proposalsGuenterNotGranpidam != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,29 @@

namespace Lc.Linca.Sdk.Specs.ActorPharmacy;

internal class US018_Dispense : Spec
internal class US018_DispenseCancelResendDispense : Spec
{
protected MedicationDispense dispense = new();
protected string dispenseId;
protected MedicationDispense dispense1 = new();
protected MedicationDispense dispense2 = new();
protected string? dispenseId;

public const string UserStory = @"
Pharmacist Mag. Franziska Fröschl, owner of the pharmacy Apotheke 'Klappernder Storch' has
access to and permission in a pharmacist role in the LINCA system.
When he is expected to fullfil medication orders for a customer, e.g., Renate Rüssel-Olifant,
and he has a LINCA order Id to go with a purchase her care giver Susanne Allzeit just made for her,
then Mag. Andreas Amsel submits a dispense record for the order position in question
and his software will send that to the LINCA server,
When she is expected to fullfil medication orders for a customer, e.g., Renate Rüssel-Olifant,
and she has a LINCA order Id to go with a purchase her care giver Susanne Allzeit just made for her,
then Mag. Fröschl submits a dispense record for the order position in question. She recognizes a mistake,
cancels the created medication dispense and submit another dispense with adjusted medication, quantity and note,
and her software will send that to the LINCA server,
and notify the ordering organization, Pflegedienst Immerdar, about the thus completed order position.";

public US018_Dispense(LincaConnection conn) : base(conn)
public US018_DispenseCancelResendDispense(LincaConnection conn) : base(conn)
{
Steps = new Step[]
{
new("Create MedicationDispense", CreateMedicationDispenseRecord),
new("Cancel MedicationDispense", CancelMedicationDispenseRecord)
new("Cancel MedicationDispense", CancelMedicationDispenseRecord),
new("Create replacement MedicationDispense", CreateReplacementMedicationDispenseRecord),
};

}
Expand Down Expand Up @@ -62,14 +65,14 @@ private bool CreateMedicationDispenseRecord()
return (false);
}

dispense.AuthorizingPrescription.Add(new()
dispense1.AuthorizingPrescription.Add(new()
{
Reference = $"LINCAPrescriptionMedicationRequest/{LinkedCareSampleClient.CareInformationSystemScaffold.Data.PrescriptionIdRenateLasix}"
});

dispense.Status = MedicationDispense.MedicationDispenseStatusCodes.Completed;
dispense.Subject = prescriptionRenateLasix!.Subject;
dispense.Medication = new()
dispense1.Status = MedicationDispense.MedicationDispenseStatusCodes.Completed;
dispense1.Subject = prescriptionRenateLasix!.Subject;
dispense1.Medication = new()
{
Concept = new()
{
Expand All @@ -85,29 +88,15 @@ private bool CreateMedicationDispenseRecord()
}
};

dispense.Quantity = new() { Value = 1 };
dispense1.Quantity = new() { Value = 3 };

dispense.DosageInstruction.Add(new Dosage()
dispense1.DosageInstruction.Add(new Dosage()
{
Sequence = 1,
Text = "1 Tablette täglich",
Timing = new Timing()
{
Repeat = new()
{
Bounds = new Duration
{
Value = 1,
Code = "d"
},
Frequency = 1,
Period = 1,
PeriodUnit = Timing.UnitsOfTime.D
}
}
});

dispense.Performer.Add(new()
dispense1.Performer.Add(new()
{
Actor = new()
{
Expand All @@ -120,15 +109,15 @@ private bool CreateMedicationDispenseRecord()
}
});

dispense.Type = new()
dispense1.Type = new()
{
Coding = new()
{
new Coding(system: "http://terminology.hl7.org/CodeSystem/v3-ActCode", code: "FFC")
}
};

(var postedMD, var canCue, var outcome) = LincaDataExchange.CreateMedicationDispense(Connection, dispense);
(var postedMD, var canCue, var outcome) = LincaDataExchange.CreateMedicationDispense(Connection, dispense1);

if (canCue)
{
Expand Down Expand Up @@ -183,4 +172,107 @@ private bool CancelMedicationDispenseRecord()
return false;
}
}

private bool CreateReplacementMedicationDispenseRecord()
{
LinkedCareSampleClient.CareInformationSystemScaffold.PseudoDatabaseRetrieve();

(Bundle orders, bool received) = LincaDataExchange.GetPrescriptionToDispense(Connection, "ASDFGHJ4KL34");

if (received)
{
List<MedicationRequest> prescriptionsToDispense = BundleHelper.FilterPrescriptionsToDispense(orders);

MedicationRequest? prescriptionRenateLasix = prescriptionsToDispense.Find(x => x.Medication.Concept.Coding.First().Display.Contains("Lasix"));

if (prescriptionRenateLasix != null)
{
LinkedCareSampleClient.CareInformationSystemScaffold.Data.PrescriptionIdRenateLasix = prescriptionRenateLasix.Id;
LinkedCareSampleClient.CareInformationSystemScaffold.PseudoDatabaseStore();
}
else
{
Console.WriteLine("Linca PrescriptionMedicationRequest for Renate Rüssel-Olifant not found, replacement-LINCAMedicationDispense cannot be created");

return (false);
}

dispense2.AuthorizingPrescription.Add(new()
{
Reference = $"LINCAPrescriptionMedicationRequest/{LinkedCareSampleClient.CareInformationSystemScaffold.Data.PrescriptionIdRenateLasix}"
});

dispense2.Status = MedicationDispense.MedicationDispenseStatusCodes.Completed;
dispense2.Subject = prescriptionRenateLasix!.Subject;
dispense2.Medication = new()
{
Concept = new()
{
Coding = new()
{
new Coding()
{
Code = "1336328",
System = "https://termgit.elga.gv.at/CodeSystem/asp-liste",
Display = "Lasix 80 mg Tabletten"
}
}
}
};

dispense2.Quantity = new() { Value = 2 };

dispense2.Note = new();
dispense2.Note.Add(new() { Text = "Änderung Wirkstoffgehalt: nur 1/2 Tablette täglich" });

dispense2.Performer.Add(new()
{
Actor = new()
{
Identifier = new()
{
Value = "2.999.40.0.34.5.1.1", // OID of dispensing pharmacy
System = "urn:ietf:rfc:3986" // Code-System: eHVD
},
Display = "Apotheke 'Klappernder Storch'"
}
});

dispense2.Type = new()
{
Coding = new()
{
new Coding(system: "http://terminology.hl7.org/CodeSystem/v3-ActCode", code: "FFC")
}
};

(var postedMD, var canCue, var outcome) = LincaDataExchange.CreateMedicationDispense(Connection, dispense2);

if (canCue)
{
Console.WriteLine($"Linca MedicationDispense transmitted, id {postedMD.Id}");
dispenseId = postedMD.Id;
}
else
{
Console.WriteLine($"Failed to transmit Linca MedicationDispense");
}

if (outcome != null)
{
foreach (var item in outcome.Issue)
{
Console.WriteLine($"Outcome Issue Code: '{item.Details.Coding?.FirstOrDefault()?.Code}', Text: '{item.Details.Text}'");
}
}

return canCue;
}
else
{
Console.WriteLine($"Failed to receive Linca Prescription Medication Requests");

return false;
}
}
}
3 changes: 2 additions & 1 deletion Lc.Linca.Sdk.Sample/Util/BundleViewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ public static List<MedicationRequest> FilterPrescriptionsToDispense(Bundle order
if (prescriptions.Find(x => x.PriorPrescription != null && x.PriorPrescription.Reference.Contains(item.Id)) == null
&& dispenses.Find(x => !x.AuthorizingPrescription.IsNullOrEmpty()
&& x.AuthorizingPrescription.First().Reference.Contains(item.Id)
&& x.Type.Coding.First().Code.EndsWith("C")) == null)
&& x.Type.Coding.First().Code.EndsWith("C")
&& x.Status == MedicationDispense.MedicationDispenseStatusCodes.Completed) == null)
{
openPrescriptions.Add(item);
}
Expand Down
14 changes: 8 additions & 6 deletions Lc.Linca.Sdk/Sdk/FhirDataExchange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,14 @@ public static (OperationOutcome received, bool canCue) DeleteResource(LincaConne
response.Content.ReadAsStream()
).ReadToEnd();

if (new FhirJsonPocoDeserializer().TryDeserializeResource
(
receivedResourceRaw,
out Resource? parsedResource,
out var _
) && parsedResource is OperationOutcome receivedResource)
if (! string.IsNullOrWhiteSpace(receivedResourceRaw)
&& new FhirJsonPocoDeserializer().TryDeserializeResource
(
receivedResourceRaw,
out Resource? parsedResource,
out var _
)
&& parsedResource is OperationOutcome receivedResource)
{
if (response?.StatusCode == HttpStatusCode.OK)
{
Expand Down

0 comments on commit ca4fc1e

Please sign in to comment.