Files
ksef_app/app/services/invoice_party_service.py
Mateusz Gruszczyński 35571df778 push
2026-03-13 11:03:13 +01:00

73 lines
2.3 KiB
Python

import re
import xml.etree.ElementTree as ET
class InvoicePartyService:
@staticmethod
def extract_address_from_ksef_xml(xml_content: str):
result = {
'street': None,
'city': None,
'postal_code': None,
'country': None,
'address': None,
}
if not xml_content:
return result
try:
root = ET.fromstring(xml_content)
except Exception:
return result
def local_name(tag: str) -> str:
return tag.split('}', 1)[1] if '}' in tag else tag
def clean(value):
return (value or '').strip()
def find_text(names: list[str]):
wanted = {name.lower() for name in names}
for node in root.iter():
if local_name(node.tag).lower() in wanted:
text = clean(node.text)
if text:
return text
return None
street = find_text(['Ulica', 'AdresL1'])
house_no = find_text(['NrDomu'])
apartment_no = find_text(['NrLokalu'])
city = find_text(['Miejscowosc'])
postal_code = find_text(['KodPocztowy'])
country = find_text(['Kraj', 'KodKraju'])
adres_l2 = find_text(['AdresL2'])
if adres_l2 and (not postal_code or not city):
match = re.match(r'^(\d{2}-\d{3})\s+(.+)$', clean(adres_l2))
if match:
postal_code = postal_code or match.group(1)
city = city or clean(match.group(2))
elif not city:
city = clean(adres_l2)
street_line = clean(street)
if not street_line:
street_parts = [part for part in [street, house_no] if part]
street_line = ' '.join([p for p in street_parts if p]).strip()
if apartment_no:
street_line = f'{street_line}/{apartment_no}' if street_line else apartment_no
address_parts = [part for part in [street_line, postal_code, city, country] if part]
result.update({
'street': street_line or None,
'city': city,
'postal_code': postal_code,
'country': country,
'address': ', '.join(address_parts) if address_parts else None,
})
return result