no message

merge-update-with-lab-changes
Zohaib Iqbal Kambrani 5 years ago
parent 4d950d3933
commit 516df96e21

@ -26,6 +26,10 @@ const GET_PROJECT = 'Services/Lists.svc/REST/GetProject';
///Geofencing ///Geofencing
const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints'; const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints';
const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo'; const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo';
// Delivery Driver
const DRIVER_LOCATION = 'Services/Patients.svc/REST/PatientER_GetDriverLocation';
//weather //weather
const WEATHER_INDICATOR = 'Services/Weather.svc/REST/GetCityInfo'; const WEATHER_INDICATOR = 'Services/Weather.svc/REST/GetCityInfo';

@ -73,6 +73,8 @@ class OrderModel {
this.preferDeliveryDate, this.preferDeliveryDate,
this.preferDeliveryTime, this.preferDeliveryTime,
this.preferDeliveryTimen, this.preferDeliveryTimen,
this.driverID,
this.driverOTP,
}); });
String id; String id;
@ -138,6 +140,8 @@ class OrderModel {
DateTime preferDeliveryDate; DateTime preferDeliveryDate;
PreferDeliveryTime preferDeliveryTime; PreferDeliveryTime preferDeliveryTime;
PreferDeliveryTimen preferDeliveryTimen; PreferDeliveryTimen preferDeliveryTimen;
String driverOTP;
String driverID;
factory OrderModel.fromJson(Map<String, dynamic> json) => OrderModel( factory OrderModel.fromJson(Map<String, dynamic> json) => OrderModel(
id: json["id"], id: json["id"],
@ -203,6 +207,11 @@ class OrderModel {
preferDeliveryDate: json["prefer_delivery_date"] == null ? null : DateTime.parse(json["prefer_delivery_date"]), preferDeliveryDate: json["prefer_delivery_date"] == null ? null : DateTime.parse(json["prefer_delivery_date"]),
preferDeliveryTime: json["prefer_delivery_time"] == null ? null : preferDeliveryTimeValues.map[json["prefer_delivery_time"]], preferDeliveryTime: json["prefer_delivery_time"] == null ? null : preferDeliveryTimeValues.map[json["prefer_delivery_time"]],
preferDeliveryTimen: json["prefer_delivery_timen"] == null ? null : preferDeliveryTimenValues.map[json["prefer_delivery_timen"]], preferDeliveryTimen: json["prefer_delivery_timen"] == null ? null : preferDeliveryTimenValues.map[json["prefer_delivery_timen"]],
// Driver Detail
driverID: json["DriverID"],
driverOTP: json["DriverOTP"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
@ -1364,7 +1373,7 @@ final titleValues = EnumValues({
"ممتاز": Title.TITLE "ممتاز": Title.TITLE
}); });
enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE } enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS,ORDER_SENT_FOR_DELIVERY, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE }
final orderStatusValues = EnumValues({ final orderStatusValues = EnumValues({
"Cancelled": OrderStatus.CANCELLED, "Cancelled": OrderStatus.CANCELLED,
@ -1374,7 +1383,8 @@ final orderStatusValues = EnumValues({
"OrderRefunded": OrderStatus.ORDER_REFUNDED, "OrderRefunded": OrderStatus.ORDER_REFUNDED,
"OrderSubmitted": OrderStatus.ORDER_SUBMITTED, "OrderSubmitted": OrderStatus.ORDER_SUBMITTED,
"Pending": OrderStatus.PENDING, "Pending": OrderStatus.PENDING,
"Processing": OrderStatus.PROCESSING "Processing": OrderStatus.PROCESSING,
"orderSentForDelivery": OrderStatus.ORDER_SENT_FOR_DELIVERY
}); });
enum OrderStatusn { ORDER_SUBMITTED, EMPTY, ORDER_IN_PROGRESS, ORDER_COMPLETED, ORDER_STATUSN, PURPLE, FLUFFY, TENTACLED } enum OrderStatusn { ORDER_SUBMITTED, EMPTY, ORDER_IN_PROGRESS, ORDER_COMPLETED, ORDER_STATUSN, PURPLE, FLUFFY, TENTACLED }
@ -1387,6 +1397,7 @@ final orderStatusnValues = EnumValues({
"ملغي": OrderStatusn.ORDER_STATUSN, "ملغي": OrderStatusn.ORDER_STATUSN,
"Order Submitted": OrderStatusn.ORDER_SUBMITTED, "Order Submitted": OrderStatusn.ORDER_SUBMITTED,
"قيد التنفيذ": OrderStatusn.PURPLE, "قيد التنفيذ": OrderStatusn.PURPLE,
"مكتمل": OrderStatusn.TENTACLED,
"مكتمل": OrderStatusn.TENTACLED "مكتمل": OrderStatusn.TENTACLED
}); });

@ -6,6 +6,8 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart';
import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart';
import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart';
import 'package:flutter/cupertino.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class OrderPreviewService extends BaseService { class OrderPreviewService extends BaseService {
bool isFinished = true; bool isFinished = true;
@ -245,4 +247,26 @@ class OrderPreviewService extends BaseService {
return ""; return "";
} }
} }
Future<LatLng> getDriverLocation(dynamic driverId) async{
Map<String, dynamic> jsonBody = Map();
jsonBody['DriverID'] = driverId;
LatLng coordinates;
await baseAppClient.post(DRIVER_LOCATION,
onSuccess: (response, statusCode) async {
if(statusCode == 200){
dynamic locationObject = response['PatientER_GetDriverLocationList'][0];
double lat = locationObject['Latitude'];
double lon = locationObject['Longitude'];
if(lat != null && lon != null){
coordinates = LatLng(lat,lon);
}
}
}, onFailure: (String error, int statusCode) {
}, body: jsonBody);
return coordinates;
}
} }

@ -50,7 +50,7 @@ class OrderModelViewModel extends BaseViewModel {
} }
} }
Future getOrderDetails(OrderId) async { Future<OrderModel> getOrderDetails(OrderId) async {
setState(ViewState.Busy); setState(ViewState.Busy);
await _orderDetailsService.getOrderDetails(OrderId); await _orderDetailsService.getOrderDetails(OrderId);
if (_orderDetailsService.hasError) { if (_orderDetailsService.hasError) {
@ -59,6 +59,7 @@ class OrderModelViewModel extends BaseViewModel {
} else { } else {
setState(ViewState.Idle); setState(ViewState.Idle);
} }
return _orderDetailsService.orderList.first;
} }
Future getProductReview() async { Future getProductReview() async {

@ -48,7 +48,7 @@ class _OrderDetailsPageState extends State<OrderDetailsPage> {
var model; var model;
var isCancel = false; var isCancel = false;
var isRefund = false; var isRefund = false;
var isActiveDelivery = true; var isActiveDelivery = false;
var dataIsCancel; var dataIsCancel;
var dataIsRefund; var dataIsRefund;
@ -66,7 +66,13 @@ class _OrderDetailsPageState extends State<OrderDetailsPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BaseView<OrderModelViewModel>( return BaseView<OrderModelViewModel>(
onModelReady: (model) => model.getOrderDetails(widget.orderModel.id), onModelReady: (model){
model.getOrderDetails(widget.orderModel.id).then((value){
setState(() {
isActiveDelivery = (value.orderStatusId == 995 && (value.driverID != null && value.driverID.isNotEmpty));
});
});
},
builder: (_, model, wi) => AppScaffold( builder: (_, model, wi) => AppScaffold(
appBarTitle: TranslationBase.of(context).orderDetail, appBarTitle: TranslationBase.of(context).orderDetail,
isShowAppBar: true, isShowAppBar: true,
@ -596,10 +602,10 @@ class _OrderDetailsPageState extends State<OrderDetailsPage> {
isActiveDelivery isActiveDelivery
? InkWell( ? InkWell(
onTap: () { onTap: () {
// Navigator.push( Navigator.push(
// context, context,
// MaterialPageRoute(builder: (context) => TrackDriver(order: widget.orderModel), MaterialPageRoute(builder: (context) => TrackDriver(order: model.orderListModel.first),
// )); ));
}, },
child: Container( child: Container(
height: 50.0, height: 50.0,

@ -1,12 +1,19 @@
import 'dart:async'; import 'dart:async';
import 'package:async/async.dart';
import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/config.dart';
import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart';
import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart';
import 'package:diplomaticquarterapp/locator.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_animarker/lat_lng_interpolation.dart';
import 'package:flutter_animarker/models/lat_lng_delta.dart';
import 'package:flutter_animarker/models/lat_lng_info.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart'; import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart'; import 'package:location/location.dart';
import 'package:flutter_animarker/streams/lat_lng_stream.dart';
class TrackDriver extends StatefulWidget { class TrackDriver extends StatefulWidget {
final OrderModel order; final OrderModel order;
@ -17,12 +24,13 @@ class TrackDriver extends StatefulWidget {
} }
class _TrackDriverState extends State<TrackDriver> { class _TrackDriverState extends State<TrackDriver> {
OrderPreviewService _orderServices = locator<OrderPreviewService>();
OrderModel _order; OrderModel _order;
Completer<GoogleMapController> _controller = Completer(); Completer<GoogleMapController> _controller = Completer();
double CAMERA_ZOOM = 16; double CAMERA_ZOOM = 14;
double CAMERA_TILT = 0; double CAMERA_TILT = 0;
double CAMERA_BEARING = 30; double CAMERA_BEARING = 30;
LatLng SOURCE_LOCATION = null; LatLng SOURCE_LOCATION = null;
@ -39,17 +47,63 @@ class _TrackDriverState extends State<TrackDriver> {
BitmapDescriptor destinationIcon; // for my custom marker pins BitmapDescriptor destinationIcon; // for my custom marker pins
Location location;// wrapper around the location API Location location;// wrapper around the location API
int locationUpdateFreq = 2;
LatLngInterpolationStream _latLngStream;
StreamGroup<LatLngDelta> subscriptions;
@override @override
void initState() { void initState() {
_order = widget.order; _order = widget.order;
DEST_LOCATION = _order.shippingAddress.getLocation(); DEST_LOCATION = _order.shippingAddress.getLocation();
location = new Location(); location = new Location();
polylinePoints = PolylinePoints(); polylinePoints = PolylinePoints();
setSourceAndDestinationIcons(); setSourceAndDestinationIcons();
initMarkerUpdateStream();
startUpdatingDriverLocation();
super.initState();
}
@override
void dispose() {
super.dispose();
subscriptions.close();
_latLngStream.cancel();
stopUpdatingDriverLocation();
}
initMarkerUpdateStream(){
_latLngStream = LatLngInterpolationStream(movementDuration: Duration(seconds: locationUpdateFreq+1));
subscriptions = StreamGroup<LatLngDelta>();
subscriptions.add(_latLngStream.getAnimatedPosition('sourcePin'));
subscriptions.stream.listen((LatLngDelta delta) {
//Update the marker with animation
setState(() {
//Get the marker Id for this animation
var markerId = MarkerId(delta.markerId);
Marker sourceMarker = Marker(
markerId: markerId,
// rotation: delta.rotation,
icon: sourceIcon,
position: LatLng(
delta.from.latitude,
delta.from.longitude,
),
);
_markers.removeWhere((m) => m.markerId.value == 'sourcePin');
_markers.add(sourceMarker);
});
});
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new Scaffold( return new Scaffold(
body: GoogleMap( body: GoogleMap(
myLocationEnabled: true, myLocationEnabled: true,
@ -63,11 +117,11 @@ class _TrackDriverState extends State<TrackDriver> {
showPinsOnMap(); showPinsOnMap();
}, },
), ),
floatingActionButton: FloatingActionButton.extended( // floatingActionButton: FloatingActionButton.extended(
onPressed: _goToDriver, // onPressed: _goToDriver,
label: Text('To the lake!'), // label: Text('To the lake!'),
icon: Icon(Icons.directions_boat), // icon: Icon(Icons.directions_boat),
), // ),
); );
} }
@ -130,6 +184,7 @@ class _TrackDriverState extends State<TrackDriver> {
if(SOURCE_LOCATION != null){ if(SOURCE_LOCATION != null){
setState(() { setState(() {
var pinPosition = SOURCE_LOCATION; var pinPosition = SOURCE_LOCATION;
_markers.removeWhere((m) => m.markerId.value == 'sourcePin');
_markers.add(Marker( _markers.add(Marker(
markerId: MarkerId('sourcePin'), markerId: MarkerId('sourcePin'),
position: pinPosition, position: pinPosition,
@ -142,6 +197,7 @@ class _TrackDriverState extends State<TrackDriver> {
if(DEST_LOCATION != null){ if(DEST_LOCATION != null){
setState(() { setState(() {
var destPosition = DEST_LOCATION; var destPosition = DEST_LOCATION;
_markers.removeWhere((m) => m.markerId.value == 'destPin');
_markers.add(Marker( _markers.add(Marker(
markerId: MarkerId('destPin'), markerId: MarkerId('destPin'),
position: destPosition, position: destPosition,
@ -166,21 +222,26 @@ class _TrackDriverState extends State<TrackDriver> {
); );
final GoogleMapController controller = await _controller.future; final GoogleMapController controller = await _controller.future;
controller.animateCamera(CameraUpdate.newCameraPosition(cPosition)); controller.animateCamera(CameraUpdate.newCameraPosition(cPosition));
_latLngStream.addLatLng(LatLngInfo(SOURCE_LOCATION.latitude, SOURCE_LOCATION.longitude, "sourcePin"));
// do this inside the setState() so Flutter gets notified // do this inside the setState() so Flutter gets notified
// that a widget update is due // that a widget update is due
setState(() { // setState(() {
// updated position // // updated position
var pinPosition = SOURCE_LOCATION; // var pinPosition = SOURCE_LOCATION;
//
// the trick is to remove the marker (by id) // // the trick is to remove the marker (by id)
// and add it again at the updated location // // and add it again at the updated location
_markers.removeWhere((m) => m.markerId.value == 'sourcePin'); // _markers.removeWhere((m) => m.markerId.value == 'sourcePin');
_markers.add(Marker( // _markers.add(Marker(
markerId: MarkerId('sourcePin'), // markerId: MarkerId('sourcePin'),
position: pinPosition, // updated position // position: pinPosition, // updated position
icon: sourceIcon // icon: sourceIcon
)); // ));
}); // });
drawRoute();
} }
void drawRoute() async { void drawRoute() async {
@ -208,4 +269,33 @@ class _TrackDriverState extends State<TrackDriver> {
}); });
} }
} }
bool isLocationUpdating = false;
startUpdatingDriverLocation({int frequencyInSeconds = 2}) async{
isLocationUpdating = true;
int driverId = int.tryParse(_order.driverID);
Future.doWhile(() async{
await Future.delayed(Duration(seconds: frequencyInSeconds));
if(isLocationUpdating){
LatLng driverLocation = (await _orderServices.getDriverLocation(driverId));
if(driverLocation != null){
if(SOURCE_LOCATION == null || DEST_LOCATION == null){
SOURCE_LOCATION = driverLocation;
DEST_LOCATION = _order.shippingAddress.getLocation();
showPinsOnMap();
}
SOURCE_LOCATION = driverLocation;
updatePinOnMap();
}
}
return isLocationUpdating;
});
}
stopUpdatingDriverLocation(){
isLocationUpdating = false;
}
} }

@ -21,6 +21,7 @@ dependencies:
# http client # http client
http: ^0.12.1 http: ^0.12.1
connectivity: ^0.4.9+3 connectivity: ^0.4.9+3
async: ^2.4.2
# State Management # State Management
provider: ^4.3.2+2 provider: ^4.3.2+2
@ -170,6 +171,9 @@ dependencies:
# Dep by Zohaib # Dep by Zohaib
shimmer: ^1.1.2 shimmer: ^1.1.2
# Marker Animation
flutter_animarker: ^1.0.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter

Loading…
Cancel
Save