diff --git a/lib/data/provider/pickup_data_provider.dart b/lib/data/provider/pickup_data_provider.dart new file mode 100644 index 0000000..94a73f5 --- /dev/null +++ b/lib/data/provider/pickup_data_provider.dart @@ -0,0 +1,20 @@ +import 'dart:convert'; + +import 'package:fcs/config.dart'; +import 'package:fcs/domain/constants.dart'; +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/domain/entities/pickup.dart'; +import 'package:fcs/helpers/api_helper.dart'; +import 'package:fcs/helpers/firebase_helper.dart'; +import 'package:logging/logging.dart'; + +class PickupDataProvider { + final log = Logger('PickupDataProvider'); + static final PickupDataProvider instance = PickupDataProvider._(); + PickupDataProvider._(); + + Future completePickup(Pickup pickup) async { + return await requestAPI("/pickups/complete", "PUT", + payload: pickup.toMapForComplete(), token: await getToken()); + } +} diff --git a/lib/data/services/pickup_imp.dart b/lib/data/services/pickup_imp.dart new file mode 100644 index 0000000..09b6f4a --- /dev/null +++ b/lib/data/services/pickup_imp.dart @@ -0,0 +1,19 @@ +import 'package:fcs/data/provider/pickup_data_provider.dart'; +import 'package:fcs/data/services/pickup_service.dart'; +import 'package:fcs/domain/entities/connectivity.dart'; +import 'package:fcs/domain/entities/pickup.dart'; + +class PickupServiceImp implements PickupService { + PickupServiceImp({ + required this.connectivity, + required this.pickupDataProvider, + }); + + final Connectivity? connectivity; + final PickupDataProvider pickupDataProvider; + + @override + Future completePickup(Pickup pickup) { + return pickupDataProvider.completePickup(pickup); + } +} diff --git a/lib/data/services/pickup_service.dart b/lib/data/services/pickup_service.dart new file mode 100644 index 0000000..39cd356 --- /dev/null +++ b/lib/data/services/pickup_service.dart @@ -0,0 +1,6 @@ +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/domain/entities/pickup.dart'; + +abstract class PickupService { + Future completePickup(Pickup pickup); +} diff --git a/lib/data/services/services.dart b/lib/data/services/services.dart index b2e15d0..9781363 100644 --- a/lib/data/services/services.dart +++ b/lib/data/services/services.dart @@ -5,6 +5,7 @@ import 'package:fcs/data/provider/delivery_address_data_provider.dart'; import 'package:fcs/data/provider/fcs_shipment_data_provider.dart'; import 'package:fcs/data/provider/invoice_data_provider.dart'; import 'package:fcs/data/provider/package_data_provider.dart'; +import 'package:fcs/data/provider/pickup_data_provider.dart'; import 'package:fcs/data/provider/rate_data_provider.dart'; import 'package:fcs/data/provider/shipment_data_provider.dart'; import 'package:fcs/data/provider/user_data_provider.dart'; @@ -16,6 +17,8 @@ import 'package:fcs/data/services/fcs_shipment_imp.dart'; import 'package:fcs/data/services/fcs_shipment_service.dart'; import 'package:fcs/data/services/invoice_imp.dart'; import 'package:fcs/data/services/invoice_service.dart'; +import 'package:fcs/data/services/pickup_imp.dart'; +import 'package:fcs/data/services/pickup_service.dart'; import 'package:fcs/data/services/rate_imp.dart'; import 'package:fcs/data/services/rate_service.dart'; import 'package:fcs/data/services/shipment_imp.dart'; @@ -46,6 +49,7 @@ class Services { late ShipmentService _shipmentService; late CartonService _cartonService; late InvoiceService _invoiceService; + late PickupService _pickupService; Services._() { _authService = AuthServiceImp( @@ -72,6 +76,8 @@ class Services { cartonDataProvider: CartonDataProvider.instance, connectivity: null); _invoiceService = InvoiceServiceImp( invoiceDataProvider: InvoiceDataProvider.instance, connectivity: null); + _pickupService = PickupServiceImp( + connectivity: null, pickupDataProvider: PickupDataProvider.instance); } AuthService get authService => _authService; @@ -85,4 +91,5 @@ class Services { ShipmentService get shipmentService => _shipmentService; CartonService get cartonService => _cartonService; InvoiceService get invoiceService => _invoiceService; + PickupService get pickupService => _pickupService; } diff --git a/lib/domain/constants.dart b/lib/domain/constants.dart index 865a62a..0bebe98 100644 --- a/lib/domain/constants.dart +++ b/lib/domain/constants.dart @@ -32,6 +32,7 @@ const user_joined_status = "joined"; const pkg_files_path = "/packages"; const shipment_labels_files_path = "/shipment_labels"; const receipt_labels_files_path = "/receipts"; +const pickups_files_path = "/pickups"; // Link page const page_payment_methods = "payment_methods"; @@ -79,7 +80,7 @@ const shipment_courier_dropoff = "Courier drop off"; //Carton types const carton_from_packages = "From packages"; -const carton_from_cartons="From cartons"; +const carton_from_cartons = "From cartons"; const carton_from_shipments = "From shipments"; const carton_mix_carton = "Mix carton"; const carton_small_bag = "Small bag"; diff --git a/lib/domain/entities/pickup.dart b/lib/domain/entities/pickup.dart index d462337..6f36444 100644 --- a/lib/domain/entities/pickup.dart +++ b/lib/domain/entities/pickup.dart @@ -20,6 +20,10 @@ class Pickup { String? shipperPhoneNumber; String? status; + // for complete + String? completeRemark; + List photoUrls; + List packages; Pickup( @@ -37,7 +41,8 @@ class Pickup { this.shipperName, this.shipperPhoneNumber, this.status, - this.packages = const []}); + this.packages = const [], + this.photoUrls = const []}); @override bool operator ==(Object other) => other is Pickup && other.id == id; @@ -83,6 +88,14 @@ class Pickup { }; } + Map toMapForComplete() { + return { + "id": id, + "complete_remark": completeRemark, + 'photo_urls': photoUrls ?? [], + }; + } + @override String toString() { return 'Pickup{id: $id}'; diff --git a/lib/pages/pickup/model/pickup_model.dart b/lib/pages/pickup/model/pickup_model.dart index c09821d..076b41e 100644 --- a/lib/pages/pickup/model/pickup_model.dart +++ b/lib/pages/pickup/model/pickup_model.dart @@ -1,15 +1,20 @@ import 'dart:async'; import 'dart:io'; +import 'dart:math'; import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:fcs/data/services/services.dart'; +import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/domain/entities/pickup.dart'; import 'package:fcs/domain/entities/processing.dart'; +import 'package:fcs/helpers/firebase_helper.dart'; import 'package:fcs/pages/main/model/base_model.dart'; import 'package:fcs/pagination/paginator_listener.dart'; import 'package:logging/logging.dart'; +import 'package:path/path.dart' as Path; class PickupModel extends BaseModel { - // List pickups = []; final log = Logger('PickupModel'); StreamSubscription? listener; @@ -48,7 +53,33 @@ class PickupModel extends BaseModel { // pickups = []; } - Future createProcessing(Processing processing) async {} + Future complete( + Pickup pickup, List files, List deletedUrls) async { + for (String? url in deletedUrls) { + pickup.photoUrls.remove(url); + } - Future updateProcessing(Processing processing) async {} + // check files count + var count = (pickup.photoUrls.length) + files.length - (deletedUrls.length); + if (count > uploadPhotoLimit) + throw Exception("Exceed number of file upload"); + + List uploadedURLs = []; + String path = Path.join(pickups_files_path, pickup.id); + uploadedURLs = await uploadFiles(path, files); + pickup.photoUrls.addAll(uploadedURLs); + pickup.photoUrls.removeWhere((e) => deletedUrls.contains(e)); + + try { + await Services.instance.pickupService.completePickup(pickup); + } catch (e) { + // delete newly uploaded photos if fails + try { + deleteStorageFromUrls(uploadedURLs); + pickup.photoUrls.removeWhere((i) => uploadedURLs.contains(i)); + } catch (e) {} + throw e; + } + return deleteStorageFromUrls(deletedUrls); + } }