read_listdata() --> classmethod

This commit is contained in:
Frederik Jaeckel 2025-01-17 12:53:11 +01:00
parent cf98fdf2ad
commit 530f37a06b

View file

@ -7,6 +7,7 @@
import os.path
import json
import copy
from lxml import etree
from datetime import datetime, date
from decimal import Decimal
@ -633,6 +634,8 @@ class Incoming(metaclass=PoolMeta):
line.account = expense_accounts[0]
# check if calculated 'amount' matches with amount from xml-data
assert invoice.currency is not None
xml_amount = line_data.get('total', {}).pop('amount', None)
if xml_amount is not None:
if xml_amount != line.get_amount(None):
@ -667,10 +670,43 @@ class Incoming(metaclass=PoolMeta):
'document_incoming_invoice_xml.msg_unused_linevalues'),
json.dumps(line_data, cls=JSONEncoder, indent=3)])
line.note = '\n'.join(x for x in notes if x)
line.on_change_invoice()
return line
def _readxml_read_listdata(self, xmldata, xpth, xtag, key_list):
""" read list of values from xml
Args:
xmldata (xtree): xml-tree
xpth (list): list of xml-tags until index-counter
pos (int): position in list
xtag (str): xml-tag to read as list
key_list (list): [('<xtag>', '<key>')]
Returns:
list: list of dict
"""
if isinstance(xtag, str):
xtag = [xtag]
xpath_list = xpth + xtag
num_listitem = len(xmldata.xpath(
self._readxml_xpath(xpath_list), namespaces=xmldata.nsmap))
listdata = []
for x in range(1, num_listitem + 1):
values = {}
for list_item in key_list:
(xkey, key, xtype) = (
list_item if len(list_item) == 3
else tuple(list(list_item) + [None]))
value = self._readxml_getvalue(
xmldata, xpath_list + [x, xkey], vtype=xtype)
if value is not None:
values[key] = value
if values:
listdata.append(values)
return listdata
def _readxml_invoice_line(self, xmldata, xpth, pos):
""" read invoice-line from xml
@ -682,43 +718,13 @@ class Incoming(metaclass=PoolMeta):
Returns:
dict: invoice line data
"""
def read_listdata(xtag, key_list):
""" read list of values from xml
Args:
xtag (str): xml-tag to read as list
key_list (list): [('<xtag>', '<key>')]
Returns:
list: list of dict
"""
if isinstance(xtag, str):
xtag = [xtag]
xpath_list = xpth + [pos] + xtag
num_listitem = len(xmldata.xpath(
self._readxml_xpath(xpath_list), namespaces=xmldata.nsmap))
listdata = []
for x in range(1, num_listitem + 1):
values = {}
for list_item in key_list:
(xkey, key, xtype) = (
list_item if len(list_item) == 3
else tuple(list(list_item) + [None]))
value = self._readxml_getvalue(
xmldata, xpath_list + [x, xkey], vtype=xtype)
if value is not None:
values[key] = value
if values:
listdata.append(values)
return listdata
xpath_line = xpth + [pos]
result = {'convert_note': []}
result['line_no'] = self._readxml_getvalue(xmldata, xpth + [pos] + [
result['line_no'] = self._readxml_getvalue(xmldata, xpath_line + [
'ram:AssociatedDocumentLineDocument', 'ram:LineID'])
result['line_note'] = '\n'.join(self._readxml_getvalue(
xmldata, xpth + [pos] + [
xmldata, xpath_line + [
'ram:AssociatedDocumentLineDocument', 'ram:IncludedNote',
'ram:Content'], allow_list=True))
@ -736,34 +742,38 @@ class Incoming(metaclass=PoolMeta):
('ram:ModelName', 'model_name'),
('ram:OriginTradeCountry', 'trade_country')
]:
result[key] = self._readxml_getvalue(xmldata, xpth + [pos] + [
result[key] = self._readxml_getvalue(xmldata, xpath_line + [
'ram:SpecifiedTradeProduct', xkey])
# attributes of product
result['attributes'] = read_listdata([
'ram:SpecifiedTradeProduct',
'ram:ApplicableProductCharacteristic'], [
result['attributes'] = self._readxml_read_listdata(
xmldata, xpath_line, [
'ram:SpecifiedTradeProduct',
'ram:ApplicableProductCharacteristic'], [
('ram:TypeCode', 'code'),
('ram:Description', 'description'),
('ram:ValueMeasure', 'uom'),
('ram:ValueY', 'value')])
# classification of product
result['classification'] = read_listdata([
'ram:SpecifiedTradeProduct',
'ram:DesignatedProductClassification'], [
result['classification'] = self._readxml_read_listdata(
xmldata, xpath_line, [
'ram:SpecifiedTradeProduct',
'ram:DesignatedProductClassification'], [
('ram:ClassCode', 'code'),
('ram:ClassName', 'name')])
# serial-numbers of product
result['serialno'] = read_listdata([
'ram:SpecifiedTradeProduct',
'ram:IndividualTradeProductInstance'], [
result['serialno'] = self._readxml_read_listdata(
xmldata, xpath_line, [
'ram:SpecifiedTradeProduct',
'ram:IndividualTradeProductInstance'], [
('ram:BatchID', 'lot'),
('ram:SupplierAssignedSerialID', 'serial')])
# referenced product
result['refprod'] = read_listdata(
result['refprod'] = self._readxml_read_listdata(
xmldata, xpath_line,
['ram:SpecifiedTradeProduct', 'ram:IncludedReferencedProduct'], [
('ram:ID', 'id'),
('ram:GlobalID', 'global_id'),
@ -775,12 +785,13 @@ class Incoming(metaclass=PoolMeta):
])
# net price
xpath_netprice = xpth + [pos] + [
xpath_netprice = xpath_line + [
'ram:SpecifiedLineTradeAgreement', 'ram:NetPriceProductTradePrice']
if self._readxml_getvalue(xmldata, xpath_netprice):
result['unit_net_price'] = read_listdata([
'ram:SpecifiedLineTradeAgreement',
'ram:NetPriceProductTradePrice'], [
result['unit_net_price'] = self._readxml_read_listdata(
xmldata, xpath_line, [
'ram:SpecifiedLineTradeAgreement',
'ram:NetPriceProductTradePrice'], [
('ram:ChargeAmount', 'amount', Decimal),
('ram:BasisQuantity', 'basequantity', Decimal)])[0]
# notice ignored field
@ -791,13 +802,14 @@ class Incoming(metaclass=PoolMeta):
xpath_netprice + ['ram:AppliedTradeAllowanceCharge']))
# gross price
xpath_grossprice = xpth + [pos] + [
xpath_grossprice = xpath_line + [
'ram:SpecifiedLineTradeAgreement',
'ram:GrossPriceProductTradePrice']
if self._readxml_getvalue(xmldata, xpath_grossprice):
result['unit_gross_price'] = read_listdata([
'ram:SpecifiedLineTradeAgreement',
'ram:GrossPriceProductTradePrice'], [
result['unit_gross_price'] = self._readxml_read_listdata(
xmldata, xpath_line, [
'ram:SpecifiedLineTradeAgreement',
'ram:GrossPriceProductTradePrice'], [
('ram:ChargeAmount', 'amount', Decimal),
('ram:BasisQuantity', 'basequantity', Decimal)])[0]
# notice ignored field
@ -809,9 +821,10 @@ class Incoming(metaclass=PoolMeta):
['ram:AppliedTradeAllowanceCharge']))
# quantity
xpath_quantity = xpth + [pos] + ['ram:SpecifiedLineTradeDelivery']
result['quantity'] = read_listdata(
['ram:SpecifiedLineTradeDelivery'], [
xpath_quantity = xpath_line + ['ram:SpecifiedLineTradeDelivery']
result['quantity'] = self._readxml_read_listdata(
xmldata, xpath_line, [
'ram:SpecifiedLineTradeDelivery'], [
('ram:BilledQuantity', 'billed', Decimal),
('ram:ChargeFreeQuantity', 'chargefree', Decimal),
('ram:PackageQuantity', 'package', Decimal),
@ -829,8 +842,8 @@ class Incoming(metaclass=PoolMeta):
'skip: ' + self._readxml_xpath(xp_to_check))
# taxes
xpath_trade = xpth + [pos] + ['ram:SpecifiedLineTradeSettlement']
result['taxes'] = read_listdata([
xpath_trade = xpath_line + ['ram:SpecifiedLineTradeSettlement']
result['taxes'] = self._readxml_read_listdata(xmldata, xpath_line, [
'ram:SpecifiedLineTradeSettlement',
'ram:ApplicableTradeTax'], [
('ram:CalculatedAmount', 'amount', Decimal),
@ -846,7 +859,7 @@ class Incoming(metaclass=PoolMeta):
('ram:RateApplicablePercent', 'percent', Decimal)])
# total amounts
result['total'] = read_listdata([
result['total'] = self._readxml_read_listdata(xmldata, xpath_line, [
'ram:SpecifiedLineTradeSettlement',
'ram:SpecifiedTradeSettlementLineMonetarySummation'], [
('ram:LineTotalAmount', 'amount', Decimal),