-- Template migration for each organization schema.
-- Replace {schema} with the real schema name, e.g. company_<organization_id>.

create table if not exists {schema}.quotes (
    id uuid primary key,
    quote_number text not null unique,
    customer_id uuid not null references {schema}.customers(id),
    status text not null default 'draft',
    valid_until date,
    cash_discount_term_id uuid references {schema}.cash_discount_terms(id),
    customer_discount_percent numeric(7, 4) not null default 0,
    notes_ciphertext bytea,
    notes_nonce bytea,
    notes_key_id text,
    created_by_user_id uuid,
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now(),
    constraint quotes_status_valid check (
        status in ('draft', 'sent', 'accepted', 'rejected', 'expired', 'cancelled')
    ),
    constraint quotes_customer_discount_valid check (
        customer_discount_percent >= 0 and customer_discount_percent <= 100
    ),
    constraint quotes_notes_encryption_complete check (
        (
            notes_ciphertext is null
            and notes_nonce is null
            and notes_key_id is null
        )
        or (
            notes_ciphertext is not null
            and notes_nonce is not null
            and notes_key_id is not null
        )
    )
);

create index if not exists idx_quotes_customer_status
    on {schema}.quotes (customer_id, status);

create table if not exists {schema}.quote_items (
    id uuid primary key,
    quote_id uuid not null references {schema}.quotes(id) on delete cascade,
    line_number integer not null,
    item_id uuid not null references {schema}.items(id),
    description_ciphertext bytea,
    description_nonce bytea,
    description_key_id text,
    quantity numeric(14, 4) not null,
    unit_price numeric(14, 4) not null,
    original_unit_price numeric(14, 4),
    discount_percent numeric(7, 4) not null default 0,
    price_overridden boolean not null default false,
    tax_rate numeric(7, 4) not null,
    created_at timestamptz not null default now(),
    updated_at timestamptz not null default now(),
    unique (quote_id, line_number),
    constraint quote_items_quantity_positive check (quantity > 0),
    constraint quote_items_unit_price_non_negative check (unit_price >= 0),
    constraint quote_items_original_price_non_negative check (
        original_unit_price is null or original_unit_price >= 0
    ),
    constraint quote_items_discount_valid check (
        discount_percent >= 0 and discount_percent <= 100
    ),
    constraint quote_items_tax_rate_non_negative check (tax_rate >= 0),
    constraint quote_items_description_encryption_complete check (
        (
            description_ciphertext is null
            and description_nonce is null
            and description_key_id is null
        )
        or (
            description_ciphertext is not null
            and description_nonce is not null
            and description_key_id is not null
        )
    )
);

create index if not exists idx_quote_items_item
    on {schema}.quote_items (item_id);
