Add role-aware cash collection for staff vs admin
Parse RoleID from myBusinesses API. CashCollectionSheet now shows role-appropriate messaging: staff keeps cash, admin deposits to business. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8d604649a2
commit
bbdc5a91c2
6 changed files with 47 additions and 6 deletions
|
|
@ -456,7 +456,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.2;
|
MARKETING_VERSION = 1.0.4;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
|
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
|
||||||
PRODUCT_NAME = "Payfrit Works";
|
PRODUCT_NAME = "Payfrit Works";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
|
@ -488,7 +488,7 @@
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.2;
|
MARKETING_VERSION = 1.0.4;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
|
PRODUCT_BUNDLE_IDENTIFIER = com.mizerek.payfritworks;
|
||||||
PRODUCT_NAME = "Payfrit Works";
|
PRODUCT_NAME = "Payfrit Works";
|
||||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ struct Employment: Identifiable {
|
||||||
let employeeStatusId: Int
|
let employeeStatusId: Int
|
||||||
let pendingTaskCount: Int
|
let pendingTaskCount: Int
|
||||||
let activeTaskCount: Int
|
let activeTaskCount: Int
|
||||||
|
let roleId: Int // 1=Staff, 2=Manager, 3=Admin
|
||||||
|
|
||||||
var id: Int { employeeId }
|
var id: Int { employeeId }
|
||||||
|
|
||||||
|
|
@ -24,6 +25,7 @@ struct Employment: Identifiable {
|
||||||
employeeStatusId = WorkTask.parseInt(json["EmployeeStatusID"] ?? json["StatusID"]) ?? 0
|
employeeStatusId = WorkTask.parseInt(json["EmployeeStatusID"] ?? json["StatusID"]) ?? 0
|
||||||
pendingTaskCount = WorkTask.parseInt(json["PendingTaskCount"]) ?? 0
|
pendingTaskCount = WorkTask.parseInt(json["PendingTaskCount"]) ?? 0
|
||||||
activeTaskCount = WorkTask.parseInt(json["ActiveTaskCount"]) ?? 0
|
activeTaskCount = WorkTask.parseInt(json["ActiveTaskCount"]) ?? 0
|
||||||
|
roleId = WorkTask.parseInt(json["RoleID"] ?? json["ROLEID"] ?? json["roleId"] ?? json["role_id"]) ?? 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusName: String {
|
var statusName: String {
|
||||||
|
|
@ -34,4 +36,14 @@ struct Employment: Identifiable {
|
||||||
default: return "Unknown"
|
default: return "Unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Human-readable role name derived from roleId
|
||||||
|
var roleName: String {
|
||||||
|
switch roleId {
|
||||||
|
case 1: return "Staff"
|
||||||
|
case 2: return "Manager"
|
||||||
|
case 3: return "Admin"
|
||||||
|
default: return "Staff"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ final class AppState: ObservableObject {
|
||||||
@Published var userPhotoUrl: String?
|
@Published var userPhotoUrl: String?
|
||||||
@Published var userToken: String?
|
@Published var userToken: String?
|
||||||
@Published var businessId: Int = 0
|
@Published var businessId: Int = 0
|
||||||
|
@Published var roleId: Int = 1 // 1=Staff, 2=Manager, 3=Admin
|
||||||
@Published var isAuthenticated = false
|
@Published var isAuthenticated = false
|
||||||
@Published var shouldPopToRoot = false
|
@Published var shouldPopToRoot = false
|
||||||
@Published var shouldPopToTaskList = false
|
@Published var shouldPopToTaskList = false
|
||||||
|
|
@ -34,8 +35,19 @@ final class AppState: ObservableObject {
|
||||||
self.isAuthenticated = true
|
self.isAuthenticated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func setBusinessId(_ id: Int) {
|
func setBusinessId(_ id: Int, roleId: Int = 1) {
|
||||||
self.businessId = id
|
self.businessId = id
|
||||||
|
self.roleId = roleId
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Human-readable role name
|
||||||
|
var roleName: String {
|
||||||
|
switch roleId {
|
||||||
|
case 1: return "Staff"
|
||||||
|
case 2: return "Manager"
|
||||||
|
case 3: return "Admin"
|
||||||
|
default: return "Staff"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearAuth() {
|
func clearAuth() {
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ struct BusinessSelectionScreen: View {
|
||||||
TaskListScreen(businessName: biz.businessName)
|
TaskListScreen(businessName: biz.businessName)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
Task { await APIService.shared.setBusinessId(biz.businessId) }
|
Task { await APIService.shared.setBusinessId(biz.businessId) }
|
||||||
appState.setBusinessId(biz.businessId)
|
appState.setBusinessId(biz.businessId, roleId: biz.roleId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ struct ProfileScreen: View {
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
Text("Worker")
|
Text(appState.roleName)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +68,7 @@ struct ProfileScreen: View {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
infoRow(icon: "person.fill", label: "Name", value: displayName)
|
infoRow(icon: "person.fill", label: "Name", value: displayName)
|
||||||
Divider().padding(.leading, 54)
|
Divider().padding(.leading, 54)
|
||||||
infoRow(icon: "briefcase.fill", label: "Role", value: "Worker")
|
infoRow(icon: "briefcase.fill", label: "Role", value: appState.roleName)
|
||||||
}
|
}
|
||||||
.background(Color(.secondarySystemGroupedBackground))
|
.background(Color(.secondarySystemGroupedBackground))
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
|
.clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ struct TaskDetailScreen: View {
|
||||||
CashCollectionSheet(
|
CashCollectionSheet(
|
||||||
orderTotalCents: orderTotalCents,
|
orderTotalCents: orderTotalCents,
|
||||||
taskId: task.taskId,
|
taskId: task.taskId,
|
||||||
|
roleId: appState.roleId,
|
||||||
onComplete: { appState.popToRoot() }
|
onComplete: { appState.popToRoot() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -762,6 +763,7 @@ struct TaskDetailScreen: View {
|
||||||
struct CashCollectionSheet: View {
|
struct CashCollectionSheet: View {
|
||||||
let orderTotalCents: Int
|
let orderTotalCents: Int
|
||||||
let taskId: Int
|
let taskId: Int
|
||||||
|
let roleId: Int // 1=Staff, 2=Manager, 3=Admin
|
||||||
let onComplete: () -> Void
|
let onComplete: () -> Void
|
||||||
|
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
@ -769,6 +771,8 @@ struct CashCollectionSheet: View {
|
||||||
@State private var isProcessing = false
|
@State private var isProcessing = false
|
||||||
@State private var errorMessage: String?
|
@State private var errorMessage: String?
|
||||||
|
|
||||||
|
private var isAdmin: Bool { roleId >= 2 }
|
||||||
|
|
||||||
private var orderTotalDollars: Double { Double(orderTotalCents) / 100 }
|
private var orderTotalDollars: Double { Double(orderTotalCents) / 100 }
|
||||||
|
|
||||||
private var cashReceivedCents: Int? {
|
private var cashReceivedCents: Int? {
|
||||||
|
|
@ -848,6 +852,19 @@ struct CashCollectionSheet: View {
|
||||||
.cornerRadius(12)
|
.cornerRadius(12)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Role-based cash routing info
|
||||||
|
HStack(spacing: 8) {
|
||||||
|
Image(systemName: isAdmin ? "building.2.fill" : "person.fill")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
Text(isAdmin ? "Cash will be deposited to the business register" : "Cash will be applied to your balance")
|
||||||
|
.font(.callout)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
.padding(12)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.background(Color(.systemGray6))
|
||||||
|
.cornerRadius(10)
|
||||||
|
|
||||||
if let err = errorMessage {
|
if let err = errorMessage {
|
||||||
Text(err)
|
Text(err)
|
||||||
.font(.callout)
|
.font(.callout)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue