chnages has been made and net salary is being displayed
This commit is contained in:
@@ -7,6 +7,7 @@ import '../dto/attendance_record_dto.dart';
|
||||
import '../dto/overtime_dto.dart';
|
||||
import '../dto/reward_dto.dart';
|
||||
import '../dto/punishment_dto.dart';
|
||||
import '../dto/salary_response_dto.dart';
|
||||
|
||||
abstract class AttendanceRemoteDataSource {
|
||||
Future<AttendanceResponseDto> login({
|
||||
@@ -25,6 +26,11 @@ abstract class AttendanceRemoteDataSource {
|
||||
Future<List<OvertimeDto>> getExtraHours({required String employeeId});
|
||||
Future<List<RewardDto>> getRewards({required String employeeId});
|
||||
Future<List<PunishmentDto>> getPunishments({required String employeeId});
|
||||
Future<SalaryResponseDto> calculateSalary({
|
||||
required String employeeId,
|
||||
required int month,
|
||||
required int year,
|
||||
});
|
||||
}
|
||||
|
||||
class AttendanceRemoteDataSourceImpl implements AttendanceRemoteDataSource {
|
||||
@@ -286,4 +292,66 @@ class AttendanceRemoteDataSourceImpl implements AttendanceRemoteDataSource {
|
||||
throw ServerException(message: 'خطأ غير متوقع');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SalaryResponseDto> calculateSalary({
|
||||
required String employeeId,
|
||||
required int month,
|
||||
required int year,
|
||||
}) async {
|
||||
try {
|
||||
final response = await apiClient.get(
|
||||
'/SalaryRecord/calculate',
|
||||
queryParameters: {
|
||||
'EmployeeId': employeeId,
|
||||
'Month': month,
|
||||
'Year': year,
|
||||
},
|
||||
);
|
||||
|
||||
print('Salary Response Status: ${response.statusCode}');
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
final responseData = response.data;
|
||||
print(
|
||||
'Salary Response Data: $responseData (${responseData.runtimeType})',
|
||||
);
|
||||
|
||||
if (responseData is Map<String, dynamic>) {
|
||||
return SalaryResponseDto.fromJson(responseData);
|
||||
} else if (responseData is num) {
|
||||
// Handle case where API returns raw number
|
||||
return SalaryResponseDto(
|
||||
isSuccess: true,
|
||||
message: 'Success',
|
||||
data: SalaryDataDto(netAmount: responseData.toDouble()),
|
||||
);
|
||||
} else if (responseData is String &&
|
||||
double.tryParse(responseData) != null) {
|
||||
// Handle case where API returns raw numeric string
|
||||
return SalaryResponseDto(
|
||||
isSuccess: true,
|
||||
message: 'Success',
|
||||
data: SalaryDataDto(netAmount: double.parse(responseData)),
|
||||
);
|
||||
} else {
|
||||
throw ServerException(
|
||||
message: 'استجابة غير صحيحة من الخادم: $responseData',
|
||||
statusCode: response.statusCode,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw ServerException(
|
||||
message: 'فشل في حساب الراتب (Status: ${response.statusCode})',
|
||||
statusCode: response.statusCode,
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
throw ServerException(
|
||||
message: e.message ?? 'Unknown error',
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
} catch (e) {
|
||||
throw ServerException(message: 'خطأ غير متوقع');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,9 +3,14 @@ import '../../core/error/exceptions.dart';
|
||||
import '../../core/network/api_client.dart';
|
||||
import '../dto/login_dto.dart';
|
||||
import '../dto/login_response_dto.dart';
|
||||
import '../dto/change_password_request_dto.dart';
|
||||
import '../dto/change_password_response_dto.dart';
|
||||
|
||||
abstract class AuthRemoteDataSource {
|
||||
Future<LoginResponseDto> login(LoginDto dto);
|
||||
Future<ChangePasswordResponseDto> changePassword(
|
||||
ChangePasswordRequestDto dto,
|
||||
);
|
||||
}
|
||||
|
||||
class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
@@ -72,4 +77,37 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
|
||||
throw ServerException(message: 'خطأ غير متوقع');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<ChangePasswordResponseDto> changePassword(
|
||||
ChangePasswordRequestDto dto,
|
||||
) async {
|
||||
try {
|
||||
final response = await apiClient.post(
|
||||
'/Auth/change-password',
|
||||
data: dto.toJson(),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
return ChangePasswordResponseDto.fromJson(response.data);
|
||||
} else {
|
||||
throw ServerException(
|
||||
message: response.data['message'] ?? 'فشل تغيير كلمة المرور',
|
||||
statusCode: response.statusCode,
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
final message =
|
||||
e.response?.data?['message'] ??
|
||||
e.response?.data?['error'] ??
|
||||
'فشل تغيير كلمة المرور';
|
||||
throw ServerException(
|
||||
message: message,
|
||||
statusCode: e.response?.statusCode,
|
||||
);
|
||||
} catch (e) {
|
||||
if (e is ServerException) rethrow;
|
||||
throw ServerException(message: 'خطأ غير متوقع: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
lib/data/dto/change_password_request_dto.dart
Normal file
13
lib/data/dto/change_password_request_dto.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
class ChangePasswordRequestDto {
|
||||
final String oldPassword;
|
||||
final String newPassword;
|
||||
|
||||
ChangePasswordRequestDto({
|
||||
required this.oldPassword,
|
||||
required this.newPassword,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'oldPassword': oldPassword, 'newPassword': newPassword};
|
||||
}
|
||||
}
|
||||
36
lib/data/dto/change_password_response_dto.dart
Normal file
36
lib/data/dto/change_password_response_dto.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
import 'login_response_dto.dart';
|
||||
|
||||
class ChangePasswordResponseDto {
|
||||
final int statusCode;
|
||||
final bool isSuccess;
|
||||
final String message;
|
||||
final LoginDataDto? data;
|
||||
|
||||
ChangePasswordResponseDto({
|
||||
required this.statusCode,
|
||||
required this.isSuccess,
|
||||
required this.message,
|
||||
this.data,
|
||||
});
|
||||
|
||||
factory ChangePasswordResponseDto.fromJson(Map<String, dynamic> json) {
|
||||
return ChangePasswordResponseDto(
|
||||
statusCode: json['statusCode'] ?? 0,
|
||||
isSuccess: json['isSuccess'] ?? false,
|
||||
message: json['message'] ?? '',
|
||||
data:
|
||||
json['data'] != null && json['data'] is Map<String, dynamic>
|
||||
? LoginDataDto.fromJson(json['data'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'statusCode': statusCode,
|
||||
'isSuccess': isSuccess,
|
||||
'message': message,
|
||||
'data': data?.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
36
lib/data/dto/salary_response_dto.dart
Normal file
36
lib/data/dto/salary_response_dto.dart
Normal file
@@ -0,0 +1,36 @@
|
||||
class SalaryResponseDto {
|
||||
final bool isSuccess;
|
||||
final String message;
|
||||
final SalaryDataDto? data;
|
||||
|
||||
SalaryResponseDto({
|
||||
required this.isSuccess,
|
||||
required this.message,
|
||||
this.data,
|
||||
});
|
||||
|
||||
factory SalaryResponseDto.fromJson(Map<String, dynamic> json) {
|
||||
return SalaryResponseDto(
|
||||
isSuccess: json['isSuccess'] ?? json['IsSuccess'] ?? false,
|
||||
message: json['message'] ?? json['Message'] ?? '',
|
||||
data:
|
||||
json['data'] != null
|
||||
? SalaryDataDto.fromJson(json['data'])
|
||||
: json['Data'] != null
|
||||
? SalaryDataDto.fromJson(json['Data'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SalaryDataDto {
|
||||
final double netAmount;
|
||||
|
||||
SalaryDataDto({required this.netAmount});
|
||||
|
||||
factory SalaryDataDto.fromJson(Map<String, dynamic> json) {
|
||||
return SalaryDataDto(
|
||||
netAmount: (json['netAmount'] ?? json['NetAmount'] ?? 0.0).toDouble(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import '../../domain/models/attendance_response_model.dart';
|
||||
import '../../domain/models/attendance_model.dart';
|
||||
import '../../domain/models/overtime_model.dart';
|
||||
import '../../domain/models/extra_payment_model.dart';
|
||||
import '../../domain/models/salary_model.dart';
|
||||
import '../../domain/repositories/attendance_repository.dart';
|
||||
import '../datasources/attendance_remote_data_source.dart';
|
||||
|
||||
@@ -131,4 +132,19 @@ class AttendanceRepositoryImpl implements AttendanceRepository {
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<SalaryModel> calculateSalary({
|
||||
required String employeeId,
|
||||
required int month,
|
||||
required int year,
|
||||
}) async {
|
||||
final dto = await remoteDataSource.calculateSalary(
|
||||
employeeId: employeeId,
|
||||
month: month,
|
||||
year: year,
|
||||
);
|
||||
|
||||
return SalaryModel(netAmount: dto.data?.netAmount ?? 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import '../../domain/models/login_request.dart';
|
||||
import '../../domain/models/login_response_model.dart';
|
||||
import '../../domain/repositories/auth_repository.dart';
|
||||
|
||||
import '../dto/change_password_request_dto.dart';
|
||||
import '../../domain/models/change_password_request.dart';
|
||||
import '../../domain/models/general_response_model.dart';
|
||||
|
||||
class AuthRepositoryImpl implements AuthRepository {
|
||||
final AuthRemoteDataSource remoteDataSource;
|
||||
final UserLocalDataSource localDataSource;
|
||||
@@ -71,4 +75,45 @@ class AuthRepositoryImpl implements AuthRepository {
|
||||
return Left(ServerFailure('خطأ غير متوقع: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, GeneralResponseModel>> changePassword(
|
||||
ChangePasswordRequest request,
|
||||
) async {
|
||||
try {
|
||||
final dto = ChangePasswordRequestDto(
|
||||
oldPassword: request.oldPassword,
|
||||
newPassword: request.newPassword,
|
||||
);
|
||||
|
||||
final responseDto = await remoteDataSource.changePassword(dto);
|
||||
|
||||
// Re-cache token and employeeId if provided in response
|
||||
if (responseDto.data != null) {
|
||||
if (responseDto.data!.token != null) {
|
||||
await localDataSource.cacheUserToken(responseDto.data!.token!);
|
||||
}
|
||||
if (responseDto.data!.employeeId != null) {
|
||||
await localDataSource.cacheEmployeeId(responseDto.data!.employeeId!);
|
||||
}
|
||||
}
|
||||
|
||||
final model = GeneralResponseModel(
|
||||
statusCode: responseDto.statusCode,
|
||||
isSuccess: responseDto.isSuccess,
|
||||
message: responseDto.message,
|
||||
data:
|
||||
responseDto
|
||||
.isSuccess, // Use isSuccess as data for the boolean model
|
||||
);
|
||||
|
||||
return Right(model);
|
||||
} on ServerException catch (e) {
|
||||
return Left(ServerFailure(e.message));
|
||||
} on NetworkException catch (e) {
|
||||
return Left(NetworkFailure(e.message));
|
||||
} catch (e) {
|
||||
return Left(ServerFailure('خطأ غير متوقع: $e'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user