maintenance: title: Order Modification Comparison for the Dosage-Range Checking MLM;; mlmname: STD_FUNC_DOSAGE_COMPARE;; arden: version 2.5;; version: 18.4;; institution: Allscripts, Standard MLM;; author: Allscripts Healthcare Solutions, Inc.;; specialist: ;; date: 2018-10-26;; validation: testing;; /* P r o p r i e t a r y N o t i c e */ /* Unpublished (c) 2013 - 2018 Allscripts Healthcare, LLC. and/or its affiliates. All Rights Reserved. P r o p r i e t a r y N o t i c e: This software has been provided pursuant to a License Agreement, with Allscripts Healthcare, LLC. and/or its affiliates, containing restrictions on its use. This software contains valuable trade secrets and proprietary information of Allscripts Healthcare, LLC. and/or its affiliates and is protected by trade secret and copyright law. This software may not be copied or distributed in any form or medium, disclosed to any third parties, or used in any manner not provided for in said License Agreement except with prior written authorization from Allscripts Healthcare, LLC. and/or its affiliates. Notice to U.S. Government Users: This software is {{{SINGLE-QUOTE}}}Commercial Computer Software{{{SINGLE-QUOTE}}}. All product names are the trademarks or registered trademarks of Allscripts Healthcare, LLC. and/or its affiliates. */ /* P r o p r i e t a r y N o t i c e */ library: purpose: When an order is modified, this MLM compares information in the current Order, Order Component, and Order Variable Component Objects and the backup Order, its Order Components, and its Order Variable Component Objects to determine if the dosage information have been modified. Order Component Objects are used for IV-Additives. Order Variable Component Objects are used for Complex Orders. ;; explanation: The comparison is as follows for the current order and its backup order: Order Object: DosageLow, DosageHigh, UOM, Frequency, Route Order Component Object: IV Additive{{{SINGLE-QUOTE}}}s DosageLow, UOM Order Variable Component Object: Complex Order{{{SINGLE-QUOTE}}}s DosageLow, DosageHigh, UOM, Route, and Frequency data. In addition, if the Order is a Concurrent Order, the data affecting the Start and Stop Dates will also be compared. If the information has changed, set the flag to return to calling MLM to indicate that dosage has changed. If the Order Variable Component Objects were created, return the current list of these objects to the calling MLM. ;; keywords: single dose; average daily dose; total daily dose; dosage range ;; knowledge: type: data-driven;; data: time_offset_limit //An Arden Duration that is used with Complex Orders. := ARGUMENT; // Set to true if logging is needed. log_execution_info := false; // Executes only when this MLM is called by the editor if called_by_editor then EvokingObject := read last { Order: This }; endif; // Declare the MLM that will be called by this MLM func_dosage_retrieve_components := MLM {{{SINGLE-QUOTE}}}std_func_dosage_retrieve_components{{{SINGLE-QUOTE}}}; // Initialize flag used to indicate of dose was modified medication_dose_modified := false; // Get the current order{{{SINGLE-QUOTE}}}s Dosage information (order_name, order_med_uom, order_med_dose_low_str, order_med_dose_high_str, order_med_route, order_med_frequency, order_med_significant_date, client_guid, chart_guid, order_complex_order_type, order_catalog_item_obj, order_component_obj, order_user_data_obj, order_variable_component_obj, order_backup_obj ) := read last { Order: Name, UOM, DosageLow, DosageHigh, OrderRouteCode, FrequencyCode, SignificantDtm, ClientGUID, ChartGUID, ComplexOrderType, OrderCatalogMasterItem, OrderComponent, OrderUserData, OrderVariableComponent, Backup REFERENCING EvokingObject}; // Get the backup order{{{SINGLE-QUOTE}}}s Dosage information (backup_order_name, backup_order_med_uom, backup_order_med_dose_low_str, backup_order_med_dose_high_str, backup_order_med_route, backup_order_med_frequency, backup_order_component_obj, backup_order_user_data_obj, backup_order_variable_component_obj ) := read last { Order: Name, UOM, DosageLow, DosageHigh, OrderRouteCode, FrequencyCode OrderComponent,OrderUserData, OrderVariableComponent REFERENCING order_backup_obj}; // Get the current order{{{SINGLE-QUOTE}}}s Component information (comp_name_list, comp_type_list, comp_low_dose_list, comp_hi_dose_list, comp_uom_list, comp_calc_actual_dose_list, comp_calc_uom_per_list, comp_catalog_item_obj_list ):= read {OrderComponent: Name, Type, Dosage, DosageTo, UOM, CalcActualDose, CalcUOMPer, OrderCatalogMasterItem REFERENCING order_component_obj where (Dosage AS number) > 0}; // Get the backup order{{{SINGLE-QUOTE}}}s Component information (oc_backup_name_list, oc_backup_type_list, oc_backup_low_dose_list, oc_backup_hi_dose_list, oc_backup_uom_list, oc_backup_calc_actual_dose_list, oc_backup_calc_uom_per_list, oc_backup_catalog_item_obj_list ):= read {OrderComponent: Name, Type, Dosage, DosageTo, UOM, CalcActualDose, CalcUOMPer, OrderCatalogMasterItem REFERENCING backup_order_component_obj where (Dosage AS number) > 0 }; user_data_weight_string:= "Weight"; user_data_height_string:= "Height"; // Get the current OrderUserData information for weight and height (weight_user_data_code, weight_user_value) := read {OrderUserData: UserDataCode, Value REFERENCING order_user_data_obj WHERE user_data_code = user_data_weight_string }; (height_user_data_code, height_user_value) := read {OrderUserData: UserDataCode, Value REFERENCING order_user_data_obj WHERE user_data_code = user_data_height_string }; // Get the back up OrderUserData information for weight and height (backup_weight_user_data_code, backup_weight_user_value) := read {OrderUserData: UserDataCode, Value REFERENCING backup_order_user_data_obj WHERE user_data_code = user_data_weight_string }; (backup_height_user_data_code, backup_height_user_value) := read {OrderUserData: UserDataCode, Value REFERENCING backup_order_user_data_obj WHERE user_data_code = user_data_height_string }; ;; evoke: ;; logic: // Convert back up and current med order doses to numbers original_low_dose := backup_order_med_dose_low_str as number; current_low_dose := order_med_dose_low_str as number; original_high_dose := backup_order_med_dose_high_str as number; current_high_dose := order_med_dose_high_str as number; // If the current order dosage has changed from previous dosage set modification flag. // Existance tests were added to the condition so that if the change was // from NULL to a non-NULL value, the MLM would recheck the dosage range. If (original_low_dose <> current_low_dose) OR (exist original_low_dose <> exist current_low_dose) OR (original_high_dose <> current_high_dose) OR (exist original_high_dose <> exist current_high_dose) OR (backup_order_med_uom <> order_med_uom) OR (exist backup_order_med_uom <> exist order_med_uom) OR (backup_order_med_route <> order_med_route) OR (exist backup_order_med_route <> exist order_med_route) OR (backup_order_med_frequency <> order_med_frequency) OR (exist backup_order_med_frequency <> exist order_med_frequency) then medication_dose_modified := TRUE; endif; //------------------------------ // Check order user data //------------------------------ // If the weight or height data has changed, then // medication dosage information can change if ( (exists weight_user_value and not exists backup_weight_user_value) or (not exists weight_user_value and exists backup_weight_user_value) or (weight_user_value <> backup_weight_user_value) or (exists height_user_value and not exists backup_height_user_value) or (not exists height_user_value and exists backup_height_user_value) or (height_user_value <> backup_height_user_value) ) then medication_dose_modified := TRUE; endif; //------------------------------ // Check OrderComponent Objects //------------------------------ // If the order has OrderComponent Objects then // Continue checking if the main item has not had its dose modifed If exist order_component_obj and exist comp_name_list and NOT medication_dose_modified then // If count or dosage has changed from previous set modification flag. // Check component item count and then step through list of components. If (count comp_name_list) = (count oc_backup_name_list) then current_additive_index := 1 seqto (count comp_name_list); // Step through list of IV-Additive components and compare for JJ in current_additive_index do comp_name := first(comp_name_list where current_additive_index = JJ); backup_name := first(oc_backup_name_list where current_additive_index = JJ); // Make certain they are the same item. if comp_name = backup_name then // Get the values comp_low_dose := comp_low_dose_list[JJ] as number; backup_low_dose := oc_backup_low_dose_list[JJ] as number; comp_uom := comp_uom_list[JJ]; backup_uom := oc_backup_uom_list[JJ]; // Compare the values, set flag if different if (comp_low_dose <> backup_low_dose) OR (comp_uom <> backup_uom) then medication_dose_modified := TRUE; endif; else // Not the same name so set flag indicating change medication_dose_modified := TRUE; endif; //if comp_name = backup_name enddo; // for JJ else // Number of items different so set flag indicating change medication_dose_modified := TRUE; endif; //If (count comp_name_list) = endif; //If exist order_component_obj //--------------------------------- // Check Order Variable Components //--------------------------------- // If the order has OrderVariable Component Objects then // Continue checking if the main item has not had its dose modifed If exist order_variable_component_obj and NOT medication_dose_modified then // Retrieve the Order_Variable_Component Objects (current_ovc_list, backup_ovc_list ) := call func_dosage_retrieve_components; // Check the details of the Order Components // when there are the same number of components If count current_ovc_list = count backup_ovc_list then // Step through list of Complex Order components and compare for KK in (1 seqto count current_ovc_list) do // Make certain they are the same components by checking GUIDs if current_ovc_list[KK].GUID = backup_ovc_list[KK].GUID then // Compare the values, set flag if different // Compensate for the possibility that one or both values can be NULL. // For Example: // var1 := NULL <> 1 returns NULL // var2 := Exist 1 <> Exist NULL returns TRUE // var3 := var1 or var2 returns TRUE if current_ovc_list[KK].dosage_low <> backup_ovc_list[KK].dosage_low OR (exist current_ovc_list[KK].dosage_low <> exist backup_ovc_list[KK].dosage_low) OR current_ovc_list[KK].dosage_high <> backup_ovc_list[KK].dosage_high OR (exist current_ovc_list[KK].dosage_high <> exist backup_ovc_list[KK].dosage_high) OR current_ovc_list[KK].uom <> backup_ovc_list[KK].uom OR (exist current_ovc_list[KK].uom <> exist backup_ovc_list[KK].uom) OR current_ovc_list[KK].order_route_code <> backup_ovc_list[KK].order_route_code OR (exist current_ovc_list[KK].order_route_code <> exist backup_ovc_list[KK].order_route_code) OR current_ovc_list[KK].frequency_code <> backup_ovc_list[KK].frequency_code OR (exist current_ovc_list[KK].frequency_code <> exist backup_ovc_list[KK].frequency_code) OR current_ovc_list[KK].freq_from_time <> backup_ovc_list[KK].freq_from_time OR (exist current_ovc_list[KK].freq_from_time <> exist backup_ovc_list[KK].freq_from_time) OR current_ovc_list[KK].freq_uom <> backup_ovc_list[KK].freq_uom OR (exist current_ovc_list[KK].freq_uom <> exist backup_ovc_list[KK].freq_uom) then medication_dose_modified := TRUE; endif; else // Not the same GUIDs so set flag indicating change medication_dose_modified := TRUE; endif; //if comp_name = backup_name // If the order is a complex order, a change to the // CalculatedStartDtm, the StopDtm, or the StopAfter can affect // the Total Daily Dose by shifting the DTMs and affecting the totals. // Calculate the difference between the current and backup DTMs // can convert the duration to an absolute number by dividing by 1 minute. diff_calculated_start_dtm := ABS ((current_ovc_list[KK].calculated_start_dtm - backup_ovc_list[KK].calculated_start_dtm)/ 1 minute); diff_estimated_stop_dtm := ABS ((current_ovc_list[KK].estimated_stop_dtm - backup_ovc_list[KK].estimated_stop_dtm)/ 1 minute) ; // Convert the time_offset_limit to an absolute number by dividing 1 minute; time_offset_limit_num := ABS (time_offset_limit/ 1 minute) ; // If the calucated values are off by more than the time_offset_limit_num // or the Stop After Value or Stop After Option Type have changed // then this is a modification that will affect the Total Daily Dose. if diff_calculated_start_dtm > time_offset_limit_num OR diff_estimated_stop_dtm > time_offset_limit_num OR current_ovc_list[KK].stop_after_value <> backup_ovc_list[KK].stop_after_value OR (exist current_ovc_list[KK].stop_after_value <> exist backup_ovc_list[KK].stop_after_value) OR current_ovc_list[KK].stop_after_option_type <> backup_ovc_list[KK].stop_after_option_type OR (exist current_ovc_list[KK].stop_after_option_type <> exist backup_ovc_list[KK].stop_after_option_type) then medication_dose_modified := TRUE; endif; //if diff_calculated_start_dtm enddo; // for KK else // Number of complex order components different so set flag indicating change medication_dose_modified := TRUE; endif; //If count current_ovc_list endif; //If exist order_variable_component_obj // Always Conclude True to Return Answer conclude TRUE; ;; action: return medication_dose_modified, current_ovc_list ; ;; end: