Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tools to support use of CAMT #1

Merged
merged 12 commits into from
Aug 14, 2024
12 changes: 7 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,12 @@ ttylog

*.xml
pacs_008_001_08/
pacs/
head/
camt/
pain/
pyiso20022/
pyiso20022/pacs/
pyiso20022/head/
pyiso20022/camt/
pyiso20022/pain/
pyiso20022/*.py

temp/

*.xlsx
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,31 @@ with open("my_pacs_008_from_code.xml", "w") as xml_file:

```

### Message types?
Currently supports PACS, PAIN and CAMT messages as well as HEAD (header documents for the messages).
## Convert a CAMT.053 into an Excel file?

You can convert the entries in a CAMT.053 into a Excel file using the tools in pyiso20022.

### Source of truth?
Currently this will extract the `Ntry` list and take all details and place them into seperate columns. It will also translate the element names into their more meaningful English versions.

Use it like this:

```python
import pyiso20022.tools as isotools

isotools.camt053_to_excel("my_camt053_file.xml",
"my_camt053_excel_file.xlsx")
```

And you'll get something like this when you open your Excel file:

<iMG SRC="https://github.com/phoughton/pyiso20022/raw/main/docs/pyiso20022_tools_camt053_excel.png?raw=true" WIDTH=800>



## Message types?
Currently pyiso20022 supports PACS, PAIN and CAMT messages as well as HEAD (header documents for the messages).


## Source of truth?

If you want the original source of truth for all things ISO 20022 schema related then check out [www.iso20022.org](https://www.iso20022.org/)
10 changes: 9 additions & 1 deletion build_classes_from_xsds.bsh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ generate_xsdata() {
done
}

rm -rf pyiso20022/
REMOVE_DIRS=("pacs" "head" "pain" "camt")

for a_dir in "${REMOVE_DIRS[@]}"
do
rm -rf "pyiso20022/${a_dir}"
done


echo "# Supported message types" > supported_msg_types.md

generate_xsdata "pacs" "xsd/payments_clearing_and_settlement"
Expand All @@ -26,3 +33,4 @@ generate_xsdata "camt" "xsd/cash_management"
wait
cat supported_msg_types.md | sort -n | uniq > supported_msg_types_final.md
rm supported_msg_types.md

2 changes: 2 additions & 0 deletions build_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ setuptools
wheel
twine
xsdata[cli,lxml,soap]
pandas
openpyxl
Binary file added docs/pyiso20022_tools_camt053_excel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 122 additions & 0 deletions example_files/pacs/gen_pacs008.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
from pyiso20022.pacs.pacs_008_001_08 import *
import pyiso20022.head.head_001_001_02 as hd
from xsdata.formats.dataclass.serializers import XmlSerializer
from xsdata.formats.dataclass.serializers.config import SerializerConfig
import uuid
from lxml import etree
from xsdata.models.datatype import XmlDateTime


clr_sys = ClearingSystemIdentification3Choice(cd="STG")
the_sttlinf = SettlementInstruction7(sttlm_mtd=SettlementMethod1Code("CLRG"),
clr_sys=clr_sys)

# Create the Group Header
grp_header = GroupHeader93(msg_id="MIDTheMessageId",
nb_of_txs=1,
cre_dt_tm=XmlDateTime.from_string("2019-01-01T00:00:00"),
sttlm_inf=the_sttlinf)


pmt_id = PaymentIdentification7(instr_id="IXWEDRFTGHJK5",
end_to_end_id="E2EDRFGHJK7",
tx_id="TIDRFGHJ54678",
uetr=str(uuid.uuid4()))


zero_amt = ActiveOrHistoricCurrencyAndAmount(ccy="GBP", value=0)

bic_1 = FinancialInstitutionIdentification18("BARCGB22")
bic_2 = FinancialInstitutionIdentification18("VODAGB23")

agt = BranchAndFinancialInstitutionIdentification6(fin_instn_id=bic_1)

instd_agt = BranchAndFinancialInstitutionIdentification6(fin_instn_id=bic_2)
instg_agt = BranchAndFinancialInstitutionIdentification6(fin_instn_id=bic_1)

chrgs_inf = Charges7(amt=zero_amt, agt=agt)

ult_pstl = PostalAddress24(bldg_nm="10",
strt_nm="Cheapside",
twn_nm="London",
ctry="GB")
dbtr_pstl = PostalAddress24(bldg_nm="11",
strt_nm="Farside",
twn_nm="York",
ctry="GB")
ult_debtr = PartyIdentification135(nm="Mr Ulti Debtor",
pstl_adr=ult_pstl)
initg_pty = PartyIdentification135(nm="Ms Initd Party",
pstl_adr=ult_pstl)
reg_debtr = PartyIdentification135(nm="Mrs Reg Debtor",
pstl_adr=dbtr_pstl)
instr_for_nxt_agt = InstructionForNextAgent1(instr_inf="HOLD")
instd_amt = ActiveOrHistoricCurrencyAndAmount(ccy="GBP", value=555.01)
intra_bk_st_amt = ActiveCurrencyAndAmount(ccy="GBP", value=555.01)

purp = Purpose2Choice(cd="PHON")
rem_loc = RemittanceLocation7(rmt_id="BUSINESS DEBIT")
rmt_inf = RemittanceInformation16(ustrd=["INVOICE 123456"])
cdtrtx = CreditTransferTransaction39(pmt_id=pmt_id,
chrg_br=ChargeBearerType1Code("SHAR"),
intr_bk_sttlm_dt="2019-01-01",
intr_bk_sttlm_amt=intra_bk_st_amt,
instd_amt=instd_amt,
chrgs_inf=[chrgs_inf],
instg_agt=instg_agt,
instd_agt=instd_agt,
ultmt_dbtr=ult_debtr,
initg_pty=initg_pty,
dbtr=reg_debtr,
dbtr_agt=instg_agt,
cdtr_agt=instd_agt,
instr_for_nxt_agt=[instr_for_nxt_agt],
purp=purp,
rltd_rmt_inf=[rem_loc],
rmt_inf=rmt_inf)


f2f_cust_cred_trans = FitoFicustomerCreditTransferV08(grp_hdr=grp_header,
cdt_trf_tx_inf=[cdtrtx])

doc = Document(fito_ficstmr_cdt_trf=f2f_cust_cred_trans)

# Create the AppHdr
fr_fiid = hd.FinancialInstitutionIdentification18(bicfi="BARCGB22")
fr_bafii = hd.BranchAndFinancialInstitutionIdentification6(fin_instn_id=fr_fiid)
fr_party44 = hd.Party44Choice(fiid=fr_bafii)

to_fiid = hd.FinancialInstitutionIdentification18(bicfi="BARCGB22")
to_bafii = hd.BranchAndFinancialInstitutionIdentification6(fin_instn_id=to_fiid)
to_party44 = hd.Party44Choice(fiid=to_bafii)

header = hd.AppHdr(fr=fr_party44,
to=to_party44,
biz_msg_idr="MIDRFGHJKL",
msg_def_idr="pacs.008.001.08",
biz_svc="boe.chaps.enh.01",
cre_dt="2019-01-01T00:00:00",
prty="NORM")

config_subs = SerializerConfig(pretty_print=True, xml_declaration=False)
serializer_subs = XmlSerializer(config=config_subs)

ns_map_header: dict[None, str] = {
None: "urn:iso:std:iso:20022:tech:xsd:head.001.001.02"
}
ns_map_doc: dict[None, str] = {
None: "urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08"
}

header_el: str = serializer_subs.render(header, ns_map=ns_map_header)
doc_el: str = serializer_subs.render(doc, ns_map=ns_map_doc)

msg_root = etree.Element('MSGRoot')
msg_root.append(etree.fromstring(header_el))
msg_root.append(etree.fromstring(doc_el))

msg_full = etree.tostring(msg_root, pretty_print=True,
xml_declaration=True, encoding='UTF-8')

with open("my_pacs_008_from_code.xml", "w") as xml_file:
xml_file.write(str(msg_full, encoding='utf-8'))
7 changes: 7 additions & 0 deletions make_xlsx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import pyiso20022.tools as isotools

isotools.camt053_to_excel("example_files/gs_camt/camt053_001_02.xml",
"camt053_excel.xlsx")

hed = isotools.camt053_to_df("example_files/gs_camt/camt053_001_02.xml").head()
print(hed)
4 changes: 4 additions & 0 deletions pyiso20022/tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from pyiso20022.tools.camt053_extract import camt053_to_excel
from pyiso20022.tools.camt053_extract import camt053_to_df

__all__ = [camt053_to_excel, camt053_to_df]
Loading