Commit a5f65ab1 authored by Sai Srinivas's avatar Sai Srinivas Committed by Sai Srinivas
Browse files

03-09-2025 HRM accessible pages and attendance/ leave approval/rejection

parent 332a8e91
class ogresponse {
String? id;
String? name;
String? title;
String? profile;
List<Children>? children;
String? error;
String? message;
int? sessionExists;
ogresponse(
{this.id,
this.name,
this.title,
this.profile,
this.children,
this.error,
this.message,
this.sessionExists});
ogresponse.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
title = json['title'];
profile = json['profile'];
if (json['children'] != null) {
children = <Children>[];
json['children'].forEach((v) {
children!.add(new Children.fromJson(v));
});
}
error = json['error'];
message = json['message'];
sessionExists = json['session_exists'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['title'] = this.title;
data['profile'] = this.profile;
if (this.children != null) {
data['children'] = this.children!.map((v) => v.toJson()).toList();
}
data['error'] = this.error;
data['message'] = this.message;
data['session_exists'] = this.sessionExists;
return data;
}
}
class Children {
String? id;
String? name;
String? title;
String? profile;
List<Children>? children;
Children({this.id, this.name, this.title, this.profile, this.children});
Children.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
title = json['title'];
profile = json['profile'];
if (json['children'] != null) {
children = <Children>[];
json['children'].forEach((v) {
children!.add(new Children.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['title'] = this.title;
data['profile'] = this.profile;
if (this.children != null) {
data['children'] = this.children!.map((v) => v.toJson()).toList();
}
return data;
}
}
...@@ -9,7 +9,7 @@ import '../Utils/BackgroundLocationService.dart'; ...@@ -9,7 +9,7 @@ import '../Utils/BackgroundLocationService.dart';
class LogoutNotifier extends ChangeNotifier{ class LogoutNotifier extends ChangeNotifier{
bool _logoutButtonClicked = true; bool _logoutButtonClicked = false;
bool _isLoading = false; bool _isLoading = false;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
......
...@@ -16,7 +16,7 @@ import 'approveRejectPaymentRequestResponse.dart'; ...@@ -16,7 +16,7 @@ import 'approveRejectPaymentRequestResponse.dart';
class Requesitionlidtdetailsprovider extends ChangeNotifier { class Requesitionlidtdetailsprovider extends ChangeNotifier {
bool _showMoreDetails = false; bool _showMoreDetails = false;
final numberFormat = NumberFormat.decimalPattern();
TextEditingController requestedAmount = TextEditingController(); TextEditingController requestedAmount = TextEditingController();
TextEditingController approvedAmountReadonly = TextEditingController(); TextEditingController approvedAmountReadonly = TextEditingController();
TextEditingController proposedPaymentAccount = TextEditingController(); TextEditingController proposedPaymentAccount = TextEditingController();
...@@ -35,6 +35,13 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier { ...@@ -35,6 +35,13 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
TextEditingController bankHolderName = TextEditingController(); TextEditingController bankHolderName = TextEditingController();
TextEditingController paymentAccountSearchController = TextEditingController paymentAccountSearchController =
TextEditingController(); TextEditingController();
TextEditingController editPaymentRequestedAmountController = TextEditingController();
TextEditingController editPaymentRequestedEditableAmountController = TextEditingController();
bool _editPaymentProcessLoading = false;
String? editableAmountError;
String? proposedAmountError; String? proposedAmountError;
PaymentDetails _paymentDetails = PaymentDetails(); PaymentDetails _paymentDetails = PaymentDetails();
RequestDetails _requestDetails = RequestDetails(); RequestDetails _requestDetails = RequestDetails();
...@@ -61,12 +68,19 @@ String? proposedAmountError; ...@@ -61,12 +68,19 @@ String? proposedAmountError;
bool get showMoreDetails => _showMoreDetails; bool get showMoreDetails => _showMoreDetails;
bool get editPaymentProcessLoading => _editPaymentProcessLoading;
int get imagePicked => _image_picked; int get imagePicked => _image_picked;
File? get imagePath => _imageName; File? get imagePath => _imageName;
File? get imageFilePath => _image; File? get imageFilePath => _image;
set editPaymentProcessLoading(bool value){
_editPaymentProcessLoading = value;
notifyListeners();
}
set imagePicked(int value) { set imagePicked(int value) {
_image_picked = value; _image_picked = value;
notifyListeners(); notifyListeners();
...@@ -329,6 +343,9 @@ String? proposedAmountError; ...@@ -329,6 +343,9 @@ String? proposedAmountError;
} catch (e, s) {} } catch (e, s) {}
} }
String? remarksError; String? remarksError;
String? ApprovedAmountError; String? ApprovedAmountError;
String? selectpaymentAccountError; String? selectpaymentAccountError;
...@@ -407,6 +424,95 @@ String? proposedAmountError; ...@@ -407,6 +424,95 @@ String? proposedAmountError;
} catch (e, s) {} } catch (e, s) {}
} }
editPrevalues(){
editPaymentRequestedAmountController.text = _requestDetails.requestedAmount ?? "-";
editPaymentRequestedEditableAmountController.text = _requestDetails.requestedAmount ?? "-";
notifyListeners();
}
onChangeEditableAmount(value,context){
var provider = Provider.of<HomescreenNotifier>(context, listen: false);
if(provider.empId=="5" || provider.empId=="130" || provider.empId=="131"||provider.empId =="6"){
editableAmountError =
"";
}else{
if (numberFormat.parse(editPaymentRequestedAmountController.text) <
numberFormat.parse(editPaymentRequestedEditableAmountController.text)) {
editableAmountError =
"Approved Amount should not be greater than amount";
} else {
editableAmountError = null;
}
}
_editPaymentProcessLoading = false;
notifyListeners();
}
bool validateEditprocessPayment(context){
bool isValid = true;
editableAmountError = null;
var provider = Provider.of<HomescreenNotifier>(context, listen: false);
if(editPaymentRequestedEditableAmountController.text.isNotEmpty){
if(provider.empId=="5" || provider.empId=="130" || provider.empId=="131" ||provider.empId =="6"){
editableAmountError = null;
}else{
if (numberFormat.parse(editPaymentRequestedAmountController.text) <
numberFormat.parse(editPaymentRequestedEditableAmountController.text)) {
editableAmountError =
"Approved Amount should not be greater than amount";
isValid = false;
} else {
editableAmountError = null;
}
}
}
_editPaymentProcessLoading = false;
notifyListeners();
return isValid;
}
Future<void> editProcessedPaymentAmountAPIFunction(context,
payment_request_id,approval_amount) async {
try {
_editPaymentProcessLoading = true;
notifyListeners();
if(!validateEditprocessPayment(context)){
return;
}
var provider = Provider.of<HomescreenNotifier>(context, listen: false);
final data = await ApiCalling.editProcessedRequestAmountAPI(
provider.empId,
provider.session,
payment_request_id,
approval_amount
);
if (data != null) {
if (data.error == "0") {
_editPaymentProcessLoading = false;
paymentRequesitionDetails(context, payment_request_id);
resetAll();
toast(context, data.message);
Navigator.pop(context,true);
notifyListeners();
}else{
_editPaymentProcessLoading = false;
notifyListeners();
}
}else{
_editPaymentProcessLoading = false;
notifyListeners();
}
} catch (e, s) {
_editPaymentProcessLoading = false;
notifyListeners();
}
}
bool validateApproval(approved_amount, bool validateApproval(approved_amount,
approve_remarks, approve_remarks,
proposed_payment_account_id,){ proposed_payment_account_id,){
...@@ -476,6 +582,10 @@ String? proposedAmountError; ...@@ -476,6 +582,10 @@ String? proposedAmountError;
resetAll() { resetAll() {
checkDropDownReset(); checkDropDownReset();
editPaymentRequestedAmountController.clear();
editPaymentRequestedEditableAmountController.clear();
_editPaymentProcessLoading = false;
editableAmountError = null;
requestedAmount.clear(); requestedAmount.clear();
proposedPaymentAccount.clear(); proposedPaymentAccount.clear();
approvedAmountReadonly.clear(); approvedAmountReadonly.clear();
......
...@@ -576,14 +576,12 @@ class Requestionlistprovider extends ChangeNotifier { ...@@ -576,14 +576,12 @@ class Requestionlistprovider extends ChangeNotifier {
payment_date, payment_date,
) async { ) async {
try { try {
_submitClicked = true;
notifyListeners();
if (!validateDirectForm(context)) { if (!validateDirectForm(context)) {
print("came here");
_submitClicked = false;
return; return;
} }
_submitClicked = true;
notifyListeners();
var homeProvider = Provider.of<HomescreenNotifier>( var homeProvider = Provider.of<HomescreenNotifier>(
context, context,
listen: false, listen: false,
...@@ -1132,14 +1130,16 @@ class Requestionlistprovider extends ChangeNotifier { ...@@ -1132,14 +1130,16 @@ class Requestionlistprovider extends ChangeNotifier {
isValid = false; isValid = false;
_submitClicked = false; _submitClicked = false;
} }
if (["Cheque", "RTGS", "IMPS", "NEFT"].contains(_paymentModeValue)) {
if (bankNameController.text.trim().isEmpty) { if (bankNameController.text.trim().isEmpty) {
bankNameError = "Please enter bank name"; bankNameError = "Please enter bank name";
isValid = false; isValid = false;
_submitClicked = false; _submitClicked = false;
} }
if (["Cheque", "RTGS", "IMPS", "NEFT"].contains(_paymentModeValue)) {
if (bankBranchController.text.trim().isEmpty) { if (bankBranchController.text.trim().isEmpty) {
bankBranchError = "Please enter bank branch"; bankBranchError = "Please enter bank branch";
isValid = false; isValid = false;
...@@ -1271,6 +1271,7 @@ class Requestionlistprovider extends ChangeNotifier { ...@@ -1271,6 +1271,7 @@ class Requestionlistprovider extends ChangeNotifier {
// FileError = "Please attach a file"; // FileError = "Please attach a file";
// isValid = false; // isValid = false;
// } // }
_submitClicked = false;
notifyListeners(); notifyListeners();
return isValid; return isValid;
} }
......
...@@ -479,11 +479,12 @@ class Paymentreceiptsprovider extends ChangeNotifier { ...@@ -479,11 +479,12 @@ class Paymentreceiptsprovider extends ChangeNotifier {
receipt_date, receipt_date,
) async { ) async {
try { try {
_submitClicked = true;
notifyListeners();
if (!validatereceiptForm(context)) { if (!validatereceiptForm(context)) {
return; return;
} }
_submitClicked = true;
notifyListeners();
var homeProvider = Provider.of<HomescreenNotifier>( var homeProvider = Provider.of<HomescreenNotifier>(
context, context,
...@@ -515,15 +516,15 @@ class Paymentreceiptsprovider extends ChangeNotifier { ...@@ -515,15 +516,15 @@ class Paymentreceiptsprovider extends ChangeNotifier {
notifyListeners(); notifyListeners();
Navigator.of(context).pop(context); Navigator.of(context).pop(context);
} else { } else {
_submitClicked = true; _submitClicked = false;
notifyListeners(); notifyListeners();
} }
} else { } else {
_submitClicked = true; _submitClicked = false;
notifyListeners(); notifyListeners();
} }
} catch (e, s) { } catch (e, s) {
_submitClicked = true; _submitClicked = false;
notifyListeners(); notifyListeners();
} }
} }
...@@ -816,57 +817,47 @@ class Paymentreceiptsprovider extends ChangeNotifier { ...@@ -816,57 +817,47 @@ class Paymentreceiptsprovider extends ChangeNotifier {
bool isValid = true; bool isValid = true;
if (_selectedreceiptAccounts == null || _receiptAccountID.trim().isEmpty) { if (_selectedreceiptAccounts == null || _receiptAccountID.trim().isEmpty) {
selectAccountError = "Please select an Account"; selectAccountError = "Please select an Account";
_submitClicked = false;
isValid = false; isValid = false;
} }
if (_selectreceiptPaymentAccounts == null || if (_selectreceiptPaymentAccounts == null ||
_receiptPaymentAccountsID.isEmpty) { _receiptPaymentAccountsID.isEmpty) {
selectPaymentAccountError = "Please select an Account"; selectPaymentAccountError = "Please select an Account";
_submitClicked = false;
isValid = false; isValid = false;
} }
if (amountController.text.trim().isEmpty) { if (amountController.text.trim().isEmpty) {
amountError = "Please enter an amount"; amountError = "Please enter an amount";
_submitClicked = false;
isValid = false; isValid = false;
} }
if (dateController.text.trim().isEmpty || _formattedDate!.isEmpty) { if (dateController.text.trim().isEmpty || _formattedDate!.isEmpty) {
dateError = "Please select Date"; dateError = "Please select Date";
isValid = false; isValid = false;
_submitClicked = false;
} }
if (_selectreceiptPaymentModes == null || _receiptPaymentModesID.isEmpty) { if (_selectreceiptPaymentModes == null || _receiptPaymentModesID.isEmpty) {
selectPaymentError = "Please select a payment mode"; selectPaymentError = "Please select a payment mode";
isValid = false; isValid = false;
_submitClicked = false;
} }
if (["Cheque", "RTGS", "IMPS", "NEFT"].contains(_paymentModeValue)) { if (["Cheque", "RTGS", "IMPS", "NEFT"].contains(_paymentModeValue)) {
if (bankNameController.text.trim().isEmpty) { if (bankNameController.text.trim().isEmpty) {
bankNameError = "Please enter bank name"; bankNameError = "Please enter bank name";
isValid = false; isValid = false;
_submitClicked = false;
} }
if (bankBranchController.text.trim().isEmpty) { if (bankBranchController.text.trim().isEmpty) {
bankBranchError = "Please enter bank branch"; bankBranchError = "Please enter bank branch";
isValid = false; isValid = false;
_submitClicked = false;
} }
if (bankAccNumberController.text.trim().isEmpty) { if (bankAccNumberController.text.trim().isEmpty) {
bankNumberError = "Please enter account number"; bankNumberError = "Please enter account number";
isValid = false; isValid = false;
_submitClicked = false;
} }
if (bankIfscController.text.trim().isEmpty) { if (bankIfscController.text.trim().isEmpty) {
bankIFSCError = "Please enter IFSC code"; bankIFSCError = "Please enter IFSC code";
isValid = false; isValid = false;
_submitClicked = false;
} }
if (bankAcHolderController.text.trim().isEmpty) { if (bankAcHolderController.text.trim().isEmpty) {
bankHolderError = "Please enter account holder name"; bankHolderError = "Please enter account holder name";
isValid = false; isValid = false;
_submitClicked = false;
} }
} }
...@@ -874,18 +865,15 @@ class Paymentreceiptsprovider extends ChangeNotifier { ...@@ -874,18 +865,15 @@ class Paymentreceiptsprovider extends ChangeNotifier {
if (bankUpiController.text.trim().isEmpty) { if (bankUpiController.text.trim().isEmpty) {
UPIError = "Please enter UPI ID"; UPIError = "Please enter UPI ID";
isValid = false; isValid = false;
_submitClicked = false;
} }
} }
if (paymentReferenceController.text.trim().isEmpty) { if (paymentReferenceController.text.trim().isEmpty) {
paymentreferenceError = "please enter refernce number"; paymentreferenceError = "please enter refernce number";
isValid = false; isValid = false;
_submitClicked = false;
} }
if (descController.text.trim().isEmpty) { if (descController.text.trim().isEmpty) {
descriptionError = "Please Enter Description"; descriptionError = "Please Enter Description";
isValid = false; isValid = false;
_submitClicked = false;
} }
_submitClicked = false; _submitClicked = false;
notifyListeners(); notifyListeners();
......
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../Models/hrmModels/leaveApplicationDetailsResponse.dart'; import '../../Models/hrmModels/leaveApplicationDetailsResponse.dart';
import '../../Models/ordersModels/commonResponse.dart';
import '../../services/api_calling.dart'; import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart'; import '../HomeScreenNotifier.dart';
...@@ -9,6 +11,11 @@ class LeaveApplicationDetailsProvider extends ChangeNotifier { ...@@ -9,6 +11,11 @@ class LeaveApplicationDetailsProvider extends ChangeNotifier {
leaveApplicationDetailsResponse? _response; leaveApplicationDetailsResponse? _response;
bool _isLoading = false; bool _isLoading = false;
String? _errorMessage; String? _errorMessage;
bool _isSubmitting = false;
bool get isSubmitting => _isSubmitting;
CommonResponse? _StatusResponse;
CommonResponse? get addResponse => _StatusResponse;
leaveApplicationDetailsResponse? get response => _response; leaveApplicationDetailsResponse? get response => _response;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
...@@ -43,6 +50,60 @@ class LeaveApplicationDetailsProvider extends ChangeNotifier { ...@@ -43,6 +50,60 @@ class LeaveApplicationDetailsProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
Future<void> leaveRequestRejectApprove(
BuildContext context, {
required String mode,
required String type,
required String remarks,
required String id,
}) async {
_isSubmitting = true;
_errorMessage = null;
_StatusResponse = null;
notifyListeners();
try {
final homeProvider = Provider.of<HomescreenNotifier>(context, listen: false);
final result = await ApiCalling.leaveRequestRejectApproveAPI(
homeProvider.session,
homeProvider.empId,
mode,
type,
remarks,
id,
);
if (result != null) {
_StatusResponse = result;
if (result.error != null && result.error!.isNotEmpty) {
_errorMessage = result.error;
} else {
// Show success snack bar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"Leave request ${type.toLowerCase()} successfully.",
),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
),
);
}
} else {
_errorMessage = "Failed to $type leave request!";
}
} catch (e) {
_errorMessage = "Error while processing leave request: $e";
}
_isSubmitting = false;
notifyListeners();
}
/// Clear the current response data /// Clear the current response data
void clearData() { void clearData() {
_response = null; _response = null;
......
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:generp/Models/hrmModels/attendanceRequestDetailsResponse.dart'; import 'package:generp/Models/hrmModels/attendanceRequestDetailsResponse.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../Models/hrmModels/attendanceRequestListResponse.dart'; import '../../Models/hrmModels/attendanceRequestListResponse.dart';
import '../../Models/ordersModels/commonResponse.dart';
import '../../services/api_calling.dart'; import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart'; import '../HomeScreenNotifier.dart';
...@@ -12,6 +14,11 @@ class AttendanceDetailsProvider extends ChangeNotifier { ...@@ -12,6 +14,11 @@ class AttendanceDetailsProvider extends ChangeNotifier {
attendanceRequestDetailsResponse? _response; attendanceRequestDetailsResponse? _response;
bool _isLoading = false; bool _isLoading = false;
String? _errorMessage; String? _errorMessage;
bool _isSubmitting = false;
bool get isSubmitting => _isSubmitting;
CommonResponse? _RejectResponse;
CommonResponse? get addResponse => _RejectResponse;
attendanceRequestDetailsResponse? get response => _response; attendanceRequestDetailsResponse? get response => _response;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
...@@ -39,4 +46,50 @@ class AttendanceDetailsProvider extends ChangeNotifier { ...@@ -39,4 +46,50 @@ class AttendanceDetailsProvider extends ChangeNotifier {
_isLoading = false; _isLoading = false;
notifyListeners(); notifyListeners();
} }
Future<void> rejectAttendanceRequest(
BuildContext context, {
required String mode,
required String type,
required String remarks,
required String id,
}) async {
_isSubmitting = true;
_errorMessage = null;
_RejectResponse = null;
notifyListeners();
try {
final homeProvider = Provider.of<HomescreenNotifier>(context, listen: false);
final result = await ApiCalling.attendanceRequestRejectAPI(
homeProvider.session,
homeProvider.empId,
mode,
type,
remarks,
id,
);
if (result != null) {
_RejectResponse = result;
if (result.error != null && result.error!.isNotEmpty) {
_errorMessage = result.error;
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Attendance request rejected successfully."),
),
);
}
} else {
_errorMessage = "Failed to reject attendance request!";
}
} catch (e) {
_errorMessage = "Error rejecting attendance request: $e";
}
_isSubmitting = false;
notifyListeners();
}
} }
...@@ -126,7 +126,7 @@ class Attendancelistprovider extends ChangeNotifier { ...@@ -126,7 +126,7 @@ class Attendancelistprovider extends ChangeNotifier {
/// Fetch attendance request list with filters /// Fetch attendance request list with filters
Future<void> fetchAttendanceRequests(BuildContext context, Future<void> fetchAttendanceRequests(BuildContext context, mode,
{String? type, String? dateRange, DateTimeRange? customRange}) async { {String? type, String? dateRange, DateTimeRange? customRange}) async {
_isLoading = true; _isLoading = true;
_errorMessage = null; _errorMessage = null;
...@@ -152,6 +152,7 @@ class Attendancelistprovider extends ChangeNotifier { ...@@ -152,6 +152,7 @@ class Attendancelistprovider extends ChangeNotifier {
apiType, apiType,
dateParams['from']!, dateParams['from']!,
dateParams['to']!, dateParams['to']!,
mode
); );
debugPrint('Fetching attendance from: ${dateParams['from']} to: ${dateParams['to']}'); debugPrint('Fetching attendance from: ${dateParams['from']} to: ${dateParams['to']}');
...@@ -232,6 +233,7 @@ class Attendancelistprovider extends ChangeNotifier { ...@@ -232,6 +233,7 @@ class Attendancelistprovider extends ChangeNotifier {
/// Apply filters coming from bottom sheet /// Apply filters coming from bottom sheet
void updateFiltersFromSheet( void updateFiltersFromSheet(
mode,
BuildContext context, { BuildContext context, {
required String type, required String type,
required String selectedValue, required String selectedValue,
...@@ -243,6 +245,7 @@ class Attendancelistprovider extends ChangeNotifier { ...@@ -243,6 +245,7 @@ class Attendancelistprovider extends ChangeNotifier {
fetchAttendanceRequests( fetchAttendanceRequests(
context, context,
mode,
type: _selectedType, type: _selectedType,
dateRange: _selectedDateRange, dateRange: _selectedDateRange,
customRange: _customDateRange, customRange: _customDateRange,
...@@ -250,13 +253,13 @@ class Attendancelistprovider extends ChangeNotifier { ...@@ -250,13 +253,13 @@ class Attendancelistprovider extends ChangeNotifier {
} }
/// Set type filter and refresh data /// Set type filter and refresh data
void setTypeFilter(BuildContext context, String type) { void setTypeFilter(BuildContext context, String type, mode) {
_selectedType = type; _selectedType = type;
fetchAttendanceRequests(context); fetchAttendanceRequests(context, mode);
} }
/// Set date range filter and refresh data /// Set date range filter and refresh data
void setDateRangeFilter(BuildContext context, String dateRange, void setDateRangeFilter(BuildContext context, String dateRange, mode,
{DateTimeRange? customRange}) { {DateTimeRange? customRange}) {
_selectedDateRange = dateRange; _selectedDateRange = dateRange;
if (customRange != null) { if (customRange != null) {
...@@ -264,24 +267,24 @@ class Attendancelistprovider extends ChangeNotifier { ...@@ -264,24 +267,24 @@ class Attendancelistprovider extends ChangeNotifier {
fromDateController.text = _formatDate(customRange.start); fromDateController.text = _formatDate(customRange.start);
toDateController.text = _formatDate(customRange.end); toDateController.text = _formatDate(customRange.end);
} }
fetchAttendanceRequests(context); fetchAttendanceRequests(context, mode);
} }
/// Clear all filters and refresh data /// Clear all filters and refresh data
void clearFilters(BuildContext context) { void clearFilters(BuildContext context, mode) {
_selectedType = "All"; _selectedType = "All";
_selectedDateRange = "This Month"; _selectedDateRange = "This Month";
_customDateRange = null; _customDateRange = null;
fromDateController.clear(); fromDateController.clear();
toDateController.clear(); toDateController.clear();
fetchAttendanceRequests(context); fetchAttendanceRequests(context, mode);
} }
/// Reset form and data /// Reset form and data
void resetForm(BuildContext context) { void resetForm(BuildContext context, mode) {
_response = null; _response = null;
_errorMessage = null; _errorMessage = null;
clearFilters(context); clearFilters(context, mode);
notifyListeners(); notifyListeners();
} }
...@@ -343,9 +346,10 @@ class Attendancelistprovider extends ChangeNotifier { ...@@ -343,9 +346,10 @@ class Attendancelistprovider extends ChangeNotifier {
} }
/// Apply filters and refresh data /// Apply filters and refresh data
void applyFilters(BuildContext context) { void applyFilters(BuildContext context, mode) {
fetchAttendanceRequests( fetchAttendanceRequests(
context, context,
mode,
type: _selectedType, type: _selectedType,
dateRange: _selectedDateRange, dateRange: _selectedDateRange,
customRange: _customDateRange, customRange: _customDateRange,
......
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../Models/hrmModels/hrmAccessiblePagesResponse.dart';
import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart';
class HrmAccessiblePagesProvider extends ChangeNotifier {
hrmAccessiblePagesResponse? _response;
bool _isLoading = false;
String? _errorMessage;
hrmAccessiblePagesResponse? get response => _response;
bool get isLoading => _isLoading;
String? get errorMessage => _errorMessage;
/// Fetch HRM Accessible Pages
Future<void> fetchAccessiblePages(BuildContext context) async {
_isLoading = true;
_errorMessage = null;
_response = null;
notifyListeners();
try {
final provider = Provider.of<HomescreenNotifier>(context, listen: false);
final result = await ApiCalling.hrmAccessiblePagesAPI(
provider.empId,
provider.session,
);
if (result != null) {
_response = result;
if (_response?.pagesAccessible == null || _response!.pagesAccessible!.isEmpty) {
_errorMessage = "No accessible pages found!";
}
} else {
_errorMessage = "No data found!";
}
} catch (e) {
_errorMessage = "Something went wrong: $e";
debugPrint("Error fetching HRM accessible pages: $e");
}
_isLoading = false;
notifyListeners();
}
/// Clear stored data
void clearData() {
_response = null;
_errorMessage = null;
notifyListeners();
}
}
...@@ -63,7 +63,7 @@ class LeaveApplicationListProvider extends ChangeNotifier { ...@@ -63,7 +63,7 @@ class LeaveApplicationListProvider extends ChangeNotifier {
DateTime? get selectedDate => _selectedDate; DateTime? get selectedDate => _selectedDate;
/// Fetch leave application list with filters /// Fetch leave application list with filters
Future<void> fetchLeaveApplications(BuildContext context, Future<void> fetchLeaveApplications(BuildContext context, mode,
{String? status, String? dateRange, DateTimeRange? customRange}) async { {String? status, String? dateRange, DateTimeRange? customRange}) async {
_isLoading = true; _isLoading = true;
_errorMessage = null; _errorMessage = null;
...@@ -83,6 +83,7 @@ class LeaveApplicationListProvider extends ChangeNotifier { ...@@ -83,6 +83,7 @@ class LeaveApplicationListProvider extends ChangeNotifier {
provider.empId, provider.empId,
dateParams['from']!, dateParams['from']!,
dateParams['to']!, dateParams['to']!,
mode
); );
debugPrint( debugPrint(
...@@ -315,9 +316,10 @@ class LeaveApplicationListProvider extends ChangeNotifier { ...@@ -315,9 +316,10 @@ class LeaveApplicationListProvider extends ChangeNotifier {
} }
/// Apply filters /// Apply filters
void applyFilters(BuildContext context) { void applyFilters(BuildContext context,mode) {
fetchLeaveApplications( fetchLeaveApplications(
context, context,
mode,
status: _selectedStatus, status: _selectedStatus,
dateRange: _selectedDateRange, dateRange: _selectedDateRange,
customRange: _customDateRange, customRange: _customDateRange,
......
import 'package:flutter/foundation.dart';
import 'package:provider/provider.dart';
import '../../Models/hrmmodels/ogresponse.dart';
import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart';
class Orgprovider extends ChangeNotifier{
List<Children> _employees=[];
String? _rootName;
String? _rootId;
String? _rootTitle;
String? _rootProfile;
List<Children> get employees => _employees;
String? get rootName => _rootName;
String? get rootID => _rootId;
String? get rootTitle => _rootTitle;
String? get rootProfile => _rootProfile;
Future<void> ogChart(context) async{
try{
var homeProvider = Provider.of<HomescreenNotifier>(
context,
listen: false,
);
final data = await ApiCalling.ogChartAPI(homeProvider.empId, homeProvider.session);
if(data!=null){
if(data.error=="0"){
_rootName = data.name!;
_rootId = data.id!;
_rootProfile = data.profile!;
_rootTitle = data.title!;
_employees = data.children!;
notifyListeners();
}
}
}catch(e,s){
}
}
}
\ No newline at end of file
...@@ -141,7 +141,10 @@ PreferredSizeWidget appbar2New(BuildContext context, title, reset, widget,int co ...@@ -141,7 +141,10 @@ PreferredSizeWidget appbar2New(BuildContext context, title, reset, widget,int co
InkResponse( InkResponse(
onTap: () { onTap: () {
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
if(reset!=null){
reset(); reset();
}
Navigator.pop(context, true); Navigator.pop(context, true);
}, },
child: SvgPicture.asset("assets/svg/appbar_back_button.svg", height: 25), child: SvgPicture.asset("assets/svg/appbar_back_button.svg", height: 25),
...@@ -152,7 +155,10 @@ PreferredSizeWidget appbar2New(BuildContext context, title, reset, widget,int co ...@@ -152,7 +155,10 @@ PreferredSizeWidget appbar2New(BuildContext context, title, reset, widget,int co
child: InkResponse( child: InkResponse(
onTap: () { onTap: () {
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
if(reset!=null){
reset(); reset();
}
Navigator.pop(context, true); Navigator.pop(context, true);
}, },
child: Text( child: Text(
......
...@@ -227,12 +227,14 @@ class MyApp extends StatelessWidget { ...@@ -227,12 +227,14 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => followUpUpdateProvider()), ChangeNotifierProvider(create: (_) => followUpUpdateProvider()),
ChangeNotifierProvider(create: (_) => Appointmentcalendarprovider()), ChangeNotifierProvider(create: (_) => Appointmentcalendarprovider()),
ChangeNotifierProvider(create: (_) => Addnewleadsandprospectsprovider()), ChangeNotifierProvider(create: (_) => Addnewleadsandprospectsprovider()),
ChangeNotifierProvider(create: (_) => HrmAccessiblePagesProvider()),
ChangeNotifierProvider(create: (_) => Attendancelistprovider()), ChangeNotifierProvider(create: (_) => Attendancelistprovider()),
ChangeNotifierProvider(create: (_) => AttendanceDetailsProvider()), ChangeNotifierProvider(create: (_) => AttendanceDetailsProvider()),
ChangeNotifierProvider(create: (_) => TourExpensesProvider()), ChangeNotifierProvider(create: (_) => TourExpensesProvider()),
ChangeNotifierProvider(create: (_) => TourExpensesDetailsProvider()), ChangeNotifierProvider(create: (_) => TourExpensesDetailsProvider()),
ChangeNotifierProvider(create: (_) => RewardListProvider()), ChangeNotifierProvider(create: (_) => RewardListProvider()),
ChangeNotifierProvider(create: (_) => LeaveApplicationListProvider()), ChangeNotifierProvider(create: (_) => LeaveApplicationListProvider()),
ChangeNotifierProvider(create: (_) => Orgprovider()),
], ],
child: Builder( child: Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
......
...@@ -335,7 +335,6 @@ class _PaymentrequestionlistdetailsState ...@@ -335,7 +335,6 @@ class _PaymentrequestionlistdetailsState
Expanded( Expanded(
child: InkResponse( child: InkResponse(
onTap: () { onTap: () {
if (provider.Headings[j] == "Attachment") { if (provider.Headings[j] == "Attachment") {
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
Navigator.push( Navigator.push(
...@@ -1126,7 +1125,7 @@ class _PaymentrequestionlistdetailsState ...@@ -1126,7 +1125,7 @@ class _PaymentrequestionlistdetailsState
SvgPicture.asset( SvgPicture.asset(
"assets/svg/finance/level_reject_ic.svg", "assets/svg/finance/level_reject_ic.svg",
), ),
SizedBox(width: 5,), SizedBox(width: 5),
Center( Center(
child: Text( child: Text(
"Reject", "Reject",
...@@ -1141,7 +1140,7 @@ class _PaymentrequestionlistdetailsState ...@@ -1141,7 +1140,7 @@ class _PaymentrequestionlistdetailsState
), ),
), ),
), ),
SizedBox(width: 10), SizedBox(width: 6),
if ([ if ([
"apr_lvl1", "apr_lvl1",
...@@ -1151,7 +1150,7 @@ class _PaymentrequestionlistdetailsState ...@@ -1151,7 +1150,7 @@ class _PaymentrequestionlistdetailsState
SvgPicture.asset( SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg", "assets/svg/crm/vertical_line_ic.svg",
), ),
SizedBox(width: 10), SizedBox(width: 6),
Expanded( Expanded(
child: InkResponse( child: InkResponse(
onTap: () { onTap: () {
...@@ -1181,7 +1180,7 @@ class _PaymentrequestionlistdetailsState ...@@ -1181,7 +1180,7 @@ class _PaymentrequestionlistdetailsState
SvgPicture.asset( SvgPicture.asset(
"assets/svg/finance/level_approve_ic.svg", "assets/svg/finance/level_approve_ic.svg",
), ),
SizedBox(width: 5,), SizedBox(width: 5),
Center( Center(
child: Text( child: Text(
"Approve", "Approve",
...@@ -1196,12 +1195,12 @@ class _PaymentrequestionlistdetailsState ...@@ -1196,12 +1195,12 @@ class _PaymentrequestionlistdetailsState
), ),
), ),
), ),
SizedBox(width: 10), SizedBox(width: 6),
] else if (widget.mode == "process") ...[ ] else if (widget.mode == "process") ...[
SvgPicture.asset( SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg", "assets/svg/crm/vertical_line_ic.svg",
), ),
SizedBox(width: 10), SizedBox(width: 6),
Expanded( Expanded(
child: InkResponse( child: InkResponse(
onTap: () { onTap: () {
...@@ -1229,14 +1228,59 @@ class _PaymentrequestionlistdetailsState ...@@ -1229,14 +1228,59 @@ class _PaymentrequestionlistdetailsState
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
SvgPicture.asset("assets/svg/finance/level_add_payment_ic.svg"), SvgPicture.asset(
SizedBox(width: 5,), "assets/svg/finance/level_add_payment_ic.svg",
),
SizedBox(width: 5),
Center( Center(
child: Text( child: Text(
"Add Payment", "Add Payment",
style: TextStyle( style: TextStyle(
color: AppColors.semi_black, color: AppColors.semi_black,
fontSize: 14 fontSize: 14,
),
),
),
],
),
),
),
),
SizedBox(width: 6),
SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg",
),
SizedBox(width: 6),
Expanded(
child: InkResponse(
onTap: () {
// provider
// .approveRejectPaymentRequestAPIFunction(
// context,
// provider.requestsDetails.id,
// );
provider.editPrevalues();
_showEditPaymentSheet(
context,
provider.requestsDetails.id,
);
},
child: Container(
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/svg/crm/lead_details_edit_ic.svg",
),
SizedBox(width: 5),
Center(
child: Text(
"Edit Amount",
style: TextStyle(
color: AppColors.semi_black,
fontSize: 14,
), ),
), ),
), ),
...@@ -2111,7 +2155,14 @@ class _PaymentrequestionlistdetailsState ...@@ -2111,7 +2155,14 @@ class _PaymentrequestionlistdetailsState
return Center(child: CircularProgressIndicator()); return Center(child: CircularProgressIndicator());
} }
return Container( return Padding(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(
context,
).viewInsets.bottom,
),
child: Container(
// Constrain the height to avoid overflow // Constrain the height to avoid overflow
constraints: BoxConstraints( constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.8, maxHeight: MediaQuery.of(context).size.height * 0.8,
...@@ -2566,6 +2617,129 @@ class _PaymentrequestionlistdetailsState ...@@ -2566,6 +2617,129 @@ class _PaymentrequestionlistdetailsState
), ),
], ],
), ),
),
);
},
),
);
},
);
},
);
}
Future<void> _showEditPaymentSheet(BuildContext context, paymentID) {
return showModalBottomSheet(
useSafeArea: true,
isDismissible: true,
isScrollControlled: true,
showDragHandle: true,
backgroundColor: Colors.white,
enableDrag: true,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
return SafeArea(
child: Consumer<Requesitionlidtdetailsprovider>(
builder: (context, provider, child) {
return Padding(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(
context,
).viewInsets.bottom,
),
child: Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height * 0.3,
),
margin: EdgeInsets.only(
bottom: 15,
left: 15,
right: 15,
top: 10,
),
child: Column(
children: [
Align(
alignment: Alignment.topLeft,
child: Text(
"Edit Processed Amount",
style: TextStyle(
color: AppColors.app_blue,
fontSize: 16,
),
),
),
textControllerReadonlyWidget(
context,
provider.editPaymentRequestedAmountController,
"Requested Amount",
(p0) {},
),
textControllerWidget(
context,
provider.editPaymentRequestedEditableAmountController,
"Approved Amount",
"Enter Approved Amount",
(p0) {
provider.onChangeEditableAmount(p0, context);
},
TextInputType.numberWithOptions(),
false,
null,
),
errorWidget(context, provider.editableAmountError),
Padding(
padding: EdgeInsets.only(
left: 5.0,
right: 5.0,
top: 5.0,
bottom: 5.0,
),
child: InkWell(
onTap:
provider.editPaymentProcessLoading
? null
: () {
provider.editPaymentProcessLoading = true;
provider.editProcessedPaymentAmountAPIFunction(
context,
paymentID,
provider
.editPaymentRequestedEditableAmountController
.text,
);
},
child: Container(
height: 45,
decoration: BoxDecoration(
color: AppColors.app_blue,
borderRadius: BorderRadius.circular(14.0),
),
child: Center(
child:
provider.editPaymentProcessLoading
? CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation(
AppColors.white,
),
)
: Text(
"Submit",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
),
),
),
),
],
),
),
); );
}, },
), ),
......
...@@ -43,6 +43,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> { ...@@ -43,6 +43,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
listen: false, listen: false,
); );
provider.addReceiptPaymentRequestionViewAPI(context); provider.addReceiptPaymentRequestionViewAPI(context);
provider.submitClicked = false;
}); });
} }
...@@ -628,6 +629,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> { ...@@ -628,6 +629,7 @@ class _AddpaymentreceiptlistState extends State<Addpaymentreceiptlist> {
? null ? null
: () { : () {
provider.submitClicked = true; provider.submitClicked = true;
provider.notifyListeners();
provider.addReceiptPaymentRequestionSubmitAPI( provider.addReceiptPaymentRequestionSubmitAPI(
context, context,
provider.formattedDateToSend, provider.formattedDateToSend,
......
...@@ -646,7 +646,7 @@ class _DirectpaymentrequesitionlistState ...@@ -646,7 +646,7 @@ class _DirectpaymentrequesitionlistState
child: child:
provider.submitClicked provider.submitClicked
? CircularProgressIndicator.adaptive( ? CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation(AppColors.app_blue), valueColor: AlwaysStoppedAnimation(AppColors.white),
) )
: Text( : Text(
"Submit", "Submit",
......
...@@ -432,7 +432,7 @@ class _FinancedashboardState extends State<Financedashboard> { ...@@ -432,7 +432,7 @@ class _FinancedashboardState extends State<Financedashboard> {
) => Allpaymentrequesitionlistsbymodes( ) => Allpaymentrequesitionlistsbymodes(
mode: "process", mode: "process",
pageTitleName: pageTitleName:
"Payment Requisition List (Self)", "Payment Requisition List (Process)",
), ),
), ),
); );
......
...@@ -229,6 +229,18 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> { ...@@ -229,6 +229,18 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
return; return;
} }
// --- Format date for server (convert from "03 Sep 2025" to "2025-09-03" or whatever format server expects) ---
String formattedDate = "";
try {
final parsedDate = DateFormat("dd MMM yyyy").parse(provider.dateController.text);
formattedDate = DateFormat("yyyy-MM-dd").format(parsedDate); // Change format as per server requirement
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("Error formatting date: $e")),
);
return;
}
// --- Build data according to type --- // --- Build data according to type ---
String? finalCheckInTime; String? finalCheckInTime;
String? finalCheckInLoc; String? finalCheckInLoc;
...@@ -268,7 +280,7 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> { ...@@ -268,7 +280,7 @@ class _AddManualAttendanceScreenState extends State<AddManualAttendanceScreen> {
: selectedType == "Check Out" : selectedType == "Check Out"
? checkOutLocation.text ? checkOutLocation.text
: "${checkInLocation.text}, ${checkOutLocation.text}", : "${checkInLocation.text}, ${checkOutLocation.text}",
checkDate: provider.dateController.text, checkDate: formattedDate, // Use the formatted date here
checkInTime: finalCheckInTime, checkInTime: finalCheckInTime,
checkInLoc: finalCheckInLoc, checkInLoc: finalCheckInLoc,
checkInProof: finalCheckInProof, checkInProof: finalCheckInProof,
......
...@@ -12,8 +12,9 @@ import '../finance/FileViewer.dart'; ...@@ -12,8 +12,9 @@ import '../finance/FileViewer.dart';
/// screen for attendance details /// screen for attendance details
class AttendanceRequestDetailScreen extends StatefulWidget { class AttendanceRequestDetailScreen extends StatefulWidget {
final String mode;
final attendanceListId; final attendanceListId;
const AttendanceRequestDetailScreen({super.key, required this.attendanceListId}); const AttendanceRequestDetailScreen({super.key, required this.attendanceListId, required this.mode});
@override @override
State<AttendanceRequestDetailScreen> createState() => State<AttendanceRequestDetailScreen> createState() =>
...@@ -238,12 +239,279 @@ class _AttendanceRequestDetailScreenState ...@@ -238,12 +239,279 @@ class _AttendanceRequestDetailScreenState
); );
}, },
), ),
bottomNavigationBar: widget.mode == "apr_lvl1"
? Container(
decoration: const BoxDecoration(color: Colors.white),
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
height: 80,
child: Row(
children: [
/// Reject Button
Expanded(
child: InkWell(
onTap: () {
showRemarkSheet(
context: context,
actionType: "Reject",
onSubmit: (remark) {
provider.rejectAttendanceRequest(
context,
mode: widget.mode,
type: "Rejected",
remarks: remark,
id: provider.response!.requestDetails!.id!,
);
},
); );
}, },
child: Container(
alignment: Alignment.center,
height: 45,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: const Color(0xFFFFFFFF),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset("assets/svg/finance/level_reject_ic.svg"),
const SizedBox(width: 6),
const Text("Reject"),
],
),
),
),
),
const SizedBox(width: 10),
/// Approve Button
Expanded(
child: InkWell(
onTap: () {
showRemarkSheet(
context: context,
actionType: "Approve",
onSubmit: (remark) {
provider.rejectAttendanceRequest(
context,
mode: widget.mode,
type: "Approved",
remarks: remark,
id: provider.response!.requestDetails!.id!,
);
},
);
},
child: Container(
alignment: Alignment.center,
height: 45,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: const Color(0xFFFFFFFF),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset("assets/svg/finance/level_approve_ic.svg"),
const SizedBox(width: 6),
const Text("Approve"),
],
),
),
),
),
],
),
) )
: const SizedBox.shrink(),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
); );
},
)
);
}
Future<void> showRemarkSheet({
required BuildContext context,
required String actionType, // "Approved" or "Rejected"
required Function(String remark) onSubmit,
}) {
final remarkController = TextEditingController();
String? remarkError;
return showModalBottomSheet(
useSafeArea: true,
isDismissible: true,
isScrollControlled: true,
showDragHandle: true,
backgroundColor: Colors.white,
enableDrag: true,
context: context,
builder: (context) {
return StatefulBuilder(
builder: (context, setState) {
void updateState(VoidCallback fn) {
setState(fn);
}
bool validateFields() {
String? newRemarkError =
remarkController.text.trim().isEmpty ? "Remark required" : null;
if (remarkError != newRemarkError) {
updateState(() {
remarkError = newRemarkError;
});
}
return newRemarkError == null;
} }
Widget errorText(String? msg) => msg == null
? const SizedBox()
: Padding(
padding: const EdgeInsets.only(top: 4, left: 4),
child: Text(
msg,
style: const TextStyle(
color: Colors.red,
fontSize: 12,
fontFamily: "JakartaMedium",
),
),
);
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
"$actionType Attendance Request",
style: const TextStyle(
fontSize: 16,
color: Colors.black87,
fontFamily: "JakartaMedium",
),
),
const SizedBox(height: 16),
Text(
"Remark",
style: const TextStyle(
fontSize: 14,
color: Colors.black87,
fontFamily: "JakartaMedium",
),
),
const SizedBox(height: 6),
TextField(
controller: remarkController,
maxLines: 3,
onChanged: (val) {
if (remarkError != null && val.isNotEmpty) {
updateState(() => remarkError = null);
}
},
decoration: InputDecoration(
hintText: "Enter your remark here...",
filled: true,
fillColor: Colors.grey.shade100,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
contentPadding: const EdgeInsets.symmetric(
vertical: 12,
horizontal: 12,
),
),
),
errorText(remarkError),
const SizedBox(height: 20),
Row(
children: [
Expanded(
child: InkResponse(
onTap: () => Navigator.pop(context),
child: Container(
height: 45,
decoration: BoxDecoration(
color: Colors.red.shade100,
borderRadius: BorderRadius.circular(12),
),
child: const Center(
child: Text(
"Cancel",
style: TextStyle(
color: Colors.red,
fontFamily: "JakartaMedium",
),
),
),
),
),
),
const SizedBox(width: 12),
Expanded(
child: InkResponse(
onTap: () async {
if (validateFields()) {
final remark = remarkController.text.trim();
// Call provider
await onSubmit(remark);
// SnackBar here
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Request submitted successfully"),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
),
);
}
},
child: Container(
height: 45,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(12),
),
child: const Center(
child: Text(
"Submit",
style: TextStyle(
color: Colors.white,
fontFamily: "JakartaMedium",
),
),
),
),
),
),
],
),
],
),
),
),
);
},
);
},
);
}
/// Reusable Row Widget for details /// Reusable Row Widget for details
Widget _buildDetailTile(String label, String? value, double scaleFactor) { Widget _buildDetailTile(String label, String? value, double scaleFactor) {
return Padding( return Padding(
......
...@@ -13,14 +13,15 @@ import '../CommonFilter2.dart'; ...@@ -13,14 +13,15 @@ import '../CommonFilter2.dart';
import '../commonDateRangeFilter.dart'; import '../commonDateRangeFilter.dart';
import 'AddLiveAttendance.dart'; import 'AddLiveAttendance.dart';
class Attendancelist extends StatefulWidget { class AttendanceListScreen extends StatefulWidget {
const Attendancelist({super.key}); final mode;
const AttendanceListScreen({super.key,required this.mode});
@override @override
State<Attendancelist> createState() => _AttendancelistState(); State<AttendanceListScreen> createState() => _AttendanceListScreenState();
} }
class _AttendancelistState extends State<Attendancelist> { class _AttendanceListScreenState extends State<AttendanceListScreen> {
// @override // @override
// void initState() { // void initState() {
// super.initState(); // super.initState();
...@@ -38,7 +39,7 @@ class _AttendancelistState extends State<Attendancelist> { ...@@ -38,7 +39,7 @@ class _AttendancelistState extends State<Attendancelist> {
create: (_) { create: (_) {
final provider = Attendancelistprovider(); final provider = Attendancelistprovider();
Future.microtask(() { Future.microtask(() {
provider.fetchAttendanceRequests(context); provider.fetchAttendanceRequests(context, widget.mode);
}); });
return provider; return provider;
}, },
...@@ -80,6 +81,7 @@ class _AttendancelistState extends State<Attendancelist> { ...@@ -80,6 +81,7 @@ class _AttendancelistState extends State<Attendancelist> {
provider.updateFiltersFromSheet( provider.updateFiltersFromSheet(
context, context,
widget.mode,
type: result['type'] ?? "All", type: result['type'] ?? "All",
selectedValue: result['selectedValue'] ?? "This Month", selectedValue: result['selectedValue'] ?? "This Month",
customRange: result['dateRange'], customRange: result['dateRange'],
...@@ -161,6 +163,7 @@ class _AttendancelistState extends State<Attendancelist> { ...@@ -161,6 +163,7 @@ class _AttendancelistState extends State<Attendancelist> {
MaterialPageRoute( MaterialPageRoute(
builder: (context) => AttendanceRequestDetailScreen( builder: (context) => AttendanceRequestDetailScreen(
attendanceListId: item.id, attendanceListId: item.id,
mode: widget.mode,
), ),
), ),
); );
...@@ -266,7 +269,7 @@ class _AttendancelistState extends State<Attendancelist> { ...@@ -266,7 +269,7 @@ class _AttendancelistState extends State<Attendancelist> {
), ),
), ),
).then((_) { ).then((_) {
provider.fetchAttendanceRequests(context); provider.fetchAttendanceRequests(context,widget.mode);
}); });
}, },
child: Row( child: Row(
...@@ -294,7 +297,7 @@ class _AttendancelistState extends State<Attendancelist> { ...@@ -294,7 +297,7 @@ class _AttendancelistState extends State<Attendancelist> {
name: 'AddManualAttendanceScreen'), name: 'AddManualAttendanceScreen'),
), ),
).then((_) { ).then((_) {
provider.fetchAttendanceRequests(context); provider.fetchAttendanceRequests(context, widget.mode);
}); });
}, },
child: Row( child: Row(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment