What I'm trying to do is when customers submit a job request, which is the RequestJobConfirmationController, I want to be able to pull up the FindEmployeeJobRequestController on the customer side and CustomerJobRequestController on the employee's side when the customer is searching for an employee. Right now, I'm having trouble bringing up CustomerJobRequestController when I reach the FindEmployeeJobRequestController on the customer side. Also, I need to pull up the CustomerJobRequestController when the jobRequest businessId matches employees' businessId, and then have the employee's statusAvailability set to true, and then send the jobRequest to the first position's employee. Let me know if you need more details of what I need, thank you!
Service
// MARK: - CustomerService
struct CustomerService {
static func uploadCustomerAndJobRequest(jobDetails: JobDetailCredentials, completion: CollectionCompletion) {
guard let uid = Auth.auth().currentUser?.uid else { return }
let values = ["fullname" : jobDetails.fullname,
"username" : jobDetails.username,
"businessName" : jobDetails.businessName,
"businessId" : jobDetails.businessId,
"address" : jobDetails.address,
"firstDateAndTimes" : jobDetails.firstDateAndTimes,
"secondDateAndTimes" : jobDetails.secondDateAndTimes,
"thirdDateAndTimes" : jobDetails.thirdDateAndTimes,
"timeConstraints" : jobDetails.timeConstraints,
"jobDescription" : jobDetails.jobDescription,
"timestamp" : Timestamp(date: Date())] as [String : Any]
REF_JOB_REQUEST_DETAILS.document(uid).collection("job-request-details").addDocument(data: values, completion: completion)
}
static func observeCurrentCustomerJobRequest(completion: @escaping(JobRequest) -> Void) {
guard let uid = Auth.auth().currentUser?.uid else { return }
REF_JOB_REQUEST_DETAILS.document(uid).collection("job-request-details").order(by: "timestamp").addSnapshotListener { snapshot, error in
snapshot?.documentChanges.forEach({ change in
let dictionary = change.document.data()
let jobRequest = JobRequest(customerUid: uid, dictionary: dictionary)
completion(jobRequest)
})
}
}
static func fetchCustomerJobRequest(uid: String, completion: @escaping(JobRequest) -> Void) {
// 'Confirm Job' called once user taps button.
guard let uid = Auth.auth().currentUser?.uid else { return }
let query = REF_JOB_REQUEST_DETAILS.document(uid).collection("job-request-details").order(by: "timestamp")
query.addSnapshotListener { snapshot, error in
snapshot?.documentChanges.forEach({ change in
let dictionary = change.document.data()
let jobRequest = JobRequest(customerUid: uid, dictionary: dictionary)
completion(jobRequest)
})
}
}
static func fetchEmployeesForJobRequest(completion: @escaping ([Employee]) -> Void) {
guard let uid = Auth.auth().currentUser?.uid else { return }
let query = REF_JOB_REQUEST_DETAILS.document(uid).collection("job-request-details").order(by: "timestamp")
query.addSnapshotListener { snapshot, error in
if let error = error {
print("Error fetching job request document: \(error.localizedDescription)")
completion([])
return
}
guard let documents = snapshot?.documents, !documents.isEmpty else {
print("No job request document found")
completion([])
return
}
let jobRequestData = documents[0].data()
guard let businessId = jobRequestData["businessId"] as? String else {
print("Business ID not found in job request document")
completion([])
return
}
REF_EMPLOYEES.whereField("businessId", isEqualTo: businessId)
.whereField("statusAvailability", isEqualTo: true)
.getDocuments { snapshot, error in
if let error = error {
print("Error fetching employees: \(error.localizedDescription)")
completion([])
return
}
var employees = [Employee]()
for document in snapshot?.documents ?? [] {
let data = document.data()
let employee = Employee(dictionary: data)
employees.append(employee)
}
completion(employees)
}
}
}
}
RequestJobConfirmationController
class RequestJobConfirmationController: UIViewController {
// MARK: - Properties
var findEmployeeController: FindEmployeeJobRequestController!
// MARK: - Selectors
@objc func handleConfirm() {
let jobDetails = JobDetailCredentials(fullname: fullname, username: username, businessName: businessName, businessId: selectedCompanyID,
address: address, firstDateAndTimes: firstDateAndTimes, secondDateAndTimes: secondDateAndTimes,
thirdDateAndTimes: thirdDateAndTimes, timeConstraints: timeConstraints,
jobDescription: jobDescription)
CustomerService.uploadCustomerAndJobRequest(jobDetails: jobDetails) { error in
if let _ = error {
self.simpleAlert(title: "Error", msg: "Unable to upload job details, please try again later.")
return
}
let controller = FindEmployeeJobRequestController()
controller.delegate = self
self.findEmployeeController = controller
controller.modalPresentationStyle = .fullScreen
self.present(controller, animated: true, completion: nil)
}
}
}
// MARK: - FindEmployeeJobRequestDelegate
extension RequestJobConfirmationController: FindEmployeeJobRequestDelegate {
func didConfirmJobRequest() {
guard let jobRequest = self.jobRequest else { return }
let controller = CustomerJobRequestController(jobRequest: jobRequest)
present(controller, animated: true)
}
}
FindEmployeeJobRequestController
protocol FindEmployeeJobRequestDelegate: AnyObject {
func didConfirmJobRequest()
}
class FindEmployeeJobRequestController: UIViewController {
// MARK: - Properties
weak var delegate: FindEmployeeJobRequestDelegate?
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
fetchCustomerJobRequest()
fetchEmployeesForJobRequest()
}
// MARK: - API
func fetchCustomerJobRequest() {
guard let uid = Auth.auth().currentUser?.uid else { return }
CustomerService.fetchCustomerJobRequest(uid: uid) { jobRequest in
self.jobRequest = jobRequest
}
}
func fetchEmployeesForJobRequest() {
CustomerService.fetchEmployeesForJobRequest { employees in
self.employees = employees
print("DEBUG: Employee array \(employees)")
}
}
func confirmJobRequest() {
delegate?.didConfirmJobRequest()
}
}
CustomerJobRequestController
class CustomerJobRequestController: UIViewController, FindEmployeeJobRequestDelegate {
// MARK: - Properties
let jobRequest: JobRequest
var availableEmployees: [Employee] = []
var lastSelectedEmployeeIndex = 0
// MARK: - Lifecycle
init(jobRequest: JobRequest) {
self.jobRequest = jobRequest
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - API
// MARK: - Helper Functions
func filterAvailableEmployees() -> [Employee] {
let filteredEmployees = availableEmployees.filter { $0.position == 1 && $0.statusAvailability == true }
return filteredEmployees
}
func getNextAvailableEmployee() -> Employee? {
let filteredEmployees = filterAvailableEmployees()
guard !filteredEmployees.isEmpty else {
return nil
}
let nextEmployee = filteredEmployees[lastSelectedEmployeeIndex]
lastSelectedEmployeeIndex = (lastSelectedEmployeeIndex + 1) % filteredEmployees.count
return nextEmployee
}
func initiateJobRequest() {
if let nextEmployee = getNextAvailableEmployee() {
let jobRequestData = prepareJobRequest(employee: nextEmployee)
let jobRequest = JobRequest(customerUid: "", dictionary: jobRequestData)
let controller = CustomerJobRequestController(jobRequest: jobRequest)
present(controller, animated: true, completion: nil)
} else {
print("No available employees.")
}
}
func prepareJobRequest(employee: Employee) -> [String : Any] {
var jobRequestData: [String : Any] = [:]
jobRequestData["employeeUid"] = employee.uid
jobRequestData["customerUid"] = jobRequest.customerUid
jobRequestData["fullname"] = jobRequest.fullname
jobRequestData["username"] = jobRequest.username
jobRequestData["businessName"] = jobRequest.businessName
jobRequestData["businessId"] = jobRequest.businessId
jobRequestData["address"] = jobRequest.address
jobRequestData["firstDateAndTimes"] = jobRequest.firstDateAndTimes
jobRequestData["secondDateAndTimes"] = jobRequest.secondDateAndTimes
jobRequestData["thirdDateAndTimes"] = jobRequest.thirdDateAndTimes
jobRequestData["timeConstraints"] = jobRequest.timeConstraints
jobRequestData["jobDescription"] = jobRequest.jobDescription
jobRequestData["timestamp"] = jobRequest.timestamp
jobRequestData["state"] = jobRequest.state
return jobRequestData
}
func didSelectEmployee() {
if let nextEmployee = getNextAvailableEmployee() {
print("Selected Employee: \(nextEmployee.fullname)")
initiateJobRequest()
} else {
simpleAlert(title: "Error", msg: "No available employees match the criteria.")
}
}
func didConfirmJobRequest() {
initiateJobRequest()
}
}