Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def parse_amount(self, ns, node):
if node is None:
return 0.0
sign = 1
amount = 0.0
sign_node = node.xpath("ns:CdtDbtInd", namespaces={"ns": ns})
if not sign_node:
sign_node = node.xpath("../../ns:CdtDbtInd", namespaces={"ns": ns})
Expand All @@ -30,9 +29,77 @@ def parse_amount(self, ns, node):
amount_node = node.xpath(
"./ns:AmtDtls/ns:TxAmt/ns:Amt", namespaces={"ns": ns}
)
parent_amount_currency = node.xpath(
"../../ns:Amt/@Ccy", namespaces={"ns": ns}
)
if amount_node and parent_amount_currency:
amount_currency = amount_node[0].get("Ccy")
if amount_currency and amount_currency != parent_amount_currency[0]:
amount_node = []
if amount_node:
amount = sign * float(amount_node[0].text)
return amount
return sign * float(amount_node[0].text or 0.0)
return 0.0

def parse_amount_details_currency(self, ns, node, transaction):
"""Extract original transaction currency details when available."""
statement_currency = transaction.get("currency")
original_currency = None
original_amount = 0.0

original_amount_nodes = node.xpath(
"./ns:AmtDtls/ns:TxAmt/ns:Amt[@Ccy] | .//ns:AmtDtls/ns:TxAmt/ns:Amt[@Ccy]",
namespaces={"ns": ns},
)
for amount_node in original_amount_nodes:
currency = amount_node.get("Ccy")
if currency and currency != statement_currency:
original_currency = currency
original_amount = float(amount_node.text or 0.0)
break

if not original_currency:
ccy_nodes = node.xpath(".//ns:AmtDtls//@Ccy", namespaces={"ns": ns})
for currency in ccy_nodes:
if currency == statement_currency:
continue
value_node = node.xpath(
f".//ns:AmtDtls//*[@Ccy='{currency}']",
namespaces={"ns": ns},
)
if value_node:
original_currency = currency
original_amount = float(value_node[0].text or 0.0)
break

if not original_currency:
trgt_ccy = node.xpath(".//ns:CcyXchg/ns:TrgtCcy", namespaces={"ns": ns})
rate = node.xpath(".//ns:CcyXchg/ns:XchgRate", namespaces={"ns": ns})
amount_node = node.xpath("ns:Amt", namespaces={"ns": ns})
if (
trgt_ccy
and rate
and amount_node
and trgt_ccy[0].text
and trgt_ccy[0].text != statement_currency
):
original_currency = trgt_ccy[0].text
original_amount = float(amount_node[0].text or 0.0) * float(
rate[0].text or 0.0
)

if not original_currency:
return False

currency = self.env["res.currency"].search(
[("name", "=", original_currency)], limit=1
)
if not currency:
return False

sign = 1 if transaction.get("amount", 0.0) >= 0 else -1
transaction["foreign_currency_id"] = currency.id
transaction["amount_currency"] = sign * abs(original_amount)
return True

def add_value_from_node(self, ns, node, xpath_str, obj, attr_name, join_str=None):
"""Add value to object from first or all nodes found with xpath.
Expand Down Expand Up @@ -279,6 +346,13 @@ def parse_entry(self, ns, node):
self.add_value_from_node(
ns, node, "./ns:BookgDt/ns:Dt | ./ns:BookgDt/ns:DtTm", transaction, "date"
)
self.add_value_from_node(
ns,
node,
["./ns:Amt/@Ccy", ".//ns:AmtDtls/ns:TxAmt/ns:Amt/@Ccy"],
transaction,
"currency",
)
amount = self.parse_amount(ns, node)
if amount != 0.0:
transaction["amount"] = amount
Expand Down Expand Up @@ -337,13 +411,20 @@ def parse_entry(self, ns, node):

details_nodes = node.xpath("./ns:NtryDtls/ns:TxDtls", namespaces={"ns": ns})
if len(details_nodes) == 0:
self.parse_amount_details_currency(ns, node, transaction)
transaction.pop("currency", None)
self.generate_narration(transaction)
yield transaction
return
transaction_base = transaction
for node in details_nodes:
transaction = transaction_base.copy()
self.parse_transaction_details(ns, node, transaction)
if not self.parse_amount_details_currency(ns, node, transaction):
self.parse_amount_details_currency(
ns, node.getparent().getparent(), transaction
)
transaction.pop("currency", None)
self.generate_narration(transaction)
yield transaction

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
('SEK',
'SE3550000000054910000003',
[{'balance_end_real': 0.0,
'balance_start': 0.0,
'date': '2026-05-06',
'name': 'STATEMENT-1',
'transactions': [{'account_number': 'SE123456789',
'amount': 345.34,
'amount_currency': 32.0,
'date': '2026-05-06',
'foreign_currency_id': 'EUR',
'narration': 'Partner Name (RltdPties/Nm): \n'
'Partner Account Number (RltdPties/Acct): SE123456789\n'
'Transaction Date (BookgDt): 2026-05-06\n'
'Reference: \n'
'Communication: \n'
'Transaction Type (BkTxCd): ',
'payment_ref': '/',
'transaction_type': ''}]}])
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02">
<BkToCstmrStmt>
<GrpHdr>
<MsgId>MULTI-1</MsgId>
<CreDtTm>2026-05-06T10:00:00</CreDtTm>
</GrpHdr>
<Stmt>
<Id>STATEMENT-1</Id>
<Acct>
<Id>
<IBAN>SE3550000000054910000003</IBAN>
</Id>
<Ccy>SEK</Ccy>
</Acct>
<Ntry>
<Amt Ccy="SEK">345.34</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<BookgDt>
<Dt>2026-05-06</Dt>
</BookgDt>
<NtryDtls>
<TxDtls>
<AmtDtls>
<TxAmt>
<Amt Ccy="EUR">32.00</Amt>
</TxAmt>
</AmtDtls>
<RltdPties>
<DbtrAcct>
<Id>
<Othr>
<Id>SE123456789</Id>
</Othr>
</Id>
</DbtrAcct>
</RltdPties>
</TxDtls>
</NtryDtls>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>

Loading
Loading