Arbeitsblätter: Abo-Vorgabe bei Einrichtungs-Tickets

Bei Tickets mit einrichtungAbrechnung 'abo' steht "Vom Abo-Stundenkonto abziehen" im Dialog von Anfang an auf an (auch wenn der Abo-Status erst nach dem Öffnen ankommt), beim Nachtragen der Zeit eines Git-Blatts wird countsToPlan beim ersten Eintragen gesetzt. 'projekt', Kommentare und Kunden ohne Wartungs-Abo bekommen keine Vorgabe; ein von Hand abgehakter Haken bleibt aus.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-16 13:36:34 +00:00
1 parent 5e59ad44bd
commit f0d39f2eee
5 files changed
+86 -7

No files matched your search

+11 -3
View File
@@ -7,6 +7,7 @@ import { Button, DateTimeInput, Dialog, DurationSelect, Field } from './ui'
import { roundUpToStep, isValidStep } from '../lib/timeSteps'
import { validateSupporters } from '../lib/support'
import SupportersEditor from './SupportersEditor'
import { countsToPlanWert } from '../lib/planVorgabe'
// Akquise-Tickets: Ergebnis des Kundenkontakts (statt technischer Status)
const ACQUISITION_STATUS = ['In Kontakt', 'Zugesagt', 'Abgesagt']
@@ -31,7 +32,7 @@ const initialForm = (workorder, newStatus) => ({
endTime: '',
details: '',
isComment: false,
countsToPlan: false,
countsToPlan: null, // null = unberührt: dann gilt die Abo-Vorgabe des Tickets (planVorgabe.js)
supporters: []
})
@@ -50,6 +51,13 @@ export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCre
: (workorder?.status || 'Open')
const [formData, setFormData] = useState(() => initialForm(workorder, defaultStatus))
// Der Abo-Status kommt oft erst nach dem Öffnen: der Wert wird bei jedem Rendern aus Handwahl und Vorgabe berechnet
const countsToPlan = countsToPlanWert({
gewaehlt: formData.countsToPlan,
ticket: workorder,
aboHoursAllowed,
isComment: formData.isComment
})
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
@@ -130,7 +138,7 @@ export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCre
endTime: timeToWoms(formData.endTime),
details: formData.details,
isComment: formData.isComment,
countsToPlan: aboHoursAllowed && !formData.isComment && formData.countsToPlan,
countsToPlan,
employeeShort: user?.prefs?.shortCode || '', // Aus User-Preferences
supporters
}
@@ -222,7 +230,7 @@ export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCre
<label className="check" title="Zeit wird vom Stundenguthaben des Wartungs-Abos abgezogen und im Kundenportal angezeigt">
<input
type="checkbox"
checked={formData.countsToPlan && !formData.isComment}
checked={countsToPlan}
disabled={formData.isComment}
onChange={(e) => handleChange('countsToPlan', e.target.checked)}
/>
+4 -3
View File
@@ -228,15 +228,16 @@ export function useWorksheets(woid = null) {
/**
* Aendert nachtraeglich Beginn, Ende und Arbeitszeit - nur fuer den Ersteller
* (employee = eigener Eintrag aus "employees", fuer Git-Pushes)
* (employee = eigener Eintrag aus "employees", fuer Git-Pushes).
* extra: weitere Felder fuer dasselbe Update (z. B. countsToPlan aus der Abo-Vorgabe)
*/
const updateWorksheetTimes = async (worksheet, times, currentUser, employee) => {
const updateWorksheetTimes = async (worksheet, times, currentUser, employee, extra = {}) => {
if (!canEditWorksheetTimes(worksheet, currentUser, employee)) {
return { success: false, error: 'Nur wer das Arbeitsblatt erstellt hat, kann die Zeiten ändern.' }
}
const { startDate, startTime, endDate, endTime, totalTime } = times
if (!isValidStep(totalTime)) return { success: false, error: STEP_ERROR }
const data = { startDate, startTime, endDate, endTime, totalTime }
const data = { startDate, startTime, endDate, endTime, totalTime, ...extra }
// Unterstuetzung nur schreiben, wenn sie sich geaendert hat. Hat inzwischen jemand anderes
// (z. B. ueber "Ich habe unterstuetzt") etwas geaendert, nicht still ueberschreiben.
if (times.supporters) {
+32
View File
@@ -0,0 +1,32 @@
// Abo-Vorgabe für Arbeitsblätter an Einrichtungs-Tickets (V9): Hängt das Ticket an einer Funktion, die aus dem Abo
// eingerichtet wird (einrichtungAbrechnung 'abo'), steht "Vom Abo-Stundenkonto abziehen" von Anfang an auf an.
// 'projekt' (im Projekt enthalten) und alle anderen Tickets bekommen keine Vorgabe. Nur Vergleiche, keine Zeitlogik.
import { isGitWorksheet, needsTimeEntry } from './ticketForm'
export const EINRICHTUNG_ABRECHNUNGEN = ['abo', 'projekt']
// 'abo' | 'projekt' | '' – nur genau diese Werte, alles andere (Großschreibung, Zahl, fehlendes Ticket) gilt als nicht gesetzt
export function einrichtungAbrechnung(ticket) {
const wert = ticket?.einrichtungAbrechnung
return EINRICHTUNG_ABRECHNUNGEN.includes(wert) ? wert : ''
}
// Vorgabe für countsToPlan: nur bei Abo-Einrichtung und wenn das Wartungs-Abo Stunden erlaubt
export function countsToPlanVorgabe(ticket, aboHoursAllowed) {
return einrichtungAbrechnung(ticket) === 'abo' && aboHoursAllowed === true
}
// Wert des Hakens im Dialog. gewaehlt: null = unberührt (dann gilt die Vorgabe, auch wenn der Abo-Status erst nach dem
// Öffnen ankommt), true/false = von Hand gesetzt. Ohne erlaubte Abo-Stunden und bei Kommentar ist der Wert immer false.
export function countsToPlanWert({ gewaehlt, ticket, aboHoursAllowed, isComment }) {
if (isComment || aboHoursAllowed !== true) return false
if (gewaehlt === null || gewaehlt === undefined) return countsToPlanVorgabe(ticket, aboHoursAllowed)
return Boolean(gewaehlt)
}
// Felder, die beim Nachtragen der Zeit eines Git-Blatts mitgeschrieben werden: nur beim ersten Eintragen der Zeit
// (das Blatt hat noch keine) und nur, wenn die Vorgabe greift. Eine bestehende Entscheidung bleibt unberührt.
export function nachtragPlanFelder({ worksheet, ticket, aboHoursAllowed }) {
if (!isGitWorksheet(worksheet) || !needsTimeEntry(worksheet) || worksheet.countsToPlan) return {}
return countsToPlanVorgabe(ticket, aboHoursAllowed) ? { countsToPlan: true } : {}
}
+2 -1
View File
@@ -18,6 +18,7 @@ import { databases, DATABASE_ID, COLLECTIONS } from '../lib/appwrite'
import { elapsedLabel } from '../lib/elapsed'
import { canAddOwnSupport } from '../lib/support'
import { canEditWorksheetTimes, serviceTypeLabel } from '../lib/ticketForm'
import { nachtragPlanFelder } from '../lib/planVorgabe'
import { listBackPath, resolveTicketTab, ticketPath, ticketRef } from '../lib/ticketRoutes'
import { statusSelectOptions, ticketTypeLabel } from '../lib/ticketStatus'
import { appointmentText, assigneeOptions, dueText, ticketNumber } from '../lib/ticketView'
@@ -307,7 +308,7 @@ function TicketView({ ticket, updateWorkorder, tab }) {
worksheet={editTimesWorksheet}
currentUserId={user?.$id}
onClose={() => setEditTimesWorksheet(null)}
onSave={(ws, times) => updateWorksheetTimes(ws, times, user, employee)}
onSave={(ws, times) => updateWorksheetTimes(ws, times, user, employee, nachtragPlanFelder({ worksheet: ws, ticket, aboHoursAllowed }))}
employeesState={employeesState}
/>
)}