Files
tradon/notes/accounting/excel_api/gl_accounts_sql_poc.sql
laurentbarontini 242406588c Excel desktop POC: direct SQL via VBA, safe mode launcher
- GLAccountsExcelApi.bas: RefreshGLApi reads Setup!B6:B9 directly,
  calls PostgreSQL via ADODB without sheet.Evaluate or live UDF formulas
- Connection string pointed to vps107.geneva.hosting / postgres
- GL_Accounts_Client_Template.xlsx: fixed formula text cell refs (B6 not B7)
- Ouvrir_Excel_SafeMode.bat: launches Excel /safe with template to bypass
  print spooler freeze (splwow64 deadlock on edit mode entry)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 01:13:04 +02:00

278 lines
9.1 KiB
PL/PgSQL

-- Finaccount-like Excel API POC for GL ACCOUNTS FUNCTIONS.
--
-- Scope:
-- - GetAccountBaseAmount
-- - GetAccountRealBaseAmount
-- - GetAccountAmount
-- - GetAccountAbbr
-- - GetAccountName
-- - GetAccountContact
-- - GetAccountContactCode
-- - GetAccountContactName
--
-- Design notes:
-- - PostgreSQL lowercases function names; VBA calls these SQL functions.
-- - Balances are computed as of p_value_date.
-- - This POC uses posted account moves only.
-- - p_currency_iso is treated as the transaction currency.
-- - p_company_key accepts either the company party code or company name.
-- - p_currency_iso accepts the currency code/name/symbol/numeric code/id.
-- - If account.move.line.second_currency is empty, the company currency is
-- used as transaction currency and the company amount is reused.
create schema if not exists excel_api;
create or replace view excel_api.gl_account_lines as
select
aml.id as move_line_id,
am.id as move_id,
cc.id as company_id,
cp.code as company_key,
cp.name as company_name,
aa.id as account_id,
aa.code as account_code,
aa.name as account_name,
coalesce(tx_cur.code, base_cur.code) as transaction_currency_code,
coalesce(aml.second_currency, cc.currency) as transaction_currency_id,
base_cur.code as base_currency_code,
cc.currency as base_currency_id,
am.date as posting_date,
am.state as posting_status,
aml.party as party_id,
party.code as party_code,
party.name as party_name,
coalesce(aml.debit, 0) as debit_base_currency,
coalesce(aml.credit, 0) as credit_base_currency,
coalesce(aml.debit, 0) - coalesce(aml.credit, 0)
as balance_base_currency,
case
when aml.second_currency is not null then
coalesce(aml.amount_second_currency, 0)
else
coalesce(aml.debit, 0) - coalesce(aml.credit, 0)
end as balance_transaction_currency
from account_move_line aml
join account_move am on am.id = aml.move
join account_account aa on aa.id = aml.account
join company_company cc on cc.id = am.company
left join party_party cp on cp.id = cc.party
left join currency_currency base_cur on base_cur.id = cc.currency
left join currency_currency tx_cur on tx_cur.id = aml.second_currency
left join party_party party on party.id = aml.party
where aa.type is not null
and coalesce(aa.closed, false) is false;
create or replace function excel_api.currency_rate_at(
p_currency_id integer,
p_value_date date)
returns numeric
language sql
stable
as $$
select cr.rate
from currency_currency_rate cr
where cr.currency = p_currency_id
and cr.date <= p_value_date
order by cr.date desc
limit 1
$$;
create or replace function excel_api.company_matches(
p_company_key text,
p_company_input text)
returns boolean
language sql
stable
as $$
select upper(btrim(coalesce(p_company_key, '')))
= upper(btrim(coalesce(p_company_input, '')))
or upper(btrim(coalesce(p_company_input, ''))) = (
select upper(btrim(coalesce(pp.name, '')))
from company_company cc
left join party_party pp on pp.id = cc.party
where pp.code = p_company_key
limit 1)
$$;
create or replace function excel_api.currency_matches(
p_currency_id integer,
p_currency_input text)
returns boolean
language sql
stable
as $$
select exists (
select 1
from currency_currency cur
where cur.id = p_currency_id
and upper(btrim(coalesce(p_currency_input, ''))) in (
upper(btrim(cur.id::text)),
upper(btrim(coalesce(cur.code, ''))),
upper(btrim(coalesce(cur.name, ''))),
upper(btrim(coalesce(cur.symbol, ''))),
upper(btrim(coalesce(cur.numeric_code, '')))))
$$;
create or replace function excel_api.get_account_amount(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns numeric
language sql
stable
as $$
select coalesce(sum(gl.balance_transaction_currency), 0)
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
and gl.posting_status = 'posted'
$$;
create or replace function excel_api.get_account_real_base_amount(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns numeric
language sql
stable
as $$
select coalesce(sum(gl.balance_base_currency), 0)
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
and gl.posting_status = 'posted'
$$;
create or replace function excel_api.get_account_base_amount(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns numeric
language sql
stable
as $$
select coalesce(sum(
case
when gl.transaction_currency_id = gl.base_currency_id then
gl.balance_transaction_currency
else
gl.balance_transaction_currency
* excel_api.currency_rate_at(gl.base_currency_id, p_value_date)
/ nullif(
excel_api.currency_rate_at(
gl.transaction_currency_id, p_value_date),
0)
end), 0)
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
and gl.posting_status = 'posted'
$$;
create or replace function excel_api.get_account_abbr(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns text
language sql
stable
as $$
select gl.account_code
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
order by gl.posting_date desc, gl.move_line_id desc
limit 1
$$;
create or replace function excel_api.get_account_name(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns text
language sql
stable
as $$
select gl.account_name
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
order by gl.posting_date desc, gl.move_line_id desc
limit 1
$$;
create or replace function excel_api.get_account_contact(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns text
language sql
stable
as $$
select nullif(string_agg(distinct coalesce(gl.party_code, gl.party_name),
', ' order by coalesce(gl.party_code, gl.party_name)), '')
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
and gl.posting_status = 'posted'
and coalesce(gl.party_code, gl.party_name) is not null
$$;
create or replace function excel_api.get_account_contact_code(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns text
language sql
stable
as $$
select nullif(string_agg(distinct coalesce(gl.party_code, gl.party_name),
', ' order by coalesce(gl.party_code, gl.party_name)), '')
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
and gl.posting_status = 'posted'
and coalesce(gl.party_code, gl.party_name) is not null
$$;
create or replace function excel_api.get_account_contact_name(
p_company_key text,
p_account_code text,
p_currency_iso text,
p_value_date date)
returns text
language sql
stable
as $$
select nullif(string_agg(distinct coalesce(gl.party_name, gl.party_code),
', ' order by coalesce(gl.party_name, gl.party_code)), '')
from excel_api.gl_account_lines gl
where excel_api.company_matches(gl.company_key, p_company_key)
and gl.account_code = p_account_code
and excel_api.currency_matches(gl.transaction_currency_id, p_currency_iso)
and gl.posting_date <= p_value_date
and gl.posting_status = 'posted'
and coalesce(gl.party_name, gl.party_code) is not null
$$;