Beispiel #1
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);
                }
            }
        }
Beispiel #2
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;
            }
        }
Beispiel #3
0
        private void OnCLEMAnimalSell(object sender, EventArgs e)
        {
            Status = ActivityStatus.NoTask;

            int    trucks     = 0;
            double saleValue  = 0;
            double saleWeight = 0;
            int    head       = 0;
            double aESum      = 0;

            // only perform this activity if timing ok, or selling required as a result of forces destock
            List <Ruminant> herd = new List <Ruminant>();

            if (this.TimingOK || this.CurrentHerd(false).Where(a => a.SaleFlag == HerdChangeReason.DestockSale).Any())
            {
                this.Status = ActivityStatus.NotNeeded;
                // get current untrucked list of animals flagged for sale
                herd = this.CurrentHerd(false).Where(a => a.SaleFlag != HerdChangeReason.None).OrderByDescending(a => a.Weight).ToList();
            }

            // no individuals to sell
            if (herd.Count == 0)
            {
                return;
            }

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

            if (trucking == null)
            {
                // no trucking just sell
                SetStatusSuccess();
                foreach (var ind in herd)
                {
                    aESum += ind.AdultEquivalent;
                    var pricing = ind.BreedParams.ValueofIndividual(ind, PurchaseOrSalePricingStyleType.Sale);
                    if (pricing != null)
                    {
                        saleValue += pricing.CalculateValue(ind);
                    }

                    saleWeight += ind.Weight;
                    soldIndividuals.Add(ind);
                    HerdResource.RemoveRuminant(ind, this);
                    head++;
                }
            }
            else
            {
                // if sale herd > min loads before allowing sale
                if (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck >= trucking.MinimumTrucksBeforeSelling)
                {
                    // while truck to fill
                    while (herd.Select(a => a.Weight / 450.0).Sum() / trucking.Number450kgPerTruck > trucking.MinimumLoadBeforeSelling)
                    {
                        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;
                                var pricing = ind.BreedParams.ValueofIndividual(ind, PurchaseOrSalePricingStyleType.Sale);
                                if (pricing != null)
                                {
                                    saleValue += pricing.CalculateValue(ind);
                                }
                                saleWeight += ind.Weight;
                                soldIndividuals.Add(ind);
                                HerdResource.RemoveRuminant(ind, this);

                                //TODO: work out what to do with suckling calves still with mothers if mother sold.
                            }
                        }
                        if (nonloaded)
                        {
                            Summary.WriteWarning(this, String.Format("There was a problem loading the sale truck as sale individuals did not meet the loading criteria for breed [r={0}]", this.PredictedHerdBreed));
                            break;
                        }
                        herd = this.CurrentHerd(false).Where(a => a.SaleFlag != HerdChangeReason.None).OrderByDescending(a => a.Weight).ToList();
                    }
                    // create trucking emissions
                    trucking.ReportEmissions(trucks, true);
                    // if sold all
                    Status = (this.CurrentHerd(false).Where(a => a.SaleFlag != HerdChangeReason.None).Count() == 0) ? ActivityStatus.Success : ActivityStatus.Warning;
                }
            }

            if (bankAccount != null && head > 0) //(trucks > 0 || trucking == null)
            {
                ResourceRequest expenseRequest = new ResourceRequest
                {
                    ActivityModel      = this,
                    AllowTransmutation = false
                };

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

                // perform payments by transaction grouping
                // uses a list of individuals that were taken from the herd

                // calculate aEsum and saleValue form the above list for use below
                // currently done above but can be shifted to calc from grouped indiv

                // add and remove from bank
                if (saleValue > 0)
                {
                    //bankAccount.Add(saleValue, this, this.PredictedHerdName, TransactionCategory);
                    var groupedIndividuals = HerdResource.SummarizeIndividualsByGroups(soldIndividuals, PurchaseOrSalePricingStyleType.Sale);
                    foreach (var item in groupedIndividuals)
                    {
                        foreach (var item2 in item.RuminantTypeGroup)
                        {
                            bankAccount.Add(item2.TotalPrice, this, item.RuminantTypeName, $"{TransactionCategory}.{item2.GroupName}");
                        }
                    }
                }

                // perform activity fee payments
                foreach (RuminantActivityFee item in this.FindAllChildren <RuminantActivityFee>())
                {
                    switch (item.PaymentStyle)
                    {
                    case AnimalPaymentStyleType.Fixed:
                        expenseRequest.Required = item.Amount;
                        break;

                    case AnimalPaymentStyleType.perHead:
                        expenseRequest.Required = head * item.Amount;
                        break;

                    case AnimalPaymentStyleType.perAE:
                        expenseRequest.Required = aESum * item.Amount;
                        break;

                    case AnimalPaymentStyleType.ProportionOfTotalSales:
                        expenseRequest.Required = saleValue * item.Amount;
                        break;

                    default:
                        throw new Exception(String.Format("PaymentStyle [{0}] is not supported for [{1}] in [{2}]", item.PaymentStyle, item.Name, this.Name));
                    }
                    expenseRequest.Category = item.TransactionCategory;
                    // uses bank account specified in the RuminantActivityFee
                    item.BankAccount.Remove(expenseRequest);
                }
            }
        }