summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrik@amftech.nl>2023-02-08 20:08:23 +0100
committerAldrik Ramaekers <aldrik@amftech.nl>2023-02-08 20:08:23 +0100
commitfcbf592d10199dbac80198dd8c2efb181f95165e (patch)
tree4fd50f1bf1c65c7180f1f3b7d64fc1603bf9be73 /lib
parente37d74527e03b6a804a35cbfb0956d4e0100889f (diff)
blacklist
Diffstat (limited to 'lib')
-rw-r--r--lib/RoutingExample.dart49
-rw-r--r--lib/config/defaults.dart2
-rw-r--r--lib/main.dart4
-rw-r--r--lib/pages/all_routes_page.dart27
-rw-r--r--lib/pages/blacklist_page.dart233
-rw-r--r--lib/pages/home_page.dart10
-rw-r--r--lib/services/iblacklist_provider_service.dart31
-rw-r--r--lib/services/local_blacklist_provider_service.dart57
-rw-r--r--lib/services/storegear_api_service.dart2
9 files changed, 401 insertions, 14 deletions
diff --git a/lib/RoutingExample.dart b/lib/RoutingExample.dart
index 910fe3e..ebe08b3 100644
--- a/lib/RoutingExample.dart
+++ b/lib/RoutingExample.dart
@@ -20,6 +20,7 @@ import 'package:training_planner/events/MapPanningEvent.dart';
import 'package:training_planner/events/NextStopLoadedEvent.dart';
import 'package:training_planner/events/StopCompletedEvent.dart';
import 'package:training_planner/pages/navigation_page.dart';
+import 'package:training_planner/services/iblacklist_provider_service.dart';
import 'route.dart' as DHLRoute;
import 'main.dart';
@@ -30,11 +31,19 @@ typedef ShowDialogFunction = void Function(String title, String message);
class DestinationPin {
final String text;
final GeoCoordinates? coords;
+ final String? postalcodeNumeric;
+ final String? postalcodeAlpha;
+ final String? houseNumberWithExtra;
WidgetPin? pin;
bool isDoublePlannedAddress;
DestinationPin(
- {this.text = '', this.coords, required this.isDoublePlannedAddress});
+ {this.text = '',
+ this.coords,
+ required this.isDoublePlannedAddress,
+ required this.postalcodeNumeric,
+ required this.postalcodeAlpha,
+ required this.houseNumberWithExtra});
}
class ActiveTask {
@@ -76,6 +85,8 @@ class RoutingExample {
late SearchOptions _searchOptions;
late MapMarker mapMarker;
+ List<BlacklistEntry> blacklist = [];
+
Future<Uint8List> _loadFileAsUint8List(String assetPathToFile) async {
// The path refers to the assets directory as specified in pubspec.yaml.
ByteData fileData = await rootBundle.load(assetPathToFile);
@@ -131,6 +142,8 @@ class RoutingExample {
updateHighlightedRouteSections();
eventBus.fire(NextStopLoadedEvent());
});
+
+ blacklistProvider.getBlacklist().then((value) => {blacklist = value});
}
void destroy() {
@@ -189,6 +202,7 @@ class RoutingExample {
padding: EdgeInsets.all(2),
decoration: BoxDecoration(
color: backgroundColor,
+ borderRadius: BorderRadius.circular(10),
shape: BoxShape.rectangle,
border: Border.all(
color: isDoublePlannedAddress
@@ -273,7 +287,11 @@ class RoutingExample {
? item.houseNumberAddition!
: ''),
coords: destinationGeoCoordinates,
- isDoublePlannedAddress: false),
+ isDoublePlannedAddress: false,
+ postalcodeNumeric: item.postalCodeNumeric,
+ postalcodeAlpha: item.postalCodeAlpha,
+ houseNumberWithExtra:
+ item.houseNumber! + (item.houseNumberAddition ?? '')),
);
_destinationCoords.add(destinationGeoCoordinates);
@@ -354,6 +372,24 @@ class RoutingExample {
}
}
+ bool destinationPinIsInBlacklist(DestinationPin pin) {
+ try {
+ for (int i = 0; i < blacklist.length; i++) {
+ if (pin.postalcodeNumeric == blacklist[i].postalcodeNumeric &&
+ pin.postalcodeAlpha!.toLowerCase() ==
+ blacklist[i].postalcodeAplha &&
+ pin.houseNumberWithExtra!.toLowerCase() ==
+ (blacklist[i].houseNumber.toString() +
+ blacklist[i].houseNumberExtra.toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ } catch (e) {
+ return false;
+ }
+ }
+
void updateHighlightedRouteSections() {
// Show the next 20 parcel pins, to let the delivery driver decide on possible detours.
int maxPins = 300;
@@ -391,6 +427,15 @@ class RoutingExample {
widgetPin?.anchor = Anchor2D.withHorizontalAndVertical(0.5, 0.5);
pin.pin = widgetPin;
}
+
+ if (destinationPinIsInBlacklist(_parcelNumberPins[i])) {
+ var widgetPin = hereMapController.pinWidget(
+ _createWidget(pin.text, ui.Color.fromARGB(255, 255, 0, 234),
+ isDoublePlannedAddress: pin.isDoublePlannedAddress),
+ _destinationCoords[i]);
+ widgetPin?.anchor = Anchor2D.withHorizontalAndVertical(0.5, 0.5);
+ pin.pin = widgetPin;
+ }
}
// Show the next 5 sections as to not clutter the screen.
diff --git a/lib/config/defaults.dart b/lib/config/defaults.dart
index 2de00ad..f629861 100644
--- a/lib/config/defaults.dart
+++ b/lib/config/defaults.dart
@@ -1,4 +1,4 @@
-String program_version = '0.11 [06/02/2023]';
+String program_version = '0.12 [08/02/2023]';
bool debug_mode = false;
class ShiftType {
diff --git a/lib/main.dart b/lib/main.dart
index a860b91..ca99946 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -7,9 +7,11 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
+import 'package:training_planner/services/iblacklist_provider_service.dart';
import 'package:training_planner/services/iroute_provider_service.dart';
import 'package:training_planner/services/ishift_provider_service.dart';
import 'package:training_planner/services/istoregear_api_service.dart';
+import 'package:training_planner/services/local_blacklist_provider_service.dart';
import 'package:training_planner/services/local_salary_provider_service.dart';
import 'package:training_planner/services/log_service.dart';
import 'package:training_planner/services/messaging_service.dart';
@@ -64,6 +66,8 @@ final MessagingService messageService = MessagingService();
final SettingsService settingsService = SettingsService();
final IStoregearApiService apiService = StoregearApiService();
final LocalSalaryProviderService incomeProvider = LocalSalaryProviderService();
+final IBlacklistProviderService blacklistProvider =
+ LocalBlacklistProviderService();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
diff --git a/lib/pages/all_routes_page.dart b/lib/pages/all_routes_page.dart
index d3c1637..58a580e 100644
--- a/lib/pages/all_routes_page.dart
+++ b/lib/pages/all_routes_page.dart
@@ -27,7 +27,6 @@ class _AllRoutesPageState extends State<AllRoutesPage> {
try {
apiService.getRoutes().then((value) {
- debugPrint('xddd 2');
setState(() => {routeInfo = value});
});
} catch (e) {
@@ -62,7 +61,7 @@ class _AllRoutesPageState extends State<AllRoutesPage> {
padding: const EdgeInsets.only(bottom: 8, left: 10, right: 10),
child: Container(
decoration: BoxDecoration(
- color: Color.fromARGB(40, 0, 0, 0),
+ color: Color.fromARGB(80, 0, 0, 0),
border: Border.all(color: Color.fromARGB(160, 0, 0, 0)),
borderRadius: BorderRadius.all(Radius.circular(4))),
child: Padding(
@@ -71,13 +70,23 @@ class _AllRoutesPageState extends State<AllRoutesPage> {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
- Text(
- 'Route ' + route.tripNumber.toString(),
- textAlign: TextAlign.center,
- style: TextStyle(
- color: Colors.white,
- fontWeight: FontWeight.bold,
- fontSize: 24),
+ Column(
+ children: [
+ Text(
+ 'Route ' + route.tripNumber.toString(),
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ fontSize: 24),
+ ),
+ Text(
+ route.tripPdaStatusDescription ?? '',
+ style: TextStyle(
+ color: Colors.white,
+ fontWeight: FontWeight.w300,
+ fontSize: 16),
+ ),
+ ],
),
Expanded(
child: Padding(
diff --git a/lib/pages/blacklist_page.dart b/lib/pages/blacklist_page.dart
new file mode 100644
index 0000000..2a76d67
--- /dev/null
+++ b/lib/pages/blacklist_page.dart
@@ -0,0 +1,233 @@
+import 'package:flutter/material.dart';
+import 'package:loading_animation_widget/loading_animation_widget.dart';
+import 'package:training_planner/main.dart';
+import 'package:training_planner/services/iblacklist_provider_service.dart';
+import 'package:training_planner/services/settings_service.dart';
+import 'package:training_planner/style/style.dart';
+
+class BlacklistPage extends StatefulWidget {
+ @override
+ _BlacklistPageState createState() => _BlacklistPageState();
+
+ const BlacklistPage({Key? key}) : super(key: key);
+}
+
+class _BlacklistPageState extends State<BlacklistPage> {
+ List<BlacklistEntry>? blacklist;
+
+ final postalCodeNumericController = TextEditingController();
+ final postalCodeAlphaController = TextEditingController();
+ final houseNumberController = TextEditingController();
+ final houseNumberExtraController = TextEditingController();
+
+ @override
+ initState() {
+ super.initState();
+
+ blacklistProvider.getBlacklist().then((value) async {
+ if (mounted) {
+ setState(
+ () {
+ blacklist = value;
+ },
+ );
+ }
+ });
+ }
+
+ Widget getLoadingScreen() {
+ return LoadingAnimationWidget.flickr(
+ leftDotColor: Style.titleColor,
+ rightDotColor: Style.background,
+ size: MediaQuery.of(context).size.width / 4,
+ );
+ }
+
+ List<Widget> createBlacklistWidgets() {
+ List<Widget> result = [];
+
+ for (var entry in blacklist!) {
+ result.add(
+ Padding(
+ padding: const EdgeInsets.only(bottom: 8, left: 10, right: 10),
+ child: Container(
+ decoration: BoxDecoration(
+ border: Border.all(color: Style.logbookEntryBorder),
+ color: Style.logbookEntryBackground,
+ borderRadius: BorderRadius.all(Radius.circular(4))),
+ child: Padding(
+ padding: const EdgeInsets.all(8),
+ child: Row(
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ entry.postalcodeNumeric +
+ ' ' +
+ entry.postalcodeAplha +
+ ' ' +
+ entry.houseNumber.toString() +
+ entry.houseNumberExtra,
+ style: TextStyle(
+ color: Colors.black, fontWeight: FontWeight.bold),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ return result;
+ }
+
+ Widget getDataList() {
+ var monthDataWidgets = createBlacklistWidgets();
+ if (monthDataWidgets.isEmpty) {
+ return Center(
+ child: Text('Geen data beschikbaar'),
+ );
+ }
+
+ return SafeArea(
+ child: CustomScrollView(
+ physics: null,
+ slivers: [
+ SliverPadding(padding: EdgeInsets.only(top: 20)),
+ SliverList(
+ delegate: SliverChildBuilderDelegate(
+ (BuildContext context, int index) {
+ return monthDataWidgets[index];
+ },
+ childCount: monthDataWidgets.length,
+ )),
+ SliverPadding(padding: EdgeInsets.only(top: 20)),
+ ],
+ ),
+ );
+ }
+
+ Widget getLoadingScreenOrDataList() {
+ if (blacklist != null) {
+ return getDataList();
+ } else {
+ return getLoadingScreen();
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('Blacklist'),
+ backgroundColor: Style.background,
+ foregroundColor: Style.titleColor,
+ ),
+ body: ShaderMask(
+ shaderCallback: (Rect rect) {
+ return LinearGradient(
+ begin: Alignment.topCenter,
+ end: Alignment.bottomCenter,
+ colors: [
+ Style.background,
+ Colors.transparent,
+ Colors.transparent,
+ Style.background
+ ],
+ stops: [
+ 0.0,
+ 0.05,
+ 0.95,
+ 1.0
+ ], // 10% purple, 80% transparent, 10% purple
+ ).createShader(rect);
+ },
+ blendMode: BlendMode.dstOut,
+ child: getLoadingScreenOrDataList(),
+ ),
+ floatingActionButton: FloatingActionButton(
+ onPressed: () async {
+ await showAddAddressDialog();
+ //eventBus.fire(RefreshWeekEvent());
+ },
+ backgroundColor: Style.titleColor,
+ child: const Icon(Icons.add),
+ ),
+ );
+ }
+
+ Future<void> addAddressFromDialog() async {
+ await blacklistProvider.addToBlacklist(BlacklistEntry(
+ postalCodeNumericController.text,
+ postalCodeAlphaController.text,
+ int.tryParse(houseNumberController.text) ?? 0,
+ houseNumberExtraController.text));
+ }
+
+ Future<void> showAddAddressDialog() async {
+ // set up the buttons
+ Widget cancelButton = TextButton(
+ child: Text("Terug"),
+ onPressed: () {
+ Navigator.pop(context);
+ },
+ );
+ Widget continueButton = TextButton(
+ child: Text("Ok"),
+ onPressed: () async {
+ await addAddressFromDialog();
+ Navigator.pop(context);
+ },
+ );
+
+ // show the dialog
+ await showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return StatefulBuilder(builder: (context, setState) {
+ return AlertDialog(
+ title: Text("Vul adres in"),
+ content: Column(children: [
+ TextField(
+ controller: postalCodeNumericController,
+ decoration: const InputDecoration(
+ labelText: 'Postcode',
+ ),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: postalCodeAlphaController,
+ decoration: const InputDecoration(
+ labelText: 'Postcode Toevoeging',
+ ),
+ keyboardType: TextInputType.text,
+ ),
+ TextField(
+ controller: houseNumberController,
+ decoration: const InputDecoration(
+ labelText: 'Huisnummer',
+ ),
+ keyboardType: TextInputType.number,
+ ),
+ TextField(
+ controller: houseNumberExtraController,
+ decoration: const InputDecoration(
+ labelText: 'Huisnummer Toegoeging',
+ ),
+ keyboardType: TextInputType.text,
+ ),
+ ]),
+ actions: [
+ cancelButton,
+ continueButton,
+ ],
+ );
+ });
+ },
+ );
+ }
+}
diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart
index b669edb..e53df61 100644
--- a/lib/pages/home_page.dart
+++ b/lib/pages/home_page.dart
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:training_planner/pages/agenda_page.dart';
+import 'package:training_planner/pages/blacklist_page.dart';
import 'package:training_planner/pages/delivery_login_page.dart';
import 'package:training_planner/pages/developer_page.dart';
import 'package:training_planner/pages/logbook_page.dart';
@@ -87,6 +88,15 @@ class _HomePageState extends State<HomePage> {
);
},
),
+ ListTile(
+ title: const Text('Blacklist'),
+ onTap: () {
+ Navigator.push(
+ context,
+ MaterialPageRoute(builder: (context) => BlacklistPage()),
+ );
+ },
+ ),
],
),
);
diff --git a/lib/services/iblacklist_provider_service.dart b/lib/services/iblacklist_provider_service.dart
new file mode 100644
index 0000000..c66a909
--- /dev/null
+++ b/lib/services/iblacklist_provider_service.dart
@@ -0,0 +1,31 @@
+import 'dart:async';
+
+class BlacklistEntry {
+ String postalcodeNumeric;
+ String postalcodeAplha;
+ int houseNumber;
+ String houseNumberExtra;
+
+ BlacklistEntry(this.postalcodeNumeric, this.postalcodeAplha, this.houseNumber,
+ this.houseNumberExtra);
+
+ BlacklistEntry.fromJson(Map<String, dynamic> json)
+ : postalcodeNumeric = json['postalcodeNumeric'],
+ postalcodeAplha = json['postalcodeAplha'],
+ houseNumber = json['houseNumber'],
+ houseNumberExtra = json['houseNumberExtra'];
+
+ Map<String, dynamic> toJson() {
+ return {
+ 'postalcodeNumeric': postalcodeNumeric,
+ 'postalcodeAplha': postalcodeAplha,
+ 'houseNumber': houseNumber,
+ 'houseNumberExtra': houseNumberExtra,
+ };
+ }
+}
+
+abstract class IBlacklistProviderService {
+ Future<List<BlacklistEntry>> getBlacklist();
+ Future<void> addToBlacklist(BlacklistEntry data);
+}
diff --git a/lib/services/local_blacklist_provider_service.dart b/lib/services/local_blacklist_provider_service.dart
new file mode 100644
index 0000000..cb3840e
--- /dev/null
+++ b/lib/services/local_blacklist_provider_service.dart
@@ -0,0 +1,57 @@
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path_provider/path_provider.dart';
+import 'package:training_planner/pages/logbook_page.dart';
+import 'package:training_planner/services/iblacklist_provider_service.dart';
+import 'package:training_planner/services/log_service.dart';
+
+class LocalBlacklistProviderService extends IBlacklistProviderService {
+ Future<Directory> get _localDir async {
+ final directory = await getApplicationDocumentsDirectory();
+ return directory;
+ }
+
+ Future<String> get _localPath async {
+ final directory = await getApplicationDocumentsDirectory();
+ return directory.path;
+ }
+
+ Future<File> _localFile() async {
+ final path = await _localPath;
+ String fullPath = '$path/blacklist.json';
+ File file = File(fullPath);
+
+ bool exists = await file.exists();
+ if (!exists) {
+ LogService.log('creating ' + fullPath);
+ await file.create();
+ await file.writeAsString(jsonEncode([]));
+ }
+
+ return File(fullPath);
+ }
+
+ @override
+ Future<List<BlacklistEntry>> getBlacklist() async {
+ var file = await _localFile();
+ var data = await file.readAsString();
+ final Iterable iterable = await jsonDecode(data);
+ List<BlacklistEntry> parsedData = List<BlacklistEntry>.from(
+ iterable.map((model) => BlacklistEntry.fromJson(model)));
+ LogService.log('read ' + data);
+ return parsedData;
+ }
+
+ @override
+ Future<void> addToBlacklist(BlacklistEntry data) async {
+ var file = await _localFile();
+
+ List<BlacklistEntry> dataToStore = await getBlacklist();
+ dataToStore.add(BlacklistEntry(data.postalcodeNumeric, data.postalcodeAplha,
+ data.houseNumber, data.houseNumberExtra));
+
+ LogService.log('writing ' + jsonEncode(dataToStore));
+ file.writeAsString(jsonEncode(dataToStore));
+ }
+}
diff --git a/lib/services/storegear_api_service.dart b/lib/services/storegear_api_service.dart
index f4d96b1..7b3657f 100644
--- a/lib/services/storegear_api_service.dart
+++ b/lib/services/storegear_api_service.dart
@@ -56,8 +56,6 @@ class StoregearApiService extends IStoregearApiService {
// If the server did return a 200 OK response,
// then parse the JSON.
-
-
var content = jsonDecode(response.body);
if (content["message"] != null) {
return RouteList(routes: []);