# Services

In VARIO Cloud, scripts access the full ERP functionality through `ctx.services`. This shared service layer is the backbone of all scripting — it is available in both workflow and batch scripts, and every service works identically in either context.

The services and methods shown below are examples. For the complete list of available services, methods, and parameters, see the Scripting Reference.

***

## Entity Services

Entity services are the primary way to read, create, update, and deactivate business objects in VARIO Cloud. They manage core ERP records — accounts, articles, documents, CRM objects, and more. Most share a common method pattern:

| Method                         | Description                                       |
| ------------------------------ | ------------------------------------------------- |
| `getNewDto()`                  | Create a new empty DTO                            |
| `createNewDtoByTemplate(name)` | Create a new DTO pre-filled from a named template |
| `readById(id)`                 | Read an entity by ID                              |
| `create(dto)`                  | Persist a new entity                              |
| `update(dto)`                  | Update an existing entity                         |
| `deactivate(id)`               | Deactivate an entity                              |

Not every service exposes every method — the available methods depend on the entity type.

```javascript
const account = ctx.services.accountService.readById(accountId);
account.custom.myapp.externalId = 'EXT-123';
ctx.services.accountService.update(account);
```

***

## VQL Service

The VARIO Cloud `vqlService` executes [VQL](https://developer.vario-software.de/documentation/fundamentals/vql) queries from within scripts, giving you full access to the query language for lookups, aggregations, and existence checks. `queryAll()` returns a `List<Map>` — access fields directly by their attribute path.

```javascript
const results = ctx.services.vqlService.queryAll(
  `SELECT id, number FROM article.query WHERE number = '${number}' LIMIT 1`
);

if (results && results.length > 0)
{
  const articleId = results[0].id;
}
```

{% hint style="info" %}
For the full VQL syntax — operators, relative dates, subqueries, JOINs — see [VQL](https://developer.vario-software.de/documentation/fundamentals/vql).
{% endhint %}

***

## User & Group Service

`userAndGroupService` resolves users and groups in the system — for example to check who created an entity or to assign a user to a task.

```javascript
const user = ctx.services.userAndGroupService.findUserById(account.info.createdFrom);
ctx.services.logger.info('Created by: ' + user.username);
```

***

## DTO Factory

In VARIO Cloud, entity services like `accountService.getNewDto()` create the top-level entity object, but not the nested objects within it. When you need to add an address, a contact, a business relationship, or similar sub-objects to an entity, you must create them separately via `dtoFactory` and then attach them — typically by assigning to a field or pushing into an array.

The factory covers all DTO types in the system — addresses, contacts, business relationships, article identifiers, metrics, and many more. The naming follows the pattern `create<TypeName>()`. The full list is available via autocompletion in the script editor.

### Adding Nested Objects to an Entity

```javascript
const account = ctx.services.accountService.getNewDto();

// Create and assign the default address
const address = ctx.services.dtoFactory.createAccountAddress();
address.name1 = 'Mustermann GmbH';
address.street = 'Hauptstraße 1';
address.postcode = '50667';
address.city = 'Köln';
account.defaultAddress = address;

// Create contacts and push them into the address
const phone = ctx.services.dtoFactory.createContact();
phone.ctType = 'PHONE';
phone.ctLabel = 'Telefon';
phone.value = '+49 221 12345';
account.defaultAddress.contacts.push(phone);

// Create the business relationship
const customer = ctx.services.dtoFactory.createCustomer();
customer.number = '10001';
account.customer = customer;

ctx.services.accountService.create(account);
```

***

## Utilities

`utils` provides helper functions used across all scripting contexts — most importantly `toApiReference()` for reference fields, but also `dateTimeNow()`, `concatLists()`, and others.

### API References

Any DTO field ending in `Ref` — such as `paymentMethodRef`, `deliveryTermRef`, `taxSchemaRef`, or `productGroupRef` — expects an API reference object. You cannot assign a plain ID string or entity directly. Use `toApiReference()` to convert an ID into the required format.

The recommended approach is to pass the ID directly:

```javascript
article.taxSchemaRef = utils.toApiReference('1434873425719062528');
article.productGroupRef = utils.toApiReference(existingGroup[0].id);
```

When using a lookup service, you can also pass the resolved entity:

```javascript
const deliveryMethod = ctx.services.deliveryMethodService.findByLabel('DL');
document.deliveryMethodRef = utils.toApiReference(deliveryMethod);
```

```javascript
account.custom.myapp.syncedAt = ctx.services.utils.dateTimeNow();
```

***

## Logger

`logger` writes log entries visible in the workflow execution log or batch import log. It provides `info()`, `warn()`, and `error()` methods.

```javascript
ctx.services.logger.info('Account ' + account.number + ' updated successfully');
ctx.services.logger.warn('Missing field — using default value');
ctx.services.logger.error('Failed to update document ' + documentId);
```

***

## Destructuring

When a script uses multiple services you can destructure them for readability:

```javascript
const { documentService, accountService, paymentMethodService, utils, logger } = ctx.services;

const document = documentService.readById(documentId);
const account = accountService.readById(document.accountId);
logger.info('Processing document for account ' + account.number);
```

***
