Using resources in activities
Advanced topic - requires coding skills
Activities in CLEM are designed to use and/or create resources. For this reason a range of functionality has been built into the CLEM model to facilitate accessing resources, checking for resource availability, limiting actions if some resources are in shortfall, managing transmutations and managing resource transactions.

Units are not handled uniformly between resources in the model. While most resources allow you to specify nominal units and work with these through the simulation, there are times when a standard unit is required, or a converter must be supplied.
While the user can work with any unit of area, many calculations are performed in hectares and so a AreaToHectares converter is a required property of the Land resource.
As human food can come in many units from each (eggs), litres (milk) and kilograms (cereal) these nominal units are provided to manage the human food store types. However, when it comes to transporting or eating these units a standard kg is needed and so a conversion is needed.

The CLEMActivityBase provides all activities with a private link to the Resource holder where all resources are stored and containing a number of methods to return resource groups or resource types.
There is a public method available for each Resource group currently available in CLEM. For example you can call AnimalFoodStore() from the ResourcesHolder to obtain the Animal Food Store. The methods available include; Products(), AnimalFoodStore(), OtherAnimalsStore(), HumanFoodStore(), GreenhouseGases(), Labour(), Land(), GrazeFoodStore(), RuminantHerd() and FinanceResource().
Each of these methods simply calls the following private method and casts the returned model as the correct store type.
Additional methods return whether a group specified by name or type exists, or whether the specified group contains items.
public bool ResourceGroupExist(Type resourceGroupType)
public bool ResourceItemsExist(Type resourceGroupType)
public object GetResourceGroupByName(string name)
public object GetResourceGroupByType(string name)
The most common method to request a resource from within an Activity is to use the GetResourceItem methods of the Resource Group.
There are three versions of this method depending upon the parameters passed. All three require two OnMissingResourceActionTypes to be passed to determine the action taken if the requested resource group or resource type are not found. The options available are ReportErrorAndStop, ReportWarning or Ignore and carry on. These option will automatically handle validation checking of the presence of resources in your activities.
The other parameters that can be passed are
ResourceRequest
The Resource Request object is used by CLEM to pass information about a resource request and holds values such as the requesting activity, resource group, resource type, amount needed, and amount provided. This is a common object to be used when working with resource transactions.
Requesting model, resource group type and resource type name
The method provides all the information to find the resource when an resource request is not available.
Requesting model, resource group and item as dot delimited string
The final version of the method takes the full string path of the resource needed (ResourceGroupName.ResourceTypeItemName) as provided by resource drop-down boxes in the CLEM user interface.


This default method manages the request and provisioning of resources to an activity as well as calling the code to perform the activity specific tasks. Much of this code is provided by the CLEMActivityBase.
As stated in Importance of component order the order activities are provided will be the order they take resources (except for a few special cases, see below). The process of activities working with available resources is managed by Activities holder during the CLEMGetResorucesRequired event. This event fires after handling start of CLEM time-step, updating labour availability, updating pasture, breeding, milk production and calculating animal potential intake.
During this event the Activities holder calls the GetResourcesForAllActivities method of all it's immediate children.
This method of the CLEMActivityBase checks that the activity is enabled and that timing is ok. If ok to proceed the protected CLEMActivityBase.ResourcesForAllActivities method is called.
This method calls the GetResourcesRequiredForActivity that in turn calls the protected void ResourcesRequiredForActivity method.
The CLEMActivityBase.ResourcesRequiredForActivity performs the following steps

A new empty resource request list (List<ResourceRequest>) is created to hold all resources needed for the activity in this time-step.

Labour is a special resource and any activity can have an associated Labour requirement. The GetLabourResourcesNeededForActivity is a common method provided by the CLEMActivityBase to get the labour required. However, this common method does not know the amount of labour (days) required by the specific event. This is obtained from the overridden GetDaysLabourRequired() method that every activity must provide. This is called for every labour requirement component supplied with the activity. As there are different styles of labour requirements as well as different rules and means of calculating the days needed this code is provided in each activity.

The next steps calls the overridden GetResourcesNeededForActivity() method of each Activity that returns a list of ResourceRequests of all resources (non-labour) that the activity needs. This is added to the labour requirements.

This step calls the CLEMActivityBase.CheckResources method, passing the resource list needed and a unique identifier for this request.
The next step is to check that the resources requested exist and calculate the amount of each resource available by doing a non-take attempt at taking the resources.
From this information we are now able to determine whether all resources requested were available or is shortfalls were present.
If shortfalls were present this method next tries to perform any transmutation that is present and allowed, thus converting another resource(s) to fill the shortfall.
After transmutation is attempted, we again check for shortfalls and report any remaining through the ShortfallOccurred event that is trapped by the Activity holder and provided for a shortfall ledger.

This step provides the activity a chance to adjust the resources required as a result of now knowing what is available.
This is performed in the overridden AdjustResourcesNeededForActivity method of each activity.

This step determines whether the activity can proceed based on the OnPartialResourcesAvailable action and the presence of any resource shortfalls. If appropriate errors or warnings will be provided here and the simulation halted if required.

The provision of labour is more complicated than other resources and so gets its own TakeLabour method in the CLEM activity base.
This method needed to determine where the labour request is coming from and manage any Labour filter groups present. It also handles the rules about the order individuals are provided, minimum and maximum labour allocations and if more than one individual is required to perform the task.
This method returns the amount of labour provided and removes the days from the allocated individuals.

This method checks that the resource type has been defined and is available and removes the requested amount, returning the amount provided.

With all resources handled the activity can now perform the activity specific code with the overridden DoActivity() method.
The base activity class provides a couple methods to return a LabourLimiter that determines what proportion of the required labour was supplied. Likewise a LimitingProportion(type) will determine what proportion of a specified type (e.g. Finance) was available for performing the activity and limiting the system.

Some activities will need to perform their allocation of labour and activity tasks at times other than the CLEMGetResorucesRequired event.
To achieve this set
this.AllocationStyle = ResourceAllocationStyle.Manual;
in the CLEMInitialiseActivity event. Then subscribe an event to the CLEM event where you want your activity to take place. Great care must be taken so that you don't break any flow logic and perform tasks before they are ready to be performed. Inside this event call
GetResourcesRequiredForActivity();
This will then move through the process provided in the Automatic Method above.

Whenever an Add or Remove method of a resource type is called a ResourceTransaction is added as a TransactionEventArgs of the TransactionOccurred event that is fired. The Resource holder catches this event and stores the last transaction details that can be reported as a resource ledger of all resource transactions.

Shortfalls detected during the CheckResources method, while processing an activity, fire ShortfallOccurred event that is trapped by the Activity holder and provided for a shortfall ledger.