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"; } }
/// <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); }
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; }
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 }
/// <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); }
/// <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)); }
/// <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); }
/// <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); }