예제 #1
0
        /// <summary>
        /// Resource price
        /// </summary>
        public ResourcePricing Price(PurchaseOrSalePricingStyleType priceType)
        {
            // find pricing that is ok;
            ResourcePricing price = Apsim.Children(this, typeof(ResourcePricing)).Where(a => a.Enabled & ((a as ResourcePricing).PurchaseOrSale == PurchaseOrSalePricingStyleType.Both | (a as ResourcePricing).PurchaseOrSale == priceType) && (a as ResourcePricing).TimingOK).FirstOrDefault() as ResourcePricing;

            // does simulation have finance
            ResourcesHolder resources       = Apsim.Parent(this, typeof(ResourcesHolder)) as ResourcesHolder;
            bool            financesPresent = (resources.FinanceResource() != null);

            if (price == null)
            {
                if (financesPresent)
                {
                    string warn = "No pricing is available for [r=" + this.Parent.Name + "." + this.Name + "]";
                    if (Clock != null & Apsim.Children(this, typeof(ResourcePricing)).Count > 0)
                    {
                        warn += " in month [" + Clock.Today.ToString("MM yyyy") + "]";
                    }
                    warn += "\nAdd [r=ResourcePricing] component to [r=" + this.Parent.Name + "." + this.Name + "] to include financial transactions for purchases and sales.";

                    if (!Warnings.Exists(warn) & Summary != null)
                    {
                        Summary.WriteWarning(this, warn);
                        Warnings.Add(warn);
                    }
                }
                return(new ResourcePricing()
                {
                    PricePerPacket = 0, PacketSize = 1, UseWholePackets = true
                });
            }
            return(price);
        }
예제 #2
0
        /// <summary>
        /// Locate the equivalent store in a market if available
        /// </summary>
        protected void FindEquivalentMarketStore()
        {
            // determine what resource types allow market transactions
            switch (this.GetType().Name)
            {
            case "FinanceType":
            case "HumanFoodStoreType":
            case "WaterType":
            case "AnimalFoodType":
            case "EquipmentType":
            case "GreenhousGasesType":
            case "ProductStoreType":
                break;

            default:
                throw new NotImplementedException($"\n[r={this.Parent.GetType().Name}] resource does not currently support transactions to and from a [m=Market]\nThis problem has arisen because a resource transaction in the code is flagged to exchange resources with the [m=Market]\nPlease contact developers for assistance.");
            }

            // if not already checked
            if (!equivalentMarketStoreDetermined)
            {
                // havent already found a market store
                if (equivalentMarketStore is null)
                {
                    // is there a market
                    Market market = FindMarket();
                    if (market != null)
                    {
                        // get the resources
                        ResourcesHolder holder = Apsim.Child(market, typeof(ResourcesHolder)) as ResourcesHolder;
                        if (holder != null)
                        {
                            object store = null;
                            holder.ResourceTypeExists(this, out store);
                            if (store != null)
                            {
                                equivalentMarketStore = store as CLEMResourceTypeBase;
                            }
                        }
                    }
                }
            }
        }
예제 #3
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");
                            }
                        }
                    }
                }
            }
        }