Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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]
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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()