# How to setup a unit price based on a C# formula

Unit price C# formulas are added by the FBO One support team only. Contact support@fboone.com for guidance.

Contents:

## Information

FBO One typically defines unit price by price agreements for a product, applying a single price agreement to set the unit price of a service on the order. There may be scenarios where additional calculations are required; Price calculators may be used in these instances.

Alternatively, defining custom calculation formulas to calculate the unit price for a product can be used. This article describes how to set up such formulas.

Unit price formulas for unit price calculation receive a number of input arguments. These inputs are:

• Value of a custom property that you can choose

• Unit price as based on the price agreements for the product

• Maximum takeoff weight of the aircraft

• Aircraft footprint

For example, a service like parking fees may need a unit price that is calculated as

```1 ````unit price = (the aircraft square meters) X (a price per square meter)`

The parking fee will then be charged to customers as

```1 ````charged amount = no_of_days_of_parking X unit_price`
• The quantity (number of days) can be determined using the parking per 24 hours calculator

• The unit price can be calculated by using a custom formula. The formula can use the following inputs.

• The unit price from a price agreement indicating the 'price per square meter'

• A custom value assigned to each aircraft type named 'aircraft square meters'

## Formula specifications

The system is able to process a formula containing the following optional input values and any number value.

1. input.CustomValue: a custom value number assigned to any of the following: order, a/c registration, a/c type, debtor, form of payment.

2. input.UnitPrice: a unit price specified in price agreements or a manually entered unit price

3. input.MtowInKg (input.MtowInPounds): when available, the maximum take-off weight of the aircraft is expressed in kilograms or pounds,

4. input.FootprintInM2 (input.FootprintInSqFt): when available, the aircraft footprint in meter square or square feet

A basic formula example adding the unit price, custom value, and MTOW in kg would be:

```1 ````input.CustomValue + input.UnitPrice + input.MtowInKg; // the result is the sum of the 3 input values.`

The formula can also be only a number. In this case, the unit price that FBO One will return will be 10:

```1 ````10`

Input parameters are optional so the formula can work with fixed numbers

```1 ````10+10`

### Syntax

Formulas can only be written with the C# programming language syntax. The mathematical function that can be used is listed here.

Whenever the syntax is not correct, the system will show an error and the formula needs to be fixed.

Errors may show when one of the input parameters is used in the formula but does not have a value. For example, It can be that a price agreement unit price is not available so when used in a calculation, the system shows an error.

To prevent this, you need to write a more complex formula syntax:

```1 2 3 4 5 6 7 8 ``````((Func<decimal?>)(() => { // always use this type of declaration decimal? result = null; // always set a default return value if (input.CustomValue.HasValue && input.UnitPrice.HasValue) // the formula is applied only when both input parameters have a value { result = (input.CustomValue.Value * input.UnitPrice.Value); // the actual formula where the return value is set } return (decimal?)result; // return of the value: this will show the result of the calculation or a '?' in the order screen, indicating that something is missing (price agreement unit price or the custom value) }))(); // always end the formula like this ```

## How to set up a product with special unit price calculation formula

1. Navigate to the Edit Product page and scroll down to the 'Special price calculation' section.

2. (Optional) Select a custom property name to be used in the calculation. One custom value of this custom property should be linked to one of the following tables: order, aircraft registration, aircraft type, form of payment, debtor.

3. Define the formula which will calculate the unit price.

In this example, we will:

1. Create a custom property and values 'A/c footprint' to be used by the calculator and assigned to registrations.

2. Create a product named Parking Fee

3. Set-up the formula

4. Create a price agreement for the Parking Fee product

5. Assign the custom property to an a/c registration

6. Create one order with this a/c registration

7. Check the calculated Parking Fee service

#### 1. In Administration, create a custom property 'A/c foot print' and add a few values. Make this custom property available for Aircraft registrations. #### 2. Create a new product #### 3. Set up the calculator and formula in the Special price calculation section and then save the settings ```1 ````input.UnitPrice * input.CustomValue;  `

#### 4. Create a price agreement. On the details page of the new product, switch to the Price agreement tab and add a new price agreement. #### 5. Navigate to an aircraft registration page and assign an a/c footprint custom value.

In this example, we searched for CSDFD registration using the top right search box and clicked on ‘Edit registration’ to assign the custom value #### 6. Create a new handling order for CSDFD registration #### 7. Add the Parking fee service created before, and check the calculated price.

Expected amount: 0.36*10*1 day of parking= 3.6  ## Unit price formula examples

For example, the unit price calculation for an air navigation charge (RANC) product can be as follows: The input arguments in FBO One are setup as follows:

1. K = the custom value assigned to the aircraft registration

2. D -150 = a unit price specified in price agreements

3. square root of W/50 =  (decimal) Math.Sqrt((double)input.MtowInKg/50)

This translates in the following formula in FBO One:

```1 2 3 4 5 6 7 8 ``````((Func<decimal?>)(() => { // always use this type of declaratio decimal? result = null; // always set a default return value if (input.CustomValue.HasValue && input.UnitPrice.HasValue && input.MtowInKg.HasValue) { result = input.UnitPrice * input.CustomValue * (decimal)Math.Sqrt((double)input.MtowInKg/50); } return (decimal?)result; }))(); // always end the formula like this  ```
##### Parking per 24H with MTOW band different unit prices ##### Parking 24H first 6 tons
1. Unit price in price agreements: 0.5

1. Calculation formula:

```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ``````((Func<decimal?>)(() => { // this is the returned unit price value decimal? result = null; // ****** place here the start of the band ********* int tonsStartValue = 0; // ***** place here the end of the band ******** int tonsEndValue = 6; // change mtow from Kg to Tons int mtowTons = Convert.ToInt32(Math.Ceiling((input.MtowInKg.Value / 1000M))); // take here the charged amount of tons decimal mtowTonsBand; if (mtowTons <= tonsStartValue) mtowTonsBand = 0; // the mtowTonsBand is not in the range else // if the mtow is within the range, the overlapping tons are returned // if the mtow is higher than the end of the range, return the range mtowTonsBand = Math.Min(mtowTons, tonsEndValue) - tonsStartValue; // multiply the amount of tons with the price agreement unit price. result = (mtowTonsBand * input.UnitPrice.Value); return (decimal?)result; }))();```
##### Parking 24H > 6 tons
```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ``````((Func<decimal?>)(() => { // this is the returned unit price value decimal? result = null; // ****** place here the start of the band ********* int tonsStartValue = 7; // ***** place here the end of the band ******** int tonsEndValue = 99999; // change mtow from Kg to Tons int mtowTons = Convert.ToInt32(Math.Ceiling((input.MtowInKg.Value / 1000M))); // take here the charged amount of tons decimal mtowTonsBand; if (mtowTons <= tonsStartValue) mtowTonsBand = 0; // the mtowTonsBand is not in the range else // if the mtow is within the range, the overlapping tons are returned // if the mtow is higher than the end of the range, return the range mtowTonsBand = Math.Min(mtowTons, tonsEndValue) - tonsStartValue; // multiply the amount of tons with the price agreement unit price. result = (mtowTonsBand * input.UnitPrice.Value); return (decimal?)result; }))();```

This will multiply the unit price by the aircraft footprint in M2

```1 ````input.FootprintInM2 * input.UnitPrice`

The above setup should give the following parking charges for an order that is parked 2 days and has an MTOW of 20T:

On the order screen, you should see:

 Product Unit price Qty Amount Parking 24H first 6 tons 3 2 6 Parking 24H > 6 tons 3.25 2 6.5

The formula uses an implicit limit when setting the number of tons to be charged. Therefore the first 6 tons are charged with 0.5 while from the 7th ton, the 0.25 unit price is applied.
[Eg: (20 -7)*0.25 = 3.25 ]

##### Calculate a fee (for example Parking) based on Aircraft footprint.

The charge is a price per 24-Hrs, per 45-Metres squared

```1 ````input.FootprintInM2 * (input.UnitPrice/45)`

If the charge is per 45-Metres squared or part thereof, the following formula should be used:

```1 2 3 4 5 ``````((Func<decimal?>)(() => { var footprintPer45m2 = Convert.ToInt32(Math.Ceiling((input.FootprintInM2.Value/45M))); var result = (footprintPer45m2 * input.UnitPrice.Value); return (decimal?)result; }))();```
##### Multiply the unit price by the MTOW in tons (rounded up) e.g 22,001Kg = 23 Tons
```1 2 3 4 5 6 7 8 9 ``````((Func<decimal?>)(() => { decimal? result = null; if (input.UnitPrice.HasValue && input.MtowInKg.HasValue) { var mtowTons = Math.Ceiling((decimal)input.MtowInKg / 1000); result = input.UnitPrice * mtowTons; } return (decimal?)result; }))();```
##### Multiply the unit price by the aircraft footprint (m2) whereby the length and wingspan are rounded to the nearest meter prior to being multiplied e.g  16.2m = 16m and 16.55m=17m
```1 2 3 4 5 6 7 8 9 10 11 12 ``````((Func<decimal?>)(() => { var result = (decimal?)null; if (input.FootprintInM2.HasValue && input.UnitPrice.HasValue) { // Math.Round(1.2, MidpointRounding.AwayFromZero) ==> 1 // Math.Round(1.5, MidpointRounding.AwayFromZero) ==> 2 // Math.Round(2.5, MidpointRounding.AwayFromZero) ==> 3 var footprintm2 = Math.Round(input.FootprintInM2.Value, decimals: 0, mode: MidpointRounding.AwayFromZero); result = (footprintm2 * input.UnitPrice.Value); } return (decimal?)result; }))(); ```
##### Replicate TNC charges e.g. unit rate * (MTOWTons/50)^0.7
```1 2 3 4 5 6 7 8 9 10 11 12 ``````((Func<decimal?>)(() => { decimal? result = null; if (input.UnitPrice.HasValue && input.MtowInKg.HasValue) { int mtowTons = Convert.ToInt32(Math.Floor((input.MtowInKg.Value / 1000M))); result = input.UnitPrice * (decimal)Math.Pow((double)mtowTons/50, 0.7); result = Math.Floor(result.Value); } return (decimal?)result; }))();```
##### Calculate landing fees based on the unit price, multiplied by emission values and the MTOW in tonnes

It considers also a 'Custom value' assigned to the registration and a minimum fee.
See also How to configure an Off-Peak Landing Discount whilst maintaining a minimum fee

```1 2 3 4 5 6 7 8 9 10 11 12 13 ``````((Func<decimal?>)(() => { decimal? result = null; if (input.UnitPrice.HasValue && input.MtowInKg.HasValue && input.CustomValue.HasValue) { var emission = input.CustomValue.Value; int mtowTons = Convert.ToInt32(Math.Ceiling((input.MtowInKg.Value / 1000M))); result = input.UnitPrice * emission * mtowTons; result = (result.Value); } return (decimal?)result; }))();```
##### Charge per Tonne, subtracting 3-Tonnes from the MTOW
```1 2 3 4 5 6 7 8 9 10 11 12 13 14 ``````((Func<decimal?>)(() => { decimal? result = null; if (input.UnitPrice.HasValue && input.MtowInKg.HasValue) { var mtowTons = Math.Ceiling((decimal)input.MtowInKg / 1000); var freeTons = 3M; if (mtowTons > freeTons) mtowTons = mtowTons - freeTons; else mtowTons = 0M; result = input.UnitPrice * mtowTons; } return (decimal?)result; }))();```
##### Multiply the unit price by the MTOW in tons (rounded to the nearest) and then subtract 1 ton e.g. 22,001Kg = 22 Tons
```1 2 3 4 5 6 7 8 9 10 11 12 13 14 ``````((Func<decimal?>)(() => { decimal? result = null; if (input.UnitPrice.HasValue && input.MtowInKg.HasValue) { var mtowTons = Math.Round((decimal)input.MtowInKg / 1000, MidpointRounding.AwayFromZero); var freeTons = 1M; if (mtowTons > freeTons) mtowTons = mtowTons - freeTons; else mtowTons = 0M; result = input.UnitPrice * mtowTons; } return (decimal?)result; }))();```