05/05 Update the API to follow-up and resinspection
This commit is contained in:
@@ -23,6 +23,16 @@ struct StartInspectionView: View {
|
||||
|
||||
@EnvironmentObject private var auth: AuthManager
|
||||
|
||||
// ── Pre-fill for re-inspections ───────────────────────────────────────
|
||||
/// When launching from a "Start Re-inspection" button, these are set so
|
||||
/// the form opens with the parent's template and facility pre-selected.
|
||||
var preFillTemplateId: Int? = nil
|
||||
var preFillFacilityId: Int? = nil
|
||||
var parentServerId: Int? = nil
|
||||
/// Local UUID of the parent — always available, used by SyncManager to
|
||||
/// clear the parent's followUpRequired badge after the re-inspection syncs.
|
||||
var parentLocalId: String? = nil
|
||||
|
||||
private var selectedFacility: LocalFacility? {
|
||||
facilities.first { $0.serverId == selectedFacilityId }
|
||||
}
|
||||
@@ -38,6 +48,24 @@ struct StartInspectionView: View {
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
Form {
|
||||
// ── Re-inspection notice ───────────────────────────────────
|
||||
if parentServerId != nil {
|
||||
Section {
|
||||
HStack(spacing: 10) {
|
||||
Image(systemName: "arrow.uturn.right.circle.fill")
|
||||
.foregroundStyle(.orange)
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text("Re-inspection")
|
||||
.font(.callout.bold())
|
||||
Text("This will be linked to inspection #\(parentServerId!).")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 4)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Template picker ────────────────────────────────────────
|
||||
Section("Inspection Template") {
|
||||
if templates.isEmpty {
|
||||
@@ -104,15 +132,20 @@ struct StartInspectionView: View {
|
||||
} label: {
|
||||
HStack {
|
||||
Spacer()
|
||||
Label("Start Inspection", systemImage: "play.circle.fill")
|
||||
.font(.headline)
|
||||
Label(
|
||||
parentServerId != nil ? "Start Re-inspection" : "Start Inspection",
|
||||
systemImage: parentServerId != nil
|
||||
? "arrow.uturn.right.circle.fill"
|
||||
: "play.circle.fill"
|
||||
)
|
||||
.font(.headline)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.disabled(!canStart)
|
||||
}
|
||||
}
|
||||
.navigationTitle("New Inspection")
|
||||
.navigationTitle(parentServerId != nil ? "Re-inspection" : "New Inspection")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
@@ -124,6 +157,11 @@ struct StartInspectionView: View {
|
||||
ExecuteInspectionView(inspection: inspection)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
// Apply pre-fill from re-inspection launch
|
||||
if let tid = preFillTemplateId { selectedTemplateId = tid }
|
||||
if let fid = preFillFacilityId { selectedFacilityId = fid }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +176,50 @@ struct StartInspectionView: View {
|
||||
areaServerId: selectedAreaId,
|
||||
inspectorUserId: auth.currentUserId
|
||||
)
|
||||
// Link to parent if this is a re-inspection
|
||||
inspection.parentServerId = parentServerId
|
||||
inspection.parentLocalId = parentLocalId
|
||||
|
||||
// ── Pre-fill from parent (mirrors web app behaviour) ───────────────
|
||||
// Copy non-scoring field values from the parent inspection so the
|
||||
// inspector doesn't re-enter static data. Scoring fields (rating,
|
||||
// pass_fail) and media fields (image, signature) are always left blank
|
||||
// so every scoreable item must be re-evaluated fresh.
|
||||
if let parentId = parentServerId {
|
||||
let allInspections = try? context.fetch(FetchDescriptor<LocalInspection>())
|
||||
if let parent = allInspections?.first(where: { $0.serverId == parentId }),
|
||||
!parent.formData.isEmpty {
|
||||
|
||||
// Fetch the template schema to identify field types
|
||||
let tid = templateId
|
||||
let schema = (try? context.fetch(
|
||||
FetchDescriptor<LocalTemplate>(predicate: #Predicate { $0.serverId == tid })
|
||||
).first?.formSchema) ?? []
|
||||
|
||||
// Build the set of field IDs that must NOT be carried over
|
||||
let excludeTypes: Set<String> = ["rating", "pass_fail", "image", "signature"]
|
||||
var excludeIds = Set<String>()
|
||||
for field in schema {
|
||||
if let type_ = field["type"] as? String, excludeTypes.contains(type_),
|
||||
let id = field["id"] {
|
||||
excludeIds.insert("\(id)")
|
||||
}
|
||||
}
|
||||
|
||||
// Copy all parent values except excluded fields
|
||||
let parentData = parent.formData
|
||||
var prefilled: [String: Any] = [:]
|
||||
for (key, value) in parentData {
|
||||
if !excludeIds.contains(key) {
|
||||
prefilled[key] = value
|
||||
}
|
||||
}
|
||||
if !prefilled.isEmpty {
|
||||
inspection.formData = prefilled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.insert(inspection)
|
||||
try? context.save()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user