Esempio n. 1
0
        /// <summary>
        /// Model the price of each present cohort for a given breed
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        public IEnumerable <AnimalPriceGroup> GetAnimalPrices(AnimalPricing parent)
        {
            List <AnimalPriceGroup> prices = new List <AnimalPriceGroup>();

            double sire_price = 0;
            int    row        = -1;

            foreach (string cohort in RumNumbers.RowNames)
            {
                row++;
                if (RumNumbers.GetData <double>(row, RumActiveID) != 0)
                {
                    if (!cohort.ToLower().Contains("sire"))
                    {
                        sire_price = RumPrices.GetData <double>(row, RumActiveID);
                    }

                    var group = new AnimalPriceGroup(parent)
                    {
                        Name  = cohort,
                        Value = RumPrices.GetData <double>(row, RumActiveID)
                    };

                    // Filter cohort based on gender
                    group.Add(new RuminantFilter(group)
                    {
                        Name      = "GenderFilter",
                        Parameter = 2,
                        Value     = cohort.ToLower().Contains("f") ? "Female" : "Male"
                    });

                    // Filter cohort based on age
                    group.Add(new RuminantFilter(group)
                    {
                        Name      = "AgeFilter",
                        Parameter = 3,
                        Operator  = 5,
                        Value     = RumAges.GetData <string>(row, RumActiveID)
                    });

                    prices.Add(group);
                }
            }
            parent.SirePrice = sire_price;

            return(prices);
        }
Esempio n. 2
0
        public IEnumerable <AnimalPriceGroup> GetAnimalPrices(AnimalPricing pricing)
        {
            List <AnimalPriceGroup> prices = new List <AnimalPriceGroup>();

            int index = Breeds.IndexOf((pricing.Parent as RuminantType).Breed);

            // List of all the present cohorts
            var cohorts = pricing.Parent.Children.First().Children;

            foreach (var cohort in cohorts)
            {
                AnimalPriceGroup price = new AnimalPriceGroup(pricing)
                {
                    Name         = cohort.Name,
                    PricingStyle = 1,
                    Value        = GetValue <double>(Prices.Element(cohort.Name), index)
                };

                price.Add(new RuminantFilter(price)
                {
                    Name      = "GenderFilter",
                    Parameter = 2,
                    Value     = (((RuminantTypeCohort)cohort).Gender == 0) ? "Male" : "Female"
                });

                price.Add(new RuminantFilter(price)
                {
                    Name      = "AgeFilter",
                    Parameter = 3,
                    Operator  = 5,
                    Value     = ((RuminantTypeCohort)cohort).Age.ToString()
                });

                prices.Add(price);
            }

            return(prices.AsEnumerable());
        }
Esempio n. 3
0
        /// <summary>
        /// Get value of a specific individual
        /// </summary>
        /// <returns>value</returns>
        public AnimalPriceGroup GetPriceGroupOfIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle, string warningMessage = "")
        {
            if (PricingAvailable())
            {
                AnimalPriceGroup animalPrice = (purchaseStyle == PurchaseOrSalePricingStyleType.Purchase) ? ind.CurrentPriceGroups.Buy : ind.CurrentPriceGroups.Sell;
                if (animalPrice == null || !animalPrice.Filter(ind))
                {
                    // search through RuminantPriceGroups for first match with desired purchase or sale flag
                    foreach (AnimalPriceGroup priceGroup in priceGroups.Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both))
                    {
                        if (priceGroup.Filter(ind))
                        {
                            if (purchaseStyle == PurchaseOrSalePricingStyleType.Purchase)
                            {
                                ind.CurrentPriceGroups = (priceGroup, ind.CurrentPriceGroups.Sell);
                                return(priceGroup);
                            }
                            else
                            {
                                ind.CurrentPriceGroups = (ind.CurrentPriceGroups.Buy, priceGroup);
                                return(priceGroup);
                            }
                        }
                    }

                    // no price match found.
                    string warningString = warningMessage;
                    if (warningString == "")
                    {
                        warningString = $"No [{purchaseStyle}] price entry was found for [r={ind.Breed}] meeting the required criteria [f=age: {ind.Age}] [f=sex: {ind.Sex}] [f=weight: {ind.Weight:##0}]";
                    }
                    Warnings.CheckAndWrite(warningString, Summary, this, MessageType.Warning);
                }
                return(animalPrice);
            }
            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// Get value of a specific individual with special requirements check (e.g. breeding sire or draught purchase)
        /// </summary>
        /// <returns>value</returns>
        public double ValueofIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle, RuminantFilterParameters property, string value)
        {
            double price = 0;

            if (PricingAvailable())
            {
                string          criteria   = property.ToString().ToUpper() + ":" + value.ToUpper();
                List <Ruminant> animalList = new List <Ruminant>()
                {
                    ind
                };

                //find first pricing entry matching specific criteria
                AnimalPriceGroup matchIndividual = null;
                AnimalPriceGroup matchCriteria   = null;
                foreach (AnimalPriceGroup item in PriceList.FindAllChildren <AnimalPriceGroup>().Cast <AnimalPriceGroup>().Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both))
                {
                    if (animalList.Filter(item).Count() == 1 && matchIndividual == null)
                    {
                        matchIndividual = item;
                    }

                    // check that pricing item meets the specified criteria.
                    if (item.FindAllChildren <RuminantFilter>().Cast <RuminantFilter>().Where(a => (a.Parameter.ToString().ToUpper() == property.ToString().ToUpper() && a.Value.ToUpper() == value.ToUpper())).Count() > 0)
                    {
                        if (matchCriteria == null)
                        {
                            matchCriteria = item;
                        }
                        else
                        {
                            // multiple price entries were found. using first. value = xxx.
                            if (!WarningsMultipleEntry.Contains(criteria))
                            {
                                WarningsMultipleEntry.Add(criteria);
                                Summary.WriteWarning(this, "Multiple specific [" + purchaseStyle.ToString() + "] price entries were found for [r=" + ind.Breed + "] where [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : ".") + "\nOnly the first entry will be used. Price [" + matchCriteria.Value.ToString("#,##0.##") + "] [" + matchCriteria.PricingStyle.ToString() + "].");
                            }
                        }
                    }
                }

                if (matchCriteria == null)
                {
                    // report specific criteria not found in price list
                    string warningString = "No [" + purchaseStyle.ToString() + "] price entry was found for [r=" + ind.Breed + "] meeting the required criteria [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : ".");

                    if (matchIndividual != null)
                    {
                        // add using the best pricing available for [][] purchases of xx per head
                        warningString += "\nThe best available price [" + matchIndividual.Value.ToString("#,##0.##") + "] [" + matchIndividual.PricingStyle.ToString() + "] will be used.";
                        price          = matchIndividual.Value * ((matchIndividual.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0);
                    }
                    else
                    {
                        warningString += "\nNo alternate price for individuals could be found for the individuals. Add a new [r=AnimalPriceGroup] entry in the [r=AnimalPricing] for [" + ind.Breed + "]";
                    }
                    if (!WarningsNotFound.Contains(criteria))
                    {
                        WarningsNotFound.Add(criteria);
                        Summary.WriteWarning(this, warningString);
                    }
                }
                else
                {
                    price = matchCriteria.Value * ((matchCriteria.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0);
                }
            }
            return(price);
        }
Esempio n. 5
0
        /// <summary>
        /// Get value of a specific individual with special requirements check (e.g. breeding sire or draught purchase)
        /// </summary>
        /// <returns>value</returns>
        public AnimalPriceGroup GetPriceGroupOfIndividual(Ruminant ind, PurchaseOrSalePricingStyleType purchaseStyle, string property, string value, string warningMessage = "")
        {
            double price = 0;

            if (PricingAvailable())
            {
                AnimalPriceGroup animalPrice = (purchaseStyle == PurchaseOrSalePricingStyleType.Purchase) ? ind.CurrentPriceGroups.Buy : ind.CurrentPriceGroups.Sell;
                if (animalPrice == null || !animalPrice.Filter(ind))
                {
                    string criteria = property.ToUpper() + ":" + value.ToUpper();

                    //find first pricing entry matching specific criteria
                    AnimalPriceGroup matchIndividual = null;
                    AnimalPriceGroup matchCriteria   = null;

                    var priceGroups = PriceList.FindAllChildren <AnimalPriceGroup>()
                                      .Where(a => a.PurchaseOrSale == purchaseStyle || a.PurchaseOrSale == PurchaseOrSalePricingStyleType.Both);

                    foreach (AnimalPriceGroup priceGroup in priceGroups)
                    {
                        if (priceGroup.Filter(ind) && matchIndividual == null)
                        {
                            matchIndividual = priceGroup;
                        }

                        var suitableFilters = priceGroup.FindAllChildren <FilterByProperty>()
                                              .Where(a => (a.PropertyOfIndividual == property) &
                                                     (
                                                         (a.Operator == System.Linq.Expressions.ExpressionType.Equal && a.Value.ToString().ToUpper() == value.ToUpper()) |
                                                         (a.Operator == System.Linq.Expressions.ExpressionType.NotEqual && a.Value.ToString().ToUpper() != value.ToUpper()) |
                                                         (a.Operator == System.Linq.Expressions.ExpressionType.IsTrue && value.ToUpper() == "TRUE") |
                                                         (a.Operator == System.Linq.Expressions.ExpressionType.IsFalse && value.ToUpper() == "FALSE")
                                                     )
                                                     ).Any();

                        // check that pricing item meets the specified criteria.
                        if (suitableFilters)
                        {
                            if (matchCriteria == null)
                            {
                                matchCriteria = priceGroup;
                            }
                            else
                            // multiple price entries were found. using first. value = xxx.
                            if (!warningsMultipleEntry.Contains(criteria))
                            {
                                warningsMultipleEntry.Add(criteria);
                                Summary.WriteMessage(this, "Multiple specific [" + purchaseStyle.ToString() + "] price entries were found for [r=" + ind.Breed + "] where [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : ".") + "\r\nOnly the first entry will be used. Price [" + matchCriteria.Value.ToString("#,##0.##") + "] [" + matchCriteria.PricingStyle.ToString() + "].", MessageType.Warning);
                            }
                        }
                    }

                    if (matchCriteria == null)
                    {
                        string warningString = warningMessage;
                        if (warningString != "")
                        {
                            // no warning string passed to method so calculate one
                            // report specific criteria not found in price list
                            warningString = "No [" + purchaseStyle.ToString() + "] price entry was found for [r=" + ind.Breed + "] meeting the required criteria [" + property + "]" + (value.ToUpper() != "TRUE" ? " = [" + value + "]." : ".");

                            if (matchIndividual != null)
                            {
                                // add using the best pricing available for [][] purchases of xx per head
                                warningString += "\r\nThe best available price [" + matchIndividual.Value.ToString("#,##0.##") + "] [" + matchIndividual.PricingStyle.ToString() + "] will be used.";
                                price          = matchIndividual.Value * ((matchIndividual.PricingStyle == PricingStyleType.perKg) ? ind.Weight : 1.0);
                            }
                            else
                            {
                                warningString += "\r\nNo alternate price for individuals could be found for the individuals. Add a new [r=AnimalPriceGroup] entry in the [r=AnimalPricing] for [" + ind.Breed + "]";
                            }
                        }

                        if (!warningsNotFound.Contains(criteria))
                        {
                            warningsNotFound.Add(criteria);
                            Summary.WriteMessage(this, warningString, MessageType.Warning);
                        }
                    }
                    if (purchaseStyle == PurchaseOrSalePricingStyleType.Purchase)
                    {
                        ind.CurrentPriceGroups = (matchCriteria, ind.CurrentPriceGroups.Sell);
                        return(matchCriteria);
                    }
                    else
                    {
                        ind.CurrentPriceGroups = (ind.CurrentPriceGroups.Buy, matchCriteria);
                        return(matchCriteria);
                    }
                }
            }
            return(null);
        }
Esempio n. 6
0
        private void BuyWithTrucking()
        {
            // This activity will purchase animals based on available funds.

            int    trucks         = 0;
            int    head           = 0;
            double aESum          = 0;
            double fundsAvailable = 0;

            if (bankAccount != null)
            {
                fundsAvailable = bankAccount.FundsAvailable;
            }
            double cost          = 0;
            double shortfall     = 0;
            bool   fundsexceeded = false;

            // get current untrucked list of animal purchases
            List <Ruminant> herd = HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).OrderByDescending(a => a.Weight).ToList();

            if (herd.Count == 0)
            {
                return;
            }

            List <Ruminant> boughtIndividuals = new List <Ruminant>();

            // if purchase herd > min loads before allowing trucking
            if (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck >= trucking.MinimumTrucksBeforeBuying)
            {
                // while truck to fill
                while (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck > trucking.MinimumLoadBeforeBuying)
                {
                    bool nonloaded = true;
                    trucks++;
                    double load450kgs = 0;
                    // while truck below carrying capacity load individuals
                    foreach (var ind in herd)
                    {
                        if (load450kgs + (ind.Weight / 450.0) <= trucking.Number450kgPerTruck)
                        {
                            nonloaded = false;
                            head++;
                            aESum      += ind.AdultEquivalent;
                            load450kgs += ind.Weight / 450.0;

                            if (bankAccount != null)  // perform with purchasing
                            {
                                double           value   = 0;
                                AnimalPriceGroup pricing = null;
                                if (ind.SaleFlag == HerdChangeReason.SirePurchase)
                                {
                                    pricing = ind.BreedParams.ValueofIndividual(ind, PurchaseOrSalePricingStyleType.Purchase, "IsSire", "true");
                                }
                                else
                                {
                                    pricing = ind.BreedParams.ValueofIndividual(ind, PurchaseOrSalePricingStyleType.Purchase);
                                }

                                if (pricing != null)
                                {
                                    value = pricing.CalculateValue(ind);
                                }

                                if (cost + value <= fundsAvailable && fundsexceeded == false)
                                {
                                    ind.ID = HerdResource.NextUniqueID;
                                    boughtIndividuals.Add(ind);
                                    HerdResource.AddRuminant(ind, this);
                                    HerdResource.PurchaseIndividuals.Remove(ind);
                                    cost += value;
                                }
                                else
                                {
                                    fundsexceeded = true;
                                    shortfall    += value;
                                }
                            }
                            else // no financial transactions
                            {
                                ind.ID = HerdResource.NextUniqueID;
                                boughtIndividuals.Add(ind);
                                HerdResource.AddRuminant(ind, this);
                                HerdResource.PurchaseIndividuals.Remove(ind);
                            }
                        }
                    }
                    if (nonloaded)
                    {
                        Summary.WriteWarning(this, String.Format("There was a problem loading the purchase truck as purchase individuals did not meet the loading criteria for breed [r={0}]", this.PredictedHerdBreed));
                        break;
                    }
                    if (shortfall > 0)
                    {
                        break;
                    }

                    herd = HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).OrderByDescending(a => a.Weight).ToList();
                }

                if (Status != ActivityStatus.Warning)
                {
                    if (HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).Any() == false)
                    {
                        SetStatusSuccess();
                    }
                    else
                    {
                        Status = ActivityStatus.Partial;
                    }
                }

                // create trucking emissions
                if (trucking != null && trucks > 0)
                {
                    trucking.ReportEmissions(trucks, false);
                }

                if (bankAccount != null && (trucks > 0 || trucking == null))
                {
                    ResourceRequest purchaseRequest = new ResourceRequest
                    {
                        ActivityModel      = this,
                        Required           = cost,
                        AllowTransmutation = false,
                        Category           = TransactionCategory,
                        RelatesToResource  = this.PredictedHerdName
                    };

                    var groupedIndividuals = HerdResource.SummarizeIndividualsByGroups(boughtIndividuals, PurchaseOrSalePricingStyleType.Purchase);
                    foreach (var item in groupedIndividuals)
                    {
                        foreach (var item2 in item.RuminantTypeGroup)
                        {
                            purchaseRequest.Required = item2.TotalPrice ?? 0;
                            purchaseRequest.Category = $"{TransactionCategory}.{item2.GroupName}";
                            bankAccount.Remove(purchaseRequest);
                        }
                    }

                    // report any financial shortfall in purchases
                    if (shortfall > 0)
                    {
                        purchaseRequest.Available        = bankAccount.Amount;
                        purchaseRequest.Required         = cost + shortfall;
                        purchaseRequest.Provided         = cost;
                        purchaseRequest.ResourceType     = typeof(Finance);
                        purchaseRequest.ResourceTypeName = BankAccountName;
                        ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                        {
                            Request = purchaseRequest
                        };
                        OnShortfallOccurred(rre);
                    }

                    ResourceRequest expenseRequest = new ResourceRequest
                    {
                        Available          = bankAccount.Amount,
                        ActivityModel      = this,
                        AllowTransmutation = false
                    };

                    // calculate transport costs
                    if (trucking != null)
                    {
                        expenseRequest.Required = trucks * trucking.DistanceToMarket * trucking.CostPerKmTrucking;
                        expenseRequest.Category = trucking.TransactionCategory;
                        bankAccount.Remove(expenseRequest);

                        if (expenseRequest.Required > expenseRequest.Available)
                        {
                            expenseRequest.Available        = bankAccount.Amount;
                            expenseRequest.ResourceType     = typeof(Finance);
                            expenseRequest.ResourceTypeName = BankAccountName;
                            ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                            {
                                Request = expenseRequest
                            };
                            OnShortfallOccurred(rre);
                        }
                    }
                }
            }
            else
            {
                this.Status = ActivityStatus.Warning;
            }
        }
Esempio n. 7
0
        private void BuyWithoutTrucking()
        {
            // This activity will purchase animals based on available funds.

            // get current untrucked list of animal purchases
            List <Ruminant> herd = HerdResource.PurchaseIndividuals.Where(a => a.BreedParams.Breed == this.PredictedHerdBreed).ToList();

            if (herd.Count > 0)
            {
                if (this.Status != ActivityStatus.Warning)
                {
                    this.Status = ActivityStatus.Success;
                }
            }
            else
            {
                return;
            }

            List <Ruminant> boughtIndividuals = new List <Ruminant>();

            double fundsAvailable = 0;

            if (bankAccount != null)
            {
                fundsAvailable = bankAccount.FundsAvailable;
            }

            double cost          = 0;
            double shortfall     = 0;
            bool   fundsexceeded = false;

            foreach (var newind in herd)
            {
                if (bankAccount != null)  // perform with purchasing
                {
                    double           value   = 0;
                    AnimalPriceGroup pricing = null;
                    if (newind.SaleFlag == HerdChangeReason.SirePurchase)
                    {
                        pricing = newind.BreedParams.ValueofIndividual(newind, PurchaseOrSalePricingStyleType.Purchase, "Male.IsSire", "true");
                    }
                    else
                    {
                        pricing = newind.BreedParams.ValueofIndividual(newind, PurchaseOrSalePricingStyleType.Purchase);
                    }

                    if (pricing != null)
                    {
                        value = pricing.CalculateValue(newind);
                    }

                    if (cost + value <= fundsAvailable && fundsexceeded == false)
                    {
                        boughtIndividuals.Add(newind);
                        HerdResource.PurchaseIndividuals.Remove(newind);
                        newind.ID = HerdResource.NextUniqueID;

                        HerdResource.AddRuminant(newind, this);
                        cost += value;
                    }
                    else
                    {
                        fundsexceeded = true;
                        shortfall    += value;
                    }
                }
                else // no financial transactions
                {
                    boughtIndividuals.Add(newind);
                    HerdResource.PurchaseIndividuals.Remove(newind);
                    newind.ID = HerdResource.NextUniqueID;
                    HerdResource.AddRuminant(newind, this);
                }
            }

            if (bankAccount != null)
            {
                ResourceRequest purchaseRequest = new ResourceRequest
                {
                    ActivityModel      = this,
                    Required           = cost,
                    AllowTransmutation = false,
                    Category           = TransactionCategory,
                    RelatesToResource  = this.PredictedHerdName
                };

                //bankAccount.Add(saleValue, this, this.PredictedHerdName, TransactionCategory);
                var groupedIndividuals = HerdResource.SummarizeIndividualsByGroups(boughtIndividuals, PurchaseOrSalePricingStyleType.Purchase);
                foreach (var item in groupedIndividuals)
                {
                    foreach (var item2 in item.RuminantTypeGroup)
                    {
                        purchaseRequest.Required = item2.TotalPrice ?? 0;
                        purchaseRequest.Category = $"{TransactionCategory}.{item2.GroupName}";
                        bankAccount.Remove(purchaseRequest);
//                        bankAccount.Add(item2.TotalPrice, this, item.RuminantTypeName, $"{TransactionCategory}.{item2.GroupName}");
                    }
                }

                // report any financial shortfall in purchases
                if (shortfall > 0)
                {
                    purchaseRequest.Available        = bankAccount.Amount;
                    purchaseRequest.Required         = cost + shortfall;
                    purchaseRequest.Provided         = cost;
                    purchaseRequest.ResourceType     = typeof(Finance);
                    purchaseRequest.ResourceTypeName = BankAccountName;
                    ResourceRequestEventArgs rre = new ResourceRequestEventArgs()
                    {
                        Request = purchaseRequest
                    };
                    OnShortfallOccurred(rre);
                }
            }
        }