# service

{% hint style="success" %}
This article assumes a knowledge of services, their rates and related concepts as documented in [Services in Exivity](https://olddocs.exivity.io/2.3.1/getting-started/concepts/services)
{% endhint %}

## Overview

The `service` statement is used to create or modify a single [service definition](https://olddocs.exivity.io/2.3.1/getting-started/concepts/services) during the execution of a Transcript task. The service definition is associated with the data in an existing DSET, and the [global database](https://olddocs.exivity.io/2.3.1/getting-started/concepts/datasets#the-global-rdf) is updated if and when the Transcript task successfully completes.

## Syntax

**`service`***`{ param1 = value [... paramN = value] }`*

Example:

```
service {
    key = "A1 VM"
    usage_col = "A1 VM - EU North"
    description = "A1 VM (EU North)"
    category = "Virtual Machines"
    interval = monthly
    model = unprorated
    unit_label = "Instances"
    rate = 0.8
    fixed_price = 10
    cogs = 45
    fixed_cogs = 16
    min_commit = 4
}
```

{% hint style="info" %}
Parameters may be specified in any order. The '=' between parameters and their values is optional and may be omitted, but if present it must be surrounded by white-space
{% endhint %}

## Details

### Summary

The `service` statement is used to create a new service definition. Once created, a service definition automatically becomes available to the reporting engine.

### Parameter table

The `service` statement creates a new service using the following parameters:

| Parameter             | Required | Notes                                                                                          |
| --------------------- | -------- | ---------------------------------------------------------------------------------------------- |
| *key*                 | Yes      | A unique identifier for the service                                                            |
| *description*         | No       | The name of the service as it will appear on a report                                          |
| *category* or *group* | No       | Services are grouped by category on a report                                                   |
| *usage\_col*          | Yes      | The name of the column containing the number of units consumed                                 |
| *interval*            | No       | The charging interval for the service                                                          |
| *model*               | No       | Whether the service charges should be prorated or not                                          |
| *unit\_label*         | No       | The label for the units of consumption; eg: `GB` for storage                                   |
| *account\_id*         | No       | Which account to associate with the rate revision                                              |
| *rate*                | No       | The price per unit of consumption                                                              |
| *fixed\_price*        | No       | The fixed price which will be charged regardless of non-zero usage in the charge interval      |
| *cogs*                | No       | The COGS price per unit of consumption                                                         |
| *fixed\_cogs*         | No       | The fixed COGS price which will be charged regardless of non-zero usage in the charge interval |
| *min\_commit*         | No       | The minimum number of units of consumption that will be charged per interval                   |
| *effective\_date*     | No       | The date from which the rate revision should be applied                                        |

### Parameter details

#### key

The *key* parameter must be distinct from that in any other service unless it is used to identify an existing service definition to be overwritten with new values. By default, an attempt to create a service with a key that is a duplicate to an existing service in the global database will result in a warning in the logfile and no further action will be taken.

If the *key* matches that of a service that has been defined previously in the task file then one of two things can happen depending on the value of the current [execution mode](https://olddocs.exivity.io/2.3.1/diving-deeper/transform/option#execution-mode):

1. If the mode is set to `strict` then an error is logged and the task will fail
2. If the mode is set to `permissive` then a warning is logged and the newest service definition is ignored

{% hint style="info" %}
To override the default protection against overwriting existing service definitions in the global database, the statement [option services = overwrite](https://olddocs.exivity.io/2.3.1/diving-deeper/transform/language/option) should be invoked prior to the `service` statement.
{% endhint %}

The value of the *key* parameter may be up to 127 characters in length. Longer names will be truncated (and as a result may no longer be unique).

#### description

The *description* parameter is freely definable and does not have to be unique. When a report is generated, the description of a service will be used on that report so care should be taken to make the description meaningful.

By default, if *description* is not specified in a service definition then a copy of the *key* will be used as the description.

The value of the *description* parameter may be up to 255 characters in length. Longer descriptions will be truncated.

#### category / group

{% hint style="info" %}
Either *category* or *group* may be used. The two terms are interchangeable in this context.
{% endhint %}

The *category* parameter is used to logically associate a service with other services. All services sharing the same *category* will be grouped together on reports. Any number of different categories may exist and if the category specified does not exist then it will be automatically created.

If no category is specified then the service will be placed into a category called `Default`.

The value of the *category* parameter may be up to 63 characters in length. Longer values will be truncated.

#### usage\_col

In order to calculate a price for a service, the number of units of that service that were consumed needs to be known. The value of the *usage\_col* parameter specifies the column in the usage data which contains this figure.

The *usage\_col* argument is also used to derive the DSET associated with the service as follows:

* If the value of *usage\_col* is a [fully qualified](https://olddocs.exivity.io/2.3.1/getting-started/concepts/datasets#fully-qualified-column-names) column name then the service will be associated with the DSET identified by that name
* If the value of *usage\_col* is not fully qualified then the service will be associated with the default DSET

If the column specified by the *usage\_col* argument is determined not to exist using the above checks, then one of two things can happen depending on the value of the current [execution mode](https://olddocs.exivity.io/2.3.1/diving-deeper/transform/option#execution-mode):

1. If the mode is set to `strict` then an error is logged and the task will fail
2. If the mode is set to `permissive` then a warning is logged and the service definition is ignored

The value of the *usage\_col* parameter may be up to 255 characters in length. Longer values will be truncated.

#### interval

Services may be charged in different ways. For example some services will invoke a charge whenever they are used whereas others are charged by a time interval, such as per month.

The value of the *interval* parameter determines how the service should be charged as per the following table:

| Interval value | Meaning                                                                                                                                                                                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `individually` | Every unit of consumption is charged individually. For example if a network-related service charges by the GB, then for every GB seen in the usage the charge is applied regardless of how many GB are used or over how long a period of time the consumption took place. |
| `hourly`       | The charge is applied once per hour regardless of the number of times within the hour the service was consumed                                                                                                                                                            |
| `daily`        | As for `hourly` but applied per-day                                                                                                                                                                                                                                       |
| `monthly`      | As for `daily` but applied per calendar month                                                                                                                                                                                                                             |

#### model

Specifies whether or not to apply [proration](https://olddocs.exivity.io/2.3.1/getting-started/concepts/services#charge-models) when calculating the charge for a monthly service.

{% hint style="info" %}
Currently, only monthly services can be prorated, based on the number of days in the month the service was used.
{% endhint %}

| Model value  | Meaning                       |
| ------------ | ----------------------------- |
| `unprorated` | No proration is to be applied |
| `prorated`   | Proration will be applied     |

#### unit\_label

The *unit\_label* is the label used for units of consumption on reports. For example storage-related services may be measured in `Gb` or `Tb`, Virtual Machines may be measured in `Instances` and software usage may be measured in `licenses`.

The specified *unit\_label* value may be up to 63 characters in length. Longer values will be truncated.

If the *unit\_label* parameter is not specified then a default value of `Units` will be used.

#### account\_id

{% hint style="danger" %}
The *account\_id* parameter is intended for internal use only and should not be used
{% endhint %}

The optional *account\_id* references an entry in the *account* table in the global database. If specified, the service will be created with a rate revision specific to the account id.

The default rate for the service (which applies to all combinations of report column values not explicitly associated with their own rate) can be defined in any of the following ways:

* By omitting the *account\_id* parameter altogether
* By specifying an *account\_id* of `0`
* By specifying an *account\_id* of `*`

#### rate

The *rate* parameter determines the cost per unit of consumption to use when calculating the charge. A rate of `0.0` may be used if there is no charge associated with the service.

This may be used in conjunction with a *fixed\_price* and one of *cogs* or *fixed\_cogs*.

Either or both of *rate* or *fixed\_price* may be specified, but at least one of them is required.

#### fixed\_price

The *fixed\_price* is a charge applied to the service per charge interval regardless of the units of consumption.

This may be used in conjunction with a *rate* and one of *cogs* or *fixed\_cogs*

Either or both of *rate* or *fixed\_price* may be specified, but at least one of them is required.

#### cogs

The optional COGS charge is the price to the provider of the service. Usually, COGS-related charges are not included on reports special permissions are required to see the COGS charges.

For services with a defined *cogs* value it is possible to generate Profit and Loss reports, the profit/loss being the total charge calculated from the *rate* and/or *fixed\_rate* values minus the price calculated from the *cogs* or *fixed\_cogs* values.

#### fixed\_cogs

The optional *fixed\_cogs* value is a fixed price to be factored into COGS-related calculations regardless of the number of units consumed in the charging interval.

#### min\_commit

The optional *min\_commit* parameter specifies a minimum number of units of consumption to include when calculating the charge associated with a service. In cases where the actual consumption is greater than the *min\_commit* value this will have no effect, but where the actual consumption is less than the minimum commit the price will be calculated as if the *min\_commit* units had been consumed.

### The Service Definition cache

Once all parameters have been evaluated by the `service` statement the resulting service definition is added to a cache in memory. This cache is committed to the [global database](https://olddocs.exivity.io/2.3.1/getting-started/concepts/datasets#the-global-rdf) at the successful conclusion of the Transcript task (or discarded in the case of error).

Once a service definition has been added to the cache, no subsequent service definitions with the same key may be added to the cache. In the event of conflict the first definition written to the cache is perserved and the attempt to add a duplicate will result in a warning or an error depending on the value of the current [execution mode](https://olddocs.exivity.io/2.3.1/diving-deeper/transform/option#execution-mode) as described in the [key](#key) section above.

### Rate revisions

As described in [Services in Exivity](https://olddocs.exivity.io/2.3.1/getting-started/concepts/services) a service may have multiple rate revisions associated with it. The `service` statement can only create a single rate revision per service per execution of a Transcript task.

A rate revision consists of the *rate*, *fixed\_rate*, *cogs*, *fixed\_cogs* and *effective\_date* parameters. Each revision must have a different *effective\_date* which indicates the date from which that service revision is to be used. A rate definition remains in force for all dates on or after the *effective\_date*, or until such time as a rate revision with a later *effective\_date* is defined (at which point that revision comes into effect).

To create multiple revisions, Transcript must be run multiple times using a `service` statement that has the same *key* and uses the same *rate*, *fixed\_rate*, *cogs* and *fixed\_cogs* values but has a different *effective\_date* each time. For each of the *effective\_date* parameters a new rate revision will be created for the service.

### Updating the Global Database

At the successful conclusion of a Transcript task the [global database](https://olddocs.exivity.io/2.3.1/getting-started/concepts/datasets#the-global-rdf) is updated from the memory cache.

## Examples

```
service {
    key = "Azure A1 VM"
    usage_col = "A1 VM - EU North"
    description = "Azure A1 VM (EU North)"
    category = "Virtual Machines"
    interval = monthly
    model = unprorated
    unit_label = "instances"
    min_commit = 2
    rate = 0.8
    fixed_price = 0.2
    cogs = 0.55
}
```
