- 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>
278 lines
9.1 KiB
PL/PgSQL
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
|
|
$$;
|