feat(projekte): Projekttyp "Abruf" fuer Abrechnung nach Aufwand
Abruf braucht keinen Budgettopf: es gibt kein zugesagtes Volumen und kein Ablaufdatum, gebucht wird, was anfaellt. Der Satz kann deshalb nicht am Topf haengen und steht am Projekt (pulse_projects.rate, Stunde oder Tag). Der Umsatz sind die abrechenbaren Stunden mal diesem Satz; offen ist nichts. - Migration ergaenzt den ENUM-Wert und die Spalte rate - Anlegen verlangt einen Satz und nimmt keine Toepfe an; ein Topf nachtraeglich anzulegen wird abgewiesen - Wechsel auf Abruf nur, solange auf den Toepfen nichts gebucht ist - sonst wuerden Buchungen ihr Budget verlieren; leere Toepfe fallen weg - Buchungsdialog, Projektkarte, Projektdetail und Projektreport zeigen Satz und Umsatz statt Budgetbalken Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2af516ec20
commit
8c93df11d9
@@ -46,6 +46,7 @@ export async function loadEntries(settings, { from, to, userIds = null, customer
|
||||
u.name AS user_name, u.color AS user_color, u.is_external, u.company AS user_company, u.weekly_hours,
|
||||
u.manager_id,
|
||||
p.name AS project_name, p.code AS project_code, p.type AS project_type, p.billing_unit,
|
||||
p.rate AS project_rate,
|
||||
c.id AS customer_id, c.name AS customer_name, c.short_name AS customer_short, c.color AS customer_color,
|
||||
t.name AS task_name,
|
||||
b.label AS pot_label, b.rate AS pot_rate, b.budget_amount AS pot_amount
|
||||
@@ -72,12 +73,13 @@ export async function loadEntries(settings, { from, to, userIds = null, customer
|
||||
}
|
||||
|
||||
return rows.map((r) => {
|
||||
const project = { name: r.project_name, code: r.project_code, billing_unit: r.billing_unit };
|
||||
const project = { name: r.project_name, code: r.project_code, billing_unit: r.billing_unit, type: r.project_type, rate: r.project_rate };
|
||||
const hours = r.minutes / 60;
|
||||
let amount = 0;
|
||||
let fixedAmount = 0;
|
||||
if (r.billable && r.project_type === 'billable') {
|
||||
const rate = hourlyRate({ rate: r.pot_rate }, project, settings);
|
||||
// Billable rechnet ueber den Satz des Topfs ab, Abruf ueber den am Projekt.
|
||||
if (r.billable && (r.project_type === 'billable' || r.project_type === 'abruf')) {
|
||||
const rate = hourlyRate(r.project_type === 'abruf' ? null : { rate: r.pot_rate }, project, settings);
|
||||
amount = rate ? hours * rate : 0;
|
||||
}
|
||||
if (r.billable && r.project_type === 'fixed' && r.pot_amount && potMinutes.get(r.pot_id)) {
|
||||
|
||||
Reference in New Issue
Block a user