source: cprs/trunk/CPRS-Chart/Orders/rODMeds.pas@ 1698

Last change on this file since 1698 was 1679, checked in by healthsevak, 10 years ago

Updating the working copy to CPRS version 28

File size: 18.0 KB
Line 
1unit rODMeds;
2
3interface
4
5uses SysUtils, Classes, ORNet, ORFn, uCore, uConst, Windows;
6
7type
8 TAdminTimeHelpText = record
9 HelpText: string;
10 end;
11
12 TInpatientClozapineText = record
13 dispText: string;
14 end;
15
16 TDrugHasMaxData = record
17 CaptureMaxData: boolean;
18 MaxSupply: integer;
19 MaxQuantity: integer;
20 MaxRefills: integer;
21 end;
22
23function DEACheckFailed(AnOI: Integer; ForInpatient: Boolean): Boolean;
24function DEACheckFailedForIVOnOutPatient(AnOI: Integer; AnOIType: Char): boolean;
25procedure ListForOrderable(var AListIEN, ACount: Integer; const DGrpNm: string);
26procedure SubsetOfOrderable(Dest: TStringList; Append: Boolean; ListIEN, First, Last: Integer);
27function IndexOfOrderable(ListIEN: Integer; From: string): Integer;
28procedure IsActivateOI(var AMsg: string; theOI: integer);
29procedure ListForQuickOrders(var AListIEN, ACount: Integer; const DGrpNm: string);
30procedure SubsetOfQuickOrders(Dest: TStringList; AListIEN, First, Last: Integer);
31function IndexOfQuickOrder(AListIEN: Integer; From: string): Integer;
32procedure LoadFormularyAltOI(AList: TStringList; AnIEN: Integer; ForInpatient: Boolean);
33procedure LoadFormularyAltDose(AList: TStringList; DispDrug, OI: Integer; ForInpatient: Boolean);
34procedure LoadAdminInfo(const Schedule: string; OrdItem: Integer; var StartText: string;
35 var AdminTime: TFMDateTime; var Duration: string; Admin: string = '');
36function GetAdminTime(const StartText, Schedule: string; OrdItem: Integer): TFMDateTime;
37procedure LoadSchedules(Dest: TStrings; IsInptDlg: boolean = False);
38procedure LoadDOWSchedules(Dest: TStrings);
39procedure LoadAllIVRoutes(Dest: TStrings);
40procedure LoadDosageFormIVRoutes(Dest: TStrings; OrderIDs: TStringList);
41function GetDefaultAddFreq(OID: integer): string;
42function QtyToDays(Quantity: Double; const UnitsPerDose, Schedule, Duration, Drug: string): Integer;
43function DaysToQty(DaysSupply: Integer; const UnitsPerDose, Schedule, Duration, Drug: string): Integer;
44function DurToQty(DaysSupply: Integer; const UnitStr, SchedStr: string): Integer;
45function DefaultDays(const ADrug, UnitStr, SchedStr: string): Integer;
46function CalcMaxRefills(const Drug: string; Days, OrdItem: Integer; Discharge: Boolean): Integer;
47function ScheduleRequired(OrdItem: Integer; const ARoute, ADrug: string): Boolean;
48function ODForMedsIn: TStrings;
49function ODForMedsOut: TStrings;
50function OIForMed(AnIEN: Integer; ForInpatient: Boolean; HavePI: boolean = True; PKIActive: Boolean = False): TStrings;
51function GetPickupForLocation(const Loc: string): string;
52function QOHasRouteDefined(AQOID: integer): boolean;
53procedure CheckExistingPI(AOrderId: string; var APtI: string);
54function PassDrugTest(OI: integer; OrderType: string; InptOrder: boolean; CheckForClozapineOnly: boolean = false): boolean;
55function AdminTimeHelpText(): string;
56//function ValidateDaySupplyandQuantity(DaySupply, Quantity: integer): boolean;
57//function ValidateMaxQuantity(Quantity: integer): boolean;
58function ValidateDrugAutoAccept(tempDrug, tempUnit, tempSch, tempDur: string; OI, tempSupply, tempQuantity, tempRefills: integer): boolean;
59function ValidateDaySupplyandQuantityErrorMsg(DaySupply, quantity: integer): String;
60procedure ClearMaxData;
61function DifferentOrderLocations(ID: string; Loc: integer): boolean;
62function IsClozapineOrder: boolean;
63//function ValidateQuantityErrorMsg(Quantity: integer): String;
64function GetQOOrderableItem(DialogIEN: string): integer;
65
66
67implementation
68 var
69 uAdminTimeHelpText: TAdminTimeHelpText;
70 uDrugHasMaxData: TDrugHasMaxData;
71 uInpatientClozapineText : TInpatientClozapineText;
72
73function DEACheckFailed(AnOI: Integer; ForInpatient: Boolean): Boolean;
74var
75 PtType: Char;
76begin
77 if ForInpatient then PtType := 'I' else PtType := 'O';
78 Result := sCallV('ORWDPS1 FAILDEA', [AnOI, Encounter.Provider, PtType]) = '1';
79end;
80
81function DEACheckFailedForIVOnOutPatient(AnOI: Integer; AnOIType: Char): boolean;
82begin
83 Result := sCallV('ORWDPS1 IVDEA',[AnOI,AnOIType,Encounter.Provider]) = '1';
84end;
85
86procedure ListForOrderable(var AListIEN, ACount: Integer; const DGrpNm: string);
87begin
88 CallV('ORWUL FV4DG', [DGrpNm]);
89 AListIEN := StrToIntDef(Piece(RPCBrokerV.Results[0], U, 1), 0);
90 ACount := StrToIntDef(Piece(RPCBrokerV.Results[0], U, 2), 0);
91end;
92
93procedure SubsetOfOrderable(Dest: TStringList; Append: Boolean; ListIEN, First, Last: Integer);
94var
95 i: Integer;
96begin
97 CallV('ORWUL FVSUB', [ListIEN, First+1, Last+1]); // M side not 0-based
98 if Append then FastAddStrings(RPCBrokerV.Results, Dest) else
99 begin
100 for i := Pred(RPCBrokerV.Results.Count) downto 0 do Dest.Insert(0, RPCBrokerV.Results[i]);
101 end;
102end;
103
104function IndexOfOrderable(ListIEN: Integer; From: string): Integer;
105var
106 x: string;
107begin
108 Result := -1;
109 if From = '' then Exit;
110 // decrement last char & concat '~' for $ORDER on M side, limit string length
111 x := UpperCase(Copy(From, 1, 220));
112 x := Copy(x, 1, Length(x) - 1) + Pred(x[Length(x)]) + '~';
113 x := sCallV('ORWUL FVIDX', [ListIEN, x]);
114 // use Pred to make the index 0-based (first value = 1 on M side)
115 if CompareText(Copy(Piece(x, U, 2), 1, Length(From)), From) = 0
116 then Result := Pred(StrToIntDef(Piece(x, U, 1), 0));
117end;
118
119procedure IsActivateOI(var AMsg: string; theOI: integer);
120begin
121 AMsg := SCallV('ORWDXA ISACTOI', [theOI]);
122end;
123
124procedure ListForQuickOrders(var AListIEN, ACount: Integer; const DGrpNm: string);
125begin
126 CallV('ORWUL QV4DG', [DGrpNm]);
127 AListIEN := StrToIntDef(Piece(RPCBrokerV.Results[0], U, 1), 0);
128 ACount := StrToIntDef(Piece(RPCBrokerV.Results[0], U, 2), 0);
129end;
130
131procedure SubsetOfQuickOrders(Dest: TStringList; AListIEN, First, Last: Integer);
132var
133 i: Integer;
134begin
135 CallV('ORWUL QVSUB', [AListIEN,'','']);
136 for i := 0 to RPCBrokerV.Results.Count -1 do
137 Dest.Add(RPCBrokerV.Results[i]);
138end;
139
140function IndexOfQuickOrder(AListIEN: Integer; From: string): Integer;
141var
142 x: string;
143begin
144 Result := -1;
145 if From = '' then Exit;
146 // decrement last char & concat '~' for $ORDER on M side, limit string length
147 x := UpperCase(Copy(From, 1, 220));
148 x := Copy(x, 1, Length(x) - 1) + Pred(x[Length(x)]) + '~';
149 x := sCallV('ORWUL QVIDX', [AListIEN, x]);
150 // use Pred to made the index 0-based (first value = 1 on M side)
151 if CompareText(Copy(Piece(x, U, 2), 1, Length(From)), From) = 0
152 then Result := Pred(StrToIntDef(Piece(x, U, 1), 0));
153end;
154
155procedure LoadFormularyAltOI(AList: TStringList; AnIEN: Integer; ForInpatient: Boolean);
156var
157 PtType: Char;
158begin
159 if ForInpatient then PtType := 'I' else PtType := 'O';
160 CallV('ORWDPS1 FORMALT', [AnIEN, PtType]);
161 FastAssign(RPCBrokerV.Results, AList);
162end;
163
164procedure LoadFormularyAltDose(AList: TStringList; DispDrug, OI: Integer; ForInpatient: Boolean);
165var
166 PtType: Char;
167begin
168 if ForInpatient then PtType := 'I' else PtType := 'O';
169 CallV('ORWDPS1 DOSEALT', [DispDrug, OI, PtType]);
170 FastAssign(RPCBrokerV.Results, AList);
171end;
172
173procedure LoadAdminInfo(const Schedule: string; OrdItem: Integer; var StartText: string;
174 var AdminTime: TFMDateTime; var Duration: string; Admin: string = '');
175var
176 x: string;
177begin
178 x := sCallV('ORWDPS2 ADMIN', [Patient.DFN, Schedule, OrdItem, Encounter.Location, Admin]);
179 StartText := Piece(x, U, 1);
180 AdminTime := MakeFMDateTime(Piece(x, U, 4));
181 Duration := Piece(x, U, 3);
182end;
183
184function GetAdminTime(const StartText, Schedule: string; OrdItem: Integer): TFMDateTime;
185var
186 x: string;
187begin
188 x := sCallV('ORWDPS2 REQST', [Patient.DFN, Schedule, OrdItem, Encounter.Location, StartText]);
189 Result := MakeFMDateTime(x);
190end;
191
192procedure LoadSchedules(Dest: TStrings; IsInptDlg: boolean);
193begin
194 // if uMedSchedules = nil then CallV('ORWDPS ALLSCHD', [nil]); uMedSchedules.Assign(...);
195 CallV('ORWDPS1 SCHALL', [patient.dfn, patient.location]);
196 FastAssign(RPCBrokerV.Results, Dest);
197 If (Dest.IndexOfName('OTHER') < 0) and IsInptDlg then
198 Dest.Add('OTHER');
199end;
200
201procedure LoadAllIVRoutes(Dest: TStrings);
202begin
203 CallV('ORWDPS32 ALLIVRTE', []);
204 FastAssign(RPCBrokerV.Results, Dest);
205end;
206
207procedure LoadDosageFormIVRoutes(Dest: TStrings; OrderIDs: TStringList);
208begin
209 CallV('ORWDPS33 IVDOSFRM', [OrderIDs, False]);
210 FastAssign(RPCBrokerV.Results, Dest);
211end;
212
213function GetDefaultAddFreq(OID: integer): string;
214begin
215 result := sCallV('ORWDPS33 GETADDFR', [OID]);
216end;
217
218procedure LoadDOWSchedules(Dest: TStrings);
219begin
220 // if uMedSchedules = nil then CallV('ORWDPS ALLSCHD', [nil]); uMedSchedules.Assign(...);
221 CallV('ORWDPS1 DOWSCH', [patient.dfn, patient.location]);
222 FastAssign(RPCBrokerV.Results, Dest);
223end;
224
225function QtyToDays(Quantity: Double; const UnitsPerDose, Schedule, Duration, Drug: string): Integer;
226begin
227 Result := StrToIntDef(sCallV('ORWDPS2 QTY2DAY',
228 [Quantity, UnitsPerDose, Schedule, Duration, Patient.DFN, Drug]), 0);
229end;
230
231function DaysToQty(DaysSupply: Integer; const UnitsPerDose, Schedule, Duration, Drug: string): Integer;
232begin
233 Result := StrToIntDef(sCallV('ORWDPS2 DAY2QTY',
234 [DaysSupply, UnitsPerDose, Schedule, Duration, Patient.DFN, Drug]), 0);
235 if uDrugHasMaxData.CaptureMaxData = True then uDrugHasMaxData.MaxQuantity := Result;
236end;
237
238function DurToQty(DaysSupply: Integer; const UnitStr, SchedStr: string): Integer;
239begin
240 Result := StrToIntDef(sCallV('ORWDPS2 DAY2QTY', [DaysSupply, UnitStr, SchedStr]), 0);
241end;
242
243function DefaultDays(const ADrug, UnitStr, SchedStr: string): Integer;
244begin
245 Result := StrToIntDef(sCallV('ORWDPS1 DFLTSPLY', [UnitStr, SchedStr, Patient.DFN, ADrug]), 0);
246 if uDrugHasMaxData.CaptureMaxData = True then uDrugHasMaxData.MaxSupply := Result;
247end;
248
249function CalcMaxRefills(const Drug: string; Days, OrdItem: Integer; Discharge: Boolean): Integer;
250begin
251 Result := StrToIntDef(sCallV('ORWDPS2 MAXREF', [Patient.DFN, Drug, Days, OrdItem, Discharge]), 0);
252 if uDrugHasMaxData.CaptureMaxData = True then uDrugHasMaxData.MaxRefills := Result;
253end;
254
255function ScheduleRequired(OrdItem: Integer; const ARoute, ADrug: string): Boolean;
256begin
257 Result := sCallV('ORWDPS2 SCHREQ', [OrdItem, ARoute, ADrug]) = '1';
258end;
259
260function ODForMedsIn: TStrings;
261{ Returns init values for inpatient meds dialog. The results must be used immediately. }
262begin
263 CallV('ORWDPS1 ODSLCT', [PST_UNIT_DOSE, Patient.DFN, Encounter.Location]);
264 Result := RPCBrokerV.Results;
265end;
266
267function ODForMedsOut: TStrings;
268{ Returns init values for outpatient meds dialog. The results must be used immediately. }
269begin
270 CallV('ORWDPS1 ODSLCT', [PST_OUTPATIENT, Patient.DFN, Encounter.Location]);
271 Result := RPCBrokerV.Results;
272end;
273
274function OIForMed(AnIEN: Integer; ForInpatient: Boolean; HavePI: Boolean; PKIActive: Boolean): TStrings;
275var
276 PtType: Char;
277 NeedPI: Char;
278 IsPKIActive: Char;
279begin
280 if HavePI then NeedPI := 'Y' else NeedPI := 'N';
281 if ForInpatient then PtType := 'U' else PtType := 'O';
282 if PKIActive then IsPKIActive := 'Y' else IsPKIActive := 'N';
283 CallV('ORWDPS2 OISLCT', [AnIEN, PtType, Patient.DFN, NeedPI, IsPKIActive]);
284 Result := RPCBrokerV.Results;
285end;
286
287function GetPickupForLocation(const Loc: string): string;
288begin
289 Result := sCallV('ORWDPS1 LOCPICK',[Loc]);
290end;
291
292function QOHasRouteDefined(AQOID: integer): boolean;
293begin
294 Result := False;
295 if ( sCallV('ORWDPS1 HASROUTE',[AQOID])='1' ) then
296 Result := True;
297end;
298
299procedure CheckExistingPI(AOrderId: string; var APtI: string);
300begin
301 APtI := sCallV('ORWDPS2 CHKPI', [AOrderId]);
302end;
303
304function PassDrugTest(OI: integer; OrderType: string; InptOrder: boolean; CheckForClozapineOnly: boolean = false): boolean;
305var
306MessCap, MessText: string;
307i: integer;
308begin
309 result := false;
310 MessText := '';
311 uDrugHasMaxData.CaptureMaxData := false;
312 uDrugHasMaxData.MaxSupply := 0;
313 uDrugHasMaxData.MaxQuantity := 0;
314 uDrugHasMaxData.MaxRefills := 0;
315 CallV('ORALWORD ALLWORD', [Patient.DFN, OI, OrderType, Encounter.Provider]);
316 for i := 0 to RPCBrokerV.Results.Count -1 do
317 begin
318 if i = 0 then
319 begin
320 MessCap := Piece(RPCBrokerV.Results.strings[i],U,1);
321 if Piece(RPCBrokerV.Results.strings[i],U,2) = '1' then uDrugHasMaxData.CaptureMaxData := True;
322 end;
323 if i >0 then MessText := MessText + RPCBrokerV.Results.Strings[i] + CRLF;
324 end;
325 if CheckForClozapineOnly = True then
326 begin
327 Result := uDrugHasMaxData.CaptureMaxData = True;
328 Exit;
329 end;
330 if (MessText = '') and (MessCap = '') then
331 begin
332 Result := True;
333 if (InptOrder = true) and (uDrugHasMaxData.CaptureMaxData = true) then
334 begin
335 uDrugHasMaxData.CaptureMaxData := false;
336 if uInpatientClozapineText.dispText = '' then
337 begin
338 CallV('ORDDPAPI CLOZMSG', []);
339 for i := 0 to RPCBrokerV.Results.Count -1 do
340 if i = 0 then uInpatientClozapineText.dispText := RPCBrokerV.Results.Strings[i]
341 else uInpatientClozapineText.dispText := uInpatientClozapineText.dispText + CRLF + RPCBrokerV.Results.Strings[i];
342 end;
343 if uInpatientClozapineText.dispText <> '' then infoBox(uInpatientClozapineText.dispText, 'Inpatient Drug Warning', MB_OK);
344 end;
345 exit;
346 end;
347 infoBox(MessText, MessCap,MB_OK);
348end;
349
350function AdminTimeHelpText(): string;
351var
352i: integer;
353begin
354 if uAdminTimeHelpText.HelpText = '' then
355 begin
356 CallV('ORDDPAPI ADMTIME',[]);
357 for I := 0 to RPCBrokerV.Results.Count - 1 do
358 if I = 0 then uAdminTimeHelpText.HelpText := RPCBrokerV.Results.Strings[i]
359 else uAdminTimeHelpText.HelpText := uAdminTimeHelpText.HelpText + CRLF +RPCBrokerV.Results.Strings[i];
360 end;
361 Result := uAdminTimeHelpText.helpText
362end;
363
364function ValidateDrugAutoAccept(tempDrug, tempUnit, tempSch, tempDur: string; OI, tempSupply, tempQuantity, tempRefills: integer): boolean;
365var
366daySupply, Quantity, Refills: integer;
367begin
368 Result := True;
369 if uDrugHasMaxData.CaptureMaxData = false then exit;
370 daySupply := DefaultDays(tempDrug, tempUnit, tempSch);
371 if (tempSupply > daySupply) and (uDrugHasMaxData.MaxSupply > 0) then
372 begin
373 infoBox('For this medication Day Supply cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxSupply), 'Cannot Save Error', MB_OK);
374 Result := false;
375 uDrugHasMaxData.CaptureMaxData := false;
376 Exit;
377 end;
378 Quantity := DaysToQty(daySupply, tempUnit, tempSch, tempDur, tempDrug);
379 if (tempQuantity > Quantity) and (uDrugHasMaxData.MaxQuantity > 0) then
380 begin
381 infoBox('For this medication Quantity cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxQuantity), 'Cannot Save Error', MB_OK);
382 Result := false;
383 uDrugHasMaxData.CaptureMaxData := false;
384 Exit;
385 end;
386 Refills := CalcMaxRefills(tempDrug, daySupply, OI, false);
387 if tempRefills > Refills then
388 begin
389 infoBox('For this medication Quantity cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxRefills), 'Cannot Save Error', MB_OK);
390 Result := false;
391 uDrugHasMaxData.CaptureMaxData := false;
392 Exit;
393 end;
394end;
395
396function ValidateDaySupplyandQuantity(DaySupply, Quantity: integer): boolean;
397var
398str: string;
399begin
400 Result := True;
401 str := '';
402 if uDrugHasMaxData.CaptureMaxData = false then exit;
403 if (daySupply > uDrugHasMaxData.MaxSupply) and (uDrugHasMaxData.MaxSupply > 0) then
404 begin
405 str := 'For this medication Day Supply cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxSupply);
406 Result := false;
407 end;
408 if (Quantity > uDrugHasMaxData.MaxQuantity) and (uDrugHasMaxData.MaxQuantity > 0) then
409 begin
410 if str <> '' then str := str + CRLF + 'For this medication Day Supply cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxQuantity)
411 else str := 'For this medication Day Supply cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxQuantity);
412 result := false;
413 end;
414 if str <> '' then infoBox(str, 'Cannot Save Error', MB_OK);
415 //uDrugHasMaxData.CaptureMaxData := false;
416end;
417
418function ValidateMaxQuantity(Quantity: integer): boolean;
419begin
420 Result := True;
421 if uDrugHasMaxData.CaptureMaxData = false then exit;
422 if uDrugHasMaxData.MaxQuantity = 0 then exit;
423 if Quantity > uDrugHasMaxData.MaxQuantity then
424 begin
425 infoBox('For this medication Day Supply cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxQuantity), 'Cannot Save Error', MB_OK);
426 Result := false;
427 end;
428end;
429
430function ValidateDaySupplyandQuantityErrorMsg(DaySupply, quantity: integer): String;
431begin
432 Result := '';
433 if uDrugHasMaxData.CaptureMaxData = false then exit;
434 if (daySupply > uDrugHasMaxData.MaxSupply) and (uDrugHasMaxData.MaxSupply > 0) then
435 begin
436 Result := 'For this medication Day Supply cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxSupply);
437 end;
438 if (Quantity > uDrugHasMaxData.MaxQuantity) and (uDrugHasMaxData.MaxQuantity > 0) then
439 begin
440 if Result <> '' then Result := Result + CRLF + 'For this medication Quantity cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxQuantity)
441 else Result := 'For this medication Quantity cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxQuantity);
442 end;
443 //uDrugHasMaxData.CaptureMaxData := false;
444end;
445
446function ValidateQuantityErrorMsg(Quantity: integer): String;
447begin
448 Result := '';
449 if uDrugHasMaxData.CaptureMaxData = false then exit;
450 if uDrugHasMaxData.MaxQuantity = 0 then exit;
451 if Quantity > uDrugHasMaxData.MaxQuantity then
452 begin
453 Result := 'For this medication Quantity cannot be greater then ' + InttoStr(uDrugHasMaxData.MaxQuantity);
454 end;
455end;
456
457procedure ClearMaxData;
458begin
459 uDrugHasMaxData.CaptureMaxData := false;
460end;
461
462function DifferentOrderLocations(ID: string; Loc: integer): boolean;
463begin
464 Result := (sCallV('ORWDPS33 COMPLOC', [ID, Loc])='1');
465end;
466
467function IsClozapineOrder: boolean;
468begin
469 if uDrugHasMaxData.CaptureMaxData = true then result := true
470 else result := false;
471end;
472
473function GetQOOrderableItem(DialogIEN: string): integer;
474begin
475 Result := StrtoInt(SCallV('ORWDPS1 QOMEDALT',[DialogIEN]))
476end;
477
478end.
Note: See TracBrowser for help on using the repository browser.