marco.pms.mobileapp/lib/controller/service_project/add_service_project_job_controller.dart

111 lines
3.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:on_field_work/helpers/services/api_service.dart';
import 'package:on_field_work/helpers/widgets/my_snackbar.dart';
import 'package:on_field_work/controller/service_project/service_project_details_screen_controller.dart';
import 'package:on_field_work/model/employees/employee_model.dart';
import 'package:on_field_work/model/service_project/service_project_branches_model.dart';
class AddServiceProjectJobController extends GetxController {
// FORM CONTROLLERS
final titleCtrl = TextEditingController();
final descCtrl = TextEditingController();
final tagCtrl = TextEditingController();
final searchFocusNode = FocusNode();
// OBSERVABLES
final startDate = Rx<DateTime?>(DateTime.now());
final dueDate = Rx<DateTime?>(DateTime.now().add(const Duration(days: 1)));
final enteredTags = <String>[].obs;
final selectedAssignees = <EmployeeModel>[].obs;
// Branches
final branches = <Branch>[].obs;
final selectedBranch = Rxn<Branch>();
final isBranchLoading = false.obs;
// Loading
final isLoading = false.obs;
@override
void onClose() {
titleCtrl.dispose();
descCtrl.dispose();
tagCtrl.dispose();
searchFocusNode.dispose();
super.onClose();
}
// FETCH BRANCHES
Future<void> fetchBranches(String projectId) async {
isBranchLoading.value = true;
final response = await ApiService.getServiceProjectBranchesFull(
projectId: projectId,
);
if (response != null && response.success) {
branches.assignAll(response.data?.data ?? []);
}
isBranchLoading.value = false;
}
// CREATE JOB
Future<void> createJob(String projectId) async {
if (titleCtrl.text.trim().isEmpty || descCtrl.text.trim().isEmpty) {
showAppSnackbar(
title: "Validation",
message: "Title and Description are required",
type: SnackbarType.warning,
);
return;
}
isLoading.value = true;
final jobId = await ApiService.createServiceProjectJobApi(
title: titleCtrl.text.trim(),
description: descCtrl.text.trim(),
projectId: projectId,
branchId: selectedBranch.value?.id,
assignees: selectedAssignees // payload mapping
.map((e) => {"employeeId": e.id, "isActive": true})
.toList(),
startDate: startDate.value!,
dueDate: dueDate.value!,
tags: enteredTags
.map((tag) => {"id": null, "name": tag, "isActive": true})
.toList(),
);
isLoading.value = false;
if (jobId != null) {
if (Get.isRegistered<ServiceProjectDetailsController>()) {
final detailsCtrl = Get.find<ServiceProjectDetailsController>();
// 🔥 1. Refresh job LIST
detailsCtrl.refreshJobsAfterAdd();
// 🔥 2. Refresh job DETAILS (FULL DATA - including tags and assignees)
await detailsCtrl.fetchJobDetail(jobId);
}
Get.back();
showAppSnackbar(
title: "Success",
message: "Job created successfully",
type: SnackbarType.success,
);
} else {
showAppSnackbar(
title: "Error",
message: "Failed to create job",
type: SnackbarType.error,
);
}
}
}