def _get_umsatz(kundennr, jahr, kundenfeld): """Ermittle den Umsatz im gegebenen Jahr""" if isinstance(jahr, datetime.date): jahr = jahr.year elif isinstance(jahr, basestring): jahr = int(jahr) # Das ist deutlich schneller als ein IN-Operator in der eigentlichen Abfrage kunde = husoftm2.kunden.get_kunde(kundennr) if kunde['land'] == 'DE': ktonr = 85100 elif huTools.world.in_european_union(kunde['land']): ktonr = 82100 else: ktonr = 81100 conditions = ['BUJJBU=%d' % (jahr - 2000), # Keinen Kommentar zu SoftM! 'BUGKTO=%s' % pad('BUGKTO', ktonr), 'BUPKTO=%s' % pad('BUPKTO', remove_prefix(kundennr, 'SC')), ] rows = query(tables=['BBU00'], fields=['BUSOHA', 'SUM(BUNEBT)'], grouping=['BUSOHA'], querymappings={'BUSOHA': 'art', 'SUM(BUNEBT)': 'umsatz'}, condition=' AND '.join(conditions), ua='husoftm2.umsatz.get_umsatz', cachingtime=86400) umsatz = decimal.Decimal() for row in rows: if row['art'] == 'H': umsatz -= decimal.Decimal(row['umsatz']) elif row['art'] == 'S': umsatz += decimal.Decimal(row['umsatz']) return umsatz
def abgabepreis_kunde(artnr, kundennr, auftragsdatum=None): """ Verkaufspreis für einen Artikel in Abhängigkeit von kundennr und Auftragsdatum ermitteln. Höchste Priorität hat der für einen Kunden hinterlegt Preis. Zweithöchste Priorität hat der für die Preisliste (Kundengruppe) hinterlegte Preis Niedrigste Priorität hat der Listenpreis aus den Artikelstammdaten. Rückgabe ist tuple mit Preis und Herkunft des Preises. >>> abgabepreis_kunde('04711', 99954) (1500, 'Preisliste 95') >>> abgabepreis_kunde('04711', 98000) (1400, 'Listenpreis') >>> abgabepreis_kunde('04711', 94763) (1300, 'Kundenpreis') """ if not auftragsdatum: auftragsdatum = datetime.date.today() # Kundennr als Zeichenkette kundennr = remove_prefix(kundennr, 'SC') date_str = sql_quote(date2softm(auftragsdatum)) # 1. Preis für Kunde hinterlegt? conditions = ["PNSANR=PRSANR", "PRANW='A'", "PRSTAT=' '", "PNSTAT=' '", "PRARTN=%s" % sql_quote(artnr), "PRDTBI>=%s" % date_str, "PRDTVO<=%s" % date_str, ] condition_kunde = conditions + ["PRKDNR=%s" % pad('PRKDNR', kundennr)] rows = query(['XPN00', 'XPR00'], fields=['PNPRB'], condition=' AND '.join(condition_kunde), ordering='PRDTVO', limit=1) if rows: return (int(rows[0][0] * 100), 'Kundenpreis') # 2. Preis aus Preislistennr. des Kunden ermitteln condition_gruppe = conditions + [ # "PRPRLK = %s" % sql_quote(kunde['kunden_gruppe']), "KDKDNR=%s" % pad('KDKDNR', kundennr), "PRPRLK=KDKGRP" ] rows = query(['XPN00', 'XPR00', 'XKD00'], fields=['PNPRB', 'PRPRLK'], ordering='PRDTVO', condition=' AND '.join(condition_gruppe), limit=1) if rows: return (int(rows[0]['preis'] * 100), 'Preisliste %s' % rows[0]['preisliste_kunde']) # 3. Listenpreis aus Artikelstammdaten return (listenpreis(artnr), 'Listenpreis')
def kundenpreise(kundennr, gueltig_von=None, gueltig_bis=None): """Alle kundenspezifischen Preis für einen Kunden""" kundennr = remove_prefix(kundennr, 'SC') conditions = ["PNSANR=PRSANR", "PRANW='A'", "PRSTAT=' '", "PNSTAT=' '", "PRKDNR=%s" % pad('PRKDNR', kundennr) ] if gueltig_von: conditions.append("PRDTVO>=%s" % sql_quote(date2softm(gueltig_von))) if gueltig_bis: conditions.append("PRDTBI>=%s" % sql_quote(date2softm(gueltig_bis))) rows = query(tables=['XPN00', 'XPR00'], fields=['PRARTN', 'PNPRB', 'PRDTVO', 'PRDTBI', 'PRSANR'], condition=' AND '.join(conditions), ordering='PRDTVO' ) preise = {} for row in rows: preise[row['artnr']] = dict(preis=int(row['preis'] * 100), gueltig_von=row.get('gueltig_ab_date'), gueltig_bis=row.get('gueltig_bis_date'), satznr=str(row['satznr_xpr00'])) return preise
def offene_auftraege_kunde(kundennr, limit=None, header_only=False, canceled=False): """Alle nicht abgeschlossene Aufträge für eine Kundennummer ermitteln. Gibt eine Liste von dict()s zurück. Wenn `canceled == False` werden keine stornierten Aufträge und Positionen zurückgegeben.""" kundennr = remove_prefix(kundennr, 'SC') auftraege = _auftraege(["AKKDNR=%s" % pad('AKKDNR', kundennr), "AKKZVA=0"], limit=limit, header_only=header_only, canceled=canceled) return auftraege
def fertige_auftraege_kunde(kundennr, limit=None, header_only=False, canceled=False): """Alle abgeschlossene Aufträge für eine Kundennummer ermitteln. Gibt eine Liste von dict()s zurück. Wenn `canceled == False` werden keine stornierten Aufträge und Positionen zurückgegeben.""" kundennr = remove_prefix(kundennr, 'SC') # dies mag stornierte Aufträge übersehen - hab ich bisher nicht überprüft auftraege = _auftraege(["AKKDNR=%s" % pad('AKKDNR', kundennr), "(AKKZVA=1 OR AKSTAT='X')"], limit=limit, header_only=header_only, canceled=canceled) return auftraege
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 auftraege_kunde(kundennr, limit=None, header_only=False, canceled=False): """Alle Aufträge für eine Kundennummer ermitteln. Gibt eine Liste von dict()s zurück. Wenn `canceled == False` werden keine stornierten Aufträge und Positionen zurückgegeben.""" conditions = [] if '.' in kundennr: kundennr, adressindex = kundennr.split('.') conditions.append("AKVANR=%d" % int(adressindex)) kundennr = remove_prefix(kundennr, 'SC') conditions.append("AKKDNR=%s" % pad('AKKDNR', kundennr)) auftraege = _auftraege(conditions, limit=limit, header_only=header_only, canceled=canceled) return auftraege
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 abgabepreise_kunde(artnrs, kundennr, auftragsdatum=None): """ Verkaufspreis für einen oder mehrere Artikel in Abhängigkeit von kundennr und Auftragsdatum ermitteln. Der Rückgabewert ist ein dict mit den ArtNr. als Schlüssel. Die Werte sind Preisinformationen als Tupel (Preis, Herkunft) oder None, falls zu der ArtNr. kein Preis ermittelt werden konnte. Die Logik funktioniert genau wie bei abgabepreis_kunde: Es werden zuerst kundenspezifische Preise, dann kundengruppen-spezifische Preise und als letztes Listenpreise ermittelt. """ warnings.warn("use `cs.salesforce.preise` instead!", DeprecationWarning, stacklevel=2) if not auftragsdatum: auftragsdatum = datetime.date.today() artnrs = set(artnrs) kundennr = remove_prefix(kundennr, 'SC') date_str = sql_quote(date2softm(auftragsdatum)) abgabepreise = {} # 1. Preise für Kunden hinterlegt? conditions = ["PNSANR=PRSANR", "PRANW='A'", "PRPRLK<>''" "PRSTAT=' '", "PNSTAT=' '", "PRDTBI>=%s" % date_str, "PRDTVO<=%s" % date_str, ] condition_kunde = conditions + ["PRKDNR=%s" % sql_quote("%8s" % kundennr), "PRARTN IN (%s)" % ",".join([sql_quote(artnr) for artnr in artnrs])] rows = query(tables=['XPN00', 'XPR00'], fields=['PRARTN', 'PNPRB'], condition=' AND '.join(condition_kunde), ordering='PRDTVO') for row in rows: if row['artnr'] in artnrs: artnrs.remove(row['artnr']) abgabepreise[row['artnr']] = (int(row['preis'] * 100), u'Kundenpreis') if not artnrs: return abgabepreise # 2. Preise aus Preislistennr. des Kunden ermitteln condition_gruppe = conditions + [ # "PRPRLK = %s" % sql_quote(kunde['kunden_gruppe']), "PRARTN IN (%s)" % ",".join([sql_quote(artnr) for artnr in artnrs]), "KZKDNR=%s" % pad('KZKDNR', kundennr), "PRPRLK=KZPREL" ] rows = query(tables=['XPN00', 'XPR00', 'AKZ00'], fields=['PRARTN', 'PNPRB', 'PRPRLK'], condition=' AND '.join(condition_gruppe), ordering='PRDTVO') for row in rows: if row['artnr'] in artnrs: artnrs.remove(row['artnr']) abgabepreise[row['artnr']] = (int(row['preis'] * 100), u'Preisliste %s' % row['preisliste_kunde']) if not artnrs: return abgabepreise # 3. Listenpreis aus Artikelstammdaten for artnr, preis in listenpreise(artnrs).iteritems(): if artnr in artnrs: artnrs.remove(artnr) abgabepreise[artnr] = (preis, u'Listenpreis') for artnr in artnrs: abgabepreise[artnr] = None return abgabepreise
def auftraege_kunde(kundennr, limit=None, header_only=False): """Alle Aufträge für eine Kundennummer ermitteln. Gibt eine Liste von dict()s zurück.""" kundennr = remove_prefix(kundennr, 'SC') auftraege = _auftraege(["AKKDNR=%s" % pad('AKKDNR', kundennr)], limit=limit, header_only=header_only) return auftraege