# Edara API v3: Common

Read the [guide](../guide.md) first: authentication, paging, errors, rate limits and the shared `PagedResult`, `BatchResult` and `*Reference` shapes.

- `GET /v3/common/convert-money-to-arabic-words`: Converts money to Arabic words.
- `GET /v3/common/convert-money-to-english-words`: Converts money to English words.
- `GET /v3/common/files/{token}`: Resolves a file download token and redirects to the file.
- `PUT /v3/common/adjust-invoiced-quantity`: Adjusts the Invoiced Quantity on one or more Source Document Lines belonging to the same Source Document.

## Endpoints

### `GET /v3/common/convert-money-to-arabic-words`: Converts money to Arabic words.

Operation `ConvertMoneyToArabicWords` · permission `read:common-utility`

**Query string**

| field | type | required | description |
|---|---|---|---|
| `numberValue` | `number` | yes | The monetary amount to convert. |
| `currency` | `string` | yes | The currency name (e.g. جنيه). |
| `currencyFraction` | `string` | yes | The currency fraction name (e.g. قرش). |

**Responses**: OK `string`: The amount in Arabic words.

**Notes**

- The query parameters are `numberValue`, `currency` and `currencyFraction`. A missing or non-numeric `numberValue` returns `400`.
- The text has this form: the integer part in words, then `currency`, then the Arabic word و, then the fraction in words, then `currencyFraction`, then the closing phrase فقط لا غير.
- `currency` and `currencyFraction` are appended exactly as you send them, with no space added before them. Include a leading space in each value yourself.
- The text ends with a trailing space.
- An amount of zero returns only the closing phrase فقط لا غير, with no number words or currency.
- Always send both `currency` and `currencyFraction`. Do not rely on a default when they are empty.
- The fraction is not read as two decimal places: 12.50, 12.05 and 12.5 all give a fraction of five. The English endpoint reads the fraction correctly.
- If the amount cannot be converted internally, you get the words for zero with no currency instead of an error.
- The response body is a bare JSON string, not an object.

---

### `GET /v3/common/convert-money-to-english-words`: Converts money to English words.

Operation `ConvertMoneyToEnglishWords` · permission `read:common-utility`

**Query string**

| field | type | required | description |
|---|---|---|---|
| `numberValue` | `number` | yes | The monetary amount to convert. |
| `currency` | `string` | yes | The currency name (e.g. Pound). |
| `currencyFraction` | `string` | yes | The currency fraction name (e.g. Piastre). |

**Responses**: OK `string`: The amount in English words.

**Notes**

- The query parameters are `numberValue`, `currency` and `currencyFraction`. A missing `numberValue` returns `400`.
- The fraction is the first two digits after the decimal point, padded with a zero when there is only one, so 12.5 gives 50 and 12.05 gives 05. Extra digits are cut off, not rounded: 12.999 gives 99.
- When the fraction is not zero, the text reads: integer in words, `currency`, a comma followed directly by the word and, the fraction in words, `currencyFraction`. There is no space before the comma and none between the comma and the word and.
- When the fraction is zero, the text is the integer in words, `currency` and the word Only.
- `currency` and `currencyFraction` have no default. A space is added before each one, so an omitted value leaves a stray space in the text.
- The response body is a bare JSON string, not an object.

---

### `GET /v3/common/files/{token}`: Resolves a file download token and redirects to the file.

Operation `GetFile` · permission `read:common-utility`

**Parameters**

| name | in | type | default | description |
|---|---|---|---|---|
| `token` | route | `string` |  | The file download token. |

**Responses**: Found: Redirects to the signed file URL. · NotFound: The token is invalid or expired.

**Business errors** (HTTP 409, match on `errorCode`):

- `ExpiredLink`: The token has expired and the request is redirected to the expired-link page.
- `InvalidLink`: The token is missing or malformed.

**Notes**

- The endpoint never returns the file content itself. A valid `token` returns `302` to a temporary download URL.
- An expired `token` also returns `302`, to a page that says the link has expired. A `302` on its own does not mean the file is available.
- A missing or invalid `token` returns `404` with the plain text body Invalid link.
- Only PDF files are served. The download has content type application/pdf and is sent as an attachment.
- The download URL you are redirected to is valid for 10 minutes.

---

### `PUT /v3/common/adjust-invoiced-quantity`: Adjusts the Invoiced Quantity on one or more Source Document Lines belonging to the same Source Document.

Operation `AdjustInvoicedQuantity` · permission `update:invoiced-quantity`

> Adds each line's quantityAdjustment onto InvoicedQuantity on Sales.DocumentDetails (SO/SR) or
> Warehouse.WHWorkOrderDetails (IO/RR/RS/IR). Any other sourceDocumentType is refused.

**Body**: `AdjustInvoicedQuantityRequest`

| field | type | default | validation | description |
|---|---|---|---|---|
| `sourceDocumentType` | `string` |  |  |  |
| `sourceDocumentCode` | `string` |  |  |  |
| `lines` | `List<AdjustInvoicedQuantityLineRequest>` |  |  |  |

**Responses**: OK `AdjustInvoicedQuantityResponse`: Lines updated.

**Business errors** (HTTP 409, match on `errorCode`):

- `DocumentNotApproved`: Source Document is not Approved.
- `DuplicateSourceLineId`: sourceLineId must be distinct across lines.
- `InvalidQuantityAdjustment`: Quantity Adjustment is invalid.
- `InvalidSourceDocumentType`: Supported values are SO, SR, IO, RR, RS, and IR.
- `InvoicedQuantityExceeded`: Resulting Invoiced Quantity exceeds the document line quantity.
- `InvoicingModeNotSupported`: Tenant is not operating in Advanced Mode.
- `NegativeInvoicedQuantity`: Resulting Invoiced Quantity would become negative.
- `RelatedDocumentExistsSO`: Source Document Line is linked to a related SO document and cannot be adjusted directly.
- `RelatedDocumentExistsSR`: Source Document Line is linked to a related SR document and cannot be adjusted directly.
- `RelatedDocumentExistsPO`: Source Document Line is linked to a related PO document and cannot be adjusted directly.
- `RelatedDocumentExistsPR`: Source Document Line is linked to a related PR document and cannot be adjusted directly.
- `SourceDocumentNotFound`: Source Document does not exist.
- `SourceLineNotFound`: Source Document Line does not exist.

**Notes**

- `quantityAdjustment` is a signed change that is added to the line's current invoiced quantity. It is not the new absolute value.
- The call changes only the invoiced quantity and the line's last update user and date. It does not change stock or accounting entries.
- The source document type must be `SO`, `SR`, `IO`, `RR`, `RS` or `IR`, in any letter case. Any other type gives `InvalidSourceDocumentType`.
- A blank document code gives `SourceDocumentNotFound`. An empty list of lines, or any line with a `quantityAdjustment` of zero, gives `InvalidQuantityAdjustment`.
- Sending the same `sourceLineId` twice gives `DuplicateSourceLineId`.
- The endpoint only works for organizations that use the advanced invoicing mode. In the default simple mode every call gives `InvoicingModeNotSupported`, so handle that error.
- The basic checks run in this order and stop at the first failure: document type, document code, lines and zero adjustments, duplicate lines, invoicing mode.
- For `SO` and `SR`, the document must be of the type you send and must be approved. A document that is not approved gives `DocumentNotApproved`.
- For `SO` and `SR`, every `sourceLineId` must belong to that document.
- For `IO`, `RR`, `RS` and `IR`, the work order must be of the type you send and must be standalone. A work order that has a related sales order, sales return, purchase order or purchase return is refused with `RelatedDocumentExistsSO`, `RelatedDocumentExistsSR`, `RelatedDocumentExistsPO` or `RelatedDocumentExistsPR`.
- After the adjustment, a line's invoiced quantity must be between zero and the line quantity. Below zero gives `NegativeInvoicedQuantity` and above the line quantity gives `InvoicedQuantityExceeded`.
- The update is all or nothing. If any `sourceLineId` cannot be updated, nothing is changed and you get `SourceLineNotFound`.
- A successful call returns `success` as true and `updatedLines` with the number of lines changed.

## Types

### `AdjustInvoicedQuantityLineRequest`

| field | type | description |
|---|---|---|
| `sourceLineId` | `int` |  |
| `quantityAdjustment` | `double` |  |

### `AdjustInvoicedQuantityResponse`

| field | type | description |
|---|---|---|
| `success` | `bool` |  |
| `updatedLines` | `int` |  |

### `DocumentType`

Document type codes shared across sales, purchase, and warehouse domains.

Values (sent/returned as the name): `RS`, `RR`, `RT`, `IO`, `IR`, `IT`, `TR`, `CI`, `CO`, `JE`, `SI`, `PI`, `CN`, `DN`, `NR`, `NP`, `SO`, `SR`, `RecSO`, `PO`, `PR`, `OB`, `RMA`
