def get_rechnung(rechnungsnr): """Findet eine Rechnung anhand ihrer Rechnungsnr""" conditions = ["FKSTAT <> 'X'", "FKRGNR = %d" % remove_prefix(rechnungsnr, 'RG')] rows = query(tables=['AFK00'], condition=' AND '.join(conditions), limit=1, ua='husoftm2.rechnungen') if not rows: return rechnung = rows[0] # Rechnungspositionen conditions = ["FURGNR <> 'X'"] rows = query(tables=['AFU00'], condition='FURGNR = %d' % remove_prefix(rechnungsnr, 'RG'), ua='husoftm2.rechnungen') rechnung['positionen'] = rows # Evtl. in Funktion auslagern wie in husoftm2.kunden: rechnung['rechnungsnr'] = add_prefix(rechnung['rechnungsnr'], 'RG') rechnung['auftragsnr'] = add_prefix(rechnung['auftragsnr'], 'SO') rechnung['kundennr_rechnungsempfaenger'] = add_prefix(rechnung['kundennr_rechnungsempfaenger'], 'SC') rechnung['kundennr_warenempfaenger'] = add_prefix(rechnung['kundennr_warenempfaenger'], 'SC') if rechnung['verbandsnr']: rechnung['verbandsnr'] = add_prefix(rechnung['verbandsnr'], 'SC') return rechnung
def preislisten(gueltig_bis=None): """Gib die 'Namen' aller Preislisten für Kundengruppen und Kunden zurück""" conditions = ["PNSANR=PRSANR", "PRANW='A'", "PRSTAT=' '", "PNSTAT=' '", ] if gueltig_bis: conditions.append("PRDTBI>=%s" % date2softm(gueltig_bis)) preislisten = husoftm2.texte.get_map('PRL') rows = query(tables=['XPR00', 'XPN00'], fields=['PRKDNR', 'PRPRLK', 'PRARTN', 'PNPRB', 'PRDTVO', 'PRDTBI'], condition=' AND '.join(conditions)) for row in rows: if row['kunde']: row['kunde'] = add_prefix(row['kunde'], 'SC') if row['preisliste_kunde']: row['preislistenname'] = preislisten.get(row['preisliste_kunde'], "?=%s" % row['preisliste_kunde']) return rows
def get_rahmenauftraege(kundennr, artnr): """Gib die Auftragsnummern aller offenen Rahmenaufträge für den Kunden und den Artikel als Liste zurück. >>> get_rahmenauftraege('SC66663', '14600') ['SO1205711'] """ kundennr = remove_prefix(kundennr, 'SC') conditions = ["AKAUFN=APAUFN", "AKKZVA=0", "APKZVA=0", "AKSTAT<>'X'", "APSTAT<>'X'", "AKAUFN>0", "AKAUFA='R'", "AKKDNR=%s" % pad('AKKDNR', kundennr), "APARTN=%s" % sql_quote(artnr)] rows = query(['AAK00', 'AAP00'], condition=' AND '.join(conditions), fields=['AKAUFN'], ua='husoftm2.auftraege.get_rahmenauftraege') return [add_prefix(row[0], 'SO') for row in rows]
def get_address(lieferantennr): """Liefert die Adresse zu einer Lieferantennummer.""" # Präfix für Lieferanten (SP) entfernen. Für Präfix siehe # https://sites.google.com/a/hudora.de/intern/it-administration/nummern/nummernkreise lieferantennr = remove_prefix(lieferantennr, 'SP') # LISTAT kann 'X' (gelöscht) oder 'I' (inaktiv) sein. Wir wollen nur gültige Adressen, also LISTAT = ' ' rows = query(tables=['XLI00'], condition="LISTAT=' ' AND LIKZLI=1 AND LILINR=%s" % pad('LILINR', lieferantennr), limit=1, ua='husoftm2.lieferanten') if rows: row = rows[0] row['lieferantennr'] = add_prefix(row['lieferantennr'], 'SP') row['land'] = land2iso(row.pop('laenderkennzeichen')) return row return None
def _auftraege(additional_conditions=None, addtables=None, mindate=None, maxdate=None, limit=None, header_only=False, canceled=False): """ Alle Aufträge ermitteln `additional_conditions` kann eine Liste von SQL-Bedingungen enthalten, die die Auftragssuche einschränken. `mindate` & `maxdate` können den Anliefertermin einschränken. `limit` kann die Zahl der zurückgelieferten Aufträge einschraenken. Dabei werden groessere Auftragsnummern zuerst zurueck gegeben. `header_only` ruft nur Auftragsköpfe ab und ist bedeutend schneller `canceled` wenn True, werden auch stornierte Aufträge zurück gegeben. Rückgabewert sind dicts nach dem Lieferungprotokoll. Wenn header_only == True, werden nur Auftragsköpfe zurück gegeben, was deutlich schneller ist. """ # Solange der Client das nciht gesondert verlangt, werden stornierte Aufträge ignoriert. if not canceled: conditions = ["AKSTAT<>'X'"] else: conditions = [] # Anliefertermin ist ein Range if mindate and maxdate: conditions.append("AKDTER BETWEEN %s AND %s" % (date2softm(mindate), date2softm(maxdate))) # Anliefertermin ist nach unten begrenzt elif mindate: conditions.append("AKDTER > %s" % date2softm(mindate)) # Anliefertermin ist nach oben begrenzt elif maxdate: conditions.append("AKDTER < %s" % date2softm(maxdate)) # vom Aufrufer direkt angegebenen, weitere SQL Bedingungen zufügen. Diese werden mit `AND` verkettet. if additional_conditions: conditions.extend(additional_conditions) condition = " AND ".join(conditions) koepfe = {} kopftexte = {} auftragsnr_to_lieferadresse_kdnr = {} if addtables is None: addtables = [] # Köpfe und Adressen einlesen for kopf in query(['AAK00'] + addtables, ordering=['AKAUFN DESC'], condition=condition, joins=[('XKD00', 'AKKDNR', 'KDKDNR')], limit=limit, ua='husoftm2.auftraege'): d = dict(kundennr="SC%s" % kopf['kundennr_warenempf'], kundennr_rechnung="SC%s" % kopf['kundennr_rechnungsempf'], name1=kopf['name1'], name2=kopf['name2'], name3=kopf['name3'], strasse=kopf['strasse'], land=husoftm2.tools.land2iso(kopf['laenderkennzeichen']), plz=kopf['plz'], ort=kopf['ort'], auftragsnr="SO%s" % kopf['auftragsnr'], auftragsnr_kunde=kopf['auftragsnr_kunde'], erfassung=kopf.get('AAK_erfassung'), aenderung=kopf.get('AAK_aenderung', None), sachbearbeiter=husoftm2.sachbearbeiter.resolve(kopf['sachbearbeiter']), anliefertermin=kopf['liefer_date'], teillieferung_erlaubt=(kopf['teillieferung_erlaubt'] == 1), # TODO: md: ich denke, "erledigt" ist ein Auftrag auch, wenn er storneirt wurde, # oder wenn alle Positionen auf voll_ausgeliefert stehen. erledigt=(kopf['voll_ausgeliefert'] == 1), positionen=[], art=kopf['art'], storniert=(kopf['AAK_status'] == 'X')) koepfe[kopf['auftragsnr']] = d # Auftrag geht an die 'normale' Lieferadresse: Kein .\d\d\d-Suffix an die `lieferadresse.kundennr` if kopf['versandadressnr'] == 0: auftragsnr_to_lieferadresse_kdnr[kopf['auftragsnr']] = add_prefix(kopf['kundennr_warenempf'], 'SC') # Auftrag geht an eine abweichende Lieferadresse: .00?-Suffix an die `lieferadresse.kundennr` hängen. else: lieferadresse_kdnr = add_prefix("%s.%03d" % (kopf['kundennr_warenempf'], kopf['versandadressnr']), "SC") auftragsnr_to_lieferadresse_kdnr[kopf['auftragsnr']] = lieferadresse_kdnr if header_only: return koepfe.values() allauftrnr = koepfe.keys() # Texte auslesen # Die dritte und vierte Position des Werts von txt_auslesen sind posdaten und kopfdaten. # Es handelt sich dabei wohl um Texte, die nicht angedruckt werden sollen. # Bis auf weiteres werden diese hier ignoriert. postexte, kopftexte, _, _ = txt_auslesen(allauftrnr) while allauftrnr: # In 50er Schritten Auftragspositionen lesen und den 50 Aufträgen zuordnen batch = allauftrnr[:50] allauftrnr = allauftrnr[50:] # Abweichende Lieferadressen for row in query(['XAD00'], ua='husoftm2.auftraege', condition="ADAART=1 AND ADRGNR IN (%s)" % ','.join([str(x) for x in batch])): koepfe[row['nr']]['lieferadresse'] = dict(name1=row['name1'], name2=row['name2'], name3=row['name3'], strasse=row['strasse'], land=husoftm2.tools.land2iso(row['laenderkennzeichen']), plz=row['plz'], kundennr=auftragsnr_to_lieferadresse_kdnr[row['nr']], ort=row['ort']) # Positionen einlesen if not canceled: poscondition = "APSTAT<>'X' AND APAUFN IN (%s)" % ','.join([str(x) for x in batch]) else: poscondition = "APAUFN IN (%s)" % ','.join([str(x) for x in batch]) for row in query(['AAP00'], condition=poscondition, ua='husoftm2.auftraege'): d = dict(menge=int(row['bestellmenge']), lager="LG%s" % row['lager'], artnr=row['artnr'], liefer_date=row['liefer_date'], menge_offen=int(row['menge_offen']), fakturierte_menge=int(row['fakturierte_menge']), erledigt=(row['voll_ausgeliefert'] == 1), storniert=(row['AAP_status'] == 'X'), posnr=int(row['position']), _aenderung=row.get('AAP_aenderung'), _erfassung=row.get('AAP_erfassung'), _zuteilung=row.get('AAP_zuteilung'), # 'position': 2, # 'teilzuteilungsverbot': u'0', ) # Preis einfügen if row.get('verkaufspreis'): d['preis'] = row['verkaufspreis'] texte = postexte.get(row['auftragsnr'], {}).get(row['position'], []) texte, attrs = texte_trennen(texte) d['infotext_kunde'] = texte if 'guid' in attrs: d['guid'] = attrs['guid'] koepfe[row['auftragsnr']]['positionen'].append(d) # Kopftexte zuordnen for auftragsnr, texte in kopftexte.items(): texte, attrs = texte_trennen(texte) koepfe[remove_prefix(auftragsnr, 'SO')]['infotext_kunde'] = texte if 'guid' in attrs: koepfe[remove_prefix(auftragsnr, 'SO')]['guid'] = attrs['guid'] return koepfe.values()