///<inheritdoc/> public bool DoTransmute(ResourceRequest request, double shortfallPacketsNeeded, double requiredByActivities, ResourcesHolder holder, bool queryOnly) { request.Required = shortfallPacketsNeeded * AmountPerPacket; if (request.Required > 0) { request.FilterDetails = groupings; CLEMActivityBase.TakeLabour(request, !queryOnly, request.ActivityModel, resources, OnPartialResourcesAvailableActionTypes.UseResourcesAvailable); } return(request.Provided >= request.Required); }
/// <summary> /// Performs the transmutation of resources into a required resource /// </summary> public void TransmutateShortfall(List <ResourceRequest> requests, bool queryOnly) { List <ResourceRequest> shortfallRequests = requests.Where(a => a.Required > a.Available).ToList(); // Search through all limited resources and determine if transmutation available foreach (ResourceRequest request in shortfallRequests) { // Check if transmutation would be successful if (request.AllowTransmutation && (queryOnly || request.TransmutationPossible)) { // get resource type IModel model = this.GetResourceItem(request.ActivityModel, request.ResourceType, request.ResourceTypeName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as IModel; if (model != null) { // check if transmutations provided foreach (Transmutation trans in Apsim.Children(model, typeof(Transmutation))) { // check if resources available for activity and transmutation double unitsNeeded = Math.Ceiling((request.Required - request.Available) / trans.AmountPerUnitPurchase); foreach (ITransmutationCost transcost in Apsim.Children(trans, typeof(IModel)).Where(a => a is ITransmutationCost).Cast <ITransmutationCost>()) { double transmutationCost = unitsNeeded * transcost.CostPerUnit; // get transcost resource IResourceType transResource = null; if (transcost.ResourceType.Name != "Labour") { transResource = this.GetResourceItem(request.ActivityModel, transcost.ResourceTypeName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as IResourceType; } if (!queryOnly) { //remove cost // create new request for this transmutation cost ResourceRequest transRequest = new ResourceRequest(); transRequest.Reason = trans.Name + " " + trans.Parent.Name; transRequest.Required = transmutationCost; transRequest.ResourceType = transcost.ResourceType; transRequest.ActivityModel = request.ActivityModel; // used to pass request, but this is not the transmutation cost if (transcost.ResourceType.Name == "Labour") { transRequest.ResourceType = typeof(Labour); transRequest.FilterDetails = Apsim.Children(transcost as IModel, typeof(LabourFilterGroup)).ToList <object>(); CLEMActivityBase.TakeLabour(transRequest, true, transRequest.ActivityModel, this, OnPartialResourcesAvailableActionTypes.UseResourcesAvailable); } else { transResource.Remove(transRequest); } } else { double activityCost = requests.Where(a => a.ResourceType == transcost.ResourceType && a.ResourceTypeName == transcost.ResourceTypeName).Sum(a => a.Required); if (transmutationCost + activityCost <= transResource.Amount) { request.TransmutationPossible = true; break; } } } if (!queryOnly) { // Add resource (model as IResourceType).Add(unitsNeeded * trans.AmountPerUnitPurchase, trans, ""); } } } } } }
/// <summary> /// Performs the transmutation of resources into a required resource /// </summary> public void TransmutateShortfall(List <ResourceRequest> requests, bool queryOnly) { List <ResourceRequest> shortfallRequests = requests.Where(a => a.Required > a.Available).ToList(); // Search through all limited resources and determine if transmutation available foreach (ResourceRequest request in shortfallRequests) { // Check if transmutation would be successful if (request.AllowTransmutation && (queryOnly || request.TransmutationPossible)) { // get resource type IModel model = request.Resource as IModel; if (model is null) { model = this.GetResourceItem(request.ActivityModel, request.ResourceType, request.ResourceTypeName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as IModel; } if (model != null) { // get the resource holder to use for this request // not it is either this class or the holder for the market place required. ResourcesHolder resHolder = model.Parent.Parent as ResourcesHolder; // check if transmutations provided foreach (Transmutation trans in model.FindAllChildren <Transmutation>()) { double unitsNeeded = 0; // check if resources available for activity and transmutation foreach (ITransmutationCost transcost in trans.FindAllChildren <IModel>().Where(a => a is ITransmutationCost).Cast <ITransmutationCost>()) { double unitsize = trans.AmountPerUnitPurchase; if (transcost is TransmutationCostUsePricing) { // use pricing details if needed unitsize = (transcost as TransmutationCostUsePricing).Pricing.PacketSize; } unitsNeeded = Math.Ceiling((request.Required - request.Available) / unitsize); double transmutationCost; if (transcost is TransmutationCostUsePricing) { // use pricing details if needed transmutationCost = unitsNeeded * (transcost as TransmutationCostUsePricing).Pricing.PricePerPacket; } else { transmutationCost = unitsNeeded * transcost.CostPerUnit; } // get transcost resource IResourceType transResource = null; if (transcost.ResourceType.Name != "Labour") { transResource = resHolder.GetResourceItem(request.ActivityModel, transcost.ResourceTypeName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.Ignore) as IResourceType; } if (!queryOnly) { // remove cost // create new request for this transmutation cost ResourceRequest transRequest = new ResourceRequest { Reason = trans.Name + " " + trans.Parent.Name, Required = transmutationCost, ResourceType = transcost.ResourceType, ActivityModel = request.ActivityModel }; // used to pass request, but this is not the transmutation cost if (transcost.ResourceType.Name == "Labour") { transRequest.ResourceType = typeof(Labour); transRequest.FilterDetails = (transcost as IModel).FindAllChildren <LabourFilterGroup>().ToList <object>(); CLEMActivityBase.TakeLabour(transRequest, true, transRequest.ActivityModel, this, OnPartialResourcesAvailableActionTypes.UseResourcesAvailable); } else { transResource.Remove(transRequest); } } else { double activityCost = requests.Where(a => a.ResourceType == transcost.ResourceType && a.ResourceTypeName == transcost.ResourceTypeName).Sum(a => a.Required); if (transmutationCost + activityCost <= transResource.Amount) { request.TransmutationPossible = true; break; } } } if (!queryOnly) { // Add resource (model as IResourceType).Add(unitsNeeded * trans.AmountPerUnitPurchase, trans, "Transmutation"); } } } } } }