/// <summary>
        /// Method used to perform activity if it can occur as soon as resources are available.
        /// </summary>
        public override void DoActivity()
        {
            Status = ActivityStatus.NotNeeded;
            double labourlimit = this.LabourLimitProportion;
            double units       = 0;

            if (labourlimit == 1 || this.OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable)
            {
                units = unitsAvailableForSale * labourlimit;
                if (price.UseWholePackets)
                {
                    units = Math.Truncate(units);
                }
            }

            if (units > 0)
            {
                // remove resource
                ResourceRequest purchaseRequest = new ResourceRequest
                {
                    ActivityModel      = this,
                    Required           = units * price.PacketSize,
                    AllowTransmutation = false,
                    Reason             = "Sell " + (resourceToSell as Model).Name
                };
                resourceToSell.Remove(purchaseRequest);

                // transfer money earned
                bankAccount.Add(units * price.PricePerPacket, this, "Sales");
                SetStatusSuccess();
            }
        }
Example #2
0
        ///// <summary>
        ///// Determines if a shortfall in all Resources can be met by transmutation
        ///// </summary>
        //public void CanTransmutateShortfall(List<ResourceRequest> requests)
        //{
        //	List<ResourceRequest> shortfallRequests = requests.Where(a => a.Required - a.Available > 0).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)
        //		{
        //			// get resource type
        //			bool resourceAvailable = false;
        //			IModel model = this.GetResourceItem(request.ResourceName, request.ResourceTypeName, out resourceAvailable) as IModel;
        //			if (model != null)
        //			{
        //				// check if transmutations provided
        //				foreach (Transmutation trans in model.Children.Where(a => a.GetType() == typeof(Transmutation)))
        //				{
        //					// check if resources available for activity and transmutation
        //					double unitsNeeded = Math.Ceiling((request.Required - request.Available) / trans.AmountPerUnitPurchase);
        //					foreach (TransmutationCost transcost in trans.Children.Where(a => a.GetType() == typeof(TransmutationCost)))
        //					{
        //						double transmutationCost = unitsNeeded * transcost.CostPerUnit;
        //						double activityCost = requests.Where(a => a.ResourceName == transcost.ResourceName & a.ResourceTypeName == transcost.ResourceTypeName).Sum(a => a.Required);
        //						if(transmutationCost+activityCost <= (model as IResourceType).Amount)
        //						{
        //							request.TransmutationSuccessful = true;
        //							break;
        //						}
        //					}
        //				}
        //			}
        //		}
        //	}
        //}

        /// <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
                    bool   resourceAvailable = false;
                    IModel model             = this.GetResourceItem(request.ResourceName, request.ResourceTypeName, out resourceAvailable) as IModel;
                    if (model != null)
                    {
                        // check if transmutations provided
                        foreach (Transmutation trans in model.Children.Where(a => a.GetType() == typeof(Transmutation)))
                        {
                            // check if resources available for activity and transmutation
                            double unitsNeeded = Math.Ceiling((request.Required - request.Available) / trans.AmountPerUnitPurchase);
                            foreach (TransmutationCost transcost in trans.Children.Where(a => a.GetType() == typeof(TransmutationCost)))
                            {
                                double transmutationCost = unitsNeeded * transcost.CostPerUnit;
                                if (!QueryOnly)
                                {
                                    //remove cost
                                    IResourceType transResource = this.GetResourceItem(transcost.ResourceName, transcost.ResourceTypeName, out resourceAvailable) as IResourceType;
                                    transResource.Remove(transmutationCost, trans.Name, trans.Parent.Name);
                                }
                                else
                                {
                                    double        activityCost   = requests.Where(a => a.ResourceName == transcost.ResourceName & a.ResourceTypeName == transcost.ResourceTypeName).Sum(a => a.Required);
                                    IResourceType resourceToTake = this.GetResourceItem(transcost.ResourceName, transcost.ResourceTypeName, out resourceAvailable) as IResourceType;
                                    if (transmutationCost + activityCost <= resourceToTake.Amount)
                                    {
                                        request.TransmutationPossible = true;
                                        break;
                                    }
                                }
                            }
                            if (!QueryOnly)
                            {
                                // Add resource
                                (model as IResourceType).Add(unitsNeeded * trans.AmountPerUnitPurchase, trans.Name, "");
                            }
                        }
                    }
                }
            }
        }
Example #3
0
        /// <inheritdoc/>
        public override void DoActivity()
        {
            Status = ActivityStatus.NotNeeded;
            double labourlimit = this.LabourLimitProportion;
            double units       = 0;

            if (labourlimit == 1 || this.OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable)
            {
                units = unitsAvailableForSale * labourlimit;
                if (price.UseWholePackets)
                {
                    units = Math.Truncate(units);
                }
            }

            if (units > 0)
            {
                // remove resource
                ResourceRequest purchaseRequest = new ResourceRequest
                {
                    ActivityModel      = this,
                    Required           = units * price.PacketSize,
                    AllowTransmutation = true,
                    Category           = TransactionCategory,
                    RelatesToResource  = (resourceToSell as CLEMModel).NameWithParent
                };
                resourceToSell.Remove(purchaseRequest);

                // transfer money earned
                if (bankAccount != null)
                {
                    if (price.PricePerPacket == 0)
                    {
                        string warn = $"No price set [0] for [r={resourceToSell.Name}] at time of transaction for [a={this.Name}]{Environment.NewLine}No financial transactions will occur.{Environment.NewLine}Ensure price is set or resource pricing file contains entries before this transaction or start of simulation.";
                        Warnings.CheckAndWrite(warn, Summary, this, MessageType.Warning);
                    }

                    bankAccount.Add(units * price.PricePerPacket, this, (resourceToSell as CLEMModel).NameWithParent, TransactionCategory);
                    if (bankAccount.EquivalentMarketStore != null)
                    {
                        purchaseRequest.Required          = units * price.PricePerPacket;
                        purchaseRequest.Category          = TransactionCategory;
                        purchaseRequest.RelatesToResource = (resourceToSell as CLEMModel).NameWithParent;
                        (bankAccount.EquivalentMarketStore as FinanceType).Remove(purchaseRequest);
                    }
                }

                SetStatusSuccess();
            }
        }
Example #4
0
        private void OnWFRequestFeed(object sender, EventArgs e)
        {
            RuminantHerd    ruminantHerd = Resources.RuminantHerd();
            List <Ruminant> herd         = ruminantHerd.Herd;

            IResourceType grazeStoreType = null;

            if (FeedArbitratorName != "")
            {
                grazeStoreType = Arbitrators.GetByName(FeedArbitratorName) as IResourceType;
            }

            // for each paddock defined in PastureActivityManage
            foreach (PastureActivityManage pasture in Activities.Children.Where(a => a.GetType() == typeof(PastureActivityManage)))
            {
                if (FeedArbitratorName == "")
                {
                    grazeStoreType = pasture.FeedType;
                }

                // create feeding activity for this pasture
                RuminantActivityGraze activity = new RuminantActivityGraze();
                activity.FeedPriority = this.FeedPriority;
                activity.FeedType     = pasture.FeedType;
                activity.HoursGrazed  = this.HoursGrazed;
                activity.Name         = String.Format("Graze {0}", pasture.FeedType.Name);

                // calculate kg per ha available
                double kgPerHa = pasture.FeedType.Amount / pasture.Area;

                if (pasture.FeedType.Amount > 0)
                {
                    // get list of all Ruminants in this paddock
                    foreach (Ruminant ind in herd.Where(a => a.Location == pasture.Name))
                    {
                        RuminantFeedRequest freqest = new RuminantFeedRequest();
                        freqest.FeedActivity = activity;
                        freqest.Requestor    = ind;

                        // Reduce potential intake based on pasture quality for the proportion consumed.


                        // calculate intake from potential modified by pasture availability and hours grazed
                        freqest.Amount = ind.PotentialIntake * (1 - Math.Exp(-ind.BreedParams.IntakeCoefficientBiomass * kgPerHa)) * (HoursGrazed / 8);
                        grazeStoreType.Remove(freqest);
                    }
                }
            }
        }
        /// <summary>
        /// Method used to perform activity if it can occur as soon as resources are available.
        /// </summary>
        public override void DoActivity()
        {
            if (this.TimingOK)
            {
                // reduce if labour limiting
                double labourlimit = 1;
                if (ResourceRequestList != null && ResourceRequestList.Where(a => a.ResourceType == typeof(Labour)).Count() > 0)
                {
                    double amountLabourNeeded   = ResourceRequestList.Where(a => a.ResourceType == typeof(Labour)).Sum(a => a.Required);
                    double amountLabourProvided = ResourceRequestList.Where(a => a.ResourceType == typeof(Labour)).Sum(a => a.Provided);
                    if (amountLabourNeeded > 0)
                    {
                        if (amountLabourProvided == 0)
                        {
                            labourlimit = 0;
                        }
                        else
                        {
                            labourlimit = amountLabourNeeded / amountLabourProvided;
                        }
                    }
                }
                double units = 0;
                if (labourlimit == 1 || this.OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable)
                {
                    units = UnitsAvailableForSale * labourlimit;
                    if (SellWholeUnitsOnly)
                    {
                        units = Math.Truncate(units);
                    }
                }

                if (units > 0)
                {
                    // remove resource
                    ResourceRequest purchaseRequest = new ResourceRequest();
                    purchaseRequest.ActivityModel      = this;
                    purchaseRequest.Required           = units * UnitSize;
                    purchaseRequest.AllowTransmutation = false;
                    purchaseRequest.Reason             = "Sales";
                    resourceToSell.Remove(purchaseRequest);

                    // transfer money earned
                    bankAccount.Add(units * UnitPrice, this.Name, "Sales");
                    SetStatusSuccess();
                }
            }
        }
Example #6
0
        /// <summary>
        /// Method used to perform activity if it can occur as soon as resources are available.
        /// </summary>
        public override void DoActivity()
        {
            Status = ActivityStatus.NotNeeded;
            double labourlimit = this.LabourLimitProportion;
            double units       = 0;

            if (labourlimit == 1 || this.OnPartialResourcesAvailableAction == OnPartialResourcesAvailableActionTypes.UseResourcesAvailable)
            {
                units = unitsAvailableForSale * labourlimit;
                if (price.UseWholePackets)
                {
                    units = Math.Truncate(units);
                }
            }

            if (units > 0)
            {
                // remove resource
                ResourceRequest purchaseRequest = new ResourceRequest
                {
                    ActivityModel      = this,
                    Required           = units * price.PacketSize,
                    AllowTransmutation = true,
                    Category           = "Sell",
                    RelatesToResource  = (resourceToSell as CLEMModel).NameWithParent
                };
                resourceToSell.Remove(purchaseRequest);

                // transfer money earned
                if (bankAccount != null)
                {
                    bankAccount.Add(units * price.PricePerPacket, this, (resourceToSell as CLEMModel).NameWithParent, "Sales");
                    if (bankAccount.EquivalentMarketStore != null)
                    {
                        purchaseRequest.Required          = units * price.PricePerPacket;
                        purchaseRequest.Category          = "Sales";
                        purchaseRequest.RelatesToResource = (resourceToSell as CLEMModel).NameWithParent;
                        (bankAccount.EquivalentMarketStore as FinanceType).Remove(purchaseRequest);
                    }
                }

                SetStatusSuccess();
            }
        }
Example #7
0
        /// <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, "");
                            }
                        }
                    }
                }
            }
        }
Example #8
0
        /// <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");
                            }
                        }
                    }
                }
            }
        }
Example #9
0
        /// <summary>
        /// Method to get this time steps current required resources for this activity.
        /// </summary>
        public void GetResourcesRequired()
        {
            bool resourceAvailable = false;

            // determine what resources are needed
            ResourceRequestList = DetermineResourcesNeeded();

            // no resources required or this is an Activity folder.
            if (ResourceRequestList == null)
            {
                return;
            }

            // check resource amounts available
            foreach (ResourceRequest request in ResourceRequestList)
            {
                request.Available = 0;
                // get resource
                IResourceType resource = Resources.GetResourceItem(request, out resourceAvailable) as IResourceType;
                if (resource != null)
                {
                    // get amount available
                    request.Available = Math.Min(resource.Amount, request.Required);
                }
                else
                {
                    if (!resourceAvailable)
                    {
                        // if resource does not exist in simulation assume unlimited resource available
                        // otherwise 0 will be assigned to available when no resouces match request
                        request.Available = request.Required;
                    }
                }
            }

            // are all resources available
            List <ResourceRequest> shortfallRequests = ResourceRequestList.Where(a => a.Required > a.Available).ToList();
            int countShortfallRequests = shortfallRequests.Count();

            if (countShortfallRequests > 0)
            {
                // check what transmutations can occur
                Resources.TransmutateShortfall(shortfallRequests, true);
            }

            // check if need to do transmutations
            int  countTransmutationsSuccessful = shortfallRequests.Where(a => a.TransmutationPossible == true & a.AllowTransmutation).Count();
            bool allTransmutationsSuccessful   = (shortfallRequests.Where(a => a.TransmutationPossible == false & a.AllowTransmutation).Count() == 0);

            // OR at least one transmutation successful and PerformWithPartialResources
            if (((countShortfallRequests > 0) & (countShortfallRequests == countTransmutationsSuccessful)) ^ (countTransmutationsSuccessful > 0 & PerformWithPartialResources))
            {
                // do transmutations.
                Resources.TransmutateShortfall(shortfallRequests, false);

                // recheck resource amounts now that resources have been topped up
                foreach (ResourceRequest request in ResourceRequestList)
                {
                    resourceAvailable = false;
                    // get resource
                    request.Available = 0;
                    IResourceType resource = Resources.GetResourceItem(request, out resourceAvailable) as IResourceType;
                    if (resource != null)
                    {
                        // get amount available
                        request.Available = Math.Max(resource.Amount, request.Required);
                    }
                }
            }

            // remove activity resources
            // check if deficit and performWithPartial
            if ((ResourceRequestList.Where(a => a.Required > a.Available).Count() == 0) | PerformWithPartialResources)
            {
                foreach (ResourceRequest request in ResourceRequestList)
                {
                    resourceAvailable = false;
                    // get resource
                    request.Provided = 0;
                    IResourceType resource = Resources.GetResourceItem(request, out resourceAvailable) as IResourceType;
                    if (resource != null)
                    {
                        // get amount available
                        request.Provided = Math.Min(resource.Amount, request.Required);
                        // remove resource
                        request.Provided = resource.Remove(request.Provided, this.Name, request.Requestor);
                    }
                }
                PerformActivity();
            }
        }