From 29f963f9a8f8fb43627f6256a0c048953ecdfcd6 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Fri, 17 Jan 2025 12:12:13 +0100 Subject: [PATCH] put invoice-update in own function --- document.py | 139 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/document.py b/document.py index 116bfc4..2b4dd4b 100644 --- a/document.py +++ b/document.py @@ -70,8 +70,10 @@ class Incoming(metaclass=PoolMeta): raise UserError(gettext( 'document_incoming_invoice_xml.msg_not_implemented', xmltype=xsd_type)) - # read xml data - (self.parsed_data, invoice) = xml_read_func(invoice, xmltree) + # read xml data, write to 'self.parsed_data' + xml_read_func(xmltree) + # update invoice with imported data + invoice = self._readxml_update_invoice(invoice) return invoice def _readxml_xpath(self, tags): @@ -291,7 +293,75 @@ class Incoming(metaclass=PoolMeta): result['party'] = party_id return result - def _readxml_facturx_extended(self, invoice, xmltree): + def _readxml_update_invoice(self, invoice): + """ update invoice with parsed_data + + Args: + invoice (record): model account.invoice + + Returns: + record: model account.invoice + """ + Configuration = Pool().get('document.incoming.configuration') + + config = Configuration.get_singleton() + + if config and config.number_target == 'number': + invoice.number = self.parsed_data.get('invoice_number', None) + else: + invoice.reference = self.parsed_data.get('invoice_number', None) + invoice.invoice_date = self.parsed_data.get('invoice_date', None) + + note_list = self.parsed_data.get('note_list', None) + if note_list: + invoice.description = note_list[0].get('Content', None) + invoice.comment = '\n'.join([ + '%(code)s%(subj)s%(msg)s' % { + 'code': ('Code=%s, ' % x.get('ContentCode', '')) + if x.get('ContentCode', '') else '', + 'subj': ('Subject=%s, ' % x.get('SubjectCode', '')) + if x.get('SubjectCode', '') else '', + 'msg': x.get('Content', ''), + } for x in note_list[1:]]) + + seller_party = self.parsed_data.get('seller_party', None) + if seller_party: + if 'party' in seller_party.keys(): + invoice.party = seller_party['party'] + invoice.on_change_party() + else: + raise UserError(gettext( + 'document_incoming_invoice_xml.msg_no_supplierparty', + partytxt=', '.join([ + seller_party[x].replace('\n', '; ') + for x in seller_party.keys()]))) + + # check if we found our company + buyer_party = self.parsed_data.get('buyer_party', None) + if buyer_party and config and not config.accept_other_company: + company_party_id = self._readxml_find_party(buyer_party) + if not (company_party_id and + (company_party_id == self.company.party.id)): + raise UserError(gettext( + 'document_incoming_invoice_xml.msg_not_our_company', + partytxt=', '.join([ + buyer_party[x].replace('\n', '; ') + for x in buyer_party.keys()]))) + + lines_data = copy.deepcopy(self.parsed_data.get('lines_data', None)) + if lines_data: + lines = [ + self._readxml_getinvoiceline(invoice, x) + for x in lines_data] + for x in range(len(lines)): + lines[x].sequence = x + 1 + invoice.lines = lines + invoice.on_change_lines() + + print('\n## parsed-data:', self.parsed_data) + return invoice + + def _readxml_facturx_extended(self, xmltree): """ read factur-x extended Args: @@ -303,7 +373,11 @@ class Incoming(metaclass=PoolMeta): Configuration = Pool().get('document.incoming.configuration') config = Configuration.get_singleton() - parsed_data = {} + + if not hasattr(self, 'parsed_data'): + self.parsed_data = {} + if not isinstance(self.parsed_data, dict): + self.parsed_data = {} # rsm:CrossIndustryInvoice xpath_cross_ind = ['rsm:CrossIndustryInvoice'] @@ -320,13 +394,8 @@ class Incoming(metaclass=PoolMeta): msg='invalid type-code: %(code)s (expect: 380, 381)' % { 'code': str(inv_code)})) - invoice_number = self._readxml_getvalue( + self.parsed_data['invoice_number'] = self._readxml_getvalue( xmltree, xpath_exchg_doc + ['ram:ID']) - if config and config.number_target == 'number': - invoice.number = invoice_number - else: - invoice.reference = invoice_number - parsed_data['invoice_number'] = invoice_number # invoice-date date_path = xpath_exchg_doc + [ @@ -337,9 +406,8 @@ class Incoming(metaclass=PoolMeta): 'document_incoming_invoice_xml.msg_convert_error', msg='invalid date-format: %(code)s (expect: 102)' % { 'code': str(date_format)})) - invoice.invoice_date = self._readxml_convertdate( + self.parsed_data['invoice_date'] = self._readxml_convertdate( self._readxml_getvalue(xmltree, date_path)) - parsed_data['invoice_date'] = invoice.invoice_date # IncludedNote, 1st line --> 'description', 2nd ff. --> 'comment' xpath_notes = xpath_exchg_doc + ['ram:IncludedNote'] @@ -355,18 +423,8 @@ class Incoming(metaclass=PoolMeta): xmltree, xpath_notes + [x, 'ram:%s' % y]) for y in ['Content', 'ContentCode', 'SubjectCode'] }) - - parsed_data['note_list'] = note_list if note_list: - invoice.description = note_list[0].get('Content', None) - invoice.comment = '\n'.join([ - '%(code)s%(subj)s%(msg)s' % { - 'code': ('Code=%s, ' % x.get('ContentCode', '')) - if x.get('ContentCode', '') else '', - 'subj': ('Subject=%s, ' % x.get('SubjectCode', '')) - if x.get('SubjectCode', '') else '', - 'msg': x.get('Content', ''), - } for x in note_list[1:]]) + self.parsed_data['note_list'] = note_list # rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction xpath_suppl_chain = xpath_cross_ind + [ @@ -382,33 +440,15 @@ class Incoming(metaclass=PoolMeta): seller_party = self._readxml_party_data( xmltree, xpath_appl_head_agree + ['ram:SellerTradeParty'], create_party=add_party) - parsed_data['seller_party'] = seller_party if seller_party: - if 'party' in seller_party.keys(): - invoice.party = seller_party['party'] - invoice.on_change_party() - else: - raise UserError(gettext( - 'document_incoming_invoice_xml.msg_no_supplierparty', - partytxt=', '.join([ - seller_party[x].replace('\n', '; ') - for x in seller_party.keys()]))) + self.parsed_data['seller_party'] = seller_party # company party buyer_party = self._readxml_party_data( xmltree, xpath_appl_head_agree + ['ram:BuyerTradeParty'], create_party=False) - parsed_data['buyer_party'] = buyer_party - # check if we found our company - if config and not config.accept_other_company: - company_party_id = self._readxml_find_party(buyer_party) - if not (company_party_id and - (company_party_id == self.company.party.id)): - raise UserError(gettext( - 'document_incoming_invoice_xml.msg_not_our_company', - partytxt=', '.join([ - buyer_party[x].replace('\n', '; ') - for x in buyer_party.keys()]))) + if buyer_party: + self.parsed_data['buyer_party'] = buyer_party # invoice - lines # rsm:CrossIndustryInvoice/ @@ -423,16 +463,9 @@ class Incoming(metaclass=PoolMeta): for x in range(1, num_lines + 1): lines_data.append( self._readxml_invoice_line(xmltree, xpath_line_item, x)) - parsed_data['lines_data'] = lines_data - lines = [ - self._readxml_getinvoiceline(invoice, x) - for x in lines_data] - for x in range(len(lines)): - lines[x].sequence = x + 1 - invoice.lines = lines + if lines_data: + self.parsed_data['lines_data'] = lines_data - invoice.on_change_lines() - return (parsed_data, invoice) def _readxml_getinvoiceline(self, invoice, line_data): """ create invoice line in memory