This commit is contained in:
Phuoc Nguyen
2025-10-28 16:48:31 +07:00
parent 5cfc56f40d
commit 4b35d236df
11 changed files with 390 additions and 102 deletions

View File

@@ -2,6 +2,7 @@ import '../../../../core/constants/api_endpoints.dart';
import '../../../../core/errors/exceptions.dart';
import '../../../../core/network/api_client.dart';
import '../../../../core/network/api_response.dart';
import '../models/create_product_warehouse_request.dart';
import '../models/product_detail_request_model.dart';
import '../models/product_model.dart';
import '../models/product_stage_model.dart';
@@ -24,6 +25,14 @@ abstract class ProductsRemoteDataSource {
/// Returns List<ProductStageModel> with all stages for the product
/// Throws [ServerException] if the API call fails
Future<List<ProductStageModel>> getProductDetail(ProductDetailRequestModel request);
/// Create product warehouse entry (import/export operation)
///
/// [request] - Request containing all product warehouse details
///
/// Returns void on success
/// Throws [ServerException] if the API call fails
Future<void> createProductWarehouse(CreateProductWarehouseRequest request);
}
/// Implementation of ProductsRemoteDataSource using ApiClient
@@ -126,4 +135,47 @@ class ProductsRemoteDataSourceImpl implements ProductsRemoteDataSource {
throw ServerException('Failed to get product stages: ${e.toString()}');
}
}
@override
Future<void> createProductWarehouse(
CreateProductWarehouseRequest request) async {
try {
// The API expects an array of requests
final requestData = [request.toJson()];
// Make API call to create product warehouse
final response = await apiClient.post(
ApiEndpoints.createProductWarehouse,
data: requestData,
);
// Parse the API response
final apiResponse = ApiResponse.fromJson(
response.data as Map<String, dynamic>,
(json) => json, // We don't need to parse the response value
);
// Check if the API call was successful
if (!apiResponse.isSuccess) {
// Throw exception with error message from API
throw ServerException(
apiResponse.errors.isNotEmpty
? apiResponse.errors.first
: 'Failed to create product warehouse entry',
);
}
} catch (e) {
// Re-throw ServerException as-is
if (e is ServerException) {
rethrow;
}
// Re-throw NetworkException as-is
if (e is NetworkException) {
rethrow;
}
// Wrap other exceptions in ServerException
throw ServerException(
'Failed to create product warehouse entry: ${e.toString()}');
}
}
}

View File

@@ -0,0 +1,77 @@
/// Request model for creating product warehouse (import/export)
class CreateProductWarehouseRequest {
final int typeId;
final int productId;
final int stageId;
final int? orderId;
final String recordDate;
final double passedQuantityWeight;
final int passedQuantity;
final double issuedQuantityWeight;
final int issuedQuantity;
final int responsibleUserId;
final String description;
final String productName;
final String productCode;
final double stockPassedQuantityWeight;
final int stockPassedQuantity;
final int stockIssuedQuantity;
final double stockIssuedQuantityWeight;
final int receiverUserId;
final int actionTypeId;
final int wareHouseId;
final int productStageId;
final bool isConfirm;
CreateProductWarehouseRequest({
required this.typeId,
required this.productId,
required this.stageId,
this.orderId,
required this.recordDate,
required this.passedQuantityWeight,
required this.passedQuantity,
required this.issuedQuantityWeight,
required this.issuedQuantity,
required this.responsibleUserId,
this.description = '',
required this.productName,
required this.productCode,
this.stockPassedQuantityWeight = 0.0,
this.stockPassedQuantity = 0,
this.stockIssuedQuantity = 0,
this.stockIssuedQuantityWeight = 0.0,
required this.receiverUserId,
required this.actionTypeId,
required this.wareHouseId,
required this.productStageId,
this.isConfirm = true,
});
Map<String, dynamic> toJson() {
return {
'TypeId': typeId,
'ProductId': productId,
'StageId': stageId,
'OrderId': orderId,
'RecordDate': recordDate,
'PassedQuantityWeight': passedQuantityWeight,
'PassedQuantity': passedQuantity,
'IssuedQuantityWeight': issuedQuantityWeight,
'IssuedQuantity': issuedQuantity,
'ResponsibleUserId': responsibleUserId,
'Description': description,
'ProductName': productName,
'ProductCode': productCode,
'StockPassedQuantityWeight': stockPassedQuantityWeight,
'StockPassedQuantity': stockPassedQuantity,
'StockIssuedQuantity': stockIssuedQuantity,
'StockIssuedQuantityWeight': stockIssuedQuantityWeight,
'ReceiverUserId': receiverUserId,
'ActionTypeId': actionTypeId,
'WareHouseId': wareHouseId,
'ProductStageId': productStageId,
'IsConfirm': isConfirm,
};
}
}

View File

@@ -13,6 +13,9 @@ class ProductStageModel extends ProductStageEntity {
required super.passedQuantityWeight,
required super.stageName,
required super.createdDate,
super.productName,
super.productCode,
super.stageId,
});
/// Create ProductStageModel from JSON
@@ -27,6 +30,9 @@ class ProductStageModel extends ProductStageEntity {
passedQuantityWeight: (json['PassedQuantityWeight'] as num).toDouble(),
stageName: json['StageName'] as String?,
createdDate: json['CreatedDate'] as String,
productName: json['ProductName'] as String? ?? '',
productCode: json['ProductCode'] as String? ?? '',
stageId: json['StageId'] as int?,
);
}
@@ -42,6 +48,9 @@ class ProductStageModel extends ProductStageEntity {
'PassedQuantityWeight': passedQuantityWeight,
'StageName': stageName,
'CreatedDate': createdDate,
'ProductName': productName,
'ProductCode': productCode,
'StageId': stageId,
};
}
@@ -57,6 +66,9 @@ class ProductStageModel extends ProductStageEntity {
passedQuantityWeight: passedQuantityWeight,
stageName: stageName,
createdDate: createdDate,
productName: productName,
productCode: productCode,
stageId: stageId,
);
}

View File

@@ -5,6 +5,7 @@ import '../../domain/entities/product_entity.dart';
import '../../domain/entities/product_stage_entity.dart';
import '../../domain/repositories/products_repository.dart';
import '../datasources/products_remote_datasource.dart';
import '../models/create_product_warehouse_request.dart';
import '../models/product_detail_request_model.dart';
/// Implementation of ProductsRepository
@@ -65,4 +66,26 @@ class ProductsRepositoryImpl implements ProductsRepository {
return Left(ServerFailure('Unexpected error: ${e.toString()}'));
}
}
@override
Future<Either<Failure, void>> createProductWarehouse(
CreateProductWarehouseRequest request,
) async {
try {
// Call remote data source to create product warehouse
await remoteDataSource.createProductWarehouse(request);
// Return success
return const Right(null);
} on ServerException catch (e) {
// Convert ServerException to ServerFailure
return Left(ServerFailure(e.message));
} on NetworkException catch (e) {
// Convert NetworkException to NetworkFailure
return Left(NetworkFailure(e.message));
} catch (e) {
// Handle any other exceptions
return Left(ServerFailure('Unexpected error: ${e.toString()}'));
}
}
}