コード例 #1
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
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
コード例 #2
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
def verfuegbare_mengen(lager=0):
    """Gibt die aktuell verfügbaren Mengen aller Artikel eines Lagers zurück. Siehe auch besteande().

    >>> verfuegbare_mengen(34)
    {'10106': 6,
     '12551': 2854,
     ...
     '83165': 598}
    """

    rows = get_connection().query('XLF00', grouping=['LFARTN'], querymappings={},
                                  fields=['LFARTN', 'SUM(LFMGLP)', 'SUM(LFMGK4)', 'SUM(LFMGLP-LFMGK4)'],
                                  condition="LFLGNR=%s AND LFMGLP<>0 AND LFSTAT<>'X'" % sql_escape(lager))
    return dict([(str(artnr), as400_2_int(menge) - as400_2_int(lfmgk4))
                 for (artnr, menge, lfmgk4, dummy) in rows])
コード例 #3
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
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])
コード例 #4
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
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])
コード例 #5
0
ファイル: artikel.py プロジェクト: mdornseif/huSoftM
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
コード例 #6
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
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
コード例 #7
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
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
コード例 #8
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
def besteande(lager):
    """Ermittelt den Lagerbestand (Buchbestand + in diesem Lager eintreffene Güter) aller Artikel am Lager.

    >>> bestaende(100)
    {'01013': 61,
     '01020': 96,
     '01022': 2197,
     '01023': 1000,
     '01104': 110,
     '01104/01': 502,
     ...
     'WK83162': 380,
     'WK84020': 68}
     """

    rows = get_connection().query('XLF00', fields=['LFARTN', 'LFMGLP'],
               condition="LFLGNR=%d AND LFMGLP<>0 AND LFSTAT<>'X'" % (int(lager)))
    bbesteande = dict([(str(row[0]), as400_2_int(row[1])) for row in rows])

    # Offene Umlagerungen an dieses Lager zurechnen.
    uml = umlagermengen(anlager=lager)
    for artnr, umlagerungsmenge in uml.items():
        bbesteande[str(artnr)] = bbesteande.get(artnr, 0) + as400_2_int(umlagerungsmenge)
    return bbesteande
コード例 #9
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
def auftragsmengen_alle_artikel(lager=0, umlagerungen=False):
    """Liefert eine Liste offener Aufträge aller Artikel.

    Per default OHNE UMLAGERUNGEN.

    >>> auftragsmengen_alle_artikel(34)
    {'14550': {datetime.date(2008, 11, 30): 3450,
               datetime.date(2008, 12, 1): 8,
               datetime.date(2008, 12, 15): 5056},
     '14565': {datetime.date(2009, 2, 9): 750,
               datetime.date(2009, 3, 23): 1008,
               datetime.date(2009, 4, 27): 625},
     '14566': {datetime.date(2009, 2, 2): 4000,
               datetime.date(2009, 6, 1): 400},
     '14635': {datetime.date(2008, 11, 19): 20,
               datetime.date(2008, 11, 24): 763,
               datetime.date(2008, 11, 27): 200}}
    """

    condition = (
    "AKAUFN=APAUFN"
    " 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 not umlagerungen:  # kein Umlagerungsauftrag:
        condition += " AND AKAUFA<>'U'"

    if lager:
        # Achtung, hier gibt es KEIN Lager 0 in der Tabelle. D.h. APLGNR=0 gibt nix
        condition += " AND APLGNR=%d" % lager
    rows = get_connection().query(['AAP00', 'AAK00'],
            fields=['APARTN', 'APDTLT', 'SUM(APMNG-APMNGF)'],
            condition=condition,
            ordering='APDTLT', grouping=['APARTN', 'APDTLT'],
            querymappings={'SUM(APMNG-APMNGF)': 'menge_offen', 'APARTN': 'artnr', 'APDTLT': 'liefer_date'})
    ret = {}
    for row in rows:
        if row['menge_offen']:
            ret.setdefault(str(row['artnr']), {})[row['liefer_date']] = as400_2_int(row['menge_offen'])
    return ret
コード例 #10
0
ファイル: bestaende.py プロジェクト: mdornseif/huSoftM
def buchbestaende(lager=0):
    """Gibt den Buchbestand aller Artikel für ein Lager zurück oder (lager=0) für alle Lager

    >>> buchbestaende()
    {'01012': 1.0,
     '01013': 246.0,
     '01020': 395.0,
     '01022': 2554.0,
     '01023': 7672.0,
     '01104': 109.0,
     '01104/01': 758.0,
     '01105': 203.0,
     '01105/01': 799.0,
     '01106/01': 1012.0}

    """

    rows = get_connection().query('XLF00', fields=['LFARTN', 'SUM(LFMGLP)'], grouping=['LFARTN'],
               condition="LFLGNR=%d AND LFMGLP<>0 AND LFSTAT<>'X'" % (int(lager)))
    return dict([(str(artnr), as400_2_int(quantity)) for artnr, quantity in rows])
コード例 #11
0
ファイル: artikel.py プロジェクト: mdornseif/huSoftM
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