diff --git a/lib/api/grpc_client.dart b/lib/api/grpc_client.dart index 7783b5f..20b2ac2 100644 --- a/lib/api/grpc_client.dart +++ b/lib/api/grpc_client.dart @@ -400,6 +400,131 @@ class GrpcCqrsApiClient { ); } + // ============================================================ + // Command Methods + // ============================================================ + + /// Marks a delivery as completed. + /// + /// Returns a [Result] indicating success or failure. Optionally accepts + /// a [deliveredAt] timestamp; if not provided, the server will use the + /// current time. + /// + /// Example: + /// ```dart + /// final result = await client.completeDelivery(deliveryId: 123); + /// result.when( + /// success: (_) => showSuccess('Delivery completed'), + /// onError: (error) => showError(error.message), + /// ); + /// ``` + Future> completeDelivery({ + required int deliveryId, + String? deliveredAt, + }) async { + final request = CompleteDeliveryRequest( + deliveryId: deliveryId, + deliveredAt: deliveredAt, + ); + + final result = await _executeWithAuth( + (options) => deliveryClient.completeDelivery(request, options: options), + ); + + return result.when( + success: (response) { + if (response.success) { + return Result.success(null); + } + return Result.error( + ApiError.unknown(response.message.isNotEmpty + ? response.message + : 'Failed to complete delivery'), + ); + }, + onError: (error) => Result.error(error), + ); + } + + /// Marks a delivery as uncompleted. + /// + /// Returns a [Result] indicating success or failure. Use this to revert + /// a previously completed delivery back to pending status. + /// + /// Example: + /// ```dart + /// final result = await client.markDeliveryAsUncompleted(deliveryId: 123); + /// result.when( + /// success: (_) => showSuccess('Delivery marked as uncompleted'), + /// onError: (error) => showError(error.message), + /// ); + /// ``` + Future> markDeliveryAsUncompleted({ + required int deliveryId, + }) async { + final request = MarkDeliveryUncompletedRequest( + deliveryId: deliveryId, + ); + + final result = await _executeWithAuth( + (options) => + deliveryClient.markDeliveryUncompleted(request, options: options), + ); + + return result.when( + success: (response) { + if (response.success) { + return Result.success(null); + } + return Result.error( + ApiError.unknown(response.message.isNotEmpty + ? response.message + : 'Failed to mark delivery as uncompleted'), + ); + }, + onError: (error) => Result.error(error), + ); + } + + /// Skips a delivery. + /// + /// Returns a [Result] indicating success or failure. Use this when a + /// delivery cannot be completed and needs to be skipped. + /// + /// Example: + /// ```dart + /// final result = await client.skipDelivery(deliveryId: 123); + /// result.when( + /// success: (_) => showSuccess('Delivery skipped'), + /// onError: (error) => showError(error.message), + /// ); + /// ``` + Future> skipDelivery({ + required int deliveryId, + }) async { + final request = SkipDeliveryRequest( + deliveryId: deliveryId, + ); + + final result = await _executeWithAuth( + (options) => deliveryClient.skipDelivery(request, options: options), + ); + + return result.when( + success: (response) { + if (response.success) { + return Result.success(null); + } + return Result.error( + ApiError.unknown(response.message.isNotEmpty + ? response.message + : 'Failed to skip delivery'), + ); + }, + onError: (error) => Result.error(error), + ); + } + /// Shuts down the gRPC channel and releases resources. /// /// Should be called when the client is no longer needed to properly