unit rODBase; interface uses SysUtils, Windows, Classes, ORNet, ORFn, uCore, uConst, rOrders; type TPrompt = class ID: string; IEN: Integer; Sequence: Double; FmtCode: string; Omit: string; Leading: string; Trailing: string; NewLine: Boolean; WrapWP: Boolean; Children: string; IsChild: Boolean; end; TResponse = class PromptIEN: Integer; PromptID: string; Instance: Integer; IValue: string; EValue: string; end; TDialogItem = class ID: string; Required: Boolean; Hidden: Boolean; Prompt: string; DataType: Char; Domain: string; EDefault: string; IDefault: string; HelpText: string; CrossRef: string; ScreenRef: string; end; TDialogNames = record Internal: string; Display: string; BaseIEN: Integer; BaseName: string; end; TConstructOrder = record DialogName: string; LeadText: string; TrailText: string; DGroup: Integer; OrderItem: Integer; DelayEvent: Char; PTEventPtr: String; // ptr to #100.2 EventPtr: String; // ptr to #100.5 Specialty: Integer; Effective: TFMDateTime; LogTime: TFMDateTime; OCList: TStringList; DigSig: string; ResponseList: TList; IsIMODialog: boolean; //imo IsEventDefaultOR: Integer; end; TPFSSActive = record PFSSActive: boolean; PFSSChecked: boolean; end; { General Calls } function AskAnotherOrder(ADialog: Integer): Boolean; function DisplayGroupByName(const AName: string): Integer; function DisplayGroupForDialog(const DialogName: string): Integer; procedure IdentifyDialog(var DialogNames: TDialogNames; ADialog: Integer); procedure LoadDialogDefinition(Dest: TList; const DialogName: string); procedure LoadOrderPrompting(Dest: TList; ADialog: Integer); //procedure LoadResponses(Dest: TList; const OrderID: string); procedure LoadResponses(Dest: TList; const OrderID: string; var HasObjects: boolean); procedure PutNewOrder(var AnOrder: TOrder; ConstructOrder: TConstructOrder; OrderSource: string); //procedure PutNewOrderAuto(var AnOrder: TOrder; ADialog: Integer); // no longer used function OIMessage(IEN: Integer): string; function OrderMenuStyle: Integer; function ResolveScreenRef(const ARef: string): string; function SubsetOfEntries(const StartFrom: string; Direction: Integer; const XRef, GblRef, ScreenRef: string): TStrings; function SubSetOfOrderItems(const StartFrom: string; Direction: Integer; const XRef: string): TStrings; function GetDefaultCopay(AnOrderID: string): String; procedure SetDefaultCoPayToNewOrder(AnOrderID, CoPayInfo:string); procedure ValidateNumericStr(const x, Dom: string; var ErrMsg: string); function IsPFSSActive: boolean; { Quick Order Calls } //function DisplayNameForOD(const InternalName: string): string; function GetQuickName(const CRC: string): string; procedure LoadQuickListForOD(Dest: TStrings; DGroup: Integer); procedure SaveQuickListForOD(Src: TStrings; DGroup: Integer); //procedure PutQuickName(DialogIEN: Integer; const DisplayName: string); procedure PutQuickOrder(var NewIEN: Integer; const CRC, DisplayName: string; DGroup: Integer; ResponseList: TList); { Medication Calls } function AmountsForIVFluid(AnIEN: Integer; FluidType: Char): string; procedure AppendMedRoutes(Dest: TStrings); procedure CheckAuthForMeds(var x: string); function DispenseMessage(AnIEN: Integer): string; procedure LookupRoute(const AName: string; var ID, Abbreviation: string); function MedIsSupply(AnIEN: Integer): Boolean; function QuantityMessage(AnIEN: Integer): string; function RequiresCopay(DispenseDrug: Integer): Boolean; procedure LoadFormularyAlt(AList: TStringList; AnIEN: Integer; PSType: Char); function MedTypeIsIV(AnIEN: Integer): Boolean; function ODForMedIn: TStrings; function OIForMedIn(AnIEN: Integer): TStrings; function ODForIVFluids: TStrings; function ODForMedOut: TStrings; function OIForMedOut(AnIEN: Integer): TStrings; function RatedDisabilities: string; //function ValidIVRate(const x: string): Boolean; procedure ValidateIVRate(var x: string); function ValidSchedule(const x: string; PSType: Char = 'I'): Integer; function ValidQuantity(const x: string): Boolean; { Vitals Calls } function ODForVitals: TStrings; implementation uses TRPCB, uOrders, uODBase; var uLastDispenseIEN: Integer; uLastDispenseMsg: string; uLastQuantityMsg: string; uMedRoutes: TStringList; uPFSSActive: TPFSSActive; { Common Internal Calls } procedure SetupORDIALOG(AParam: TParamRecord; ResponseList: TList; IsIV: boolean = False); const MAX_STR_LEN = 74; var i,j,ALine,odIdx,piIdx : Integer; Subs, x, ODtxt, thePI: string; WPStrings: TStringList; IVDuration, IVDurVal: string; begin piIdx := 0; odIdx := 0; IVDuration := ''; IVDurVal := ''; AParam.PType := list; for j := 0 to ResponseList.Count - 1 do begin if TResponse(ResponseList.Items[j]).PromptID = 'SIG' then begin ODtxt := TResponse(ResponseList.Items[j]).EValue; odIdx := j; end; if TResponse(ResponseList.Items[j]).PromptID = 'PI' then thePI := TResponse(ResponseList.Items[j]).EValue; if Length(Trim(thePI)) > 0 then piIdx := Pos(thePI, ODtxt); if piIdx > 0 then begin Delete(ODtxt,piIdx,Length(thePI)); TResponse(ResponseList.Items[odIdx]).EValue := ODtxt; end; if (IsIV and (TResponse(ResponseList.Items[j]).PromptID = 'DAYS')) then begin IVDuration := TResponse(ResponseList.Items[j]).EValue; if (Length(IVDuration) > 1) then begin if (Pos('TOTAL',upperCase(IVDuration))>0) or (Pos('FOR',upperCase(IVDuration))>0) then continue; if (Pos('H',upperCase(IVDuration))>0) then begin IVDurVal := Copy(IVDuration,1,length(IVDuration)-1); TResponse(ResponseList.Items[j]).IValue := 'for ' + IVDurVal + 'hours'; end else if (Pos('D',upperCase(IVDuration))>0) then begin IVDurVal := Copy(IVDuration,1,length(IVDuration)-1); TResponse(ResponseList.Items[j]).IValue := 'for ' + IVDurVal + 'days'; end else if ((Pos('ML',upperCase(IVDuration))>0) or (Pos('CC',upperCase(IVDuration))>0)) then begin IVDurVal := Copy(IVDuration,1,length(IVDuration)-2); TResponse(ResponseList.Items[j]).IValue := 'with total volume ' + IVDurVal + 'ml'; end else if (Pos('L',upperCase(IVDuration))>0) then begin IVDurVal := Copy(IVDuration,0,length(IVDuration)-1); TResponse(ResponseList.Items[j]).IValue := 'with total volume ' + IVDurVal + 'L'; end; end; end; end; with AParam, ResponseList do for i := 0 to Count - 1 do begin with TResponse(Items[i]) do begin Subs := IntToStr(PromptIEN) + ',' + IntToStr(Instance); if IValue = TX_WPTYPE then begin WPStrings := TStringList.Create; try WPStrings.Text := EValue; LimitStringLength(WPStrings, MAX_STR_LEN); x := 'ORDIALOG("WP",' + Subs + ')'; Mult[Subs] := x; for ALine := 0 to WPStrings.Count - 1 do begin x := '"WP",' + Subs + ',' + IntToStr(ALine+1) + ',0'; Mult[x] := WPStrings[ALine]; end; {for} finally WPStrings.Free; end; {try} end else Mult[Subs] := IValue; end; {with TResponse} end; {with AParam} end; { Quick Order Calls } //function DisplayNameForOD(const InternalName: string): string; //begin // Result := sCallV('ORWDXQ DLGNAME', [InternalName]); //end; function GetQuickName(const CRC: string): string; begin Result := sCallV('ORWDXQ GETQNAM', [CRC]); end; procedure LoadQuickListForOD(Dest: TStrings; DGroup: Integer); begin CallV('ORWDXQ GETQLST', [DGroup]); Dest.Assign(RPCBrokerV.Results); end; procedure SaveQuickListForOD(Src: TStrings; DGroup: Integer); begin CallV('ORWDXQ PUTQLST', [DGroup, Src]); // ignore return value for now end; //procedure PutQuickName(DialogIEN: Integer; const DisplayName: string); //begin // CallV('ORWDXQ PUTQNAM', [DialogIEN, DisplayName]); // // ignore return value for now //end; procedure PutQuickOrder(var NewIEN: Integer; const CRC, DisplayName: string; DGroup: Integer; ResponseList: TList); begin with RPCBrokerV do begin ClearParameters := True; RemoteProcedure := 'ORWDXQ DLGSAVE'; Param[0].PType := literal; Param[0].Value := CRC; Param[1].PType := literal; Param[1].Value := DisplayName; Param[2].PType := literal; Param[2].Value := IntToStr(DGroup); SetupORDIALOG(Param[3], ResponseList); CallBroker; if Results.Count = 0 then Exit; // error creating order NewIEN := StrToIntDef(Results[0], 0); end; end; { General Calls } function AskAnotherOrder(ADialog: Integer): Boolean; begin Result := sCallV('ORWDX AGAIN', [ADialog]) = '1'; end; function DisplayGroupByName(const AName: string): Integer; begin Result := StrToIntDef(sCallV('ORWDX DGNM', [AName]), 0); end; function DisplayGroupForDialog(const DialogName: string): Integer; begin Result := StrToIntDef(sCallV('ORWDX DGRP', [DialogName]),0); end; procedure IdentifyDialog(var DialogNames: TDialogNames; ADialog: Integer); var x: string; begin x := sCallV('ORWDXM DLGNAME', [ADialog]); with DialogNames do begin Internal := Piece(x, U, 1); Display := Piece(x, U, 2); BaseIEN := StrToIntDef(Piece(x, U, 3), 0); BaseName := Piece(x, U, 4); end; end; procedure LoadDialogDefinition(Dest: TList; const DialogName: string); { loads a list of TPrompt records Pieces: PromptID[1]^PromptIEN[2]^FmtSeq[3]^Fmt[4]^Omit[5]^Lead[6]^Trail[7]^NwLn[8]^Wrap[9]^Children[10]^IsChild[11] } var i: Integer; APrompt: TPrompt; begin CallV('ORWDX DLGDEF', [DialogName]); with RPCBrokerV do for i := 0 to Results.Count - 1 do begin APrompt := TPrompt.Create; with APrompt do begin ID := Piece(Results[i], U, 1); IEN := StrToIntDef(Piece(Results[i], U, 2), 0); if Length(Piece(Results[i], U, 3)) > 0 then Sequence := StrToFloat(Piece(Results[i], U, 3)) else Sequence := 0; FmtCode := Piece(Results[i], U, 4); Omit := Piece(Results[i], U, 5); Leading := Piece(Results[i], U, 6); Trailing := Piece(Results[i], U, 7); NewLine := Piece(Results[i], U, 8) = '1'; WrapWP := Piece(Results[i], U, 9) = '1'; Children := Piece(Results[i], U, 10); IsChild := Piece(Results[i], U, 11) = '1'; end; Dest.Add(APrompt); end; end; procedure LoadOrderPrompting(Dest: TList; ADialog: Integer); // ID^REQ^HID^PROMPT^TYPE^DOMAIN^DEFAULT^IDFLT^HELP var i: Integer; DialogItem: TDialogItem; begin CallV('ORWDXM PROMPTS', [ADialog]); DialogItem := nil; with RPCBrokerV do for i := 0 to Results.Count - 1 do begin if CharAt(Results[i], 1) = '~' then begin DialogItem := TDialogItem.Create; // create a new dialog item with DialogItem do begin Results[i] := Copy(Results[i], 2, Length(Results[i])); ID := Piece(Results[i], U, 1); Required := Piece(Results[i], U, 2) = '1'; Hidden := Piece(Results[i], U, 3) = '1'; Prompt := Piece(Results[i], U, 4); DataType := CharAt(Piece(Results[i], U, 5), 1); Domain := Piece(Results[i], U, 6); EDefault := Piece(Results[i], U, 7); IDefault := Piece(Results[i], U, 8); HelpText := Piece(Results[i], U, 9); CrossRef := Piece(Results[i], U, 10); ScreenRef := Piece(Results[i], U, 11); if Hidden then DataType := 'H'; // if hidden, use 'Hidden' type end; Dest.Add(DialogItem); end; if (CharAt(Results[i], 1) = 't') and (DialogItem <> nil) then // use last DialogItem with DialogItem do EDefault := EDefault + Copy(Results[i], 2, Length(Results[i])) + CRLF; end; end; procedure ExtractToResponses(Dest: TList; var HasObjects: boolean); { load a list with TResponse records, assumes source strings are in RPCBrokerV.Results } var i: Integer; AResponse: TResponse; WPContainsObjects, TxContainsObjects: boolean; TempBroker: TStrings; begin i := 0; HasObjects := FALSE; TempBroker := TStringlist.Create; TempBroker.Assign(RPCBrokerV.Results); try with TempBroker do while i < Count do begin if CharAt(Strings[i], 1) = '~' then begin AResponse := TResponse.Create; with AResponse do begin PromptIEN := StrToIntDef(Piece(Copy(Strings[i], 2, 255), U, 1), 0); Instance := StrToIntDef(Piece(Strings[i], U, 2), 0); PromptID := Piece(Strings[i], U, 3); Inc(i); while (i < Count) and (CharAt(Strings[i], 1) <> '~') do begin if CharAt(Strings[i], 1) = 'i' then IValue := Copy(Strings[i], 2, 255); if CharAt(Strings[i], 1) = 'e' then EValue := Copy(Strings[i], 2, 255); if CharAt(Strings[i], 1) = 't' then begin if Length(EValue) > 0 then EValue := EValue + CRLF; EValue := EValue + Copy(Strings[i], 2, 255); IValue := TX_WPTYPE; // signals that this is a word processing field end; Inc(i); end; {while i} if IValue <> TX_WPTYPE then ExpandOrderObjects(IValue, TxContainsObjects); ExpandOrderObjects(EValue, WPContainsObjects); HasObjects := HasObjects or WPContainsObjects or TxContainsObjects; Dest.Add(AResponse); end; {with AResponse} end; {if CharAt} end; {With RPCBrokerV} finally TempBroker.Free; end; end; procedure LoadResponses(Dest: TList; const OrderID: string; var HasObjects: boolean); begin CallV('ORWDX LOADRSP', [OrderID]); ExtractToResponses(Dest, HasObjects); end; procedure PutNewOrder(var AnOrder: TOrder; ConstructOrder: TConstructOrder; OrderSource: string); var i: Integer; x, y, z: string; begin with RPCBrokerV do begin ClearParameters := True; RemoteProcedure := 'ORWDX SAVE'; Param[0].PType := literal; Param[0].Value := Patient.DFN; //*DFN* Param[1].PType := literal; Param[1].Value := IntToStr(Encounter.Provider); Param[2].PType := literal; (*if loc > 0 then Param[2].Value := IntToStr(Loc) else Param[2].Value := IntToStr(Encounter.Location);*) Param[2].Value := IntToStr(Encounter.Location); Param[3].PType := literal; Param[3].Value := ConstructOrder.DialogName; Param[4].PType := literal; Param[4].Value := IntToStr(ConstructOrder.DGroup); Param[5].PType := literal; Param[5].Value := IntToStr(ConstructOrder.OrderItem); Param[6].PType := literal; Param[6].Value := AnOrder.EditOf; // null if new order, otherwise ORIFN of original if (ConstructOrder.DGroup = IVDisp) then SetupORDIALOG(Param[7], ConstructOrder.ResponseList, True) else SetupORDIALOG(Param[7], ConstructOrder.ResponseList); if Length(ConstructOrder.LeadText) > 0 then Param[7].Mult['"ORLEAD"'] := ConstructOrder.LeadText; if Length(ConstructOrder.TrailText) > 0 then Param[7].Mult['"ORTRAIL"'] := ConstructOrder.TrailText; Param[7].Mult['"ORCHECK"'] := IntToStr(ConstructOrder.OCList.Count); with ConstructOrder do for i := 0 to OCList.Count - 1 do begin // put quotes around everything to prevent broker from choking y := '"ORCHECK","' + Piece(OCList[i], U, 1) + '","' + Piece(OCList[i], U, 3) + '","' + IntToStr(i+1) + '"'; Param[7].Mult[y] := Pieces(OCList[i], U, 2, 4); end; if ConstructOrder.DelayEvent in ['A','D','T','M','O'] then Param[7].Mult['"OREVENT"'] := ConstructOrder.PTEventPtr; if ConstructOrder.LogTime > 0 then Param[7].Mult['"ORSLOG"'] := FloatToStr(ConstructOrder.LogTime); Param[7].Mult['"ORTS"'] := IntToStr(Patient.Specialty); // pass in treating specialty for ORTS Param[8].PType := literal; Param[8].Value := ConstructOrder.DigSig; if Constructorder.IsIMODialog then begin Param[9].PType := literal; //IMO Param[9].Value := FloatToStr(Encounter.DateTime); end else begin Param[9].PType := literal; //IMO Param[9].Value := ''; end; Param[10].PType := literal; Param[10].Value := OrderSource; Param[11].PType := literal; Param[11].Value := IntToStr(Constructorder.IsEventDefaultOR); CallBroker; if Results.Count = 0 then Exit; // error creating order x := Results[0]; Results.Delete(0); y := ''; while (Results.Count > 0) and (CharAt(Results[0], 1) <> '~') and (CharAt(Results[0], 1) <> '|') do begin y := y + Copy(Results[0], 2, Length(Results[0])) + CRLF; Results.Delete(0); end; if Length(y) > 0 then y := Copy(y, 1, Length(y) - 2); // take off last CRLF z := ''; if (Results.Count > 0) and (Results[0] = '|') then begin Results.Delete(0); while (Results.Count > 0) and (CharAt(Results[0], 1) <> '~') and (CharAt(Results[0], 1) <> '|') do begin z := z + Copy(Results[0], 2, Length(Results[0])); Results.Delete(0); end; end; SetOrderFields(AnOrder, x, y, z); end; end; { no longer used - procedure PutNewOrderAuto(var AnOrder: TOrder; ADialog: Integer); var i: Integer; y: string; begin CallV('ORWDXM AUTOACK', [Patient.DFN, Encounter.Provider, Encounter.Location, ADialog]); with RPCBrokerV do if Results.Count > 0 then begin y := ''; for i := 1 to Results.Count - 1 do y := y + Copy(Results[i], 2, Length(Results[i])) + CRLF; if Length(y) > 0 then y := Copy(y, 1, Length(y) - 2); // take off last CRLF SetOrderFields(AnOrder, Results[0], y); end; end; } function OIMessage(IEN: Integer): string; begin CallV('ORWDX MSG', [IEN]); with RPCBrokerV.Results do SetString(Result, GetText, Length(Text)); end; function OrderMenuStyle: Integer; begin Result := StrToIntDef(sCallV('ORWDXM MSTYLE', [nil]), 0); end; function ResolveScreenRef(const ARef: string): string; begin Result := sCallV('ORWDXM RSCRN', [ARef]); end; function SubSetOfOrderItems(const StartFrom: string; Direction: Integer; const XRef: string): TStrings; { returns a pointer to a list of orderable items matching an S.xxx cross reference (for use in a long list box) - The return value is a pointer to RPCBrokerV.Results, so the data must be used BEFORE the next broker call! } begin CallV('ORWDX ORDITM', [StartFrom, Direction, XRef]); Result := RPCBrokerV.Results; end; function GetDefaultCopay(AnOrderID: string): String; begin with RPCBrokerV do begin ClearParameters := True; RemoteProcedure := 'ORWDPS4 CPLST'; Param[0].PType := literal; Param[0].Value := Patient.DFN; Param[1].PType := list; Param[1].Mult['1'] := AnOrderID; end; CallBroker; if RPCBrokerV.Results.Count > 0 then Result := RPCBrokerV.Results[0] else Result := ''; end; procedure SetDefaultCoPayToNewOrder(AnOrderID, CoPayInfo:string); var temp,CPExems: string; CoPayValue: array [1..7] of Char; i: integer; begin // SC AO IR EC MST HNC CV CoPayValue[1] := 'N'; CoPayValue[2] := 'N'; CoPayValue[3] := 'N'; CoPayValue[4] := 'N'; CoPayValue[5] := 'N'; CoPayValue[6] := 'N'; CoPayValue[7] := 'N'; temp := Pieces(CoPayInfo,'^',2,6); i := 1; while Length(Piece(temp,'^',i))>0 do begin if Piece(Piece(temp,'^',i),';',1) = 'SC' then begin if Piece( Piece(temp,'^',i),';',2) = '1' then CoPayValue[1] := 'C' else CopayValue[1] := 'U'; end; if Piece(Piece(temp,'^',i),';',1) = 'AO' then begin if Piece( Piece(temp,'^',i),';',2) = '1' then CoPayValue[2] := 'C' else CopayValue[2] := 'U'; end; if Piece(Piece(temp,'^',i),';',1) = 'IR' then begin if Piece( Piece(temp,'^',i),';',2) = '1' then CoPayValue[3] := 'C' else CopayValue[3] := 'U'; end; if Piece(Piece(temp,'^',i),';',1) = 'EC' then begin if Piece( Piece(temp,'^',i),';',2) = '1' then CoPayValue[4] := 'C' else CopayValue[4] := 'U'; end; if Piece(Piece(temp,'^',i),';',1) = 'MST' then begin if Piece( Piece(temp,'^',i),';',2) = '1' then CoPayValue[5] := 'C' else CopayValue[5] := 'U'; end; if Piece(Piece(temp,'^',i),';',1) = 'HNC' then begin if Piece( Piece(temp,'^',i),';',2) = '1' then CoPayValue[6] := 'C' else CopayValue[6] := 'U'; end; if Piece(Piece(temp,'^',i),';',1) = 'CV' then begin if Piece( Piece(temp,'^',i),';',2) = '1' then CoPayValue[7] := 'C' else CopayValue[7] := 'U'; end; i := i + 1; end; CPExems := CoPayValue[1] + CoPayValue[2] + CoPayValue[3] + CoPayValue[4] + CoPayValue[5] + CoPayValue[6] + CoPayValue[7]; CPExems := AnOrderId + '^' + CPExems; with RPCBrokerV do begin ClearParameters := True; RemoteProcedure := 'ORWDPS4 CPINFO'; Param[0].PType := list; Param[0].Mult['1'] := CPExems; CallBroker; end; end; function SubsetOfEntries(const StartFrom: string; Direction: Integer; const XRef, GblRef, ScreenRef: string): TStrings; { returns a pointer to a list of file entries (for use in a long list box) - The return value is a pointer to RPCBrokerV.Results, so the data must be used BEFORE the next broker call! } begin CallV('ORWDOR LKSCRN', [StartFrom, Direction, XRef, GblRef, ScreenRef]); Result := RPCBrokerV.Results; end; procedure ValidateNumericStr(const x, Dom: string; var ErrMsg: string); begin ErrMsg := sCallV('ORWDOR VALNUM', [x, Dom]); if ErrMsg = '0' then ErrMsg := '' else ErrMsg := Piece(ErrMsg, U, 2); end; function IsPFSSActive: boolean; begin with uPFSSActive do if not PFSSChecked then begin PFSSActive := (sCallV('ORWPFSS IS PFSS ACTIVE?', [nil]) = '1'); PFSSChecked := True; end; Result := uPFSSActive.PFSSActive end; { Medication Calls } procedure AppendMedRoutes(Dest: TStrings); var i: Integer; x: string; begin if uMedRoutes = nil then begin CallV('ORWDPS32 ALLROUTE', [nil]); with RPCBrokerV do begin uMedRoutes := TStringList.Create; uMedRoutes.Assign(Results); for i := 0 to Results.Count - 1 do if Length(Piece(Results[i], U, 3)) > 0 then begin x := Piece(Results[i], U, 1) + U + Piece(Results[i], U, 3) + ' (' + Piece(Results[i], U, 2) + ')' + U + Piece(Results[i], U, 3); uMedRoutes.Add(x); end; {if Length} SortByPiece(uMedRoutes, U, 2); end; {with RPCBrokerV} end; {if uMedRoutes} Dest.AddStrings(uMedRoutes); end; procedure CheckAuthForMeds(var x: string); begin x := Piece(sCallV('ORWDPS32 AUTH', [Encounter.Provider]), U, 2); end; function DispenseMessage(AnIEN: Integer): string; var x: string; begin if AnIEN = uLastDispenseIEN then Result := uLastDispenseMsg else begin x := sCallV('ORWDPS32 DRUGMSG', [AnIEN]); uLastDispenseIEN := AnIEN; uLastDispenseMsg := Piece(x, U, 1); uLastQuantityMsg := Piece(x, U, 2); Result := uLastDispenseMsg; end; end; function QuantityMessage(AnIEN: Integer): string; var x: string; begin if AnIEN = uLastDispenseIEN then Result := uLastQuantityMsg else begin x := sCallV('ORWDPS32 DRUGMSG', [AnIEN]); uLastDispenseIEN := AnIEN; uLastDispenseMsg := Piece(x, U, 1); uLastQuantityMsg := Piece(x, U, 2); Result := uLastQuantityMsg; end; end; function RequiresCopay(DispenseDrug: Integer): Boolean; begin Result := sCallV('ORWDPS32 SCSTS', [Patient.DFN, DispenseDrug]) = '1'; end; procedure LoadFormularyAlt(AList: TStringList; AnIEN: Integer; PSType: Char); begin CallV('ORWDPS32 FORMALT', [AnIEN, PSType]); AList.Assign(RPCBrokerV.Results); end; procedure LookupRoute(const AName: string; var ID, Abbreviation: string); var x: string; begin x := sCallV('ORWDPS32 VALROUTE', [AName]); ID := Piece(x, U, 1); Abbreviation := Piece(x, U, 2); end; function MedIsSupply(AnIEN: Integer): Boolean; begin Result := sCallV('ORWDPS32 ISSPLY', [AnIEN]) = '1'; end; function MedTypeIsIV(AnIEN: Integer): Boolean; begin Result := sCallV('ORWDPS32 MEDISIV', [AnIEN]) = '1'; end; function ODForMedIn: TStrings; { Returns init values for inpatient meds dialog. The results must be used immediately. } begin CallV('ORWDPS32 DLGSLCT', [PST_UNIT_DOSE]); Result := RPCBrokerV.Results; end; function ODForIVFluids: TStrings; { Returns init values for IV Fluids dialog. The results must be used immediately. } begin CallV('ORWDPS32 DLGSLCT', [PST_IV_FLUIDS]); Result := RPCBrokerV.Results; end; function AmountsForIVFluid(AnIEN: Integer; FluidType: Char): string; begin Result := sCallV('ORWDPS32 IVAMT', [AnIEN, FluidType]); end; function ODForMedOut: TStrings; { Returns init values for outpatient meds dialog. The results must be used immediately. } begin CallV('ORWDPS32 DLGSLCT', [PST_OUTPATIENT]); Result := RPCBrokerV.Results; end; function OIForMedIn(AnIEN: Integer): TStrings; { Returns init values for inpatient meds order item. The results must be used immediately. } begin CallV('ORWDPS32 OISLCT', [AnIEN, PST_UNIT_DOSE, Patient.DFN]); Result := RPCBrokerV.Results; end; function OIForMedOut(AnIEN: Integer): TStrings; { Returns init values for outpatient meds order item. The results must be used immediately. } begin CallV('ORWDPS32 OISLCT', [AnIEN, PST_OUTPATIENT, Patient.DFN]); Result := RPCBrokerV.Results; end; function RatedDisabilities: string; { Returns a list of rated disabilities, if any, for a patient } begin CallV('ORWPCE SCDIS', [Patient.DFN]); Result := RPCBrokerV.Results.Text; end; procedure ValidateIVRate(var x: string); begin x := sCallV('ORWDPS32 VALRATE', [x]); end; //function ValidIVRate(const x: string): Boolean; //{ returns true if the text entered as the IV rate is valid } //begin // Result := sCallV('ORWDPS32 VALRATE', [x]) = '1'; //end; function ValidSchedule(const x: string; PSType: Char = 'I'): Integer; { returns 1 if schedule is valid, 0 if schedule is not valid, -1 pharmacy routine not there } begin Result := StrToIntDef(sCallV('ORWDPS32 VALSCH', [x, PSType]), -1); end; function ValidQuantity(const x: string): Boolean; { returns true if the text entered as the quantity is valid } begin Result := sCallV('ORWDPS32 VALQTY', [Trim(x)]) = '1'; end; function ODForVitals: TStrings; { Returns init values for vitals dialog. The results must be used immediately. } begin CallV('ORWDOR VMSLCT', [nil]); Result := RPCBrokerV.Results; end; initialization uLastDispenseIEN := 0; uLastDispenseMsg := ''; finalization if uMedRoutes <> nil then uMedRoutes.Free; end.