Wartungs-Abo: Worksheets als Abo-Stunden markieren
Haken beim Anlegen + Umschalter in der Worksheet-Liste setzen worksheets.countsToPlan. Nur markierte Arbeitszeit wird im Kundenportal vom Abo-Stundenguthaben abgezogen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d42ee939e9
commit
cf1d653eb2
4 files changed
+50
-4
No files matched your search
@@ -51,7 +51,8 @@ export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCre
|
||||
endDate: today,
|
||||
endTime: '',
|
||||
details: '',
|
||||
isComment: false
|
||||
isComment: false,
|
||||
countsToPlan: false
|
||||
})
|
||||
|
||||
const [loading, setLoading] = useState(false)
|
||||
@@ -77,7 +78,8 @@ export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCre
|
||||
endDate: today,
|
||||
endTime: '',
|
||||
details: '',
|
||||
isComment: false
|
||||
isComment: false,
|
||||
countsToPlan: false
|
||||
})
|
||||
setError('')
|
||||
setAutoCalculate(true)
|
||||
@@ -146,6 +148,7 @@ export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCre
|
||||
endTime: formData.endTime,
|
||||
details: formData.details,
|
||||
isComment: formData.isComment,
|
||||
countsToPlan: !formData.isComment && formData.countsToPlan,
|
||||
employeeShort: user?.prefs?.shortCode || '' // Aus User-Preferences
|
||||
}
|
||||
|
||||
@@ -240,6 +243,18 @@ export default function CreateWorksheetModal({ isOpen, onClose, workorder, onCre
|
||||
Nur Kommentar (keine Arbeitszeit)
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label style={{ display: 'flex', alignItems: 'center', gap: '8px' }} title="Zeit wird vom Stundenguthaben des Wartungs-Abos abgezogen und im Kundenportal angezeigt">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={formData.countsToPlan && !formData.isComment}
|
||||
disabled={formData.isComment}
|
||||
onChange={(e) => handleChange('countsToPlan', e.target.checked)}
|
||||
/>
|
||||
Vom Abo-Stundenkonto abziehen
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="col col-6">
|
||||
|
||||
@@ -68,6 +68,8 @@ export default function TicketRow({ ticket, onUpdate, onExpand }) {
|
||||
|
||||
// Startzeit fuer Git-Push-Worksheets nachtragen (Endzeit kam vom Push)
|
||||
const handleSaveWorksheetTime = async (ws, data) => updateWorksheet(ws.$id, data)
|
||||
// Wartungs-Abo: Arbeitszeit aufs Stundenkonto des Kunden buchen (Kundenportal zeigt den Stand)
|
||||
const handleTogglePlan = async (ws) => updateWorksheet(ws.$id, { countsToPlan: !ws.countsToPlan })
|
||||
|
||||
const createdAt = new Date(ticket.$createdAt || ticket.createdAt)
|
||||
const elapsed = formatDistanceToNow(createdAt, { locale: de })
|
||||
@@ -243,7 +245,7 @@ export default function TicketRow({ ticket, onUpdate, onExpand }) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<WorksheetList worksheets={worksheets} totalTime={getTotalTime()} loading={worksheetsLoading} onEditTime={setEditTimeWorksheet} />
|
||||
<WorksheetList worksheets={worksheets} totalTime={getTotalTime()} loading={worksheetsLoading} onEditTime={setEditTimeWorksheet} onTogglePlan={handleTogglePlan} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ function needsTimeEntry(ws) {
|
||||
return ws.serviceType === 'GIT' && (!ws.startTime || !Number(ws.totalTime))
|
||||
}
|
||||
|
||||
export default function WorksheetList({ worksheets, totalTime, loading, onEditTime }) {
|
||||
export default function WorksheetList({ worksheets, totalTime, loading, onEditTime, onTogglePlan }) {
|
||||
const [expandedWorksheets, setExpandedWorksheets] = useState({})
|
||||
if (loading) {
|
||||
return (
|
||||
@@ -123,6 +123,13 @@ export default function WorksheetList({ worksheets, totalTime, loading, onEditTi
|
||||
<FaClock className="me-1" /> Zeit offen
|
||||
</span>
|
||||
)}
|
||||
{ws.countsToPlan && !ws.isComment && (
|
||||
<span className="badge ms-2" title="Wird vom Stundenguthaben des Wartungs-Abos abgezogen" style={{
|
||||
background: '#9d3dfe'
|
||||
}}>
|
||||
Abo-Stunden
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{/* Collapsed: Mitarbeiter & Zeit im Header */}
|
||||
{!isExpanded && (
|
||||
@@ -165,6 +172,27 @@ export default function WorksheetList({ worksheets, totalTime, loading, onEditTi
|
||||
<FaClock className="me-1" /> Zeit nachtragen
|
||||
</button>
|
||||
)}
|
||||
{onTogglePlan && !ws.isComment && Number(ws.totalTime) > 0 && (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm"
|
||||
title={ws.countsToPlan ? 'Nicht mehr vom Abo-Stundenkonto abziehen' : 'Vom Abo-Stundenkonto des Kunden abziehen'}
|
||||
style={{
|
||||
background: ws.countsToPlan ? '#9d3dfe' : 'rgba(255,255,255,0.15)',
|
||||
color: 'white',
|
||||
border: '1px solid rgba(255,255,255,0.4)',
|
||||
borderRadius: '6px',
|
||||
padding: '2px 10px',
|
||||
fontSize: '0.8rem',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
onTogglePlan(ws)
|
||||
}}
|
||||
>
|
||||
{ws.countsToPlan ? '✓ Abo' : '+ Abo'}
|
||||
</button>
|
||||
)}
|
||||
<small style={{ opacity: 0.9 }}>
|
||||
{formatDateTime(ws.startDate, ws.startTime) || formatDateTime(ws.endDate, ws.endTime)}
|
||||
</small>
|
||||
|
||||
@@ -340,6 +340,7 @@ export function useWorksheets(woid = null) {
|
||||
endTime: data.endTime || '',
|
||||
details: data.details.trim(),
|
||||
isComment: data.isComment || false,
|
||||
countsToPlan: !data.isComment && Boolean(data.countsToPlan),
|
||||
createdAt: new Date().toISOString()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user