예제 #1
0
        /// <summary>
        /// Validate model
        /// </summary>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        public IEnumerable <ValidationResult> Validate(ValidationContext validationContext)
        {
            var results = new List <ValidationResult>();

            if (this.Parent.GetType() != typeof(CropActivityManageProduct))
            {
                string[] memberNames = new string[] { "Parent model" };
                results.Add(new ValidationResult("A crop activity task must be placed immediately below a CropActivityManageProduct model component", memberNames));
            }

            CropActivityManageProduct ProductParent = Parent as CropActivityManageProduct;

            foreach (CropActivityFee item in Apsim.Children(this, typeof(CropActivityFee)))
            {
                if (!ProductParent.IsTreeCrop)
                {
                    if (item.PaymentStyle == CropPaymentStyleType.perTree)
                    {
                        string[] memberNames = new string[] { item.Name + ".PaymentStyle" };
                        results.Add(new ValidationResult("The payment style " + item.PaymentStyle.ToString() + " is not supported for crops defined non tree crops", memberNames));
                    }
                }
            }
            return(results);
        }
예제 #2
0
 private void OnCLEMInitialiseActivity(object sender, EventArgs e)
 {
     BankAccount    = Resources.FindResourceType <Finance, FinanceType>(this, AccountName, OnMissingResourceActionTypes.Ignore, OnMissingResourceActionTypes.ReportErrorAndStop);
     managingParent = FindAncestor <CropActivityManageProduct>();
     if (managingParent != null)
     {
         relatesToResourceName = managingParent.StoreItemName;
     }
 }
예제 #3
0
        /// <summary>
        /// Method to adjust area planted if crop has a area planted multiplier
        /// </summary>
        /// <param name="cropProduct">The crop product details to define final land area</param>
        private void AdjustLand(CropActivityManageProduct cropProduct)
        {
            // is this using available land and not yet assigned, or not using available land
            if (Area == 0 || !UseAreaAvailable)
            {
                // is the requested land different to land currently provided
                double areaneeded = UseAreaAvailable ? LinkedLandItem.AreaAvailable : (AreaRequested * cropProduct.PlantedMultiplier) - Area;
                if (areaneeded != 0)
                {
                    if (areaneeded > 0)
                    {
                        ResourceRequestList = new List <ResourceRequest> {
                            new ResourceRequest()
                            {
                                Resource           = LinkedLandItem,
                                AllowTransmutation = false,
                                Required           = areaneeded,
                                ResourceType       = typeof(Land),
                                ResourceTypeName   = LandItemNameToUse,
                                ActivityModel      = this,
                                Category           = TransactionCategory,
                                FilterDetails      = null,
                                RelatesToResource  = cropProduct.LinkedResourceItem.Name
                            }
                        };

                        if (!UseAreaAvailable & LinkedLandItem != null)
                        {
                            CheckResources(ResourceRequestList, Guid.NewGuid());
                            TakeResources(ResourceRequestList, false);
                            //Now the Land has been allocated we have an Area
                            //Assign the area actually got after taking it. It might be less than AreaRequested (if partial)
                            Area += ResourceRequestList.FirstOrDefault().Provided;
                        }
                        else
                        {
                            Area += areaneeded;
                        }
                    }
                    else
                    {
                        // excess land for planting can be reterned to land resource
                        // careful that this doesn't get taken by a use all available elewhere if you want it back again.
                        if (LinkedLandItem != null)
                        {
                            LinkedLandItem.Add(-areaneeded, this, cropProduct.LinkedResourceItem.Name, this.TransactionCategory);
                            Area += areaneeded;
                        }
                    }
                }
            }
        }
예제 #4
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);
        }
예제 #5
0
        /// <summary>
        /// Validate model
        /// </summary>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        public IEnumerable <ValidationResult> Validate(ValidationContext validationContext)
        {
            var results = new List <ValidationResult>();
            CropActivityManageProduct productParent = FindAncestor <CropActivityManageProduct>();

            if (!productParent.IsTreeCrop)
            {
                if (this.PaymentStyle == CropPaymentStyleType.perTree)
                {
                    string[] memberNames = new string[] { this.Name + ".PaymentStyle" };
                    results.Add(new ValidationResult("The payment style " + this.PaymentStyle.ToString() + " is not supported for crops defined as non tree crops", memberNames));
                }
            }
            return(results);
        }
예제 #6
0
        /// <summary>
        /// Validate model
        /// </summary>
        /// <param name="validationContext"></param>
        /// <returns></returns>
        public IEnumerable <ValidationResult> Validate(ValidationContext validationContext)
        {
            var results = new List <ValidationResult>();
            // check that this activity has a parent of type CropActivityManageProduct

            Model current = this;

            while (current.GetType() != typeof(ZoneCLEM))
            {
                if (current.GetType() == typeof(CropActivityManageProduct))
                {
                    ManageProductActivity = current as CropActivityManageProduct;
                }
                current = current.Parent as Model;
            }

            if (ManageProductActivity == null)
            {
                string[] memberNames = new string[] { "CropActivityManageProduct parent" };
                results.Add(new ValidationResult("This crop timer be below a parent of the type Crop Activity Manage Product", memberNames));
            }

            return(results);
        }
예제 #7
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);
        }
예제 #8
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));
        }
예제 #9
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);
        }
예제 #10
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);
        }