86 lines
3.2 KiB
Swift
86 lines
3.2 KiB
Swift
// Models/LocalScheduledInspection.swift
|
|
// --------------------------------------
|
|
// SwiftData model for planned/recurring inspection assignments (phase36).
|
|
//
|
|
// Read-only reference data pulled from the server (GET /api/v1/scheduled-inspections)
|
|
// and refreshed by SyncManager.pullScheduledInspections() — never created or
|
|
// mutated on device. Surfaced in the "Scheduled" section on the Dashboard and
|
|
// My Inspections. Tapping "Start" opens the normal new-inspection flow with the
|
|
// facility + template preselected; the schedule lifecycle (fulfil / roll-forward)
|
|
// stays server-driven.
|
|
//
|
|
// Follows the same pattern as LocalFacility / LocalArea: a `.unique` serverId
|
|
// WITHOUT an inline default (a default on the unique key breaks @Model's
|
|
// PersistentModel conformance) and a full init(from:)/update(from:) pair.
|
|
|
|
import Foundation
|
|
import SwiftData
|
|
|
|
@Model
|
|
final class LocalScheduledInspection {
|
|
|
|
/// Server ID of the ScheduledInspection row — stable unique identity.
|
|
@Attribute(.unique) var serverId: Int
|
|
|
|
var facilityServerId: Int
|
|
var facilityName: String
|
|
var templateServerId: Int
|
|
var templateName: String
|
|
var inspectorId: Int?
|
|
|
|
var frequency: String // once | daily | weekly | monthly
|
|
var frequencyLabel: String
|
|
|
|
/// Raw server date string "YYYY-MM-DD" — sortable (ISO strings sort
|
|
/// chronologically) and the source for the parsed `nextDue`.
|
|
var dueDateString: String
|
|
|
|
var isOverdue: Bool
|
|
var notes: String?
|
|
|
|
/// Last time this row was refreshed from the server pull.
|
|
var updatedAt: Date
|
|
|
|
/// Parsed due date for display. Computed properties are not persisted by
|
|
/// SwiftData; sort on `dueDateString` (not this) in @Query.
|
|
var nextDue: Date? {
|
|
Self.dateOnlyFormatter.date(from: dueDateString)
|
|
}
|
|
|
|
private static let dateOnlyFormatter: DateFormatter = {
|
|
let f = DateFormatter()
|
|
f.locale = Locale(identifier: "en_US_POSIX")
|
|
f.dateFormat = "yyyy-MM-dd"
|
|
return f
|
|
}()
|
|
|
|
init(from api: APIScheduledInspection) {
|
|
self.serverId = api.id
|
|
self.facilityServerId = api.facilityId
|
|
self.facilityName = api.facilityName ?? ""
|
|
self.templateServerId = api.templateId
|
|
self.templateName = api.templateName ?? ""
|
|
self.inspectorId = api.inspectorId
|
|
self.frequency = api.frequency
|
|
self.frequencyLabel = api.frequencyLabel ?? ""
|
|
self.dueDateString = api.nextDueDate ?? ""
|
|
self.isOverdue = api.isOverdue
|
|
self.notes = api.notes
|
|
self.updatedAt = Date()
|
|
}
|
|
|
|
func update(from api: APIScheduledInspection) {
|
|
self.facilityServerId = api.facilityId
|
|
self.facilityName = api.facilityName ?? ""
|
|
self.templateServerId = api.templateId
|
|
self.templateName = api.templateName ?? ""
|
|
self.inspectorId = api.inspectorId
|
|
self.frequency = api.frequency
|
|
self.frequencyLabel = api.frequencyLabel ?? ""
|
|
self.dueDateString = api.nextDueDate ?? ""
|
|
self.isOverdue = api.isOverdue
|
|
self.notes = api.notes
|
|
self.updatedAt = Date()
|
|
}
|
|
}
|