0

Berechnung von Kalenderwochen

Hallo liebe Ninox-Gemeinde,

ich habe folgendes Problem wofür ich aktuell keine Lösung finde.

Ich habe ein Rechnungsprogramm mit dem vermietete Gegenstände (hier Miettoiletten) abgerechnet werden.

Abrechnungszyklus sind Kalenderwochen, d.h. es gibt einen Betrag X der pro Kalenderwoche gezahlt werden muss. Es wird dann irgendwann eine Kalenderwoche X als Abrechnungswoche bestimmt und alle laufenden Aufträge werden bis zu dieser Kalenderwoche abgerechnet. Der Auftrag für einen Gegenstand kann dann noch weiterlaufen und muss dann im nächsten Zyklus wieder vom letzten Abrechnungszeitpunkt bis zur aktuellen Kalenderwoche oder bis zum Rückgabedatum abgerechnet werden. Zu dem gibt es noch eine Mindestabnahme von 4 Kalenderwochen.

Das habe ich alles soweit mit folgendem hinbekommen (Funktion zur Berechnung der Kalenderwochen innerhalb der Rechnung):

let Abholung := Auftragsende;
let Mindestabnahmepruefung := if Abholung = null then
'KW-Ende-diese-Rechnung' - 'KW-Start-diese-Rechnung'
else
if 'KW-Ende-diese-Rechnung' - week(Lieferdatum) < 4 then
if 'RG abgerechnet bis' = null then
4
else
4 - (week('RG abgerechnet bis') + 1 - week(Lieferdatum))
end
else
'KW-Ende-diese-Rechnung' - 'KW-Start-diese-Rechnung'
end
end;
Mindestabnahmepruefung

 

Ein Problem gibt es jedoch beim Jahreswechsel, da die Kalenderwochenzählung ja wieder bei 1 beginnt und somit die Berechnungen absolut in die falsche Richtung laufen. Wie könnte ich die Funktion anpassen damit die Kalenderwoche des Folgejahres größer ist als die des alten Jahres. Es ist wahrscheinlich relativ simpel aber ich habe das altbekannte Brett vorm Kopf.

 

Bereits jetzt Danke für die Mithilfe.

7 Antworten

null
    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hi Robby. Wenn Du mit Kalenderwochen rechnen willst und die Anzahl der Vermietwochen stets < 52 (53 Schaltjahr) ist, dann kann Dir folgendes Script helfen, welches auch bei Jahreswechsel funktioniert. Es ermittelt die Anzahl der Kalenderwochen als Differenz der Kalenderwoche vom Enddatum und Anfangsdatum, nur eben als Schleifenzählung und unabhängig ob es volle Wochen sind oder nur angefangene.

    *

    let anfang := ANFANGSDATUM;
    let ende := ENDDATUM;
    let anzahl := days(anfang, ende);
    cnt(unique(for i in range(0, anzahl + 1) do
    week(date(year(anfang), month(anfang), day(anfang) + i))
    end))

    *

    Mirko

    • Daniel.3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Robby, 

    das ist ja interessant. Ich will gerad genau das Gleiche auf die Beine stellen (Als Endlösung auch für Mobiltoiletten ;) ) . Allerdings mit möglichst variablen Abrechnungseinstellungen (Monat, KW, Tag etc.) um damit auch Container und andere Sachen abrechnen zu können. Kannst mich ja mal auf dem Laufenden halten. Ich bin gerad dabei, den Monat durch seine jeweiligen Tage zu teilen um "anteilige" Schlussrechnungen zu stellen. 

    Gruß,

    Daniel  

    • CENTaros Finanzen GmbH
    • Robby_Kurze
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo MZ,

    die Formel funktioniert super und ist genau das was ich brauche in der Hoffnung das eine Toilette nicht länger als 52 Wochen vermietet wird ;-), wobei ja immer spätestens nach 4 Wochen eine Zwischenabrechnung gemacht wird.

    Ich habe jedoch noch das Problem dem Script zu vermitteln, dass das Anfangsdatum falls es die zweite Rechnung ist eine Kalenderwoche nach Ende der letzten Rechnung ansetzen soll.

    Als Beispiel:

    1. Rechnung 23.08.2021 (KW34) - 01.09.2021 (KW35): Es werden 2 KWs in Rechnung gestellt.

    die 2. Rechnung sollte sein: KW 36 - KW egal

     

    In deinem Script kann ich jetzt sagen rechne ab dem nächsten Tag (02.09.2021). Das wäre aber weiterhin KW 35.

    Wie könnte ich das Skript abwandeln um als Beginndatum immer mit der nächsten KW zu starten. Aktuell würde es nur funktionieren wenn ich den Abrechnungszeitpunkt immer auf den letzten Tag der Kalenderwoche lege. Das wäre jetzt meine Notlösung.    

     

    Hast du oder jemand anders eine Idee.

     

    Weiterhin vieren Dank für die Mühe und Mithilfe.

     

    @Daniel Ich werde dich auf dem Laufenden halten.

    • mirko3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hi Robby. Mir fehlt natürlich die Kenntnis zum Rest des Scripts und dem Aufbau Deiner Datenbank. Es scheint mir aber machbar zu sein.
    Ich habe mir folgendes zusammengereimt: Du vermietest eine Zeitdauer die beginnt mit einem Anfangsdatum und endet mit einem Enddatum. Dann erstellst Du Rechnungen
    alle 4 Wochen und benötigst dafür dann den Abrechnungszeitraum in Kalenderwochen. Wenn der nächste Abrechnungszeitraum um ist -> wieder Rechnung. Es muss also
    einen Unterschied geben zwischen dem Anfangs/Enddatum Mietzeit und Anfangs/Enddatum Teilrechnung, oder auch nicht. Und vielleicht sind es auch getrennte Tabellen (hoffe ich für Dich), die Miete und Rechnungen betreffen und es gibt noch eine Tabelle für die Kontakte. Das alles wäre natürlich wichtig zu wissen für eine kompetente Antwort.

    Das folgende Script (1) ist nur ein Beispiel. Es prüft kundenbezogen das letzte Enddatum und das neu vergebene Anfangsdatum und zeigt Dir an, wenn es in der gleichen Kalenderwoche liegt. Das könnte man auch automatisieren, z.B. als Trigger (2) im Datumfeld ANFANGSDATUM und das Datum prüfen und bei Gleichheit der Kalenderwochen auf die folgende Woche legen oder so. Und sicher gibt es noch ein paar elegantere Lösungen, die mir nicht einfallen und deshalb schiebe ich mal Deinen Thread wieder nach oben.
    *1
    let me := this.KUNDENNAME; //oder andere Bezeichnung
    let anzahl := cnt((select TABELLE)[KUNDENNAME = me].number(Nr));
    let vorletzter := item((select TABELLE)[KUNDENNAME = me].number(Nr), anzahl - 2);
    let dateEnde := record(TABELLE,vorletzter).ENDDATUM;
    if week(dateEnde) = week(ANFANGSDATUM) then
    "so nicht!" //oder alert("so nicht!")
    end

    *2
    let me := this.KUNDENNAME;
    let anzahl := cnt((select TABELLE)[KUNDENNAME = me].number(Nr));
    let vorletzter := item((select TABELLE)[KUNDENNAME = me].number(Nr), anzahl - 2);
    let dateEnde := record(TABELLE,vorletzter).ENDDATUM;
    if week(dateEnde) = week(ANFANGSDATUM) then
    ANFANGSDATUM := date(year(dateEnde), month(dateEnde), day(dateEnde) + 7) //führt sicher in die nächste Woche
    end
    *
    Gruß Mirko

    • CENTaros Finanzen GmbH
    • Robby_Kurze
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Mirko,

     

    vielen Dank für den Aufwand. Es ist natürlich mein Fehler, dass ich nichts genaueres beschrieben habe. Du hast das Gerüst aber schon ziemlich genau getroffen.

    Es gibt folgende Tabellen:

     

    Kunden

    Aufträge

    Rechnungen

     

    Der Clou bei der Datenbank sollte sein, dass alle Aufträge im laufenden Monat angelegt werden, es natürlich schon laufende gibt und natürlich auch neue dazu kommen.

    Nun wird ein Abrechnungstag bestimmt an dem alle Aufträge abgerechnet werden. Das besondere ist, dass das bisher immer zwischen 200 - 300 Aufträge pro Abrechnungszeitraum sind und alles per Hand in Excel für die Rechnung einegegben worden ist.

     

    Nun übergebe ich mit einem Knopfdruck den Abrechnungstag in die laufenden (alten), die laufenden neu dazu gekommenen und in die seit der letzten Abrechnung abgeschlossenen Aufträge.

    Anschliessend noch ein Knopfdruck und aus allen Aufträgen wird eine Rechnung generiert, ausgedruckt und in Zukunft soll per E-Mail versendet werden.

     

    Ich habe das im Auftrag derzeit so gelöst, dass der Abrechnungstag per Button in alle laufenden Aufträge geschrieben wird und sobald der Knopf zur Rechnungsgenerierung gedrückt wird werden Enddatum alte Rechnung + Enddatum aktuelle Rechnung und diverse andere Sachen aus dem Auftrag in die Rechnungstabelle geschrieben und dort daraus die KWs ermittelt. Im Auftrag wird dann der aktuelle Abrechungszeitpunkt in bisherigen Abrechnungszeitpunkt umgewandelt und so ist alles für den nächsten Rechnungslauf vorbereitet. Sollte die Toielette bereits abgeholt worden sein wird der Auftrag natürlich automatisch beendet und nach Rechnungserstellung als abgeschlossen dargestellt und entfällt für den nächsten Rechnungslauf.

     

    Ich hoffe ich konnte ein wenig Licht ins Dunkel bringen.

    Diese + 7 Tage die sich in deinem letzten Teil befinden sind eigentlich eine geniale Idee weil ich somit immer in die nächste KW komme.

    ANFANGSDATUM := date(year(dateEnde), month(dateEnde), day(dateEnde) + 7)

     

    Da ich leider ein relativer Anfänger bin ist nochmal meine letzte Frage an dich ob man das nicht irgendwie in dein Script von der ersten Antwort kombinieren kann???

     

    let anfang := ANFANGSDATUM;
    let ende := ENDDATUM;
    let anzahl := days(anfang, ende);
    cnt(unique(for i in range(0, anzahl + 1) do
    week(date(year(anfang), month(anfang), day(anfang) + i))
    end))

     

    Ich denke das wäre des Rätsels Lösung.

    • CENTaros Finanzen GmbH
    • Robby_Kurze
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Mirko,

    beim Absenden ist mir gaube ich eine Lösung in den Kopf gekommen.

    Ich lasse überprüfen ob es in der neuen (zweiten) Rechnung ein Datum (bereits abgerechnet bis Datum) gibt. Das entspricht in dieser Rechnung ja dem ANFANGSDATUM deines ersten Scripts. Das Datum erhöhe ich einfach um 7 Tage und lasse dann dein erstes Script laufen. Da das Datum in eine Kalenderwoche umgerechnet wird und nicht auf der Rechnung erscheint ist es ja egal, das es um 7 Tage erhöht worden ist. Somit wird in dein Script aber immer die nächste Kalenderwoche als Anfangswoche übergeben.

     

    Ich werde es nachher mal testen und hoffe das ich keinen Denkfehler habe.

    • Daniel.3
    • vor 2 Jahren
    • Gemeldet - anzeigen

    Hallo Robby, 

    Ich habe den Thread jetzt nur überflogen. Aber mein Ansatz ist folgender: 

    Ich habe die Tabelle "Aufträge" mit Untertabelle "Positionen" . die eigentlichen Berechnungen zur Abrechnung führe ich in der Tabelle Positionen  (z.b. Container, Toilettekabine, Anlieferung, Endreinigung etc. ) durch. Zu jeder einzelnen Position gibt es unter Anderem folgende Felder:

    "Abrechnen ab" (gleichzusetzten mit Mietbeginn/Lieferdatum) 

    "nächste Abrechnung ab" (Mietbeginn + Abrechnungszyklus)

    "Abrechnen bis" ("Abrechnen ab" oder "nächste Abrechnung ab" + eingestellter Abrechnungsintervall z.b. 1 Monat oder 4 Wochen).

    Aus diesen Daten bilde ich in den Positionen Summen, die ich dann in eine Extra Rechnungstabelle schreibe. Beim Erstellen der Rechnung werden dann die Daten "nächste Abrechnung ab" und "Abrechnen bis" automatisch um den von mir eingestellten Abrechnungsintervall weitergeschoben. Bis dieser wieder abgelaufen ist und ich die nächsten Rechnungen schreibe. 

    Die Abrechnungsart "Monatsabrechnung" mit Mindestmiete und anteiligen Monaten habe ich soeben fertig gestellt. Die Wochen will ich danach angehen. Mir ist wichtig, dass die Lösung möglichst skalierbar ist, da unterschiedliche Artikel auch unterschiedlich abgerechnet werden.

     

    Hast du schonmal das Thema Routenoptimierung und Fahrerportal angefasst?

Content aside

  • vor 2 JahrenZuletzt aktiv
  • 7Antworten
  • 506Ansichten