Ejemplo n.º 1
0
def get_artikel(artnr=None, ean=None):
    """Returns articles for artnr and/or ean, depending on what parameter is not None.

    Use both parameters if ean is not unique, like in the following example.
    This function can be used to check if an EAN and article number fit to each other.

    Non-unique example:
    >>> a = get_artikel(artnr='76095')
    >>> b = get_artikel(artnr=None, ean=a.ean)
    RuntimeError: Ergebnis nicht eindeutig für: Artnr None && EAN 4005998760956L"""

    cond1 = "ARARTN=%s" % sql_quote(artnr)
    cond2 = "AREAN=%s" % sql_quote(ean)
    if artnr and ean:
        condition = cond1 + " AND " + cond2
    elif artnr:
        condition = cond1
    elif ean:
        condition = cond2
    else:
        raise RuntimeError("Artikelabfrage ohne EAN und Artnr nicht möglich.")

    rows = get_connection().query(['XAR00'], condition=condition)
    rowcount = len(rows)
    if rowcount > 1:
        raise RuntimeError("Ergebnis nicht eindeutig für: Artnr %r && EAN %r" % (artnr, ean))
    elif rowcount == 0:
        return None
    return Artikel().fill_from_softm(rows[0])
Ejemplo n.º 2
0
def get_zugaenge_warenvereinnahmungsnr_simple(bestellnr, warenvereinnahmungsnr):
    """Liefert alle Warenzugaenge zu einer Bestellnummer und zug. Warenvereinnahmungsnummer.

    Sammelt *nicht* alle Daten zu einer Bestellung, sondern nur die jeweils gelieferten Positionen.
    """
    rows = get_connection().query('EWZ00', condition="WZBSTN=%s and WZWVNR=%s" %
                                  (sql_quote(bestellnr), sql_quote(warenvereinnahmungsnr)))
    return rows
Ejemplo n.º 3
0
def get_guid(auftragsnr):
    """
    Gibt den GUID zu einer Auftragsnr zurück, sofern vorhanden.
    """
    warnings.warn("husoftm.auftraege is deprecated, use husoftm2.auftraege instead",
                  DeprecationWarning, stacklevel=2)
    condition = "ATTX60 LIKE %s AND ATAUFN = %s AND ATAUPO = 0 AND ATTART = 8" % (sql_quote("#:guid:%%"),
                                                                                  sql_quote(auftragsnr))
    rows = get_connection().query('AAT00', fields=['ATTX60'], condition=condition)
    if rows:
        return rows[0][0].replace('#:guid:', '')
    return ''
Ejemplo n.º 4
0
def abgabepreisbasis(artnr):
    """Gibt eine Liste mit den durchschnittlichen Rechnungspreisen pro Monat zurück.

    Liefert eine Liste von 4-Tuples
    (datum, AVG(preis), menge, gesammtpreis)

    [ ...
    (datetime.date(2009, 2, 10), 32.95, 2, 65.90),
    (datetime.date(2009, 10, 19), 17.44, 2, 34.88)]
    """

    condition = (
    "FKRGNR=FURGNR"             # JOIN
    " AND FKAUFA<>'U'"          # Keine Umlagerung
    " AND FKSTAT<>'X'"          # nicht gelöscht
    " AND FKDTFA > 0"           # Druckdatum nicht leer
    " AND FUKZRV=2"             # ?
    " AND FURGNI<>0"            # ?
    " AND FKFORM=' '"           # ?
    " AND FURGNR<>0"            # es gibt eine Rechnungsnummer
    " AND FUPNET>0"             # keine Gutschriften
    " AND FKMJBU>'10412'"       # keine legacy Daten
    " AND FUARTN=%s")           # nur bestimmten Artikel beachten

    rows = get_connection().query(['AFU00', 'AFK00'], fields=['FKDTFA', 'SUM(FUMNG)', 'SUM(FUPNET)', 'COUNT(FKRGNR)'],
                   condition=condition % (sql_quote(artnr)),
                   ordering='FKDTFA', grouping='FKDTFA',
                   querymappings={'SUM(FUMNG)': 'menge', 'SUM(FUPNET)': 'nettopreis', 'COUNT(FKRGNR)': 'rechnungen', 'FKDTFA': 'rechnung_date'})
    ret = []
    for row in rows:
        menge = as400_2_int(row['menge'])
        if menge:
            ret.append((row['rechnung_date'], float(row['nettopreis']) / float(row['menge']), menge, float(row['nettopreis'])))
    ret.sort()
    return ret
Ejemplo n.º 5
0
def bestellmengen(artnr, lager=0):
    """Liefert eine liste mit allen Bestellten aber noch nicht gelieferten Wareneingängen.

    >>> bestellmengen('14865')

    {datetime.date(2009, 2, 20): 1200,
     datetime.date(2009, 5, 5): 300}
    """
    condition = "BPSTAT<>'X' AND BPKZAK=0 AND BPARTN=%s" % sql_quote(artnr)
    if lager:
        condition += "AND BPLGNR=%s" % sql_quote(lager)
    # detailierte Informationen gibts in EWZ00
    rows = get_connection().query('EBP00', fields=['BPDTLT', 'SUM(BPMNGB-BPMNGL)'], ordering='BPDTLT',
                                  grouping='BPDTLT', condition=condition)
    return dict([(x['liefer_date'], as400_2_int(x['SUM(BPMNGB-BPMNGL)']))
                 for x in rows if as400_2_int(x['SUM(BPMNGB-BPMNGL)']) > 0])
Ejemplo n.º 6
0
def auftragsmengen(artnr, lager=None):
    """Liefert eine Liste offener Aufträge für einen Artikel OHNE UMLAGERUNGEN.

    >>> auftragsmengen(14865)
    {datetime.date(2009, 3, 2): 340,
     datetime.date(2009, 4, 1): 300,
     datetime.date(2009, 5, 4): 260,
     datetime.date(2009, 6, 2): 300}
    """

    condition = (
    "AKAUFN=APAUFN"
    " AND AKAUFA<>'U'"                # kein Umlagerungsauftrag
    " AND APARTN=%s"                  # Artikelnummer
    " AND APSTAT<>'X'"                # Position nicht logisch gelöscht
    " AND APKZVA=0"                   # Position nicht als 'voll ausgeliefert' markiert
    " AND (APMNG-APMNGF) > 0"  # (noch) zu liefernde menge ist positiv
    " AND AKSTAT<>'X'"                # Auftrag nicht logisch gelöscht
    " AND AKKZVA=0")                  # Auftrag nicht als 'voll ausgeliefert' markiert

    if lager:
        # Achtung, hier gibt es KEIN Lager 0 in der Tabelle. D.h. APLGNR=0 gibt nix
        condition = condition + (" AND APLGNR=%d" % lager)
    rows = get_connection().query(['AAP00', 'AAK00'], fields=['APDTLT', 'SUM(APMNG-APMNGF)'],
                   condition=condition % (sql_quote(artnr)),
                   ordering='APDTLT', grouping='APDTLT',
                   querymappings={'SUM(APMNG-APMNGF)': 'menge_offen', 'APDTLT': 'liefer_date'})
    return dict([(x['liefer_date'], as400_2_int(x['menge_offen'])) for x in rows if x['menge_offen'] > 0])
Ejemplo n.º 7
0
def umlagermenge(artnr, anlager=100):
    """Ermittelt wieviel Umlagerungen für einen Artikel der nach anlager unterwegs sind.

    Rueckgabe:
     - Wenn eine Artikelnummer angegeben wird, dann eine Menge als int
    """

    # Das Auslieferungslager steht in AKLGN1, Das Ziellager steht in AKLGN2
    # In APLGNR steht AUCH das Auslieferungslager
    tables = ['AAP00', 'AAK00']
    conditions = [
        "APARTN=%s" % sql_quote(artnr),
        "AKLGN2=%d" % int(anlager),   # Zugangslager
        "AKAUFN=APAUFN",
        "AKAUFA='U'",                 # Umlagerungsauftrag
        "APSTAT<>'X'",                # Position nicht logisch gelöscht
        "APKZVA=0",                   # Position nicht als 'voll ausgeliefert' markiert
        #"(APMNG-APMNGF-APMNGG) > 0"  # (noch) zu liefernde menge ist positiv
        "AKSTAT<>'X'",                # Auftrag nicht logisch gelöscht
        "AKKZVA=0"]                   # Auftrag nicht als 'voll ausgeliefert' markiert

    rows = query(tables=tables, fields=['SUM(APMNG)'], querymappings={}, condition=' AND '.join(conditions))
    if rows and rows[0] and rows[0][0]:
        return as400_2_int(rows[0][0])
    return 0
Ejemplo n.º 8
0
def verkaufspreis(artnr, kundennr, bestelldatum=datetime.date.today()):
    """
    Verkaufspreis in Abh. von kundennr und artnr ermitteln.

    Höchste Priorität hat der für einen Kunden hinterlegt Preis.
    Zweithöchste Prio hat der für die Preisliste (Kundengruppe) hinterlegte Preis
    Niedrigste Prio hat der Listenpreis aus den Artikelstammdaten.

    Rückgabe ist ein dict mit Preis und Herkunft des Preises.

    >>> verkaufspreis('04711', 99954)
    {'preis': Decimal('14.00'), 'herkunft': 'Preisliste 95'}

    >>> verkaufspreis('04711', 98000)
    {'preis': Decimal('13.65'), 'herkunft': 'Listenpreis'}

    >>> verkaufspreis('04711', 94763)
    {'preis': Decimal('13.00'), 'herkunft': 'Kundenpreis'}

    """

    # Kundennr als Zeichenkette
    kundennr_str = sql_quote("%8s" % int(kundennr))
    date_str = sql_quote(date2softm(bestelldatum))
    artnr_str = sql_quote(artnr)

    # 1. Preis für Kunde hinterlegt?
    condition = ("PNSANR=PRSANR and PRANW='A' and PRSTAT=' ' and PNSTAT=' ' AND "
                 "PRARTN = %s and PRDTBI >= %s AND PRDTVO <= %s" % (artnr_str, date_str, date_str))

    condition_kunde = condition + " AND PRKDNR = %s" % kundennr_str
    rows = get_connection().query(['XPN00', 'XPR00'], fields=["PNPRB"], ordering='PRDTVO', condition=condition_kunde)

    if rows:
        return dict(preis=rows[0][0], herkunft='Kundenpreis')

    # 2. Preis aus Preislistennr. des Kunden ermitteln
    kdgruppe = get_connection().query('XXA00', fields='XAKGRP', condition='XAKDNR = %s' % kundennr_str)
    if kdgruppe and kdgruppe[0][0]:
        kdgruppe = kdgruppe[0][0]
        condition_gruppe = condition + " AND PRPRLK = %s" % sql_quote(kdgruppe)
        rows = get_connection().query(['XPN00', 'XPR00'], ordering='PRDTVO', condition=condition_gruppe)
        if rows:
            return dict(preis=rows[0]['preis'], herkunft='Preisliste %s' % kdgruppe)

    # 3. Listenpreis aus Artikelstammdaten
    return dict(preis=preis(artnr), herkunft='Listenpreis')
Ejemplo n.º 9
0
def kommibelege_for_auftrag(auftragsnr):
    """Return all Kommibeleg objects for a given auftragsnr"""

    warnings.warn("husoftm.lieferscheine is deprecated, use husoftm2.lieferscheine instead",
                  DeprecationWarning, stacklevel=2)
    conditions = ["LKAUFS = %s" % sql_quote(auftragsnr), "LKLFSN = 0"]
    condition = " AND ".join(conditions)
    rows = get_connection().query(["ALK00"], condition=condition)
    return [Kommibeleg(row['kommissionierbelegnr']) for row in rows]
Ejemplo n.º 10
0
def auftragsnr_to_rechnungsnr(auftragsnr):
    """Liefert eine Liste mit Rechnungsnummern zurück, die zu einer Auftragsnummer gehören.

    Die Nummern werden gemäss https://cybernetics.hudora.biz/intern/trac/wiki/NummernKreise
    mit dem Prefix RG zurückgegeben."""

    rows = get_connection().query(['AFK00'], fields=['FKRGNR'],
                   condition="FKAUFN = %s" % (sql_quote(auftragsnr)))
    return [("RG%s" % r[0]) for r in rows]
Ejemplo n.º 11
0
def _umlagermenge_helper(artnr, lager=100):
    """ Ermittelt wieviel Umlagerungen für einen oder alle Artikel unterwegs sind.

    Parmeter:
     - artnr - 0 oder None -> alle Artikel, die sich in der Umlagerung befinden auflisten,
               sonst die gesuchte Artikelnummer
     - lager - Das Lager, an das die Umlagerungen unterwegs sind (default 100)

    Rueckgabe:
     - Wenn eine Artikelnummer angegeben wird, dann eine Menge als int
     - Wenn keine Artikelnummer angegeben wird, dann alle Artikeln die sich
       zu dem gegebenen Zugangslager (lager) unterwegs sind.
    """

    # This is just a private helper funcion, which should only be called by umlagermenge and
    # umlagermengen. The reason therefore is, that this function has different return types, depending
    # on the artnr you provide. umlagermenge and umlagermengen are wrappers around this function.

    # Das Auslieferungslager steht in AKLGN1, Das Ziellager steht in AKLGN2
    # In APLGNR steht AUCH das Abgangslager

    tables = ['AAP00', 'AAK00']
    condition = (
    "AKAUFN=APAUFN"
    " AND AKAUFA='U'"                 # Umlagerungsauftrag
    " AND APSTAT<>'X'"                # Position nicht logisch gelöscht
    " AND APKZVA=0"                   # Position nicht als 'voll ausgeliefert' markiert
    #" AND (APMNG-APMNGF-APMNGG) > 0"  # (noch) zu liefernde menge ist positiv
    " AND AKSTAT<>'X'"                # Auftrag nicht logisch gelöscht
    " AND AKKZVA=0")                 # Auftrag nicht als 'voll ausgeliefert' markiert
    fields = ['SUM(APMNG)']
    grouping = []

    if lager:
        # Zugangslager
        condition += " AND AKLGN2=%d" % int(lager)

    if artnr:
        # Artikelnummer
        condition += " AND APARTN=%s" % sql_quote(artnr)
    else:
        fields.insert(0, 'APARTN')
        grouping = ['APARTN']

    rows = get_connection().query(tables=tables, fields=fields, querymappings={}, condition=condition,
                                  grouping=grouping)

    if not artnr:
        # Wenn kein bestimmter Artikel abgefragt wird, dann das Abfrageergebnis in ein dict umwandeln
        ret = {}
        for artnr, menge in rows:
            ret[artnr] = as400_2_int(menge)
        return ret
    else:
        if rows and rows[0] and rows[0][0]:
            return as400_2_int(rows[0][0])
    return 0
Ejemplo n.º 12
0
def auftraege_for_kunde(kundennr, limit=None):
    """Alle Aufträge für eine Kundennummer ermitteln"""

    warnings.warn("husoftm.auftraege is deprecated, use husoftm2.auftraege instead",
                  DeprecationWarning, stacklevel=2)
    condition = "AKKDNR = %s" % sql_quote(pad('AKKDNR', kundennr))
    rows = get_connection().query('AAK00', ordering=['AKAUFN DESC', 'AKDTLT'],
                                  condition=condition, limit=limit)
    return rows
Ejemplo n.º 13
0
def auftraege_for_artnr(artnr, additional_conditions=None, limit=None):
    """Alle Aufträge zu einer Artikelnummer"""
    warnings.warn("husoftm.auftraege is deprecated, use husoftm2.auftraege instead",
                  DeprecationWarning, stacklevel=2)
    conditions = ['AAK00.AKAUFN = ALN00.LNAUFN', 'ALN00.LNARTN=%s' % sql_quote(artnr)]
    if additional_conditions:
        conditions.extend(additional_conditions)
    condition = " AND ".join(conditions)
    rows = get_connection().query(['AAK00', 'ALN00'], condition=condition,
                                  ordering=['AKAUFN DESC', 'AKDTLT'], limit=limit)
    return rows
Ejemplo n.º 14
0
def get_auftragnr(guid):
    """
    Gibt die Auftragsnr zu einem GUID zurück, sofern vorhanden.
    """

    warnings.warn("husoftm.auftraege is deprecated, use husoftm2.auftraege instead",
                  DeprecationWarning, stacklevel=2)
    condition = "ATTX60 = %s AND ATAUPO = 0 AND ATTART = 8" % sql_quote("#:guid:" + guid)
    rows = get_connection().query('AAT00', fields=['ATAUFN'], condition=condition)
    if rows:
        return rows[0][0]
    return None
Ejemplo n.º 15
0
def buchbestaende(artnrs=None, lager=0):
    """Gibt die Buchbestand einiger oder aller Artikels für ein Lager zurück oder (lager=0) für alle Lager

    >>> buchbestand(['14600/03'])
    {u'14600/03': 338}
    """
    conditions = ["LFLGNR=%d" % int(lager),
                  "LFMGLP<>0",
                  "LFSTAT<>'X'"]
    if artnrs:
        conditions += ["LFARTN IN (%s)" % ','.join([sql_quote(artnr) for artnr in artnrs])]
    rows = query(['XLF00'], fields=['LFARTN', 'LFMGLP'], condition=' AND '.join(conditions))
    return dict([(artnr, int(menge)) for (artnr, menge) in rows])
Ejemplo n.º 16
0
def name(lieferantennr):
    """Liefert den Namen zu einer Lieferantennummer zurück.

    >>> name('99999')
    'Blocklieferant'
    """
    assert isinstance(lieferantennr, basestring)

    rows = get_connection().query(['XXA00'],
        condition=("XASTAT=' ' and XALINR LIKE %s" % sql_quote('%%%s' % lieferantennr)))
    if rows:
        return rows[0]['name1']
    return None
Ejemplo n.º 17
0
def preis(artnr):
    """Gibt den (aktuellen) Listenpreis für einen Artikel zurück.

    >>> preis('04711')
    13.65
    """

    rows = get_connection().query('XAR00', fields=['ARPREV'],
                                  condition="ARARTN=%s AND ARSTAT<>'X'" % sql_quote(artnr))
    if rows:
        return _auf_zwei_stellen(rows[0][0])
    else:
        return 0
Ejemplo n.º 18
0
def buchbestand(artnr, lager=0):
    """Gibt den Buchbestand eines Artikels für ein Lager zurück oder (lager=0) für alle Lager

    >>> buchbestand('14600')
    2345

    """

    rows = get_connection().query('XLF00', fields=['LFMGLP'],
               condition="LFLGNR=%d AND LFARTN=%s AND LFMGLP<>0 AND LFSTAT<>'X'" % (int(lager),
                                                                                    sql_quote(artnr)))
    if rows:
        return as400_2_int(rows[0][0])
    return 0
Ejemplo n.º 19
0
def rechnungen_for_kunde(kundennr, mindate=None):
    """Liefert eine Liste mit Rechnungsnummern zurück.

    Dies sind allerdings nur Rechnungen, die aus der Warenwirtschaft faktiuriert wurden. 'Rechnungen'
    (eigentlich mauell erstellte offenene Forderungen) aus der Buchhaltung sind hier nicht berücksichtigt.
    Die Nummern werden gemäss https://cybernetics.hudora.biz/intern/trac/wiki/NummernKreise
    mit dem Prefix RG zurückgegeben.
    """
    conditions = ["FKKDNR=%s" % sql_quote(pad('FKKDNR', kundennr))]
    if mindate:
        conditions.append("FKDTER >= %s AND FKRGNR <> 0" % date2softm(mindate))
    rows = get_connection().query(['AFK00'], fields=['FKRGNR'],
                   condition=" AND ".join(conditions))
    return ["RG%s" % row[0] for row in rows if str(row[0]) != '0']
Ejemplo n.º 20
0
def lieferadresse(auftragsnr):
    """Lieferadresse für Auftrag ermitteln"""

    warnings.warn("husoftm.auftraege is deprecated, use husoftm2.auftraege instead",
                  DeprecationWarning, stacklevel=2)
    conn = get_connection()
    # Gibt es eine abweichende Lieferadresse?
    condition = "ADAART = 1 AND ADRGNR=%s " % sql_quote(auftragsnr)
    rows = conn.query('XAD00', condition=condition)

    # if len(rows) > 1:
    #     raise RuntimeError("Es gibt mehr als eine abweichende Lieferadresse für Auftrag %s" % auftragsnr)
    # elif len(rows) == 1:
    #     return rows[0]
    if len(rows) > 0:
        return rows[0]

    condition = "AKAUFN=%s AND AKKDNR = KDKDNR" % sql_quote(auftragsnr)
    rows = conn.query(['AAK00', 'XKD00'], condition=condition,
                      fields=['KDNAME', 'KDNAM2', 'KDNAM3', 'KDNAM4', 'KDSTR', 'KDPLZ', 'KDORT', 'KDLKZ'])
    if len(rows) != 1:
        raise RuntimeError('inkonsistente Kopfdaten in AAK00 für Auftragsnr %s' % auftragsnr)

    return rows[0]
Ejemplo n.º 21
0
def verfuegbare_menge(artnr, lager=0):
    """Gibt die aktuell verfügbare Menge eines Artikels an einem Lager zurück oder (lager=0) für alle Lager

    Achtung! Die verfügbare Menge ist nicht die "freie Menge".

    >>> verfuegbare_menge('12345')
    3456
    """

    rows = get_connection().query('XLF00', fields=['LFMGLP', 'LFMGK4'],
               condition="LFLGNR=%s AND LFARTN=%s AND LFMGLP<>0 AND LFSTAT<>'X'" % (
                    sql_escape(lager), sql_quote(artnr)))
    if rows:
        (menge, lfmgk4) = rows[0]
        return as400_2_int(menge) - as400_2_int(lfmgk4)
    else:
        return 0
Ejemplo n.º 22
0
def versandart(vart, anwendung="A"):
    """Gibt die Kurz- und Bezeichnung einer Versandart wieder.

    >>> versandart(11)
    ('DPD/Danzas EXW', 'DPD/Danzas unfrei/EXW')
    >>> versandart(14)
    ('Cretschmar', 'Cretschmar Cargo')

    """
    vart = "%03d" % int(vart)
    condition = "TYFNR <> '' AND TYANW = %s AND TYVSAR = %s" % (sql_quote(anwendung), sql_quote(vart))
    rows = get_connection().query("XTY00", condition=condition)
    if len(rows) == 0:
        return "", ""

    if len(rows) > 1:
        print "Achtung: mehr als eine passende Versandart:", rows
    return rows[0]["kurzbezeichnung"], rows[0]["bezeichnung"]
Ejemplo n.º 23
0
def get_bestellungen_artnr(artnr):
    """Liefert alle Warenzugaenge einer Artikelnummer."""

    # BZT00 - zusatztexte
    positionen = query(['EBP00', 'EBL00'], ordering=['BPDTLT'],
        condition="BLBSTN=BPBSTN AND BLSTAT<>'X' AND BPSTAT<>'X' AND BPARTN=%s" % sql_quote(artnr))
    ret = []
    for position in positionen:
        position['_zugaenge'] = [x for x in get_zugaenge_bestellnr(position['bestellnr'])
                                     if x['artnr'] == artnr]
        for zugang in position['_zugaenge']:  # Buchungsdaten
            buchungen = query('BBU00',
                condition='BUBELN=%s' % sql_escape(zugang['rechnungsnr']))
            zugang['_fibubuchungen'] = kursfaktorkorrektur(buchungen, umdrehen=False)
        position['_lager_stapelschnittstelle'] = query(
            'ESL00', condition="SLBSTN=%s AND SLBSTP=%s AND SLARTN=%s"
            % (sql_escape(position['bestellnr']), sql_escape(position['bestellpos']), sql_escape(artnr)))
        ret.append(position)
    # ?: SELECT * FROM EWZ00 WHERE WZBSTN = 43072
    return kursfaktorkorrektur(ret)
Ejemplo n.º 24
0
def get_umschlag(artnr):
    """Gibt aufgeschlüsselt nach Datum zurück, wie viel Einheiten fakturiert wurden.

    >>> get_umschlag('14600')
    [(datetime.date(2005, 1, 25), 104),
     (datetime.date(2005, 1, 27), 8),
     ...
     (datetime.date(2008, 5, 29), 2),
     (datetime.date(2009, 2, 10), 2)]

    Achtung: Diese Funktion implementiert mehrere Tage caching.
    """

    # check if we have a cached result
    memc = caching.get_cache()
    cacheddata = memc.get('husoftm.umschlag.%r' % (artnr))
    if cacheddata:
        return cacheddata

    condition = (
    "FKRGNR=FURGNR"             # JOIN
    " AND FKAUFA<>'U'"          # Keine Umlagerung
    " AND FKSTAT<>'X'"          # nicht gelöscht
    " AND FKDTFA > 0"           # Druckdatum nicht leer
    " AND FUKZRV=2"             # ?
    " AND FURGNI<>0"            # ?
    " AND FKFORM=' '"           # ?
    " AND FURGNR<>0"            # es gibt eine Rechnungsnummer
    " AND FKMJBU>'10412'"       # keine legacy Daten
    " AND FUARTN=%s")           # nur bestimmten Artikel beachten

    rows = get_connection().query(['AFU00', 'AFK00'], fields=['FKDTFA', 'SUM(FUMNG)'],
                   condition=condition % (sql_quote(artnr)),
                   ordering='FKDTFA', grouping='FKDTFA',
                   querymappings={'SUM(FUMNG)': 'menge', 'FKDTFA': 'rechnung_date'})
    ret = [(x['rechnung_date'], as400_2_int(x['menge'])) for x in rows if x['menge'] > 0]

    memc.set('husoftm.umschlag.%r' % (artnr), ret, 60 * 60 * 24 * 6)  # 6 d
    return ret
Ejemplo n.º 25
0
def preisentwicklung(artnrs):
    """Ermittelt alle Preise für eine Liste von Artikelnummern.

    ACHTUNG: erwartet eine Liste von Artikelnummern. In der Regel will man die Preise
    für alle Versionen auf einmal ermitteln.

    >>> pprint(preisentwicklung(['77068', '77068/00'])[:4])
    [(datetime.date(2005, 9, 1),
      datetime.date(2006, 7, 3),
      '77068',
      (Decimal('0.06'), 'USD')),
     (datetime.date(2006, 7, 4),
      datetime.date(2007, 7, 24),
      '77068',
      (Decimal('0.07'), 'USD')),
     (datetime.date(2007, 7, 4),
      datetime.date(2008, 3, 31),
      '77068/00',
      (Decimal('0.07'), 'USD')),
     (datetime.date(2007, 7, 24),
      datetime.date(2008, 3, 31),
      '77068',
      (Decimal('0.12'), 'USD'))]
    """

    # common error: providing a string, not a list
    assert not isinstance(artnrs, basestring)

    artnrsstr = ','.join([sql_quote(artnr) for artnr in artnrs])
    rows = get_connection().query(['XPN00', 'XPR00'], ordering='PRDTVO',
        condition=("PNSANR=PRSANR and PRANW='E' and PRSTAT=' ' and PNSTAT=' '"
                   " and PRARTN IN (%s)" % artnrsstr))
    return [(row['gueltig_ab_date'],
             row['gueltig_bis_date'],
             row['artnr'],
             ((Decimal(str(row['preis'])).quantize(Decimal(10) ** -2)),
             row['waehrung'])) for row in rows]
Ejemplo n.º 26
0
def name(sachbearbeiternr):
    """Returns the name"""

    rows = get_connection().query('XSB00', fields=['SBNAME'], condition="SBSBNR = %s" % sql_quote(sachbearbeiternr))
    if len(rows) == 0:
        raise ValueError("Kein Sachbearbeiter mit Nummer %s" % sachbearbeiternr)
    return rows[0][0]
Ejemplo n.º 27
0
 def generate_insert_sql(self, fields, values):
     """Generate the SQL-string for executing a insert command."""
     return "INSERT INTO %s (%s) VALUES(%s)" % (self.tablename, fields,
                                                ','.join([sql_quote(x) for x in values]))
Ejemplo n.º 28
0
def get_artikel_by_ean(ean):
    """Returns all articles w/ given EAN."""
    condition = "AREAN=%s" % sql_quote(ean)
    rows = get_connection().query(['XAR00'], condition=condition)
    return [Artikel().fill_from_softm(row) for row in rows]
Ejemplo n.º 29
0
def find_text(text):
    """Durchsucht alle Auftragstexte nach 'text'.

    Rückgabewert ist eine Liste mit gefundenen Texten und dazugehörigen Auftragsnummern.

    Das ist ganz nützlich, wenn nach einem GUID gesucht werden soll:

    >>> find_text('EUDA4BGY')
    [{'auftragsnr': 1130969, 'text': 'Referenz: 0EUDA4BGYJCLT4VSNI2CP5XCPDQ'},
     {'auftragsnr': 1130970, 'text': 'Referenz: 1EUDA4BGYJCLT4VSNI2CP5XCPDQ'}]
    """
    warnings.warn("husoftm.auftraege is deprecated, use husoftm2.auftraege instead",
                  DeprecationWarning, stacklevel=2)
    rows = get_connection().query('AAT00', fields=['ATTX60', 'ATAUFN'], condition="ATTX60 LIKE %s" % sql_quote("%%%s%%" % text))
    return rows
Ejemplo n.º 30
0
def buchdurchschnittspreis(artnr):
    """Gibt den (aktuellen) Buchdurchschnittspreis für einen Artikel zurück.

    >>> buchdurchschnittspreis('04711')
    13.65
    """
    rows = get_connection().query('XLF00', fields=['LFPRBD'],
                                  condition="LFLGNR=0 AND LFARTN=%s AND LFSTAT<>'X'" % sql_quote(artnr))
    if rows:
        return _auf_zwei_stellen(rows[0][0])
    else:
        return Decimal()