# Microsoft Dynamics 365 Finance & Operations

Workist connects to your environment through the data entities of Dynamics 365 Finance & Operations (F&O). Workist reads customers and released products as master data, creates completed orders as sales orders and requests for quotation as sales quotations. Nothing is installed in F&O.

## Overview

**Prerequisites**

- An app registration in Microsoft Entra ID with a client secret. Workist uses it to sign in without user interaction.
- The app is enabled as an application in F&O and mapped to a user that may use these data entities:
  - read: `CustomersV3`, `ContactPersons`, `CDSCustomerContactPersons`, `CustomerPostalAddresses`, `CDSReleasedDistinctProducts`, `CustomerProductDescriptionsV2`
  - create: `SalesOrderHeadersV2` or `SalesOrderHeadersV4`, `SalesOrderLines`, `SalesOrderHeaderDocumentAttachmentsV2`, `SalesQuotationHeaders`, `SalesQuotationLines`
  - delete: `SalesOrderHeadersV2` or `SalesOrderHeadersV4`, so that Workist can roll back an incomplete order
- Workist must be able to reach your F&O environment over the internet, directly or through an API gateway.

**Data flow**

| Direction | Content | When |
| --- | --- | --- |
| F&O → Workist | Customers, contact persons, postal addresses, released products, external item numbers | daily at 06:00 German time and on demand |
| Workist → F&O | Sales order with lines, order document (PDF) and original email | as soon as an order is completed |
| Workist → F&O | Sales quotation with lines | as soon as a request for quotation is completed |

## What we read from Finance & Operations

| Master data in Workist | Source in Finance & Operations | Data entities |
| --- | --- | --- |
| [Customers](/en/docs/master-data/customers.md) | Customers | `CustomersV3`, `ContactPersons`, `CDSCustomerContactPersons` |
| [Customer contacts](/en/docs/master-data/customer-contacts.md) | Customer contact persons | `ContactPersons`, `CDSCustomerContactPersons` |
| [Delivery addresses](/en/docs/master-data/delivery-and-invoice-recipients.md) | Customer postal addresses | `CustomerPostalAddresses` |
| [Articles](/en/docs/master-data/articles.md) | Released products | `CDSReleasedDistinctProducts` |
| [Customer-specific item numbers](/en/docs/master-data/articles.md) | Customer external item numbers (assigned to a single customer, not to customer groups) | `CustomerProductDescriptionsV2` |

- If a data area ID is set in the integration, Workist only reads that legal entity. Without a data area ID, Workist reads all of them.
- The integration's options narrow down the products: only stocked products (`IsStockedProduct` = Yes) and only products with both a sales and an inventory unit.
- Workist does not read invoice addresses, unit conversions, framework agreements or quotes from F&O.

The [field reference](#field-reference) lists every field Workist takes over.

## What we write to Finance & Operations

**Sales order** (from orders)

1. Workist creates the order header: customer, order number as the customer requisition, delivery address, customer contact and delivery date.
2. Workist creates the lines: item number, quantity, unit, product dimensions from the article master data and delivery date. F&O determines the prices itself.
3. Workist attaches the order document (PDF) and, for documents received by email, the original email (.eml) to the order.

On request, Workist puts every order on hold in F&O (`IsSalesProcessingStopped`) so it is reviewed before further processing.

**Sales quotation** (from requests for quotation)

Workist creates the quotation header with the customer and then the lines with item number, quantity, unit and product dimensions.

**Data in detail**

- Workist only transfers delivery dates when the field is enabled in the channel. If a delivery date is in the past, Workist sets today's date, because F&O rejects dates in the past.
- Workist takes the legal entity (data area ID) from the customer master data, else from the integration.
- As the reference on the document in the Workbench, Workist stores the order or quotation number from F&O. **Open in external application** takes you straight to the order or quotation in F&O.

## Setup in the Workbench

1. Create the app registration in Microsoft Entra ID and enable the app in F&O (see [Prerequisites](#overview)).
2. In the Workbench, open **Settings** → **Business Systems (ERP)** → **Integrations** and click **Connect** next to Microsoft Dynamics 365 Finance and Operations.
3. Enter the connection:

   | Field | Content |
   | --- | --- |
   | Integration Name | any name |
   | Tenant ID | ID of your Entra ID tenant |
   | Environment URL | URL of your F&O environment |
   | API Data URL (optional) | address of an API gateway in front of F&O; leave empty if Workist accesses the environment directly |
   | Client ID (Application ID), Client Secret | from the app registration |
   | Data Area ID | legal entity, for example `usmf` |
   | Order Channels | channels whose orders are created as sales orders |
   | RFQ Channels | channels whose requests for quotation are created as sales quotations |

4. Optional:

   | Option | Effect |
   | --- | --- |
   | Only import articles where IsStockedProduct is 'Yes' | reads stocked products only |
   | Only import articles that have both SalesUnitSymbol and InventoryUnitSymbol set | reads products with a sales and an inventory unit only |
   | Articles have multiple versions | for products with several versions: Workist uses the versioned product number as the item number and transfers part number 2 |
   | Sales order header entity | V2 (default) or V4; V4 also knows the order taker and the retail channel |
   | Order taker personnel number, Retail channel RecId | order taker's personnel number or retail channel for every order (V4 only) |
   | Put every pushed sales order on hold in F&O | puts every order on hold |
   | Delete the sales order again if creating its lines fails | default: on. See [Error handling](#error-handling) |
   | Delete the whole sales order if uploading an attachment (PDF/email) fails | default: off. See [Error handling](#error-handling) |
   | Disable master data transfer | Workist reads no master data from F&O, neither scheduled nor on demand |

5. Click **Create**. **Trigger master data update** loads the master data right away.

How the master data reaches the channels and how Workist switches the channels over is described under [What all connectors have in common](/en/docs/data-exchange/connectors.md#common-behaviour).

## Error handling

If F&O rejects a document, it appears again among the open documents, with the message from F&O. Workist does not retry automatically. Fix the cause and complete the document again after **Reopen for assistance**.

- **Order without a customer number**: Workist does not transfer it and reports the error on the document.
- **Error creating a line**: Workist tries all lines and reports every failed line with its item number. Workist then deletes the order again. If "Delete the sales order again if creating its lines fails" is off, the incomplete order stays in F&O and its number is shown on the document. Complete or delete it in F&O before you complete the order again.
- **Error attaching the PDF or email**: by default, the order stays and the document counts as transferred; the message is shown on the document. If "Delete the whole sales order if uploading an attachment (PDF/email) fails" is on, Workist deletes the order and marks the document as failed.
- If Workist cannot delete an order again, a note with the order number is shown on the document. Remove the order manually.
- **Missing permission**: if F&O reports missing rights, the document says so. A new attempt only helps once the app's user has the rights.

## Limitations

- Workist currently creates sales quotations with currency `USD` and language `en-US`.
- If a quotation line fails, Workist does not delete the sales quotation it already created. It stays incomplete in F&O.
- Workist does not check whether an order already exists for the document before creating one. If an order is completed again, another order is created.

## Field reference

### Fields read

#### Customers

| Workist column | From Finance & Operations |
| --- | --- |
| `client_id1` | `CustomerAccount` |
| `client_id2` | `PartyNumber` |
| `client_contact_person1` | `FirstName` + `LastName` of the customer's first contact person |
| `company_name` | `OrganizationName` |
| `address1` | `AddressStreet` |
| `zip_code` | `AddressZipCode` |
| `city` | `AddressCity` |
| `country` | `AddressCountryRegionId` |
| `extra_data` | `dataAreaId`, `EmployeeResponsibleNumber` |

#### Customer contacts

| Workist column | From Finance & Operations |
| --- | --- |
| `partition_id` | Customer account the contact person belongs to (`CustomerAccountNumber`) |
| `contact_id` | `ContactPersonId` – else `ContactPersonPartyNumber` |
| `first_name` | `FirstName` |
| `last_name` | `LastName` |
| `phone` | `PrimaryPhoneNumber` |
| `email` | `PrimaryEmailAddress` |

#### Delivery addresses

| Workist column | From Finance & Operations |
| --- | --- |
| `partition_id` | `CustomerAccountNumber` |
| `address_id1` | `AddressLocationId` |
| `name` | `AddressDescription` |
| `address1` | `AddressStreet` |
| `zip_code` | `AddressZipCode` |
| `city` | `AddressCity` |
| `country` | `AddressCountryRegionId` |

#### Articles

| Workist column | From Finance & Operations |
| --- | --- |
| `article_id1` | `ItemNumber`; with “Articles have multiple versions”: `ProductNumber` |
| `article_id2` | `ProductNumber`; with “Articles have multiple versions”: `ItemNumber` |
| `description` | `ProductName`, extended by size, colour, style and version if present |
| `description_boosted` | `ProductDescription` |
| `gross_price` | `SalesPrice` |
| `order_units` | `SalesUnitSymbol` |
| `sales_units` | `SalesUnitSymbol` |
| `extra_data` | Product dimensions `ProductSizeId`, `ProductColorId`, `ProductStyleId`, `ProductVersionId`, `ProductConfigurationId` (passed on to the order line) plus `CurrencyCode`, `SalesUnitSymbol`, `SalesPrice`, `InventoryUnitSymbol`, `UnitCost`, `IsStockedProduct` |

#### Customer-specific item numbers

| Workist column | From Finance & Operations |
| --- | --- |
| `partition_id` | `CustomerAccountNumber` |
| `article_id1` | `ItemNumber` |
| `article_id2` | `CustomerProductNumber` |
| `description` | `CustomerProductDescription` |
| `extra_data` | `ProductSizeId`, `ProductColorId`, `ProductVersionId`, `ProductStyleId`, `ProductConfigurationId`, `dataAreaId` |

### Fields written

Listed are the fields Workist fills. F&O sets the order and quotation number, prices, totals and all other fields itself.

#### Sales order – header

| Field | Content |
| --- | --- |
| `OrderingCustomerAccountNumber` | Client (customer number) |
| `dataAreaId` | Data area ID from the customer master data – else the integration's “Data Area ID” |
| `DeliveryAddressLocationId` | Delivery address (address ID from master data) |
| `RequestedShippingDate` | Delivery date (header); a date in the past is replaced by today |
| `ContactPersonId` | Customer contact, if matched |
| `CustomerRequisitionNumber` | Order number |
| `IsSalesProcessingStopped` | `Yes` when “Put every pushed sales order on hold” is on – else not sent |
| `OrderTakerPersonnelNumber` | “Order taker personnel number” (only with header entity V4) |
| `RetailChannelTable` | “Retail channel RecId” (only with header entity V4) |

#### Sales order – lines

| Field | Content |
| --- | --- |
| `ItemNumber` | Item number (with “Articles have multiple versions”: part number 2) |
| `OrderedSalesQuantity` | Quantity |
| `SalesUnitSymbol` | Unit |
| `ProductSizeId` `ProductColorId` `ProductStyleId` `ProductVersionId` `ProductConfigurationId` | Product dimension from the article master data |
| `RequestedShippingDate` | Line delivery date – else the header delivery date |

#### Sales quotation – header

| Field | Content |
| --- | --- |
| `dataAreaId` | Data area ID from the customer master data – else the integration's “Data Area ID” |
| `RequestingCustomerAccountNumber` | Client (customer number) |
| `CurrencyCode` | fixed: `USD` |
| `LanguageId` | fixed: `en-US` |

#### Sales quotation – lines

| Field | Content |
| --- | --- |
| `LineCreationSequenceNumber` | Position (counting from 1) |
| `ItemNumber` | Item number (with “Articles have multiple versions”: part number 2) |
| `RequestedSalesQuantity` | Quantity |
| `SalesUnitSymbol` | Unit |
| `ProductColorId` `ProductSizeId` `ProductStyleId` `ProductVersionId` `ProductConfigurationId` | Product dimension from the article master data |
