def parse_to_objects(lines): """Implementiert das Parsen einer liste von SoftM EDI-Datensätzen in Objekte.""" satzresolver = dict( XH=XHsatzklasse, F1=F1satzklasse, F2=F2satzklasse, F3=F3satzklasse, F4=F4satzklasse, # Rabatte # F5 - Zuschlaege F6=generate_field_datensatz_class(FELDERTEXT, name="komponenteninfo", length=496), # F7 Chargen F8=F8satzklasse, # Bankverbindung F9=F9satzklasse, # Rechnungsende # ER=ERsatzklasse, A1=A1satzklasse, R1=R1satzklasse, R2=R2satzklasse, R3=R3satzklasse, FA=FAsatzklasse, FR=generate_field_datensatz_class(FELDERTEXT, name="positionsrabatttext", length=496), FP=generate_field_datensatz_class(FELDERTEXT, name="positionstext", length=496), FK=generate_field_datensatz_class(FELDERTEXT, name="kopftext", length=496), FX=generate_field_datensatz_class(FELDERTEXT, name="kopfrabatttext", length=496), FE=generate_field_datensatz_class(FELDERTEXT, name="endtexte", length=496), # FV Versandarttexte # FL Lieferbedingungstexte # FN Nebenkosten ) ret = [] lineno = 0 for rawline in lines: lineno += 1 # remove newline & EOF line = rawline.rstrip("\r\n").strip(" \x1a") if not line: # skip empty lines continue # remove erstellungsdatum erstellungsdatum = line[519:] line = line[:519] # remove line-header line = line[19:] # pad line if it is to short now line = "% 500s" % line satzart, version, data = line[:2], line[2:4], line[4:] satzklasse = satzresolver.get(satzart, None) if satzklasse: satz = satzklasse() satz.parse(data) ret.append((satzart, Struct(**satz.as_dict()))) del satz else: print "Zeile %s:" % lineno, repr(satzart), repr(version), repr(erstellungsdatum), print len(line), len(data) print "unbekannter Satz:", satzart, version print repr(rawline) raise RuntimeError("unbekannter Satz: %r %r" % (str(satzart), str(version))) return ret
if previousparsers[-1].satzart not in ['900', '913']: raise MalformedFileException("Abschlaegesatz can only follow a Belegsummensatz." + (" Previous records = %r" % previousparsers)) def contribute_to_order(self, orderdict): """Return a dict contributing to the OrderProtocol.""" orderdict['abschlaege'].append({'art': unicode(self.parser.art), 'prozent': self.parser.prozent, 'name': unicode(self.parser.art_abschlag), }) return {'abschlaege': orderdict['abschlaege']} ordersparser = { '000': generate_field_datensatz_class(INTERCHANGEHEADER000, name='interchangeheader', length=512), '100': generate_field_datensatz_class(transaktionskopf, name='transaktionskopf', length=512), '111': generate_field_datensatz_class(TRANSAKTIONSREFERENZ111, name='transaktionsreferenz', length=512), '115': generate_field_datensatz_class(transaktionstermine, name='transaktionstermine', length=512), '119': generate_field_datensatz_class(addressen, name='addresse', length=512), '120': generate_field_datensatz_class(ZAHLUNGSBEDINGUNGEN120, name='zahlungsbedingungen', length=512), '130': generate_field_datensatz_class(texte, name='texte', length=512), '140': generate_field_datensatz_class(zusatzkosten, name='zusatzkosten', length=512), '500': generate_field_datensatz_class(auftragsposition, name='auftragsposition', length=512), '515': generate_field_datensatz_class(positionstermine, name='positionstermin', length=512), '900': generate_field_datensatz_class(belegsummen, name='belegsummen', length=512), '913': generate_field_datensatz_class(ABSCHLAEGE913, name='abschlaege', length=512), } recordhandlers = {
dict(length=4, startpos=82, endpos=85, name='erstellungszeit', fieldclass=TimeField, default=datetime.datetime.now), dict(length=14, startpos=86, endpos=99, name='datenaustauschreferenz', fieldclass=IntegerField, doc='Fortlaufende achtstellige Sendenummer.'), dict(length=14, startpos=100, endpos=113, name='referenznummer', fieldclass=IntegerField), dict(length=14, startpos=114, endpos=127, name='anwendungsreferenz'), # This has to be changed to 0 for production data dict(length=1, startpos=128, endpos=128, name='testkennzeichen'), dict(length=5, startpos=129, endpos=133, name='schnittstellenversion', fieldclass=FixedField, default='4.5 '), dict(length=467, startpos=134, endpos=600, name='filler', fieldclass=FixedField, default=' '* 467), ] # fix since this is not in python notation fix "off by one" errors for feld in INTERCHANGEHEADER000: feld['startpos'] -= 1 interchangeheader000 = generate_field_datensatz_class(INTERCHANGEHEADER000, name='interchangeheader', length=600) TRANSAKTIONSKOPF100 = [ dict(startpos=1, endpos=3, length=3, name='satzart', fieldclass=FixedField, default="100"), dict(startpos=4, endpos=17, length=14, name='referenz', fieldclass=IntegerField, doc='Eindeutige Nachrichtenreferenz des Absenders; laufende Nummer der Nachrichten im Datenaustausch;' + ' beginnt mit "1" und wird für jede Rechnung/Gutschrift innerhalb einer Übertragungsdatei' + ' um 1 erhöht.'), dict(startpos=18, endpos=23, length=6, name='typ', fieldclass=FixedField, default="INVOIC", doc="UNH-0065"), dict(startpos=24, endpos=26, length=3, name='version', fieldclass=FixedField, default="D ", doc="UNH-0052"), dict(startpos=27, endpos=29, length=3, name='release', fieldclass=FixedField, default='96A', doc="UNH-0054"), dict(startpos=30, endpos=31, length=2, name='organisation1', fieldclass=FixedField, default="UN", doc="UNH-0051"),
# dict(length=8, startpos=260, endpos=267, name='1.Res. 8 St.'), # dict(length=8, startpos=268, endpos=275, name='2.Res. 8 St.'), # dict(length=3, startpos=276, endpos=278, name='1.Res. 3 St.'), # dict(length=3, startpos=279, endpos=281, name='2.Res. 3 St.'), dict(length=2, startpos=282, endpos=283, name="testkennzeichen"), # dict(length=10, startpos=284, endpos=293, name='versionsnummer'), # dict(length=10, startpos=294, endpos=303, name='freigabenummer'), # dict(length=178, startpos=304, endpos=481, name='reserve_178'), dict(length=8, startpos=482, endpos=489, name="erstellungs_datum"), dict(length=6, startpos=490, endpos=495, name="erstellungs_zeit"), dict(length=1, startpos=496, endpos=496, name="status"), ] # fix difference in array counting between SoftM and Python for feld in FELDERXH: feld["startpos"] = feld["startpos"] - 1 XHsatzklasse = generate_field_datensatz_class(FELDERXH, name="XHheader", length=496, doc=doctext) # Rechnungskopf doctext = """Kopfdaten (XOO00EF1) = Diese Satzart enthält die Kopfdaten einer Rechnung und kann beliebig oft pro Übertragung vorkommen.""" FELDERF1 = [ dict(length=3, startpos=1, endpos=3, name="belegart"), dict(length=35, startpos=4, endpos=38, name="rechnungsnr", fieldclass=IntegerField, doc="100-10 bei StratEDI"), dict(length=8, startpos=39, endpos=46, name="rechnungsdatum", fieldclass=DateField, doc="100-11 bei StratEDI"), dict(length=8, startpos=47, endpos=54, name="liefertermin", fieldclass=DateField), dict(length=35, startpos=55, endpos=89, name="lieferscheinnr", fieldclass=IntegerField), dict(length=8, startpos=90, endpos=97, name="lieferscheindatum", fieldclass=DateField), dict(length=20, startpos=98, endpos=117, name="kundenbestellnummer"),