maintenance: title: Called MLM for updating the RX Instruction UDDI;; filename: FORM_RX_ORM_Instruct;; arden: version 2;; version: 5.50;; //FP1 Order Reconciliation Manager institution: St. Clair;; author: Teresa Spicuzza - adapted from MLM by Phil Thomas, Allscripts Knowledge Management;; specialist: ;; date: 2013-08-09;; validation: testing;; library: purpose: This Called MLM is to be assigned to FORM CLOSE on any order form and Medication Catalog item combination that allows for a Complex Dose or Multiple Frequency. It will update the RX Comments UDDI which will transfer to any prescriptions if continued after discharge. ;; explanation: This Called MLM, upon FORM CLOSE, will read the following complex dosing fields and format the cell rows into the RX Instruction UDDI on the form. System UDDIs examined: CalculatedDose, DosageLow and FrequencyCode UDDI Updated: "RX Comments" (Must be on the form to execute). Note: The legnth of the RX Instruction should be configured to 2000 characters but the RX WRiter Sig Line can only handle 140 characters. If this occurs the field value for RX Comments will be truncated to 140 chracters but the MLM will look for the "RX COmments" UDDI. This can handle the full 2000 characters from the "RX Comments" UDDI and will appear on the RX Comments Tab along with Multum data. To transfer the RX Instruction UDDI to the RX Sig Line of a Home Medication or Prescription the following Environemental Profile must be configured: Orders > PrescriptionToOrderFieldMaping > Instructions > Value " RX Instructions" To transfer the RX Coments UDDI to the RX Comments of a Home Medication or Prescription the following Environemental Profile must be configured: Orders > PrescriptionToOrderFieldMaping > Comments > Value " RX Comments" Note: If your institution uses a different Order Form UDDI for this purpose then you will need to alter this MLM and replace "RX Comments" and "RX Instructions" with your UDDI values. Complex Dosing options must be enabled under the Pharamcy configuration section of the Order Catalog Item. Tips: - Form Close will run even if the form is configured to not display and the MLM can update the UDDIS even if protected or hidden. - This MLM will also work with the Frequency option and perfomrm the same behavior as above if discovered. - If you already have an MLM on Form Close you may sub-call this MLM from the existing MLM to avoid reconfiguration of the forms. *** Allscripts Disclaimer: Client is responsible for all decisions, acts, and omissions of any persons in connection with the delivery of medical care or other services to any patients. Before any Licensed Materials are placed into a live production environment, it is Client’s responsibility to review and test all Licensed Materials and associated workflows and other content, as implemented, make independent decisions about system settings and configuration based upon Client’s needs, practices, standards and environment, and reach its own independent determination that they are appropriate for such live production use. Any such use by Client (or its Authorized Users) will constitute Client’s representation that it has complied with the foregoing. Client shall ensure that all Authorized Users are appropriately trained in use of the then-deployed release of the Software prior to their use of the Software in a live production environment. Clinical Materials are tools to assist Authorized Users in the delivery of medical care, but should not be viewed as prescriptive or authoritative. Clinical Materials are not a substitute for, and Client shall ensure that each Authorized User applies in conjunction with the use thereof, independent professional medical judgment. Clinical Materials are not designed for use, and Client shall not use them, in any system that provides medical care without the participation of properly trained personnel. Any live production use of Clinical Materials by Client (or its Authorized Users) will constitute Client’s acceptance of clinical responsibility for the use of such materials. History: 08.12.2013 TMS Adapted from MLM (FORM_Preset_MultiDose_RX) by Phil Thomas, Allscripts Knowledge Management with modifications to calculate start dates of subsequent order rows from first row value for for decreasing (taper) or increasing dose. Changed size of Instructions, and added then stop comment for end of taper. Logic added for user schedule translation to patient friendly instructions, order route to be added when specific (i.e., right eye, via tube); include synonym for Aspart Insulin, add PRN Reason when populated to Rx Comments. Called from FORM_Now_and_Then. CSR 31639 11.04.2014 TMS Added logic to write medrol dose pak instructions to comment field when orders entered with Medrol Dosing dose option for inclusion in discharge reconciliation. CSR 31407 11.05.2015 TMS Added insulin brand names "Lantus" for Insulin Glargine and "Levemir" for Insulin Detemir to populate the RX comments for inclusion in discharge reconciliation. CSR 33859 07.23.2019 TMS CSR 37676 - Change log_execution_info to false per upgrade analysis. ;; keywords: Called MLMs, Form fields, RX Instructions, Orders Reconciliation Manager, RX Comments; ;; knowledge: type: data-driven;; data: // This MLM is passed three arguments, of types // communication_type, form_type and client info object respectively. (this_communication, // Communication object this_form, // Form object client_info_obj //Arden ClientInfo object ) := argument; PrimaryObjdetail:=this_communication.PrimaryObj; OrderName := PrimaryObjdetail.name; /*******************Make Changes To Spelling And Flags In This Section*******************/ /* Set to true if a decision.log is needed.*/ log_execution_info := FALSE; /* Null field variables */ RX_Summary := Null; RX_Comments_User := ""; //Formatting Characters SP := " "; CR := 13 formatted with "%c"; LF := 10 formatted with "%c"; CRLF:= CR||LF; TAB := 9 formatted with "%c"; xxcounter := 0; /***************************************************************************************/ // Initialize error message error_message:=""; // standard_libs := MLM {{{SINGLE-QUOTE}}}std_include_libs{{{SINGLE-QUOTE}}}; // Assigns fields passed in the Form object to the Field object field_list:= this_form.fields; //Capture the RX Comments Data Item and test if present, Do not proceeed with MLM if not found on order form RX_Comments_field := first of (field_list where field_list.DataItemName = "Rx Comments"); RX_Instructions_field := last of (field_list where field_list.DataItemName = "Rx Instructions"); FreqText := " "; requested_date := last of (field_list where field_list.DataItemName = "RequestedDate" ); requested_time := last of (field_list where field_list.DataItemName = "RequestedTime" ); stop_after:= last of (field_list where field_list.DataItemName = "StopAfter" ); stop_after_Value := stop_after.value; stop_date := last of (field_list where field_list.DataItemName = "StopDate" ); stop_time := last of (field_list where field_list.DataItemName = "StopTime" ); stop_time_value := stop_time.value ; is_prn := last of (field_list where field_list.DataItemName = "IsPRN" ); regular_freq := last of (field_list where field_list.DataItemName = "FrequencyCode"); requested_time_value := requested_time.value; regular_freq_value := regular_freq.value; start_now := last of (field_list where field_list.DataItemName = "PRX_Dosing Start Now" ); start_now_value := start_now.value; PRX_PRN_Reason_field := first of (field_list where field_list.DataItemName = "PRX_PRNCONDITION"); PRX_PRN_Reason_field_value := PRX_PRN_Reason_field.value; Route_Code := last of (field_list where field_list.DataItemName = "OrderRouteCode" ); SpecifyRoute := ("Right Eye", "Left Eye", "Both Eyes", "Right Ear", "Left Ear", "Both Ears", "Alternating Nostrils", "Left Nostril", "Right Nostril", "Each Nostril", "Via Tube"); FreqText := " "; If PRX_PRN_Reason_field.value is NULL then ReasonText := " "; else ReasonText := "for " || PRX_PRN_Reason_field_value; endif; If Route_Code.value in SpecifyRoute then RouteText := " to " || Route_Code.value; else RouteText := " "; endif; RX_Comments_field_value := RX_Comments_field.value; str_parse := mlm {{{SINGLE-QUOTE}}}UTIL_STRING_PARSE{{{SINGLE-QUOTE}}}; FreqTranslate := (); FreqTranslate := read { "select value from cv3userdictionaryvalue v with (nolock)" || " where userdictionarycode = {{{SINGLE-QUOTE}}}PRX_ORM Frequency Translation{{{SINGLE-QUOTE}}} " || " and active = {{{SINGLE-QUOTE}}}1{{{SINGLE-QUOTE}}} " }; If exists RX_Comments_field then //Save any data already enetered by the user If RX_Comments_field.Value is not NULL then RX_Comments_User := RX_Comments_field.Value; Endif; If OrderName matches pattern "Insulin Aspart%" then InsulinNote := "(Humalog or NovoLog)"; elseif Ordername matches pattern "Insulin Glargine%" then InsulinNote := "(Lantus)"; elseif Ordername matches pattern "Insulin Detemir%" then InsulinNote := "(Levemir)"; else InsulinNote := " "; endif; If regular_freq_value.FrequencySummary <> "" then NumMembs:= count FreqTranslate; for k in (1 seqto (NumMembs)) do listings := call str_parse with FreqTranslate[k],"|"; tempstr:=first of (listings); if tempstr = regular_freq_value.FrequencySummary then if exists(listings[2]) then FreqText := listings [2]; else FreqText := " "; endif; endif; enddo; RX_Comments_field.value := FreqText || " " || RouteText || " " || ReasonText || " " || insulinnote; RX_Instructions_field.value := FreqText || " " || RouteText || " " || ReasonText || " " || insulinnote; endif; If regular_freq_value.FrequencySummary = "" AND regular_freq_value.FreqUOM = "irregular" then RX_Comments_field.value := ""; RX_Instructions_field.value := ""; // obtain a list of the scheduled dates and times freq_schedules := regular_freq_value.FreqIrregularDtm; // find the earliest scheduled time earliest_time := minimum of freq_schedules; // extract the time from the date_time sched_hour := EXTRACT HOUR(earliest_time); sched_minute := EXTRACT MINUTE(earliest_time); sched_time := sched_hour || ":" || sched_minute; // create patient friendly Rx instructions and Rx comments for ORM for user schedule frequencies adminat := ""; freq_schedules_sort := sort (regular_freq_value.FreqIrregularDtm as time); Irregtimes := count freq_schedules; for n in (1 seqto Irregtimes ) do schedtime := freq_schedules_sort [n]; schedmin := EXTRACT Minute(schedtime as time); if (schedmin as number) < 10 then schedmin := "0" || schedmin ; endif; schedhour := EXTRACT HOUR(schedtime as time); if (schedhour as number) >= 12 then timeofday := "PM"; if (schedhour as number) >= 13 then schedhour := schedhour - 12; endif; else timeofday := "AM"; if (schedhour as number) = 0 then schedhour := 12; endif; endif; schedmm := EXTRACT Month(schedtime as time); scheddd := EXTRACT Day(schedtime as time); schedyy := EXTRACT Year(schedtime as time); adminat := adminat || schedmm ||"/" ||scheddd || "/" || schedyy || " at " || schedhour || ":" || schedmin || timeofday || "; "; enddo; // populate rxinstructions and rx comments with user schedule translation for irregular rxinstruct := "on " || adminat ; RX_Comments_field.value := rxinstruct || " " || RouteText || " " || ReasonText || " " || InsulinNote; RX_Instructions_field.value := rxinstruct || " " || RouteText || " " || ReasonText || " " || InsulinNote; endif; //if user schedule and irregular //Update Rx Instructions and Rx Comments with patient friendly definitions for User Schedule If regular_freq_value.FrequencySummary = "" AND (regular_freq_value.FreqUOM = "day" OR regular_freq_value.FreqUOM = "week") then if regular_freq_value.FreqUOM = "day" then If (regular_freq_value.FreqFromTime as number) = 1 then weeklydays := "day"; elseif (regular_freq_value.FreqFromTime as number) > 1 then weeklydays := regular_freq_value.FreqFromTime || " days"; endif; endif; If regular_freq_value.FreqUOM = "week" then If "Monday" in regular_freq_value.FreqWeeklyDays then If weeklydays is not Null then weeklydays := weeklydays || ", Monday"; else weeklydays := "Monday"; endif; endif; If "Tuesday" in regular_freq_value.FreqWeeklyDays then If weeklydays is not Null then weeklydays := weeklydays || ", Tuesday"; else weeklydays := "Tuesday"; endif; endif; If "Wednesday" in regular_freq_value.FreqWeeklyDays then If weeklydays is not Null then weeklydays := weeklydays || ", Wednesday"; else weeklydays := "Wednesday"; endif; endif; If "Thursday" in regular_freq_value.FreqWeeklyDays then If weeklydays is not Null then weeklydays := weeklydays || ", Thursday"; else weeklydays := "Thursday"; endif; endif; If "Friday" in regular_freq_value.FreqWeeklyDays then If weeklydays is not Null then weeklydays := weeklydays || ", Friday"; else weeklydays := "Friday"; endif; endif; If "Saturday" in regular_freq_value.FreqWeeklyDays then If weeklydays is not Null then weeklydays := weeklydays || ", Saturday"; else weeklydays := "Saturday"; endif; endif; If "Sunday" in regular_freq_value.FreqWeeklyDays then If weeklydays is not Null then weeklydays := weeklydays || ", Sunday"; else weeklydays := "Sunday"; endif; endif; endif; Numtimes := count regular_freq_value.FreqTimes; if Numtimes > 1 then septime := ", "; adminat := ""; else septime := "";adminat := ""; endif; for k in (1 seqto NumTimes) do schedtime := regular_freq_value.FreqTimes [k]; schedmin := EXTRACT Minute(schedtime as time); if (schedmin as number) < 10 then schedmin := "0" || schedmin ; endif; schedhour := EXTRACT HOUR(schedtime as time); if (schedhour as number) >= 12 then timeofday := "PM"; if (schedhour as number) >= 13 then schedhour := schedhour - 12; endif; else timeofday := "AM"; if (schedhour as number) = 0 then schedhour := 12; endif; endif; admintime := schedhour ||":" || schedmin || timeofday; if numtimes = k then Adminat := adminat || admintime; else adminat := adminat || admintime || septime; endif; enddo; // populate rxinstructions and rx comments with user schedule translation for weekly and daily rxinstruct := "every " || WeeklyDays || " at " || adminat; RX_Comments_field.value := rxinstruct || " " || RouteText || " " || ReasonText || " " || InsulinNote; RX_Instructions_field.value := rxinstruct || " " || RouteText || " " || ReasonText || " " || InsulinNote; endif; // this section is for calculated dosing - not used /* //Capture the Calculated Dose Data Item and all componenets CalculatedDose_field := first of (field_list where field_list.DataItemName = "CalculatedDose"); If exists CalculatedDose_field then CalcDoseValue:= CalculatedDose_field.Value; // Statements used to read the Complex Dosing Grid. // If DosingOption field is NULL, we expect the structure // stored in Value is regular CalculatedDose compound value // structure. If exists CalcDoseValue.DosingOption AND CalcDoseValue.DosingOption is NOT NULL then // access the dosing options grid CalcGridDosingOption := CalcDoseValue.DosingOption; CalcGridRows := CalcDoseValue.Rows; CalcGridCols := CalcDoseValue.Cols; CalcGridDefAllowAddRemove := CalcDoseValue.ConfigAllowRowAddRemove; CalcGridAllowAddRemove := CalcDoseValue.AllowRowAddRemove; Else // access as regular CalcDose fields CalculatedDose_obj := OBJECT [DosageLow, CalcActualDose, CalcOverrideReason, CalcRequestedDose, CalcTotalDailyDose, CalcDoseUOM, CalcUOMPer]; CalculatedDoseValue := CalculatedDose_field.Value; // Statements used to read calculateddose sub-fields Found_CalcDosageLow := CalculatedDoseValue.DosageLow; Found_CalcActualDose := CalculatedDoseValue.CalcActualDose; Found_CalcOverrideReason := CalculatedDoseValue.CalcOverrideReason; Found_CalcRequestedDose := CalculatedDoseValue.CalcRequestedDose; Found_CalcTotalDailyDose := CalculatedDoseValue.CalcTotalDailyDose; Found_CalcUom := CalculatedDoseValue.CalcUOM; Found_CalcUomPER := CalculatedDoseValue.CalcUOMPer; Found_CalcReadONly := CalculatedDose_field.control_read_only; Endif; //Explode the Complex Dosing Option if found and update the RX Comments field for conversion to a prescription If Exist CalcGridRows then // Build a list of found rows and columns of the dosing option grid index_list := 0 seqto ( count CalcGridRows ); Total_Rows := count CalcGridRows; for M in index_list do //Sequentially go thru each of the dosing option rows to get the data item values assigned temp_Cell_Row:=Last(First M from CalcGridRows.Cells); //Look for the Calculated Dose Data item and read the value temp_Cell_DosageLow := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "CalculatedDose"); temp_Cell_ItemValue:=temp_Cell_DosageLow.ItemValue; temp_Cell_DosageLow_Value:=temp_Cell_ItemValue.DosageLow; //Check to see if a Dose is present to proceed If temp_Cell_DosageLow_Value Is Not NULL then //If the last row then indicate the last like the application does If M = Total_Rows Then RX_Summary := RX_Summary || CRLF || "Last: " || temp_Cell_DosageLow_Value || SP; ElseIf RX_Summary Is Null then RX_Summary := "Start: " || temp_Cell_DosageLow_Value || SP; Else RX_Summary := RX_Summary || CRLF || "Then: " || temp_Cell_DosageLow_Value || SP; Endif; //Capture the Unit of Measure and add to the RX Summary if found temp_Cell_UOM := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "Uom"); temp_Cell_UOM_Value:=temp_Cell_UOM.ItemValue; //Update the RX Summary if a value was found If temp_Cell_UOM_Value Is Not NULL then RX_Summary := RX_Summary || temp_Cell_UOM_Value|| SP; Endif; //Capture the Frequency value and add to the RX Summary if found temp_Cell_Frequency := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "FrequencyCode"); temp_Cell_ItemValue:=temp_Cell_Frequency.ItemValue; temp_Cell_Frequency_Value:=temp_Cell_ItemValue.FrequencySummary; //Update the RX Summary if a value was found If temp_Cell_Frequency_Value Is Not NULL Then RX_Summary := RX_Summary || temp_Cell_Frequency_Value|| SP; Endif; //Capture the Route value and add to the RX Summary if found temp_Cell_Route := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "OrderRouteCode"); temp_Cell_Route_Value:=temp_Cell_Route.ItemValue; //Update the RX Summary if a value was found If temp_Cell_Route_Value Is Not NULL then RX_Summary := RX_Summary || ", " || temp_Cell_Route_Value; Endif; //Capture the Stop After value and add to the RX Summary if found temp_Cell_StopAfter := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "StopAfter"); temp_Cell_ItemValue:=temp_Cell_StopAfter.ItemValue; temp_Cell_NUMBER_Value:=temp_Cell_ItemValue.NUMBER; temp_Cell_Option_Value:=temp_Cell_ItemValue.Option; //Update the RX Summary if a value was found If temp_Cell_Option_Value Is Not NULL Then RX_Summary := RX_Summary || ", for " || temp_Cell_NUMBER_Value || SP || temp_Cell_Option_Value; Endif; Endif; //A Row has a Dose enddo; //End of Row List Loop Endif; //tapering Dose was found Endif; //End of CalculatedDose Examination */ // This looks for the presence of the field dataitem - dosagelow - and stores it incase a checkbox is removed. DosageLow_field := first of (field_list where field_list.DataItemName = "DosageLow"); If exists DosageLow_field then DoseLowValue := DosageLow_field.Value; // DosageLow value can either be a numeric value or a //complex dosing grid value. If exists DoseLowValue And DoseLowValue is not NUMBER then // access the dosing options grid DosingOption := DoseLowValue.DosingOption; DoseLowGrid_ColList := DoseLowValue.Cols; DoseLowGrid_RowList := DoseLowValue.Rows; AllowAddRemove := DoseLowValue.AllowRowAddRemove; ConfigAllowRowAddRemove := DoseLowValue.ConfigAllowRowAddRemove; Else // access as regular DosageLow field Is_Calc_Field := FALSE; Endif; //DoseageLow was a complex dose option If Exist DoseLowGrid_RowList then If DosingOption = "Medrol Dose Pak" then dosingtype := "DosePak"; endif; // Build a list of found rows and columns of the dosing option grid index_list_dl := 0 seqto ( count DoseLowGrid_RowList ); Total_Rows_dl := count DoseLowGrid_RowList; //Build a loop to go thru the list of Rows found for M in index_list_dl do //Sequentially go thru each of the dosing option rows to get the data item values assigned // and obtain prior row info if available for frequency, durationa and start date temp_Cell_Row:=Last(First M from DoseLowGrid_RowList.Cells); If M > 1 then P := (M as number)-1; prior_cell_row :=Last(First P from DoseLowGrid_RowList.Cells); endif; //Look for the Dose Data item and read the value temp_Cell_DosageLow := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "DosageLow"); temp_Cell_DosageLow_Value:=temp_Cell_DosageLow.ItemValue; //Check to see if a Dose is present to proceed If temp_Cell_DosageLow_Value Is Not NULL then //If the last row then indicate the last like the application does If M = Total_Rows_dl Then // RX_Summary := RX_Summary || CRLF || "Last: " || temp_Cell_DosageLow_Value || SP; RX_Summary := RX_Summary || CRLF || "THEN: " || temp_Cell_DosageLow_Value || SP; FirstEntry := "No"; EndMessage := "THEN STOP" || " " || RouteText || " " || ReasonText; ElseIf RX_Summary Is Null then RX_Summary := "START: " || temp_Cell_DosageLow_Value || SP; EndMessage := " "; FirstEntry := "Yes"; Else // RX_Summary := RX_Summary || CRLF || "Then: " || temp_Cell_DosageLow_Value || SP; RX_Summary := RX_Summary || CRLF || " THEN: " || temp_Cell_DosageLow_Value || SP; EndMessage := " "; FirstEntry := "No"; Endif; //Capture the Unit of Measure and add to the RX Summary if found temp_Cell_UOM := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "Uom"); temp_Cell_UOM_Value:=temp_Cell_UOM.ItemValue; //Update the RX Summary if a value was found If temp_Cell_UOM_Value Is Not NULL then RX_Summary := RX_Summary || temp_Cell_UOM_Value|| SP; Endif; //Capture the Frequency value and add to the RX Summary if found temp_Cell_Frequency := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "FrequencyCode"); temp_Cell_ItemValue:=temp_Cell_Frequency.ItemValue; temp_Cell_Frequency_Value:=temp_Cell_ItemValue.FrequencySummary; prior_cell_Frequency := first of (prior_Cell_Row where prior_Cell_Row.DataItemCode = "FrequencyCode"); prior_Cell_ItemValue:=prior_Cell_Frequency.ItemValue; prior_Cell_Frequency_Value:=prior_Cell_ItemValue.FrequencySummary; If prior_Cell_Frequency_Value Is Not NULL and dosingtype <> "DosePak" Then (PriorFreqType, PriorFreqSpan, PriorFreqUom) := read last {"Select DefinitionType, TimeFromValue, TimeUom " ||" From cv3Frequency " ||" Where Code = " || SQL(Prior_Cell_Frequency_Value) }; Endif; //Update the RX Summary if a value was found If temp_Cell_Frequency_Value Is Not NULL and dosingtype <> "DosePak" Then RX_Summary := RX_Summary || temp_Cell_Frequency_Value|| SP; (FreqType, FreqSpan, FreqUom) := read last {"Select DefinitionType, TimeFromValue, TimeUom " ||" From cv3Frequency " ||" Where Code = " || SQL(temp_Cell_Frequency_Value) }; Endif; // compare prior row frequency with current row frequency to determine if // frequency is increasing, decreasing, or staying the same. If dosingtype <> "DosePak" Then If priorfreqtype = 2 and freqtype = 1 then dosingtype := "increasing"; freqspan := freqtype; elseif priorfreqtype = 1 and freqtype = 2 then dosingtype := "decreasing"; priorfreqspan := priorfreqtype; elseif priorfreqtype = 2 and freqtype = 2 then if priorfreqspan > freqspan then dosingtype := "increasing"; elseif priorfreqspan < freqspan then dosingtype := "decreasing"; else dosingtype := "same"; endif; elseif priorfreqtype = 1 and freqtype = 1 then dosingtype := "same"; priorfreqspan := priorfreqtype; freqspan := freqtype; endif; endif; //Capture the Route value and add to the RX Summary if found temp_Cell_Route := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "OrderRouteCode"); temp_Cell_Route_Value:=temp_Cell_Route.ItemValue; //Update the RX Summary if a value was found If temp_Cell_Route_Value Is Not NULL and dosingtype <> "DosePak" Then RX_Summary := RX_Summary || ", " || temp_Cell_Route_Value; Endif; //Capture the Stop After value and add to the RX Summary if found temp_Cell_StopAfter := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "StopAfter"); temp_Cell_ItemValue:=temp_Cell_StopAfter.ItemValue; temp_Cell_NUMBER_Value:=temp_Cell_ItemValue.NUMBER; temp_Cell_Option_Value:=temp_Cell_ItemValue.Option; prior_Cell_StopAfter := first of (prior_Cell_Row where prior_Cell_Row.DataItemCode = "StopAfter"); prior_Cell_ItemValue:=prior_Cell_StopAfter.ItemValue; prior_Cell_NUMBER_Value:=prior_Cell_ItemValue.NUMBER; prior_Cell_Option_Value:=prior_Cell_ItemValue.Option; //Update the RX Summary if a value was found If temp_Cell_Option_Value Is Not NULL and dosingtype <> "DosePak" Then RX_Summary := RX_Summary || " for " || temp_Cell_NUMBER_Value || SP || temp_Cell_Option_Value || SP ; endif; temp_Cell_Start := first of (temp_Cell_Row where temp_Cell_Row.DataItemCode = "RequestedDate"); temp_Cell_Start_Value:=temp_Cell_Start.ItemValue; prior_Cell_Start := first of (prior_Cell_Row where prior_Cell_Row.DataItemCode = "RequestedDate"); prior_Cell_Start_Value:=prior_Cell_Start.ItemValue; If prior_Cell_Start_Value Is Not NULL and FirstEntry = "No" and prior_Cell_Option_Value = "Days" and dosingtype <> "DosePak" Then PriorNumdays := prior_Cell_ItemValue.NUMBER; // determine start date of current row dependent upon frequency and duration of current and // prior row. (Increasing, decreasing or same) If dosingtype = "decreasing" or dosingtype = "same" then Calc_duration := (Priornumdays as number) - 1; Offsetdays := Calc_duration - (PriorFreqSpan *(Int(Calc_duration /PriorFreqSpan))); Addtodate := Calc_duration + FreqSpan - offsetdays; temp_Cell_Start.ItemValue := prior_Cell_Start_Value + addtodate day ; yr := extract year temp_Cell_Start.ItemValue ; mn := extract month temp_Cell_Start.ItemValue ; if mn < 10 then mn := "0" || mn; endif; dd := extract day temp_Cell_Start.ItemValue ; if dd < 10 then dd := "0" || dd; endif; DisplayDate := mn || "-" || dd || "-" || yr ; elseif dosingtype = "increasing" then Calc_duration := (Priornumdays as number) - 1; Offsetdays := Calc_duration - (PriorFreqSpan *(Int(Calc_duration /PriorFreqSpan))); Addtodate := Calc_duration + PriorFreqSpan - offsetdays; temp_Cell_Start.ItemValue := prior_Cell_Start_Value + addtodate day ; yr := extract year temp_Cell_Start.ItemValue ; mn := extract month temp_Cell_Start.ItemValue ; if mn < 10 then mn := "0" || mn; endif; dd := extract day temp_Cell_Start.ItemValue ; if dd < 10 then dd := "0" || dd; endif; DisplayDate := mn || "-" || dd || "-" || yr ; endif; RX_Summary := RX_Summary || CRLF || " Begin: " || DisplayDate || SP || EndMessage|| CRLF; elseIf prior_Cell_Start_Value Is NULL and FirstEntry = "Yes" and temp_Cell_Option_Value = "Days" and dosingtype <> "DosePak" Then yr := extract year temp_Cell_Start.ItemValue ; mn := extract month temp_Cell_Start.ItemValue ; if mn < 10 then mn := "0" || mn; endif; dd := extract day temp_Cell_Start.ItemValue ; if dd < 10 then dd := "0" || dd; endif; DisplayDate := mn || "-" || dd || "-" || yr ; RX_Summary := RX_Summary || CRLF || " Begin: " || DisplayDate || SP || EndMessage || CRLF; elseIf prior_Cell_Start_Value Is NULL and dosingtype = "DosePak" Then yr := extract year temp_Cell_Start.ItemValue ; mn := extract month temp_Cell_Start.ItemValue ; if mn < 10 then mn := "0" || mn; endif; dd := extract day temp_Cell_Start.ItemValue ; if dd < 10 then dd := "0" || dd; endif; StartingDisplayDate := mn || "-" || dd || "-" || yr ; elseIf prior_Cell_Start_Value Is Not NULL and dosingtype = "DosePak" Then RX_Summary := "Start on " || StartingDisplayDate || CRLF || "Day 1: 2 tabs before breakfast, 1 tab after lunch, 1 tab after dinner, 2 tabs at bedtime" || CRLF || "Day 2: 1 tab before breakfast, 1 tab after lunch, 1 tab after dinner, 2 tabs at bedtime" || CRLF || "Day 3: 1 tab before breakfast, 1 tab after lunch, 1 tab after dinner, 1 tab at bedtime" || CRLF || "Day 4: 1 tab before breakfast, 1 tab after lunch, 1 tab at bedtime" || CRLF || "Day 5: 1 tab before breakfast, 1 tab at bedtime" || CRLF || "Day 6: 1 tab before breakfast"; endif; Endif; //A Row has a Dose enddo; //End of Row List Loop Endif; //DosageLow was found with a value Endif; //DosageLow was found // this section is for complex frequency dosing /* //Look for a Complex Frequency and Update th RX Comments accordingly Freq_field := first of (field_list where field_list.DataItemName = "FrequencyCode"); If exists Freq_field then FreqValue:= Freq_field.Value; // If DosingOption sub-field exists, this is a Frequency Grid If exists FreqValue.DosingOption and FreqValue.DosingOption is NOT NULL then // Get Grid information AllowRowAddRemove := FreqValue.AllowRowAddRemove; ConfigAllowRowAddRemove := FreqValue.ConfigAllowRowAddRemove; // Get Row information GridRows:= FreqValue.Rows; //Explode the Complex Dosing Option Freq if found and update the RX Comments field for conversion to a prescription If Exist GridRows then // Build a list of found rows and columns of the dosing option grid index_list_fq := 0 seqto ( count GridRows ); Total_Rows_fq := count GridRows; for M in index_list_fq do //Get the Frequency Code temp_FreqSummary :=Last(First M from GridRows.FrequencySummary); //Update the RX Summary if a value was found If temp_FreqSummary Is Not NULL Then //If the last row then indicate the last like the application does If M = Total_Rows_fq Then RX_Summary := RX_Summary || CRLF || "Last: " || temp_FreqSummary || SP; ElseIf RX_Summary Is Null then RX_Summary := "Start: " || temp_FreqSummary || SP; Else RX_Summary := RX_Summary || CRLF || "Then: " || temp_FreqSummary || SP; Endif; Endif; //Get the Frequency From Time temp_FreqFromTime :=Last(First M from GridRows.FreqFromTime); //Update the RX Summary if a value was found If temp_FreqFromTime > 0 Then RX_Summary := RX_Summary || "From: " || temp_FreqFromTime || SP; Endif; //Get the Frequency To Time temp_FreqToTime :=Last(First M from GridRows.FreqToTime); //Update the RX Summary if a value was found If temp_FreqToTime > 0 Then RX_Summary := RX_Summary || "To: " || temp_FreqToTime || SP; Endif; //Get the Frequency FreqEventModifier temp_FreqEventModifier :=Last(First M from GridRows.FreqEventModifier); //Update the RX Summary if a value was found If temp_FreqEventModifier Is Not NULL Then RX_Summary := RX_Summary || temp_FreqEventModifier || SP; Endif; //Get the Frequency FreqEventCode temp_FreqEventCode :=Last(First M from GridRows.FreqEventCode); //Update the RX Summary if a value was found If temp_FreqEventCode Is Not NULL Then RX_Summary := RX_Summary || temp_FreqEventCode || SP; Endif; //Get the Frequency Stop After Value temp_StopAfterNumber :=Last(First M from GridRows.StopAfterNumber); //Update the RX Summary if a value was found If temp_StopAfterNumber Is Not NULL Then RX_Summary := RX_Summary || "Stop After: " || temp_StopAfterNumber || SP; Endif; temp_StopAfterOption :=Last(First M from GridRows.StopAfterOption); //Update the RX Summary if a value was found If temp_StopAfterOption Is Not NULL Then RX_Summary := RX_Summary || temp_StopAfterOption || SP; Endif; //Reserve for Future Use //Found_DataItemCode1:= Found_Freq.DataItemCode1; //Found_DataItemValue1:= Found_Freq.DataItemValue1; //Found_DataItemCode2:= Found_Freq.DataItemCode2; //Found_DataItemValue2:= Found_Freq.DataItemValue2; //Found_DataItemCode3:= Found_Freq.DataItemCode3; //Found_DataItemValue3:= Found_Freq.DataItemValue3; //Found_DataItemCode4:= Found_Freq.DataItemCode4; //Found_DataItemValue4:= Found_Freq.DataItemValue4; //Found_DataItemCode5:= Found_Freq.DataItemCode5; //Found_DataItemValue5:= Found_Freq.DataItemValue5; Enddo; //End of Grid Row Loop Endif; //Grid Row exists ENDIF; //The Frequency is a dosing option type ENDIF; //FrequencyCode was found */ //Update the RX Comments UDDI with the Variable DOse or Multiple Frequency option. If RX_Summary Is not NULL then //The RX WRiter Sig Comment UDDI can only handle 2000 characters so trim to fit on form if (length RX_Summary) > 2000 then RX_Summary_Truncate := (substring 1997 characters starting at 1 from RX_Summary) || "..."; RX_Comments_field.Value := RX_Summary_Truncate; Else RX_Comments_field.Value := RX_Summary; Endif; //Update RX Comments //Add a note to the RX Instructions field (if exists) which displays when converting to a Home Medication. //Note - This field can only accomodate 140 chracters at this time so it will be truncated. //Check for the RX Instructions: RX_Instructions_field := first of (field_list where field_list.DataItemName = "Rx Instructions"); If exists RX_Instructions_field then // If (length RX_Summary) > 140 then // RX_Instructions_Truncate := (substring 137 characters starting at 1 from RX_Summary) || "..."; If (length RX_Summary) > 500 then RX_Instructions_Truncate := (substring 497 characters starting at 1 from RX_Summary) || "..."; RX_Instructions_field.Value := RX_Instructions_Truncate; Else RX_Instructions_field.Value := RX_Summary; Endif; Endif; Endif; //An RX Summary was found //The Field was not on the Order Form Elseif RX_Summary Is not NULL Then error_message := "The RX Comment Data Item was not found on the form and a Complex Dose was entered."; Endif; //The RX Comments UDDI was found on the form If error_message <> "" Then this_communication.DisplayForm := "Yes"; this_communication.Message := "error_message"; this_communication.MessageType := "Informational"; Endif; ;; evoke: // No evoke statement ;; logic: conclude true; ;; action: // This MLM returns two parameters, of types communication_type and form_type respectively. return this_communication, this_form; ;; end: