You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
479 lines
21 KiB
Dart
479 lines
21 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:android_intent/android_intent.dart';
|
|
import 'package:driverapp/app-icons/driver_app_icons.dart';
|
|
import 'package:driverapp/config/config.dart';
|
|
import 'package:driverapp/core/enum/viewstate.dart';
|
|
import 'package:driverapp/core/model/StatusModel.dart';
|
|
import 'package:driverapp/core/model/orders/pending_orders_req_model.dart';
|
|
import 'package:driverapp/core/model/orders/pending_orders_res_model.dart';
|
|
import 'package:driverapp/core/model/orders/update_order_status_request_model.dart';
|
|
import 'package:driverapp/core/service/delivery_tracking_services.dart';
|
|
import 'package:driverapp/core/viewModels/orders_view_model.dart';
|
|
import 'package:driverapp/locator.dart';
|
|
import 'package:driverapp/pages/authentication/delivery_verification_page.dart';
|
|
import 'package:driverapp/pages/authentication/verification_page.dart';
|
|
import 'package:driverapp/pages/base/base_view.dart';
|
|
import 'package:driverapp/uitl/app_shared_preferences.dart';
|
|
import 'package:driverapp/uitl/app_toast.dart';
|
|
import 'package:driverapp/uitl/translations_delegate_base.dart';
|
|
import 'package:driverapp/uitl/utils.dart';
|
|
import 'package:driverapp/widgets/bottom_sheet/action_sheet_button.dart';
|
|
import 'package:driverapp/widgets/buttons/secondary_button.dart';
|
|
import 'package:driverapp/widgets/data_display/dialog/custom_dialog.dart';
|
|
import 'package:driverapp/widgets/data_display/text.dart';
|
|
import 'package:driverapp/widgets/delivery/customer_brief_card.dart';
|
|
import 'package:driverapp/widgets/delivery/delivery_action_button.dart';
|
|
import 'package:driverapp/widgets/delivery/package_content.dart';
|
|
import 'package:driverapp/widgets/others/app_scaffold_widget.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_material_pickers/flutter_material_pickers.dart';
|
|
import 'package:hexcolor/hexcolor.dart';
|
|
import 'package:map_launcher/map_launcher.dart';
|
|
import 'package:sweetalert/sweetalert.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
|
|
import 'delivery_cancel_page.dart';
|
|
import 'delivery_confirmed_page.dart';
|
|
|
|
|
|
class InformationPage extends StatefulWidget {
|
|
final PendingOrdersRes item;
|
|
InformationPage({this.item});
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => _InformationPageState();
|
|
|
|
}
|
|
|
|
// ignore: must_be_immutable
|
|
class _InformationPageState extends State<InformationPage> {
|
|
var _deliveryService = locator<DeliveryTrackingServices>();
|
|
PendingOrdersRes _item;
|
|
bool _isDeliveryStarted;
|
|
OrdersViewModel _viewModel;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_item = widget.item;
|
|
_isDeliveryStarted = _deliveryService.getActiveDeliveringOrders().contains(_item.ePharmacyOrderNo.toString());
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
|
|
return BaseView<OrdersViewModel>(
|
|
onModelReady: (model) => _viewModel = model,
|
|
builder: (_, model, w) => AppScaffold(
|
|
isShowAppBar: true,
|
|
isShowHomeIcon: true,
|
|
appBarColor: Color(0xff49C1BC),
|
|
arrowColor: Colors.white,
|
|
titleColor: Colors.white,
|
|
appBarTitle: TranslationBase.of(context).deliveryInfo,
|
|
isAppBarGradient: true,
|
|
body: SingleChildScrollView(
|
|
child: Container(
|
|
decoration: BoxDecoration(gradient: LINEAR_GRADIENT),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Stack(
|
|
children: <Widget>[
|
|
// Container(
|
|
// width: MediaQuery.of(context).size.width,
|
|
// height: MediaQuery.of(context).size.width,
|
|
// ),
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 75.0),
|
|
child: Container(
|
|
width: MediaQuery.of(context).size.width * 1.0,
|
|
height: MediaQuery.of(context).orientation ==
|
|
Orientation.portrait
|
|
? MediaQuery.of(context).size.height * 0.70
|
|
: MediaQuery.of(context).size.height * 1.7,
|
|
margin: EdgeInsets.only(
|
|
top: MediaQuery.of(context).orientation ==
|
|
Orientation.portrait
|
|
? MediaQuery.of(context).size.width * 0.23
|
|
: MediaQuery.of(context).size.width * 0.13),
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).scaffoldBackgroundColor,
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(45),
|
|
topRight: Radius.circular(45)),
|
|
),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
Visibility(
|
|
visible: _isDeliveryStarted,
|
|
child: Padding(
|
|
padding: MediaQuery.of(context).orientation ==
|
|
Orientation.portrait
|
|
? EdgeInsets.only(top: 60.0)
|
|
: EdgeInsets.only(top: 15.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
DeliveryInfoButton(
|
|
btnColor: Colors.white, //Color(0xffED1C24),
|
|
btnIcon: Icon(DriverApp.location_1,
|
|
size: MediaQuery.of(context)
|
|
.orientation ==
|
|
Orientation.portrait
|
|
? 50
|
|
: 90,
|
|
color: Color(0xffED1C24)),
|
|
btnName:
|
|
TranslationBase.of(context).location,
|
|
btnFunction: () {
|
|
_openMapDirection(_item);
|
|
// MapsLauncher.launchCoordinates(
|
|
// _item.latitude, _item.longitude);
|
|
},
|
|
),
|
|
DeliveryInfoButton(
|
|
btnColor: Colors.white,
|
|
//Theme.of(context).primaryColor,
|
|
btnIcon: Icon(
|
|
DriverApp.call,
|
|
size:
|
|
MediaQuery.of(context).orientation ==
|
|
Orientation.portrait
|
|
? 50
|
|
: 90,
|
|
color: Theme.of(context).primaryColor,
|
|
),
|
|
btnName: TranslationBase.of(context).call,
|
|
btnFunction: () =>
|
|
launch("tel://" + _item.mobileNumber),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
margin: EdgeInsets.only(
|
|
left: MediaQuery.of(context).size.width * 0.05,
|
|
right: MediaQuery.of(context).size.width * 0.05,
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 8),
|
|
child: Text(
|
|
TranslationBase.of(context)
|
|
.packageContent,
|
|
style: TextStyle(
|
|
fontWeight: FontWeight.w900,
|
|
fontSize: 20),
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: MediaQuery.of(context).size.width *
|
|
0.05,
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.only(left: 10),
|
|
child: Column(
|
|
children: List.generate(
|
|
_item.itemsQuantitiesList != null
|
|
? _item.itemsQuantitiesList.length
|
|
: 0, (index) {
|
|
return packageContent(
|
|
packageName: _item
|
|
.itemsQuantitiesList[index]
|
|
.itemName
|
|
.toString(),
|
|
packageCount: _item
|
|
.itemsQuantitiesList[index]
|
|
.quantity
|
|
.toString(),
|
|
);
|
|
}),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: MediaQuery.of(context).size.width * 0.1,
|
|
),
|
|
Container(
|
|
margin: MediaQuery.of(context).orientation ==
|
|
Orientation.portrait
|
|
? EdgeInsets.all(8.0)
|
|
: EdgeInsets.symmetric(horizontal: 12.0),
|
|
child: SecondaryButton(
|
|
label: _isDeliveryStarted
|
|
? TranslationBase.of(context).deliveryOption
|
|
: TranslationBase.of(context).startDelivery,
|
|
onTap: () {
|
|
takeAction();
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
CustomerBriefCard(
|
|
customerOrderId: _item.orderID,
|
|
pharmacyOrderId: _item.ePharmacyOrderNo,
|
|
customerFirstName: _item.firstName,
|
|
customerLastName: _item.lastName,
|
|
mobileNo: _item.mobileNumber,
|
|
totalPayment: _item.amount,
|
|
deliveryTime: _item.orderCreatedOn,
|
|
longitude: _item.longitude,
|
|
latitude: _item.latitude,
|
|
distanceInKilometers: _item.distanceInKilometers,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void takeAction(){
|
|
if(_isDeliveryStarted) {
|
|
showDeliveryOptions(_viewModel);
|
|
}else{
|
|
if(_deliveryService.getActiveDeliveringOrders().isEmpty){
|
|
SweetAlert.show(context,subtitle: "Initializing delivery...", style: SweetAlertStyle.loading);
|
|
_viewModel.initDelivery(_item, completion: (response) {
|
|
if (response.isSuccessful) {
|
|
setState(() => _isDeliveryStarted = true);
|
|
Navigator.pop(context);
|
|
AppToast.showSuccessToast(message: "Start navigation by clicking icon [${response.data}]");
|
|
|
|
}else{
|
|
SweetAlert.show(context,subtitle: response.message, style: SweetAlertStyle.error);
|
|
}
|
|
});
|
|
}else{
|
|
SweetAlert.show(context,subtitle: "Complete the last delivery first.",style: SweetAlertStyle.error);
|
|
}
|
|
}
|
|
}
|
|
|
|
cancelDelivery() {
|
|
List<String> speedOptions = <String>[
|
|
TranslationBase.of(context).notReachableOnPhoneCall,
|
|
TranslationBase.of(context).notAvailableAtlocation,
|
|
TranslationBase.of(context).accident,
|
|
TranslationBase.of(context).deliverLater,
|
|
// TranslationBase.of(context).other,
|
|
];
|
|
|
|
List<Icon> speedIcons = <Icon>[
|
|
Icon(IconData(0xe901, fontFamily: 'HMGIcon1')),
|
|
Icon(IconData(0xe900, fontFamily: 'HMGIcon1')),
|
|
Icon(IconData(0xe902, fontFamily: 'HMGIcon1')),
|
|
Icon(IconData(0xe903, fontFamily: 'HMGIcon1')),
|
|
];
|
|
|
|
showMaterialSelectionPicker(
|
|
context: context,
|
|
title: TranslationBase.of(context).selectReason,
|
|
items: speedOptions,
|
|
selectedItem: speedOptions.first,
|
|
icons: speedIcons,
|
|
onChanged: (value) async {
|
|
SweetAlert.show(context,subtitle: "Canceling delivery...", style: SweetAlertStyle.loading);
|
|
var result = await _viewModel.updateOrderStatus(orderNo: _item.orderID, status: DeliveryStatus.cancel);
|
|
Navigator.pop(context);
|
|
if(result.isSuccessful){
|
|
_viewModel.deliveryService.stopLocationUpdate(_item.ePharmacyOrderNo);
|
|
Navigator.pushReplacement(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) => DeliveryCancelRejectedPage(_item), // Replace with Delivery Cancel Screen
|
|
),
|
|
);
|
|
|
|
}else{
|
|
SweetAlert.show(context,subtitle: result.message,style: SweetAlertStyle.error);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
|
|
showDeliveryOptions(OrdersViewModel model) {
|
|
showModalBottomSheet(
|
|
backgroundColor: Colors.white,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(50.0),
|
|
topRight: Radius.circular(50.0),
|
|
),
|
|
),
|
|
isScrollControlled: true,
|
|
context: context,
|
|
builder: (BuildContext bc) {
|
|
return FractionallySizedBox(
|
|
heightFactor: 0.40,
|
|
child: ListView(
|
|
children: <Widget>[
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(50.0),
|
|
topRight: Radius.circular(50.0),
|
|
),
|
|
),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: <Widget>[
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Center(
|
|
child: Texts(
|
|
TranslationBase.of(context).selectAction,
|
|
color: Colors.black,
|
|
fontSize: 22,
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
FractionallySizedBox(
|
|
widthFactor: MediaQuery.of(context).orientation == Orientation.portrait
|
|
? 0.9
|
|
: 0.98,
|
|
child: Container(
|
|
height: MediaQuery.of(context).size.height * 0.45,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(50.0),
|
|
topRight: Radius.circular(50.0),
|
|
),
|
|
),
|
|
width: double.infinity,
|
|
child: ListView(
|
|
children: <Widget>[
|
|
Column(
|
|
children: <Widget>[
|
|
SizedBox(
|
|
height: 3,
|
|
child: Container(
|
|
color: HexColor("#D5D5D5"),
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 15,
|
|
),
|
|
ActionSheetButton(
|
|
label:
|
|
TranslationBase.of(context).delivered,
|
|
icon: DriverApp.deliverd_icon,
|
|
onTap: () {
|
|
Navigator.of(context).pop(); // Pop Bottom Action Sheet
|
|
Navigator.pushReplacement(
|
|
context,
|
|
MaterialPageRoute(builder: (context) => DeliveryVerificationPage(order: _item)),
|
|
);
|
|
},
|
|
),
|
|
SizedBox(height: 15),
|
|
// ActionSheetButton(
|
|
// label: TranslationBase.of(context)
|
|
// .deliveredAccepted,
|
|
// icon: DriverApp.not_available,
|
|
// onTap: () {
|
|
// selectAction(context, 4, model);
|
|
// },
|
|
// ),
|
|
// SizedBox(height: 15),
|
|
ActionSheetButton(
|
|
label: TranslationBase.of(context)
|
|
.deliveredRejected,
|
|
icon: DriverApp.rejected_icon,
|
|
onTap: () {
|
|
Navigator.of(context).pop(); // Pop Bottom Action Sheet
|
|
rejectDelivery();
|
|
}
|
|
),
|
|
SizedBox(height: 15),
|
|
ActionSheetButton(
|
|
label: TranslationBase.of(context).cancel,
|
|
icon: DriverApp.not_reachable_icon,
|
|
onTap: () {
|
|
cancelDelivery();
|
|
},
|
|
),
|
|
SizedBox(height: 15),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
rejectDelivery(){
|
|
SweetAlert.show(context,title: "Are you sure?",style: SweetAlertStyle.confirm, showCancelButton: true,onPress: (bool isConfirm) {
|
|
if (isConfirm) {
|
|
_viewModel.updateOrderStatus(orderNo: _item.orderID, status: DeliveryStatus.rejected).then((results){
|
|
|
|
});
|
|
}
|
|
return true;
|
|
});
|
|
}
|
|
|
|
_openMapDirection(PendingOrdersRes order) async{
|
|
Utils.getLocation().then((locationData){
|
|
if(locationData != null){
|
|
// MapLauncher.isMapAvailable(MapType.google).then((value){
|
|
// if (value) {
|
|
// MapLauncher.showDirections(
|
|
// mapType: MapType.google,
|
|
// destination: Coords(order.latitude, order.longitude),
|
|
// directionsMode: DirectionsMode.driving,
|
|
// destinationTitle: order.receiverFullName())
|
|
// .then((value) {
|
|
//
|
|
// });
|
|
// }else{
|
|
// // Google Map Not installed show error
|
|
// }
|
|
// });
|
|
|
|
/* Directly start navigation */
|
|
MapLauncher.isMapAvailable(MapType.google).then((value){
|
|
var url = "https://www.google.com/maps/dir/?api=1&destination=${order.latitude},${order.longitude}&travelmode=driving&dir_action=navigate";
|
|
if (Platform.isAndroid) {
|
|
var intent = AndroidIntent(action: 'action_view',data: url,package: 'com.google.android.apps.maps');
|
|
intent.launch();
|
|
}else if (Platform.isIOS) {
|
|
launch(url);
|
|
}
|
|
});
|
|
|
|
// Start updating server wit your current location
|
|
_deliveryService.startLocationUpdate(order.ePharmacyOrderNo);
|
|
|
|
}
|
|
});
|
|
}
|
|
}
|