ores.refdata.book

Table of Contents

Operational ledger leaves. The only entity that holds trades. Serves as the basis for accounting, ownership, and regulatory capital treatment. Must belong to exactly one portfolio.

1. Flags

2. Columns

2.1. id

UUID uniquely identifying this book.

Surrogate key for the book record.

2.2. party_id

Party that owns this book.

References the parties table.

ctx.generate_uuid()

2.3. name

Book name, unique within party.

e.g., 'FXO_EUR_VOL_01'.

std::string("BOOK_") + std::to_string(faker::number::integer(1, 999))

2.4. description

Optional free-text description of the book.

std::string(faker::lorem::sentence())

2.5. parent_portfolio_id

Links to exactly one portfolio.

Mandatory: Every book must belong to a portfolio.

ctx.generate_uuid()

2.6. owner_unit_id

Business unit that owns this book.

Optional FK to business_units. Should reference a unit that is an owner_unit_id in the book's portfolio ancestry chain.

std::nullopt

2.7. functional_currency

Functional/accounting currency, designated by the ledger.

ISO 4217 currency code.

// X-0 is the sentinel code the eventing integration fixture seeds
// before writing this row: the functional-currency trigger accepts only
// codes of active currencies for the write tenant, so no fixed code is
// valid on its own and the seed must come first. A caller that does not
// seed it must overwrite this with a code it has written, or the insert
// is rejected.
std::string("X-0")

2.8. gl_account_ref

Reference to external General Ledger.

e.g., 'GL-10150-FXO'. Nullable if not integrated.

std::string("GL-10150-TEST")

2.9. cost_center

Internal finance code for P&L attribution.

Links to cost center in finance system.

std::string("CC-001")

2.10. book_status

Lifecycle status of the book.

References book_statuses lookup (Active, Closed, Frozen). Defaults to Active so a freshly-constructed book (the Add dialog, before the Status combo's async populate completes) always carries a value the FK-validation trigger accepts.

std::string("Active")

2.11. regulatory_book_type

Basel III/IV FRTB trading book / banking book classification.

References regulatory_book_types lookup (Trading, Banking). Defaults to Trading for the same reason book_status defaults to Active.

std::string("Trading")

2.12. book_purpose_type

The risk role this book plays.

References book_purpose_types lookup (Trading, Reserve, Funding, Wash, WriteOff, Test, Sales, SweepTarget, RemittanceTarget). Defaults to Trading, which that lookup's own seed describes as the purpose for a book that plays none of the specialised roles, for the same reason book_status defaults to Active.

std::string("Trading")

2.13. ledger_feed_type

How this book's ledger balance is fed.

References ledger_feed_types lookup (None, Automatic, Manual). Defaults to None, which that lookup's own seed describes as the value for a book with no ledger connection.

std::string("None")

2.14. is_sweepable

Whether this book is eligible for spot-sweep transfers to the designated Sweep target book – independent of ledger_feed_type and book_purpose_type; see Book classification.

false

2.15. restricts_product_types

Whether this book states the product types it allows. False means the book allows every product type the catalogue states, which is what a book that has never been restricted does; true means the book's product types junction holds the allowed set, and an empty junction is then a book that allows none.

The two states are different facts and must not be collapsed: a book with no junction rows is unrestricted when this is false and allows nothing when it is true. A blank set is a decision, not a gap, and the page that draws it says which of the two it is.

false

2.16. rates_centre_code

Rates centre determining which revaluation market data snapshot this book uses at end-of-day; see Book groups and rates centres.

Soft FK to business_centres by code (e.g. "GBLO", "USNY"), reusing the same location reference already used by counterparty/party/business_unit rather than modeling a dedicated rates-centre entity. Defaults to WRLD (the global sentinel business centre, seeded for every tenant) for the same reason book_status defaults to Active – a freshly-constructed book always carries a value the FK-validation trigger accepts.

std::string("WRLD")

2.17. sandbox_id

The sandbox the book belongs to; absent for an official book.

A book in a sandbox is a virtual book (see Sandbox): the trading system creates it, it never maps to the ledger, and nothing official reads it. It sits in its sandbox's portfolio tree, so its parent portfolio belongs to the same sandbox, and an official book never sits under a sandbox portfolio. It carries no ledger reference and is not a sweep target. Fixed for the book's life.

std::nullopt

3. Artefact columns

The import permits a null rates_centre_code, which the publish reads as "region-agnostic" and replaces with the publishing party's own business centre. The store's column is NOT NULL because the publish always supplies one.

3.1. id

3.2. version

3.3. name

3.4. parent_portfolio_id

3.5. functional_currency

3.6. gl_account_ref

3.7. cost_center

3.8. book_status

3.9. regulatory_book_type

3.10. book_purpose_type

3.11. ledger_feed_type

3.12. is_sweepable

3.13. rates_centre_code

4. SQL

4.1. Flags

4.2. Checks

expression
"sandbox_id" is null or (coalesce("gl_account_ref", '') = '' and not "is_sweepable")

5. Foreign keys

5.1. functional_currency

5.2. party_id

5.3. parent_portfolio_id

5.4. owner_unit_id

5.5. sandbox_id

6. Insert trigger

-- A book belongs to its parent portfolio's sandbox, or both to none: a
-- virtual book sits only in its sandbox's tree, and a real book never
-- does.
if exists (
    select 1 from ores_refdata_portfolios_tbl
    where tenant_id = NEW.tenant_id
      and id = NEW.parent_portfolio_id
      and valid_to = ores_utility_infinity_timestamp_fn()
      and sandbox_id is distinct from NEW.sandbox_id
) then
    raise exception 'Invalid parent_portfolio_id: %. A book and its portfolio belong to the same sandbox, or both to none.',
        NEW.parent_portfolio_id
        using errcode = '23514';
end if;

-- An archived sandbox is read-only.
if NEW.sandbox_id is not null and exists (
    select 1 from ores_refdata_sandboxes_tbl
    where tenant_id = NEW.tenant_id
      and id = NEW.sandbox_id
      and valid_to = ores_utility_infinity_timestamp_fn()
      and status = 'archived'
) then
    raise exception 'Invalid sandbox_id: %. The sandbox is archived and read-only.',
        NEW.sandbox_id
        using errcode = '23514';
end if;

-- The lifecycle the journey draws: Active to Frozen or Closed, Frozen back
-- to Active only, and Closed terminal. A move to the status a row already
-- holds is not a move. A create has no current row, so it has no move to
-- refuse and every status the lookup accepts is a legal opening status.
declare
    v_current_status text;
begin
    select book_status into v_current_status
    from ores_refdata_books_tbl
    where tenant_id = NEW.tenant_id
      and id = NEW.id
      and valid_to = ores_utility_infinity_timestamp_fn()
    for update;

    if found and v_current_status is distinct from NEW.book_status then
        if not (
            (v_current_status = 'Active' and NEW.book_status in ('Frozen', 'Closed'))
            or (v_current_status = 'Frozen' and NEW.book_status = 'Active')
        ) then
            perform ores_outcome_raise_fn(
                'status_transition_not_allowed',
                'book',
                'book_status',
                NEW.book_status,
                v_current_status);
        end if;
    end if;
end;

-- The owning unit must be the owning unit of the book's own portfolio or of
-- one above it. A unit the chain never names cannot own the book, however
-- much the picker allows it. Walk the chain from the book's parent portfolio
-- to the root, stopping if a link would repeat so a cycle cannot hang it.
if NEW.owner_unit_id is not null then
    declare
        v_walk_id uuid := NEW.parent_portfolio_id;
        v_seen uuid[] := array[]::uuid[];
        v_found boolean := false;
    begin
        while v_walk_id is not null and not (v_walk_id = any(v_seen)) loop
            v_seen := array_append(v_seen, v_walk_id);

            if exists (
                select 1 from ores_refdata_portfolios_tbl
                where tenant_id = NEW.tenant_id
                  and id = v_walk_id
                  and valid_to = ores_utility_infinity_timestamp_fn()
                  and owner_unit_id = NEW.owner_unit_id
            ) then
                v_found := true;
                exit;
            end if;

            select parent_portfolio_id into v_walk_id
            from ores_refdata_portfolios_tbl
            where tenant_id = NEW.tenant_id
              and id = v_walk_id
              and valid_to = ores_utility_infinity_timestamp_fn();
        end loop;

        if not v_found then
            perform ores_outcome_raise_fn(
                'unit_outside_ancestry',
                'book',
                'owner_unit_id',
                NEW.owner_unit_id::text);
        end if;
    end;
end if;

6.1. Validations

column validation_function
functional_currency ores_refdata_validate_currency_fn
book_status ores_refdata_validate_book_status_fn
regulatory_book_type ores_refdata_validate_regulatory_book_type_fn
book_purpose_type ores_refdata_validate_book_purpose_type_fn
ledger_feed_type ores_refdata_validate_ledger_feed_type_fn
rates_centre_code ores_refdata_validate_business_centre_fn

7. C++

7.1. Flags

7.2. Repository

7.3. Domain includes

#include <optional>
#include <string>
#include <boost/uuid/uuid.hpp>

7.4. Entity includes

#include <string>

7.5. Conventions

7.6. Table display

column header
name Name
party_id Party
functional_currency Currency
book_status Status
regulatory_book_type Regulatory Book Type
book_purpose_type Book Purpose Type
ledger_feed_type Ledger Feed Type
is_sweepable Sweepable
rates_centre_code Rates Centre
modified_by Modified By
version Version

7.7. Presentation

7.7.1. Detail fields

field label widget type is_key is_required placeholder flag_source combo_allow_blank combo_fetch combo_domain_type combo_fetch_include combo_fetch_fn combo_as_of_fetch_fn combo_watcher_name combo_code_field combo_tooltip_field combo_sort_field combo_label combo_setter_pascal badge_key
id Id idEdit line_edit true true Book id                            
name Name nameEdit line_edit   true Enter book name                            
functional_currency Functional Currency functionalCurrencyEdit flagged_combo       currency                          
gl_account_ref GL Account Ref glAccountRefEdit line_edit     Enter GL account reference                            
cost_center Cost Center costCenterEdit line_edit     Enter cost center                            
book_status Status bookStatusCombo dynamic_combo             refdata::domain::book_status   fetch_book_statuses fetch_book_statuses_at_timepoint bookStatusWatcher code description display_order book statuses BookStatusCombo book_status
regulatory_book_type Regulatory Book Type regulatoryBookTypeCombo dynamic_combo             refdata::domain::regulatory_book_type   fetch_regulatory_book_types fetch_regulatory_book_types_at_timepoint regulatoryBookTypeWatcher code description display_order regulatory book types RegulatoryBookTypeCombo regulatory_book_type
book_purpose_type Book Purpose Type bookPurposeTypeCombo dynamic_combo             refdata::domain::book_purpose_type   fetch_book_purpose_types fetch_book_purpose_types_at_timepoint bookPurposeTypeWatcher code description display_order book purpose types BookPurposeTypeCombo book_purpose_type
ledger_feed_type Ledger Feed Type ledgerFeedTypeCombo dynamic_combo             refdata::domain::ledger_feed_type   fetch_ledger_feed_types fetch_ledger_feed_types_at_timepoint ledgerFeedTypeWatcher code description display_order ledger feed types LedgerFeedTypeCombo ledger_feed_type
is_sweepable Sweepable isSweepableCheckBox check_box                                  
rates_centre_code Rates Centre ratesCentreCodeCombo flagged_combo       business_centre false fetch_business_centre_codes                      

7.7.2. Columns

enum_name field header type width is_badge badge_key formatter formatter_include
Name name Name string 200        
FunctionalCurrency functional_currency Functional Currency string 130        
BookStatus book_status Status string 100 true book_status    
CostCenter cost_center Cost Center string 120        
RegulatoryBookType regulatory_book_type Regulatory Book Type string 130 true regulatory_book_type    
BookPurposeType book_purpose_type Book Purpose Type string 130 true book_purpose_type    
LedgerFeedType ledger_feed_type Ledger Feed Type string 130 true ledger_feed_type    
IsSweepable is_sweepable Sweepable bool 90 true is_sweepable    
RatesCentreCode rates_centre_code Rates Centre string 110        
Version version Version int 80        
ModifiedBy modified_by Modified By string 120        
RecordedAt recorded_at Recorded At timestamp 150        

7.7.3. Icon columns

Ledger currency gets its own flag icon, same as any other single-currency cell (e.g. Currency's own code column) — no compositing needed since it's a single column.

column accessor field1 field2
FunctionalCurrency currency_flag_icon functional_currency  
RatesCentreCode business_centre_flag_icon rates_centre_code  

7.7.4. Related entity shortcuts

signal icon label tooltip
BookStatuses Flag Statuses Open Book Statuses list
RegulatoryBookTypes Flag Regulatory Types Open Regulatory Book Types list
BookPurposeTypes Flag Purpose Types Open Book Purpose Types list
LedgerFeedTypes Flag Ledger Feed Types Open Ledger Feed Types list

7.8. Custom repository methods

8. See also

Emacs 29.3 (Org mode 9.6.15)