Aktueller Wert meines Lagers mit Berücks. des Wechselkurses

Allgemeine Diskussionen um die ERP Software AvERP

Moderator: SYNERPY

Antworten
2mad
Beiträge: 79
Registriert: Fr Apr 15, 2005 8:52 am

Aktueller Wert meines Lagers mit Berücks. des Wechselkurses

Beitrag von 2mad »

Hi @all!

Ich würde gerne den aktuellen Warenwert meines Lagers nach Artikeln gruppiert abfragen. Da ich die Waren mit Fremdwährung zum derzeitigen Wechselkurs bestelle, brauche ich irgendeine Auswertung, die mir eine Zuweisung zu den jeweiligen EK-Bestellungen der Artikel und den dort angegebenen Preisen ausgibt.

Kann mir jemand sagen, wie ich das realisiere?

Danke und Gruß @all!
admin
Site Admin
Beiträge: 2673
Registriert: Di Feb 10, 2004 5:48 am
Wohnort: Bayreuth

Beitrag von admin »

Das ist schon eine etwas aufwändigere Statistik.

Hier müsste man alle entsprechenden Artikel durchgehen, den Lagerbestand holen und dann LIFO- oder FIFO-technisch die Bestellungen durchlaufen. Hier könnte man dann auf Grund der Rechnungseingänge den exakten Lagerwert bestimmen.
2mad
Beiträge: 79
Registriert: Fr Apr 15, 2005 8:52 am

Beitrag von 2mad »

Hallo admin!

Gibt es denn irgendeine Verknüpfung zwischen den Bestellugen/Rechnungen und den Artikeln im Lager?
Oder wie gehe ich das am Besten an?

Und wo/wie baue ich diese Statistik ein? Geht ja dann weit über einen simplen SQL-Query, den ich mir unter MIS->Statistiken ablegen könnte hinaus, oder?
tgvoelker
Beiträge: 47
Registriert: So Dez 11, 2005 11:52 am

Beitrag von tgvoelker »

Die Vorgehensweise ist relativ trivial, jedoch handelt es sich eher um ein betriebswirtschaftliches denn ein IT-Problem:

Zunächst muß geklärt werden, wie sich der der Lagerwert zusammensetzt. Dazu ist die Wahl einer Bewertungsmethode (historischer EHK, letzte EHK, gleitender Durchschnitt EHK, pauschal abgewertete EHK...) und ggf. die Wahl einer Lagerabgangsmethode notwendig (LiFo, FiFo, HiFo, LoFo...). Eine Lagerabgangsmethode muß immer dann gewählt werden, wenn die Bewertungsmethode historische Werte verwendet.

Aufpassen: bei Bewertungen für die KoRe haben Sie freie Hand, handelsrechtlich sind nur einige Kombinationen zulässig und steuerrechtlich noch weniger!

Entsprechend der Bewertungs-/Lagerabgangsmethode ergeben sich andere maßgebliche Preise für die Bewertung - eine feste "Verknüpfung" macht also keinen Sinn. Nehmen wir ein Beispiel, was sowohl handels- als auch steuerrechtlich grundsätzlich anerkannt ist: historische EHK mit LiFo.

Dabei wird unterstellt, daß immer das jeweils zuletzt im Lager eingegangene wieder abgeht.

Nehmen wir an: AnfBest 1000 AnfWert 10000
Wareneingang: 500 á 5500
Warenabgang: 200
EndBest: 1300, Endwert: 13300

Was wird also gerechnet:

Menge ist unkritisch: AB+Wareneingang-Warenabgang
Wert: AW+Wert Wareneingang-Entsprechend der jeweils letzten Wareneingänge bewerteter Warenabgang.

EDIT:
Folgendes könnte Ihnen bei den Hintergründen helfen:
Prinzip der Gewinnrealisation, Prinzip der Verlustantizipation, Prinzip der Bilanzwahrheit, Niederstwertprinzip (ergibt sich aus Gewinnrealisation und Verlustantizipation)
2mad
Beiträge: 79
Registriert: Fr Apr 15, 2005 8:52 am

Beitrag von 2mad »

Hallo tgvoelker!

Erstmal danke für die Antwort!
Bei uns handelt es sich um ein FiFo Lager und wir müssen/wollen/sollten ;) mit den tatsächlich bezahlten EKs inkl des damaligen Wechselkurses rechnen (der Wechselkurs soll auf der Statistik ebenfalls erscheinen...brauchen wir zu statistischen Zwecken).
Das Problem ist bei mir jedoch wirklich die technische Umsetzung.
Meine Vorgehensweise wäre folgendermaßen (unterbrechen Sie mich, wenn ich falsch liege ;)):

Ich setze voraus, daß für sämtliche Ware auf Lager bereits eine Rechnung gestellt und gebucht wurde. Nur so kann ich die Ausgabe des korrekten Wechselkurses und der tatsächlichen Einkaufspreise sicherstellen.

1. Schauen, welche Artikel im Lager sind - soweit kein Problem.
2. die LETZTEN Wareneingänge dieser Artikel finden (da FiFo) und die Rechnungen so zerpflücken, daß ich nur die EK-Beträge der gesuchten Artikel zurückbekomme.
Da gibt es für mich schon ein Problem (siehe P2).
3. Alles schön gruppieren und ausgeben.

P2:
Hier können ja generell 3 Fälle eintreten:
1. Die Anzahl eines besitmmten Artikels auf Lager stimmt mit der einer Rechnung überein. Das wäre super, dann kann ich den Wert und den Wechselkurs eifnach 1:1 zurückgeben.
2. Die Anzahl auf Lager ist kleiner als die der Bestellung. Auch kein Problem..
3. Die Anzahl auf Lager ist größer als die in der letzten Bestellung. Dann muss ich die nächste Bestellung dieses Artikels suchen und dort schauen, ob der Wechselkurs der gleiche war wie bei der ersten. ist dies der Fall addiere ich die Anzahl der ersten und den Übertrag der Artikel.
Wenn nicht muss ich die zweite Bestellung quasi neu Gruppieren, so daß die Artikel in der Statistik (da sie einen anderen Wechselkurs haben) separat aufgelistet werden.

Ich hoffe man versteht mein Problem. ;)

Vom Prinzip her ist das schon trivial, nur die Umsetzung macht mir gerade etwas Kopfschmerzen, auch wenn ich mittlerweile schon viel an AVERP selber gemacht habe. Oder unterliege ich irgendwo einem ganz komplizierten Denkfehler?

Danke nochmal!
tgvoelker hat geschrieben:Die Vorgehensweise ist relativ trivial, jedoch handelt es sich eher um ein betriebswirtschaftliches denn ein IT-Problem:

Zunächst muß geklärt werden, wie sich der der Lagerwert zusammensetzt. Dazu ist die Wahl einer Bewertungsmethode (historischer EHK, letzte EHK, gleitender Durchschnitt EHK, pauschal abgewertete EHK...) und ggf. die Wahl einer Lagerabgangsmethode notwendig (LiFo, FiFo, HiFo, LoFo...). Eine Lagerabgangsmethode muß immer dann gewählt werden, wenn die Bewertungsmethode historische Werte verwendet.

Aufpassen: bei Bewertungen für die KoRe haben Sie freie Hand, handelsrechtlich sind nur einige Kombinationen zulässig und steuerrechtlich noch weniger!

Entsprechend der Bewertungs-/Lagerabgangsmethode ergeben sich andere maßgebliche Preise für die Bewertung - eine feste "Verknüpfung" macht also keinen Sinn. Nehmen wir ein Beispiel, was sowohl handels- als auch steuerrechtlich grundsätzlich anerkannt ist: historische EHK mit LiFo.

Dabei wird unterstellt, daß immer das jeweils zuletzt im Lager eingegangene wieder abgeht.

Nehmen wir an: AnfBest 1000 AnfWert 10000
Wareneingang: 500 á 5500
Warenabgang: 200
EndBest: 1300, Endwert: 13300

Was wird also gerechnet:

Menge ist unkritisch: AB+Wareneingang-Warenabgang
Wert: AW+Wert Wareneingang-Entsprechend der jeweils letzten Wareneingänge bewerteter Warenabgang.

EDIT:
Folgendes könnte Ihnen bei den Hintergründen helfen:
Prinzip der Gewinnrealisation, Prinzip der Verlustantizipation, Prinzip der Bilanzwahrheit, Niederstwertprinzip (ergibt sich aus Gewinnrealisation und Verlustantizipation)
Gast

Beitrag von Gast »

Hallo 2mad,

FiFo ist steuerrechtlich nur dann zulässig, wenn dies nachgewiesenermaßen den tatsächlichen Lagerbewegungen entsprich. Dies ist z.B. bei Silos der Fall: Oben nachfüllen, unten entnehmen, d.h. Auslagerung erfolgt in derselben Reihenfolge wie die Einlagerung. Wenn Sie unter 2. beschrieben den letzten EK zuordnen wollen, dann verwenden Sie LiFo.

Unabhängig davon hier das Lösungsschema für FiFo anhand von Beispieldaten. Das Beispiel ist in Transact SQL gemacht (geht mir besser von der Hand und hat mehr Funktionen, z.B. CASE), benötigt also MS SQL Server in irgendeiner Version als Middleware. Zur Anbindung von Interbase siehe Thread von mir in den Tips und Tricks (Anbindung von Fremdsystemen oder so). Umsetzung in Interbase auch möglich, aber punktuell andere Syntax notwendig.

Vorgehensweise:
Zugänge in temporäre Tabelle schreiben.
Abgänge in temporäre Tabelle schreiben.
Zugange in Hilfstabelle kopieren.
Zugänge um DS für "Sonderpreis" erweitern.
Abgänge durchlaufen und jeweils vorhandene Zugänge zuordnen und die Zugänge abbuchen (aus der Hilfstabelle).
Danach alle 3 Tabellen verknüpfen - dann sieht man, welche Zugänge welchen Abgängen zugewiesen wurden, für welche Abgänge es nichts gab (ZUG_ID=0) und gegen welche Zugänge noch nichts abgebucht wurde (NULL in Spalte ID).

Code: Alles auswählen

DROP TABLE #ZUGANG;
GO
DroP TABLE #ABGANG;
GO
DROP TABLE #HELPTBL;
GO
/*Beispiel zur Zuordnung von Werten zu Lagerabgängen bei FiFo

Zuerst Vorbereitung:
Datumsformat setzen*/
SET DATEFORMAT dmy;
/*zwei temporäre Tabellen anlegen, einmal Zugänge, einmal Abgänge*/
CREATE TABLE #ZUGANG (ID INT NOT NULL,DATUM DATETIME NOT NULL, MENGE INT NOT NULL, PREIS MONEY NOT NULL);
CREATE TABLE #ABGANG (ID INT NOT NULL, DATUM DATETIME NOT NULL, MENGE INT NOT NULL,ZUGANG_ID INT);
/*Und füllen, 7 x Abgang, 10 x Zugang*/
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(1,'1/1/2005',50,17.01);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(2,'1/2/2005',47,17.02);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(3,'1/3/2005',10,17.03);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(4,'1/4/2005',32,17.04);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(5,'1/5/2005',58,17.05);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(6,'1/6/2005',70,17.06);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(7,'1/7/2005',23,17.07);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(8,'1/8/2005',19,17.08);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(9,'1/9/2005',44,17.09);
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(10,'1/10/2005',35,17.10);

INSERT INTO #ABGANG (ID,DATUM,MENGE) VALUES(1,'15/1/2005',70); /*nicht im Zugang erfaßte Menge wird mit vorgesetztem Preis bewertet*/
INSERT INTO #ABGANG (ID,DATUM,MENGE) VALUES(2,'15/2/2005',30); /*Geht mehr ab, als eingegangen ist, dann wird kein Preis zugewiesen!*/
INSERT INTO #ABGANG (ID,DATUM,MENGE) VALUES(3,'15/3/2005',27);
INSERT INTO #ABGANG (ID,DATUM,MENGE) VALUES(4,'15/4/2005',5);
INSERT INTO #ABGANG (ID,DATUM,MENGE) VALUES(5,'15/5/2005',40);
INSERT INTO #ABGANG (ID,DATUM,MENGE) VALUES(6,'15/6/2005',8);
INSERT INTO #ABGANG (ID,DATUM,MENGE) VALUES(7,'15/7/2005',60);

/*Jetzt kanns losgehen, zunächst Hilfstabelle anlegen. Mit der werden die Zugangsdaten zugewiesen*/
SELECT * INTO #HELPTBL FROM #ZUGANG;
/*Preis für Entnahme von Ware vor dem ersten Zugang definieren. Da später gejoined wird, neuer DS in die Zugangstabelle*/
INSERT INTO #ZUGANG (ID,DATUM,MENGE,PREIS) VALUES(0,'1/1/2005',0,20);

/*While Schleife. Solange nicht allen Abgangsdaten ein Preis zugeordnet ist und noch Zugangsdaten existieren, gehts weiter*/
/*In der Schleife werden Variablen benötigt*/
DECLARE @ZUG_MENGE INT;
DECLARE @ZUG_ID INT;
DECLARE @ABG_MENGE INT;
DECLARE @ABG_ID INT;
DECLARE @ABG_DATUM DATETIME;

WHILE (EXISTS(SELECT * FROM #ABGANG WHERE ZUGANG_ID IS NULL) AND EXISTS(SELECT * FROM #HELPTBL))
BEGIN
  SET @ABG_ID = (SELECT ID FROM #ABGANG WHERE (ZUGANG_ID IS NULL)AND(DATUM=(SELECT MIN(DATUM) FROM #ABGANG WHERE ZUGANG_ID IS NULL)));
  SET @ABG_MENGE = (SELECT MENGE FROM #ABGANG WHERE ID=@ABG_ID);
  SET @ABG_DATUM = (SELECT DATUM FROM #ABGANG WHERE ID=@ABG_ID);
  IF EXISTS(SELECT DATUM FROM #HELPTBL WHERE DATUM<=@ABG_DATUM)
  BEGIN
    SET @ZUG_ID=(SELECT ID FROM #HELPTBL WHERE DATUM=(SELECT MIN(DATUM)FROM #HELPTBL));
    SET @ZUG_MENGE = (SELECT MENGE FROM #HELPTBL WHERE ID=@ZUG_ID);
  END ELSE BEGIN
    SET @ZUG_ID = 0;/*Ersatzpreis!*/
    SET @ZUG_MENGE = 5000000; /*so groß, daß es auf jeden Fall größer ist als der Abgang!*/
  END
  IF @ZUG_MENGE > @ABG_MENGE
  BEGIN
    UPDATE #ABGANG SET ZUGANG_ID=@ZUG_ID WHERE ID=@ABG_ID;
    UPDATE #HELPTBL SET MENGE=MENGE-@ABG_MENGE WHERE ID = @ZUG_ID;/*Ändert für den ErsatzPreis keine Daten, ansonsten Verringerung um abgebuchte Menge*/
  END
  ELSE
  BEGIN
    UPDATE #ABGANG SET MENGE = @ZUG_MENGE, ZUGANG_ID=@ZUG_ID WHERE ID = @ABG_ID;/*Preis für das zuweisen, was im akt. Eingang vorhanden ist*/
    IF @ZUG_MENGE < @ABG_MENGE /*Wenn Mengen gleich sind, keinen DS anlegen*/
    BEGIN 
      INSERT INTO #ABGANG (ID,DATUM,MENGE)/*Nun neuen DS mit Differenz anlegen*/
      SELECT ID=(SELECT MAX(ID) FROM #ABGANG)+1,DATUM,MENGE=@ABG_MENGE-@ZUG_MENGE
      FROM #ABGANG WHERE ID=@ABG_ID;
    END
    DELETE FROM #HELPTBL WHERE ID=@ZUG_ID;/*vollständig abgebuchten Zugang löschen*/
  END
  
END;
SELECT
#ABGANG.ID,
DAT=CASE WHEN #ABGANG.DATUM IS NULL THEN #HELPTBL.DATUM ELSE #ABGANG.DATUM END,
#ABGANG.MENGE,
ZUG_ID = CASE WHEN #ABGANG.ZUGANG_ID IS NULL THEN #HELPTBL.ID ELSE #ABGANG.ZUGANG_ID END,
#ZUGANG.PREIS,
#HELPTBL.MENGE AS RESTMENGE
FROM
#ABGANG INNER JOIN #ZUGANG ON #ABGANG.ZUGANG_ID=#ZUGANG.ID
FULL OUTER JOIN #HELPTBL ON #ABGANG.ZUGANG_ID=#HELPTBL.ID
ORDER BY ZUG_ID,DAT;
Als Resultset wird ausgegeben:

Code: Alles auswählen

ID          DAT                                                    MENGE       ZUG_ID      PREIS                 RESTMENGE   
----------- ------------------------------------------------------ ----------- ----------- --------------------- ----------- 
8           2005-01-15 00:00:00.000                                20          0           20.0000               NULL
1           2005-01-15 00:00:00.000                                50          1           17.0100               NULL
2           2005-02-15 00:00:00.000                                30          2           17.0200               NULL
3           2005-03-15 00:00:00.000                                17          2           17.0200               NULL
9           2005-03-15 00:00:00.000                                10          3           17.0300               NULL
4           2005-04-15 00:00:00.000                                5           4           17.0400               NULL
5           2005-05-15 00:00:00.000                                27          4           17.0400               NULL
10          2005-05-15 00:00:00.000                                13          5           17.0500               NULL
6           2005-06-15 00:00:00.000                                8           5           17.0500               NULL
7           2005-07-15 00:00:00.000                                37          5           17.0500               NULL
11          2005-07-15 00:00:00.000                                23          6           17.0600               47
NULL        2005-07-01 00:00:00.000                                NULL        7           NULL                  23
NULL        2005-08-01 00:00:00.000                                NULL        8           NULL                  19
NULL        2005-09-01 00:00:00.000                                NULL        9           NULL                  44
NULL        2005-10-01 00:00:00.000                                NULL        10          NULL                  35
Grüße,

Thomas
tgvoelker
Beiträge: 47
Registriert: So Dez 11, 2005 11:52 am

Beitrag von tgvoelker »

Hmm, Opfer von Autologout!

Anbei noch einige Anmerkungen zu Ihrem und meinem Post:
Gast hat geschrieben: Wenn Sie unter 2. beschrieben den letzten EK zuordnen wollen, dann verwenden Sie LiFo.
Fehler von mir, Lagerwert wird so ermittelt, das ist richtig. Hatte das im ersten Moment überlesen und dachte, Sie meinen den Wert des Warenabganges. Der von mir gepostete Algorithmus ist etwas komplizierter, da er auch für andere Lagerabgangsmethoder verwendet werden kann. Die Lagerabgangsmethode wird über

Code: Alles auswählen

    SET @ZUG_ID=(SELECT ID FROM #HELPTBL WHERE DATUM=(SELECT MIN(DATUM)FROM #HELPTBL));
gesteuert. LiFo wäre entsprechend

Code: Alles auswählen

    SET @ZUG_ID=(SELECT ID FROM #HELPTBL WHERE DATUM=(SELECT MAX(DATUM)FROM #HELPTBL));
LoFo

Code: Alles auswählen

    SET @ZUG_ID=(SELECT ID FROM #HELPTBL WHERE PREIS=(SELECT MIN(PREIS)FROM #HELPTBL));
usw.

Bei FiFo wäre auch folgender iterativer Algorithmus denkbar (dieser berücksichtigt jedoch keine Lagerabgänge ohne zuordbare Zugänge - funktioniert also nur, wenn die Auswahl ALLE Lagerabgänge und Zugänge umfaßt und nicht auf einen bestimmten Zeitraum eingeschränkt ist).

1. Hilfstabelle wird diesmal leer angelegt.
2. Schleife wird solange ausgeführt, bis Menge Warenausgang+Menge Hilfstabelle=Menge Wareneingang
3. In der Schleife werden der Hilfstabelle rückwärts Wareneingangstupel hinzugefügt
4. ebenfalls in der Schleife wird nach dem Hinzufügen zur Hilfstabelle die Schleifenbedingung geprüft. Wenn diese falsch wird, dann wird die Menge des zuletzt hinzugefügten DS entsprechend geändert.
5. Danach entsprechend die in der Hilfstabelle vorhandenen DS dem Lagerwert.

Noch ein paar Worte zu der ausgegebenen Tabelle. Dazu eine kleine Änderung - Abgangsdatum und Zugangsdatum wird separat ausgegeben:

Code: Alles auswählen

SELECT
#ABGANG.ID,
ABG_DAT=#ABGANG.DATUM,
ZUG_DAT=#ZUGANG.DATUM,
#ABGANG.MENGE,
ZUG_ID = CASE WHEN #ABGANG.ZUGANG_ID IS NULL THEN #HELPTBL.ID ELSE #ABGANG.ZUGANG_ID END,
#ZUGANG.PREIS,
#HELPTBL.MENGE AS RESTMENGE
FROM
#ABGANG FULL OUTER JOIN #ZUGANG ON #ABGANG.ZUGANG_ID=#ZUGANG.ID
FULL OUTER JOIN #HELPTBL ON #ZUGANG.ID=#HELPTBL.ID
ORDER BY #ZUGANG.ID,ABG_DAT;
ResultSet

Code: Alles auswählen

ID   ABG_DAT                 ZUG_DAT                 MENGE ZUG_ID PREIS   RESTMENGE   
---- ----------------------- ----------------------- ----- ------ ------- ----------- 
8    2005-01-15 00:00:00.000 2005-01-01 00:00:00.000 20    0      20.0000 NULL
1    2005-01-15 00:00:00.000 2005-01-01 00:00:00.000 50    1      17.0100 NULL
2    2005-02-15 00:00:00.000 2005-02-01 00:00:00.000 30    2      17.0200 NULL
3    2005-03-15 00:00:00.000 2005-02-01 00:00:00.000 17    2      17.0200 NULL
9    2005-03-15 00:00:00.000 2005-03-01 00:00:00.000 10    3      17.0300 NULL
4    2005-04-15 00:00:00.000 2005-04-01 00:00:00.000 5     4      17.0400 NULL
5    2005-05-15 00:00:00.000 2005-04-01 00:00:00.000 27    4      17.0400 NULL
10   2005-05-15 00:00:00.000 2005-05-01 00:00:00.000 13    5      17.0500 NULL
6    2005-06-15 00:00:00.000 2005-05-01 00:00:00.000 8     5      17.0500 NULL
7    2005-07-15 00:00:00.000 2005-05-01 00:00:00.000 37    5      17.0500 NULL
11   2005-07-15 00:00:00.000 2005-06-01 00:00:00.000 23    6      17.0600 47
NULL NULL                    2005-07-01 00:00:00.000 NULL  7      17.0700 23
NULL NULL                    2005-08-01 00:00:00.000 NULL  8      17.0800 19
NULL NULL                    2005-09-01 00:00:00.000 NULL  9      17.0900 44
NULL NULL                    2005-10-01 00:00:00.000 NULL  10     17.1000 35
Tupel mit ZUG_ID 0 zeigen Abgänge an, denen im Zeitraum keine Zugänge zugeordnet werden konnten.
Tupel mit ZUG_ID <>0 und gefülltem Abgangsdatum stellen Lagerabgänge dar.
Tupel mit Restmenge stellen Lagerwert dar. Summe über (Preis * Restmenge) ist Lagerwert.

EDIT: Habe nochmal die verschiedenen Lagerabgangsmethoden probiert und dabei einen kleinen Fehler entdeckt. Korrekte Version kommt in die Tipps und Tricks.
Antworten