Kontrolle: Projektkonto und Rechnungsbau waehlen dieselbe Aufwands-AB
Gemeinsame Auswahl juengsteAufwandAb (gueltig, jueengste nach gesendetAm) im AB-Speicher. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4177b76d82
commit
c2245b6905
4 files changed
+32
-8
No files matched your search
@@ -8,7 +8,7 @@
|
||||
import { config } from '../../config.js'
|
||||
import { createDocument, deleteDocument, getDocument, listAllDocuments, listDocuments, Query, updateDocument } from '../appwriteAdmin.js'
|
||||
import { AuftragError } from './fehler.js'
|
||||
import { LIMITS, ZAHLUNGSPLAN_ARTEN } from './konstanten.js'
|
||||
import { LIMITS, VEREINBARTE_STATUS, ZAHLUNGSPLAN_ARTEN } from './konstanten.js'
|
||||
import { AUFTRAEGE_COLLECTIONS } from './schema.js'
|
||||
|
||||
const JSON_SPALTEN = { kundeJson: 'kunde', zeitquelleJson: 'zeitquelle', positionenJson: 'positionen', zahlungsplanJson: 'zahlungsplan' }
|
||||
@@ -188,3 +188,16 @@ export async function findAuftragByNummer(nummer) {
|
||||
if (typeof nummer !== 'string' || !AB_NUMMER.test(nummer)) return null
|
||||
return findeEine('nummer', nummer)
|
||||
}
|
||||
|
||||
const sendezeit = (auftrag) => new Date(auftrag.gesendetAm || auftrag.erstelltAm || 0).getTime() || 0
|
||||
|
||||
/** Jüngste zuerst nach Sendezeitpunkt (ersatzweise Anlagezeit), bei Gleichstand nach Kennung. */
|
||||
export const juengsteZuerst = (a, b) => sendezeit(b) - sendezeit(a) || String(b.id).localeCompare(String(a.id))
|
||||
|
||||
/**
|
||||
* Die Aufwands-AB, mit der ein Projekt abgerechnet und angezeigt wird: unter den gültigen (versendet, bestätigt) die jüngste
|
||||
* nach gesendetAm, sonst null. Projektkonto und Rechnungsbau benutzen beide diese eine Auswahl.
|
||||
*/
|
||||
export function juengsteAufwandAb(liste) {
|
||||
return liste.filter((ab) => ab.art === 'aufwand' && VEREINBARTE_STATUS.includes(ab.status)).sort(juengsteZuerst)[0] ?? null
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import { KUNDENARTEN, STUNDENSATZ_STANDARD_CENTS, VEREINBARTE_STATUS } from './k
|
||||
import { AuftragError } from './fehler.js'
|
||||
import { auftraegeAktiv } from './schalter.js'
|
||||
import { auftragFuerTeam } from './auftragSicht.js'
|
||||
import { listAuftraege } from './auftragStore.js'
|
||||
import { listAuftraege, juengsteAufwandAb } from './auftragStore.js'
|
||||
import { listProjektRechnungen } from './projektRechnungenStore.js'
|
||||
import { abgerechneteArbeitsblaetter, abrechenbar, ladeArbeitsblaetter, zeitquelleFuerProjekt } from './arbeitsblaetter.js'
|
||||
|
||||
@@ -21,8 +21,6 @@ import { abgerechneteArbeitsblaetter, abrechenbar, ladeArbeitsblaetter, zeitquel
|
||||
const FINALISIERT = new Set(['offen', 'ueberfaellig', 'bezahlt', 'uneinbringlich'])
|
||||
|
||||
const summe = (liste, feld) => liste.reduce((s, eintrag) => s + eintrag[feld], 0)
|
||||
const zeitpunkt = (auftrag) => new Date(auftrag.gesendetAm || auftrag.erstelltAm || 0).getTime() || 0
|
||||
const juengsteZuerst = (a, b) => zeitpunkt(b) - zeitpunkt(a) || String(b.id).localeCompare(String(a.id))
|
||||
const zeitWert = (minuten, satzCents) => Math.round((minuten * satzCents) / 60)
|
||||
// Wert der Zeit = Summe der je Berliner Tag gerundeten Werte (Karte: Tag -> Minuten), genau wie die Zeilen einer Aufwandsrechnung
|
||||
// (aufwandPositionen in L2: eine Zeile je Tag mit Math.round(Minuten × Satz / 60)); so laufen Konto und Rechnung nicht um Cent auseinander
|
||||
@@ -40,7 +38,7 @@ export function rechneKonto({ auftraege = [], rechnungen = [], blaetter = [], ab
|
||||
const festpreise = gueltig.filter((auftrag) => auftrag.art === 'festpreis')
|
||||
const festpreisIds = new Set(festpreise.map((auftrag) => auftrag.id))
|
||||
const festpreisCents = festpreise.length ? festpreise.reduce((s, auftrag) => s + (Number(auftrag.summeCents) || 0), 0) : null
|
||||
const aufwandAb = gueltig.filter((auftrag) => auftrag.art === 'aufwand').sort(juengsteZuerst)[0] ?? null
|
||||
const aufwandAb = juengsteAufwandAb(gueltig)
|
||||
const aufwand = aufwandAb
|
||||
? {
|
||||
stundensatzCents: aufwandAb.stundensatzCents > 0 ? aufwandAb.stundensatzCents : STUNDENSATZ_STANDARD_CENTS,
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
anzahlungPosition, schlussPositionen, SCHLUSS_GRENZEN,
|
||||
} from './positionen.js'
|
||||
import { auftraegeAktiv } from './schalter.js'
|
||||
import { getAuftrag, listAuftraege, updateAuftrag } from './auftragStore.js'
|
||||
import { getAuftrag, listAuftraege, updateAuftrag, juengsteAufwandAb } from './auftragStore.js'
|
||||
import { getProjektRechnung, listProjektRechnungen, updateProjektRechnung } from './projektRechnungenStore.js'
|
||||
import {
|
||||
ladeArbeitsblaetter, ladeArbeitsblaetterNachIds, abrechenbar, abgerechneteArbeitsblaetter, offeneArbeitsblaetter, zeitquelleFuerProjekt,
|
||||
@@ -227,7 +227,7 @@ async function ladeAufwandAuftrag(kunde, projekt, auftragId) {
|
||||
}
|
||||
if (!auftraegeAktiv(kunde)) return null
|
||||
const liste = await listAuftraege({ kundenId: kunde.$id, projektId: projekt.id })
|
||||
return liste.find((ab) => ab.art === 'aufwand' && VEREINBARTE_STATUS.includes(ab.status)) ?? null
|
||||
return juengsteAufwandAb(liste)
|
||||
}
|
||||
|
||||
/** Ausdrueckliche Auswahl der Blaetter (Pruefung, Zugehoerigkeit zum Kunden, Doppelabrechnung mit Selbstheilung). */
|
||||
|
||||
Reference in new issue
Block a user