private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            InsideMultiHarvestSequence = false;

            // activity is performed in CLEMDoCutAndCarry not CLEMGetResources
            this.AllocationStyle = ResourceAllocationStyle.Manual;

            fileCrop = simulation.FindAllDescendants().Where(a => a.Name == ModelNameFileCrop).FirstOrDefault() as IFileCrop;
            if (fileCrop == null)
            {
                throw new ApsimXException(this, String.Format("Unable to locate crop data reader [x={0}] requested by [a={1}]", this.ModelNameFileCrop ?? "Unknown", this.Name));
            }

            LinkedResourceItem = Resources.FindResourceType <ResourceBaseWithTransactions, IResourceType>(this, StoreItemName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop);
            if ((LinkedResourceItem as Model).Parent is GrazeFoodStore)
            {
                // set manager of graze food store if linked
                (LinkedResourceItem as GrazeFoodStoreType).Manager = (Parent as IPastureManager);
                addReason = "Growth";
            }

            // look up tree until we find a parent to allow nested crop products for rotate vs mixed cropping/products
            parentManagementActivity = FindAncestor <CropActivityManageCrop>();

            // Retrieve harvest data from the forage file for the entire run.
            // only get entries where a harvest happened (Amtkg > 0)
            HarvestData = fileCrop.GetCropDataForEntireRun(parentManagementActivity.LinkedLandItem.SoilType, CropName,
                                                           clock.StartDate, clock.EndDate).Where(a => a.AmtKg > 0).OrderBy(a => a.Year * 100 + a.Month).ToList <CropDataType>();
            if ((HarvestData == null) || (HarvestData.Count == 0))
            {
                Summary.WriteWarning(this, $"Unable to locate any harvest data in [x={fileCrop.Name}] using [x={fileCrop.FileName}] for soil type [{parentManagementActivity.LinkedLandItem.SoilType}] and crop name [{CropName}] between the dates [{clock.StartDate.ToShortDateString()}] and [{clock.EndDate.ToShortDateString()}]");
            }

            IsTreeCrop = (TreesPerHa == 0) ? false : true;  //using this boolean just makes things more readable.

            UnitsToHaConverter = (parentManagementActivity.LinkedLandItem.Parent as Land).UnitsOfAreaToHaConversion;

            // locate a cut and carry limiter associated with this event.
            limiter = LocateCutAndCarryLimiter(this);

            // check if harvest type tags have been provided
            HarvestTagsUsed = HarvestData.Where(a => a.HarvestType != "").Count() > 0;

            if (LinkedResourceItem is GrazeFoodStoreType)
            {
                double       firstMonthsGrowth = 0;
                CropDataType cropData          = HarvestData.Where(a => a.Year == clock.StartDate.Year && a.Month == clock.StartDate.Month).FirstOrDefault();
                if (cropData != null)
                {
                    firstMonthsGrowth = cropData.AmtKg;
                }

                (LinkedResourceItem as GrazeFoodStoreType).SetupStartingPasturePools(UnitsToHaConverter * (Parent as CropActivityManageCrop).Area * UnitsToHaConverter, firstMonthsGrowth);
                addReason = "Growth";
            }
        }
Пример #2
0
        /// <inheritdoc/>
        public override List <ResourceRequest> GetResourcesNeededForActivity()
        {
            if (this.TimingOK)
            {
                List <ResourceRequest> resourcesNeeded = new List <ResourceRequest>();
                double sumneeded;
                switch (PaymentStyle)
                {
                case CropPaymentStyleType.Fixed:
                    sumneeded = Amount;
                    break;

                case CropPaymentStyleType.perUnitOfLand:
                    CropActivityManageCrop cropParent = FindAncestor <CropActivityManageCrop>();
                    sumneeded = cropParent.Area * Amount;
                    break;

                case CropPaymentStyleType.perHa:
                    cropParent = FindAncestor <CropActivityManageCrop>();
                    CropActivityManageProduct productParent = FindAncestor <CropActivityManageProduct>();
                    sumneeded = cropParent.Area * productParent.UnitsToHaConverter * Amount;
                    break;

                case CropPaymentStyleType.perTree:
                    cropParent    = FindAncestor <CropActivityManageCrop>();
                    productParent = FindAncestor <CropActivityManageProduct>();
                    sumneeded     = productParent.TreesPerHa * cropParent.Area * productParent.UnitsToHaConverter * Amount;
                    break;

                default:
                    throw new Exception(String.Format("PaymentStyle ({0}) is not supported for ({1}) in ({2})", PaymentStyle, Name, this.Name));
                }
                resourcesNeeded.Add(new ResourceRequest()
                {
                    Resource           = BankAccount,
                    AllowTransmutation = false,
                    Required           = sumneeded,
                    ResourceType       = typeof(Finance),
                    ResourceTypeName   = AccountName,
                    ActivityModel      = this,
                    FilterDetails      = null,
                    RelatesToResource  = relatesToResourceName,
                    Category           = TransactionCategory
                }
                                    );
                return(resourcesNeeded);
            }
            return(null);
        }
Пример #3
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            fileCrop = Apsim.Child(Simulation, ModelNameFileCrop) as FileCrop;
            if (fileCrop == null)
            {
                throw new ApsimXException(this, String.Format("Unable to locate model for crop input file {0} (under Simulation) referred to in {1}", this.ModelNameFileCrop, this.Name));
            }

            switch (Store)
            {
            case StoresForCrops.HumanFoodStore:
                LinkedResourceItem = Resources.GetResourceItem(this, typeof(HumanFoodStore), StoreItemName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as IResourceType;
                break;

            case StoresForCrops.AnimalFoodStore:
                LinkedResourceItem = Resources.GetResourceItem(this, typeof(AnimalFoodStore), StoreItemName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as IResourceType;
                break;

            case StoresForCrops.GrazeFoodStore:
                LinkedResourceItem = Resources.GetResourceItem(this, typeof(GrazeFoodStore), StoreItemName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as IResourceType;
                break;

            case StoresForCrops.ProductStore:
                LinkedResourceItem = Resources.GetResourceItem(this, typeof(ProductStore), StoreItemName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as IResourceType;
                break;

            default:
                throw new Exception(String.Format("Store {0} is not supported for {1}", Enum.GetName(typeof(StoresForCrops), Store), this.Name));
            }

            parentManagementActivity = (CropActivityManageCrop)this.Parent;

            // Retrieve harvest data from the forage file for the entire run.
            HarvestData = fileCrop.GetCropDataForEntireRun(parentManagementActivity.LinkedLandItem.SoilType, CropName,
                                                           Clock.StartDate, Clock.EndDate).OrderBy(a => a.Year * 100 + a.Month).ToList <CropDataType>();
            if ((HarvestData == null) || (HarvestData.Count == 0))
            {
                throw new ApsimXException(this, String.Format("Unable to locate in crop file {0} any harvest data for SoilType {1}, CropName {2} between the dates {3} and {4}",
                                                              fileCrop.FileName, parentManagementActivity.LinkedLandItem.SoilType, CropName, Clock.StartDate, Clock.EndDate));
            }

            IsTreeCrop = (TreesPerHa == 0) ? false : true;  //using this boolean just makes things more readable.

            UnitsToHaConverter = (parentManagementActivity.LinkedLandItem.Parent as Land).UnitsOfAreaToHaConversion;
        }
Пример #4
0
        private void OnCLEMInitialiseActivity(object sender, EventArgs e)
        {
            // activity is performed in CLEMDoCutAndCarry not CLEMGetResources
            this.AllocationStyle = ResourceAllocationStyle.Manual;

            fileCrop = Apsim.ChildrenRecursively(Simulation).Where(a => a.Name == ModelNameFileCrop).FirstOrDefault() as IFileCrop;
            if (fileCrop == null)
            {
                throw new ApsimXException(this, String.Format("Unable to locate model for crop input file [x={0}] referred to in [a={1}]", this.ModelNameFileCrop ?? "Unknown", this.Name));
            }

            LinkedResourceItem = Resources.GetResourceItem(this, StoreItemName, OnMissingResourceActionTypes.ReportErrorAndStop, OnMissingResourceActionTypes.ReportErrorAndStop) as IResourceType;
            if ((LinkedResourceItem as Model).Parent.GetType() == typeof(GrazeFoodStore))
            {
                (LinkedResourceItem as GrazeFoodStoreType).Manager = (Parent as IPastureManager);
                addReason = "Growth";
            }

            // look up tree until we find a parent to allow nested crop products for rotate vs mixed cropping/products
            parentManagementActivity = Apsim.Parent(this, typeof(CropActivityManageCrop)) as CropActivityManageCrop;

            // Retrieve harvest data from the forage file for the entire run.
            // only get entries where a harvest happened (Amtkg > 0)
            HarvestData = fileCrop.GetCropDataForEntireRun(parentManagementActivity.LinkedLandItem.SoilType, CropName,
                                                           Clock.StartDate, Clock.EndDate).Where(a => a.AmtKg > 0).OrderBy(a => a.Year * 100 + a.Month).ToList <CropDataType>();
            if ((HarvestData == null) || (HarvestData.Count == 0))
            {
                Summary.WriteWarning(this, String.Format("Unable to locate any harvest data in [x={0}] using [x={1}] for soil type [{2}] and crop name [{3}] between the dates [{4}] and [{5}]",
                                                         fileCrop.Name, fileCrop.FileName, parentManagementActivity.LinkedLandItem.SoilType, CropName, Clock.StartDate.ToShortDateString(), Clock.EndDate.ToShortDateString()));
            }

            IsTreeCrop = (TreesPerHa == 0) ? false : true;  //using this boolean just makes things more readable.

            UnitsToHaConverter = (parentManagementActivity.LinkedLandItem.Parent as Land).UnitsOfAreaToHaConversion;

            // locate a cut and carry limiter associated with this event.
            limiter = LocateCutAndCarryLimiter(this);

            // set manager of graze food store if linked
        }
Пример #5
0
        /// <summary>
        /// Determines how much labour is required from this activity based on the requirement provided
        /// </summary>
        /// <param name="requirement">The details of how labour are to be provided</param>
        /// <returns></returns>
        public override double GetDaysLabourRequired(LabourRequirement requirement)
        {
            double daysNeeded;
            double numberUnits;

            switch (requirement.UnitType)
            {
            case LabourUnitType.Fixed:
                daysNeeded = requirement.LabourPerUnit;
                break;

            case LabourUnitType.perHa:
                CropActivityManageCrop    cropParent    = Apsim.Parent(this, typeof(CropActivityManageCrop)) as CropActivityManageCrop;
                CropActivityManageProduct productParent = Apsim.Parent(this, typeof(CropActivityManageProduct)) as CropActivityManageProduct;
                numberUnits = cropParent.Area * productParent.UnitsToHaConverter / requirement.UnitSize;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            case LabourUnitType.perTree:
                cropParent    = Apsim.Parent(this, typeof(CropActivityManageCrop)) as CropActivityManageCrop;
                productParent = Apsim.Parent(this, typeof(CropActivityManageProduct)) as CropActivityManageProduct;
                numberUnits   = productParent.TreesPerHa * cropParent.Area * productParent.UnitsToHaConverter / requirement.UnitSize;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            case LabourUnitType.perKg:
                productParent = Apsim.Parent(this, typeof(CropActivityManageProduct)) as CropActivityManageProduct;
                numberUnits   = productParent.AmountHarvested;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            case LabourUnitType.perUnit:
                productParent = Apsim.Parent(this, typeof(CropActivityManageProduct)) as CropActivityManageProduct;
                numberUnits   = productParent.AmountHarvested / requirement.UnitSize;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            default:
                throw new Exception(String.Format("LabourUnitType {0} is not supported for {1} in {2}", requirement.UnitType, requirement.Name, this.Name));
            }
            return(daysNeeded);
        }
Пример #6
0
        /// <summary>
        /// Determines how much labour is required from this activity based on the requirement provided
        /// </summary>
        /// <param name="requirement">The details of how labour are to be provided</param>
        /// <returns></returns>
        public override GetDaysLabourRequiredReturnArgs GetDaysLabourRequired(LabourRequirement requirement)
        {
            double numberUnits;
            double daysNeeded;

            switch (requirement.UnitType)
            {
            case LabourUnitType.Fixed:
                daysNeeded = requirement.LabourPerUnit;
                break;

            case LabourUnitType.perUnitOfLand:
                CropActivityManageCrop cropParent = FindAncestor <CropActivityManageCrop>();
                numberUnits = cropParent.Area;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }
                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            case LabourUnitType.perHa:
                cropParent = FindAncestor <CropActivityManageCrop>();
                CropActivityManageProduct productParent = FindAncestor <CropActivityManageProduct>();
                numberUnits = cropParent.Area * productParent.UnitsToHaConverter / requirement.UnitSize;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            case LabourUnitType.perTree:
                cropParent    = FindAncestor <CropActivityManageCrop>();
                productParent = FindAncestor <CropActivityManageProduct>();
                numberUnits   = productParent.TreesPerHa * cropParent.Area * productParent.UnitsToHaConverter / requirement.UnitSize;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            case LabourUnitType.perKg:
                productParent = FindAncestor <CropActivityManageProduct>();
                numberUnits   = productParent.AmountHarvested;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            case LabourUnitType.perUnit:
                productParent = FindAncestor <CropActivityManageProduct>();
                numberUnits   = productParent.AmountHarvested / requirement.UnitSize;
                if (requirement.WholeUnitBlocks)
                {
                    numberUnits = Math.Ceiling(numberUnits);
                }

                daysNeeded = numberUnits * requirement.LabourPerUnit;
                break;

            default:
                throw new Exception(String.Format("LabourUnitType {0} is not supported for {1} in {2}", requirement.UnitType, requirement.Name, this.Name));
            }

            return(new GetDaysLabourRequiredReturnArgs(daysNeeded, this.Category, RelatesToResourceName));
        }
Пример #7
0
        /// <summary>
        /// Method to determine resources required for this activity in the current month
        /// </summary>
        /// <returns>List of required resource requests</returns>
        public override List <ResourceRequest> GetResourcesNeededForActivity()
        {
            ResourceRequestList = null;

            if (this.TimingOK)
            {
                // get all crop fees for task
                foreach (CropActivityFee item in Apsim.Children(this, typeof(CropActivityFee)))
                {
                    if (ResourceRequestList == null)
                    {
                        ResourceRequestList = new List <ResourceRequest>();
                    }
                    double sumneeded = 0;
                    switch (item.PaymentStyle)
                    {
                    case CropPaymentStyleType.Fixed:
                        sumneeded = item.Amount;
                        break;

                    case CropPaymentStyleType.perHa:
                        CropActivityManageCrop    CropParent    = Parent.Parent as CropActivityManageCrop;
                        CropActivityManageProduct ProductParent = Parent as CropActivityManageProduct;
                        sumneeded = CropParent.Area * ProductParent.UnitsToHaConverter * item.Amount;
                        break;

                    case CropPaymentStyleType.perTree:
                        CropParent    = Parent.Parent as CropActivityManageCrop;
                        ProductParent = Parent as CropActivityManageProduct;
                        sumneeded     = ProductParent.TreesPerHa * CropParent.Area * ProductParent.UnitsToHaConverter * item.Amount;
                        break;

                    default:
                        throw new Exception(String.Format("PaymentStyle ({0}) is not supported for ({1}) in ({2})", item.PaymentStyle, item.Name, this.Name));
                    }
                    ResourceRequestList.Add(new ResourceRequest()
                    {
                        AllowTransmutation = false,
                        Required           = sumneeded,
                        ResourceType       = typeof(Finance),
                        ResourceTypeName   = "General account",
                        ActivityModel      = this,
                        FilterDetails      = null,
                        Reason             = item.Name
                    }
                                            );
                }

                // for each labour item specified
                foreach (var item in labour)
                {
                    double daysNeeded = 0;
                    switch (item.UnitType)
                    {
                    case LabourUnitType.Fixed:
                        daysNeeded = item.LabourPerUnit;
                        break;

                    case LabourUnitType.perHa:
                        CropActivityManageCrop    CropParent    = Parent.Parent as CropActivityManageCrop;
                        CropActivityManageProduct ProductParent = Parent as CropActivityManageProduct;
                        daysNeeded = Math.Ceiling(CropParent.Area * ProductParent.UnitsToHaConverter / item.UnitSize) * item.LabourPerUnit;
                        break;

                    case LabourUnitType.perTree:
                        CropParent    = Parent.Parent as CropActivityManageCrop;
                        ProductParent = Parent as CropActivityManageProduct;
                        daysNeeded    = Math.Ceiling(ProductParent.TreesPerHa * CropParent.Area * ProductParent.UnitsToHaConverter / item.UnitSize) * item.LabourPerUnit;
                        break;

                    default:
                        throw new Exception(String.Format("LabourUnitType {0} is not supported for {1} in {2}", item.UnitType, item.Name, this.Name));
                    }
                    if (daysNeeded > 0)
                    {
                        if (ResourceRequestList == null)
                        {
                            ResourceRequestList = new List <ResourceRequest>();
                        }
                        ResourceRequestList.Add(new ResourceRequest()
                        {
                            AllowTransmutation = false,
                            Required           = daysNeeded,
                            ResourceType       = typeof(Labour),
                            ResourceTypeName   = "",
                            ActivityModel      = this,
                            FilterDetails      = new List <object>()
                            {
                                item
                            }
                        }
                                                );
                    }
                }
            }
            return(ResourceRequestList);
        }
Пример #8
0
        /// <inheritdoc/>
        public override List <ResourceRequest> GetResourcesNeededForActivity()
        {
            if (this.TimingOK)
            {
                List <ResourceRequest> resourcesNeeded = new List <ResourceRequest>();
                double sumneeded;
                switch (PaymentStyle)
                {
                case CropPaymentStyleType.Fixed:
                    sumneeded = Amount;
                    break;

                case CropPaymentStyleType.perUnitOfLand:
                    CropActivityManageCrop cropParent = FindAncestor <CropActivityManageCrop>();
                    sumneeded = cropParent.Area * Amount;
                    break;

                case CropPaymentStyleType.perHa:
                    cropParent = FindAncestor <CropActivityManageCrop>();
                    CropActivityManageProduct productParent = FindAncestor <CropActivityManageProduct>();
                    sumneeded = cropParent.Area * productParent.UnitsToHaConverter * Amount;
                    break;

                case CropPaymentStyleType.perTree:
                    cropParent    = FindAncestor <CropActivityManageCrop>();
                    productParent = FindAncestor <CropActivityManageProduct>();
                    sumneeded     = productParent.TreesPerHa * cropParent.Area * productParent.UnitsToHaConverter * Amount;
                    break;

                default:
                    throw new Exception(String.Format("PaymentStyle ({0}) is not supported for ({1}) in ({2})", PaymentStyle, Name, this.Name));
                }
                resourcesNeeded.Add(new ResourceRequest()
                {
                    Resource           = BankAccount,
                    AllowTransmutation = false,
                    Required           = sumneeded,
                    ResourceType       = typeof(Finance),
                    ResourceTypeName   = AccountName,
                    ActivityModel      = this,
                    FilterDetails      = null,
                    RelatesToResource  = relatesToResourceName,
                    Category           = TransactionCategory
                }
                                    );
                if (managingParent.CurrentlyManaged)
                {
                    if (sumneeded > 0)
                    {
                        Status = ActivityStatus.Success;
                    }
                    else
                    {
                        Status = ActivityStatus.NotNeeded;
                    }
                }
                else
                {
                    Status = ActivityStatus.Warning;
                    if (!timingIssueReported)
                    {
                        Summary.WriteMessage(this, $"The harvest timer for crop task [a={this.NameWithParent}] did not allow the task to be performed. This is likely due to insufficient time between rotating to a crop and the next harvest date.", MessageType.Warning);
                        timingIssueReported = true;
                    }
                }

                return(resourcesNeeded);
            }
            return(null);
        }