/// <summary> /// Find if one (or more) operations are associated for the vehicle, date and group. /// If an operation is found, but in other group, the method checks if the PDM of the operation found belongs /// to an amplied zone containing the associated group and the PDM. If the amplied zone is found, the operation /// is considered valid. /// </summary> /// <param name="maxTime">If retval is FindOperationsResult.OK, the parameter is filled with the max of OPE_ENDDATE of all operations</param> /// <returns>true if one or more operations were found</returns> public FindOperationsResults FindOperations(out DateTime maxTime) { // 1. Get all operations for the current vehicleID and date. maxTime = DateTime.MinValue; CmpOperationsDB cmp = new CmpOperationsDB(); DataTable dt = cmp.GetData(null, "OPE_INIDATE <= @OPERATIONS.OPE_INIDATE@ AND OPE_ENDDATE >= @OPERATIONS.OPE_ENDDATE@ AND OPE_VEHICLEID = @OPERATIONS.OPE_VEHICLEID@", //ORDER BY OPE_ENDDATE DESC new object[] { _date, _date, _vehicle }); if (dt.Rows.Count == 0) { return(FindOperationsResults.NotFoundAnyOperation); // No operations found... } // Select the operations on the same group DataRow[] currentGroupOperations = dt.Select("OPE_GRP_ID=" + _grpid, "OPE_ENDDATE DESC"); if (currentGroupOperations.Length > 0) { maxTime = Convert.ToDateTime(currentGroupOperations[0]["OPE_ENDDATE"]); return(FindOperationsResults.OK); } else { FindOperationsResults bRet = FindOperationsResults.OK; // Not found operations for the SAME group... let's check PDM of all operations for the vehicle... DateTime maxOpeDate = DateTime.MinValue; foreach (DataRow dr in dt.Rows) { // Check if operation is in the current group or in another group but inside the same amplied zone int opePdm = Convert.ToInt32(dr["OPE_UNI_ID"]); if (CheckForAmpliedZone(opePdm) != -1) { // operation is good // NOTE: When we find the first operation that is in the amplied group, we could finish (because // we have the operations sorted by OPE_ENDDATE). // But we will continue, because we could find a 2nd operation in INVALID zone... in that case the car // must be fined. DateTime opeEnd = Convert.ToDateTime(dr["OPE_ENDDATE"]); if (opeEnd > maxOpeDate) { maxOpeDate = opeEnd; } } else { // Vehicle MUST be fined bRet = FindOperationsResults.OperationOnInvalidZone; break; } } if (bRet == FindOperationsResults.OK) { maxTime = maxOpeDate; } return(bRet); } }
/// <summary> /// Computes the minimum MP. /// Foreach group in the table of groups: /// Get all operations of the group (for article and vehicle passed) /// Sums all OPE_DURATION times /// Set CalculoMP of the group to the value MP - Sum(OPE_DURATION) /// The dtConstraints DataTable is modified (CalculoMP field is set). /// </summary> /// <param name="dtConstraints">DataTable of constraints (obtained with CmpConstraints::GetConstraints())</param> /// <param name="artid">ID of the article (use -1 for NULL)</param> /// <param name="vehid">ID of the vehicle (cannot be NULL)</param> /// <param name="pInDate">DateTime of the new intended operation (OPE_INIDATE or OPE_MOVDATE if passed in the message).</param> public void CalculateMP(DataTable dtConstraints, DateTime pInDate, int artid, string vehid) { CmpOperationsDB cmp = new CmpOperationsDB(); _treeGroups.EvalHandler = new OTS.Framework.Collections.UnorderedTree.EvalItem(TreeItemToId); foreach (DataRow drGroup in dtConstraints.Rows) { // Can use Agrupación, we don't have GROUP_TYPEs at that step // (were all removed in FilterConstraintsTable) int group = Convert.ToInt32(drGroup["Agrupacion"]); UnorderedTree.TreeItem titem = _treeGroups.FindItem(new UnorderedTree.FindItemDelegate(FindItemById), drGroup); // Get an arraylist with the IDs of all descendants of the current group. ArrayList groupChilds = titem.MapcarDescendants(); // Get all operations. int mp = drGroup["MP"] != DBNull.Value ? Convert.ToInt32(drGroup["MP"]) : 0; DateTime opend = pInDate; if (mp > 0) { opend = opend.Subtract(new TimeSpan(0, mp, 0)); } DataTable dtOperations = cmp.GetData(null, "OPE_ENDDATE > @OPERATIONS.OPE_ENDDATE@ AND OPE_ART_ID = @OPERATIONS.OPE_ART_ID@ AND OPE_VEHICLEID = @OPERATIONS.OPE_VEHICLEID@", "OPE_ENDDATE DESC", new object[] { opend, artid != -1 ? (object)artid : (object)DBNull.Value, vehid }); // Iterates throught the operations DataTable. We will exit when we found an OPERATION that: // a) Were not related to the group we are processing (group variable) // b) AND were not related to any of the group_childs of the group... int sumOpeDuration = 0; foreach (DataRow drOperation in dtOperations.Rows) { int opeGroup = Convert.ToInt32(drOperation["OPE_GRP_ID"]); // Check if opeGroup (group of the operation) is the group we are processing (group) or any // descendant of the group we are processing.. if (!groupChilds.Contains(opeGroup)) { break; // finish the iteration over operations table } sumOpeDuration += Convert.ToInt32(drOperation["OPE_DURATION"]); } // At that point we have the sumOpeDuration for the current group, so store it in the CalculoMP row drGroup["CalculoMP"] = mp - sumOpeDuration; } // Now we have "CalculoMP" computed by all operations. _treeGroups.EvalHandler = null; }