---
id: WF-ACC-BKS-002
title: Save a Unit’s Policies and Currency Setup
trigger: A caller replaces an existing unit using its loaded version.
product_area: accounting
module: books
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-ACC-BKS-001
  - CAP-ACC-BKS-002
  - CAP-ACC-BKS-003
  - CAP-ACC-BKS-015
  - CAP-ACC-BKS-016
moves:
  - STATE-ACC-BKS-001
  - STATE-ACC-BKS-003
crosses: []
idempotency: >-
  A successful replacement advances the version. Repeating that payload and
  version is stale rather than an idempotent success.
concurrency: >-
  The mutation locks the unit and conditions its update on the expected version.
  Currency foreign keys constrain racing references, but the method guard’s
  batch count does not lock concurrent posting.
hops:
  - 'n': 1
    actor_or_service: Books service (transaction)
    action: >-
      Lock the unit and reject a full update lock or changed founding currency
      and month.
    anchor: >-
      services-accounting:modules/books/services/persistence/business-units.ts:updateBusinessUnit
    seam: sync
    on_failure: Return not-found or a named conflict before any mutation.
    left_inconsistent: The stored unit remains unchanged.
    observer: the caller
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/business-units.e2e.spec.js#answers
      409 to a change of the base currency, naming the column
  - 'n': 2
    actor_or_service: Books service
    action: >-
      Determine the stated supported set and settings; preserve omission, apply
      code-list precedence and clear foreign currencies when multicurrency is
      off.
    anchor: >-
      services-accounting:modules/books/services/persistence/business-units.ts:statedSupportedCurrencies
    seam: sync
    on_failure: Refuse invalid multicurrency or supported-set input and roll back.
    left_inconsistent: No replacement writes commit.
    observer: the caller
    provenance: test
    source: >-
      services-accounting:modules/books/tests/integration/services/persistence/business-units.integration.spec.js#lets
      the codes govern when both are sent (the console’s round trip), the
      settings applying to the codes they name
  - 'n': 3
    actor_or_service: Books service
    action: >-
      Preserve a wholly omitted fee group; validate fee values and any product
      explicitly supplied.
    anchor: >-
      services-accounting:modules/books/services/persistence/business-units.ts:cardFeeSettingsOf
    seam: sync
    on_failure: Return a fee validation refusal and roll back the replacement.
    left_inconsistent: The previous policy group stays intact.
    observer: the caller
    provenance: observed
    source: >-
      services-accounting:modules/books/services/persistence/business-units.ts:cardFeeSettingsOf
  - 'n': 4
    actor_or_service: Books service (reads batches)
    action: >-
      If the accounting method changes, locate the current open period and count
      its posted or downloaded batches.
    anchor: >-
      services-accounting:modules/books/services/persistence/business-units.ts:assertAccountingMethodChangeable
    seam: sync
    on_failure: >-
      Refuse the switch with the period and posted-work count; retain the stored
      method.
    left_inconsistent: This request leaves the method unchanged.
    observer: the caller
    provenance: test
    source: >-
      services-accounting:modules/books/tests/integration/services/persistence/business-units.integration.spec.js#refuses
      the change 409 naming the period and the count when a batch of the open
      period is posted, leaving the method
  - 'n': 5
    actor_or_service: Books service and database
    action: >-
      Update the unit at the expected version; preserve omitted fee and
      write-off groups and validate document references.
    anchor: >-
      services-accounting:modules/books/db/business-units.table.ts:business_units_template_references_trigger
    seam: sync
    on_failure: Refuse a stale version or unusable template and roll back.
    left_inconsistent: No partial policy or selection change commits.
    observer: the caller
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/document-templates.e2e.spec.js#answers
      400 to a business unit naming an inactive template
  - 'n': 6
    actor_or_service: Books service and database
    action: >-
      Apply stated currency additions, removals and settings, refusing removal
      of rows still referenced.
    anchor: >-
      services-accounting:modules/books/services/persistence/business-units.ts:replaceSupportedCurrencies
    seam: sync
    on_failure: >-
      Report the currency and known dependent kinds; roll back the complete
      replacement.
    left_inconsistent: The unit and its currency set retain their earlier values.
    observer: the caller
    provenance: test
    source: >-
      services-accounting:modules/books/tests/e2e/business-units.e2e.spec.js#answers
      409 naming the currency, the unit and the kinds of account that use it
branches:
  - condition: Disable multicurrency
    path: >-
      The console asks for confirmation; saving clears supported currencies only
      if no dependent references block removal.
  - condition: Omit a document choice
    path: >-
      That document kind returns to built-in selection rather than preserving
      the previous choice.
waits: []
evidence:
  - >-
    services-accounting at f47cb263:
    modules/books/services/persistence/business-units.ts
  - >-
    react-console at baf6dae3:
    components/configuration/accounting/business-unit-currencies.tsx,
    business-unit-documents.tsx
controls: [TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-DAT-001, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003]
---

# Save a Unit’s Policies and Currency Setup

## What It Does

A unit save carries its complete ordinary configuration and loaded version. Founding choices remain fixed. Newer fee, direct write-off and supported-currency groups have explicit preservation behavior for older clients that omit them.

## The Flow

```mermaid
flowchart TD
  h0["Lock the unit and reject a full update lock or changed founding currency and month."]
  h1["Determine the stated supported set and settings; preserve omission, apply code-list precedence and clear foreign currencies when multicurrency is off."]
  h0 --> h1
  h2["Preserve a wholly omitted fee group; validate fee values and any product explicitly supplied."]
  h1 --> h2
  h3["If the accounting method changes, locate the current open period and count its posted or downloaded batches."]
  h2 --> h3
  h4["Update the unit at the expected version; preserve omitted fee and write-off groups and validate document references."]
  h3 --> h4
  h5["Apply stated currency additions, removals and settings, refusing removal of rows still referenced."]
  h4 --> h5
```

## When Something Fails

Each database stage shares one replacement transaction. Validation, locks, a stale version or a dependency refusal prevent the whole save. The batch count can miss posting that happens concurrently, so the guard is not a complete concurrency guarantee. Omission also differs across groups: templates reset to built-ins, while the specified policy groups are preserved.

## Open Design Questions

The method guard needs a concurrency decision before it is relied on as a financial safeguard. The console still has no controls for tender fees or direct write-off treatment.
