/// <summary> /// Find a resource type from details supplied from a ResourceRequest /// </summary> /// <typeparam name="T">Type of ResourceType to return</typeparam> /// <typeparam name="R">Type of Resource group containing resource type</typeparam> /// <param name="request">Resource request with all required information</param> /// <param name="missingResourceAction">Action if resource group missing</param> /// <param name="missingResourceTypeAction">Action if resource type is missing</param> /// <returns>A resource type component</returns> public T FindResourceType <R, T>(ResourceRequest request, OnMissingResourceActionTypes missingResourceAction = OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes missingResourceTypeAction = OnMissingResourceActionTypes.Ignore) where T : IResourceType where R : ResourceBaseWithTransactions { if (request.Resource is T) { return((T)Convert.ChangeType(request.Resource, typeof(T))); } return(FindResourceType <R, T>(request.ActivityModel, request.ResourceTypeName, missingResourceAction, missingResourceTypeAction)); }
/// <summary> /// Retrieve a ResourceType from a ResourceGroup with specified names /// </summary> /// <param name="requestingModel">name of model requesting resource</param> /// <param name="resourceGroupAndItem">Period seperated list of resource group and type</param> /// <param name="missingResourceAction">Action to take if requested resource group not found</param> /// <param name="missingResourceTypeAction">Action to take if requested resource type not found</param> /// <returns>A reference to the item of type object</returns> public Model GetResourceItem(Model requestingModel, string resourceGroupAndItem, OnMissingResourceActionTypes missingResourceAction, OnMissingResourceActionTypes missingResourceTypeAction) { if (resourceGroupAndItem == null) { resourceGroupAndItem = " . "; } // locate specified resource string[] names = resourceGroupAndItem.Split('.'); if (names.Count() != 2) { string errorMsg = String.Format("@error:Invalid resource group and type string for [{0}], expecting 'ResourceName.ResourceTypeName'. Value provided [{1}] ", requestingModel.Name, resourceGroupAndItem); throw new Exception(errorMsg); } Model resourceGroup = this.GetResourceGroupByName(names[0]) as Model; if (resourceGroup != null) { Model resource = resourceGroup.Children.Where(a => a.Name == names[1]).FirstOrDefault(); if (resource == null) { string errorMsg = String.Format("@error:Unable to locate resources item [r={0}] in resources [r={1}] for [a={2}]", names[1], names[0], requestingModel.Name); switch (missingResourceTypeAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(requestingModel, errorMsg); break; default: break; } return(null); } return(resource); } else { string errorMsg = String.Format("@error:Unable to locate resources of type [r={0}] for [a={1}]", names[0], requestingModel.Name); switch (missingResourceAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(requestingModel, errorMsg); break; default: break; } return(null); } }
/// <summary> /// Retrieve a ResourceType from a ResourceGroup with specified names /// </summary> /// <param name="requestingModel">name of model requesting resource</param> /// <param name="resourceGroupType">Type of the resource group</param> /// <param name="resourceItemName">Name of the resource item</param> /// <param name="missingResourceAction">Action to take if requested resource group not found</param> /// <param name="missingResourceTypeAction">Action to take if requested resource type not found</param> /// <returns>A reference to the item of type object</returns> public Model GetResourceItem(Model requestingModel, Type resourceGroupType, string resourceItemName, OnMissingResourceActionTypes missingResourceAction, OnMissingResourceActionTypes missingResourceTypeAction) { // locate specified resource Model resourceGroup = Apsim.Children(this, resourceGroupType).FirstOrDefault() as Model; if (resourceGroup != null) { Model resource = resourceGroup.Children.Where(a => a.Name == resourceItemName).FirstOrDefault(); if (resource == null) { string errorMsg = String.Format("@error:Unable to locate resources item [r={0}] in resources [r={1}] for [a={2}]", resourceItemName, resourceGroupType.ToString(), requestingModel.Name); switch (missingResourceTypeAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(requestingModel, errorMsg); break; default: break; } return(null); } return(resource); } else { string errorMsg = String.Format("@error:Unable to locate resources of type [r={0}] for [a={1}]", resourceGroupType.ToString(), requestingModel.Name); switch (missingResourceAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(requestingModel, errorMsg); break; default: break; } return(null); } }
/// <summary> /// Retrieve a ResourceType from a ResourceGroup based on a request item including filter and sort options /// </summary> /// <param name="request">A resource request item</param> /// <param name="missingResourceAction">Action to take if requested resource group not found</param> /// <param name="missingResourceTypeAction">Action to take if requested resource type not found</param> /// <returns>A reference to the item of type Model</returns> public Model GetResourceItem(ResourceRequest request, OnMissingResourceActionTypes missingResourceAction, OnMissingResourceActionTypes missingResourceTypeAction) { if (request.FilterDetails != null) { if (request.ResourceType == null) { string errorMsg = String.Format("Resource type must be supplied in resource request from [a={0}]", request.ActivityModel.Name); throw new Exception(errorMsg); } IModel resourceGroup = this.GetGroupByType(request.ResourceType); if (resourceGroup == null) { string errorMsg = String.Format("@error:Unable to locate resources of type [r{0}] for [a={1}]", request.ResourceType, request.ActivityModel.Name); switch (missingResourceAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(request.ActivityModel, errorMsg); break; default: break; } return(null); } // get list of children matching the conditions in filter // and return the lowest item that has enough time available object resourceGroupObject = resourceGroup as object; switch (resourceGroupObject.GetType().ToString()) { case "Models.CLEM.Resources.Labour": // get matching labour types // use activity uid to ensure unique for this request List <LabourType> items = (resourceGroup as Labour).Items; items = items.Filter(request.FilterDetails.FirstOrDefault() as Model); items = items.Where(a => a.LastActivityRequestID != request.ActivityID).ToList(); if (items.Where(a => a.Amount >= request.Required).Count() > 0) { // get labour least available but with the amount needed return(items.Where(a => a.Amount >= request.Required).OrderByDescending(a => a.Amount).FirstOrDefault()); } else { // get labour with most available but with less than the amount needed return(items.OrderByDescending(a => a.Amount).FirstOrDefault()); } default: string errorMsg = "Resource cannot be filtered. Filtering not implemented for [r=" + resourceGroupObject.GetType().ToString() + "] from activity [a=" + request.ActivityModel.Name + "]"; Summary.WriteWarning(request.ActivityModel, errorMsg); throw new Exception(errorMsg); } } else { // check style of ResourceTypeName used // this is either "Group.Type" from dropdown menus or "Type" only. if (request.ResourceTypeName.Contains(".")) { return(GetResourceItem(request.ActivityModel, request.ResourceTypeName, missingResourceAction, missingResourceTypeAction)); } else { return(GetResourceItem(request.ActivityModel, request.ResourceType, request.ResourceTypeName, missingResourceAction, missingResourceTypeAction)); } } }
/// <summary> /// Retrieve a ResourceType from a ResourceGroup based on a request item including filter and sort options /// </summary> /// <param name="Request">A resource request item</param> /// <param name="MissingResourceAction">Action to take if requested resource group not found</param> /// <param name="MissingResourceTypeAction">Action to take if requested resource type not found</param> /// <returns>A reference to the item of type Model</returns> public Model GetResourceItem(ResourceRequest Request, OnMissingResourceActionTypes MissingResourceAction, OnMissingResourceActionTypes MissingResourceTypeAction) { if (Request.FilterDetails != null) { if (Request.ResourceType == null) { string errorMsg = String.Format("Resource type must be supplied in resource request from {0}", Request.ActivityModel.Name); Summary.WriteWarning(Request.ActivityModel, String.Format("Resource type must be supplied in resource request from {0}", Request.ActivityModel.Name)); throw new Exception(errorMsg); } IModel resourceGroup = this.GetByType(Request.ResourceType); if (resourceGroup == null) { string errorMsg = String.Format("Unable to locate resources of type ({0}) for ({1})", Request.ResourceType, Request.ActivityModel.Name); switch (MissingResourceAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(Request.ActivityModel, errorMsg); break; default: break; } return(null); } // get list of children matching the conditions in filter // and return the lowest item that has enough time available object resourceGroupObject = resourceGroup as object; switch (resourceGroupObject.GetType().ToString()) { case "Models.CLEM.Resources.Labour": // get matching labour types // use activity uid to ensure unique for this request List <LabourType> items = (resourceGroup as Labour).Items; items = items.Filter(Request.FilterDetails.FirstOrDefault() as Model); items = items.Where(a => a.LastActivityRequestID != Request.ActivityID).ToList(); if (items.Where(a => a.Amount >= Request.Required).Count() > 0) { // get labour least available but with the amount needed return(items.Where(a => a.Amount >= Request.Required).OrderByDescending(a => a.Amount).FirstOrDefault()); } else { // get labour with most available but with less than the amount needed return(items.OrderByDescending(a => a.Amount).FirstOrDefault()); } default: string errorMsg = "Resource cannot be filtered. Filtering not implemented for " + resourceGroupObject.GetType().ToString() + " from activity (" + Request.ActivityModel.Name + ")"; Summary.WriteWarning(Request.ActivityModel, errorMsg); throw new Exception(errorMsg); } } else { return(GetResourceItem(Request.ActivityModel, Request.ResourceType, Request.ResourceTypeName, MissingResourceAction, MissingResourceTypeAction)); } }
/// <summary> /// Retrieve a ResourceType from a ResourceGroup with specified names /// </summary> /// <param name="RequestingModel">name of model requesting resource</param> /// <param name="ResourceType">Type of the resource group</param> /// <param name="ResourceTypeName">Name of the resource item</param> /// <param name="MissingResourceAction">Action to take if requested resource group not found</param> /// <param name="MissingResourceTypeAction">Action to take if requested resource type not found</param> /// <returns>A reference to the item of type object</returns> public Model GetResourceItem(Model RequestingModel, Type ResourceType, string ResourceTypeName, OnMissingResourceActionTypes MissingResourceAction, OnMissingResourceActionTypes MissingResourceTypeAction) { // locate specified resource Model resourceGroup = Apsim.Children(this, ResourceType).FirstOrDefault() as Model; if (resourceGroup != null) { Model resource = resourceGroup.Children.Where(a => a.Name == ResourceTypeName).FirstOrDefault(); if (resource == null) { string errorMsg = String.Format("Unable to locate resources type ({0}) in resources ({1}) for ({2})", ResourceTypeName, ResourceType.ToString(), RequestingModel.Name); switch (MissingResourceTypeAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(RequestingModel, errorMsg); break; default: break; } return(null); } return(resource); } else { string errorMsg = String.Format("Unable to locate resources of type ({0}) for ({1})", ResourceType.ToString(), RequestingModel.Name); switch (MissingResourceAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new Exception(errorMsg); case OnMissingResourceActionTypes.ReportWarning: Summary.WriteWarning(RequestingModel, errorMsg); break; default: break; } return(null); } }
/// <summary> /// Find a resource type from type of resources and name of resource type component /// </summary> /// <typeparam name="T">Type of ResourceType to return</typeparam> /// <typeparam name="R">Type of Resource group containing resource type</typeparam> /// <param name="requestingModel">The model requesting this resource</param> /// <param name="resourceName">The name identifier NameOfResource.NameOfResourceType or simply NameOfResourceType</param> /// <param name="missingResourceAction">Action if resource group missing</param> /// <param name="missingResourceTypeAction">Action if resource type is missing</param> /// <returns>A resource type component</returns> public T FindResourceType <R, T>(IModel requestingModel, string resourceName, OnMissingResourceActionTypes missingResourceAction = OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes missingResourceTypeAction = OnMissingResourceActionTypes.Ignore) where T : IResourceType where R : ResourceBaseWithTransactions { string[] nameParts = new string[] { "", resourceName }; if (nameParts.Last().Contains('.')) { nameParts = nameParts.Last().Split('.'); if (nameParts.Length > 2) { throw new ApsimXException(requestingModel, $"Invalid resource name identifier for [{requestingModel.Name}], expecting 'ResourceName.ResourceTypeName' or 'ResourceTypeName'. Value provided [{resourceName}]"); } } // not sure it's quickets to find the resource then look at it's children // or look through all descendents for the type and name // if we find children then we use R as a double check bool searchForAllIresourceType = false; bool resGroupNameMatch = true; T resType = default(T); ResourceBaseWithTransactions resGroup = null; if (!typeof(R).IsSubclassOf(typeof(ResourceBaseWithTransactions))) { if (nameParts.First() == "") { searchForAllIresourceType = true; } else { // find resource by name resGroup = FindChild <R>(nameParts.First()); } } else { resGroup = (nameParts.First() != "") ? FindResource <R>(nameParts.First()) : FindResource <R>(); if (resGroup == null && nameParts.First() != "") { // no resource name match so try with just the type resGroupNameMatch = false; resGroup = FindResource <R>(); } } if (searchForAllIresourceType) { resType = FindAllDescendants <T>(nameParts.Last()).FirstOrDefault(); } else { if (resGroup != null) { resType = (resGroup as IModel).FindChild <T>(nameParts.Last()); } } string errorMsg; if (resGroup == null) { errorMsg = $"Unable to locate resource group [r={typeof(R).Name}] for [a={requestingModel.Name}]"; switch (missingResourceAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new ApsimXException(this, errorMsg); case OnMissingResourceActionTypes.ReportWarning: Warnings.CheckAndWrite(errorMsg, Summary, this); break; default: break; } return(default(T)); } else { if (!resGroupNameMatch) { errorMsg = $"Unable to locate resource named [r={nameParts.First()}] for [a={requestingModel.Name}] but a [{typeof(R).Name}] resource was found and will be used."; Warnings.CheckAndWrite(errorMsg, Summary, this); } } if (resType as IModel is null) { errorMsg = $"Unable to locate resource type [r={nameParts.Last()}] in [r={resGroup.Name}] for [a={requestingModel.Name}]"; switch (missingResourceTypeAction) { case OnMissingResourceActionTypes.ReportErrorAndStop: throw new ApsimXException(this, errorMsg); case OnMissingResourceActionTypes.ReportWarning: Warnings.CheckAndWrite(errorMsg, Summary, this); break; default: break; } } return(resType); }