Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Phaung Phaung
2021-09-10 14:32:04 +06:30
88 changed files with 851 additions and 854 deletions

View File

@@ -9,7 +9,7 @@ import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/domain/exceiptions/signin_exception.dart'; import 'package:fcs/domain/exceiptions/signin_exception.dart';
import 'package:fcs/helpers/api_helper.dart'; import 'package:fcs/helpers/api_helper.dart';
import 'package:fcs/helpers/firebase_helper.dart'; import 'package:fcs/helpers/firebase_helper.dart';
import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_auth/firebase_auth.dart' as fb;
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
class AuthFb { class AuthFb {
@@ -18,17 +18,17 @@ class AuthFb {
static final AuthFb instance = AuthFb._(); static final AuthFb instance = AuthFb._();
AuthFb._(); AuthFb._();
StreamController<User> controller; late StreamController<User?> controller;
static final FirebaseAuth _fb = FirebaseAuth.instance; static final fb.FirebaseAuth _fb = fb.FirebaseAuth.instance;
static String _verificationId; static String _verificationId = '';
Future<fcs.AuthResult> sendSmsCodeToPhoneNumber(String phoneNumber) { Future<fcs.AuthResult> sendSmsCodeToPhoneNumber(String phoneNumber) {
Completer<fcs.AuthResult> completer = Completer(); Completer<fcs.AuthResult> completer = Completer();
bool codeSentCompleted = false; bool codeSentCompleted = false;
final PhoneVerificationCompleted verificationCompleted = final fb.PhoneVerificationCompleted verificationCompleted =
(AuthCredential credential) async { (fb.AuthCredential credential) async {
AuthResult _authResult; fb.UserCredential _authResult;
try { try {
_authResult = await _fb.signInWithCredential(credential); _authResult = await _fb.signInWithCredential(credential);
print("PhoneVerificationCompleted :$_authResult"); print("PhoneVerificationCompleted :$_authResult");
@@ -48,23 +48,23 @@ class AuthFb {
'Inside _sendCodeToPhoneNumber: signInWithPhoneNumber auto succeeded: ${_authResult.user}'); 'Inside _sendCodeToPhoneNumber: signInWithPhoneNumber auto succeeded: ${_authResult.user}');
}; };
final PhoneVerificationFailed verificationFailed = final fb.PhoneVerificationFailed verificationFailed =
(AuthException authException) async { (fb.FirebaseAuthException authException) async {
print( print(
'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}'); 'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}');
completer.completeError(SigninException( completer.completeError(SigninException(
"Phone number verification failed:${authException.message}")); "Phone number verification failed:${authException.message}"));
}; };
final PhoneCodeSent codeSent = final fb.PhoneCodeSent codeSent =
(String verificationId, [int forceResendingToken]) async { (String verificationId, [int? forceResendingToken]) async {
_verificationId = verificationId; _verificationId = verificationId;
print("codeSent " + phoneNumber); print("codeSent " + phoneNumber);
codeSentCompleted = true; codeSentCompleted = true;
completer.complete(fcs.AuthResult(authStatus: AuthStatus.SMS_SENT)); completer.complete(fcs.AuthResult(authStatus: AuthStatus.SMS_SENT));
}; };
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout = final fb.PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
(String verificationId) { (String verificationId) {
print("codeAutoRetrievalTimeout $verificationId "); print("codeAutoRetrievalTimeout $verificationId ");
@@ -89,11 +89,11 @@ class AuthFb {
Future<fcs.AuthResult> signInWithPhoneNumber(String smsCode) async { Future<fcs.AuthResult> signInWithPhoneNumber(String smsCode) async {
try { try {
final AuthCredential credential = PhoneAuthProvider.getCredential( final fb.AuthCredential credential = fb.PhoneAuthProvider.credential(
verificationId: _verificationId, verificationId: _verificationId, smsCode: smsCode);
smsCode: smsCode,
); fb.UserCredential _authResult =
AuthResult _authResult = await _fb.signInWithCredential(credential); await _fb.signInWithCredential(credential);
if (_authResult == null) { if (_authResult == null) {
throw SigninException("Sigin error!"); throw SigninException("Sigin error!");
} }
@@ -105,19 +105,21 @@ class AuthFb {
} }
Future<void> signout() async { Future<void> signout() async {
if (userListener != null) await userListener.cancel(); if (userListener != null) await userListener!.cancel();
return _fb.signOut(); return _fb.signOut();
} }
Future<void> _addUserToStream({bool refreshIdToken = false}) async { Future<void> _addUserToStream({bool refreshIdToken = false}) async {
FirebaseUser firebaseUser = await _fb.currentUser(); fb.User? firebaseUser = _fb.currentUser;
if (firebaseUser == null) return null; if (firebaseUser == null) return null;
Map claims = await getClaims(refreshIdToken: refreshIdToken); Map<dynamic, dynamic>? claims =
await getClaims(refreshIdToken: refreshIdToken);
log.info("Claims:$claims"); log.info("Claims:$claims");
if (claims == null) return;
String cid = claims["cid"]; String cid = claims["cid"];
User user; User? user;
if (cid != null && cid != "") { if (cid != null && cid != "") {
user = await _getUserFromFirestore(cid); user = await _getUserFromFirestore(cid);
} }
@@ -136,20 +138,20 @@ class AuthFb {
controller.add(user); controller.add(user);
} }
Future<User> _getUserFromFirestore(String userID) async { Future<User?> _getUserFromFirestore(String userID) async {
DocumentSnapshot snap = await Firestore.instance DocumentSnapshot snap = await FirebaseFirestore.instance
.collection(user_collection) .collection(user_collection)
.document(userID) .doc(userID)
.get(); .get();
if (snap.exists) { if (snap.exists) {
User user = User.fromMap(snap.data, snap.documentID); User user = User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
return user; return user;
} }
return null; return null;
} }
Future<bool> isLogin() async { Future<bool> isLogin() async {
final FirebaseUser firebaseUser = await _fb.currentUser(); final fb.User? firebaseUser = _fb.currentUser;
return Future.value(firebaseUser != null); return Future.value(firebaseUser != null);
} }
@@ -193,48 +195,50 @@ class AuthFb {
} }
Stream<Setting> settings() async* { Stream<Setting> settings() async* {
Stream<DocumentSnapshot> snapshot = Firestore.instance Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
.collection(config_collection) .collection(config_collection)
.document(setting_doc_id) .doc(setting_doc_id)
.snapshots(); .snapshots();
await for (var snap in snapshot) { await for (var snap in snapshot) {
Setting setting = Setting.fromMap(snap.data); Setting setting = Setting.fromMap(snap.data() as Map<String, dynamic>);
yield setting; yield setting;
} }
} }
Future<String> _getCurrentUserID() async { Future<String?> _getCurrentUserID() async {
FirebaseUser firebaseUser = await _fb.currentUser(); fb.User? firebaseUser = _fb.currentUser;
if (firebaseUser == null) return null; if (firebaseUser == null) return null;
Map claims = await getClaims(); Map? claims = await getClaims();
if (claims == null) return null;
String cid = claims["cid"]; String cid = claims["cid"];
return cid; return cid;
} }
Future<void> _startUserListener() async { Future<void> _startUserListener() async {
if (userListener != null) userListener.cancel(); if (userListener != null) userListener!.cancel();
String _userID = await _getCurrentUserID(); String? _userID = await _getCurrentUserID();
if (_userID == null) { if (_userID == null) {
return; return;
} }
Stream<DocumentSnapshot> snapshot = Firestore.instance Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
.collection(user_collection) .collection(user_collection)
.document(_userID) .doc(_userID)
.snapshots(); .snapshots();
userListener = snapshot.listen((snap) async { userListener = snapshot.listen((snap) async {
User user = User.fromMap(snap.data, snap.documentID); User user = User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
FirebaseUser firebaseUser = await _fb.currentUser(); fb.User? firebaseUser = _fb.currentUser;
if (firebaseUser == null) { if (firebaseUser == null) {
userListener.cancel(); userListener?.cancel();
return; return;
} }
try { try {
// get privilege from claim // get privilege from claim
IdTokenResult idToken = await firebaseUser.getIdToken(refresh: true); fb.IdTokenResult idToken = await firebaseUser.getIdTokenResult(true);
String privileges = idToken.claims["pr"];
String privileges = idToken.claims?["pr"] ?? '';
if (privileges != null && privileges != "") { if (privileges != null && privileges != "") {
user.privileges = privileges.split(":").toList(); user.privileges = privileges.split(":").toList();
} }
@@ -245,13 +249,13 @@ class AuthFb {
}); });
} }
StreamSubscription<DocumentSnapshot> userListener; StreamSubscription<DocumentSnapshot>? userListener;
Stream<User> user() { Stream<User?> user() {
// ignore: close_sinks // ignore: close_sinks
StreamSubscription<FirebaseUser> authListener; StreamSubscription<fb.User?>? authListener;
Future<void> _start() async { Future<void> _start() async {
authListener = _fb.onAuthStateChanged.listen((firebaseUser) async { authListener = _fb.authStateChanges().listen((firebaseUser) {
if (firebaseUser == null) { if (firebaseUser == null) {
controller.add(null); controller.add(null);
} else { } else {
@@ -263,10 +267,10 @@ class AuthFb {
void _stop() { void _stop() {
if (userListener != null) { if (userListener != null) {
userListener.cancel(); userListener!.cancel();
} }
if (authListener != null) { if (authListener != null) {
authListener.cancel(); authListener!.cancel();
} }
} }

View File

@@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/constants.dart';
@@ -36,7 +35,7 @@ class CartonDataProvider {
} }
Future<List<Carton>> searchCarton(String term) async { Future<List<Carton>> searchCarton(String term) async {
if (term == null || term == '') return List(); if (term == null || term == '') return [];
// var bytes = utf8.encode(term); // var bytes = utf8.encode(term);
// var base64Str = base64.encode(bytes); // var base64Str = base64.encode(bytes);
@@ -45,7 +44,7 @@ class CartonDataProvider {
try { try {
String path = "/$cartons_collection"; String path = "/$cartons_collection";
var querySnap = await Firestore.instance var querySnap = await FirebaseFirestore.instance
.collection(path) .collection(path)
.where("carton_number", isEqualTo: term) .where("carton_number", isEqualTo: term)
.where("carton_type", .where("carton_type",
@@ -53,13 +52,11 @@ class CartonDataProvider {
.where("status", isEqualTo: carton_packed_status) .where("status", isEqualTo: carton_packed_status)
.where("is_deleted", isEqualTo: false) .where("is_deleted", isEqualTo: false)
.orderBy("user_name") .orderBy("user_name")
.getDocuments(); .get();
return querySnap.documents return querySnap.docs.map((e) => Carton.fromMap(e.data(), e.id)).toList();
.map((e) => Carton.fromMap(e.data, e.documentID))
.toList();
} catch (e) { } catch (e) {
log.warning("carton error:" + e.toString()); log.warning("carton error:" + e.toString());
return null; return [];
} }
} }
} }

View File

@@ -56,8 +56,8 @@ class PackageDataProvider {
token: await getToken()); token: await getToken());
} }
Future<List<Package>> ftsSearchPackage(String term) async { Future<List<Package>?> ftsSearchPackage(String term) async {
if (term == null || term == '') return List(); if (term == null || term == '') return [];
var bytes = utf8.encode(term); var bytes = utf8.encode(term);
var base64Str = base64.encode(bytes); var base64Str = base64.encode(bytes);
@@ -72,7 +72,7 @@ class PackageDataProvider {
"/api/fts/$packages_collection/$escapePackage/$limit", "GET", "/api/fts/$packages_collection/$escapePackage/$limit", "GET",
url: Config.instance.reportURL, token: await getToken()); url: Config.instance.reportURL, token: await getToken());
if (data == null) return List(); if (data == null) return [];
data.forEach((p) { data.forEach((p) {
var package = Package.fromJson(p); var package = Package.fromJson(p);
@@ -86,7 +86,7 @@ class PackageDataProvider {
} }
Future<List<Package>> searchPackage(String term) async { Future<List<Package>> searchPackage(String term) async {
if (term == null || term == '') return List(); if (term == null || term == '') return [];
List<Package> packages = []; List<Package> packages = [];

View File

@@ -16,33 +16,33 @@ class RateDataProvider {
static final RateDataProvider instance = RateDataProvider._(); static final RateDataProvider instance = RateDataProvider._();
RateDataProvider._(); RateDataProvider._();
StreamController<Rate> controller; late StreamController<Rate> controller;
static Rate _rate = Rate(); static Rate _rate = Rate();
Stream<Rate> _rateStream() async* { Stream<Rate> _rateStream() async* {
Stream<DocumentSnapshot> snapshot = Firestore.instance Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
.collection(config_collection) .collection(config_collection)
.document(rate_doc_id) .doc(rate_doc_id)
.snapshots(); .snapshots();
await for (var snap in snapshot) { await for (var snap in snapshot) {
Rate rate = Rate.fromMap(snap.data); Rate rate = Rate.fromMap(snap.data() as Map<String, dynamic>);
yield rate; yield rate;
} }
} }
Stream<List<CargoType>> _cargoTypeStream() async* { Stream<List<CargoType>> _cargoTypeStream() async* {
List<CargoType> cargoTypes = []; List<CargoType> cargoTypes = [];
Stream<QuerySnapshot> snapshots = Firestore.instance Stream<QuerySnapshot> snapshots = FirebaseFirestore.instance
.collection(config_collection) .collection(config_collection)
.document(rate_doc_id) .doc(rate_doc_id)
.collection(cargo_types_collection) .collection(cargo_types_collection)
.where("custom_duty", isEqualTo: false) .where("custom_duty", isEqualTo: false)
.snapshots(); .snapshots();
await for (var snaps in snapshots) { await for (var snaps in snapshots) {
cargoTypes = []; cargoTypes = [];
cargoTypes = snaps.documents.map((snap) { cargoTypes = snaps.docs.map((snap) {
return CargoType.fromMap(snap.data, snap.documentID); return CargoType.fromMap(snap.data() as Map<String, dynamic>, snap.id);
}).toList(); }).toList();
yield cargoTypes; yield cargoTypes;
@@ -51,17 +51,17 @@ class RateDataProvider {
Stream<List<CargoType>> _customDutiesStream() async* { Stream<List<CargoType>> _customDutiesStream() async* {
List<CargoType> customDuries = []; List<CargoType> customDuries = [];
Stream<QuerySnapshot> snapshots = Firestore.instance Stream<QuerySnapshot> snapshots = FirebaseFirestore.instance
.collection(config_collection) .collection(config_collection)
.document(rate_doc_id) .doc(rate_doc_id)
.collection(cargo_types_collection) .collection(cargo_types_collection)
.where("custom_duty", isEqualTo: true) .where("custom_duty", isEqualTo: true)
.snapshots(); .snapshots();
await for (var snaps in snapshots) { await for (var snaps in snapshots) {
customDuries = []; customDuries = [];
customDuries = snaps.documents.map((snap) { customDuries = snaps.docs.map((snap) {
return CargoType.fromMap(snap.data, snap.documentID); return CargoType.fromMap(snap.data() as Map<String, dynamic>, snap.id);
}).toList(); }).toList();
yield customDuries; yield customDuries;
} }
@@ -69,25 +69,26 @@ class RateDataProvider {
Stream<List<DiscountByWeight>> _discountByWeightStream() async* { Stream<List<DiscountByWeight>> _discountByWeightStream() async* {
List<DiscountByWeight> discountByWeight = []; List<DiscountByWeight> discountByWeight = [];
Stream<QuerySnapshot> snapshots = Firestore.instance Stream<QuerySnapshot> snapshots = FirebaseFirestore.instance
.collection(config_collection) .collection(config_collection)
.document(rate_doc_id) .doc(rate_doc_id)
.collection(discounts_by_weights_collection) .collection(discounts_by_weights_collection)
.snapshots(); .snapshots();
await for (var snaps in snapshots) { await for (var snaps in snapshots) {
discountByWeight = []; discountByWeight = [];
discountByWeight = snaps.documents.map((snap) { discountByWeight = snaps.docs.map((snap) {
return DiscountByWeight.fromMap(snap.data, snap.documentID); return DiscountByWeight.fromMap(
snap.data() as Map<String, dynamic>, snap.id);
}).toList(); }).toList();
yield discountByWeight; yield discountByWeight;
} }
} }
StreamSubscription<Rate> rateListener; late StreamSubscription<Rate> rateListener;
StreamSubscription<List<CargoType>> cargoListener; late StreamSubscription<List<CargoType>> cargoListener;
StreamSubscription<List<CargoType>> customListener; late StreamSubscription<List<CargoType>> customListener;
StreamSubscription<List<DiscountByWeight>> discountListener; late StreamSubscription<List<DiscountByWeight>> discountListener;
Stream<Rate> rate() { Stream<Rate> rate() {
Future<void> _start() async { Future<void> _start() async {
rateListener = _rateStream().listen((rate) { rateListener = _rateStream().listen((rate) {

View File

@@ -37,23 +37,23 @@ class UserDataProvider {
payload: {"token": token}, token: await getToken()); payload: {"token": token}, token: await getToken());
} }
Future<User> findUser(String phoneNumber) async { Future<User?> findUser(String phoneNumber) async {
QuerySnapshot querySnap = await Firestore.instance QuerySnapshot querySnap = await FirebaseFirestore.instance
.collection(user_collection) .collection(user_collection)
.where("phone_number", isEqualTo: phoneNumber) .where("phone_number", isEqualTo: phoneNumber)
.limit(1) .limit(1)
.getDocuments(); .get();
if (querySnap.documents.length > 0) { if (querySnap.docs.length > 0) {
var snap = querySnap.documents.first; var snap = querySnap.docs.first;
User user = User.fromMap(snap.data, snap.documentID); User user = User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
return user; return user;
} }
return null; return null;
} }
Future<List<User>> searchUser(String term) async { Future<List<User>> searchUser(String term) async {
if (term == null || term == '') return List(); if (term == null || term == '') return [];
var bytes = utf8.encode(term); var bytes = utf8.encode(term);
var base64Str = base64.encode(bytes); var base64Str = base64.encode(bytes);
@@ -68,7 +68,7 @@ class UserDataProvider {
"/api/fts/$user_collection/$escapeBuyer/$limit", "GET", "/api/fts/$user_collection/$escapeBuyer/$limit", "GET",
url: Config.instance.reportURL, token: await getToken()); url: Config.instance.reportURL, token: await getToken());
if (data == null) return List(); if (data == null) return [];
data.forEach((buyer) { data.forEach((buyer) {
var user = User.fromJson(buyer); var user = User.fromJson(buyer);
@@ -76,7 +76,7 @@ class UserDataProvider {
}); });
} catch (e) { } catch (e) {
log.warning("buyer error:" + e.toString()); log.warning("buyer error:" + e.toString());
return null; // return null;
} }
return users; return users;
} }

View File

@@ -3,17 +3,16 @@ import 'package:fcs/domain/entities/auth_result.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/entities/setting.dart'; import 'package:fcs/domain/entities/setting.dart';
import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/domain/entities/user.dart';
import 'package:flutter/material.dart';
import 'auth_service.dart'; import 'auth_service.dart';
class AuthServiceImp implements AuthService { class AuthServiceImp implements AuthService {
AuthServiceImp({ AuthServiceImp({
@required this.authFb, required this.authFb,
@required this.connectivity, required this.connectivity,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final AuthFb authFb; final AuthFb authFb;
@override @override
@@ -32,7 +31,7 @@ class AuthServiceImp implements AuthService {
} }
@override @override
Stream<User> getUserStream() { Stream<User?> getUserStream() {
return authFb.user(); return authFb.user();
} }

View File

@@ -11,6 +11,6 @@ abstract class AuthService {
Future<void> updateProfileName(String newUserName); Future<void> updateProfileName(String newUserName);
Future<void> updatePreferredCurrency(String currency); Future<void> updatePreferredCurrency(String currency);
Future<bool> hasInvite(); Future<bool> hasInvite();
Stream<User> getUserStream(); Stream<User?> getUserStream();
Stream<Setting> getSetting(); Stream<Setting> getSetting();
} }

View File

@@ -1,17 +1,16 @@
import 'package:fcs/data/provider/carton_data_provider.dart'; import 'package:fcs/data/provider/carton_data_provider.dart';
import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:flutter/material.dart';
import 'carton_service.dart'; import 'carton_service.dart';
class CartonServiceImp implements CartonService { class CartonServiceImp implements CartonService {
CartonServiceImp({ CartonServiceImp({
@required this.cartonDataProvider, required this.cartonDataProvider,
@required this.connectivity, required this.connectivity,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final CartonDataProvider cartonDataProvider; final CartonDataProvider cartonDataProvider;
@override @override

View File

@@ -2,13 +2,12 @@ import 'package:fcs/data/provider/common_data_provider.dart';
import 'package:fcs/domain/entities/discount.dart'; import 'package:fcs/domain/entities/discount.dart';
import 'package:fcs/domain/entities/payment_method.dart'; import 'package:fcs/domain/entities/payment_method.dart';
import 'package:fcs/domain/vo/message.dart'; import 'package:fcs/domain/vo/message.dart';
import 'package:flutter/material.dart';
import 'common_service.dart'; import 'common_service.dart';
class CommonServiceImp implements CommonService { class CommonServiceImp implements CommonService {
CommonServiceImp({ CommonServiceImp({
@required this.commonDataProvider, required this.commonDataProvider,
}); });
final CommonDataProvider commonDataProvider; final CommonDataProvider commonDataProvider;

View File

@@ -1,17 +1,16 @@
import 'package:fcs/data/provider/delivery_address_data_provider.dart'; import 'package:fcs/data/provider/delivery_address_data_provider.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/vo/delivery_address.dart'; import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:flutter/material.dart';
import 'delivery_address_service.dart'; import 'delivery_address_service.dart';
class DeliveryAddressImp implements DeliveryAddressService { class DeliveryAddressImp implements DeliveryAddressService {
DeliveryAddressImp({ DeliveryAddressImp({
@required this.connectivity, required this.connectivity,
@required this.deliveryAddressDataProvider, required this.deliveryAddressDataProvider,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final DeliveryAddressDataProvider deliveryAddressDataProvider; final DeliveryAddressDataProvider deliveryAddressDataProvider;
@override @override

View File

@@ -1,17 +1,16 @@
import 'package:fcs/data/provider/fcs_shipment_data_provider.dart'; import 'package:fcs/data/provider/fcs_shipment_data_provider.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/entities/fcs_shipment.dart'; import 'package:fcs/domain/entities/fcs_shipment.dart';
import 'package:flutter/material.dart';
import 'fcs_shipment_service.dart'; import 'fcs_shipment_service.dart';
class FcsShipmentServiceImp implements FcsShipmentService { class FcsShipmentServiceImp implements FcsShipmentService {
FcsShipmentServiceImp({ FcsShipmentServiceImp({
@required this.connectivity, required this.connectivity,
@required this.shipmentDataProvider, required this.shipmentDataProvider,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final FcsShipmentDataProvider shipmentDataProvider; final FcsShipmentDataProvider shipmentDataProvider;
@override @override

View File

@@ -1,21 +1,17 @@
import 'package:fcs/data/provider/invoice_data_provider.dart'; import 'package:fcs/data/provider/invoice_data_provider.dart';
import 'package:fcs/data/provider/shipment_data_provider.dart';
import 'package:fcs/data/services/shipment_service.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/entities/invoice.dart'; import 'package:fcs/domain/entities/invoice.dart';
import 'package:fcs/domain/entities/payment.dart'; import 'package:fcs/domain/entities/payment.dart';
import 'package:fcs/domain/entities/shipment.dart';
import 'package:flutter/material.dart';
import 'invoice_service.dart'; import 'invoice_service.dart';
class InvoiceServiceImp implements InvoiceService { class InvoiceServiceImp implements InvoiceService {
InvoiceServiceImp({ InvoiceServiceImp({
@required this.invoiceDataProvider, required this.invoiceDataProvider,
@required this.connectivity, required this.connectivity,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final InvoiceDataProvider invoiceDataProvider; final InvoiceDataProvider invoiceDataProvider;
@override @override

View File

@@ -1,17 +1,16 @@
import 'package:fcs/data/provider/package_data_provider.dart'; import 'package:fcs/data/provider/package_data_provider.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/domain/entities/package.dart';
import 'package:flutter/material.dart';
import 'package_service.dart'; import 'package_service.dart';
class PackageServiceImp implements PackageService { class PackageServiceImp implements PackageService {
PackageServiceImp({ PackageServiceImp({
@required this.connectivity, required this.connectivity,
@required this.packageDataProvider, required this.packageDataProvider,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final PackageDataProvider packageDataProvider; final PackageDataProvider packageDataProvider;
@override @override
@@ -30,7 +29,7 @@ class PackageServiceImp implements PackageService {
} }
@override @override
Future<List<Package>> ftsSearchPackage(String term) { Future<List<Package>?> ftsSearchPackage(String term) {
return packageDataProvider.ftsSearchPackage(term); return packageDataProvider.ftsSearchPackage(term);
} }

View File

@@ -7,7 +7,7 @@ abstract class PackageService {
Future<void> deleteReceiving(Package package); Future<void> deleteReceiving(Package package);
Future<void> updateProcessing(Package package); Future<void> updateProcessing(Package package);
Future<void> deleteProcessing(Package package); Future<void> deleteProcessing(Package package);
Future<List<Package>> ftsSearchPackage(String term); Future<List<Package>?> ftsSearchPackage(String term);
Future<List<Package>> searchPackage(String term); Future<List<Package>> searchPackage(String term);
Future<void> changeDeliveryAddress(String packageID, String deliveryID); Future<void> changeDeliveryAddress(String packageID, String deliveryID);
Future<void> packageReturn(String packageID); Future<void> packageReturn(String packageID);

View File

@@ -4,17 +4,16 @@ import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/entities/discount_by_weight.dart'; import 'package:fcs/domain/entities/discount_by_weight.dart';
import 'package:fcs/domain/entities/custom_duty.dart'; import 'package:fcs/domain/entities/custom_duty.dart';
import 'package:fcs/domain/entities/rate.dart'; import 'package:fcs/domain/entities/rate.dart';
import 'package:flutter/material.dart';
import 'rate_service.dart'; import 'rate_service.dart';
class RateServiceImp implements RateService { class RateServiceImp implements RateService {
RateServiceImp({ RateServiceImp({
@required this.rateDataProvider, required this.rateDataProvider,
@required this.connectivity, required this.connectivity,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final RateDataProvider rateDataProvider; final RateDataProvider rateDataProvider;
@override @override

View File

@@ -35,17 +35,18 @@ import 'user_service.dart';
class Services { class Services {
static final Services instance = Services._(); static final Services instance = Services._();
AuthService _authService; late AuthService _authService;
UserService _userService; late UserService _userService;
PackageService _packageService; late PackageService _packageService;
MessagingService _messagingService; late MessagingService _messagingService;
CommonService _commonService; late CommonService _commonService;
FcsShipmentService _fcsShipmentService; late FcsShipmentService _fcsShipmentService;
DeliveryAddressService _deliveryAddressService; late DeliveryAddressService _deliveryAddressService;
RateService _rateService; late RateService _rateService;
ShipmentService _shipmentService; late ShipmentService _shipmentService;
CartonService _cartonService; late CartonService _cartonService;
InvoiceService _invoiceService; late InvoiceService _invoiceService;
Services._() { Services._() {
_authService = AuthServiceImp( _authService = AuthServiceImp(
authFb: AuthFb.instance, authFb: AuthFb.instance,

View File

@@ -2,15 +2,14 @@ import 'package:fcs/data/provider/shipment_data_provider.dart';
import 'package:fcs/data/services/shipment_service.dart'; import 'package:fcs/data/services/shipment_service.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/entities/shipment.dart'; import 'package:fcs/domain/entities/shipment.dart';
import 'package:flutter/material.dart';
class ShipmentServiceImp implements ShipmentService { class ShipmentServiceImp implements ShipmentService {
ShipmentServiceImp({ ShipmentServiceImp({
@required this.shipmentDataProvider, required this.shipmentDataProvider,
@required this.connectivity, required this.connectivity,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final ShipmentDataProvider shipmentDataProvider; final ShipmentDataProvider shipmentDataProvider;
@override @override

View File

@@ -1,17 +1,16 @@
import 'package:fcs/data/provider/user_data_provider.dart'; import 'package:fcs/data/provider/user_data_provider.dart';
import 'package:fcs/domain/entities/connectivity.dart'; import 'package:fcs/domain/entities/connectivity.dart';
import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/domain/entities/user.dart';
import 'package:flutter/material.dart';
import 'user_service.dart'; import 'user_service.dart';
class UserServiceImp implements UserService { class UserServiceImp implements UserService {
UserServiceImp({ UserServiceImp({
@required this.connectivity, required this.connectivity,
@required this.userDataProvider, required this.userDataProvider,
}); });
final Connectivity connectivity; final Connectivity? connectivity;
final UserDataProvider userDataProvider; final UserDataProvider userDataProvider;
@override @override
@@ -30,7 +29,7 @@ class UserServiceImp implements UserService {
} }
@override @override
Future<User> findUser(String phoneNumber) { Future<User?> findUser(String phoneNumber) {
return userDataProvider.findUser(phoneNumber); return userDataProvider.findUser(phoneNumber);
} }

View File

@@ -4,7 +4,7 @@ abstract class UserService {
Future<void> inviteUser(String userName, String phoneNumber); Future<void> inviteUser(String userName, String phoneNumber);
Future<void> deleteInvite(String phoneNumber); Future<void> deleteInvite(String phoneNumber);
Future<void> acceptRequest(String userID); Future<void> acceptRequest(String userID);
Future<User> findUser(String phoneNumber); Future<User?> findUser(String phoneNumber);
Future<List<User>> searchUser(String term); Future<List<User>> searchUser(String term);
Future<void> uploadMsgToken(String token); Future<void> uploadMsgToken(String token);
Future<void> removeMsgToken(String token); Future<void> removeMsgToken(String token);

View File

@@ -1,9 +1,9 @@
import 'auth_status.dart'; import 'auth_status.dart';
class AuthResult { class AuthResult {
AuthStatus authStatus; AuthStatus? authStatus;
String authErrorCode; String? authErrorCode;
String authErrorMsg; String? authErrorMsg;
AuthResult({this.authStatus, this.authErrorCode, this.authErrorMsg}); AuthResult({this.authStatus, this.authErrorCode, this.authErrorMsg});
} }

View File

@@ -1,28 +1,28 @@
class CargoType { class CargoType {
String? id; String? id;
String? name; String? name;
double? rate; double rate;
double? weight; double weight;
bool? isChecked; bool isChecked;
int? qty; int qty;
bool? isCutomDuty; bool? isCutomDuty;
double? customDutyFee; double customDutyFee;
double calRate;
double calWeight;
double get calAmount => (calRate ?? 0) * (calWeight ?? 0); double get calAmount => calRate * calWeight;
double? calRate;
double? calWeight;
CargoType( CargoType(
{this.id, {this.id,
this.name, this.name,
this.rate, this.rate = 0,
this.weight, this.weight = 0,
this.calWeight, this.calWeight = 0,
this.calRate, this.calRate = 0,
this.isChecked = false, this.isChecked = false,
this.qty = 0, this.qty = 0,
this.isCutomDuty, this.isCutomDuty,
this.customDutyFee}); this.customDutyFee = 0});
factory CargoType.fromMap(Map<String, dynamic> map, String id) { factory CargoType.fromMap(Map<String, dynamic> map, String id) {
return CargoType( return CargoType(
@@ -63,7 +63,7 @@ class CargoType {
@override @override
String toString() { String toString() {
return name!; return name ?? "";
} }
bool isChangedForEdit(CargoType cargoType) { bool isChangedForEdit(CargoType cargoType) {

View File

@@ -9,61 +9,60 @@ import 'cargo_type.dart';
import 'package.dart'; import 'package.dart';
class Carton { class Carton {
String id; String? id;
String shipmentID; String? shipmentID;
String shipmentNumber; String? shipmentNumber;
String senderID; String? senderID;
String senderFCSID; String? senderFCSID;
String senderName; String? senderName;
String boxNumber; String? boxNumber;
String status; String? status;
String cargoDesc; String? cargoDesc;
String desc; String? desc;
double width; double width;
double height; double height;
double length; double length;
int shipmentWeight; int? shipmentWeight;
bool isChecked; bool? isChecked;
bool isShipmentCarton; bool? isShipmentCarton;
String cartonType; String? cartonType;
String fcsID; String? fcsID;
String userName; String? userName;
String userID; String? userID;
String fcsShipmentID; String? fcsShipmentID;
String fcsShipmentNumber; String? fcsShipmentNumber;
String mixCartonID; String? mixCartonID;
String mixCartonNumber; String? mixCartonNumber;
String cartonSizeID; String? cartonSizeID;
String cartonSizeName; String? cartonSizeName;
double cartonWeight; double? cartonWeight;
int rate; int rate;
int weight; int weight;
String packageType; String? packageType;
String pickUpID; String? pickUpID;
List<String> photos; List<String> photos = [];
String remark; String? remark;
DateTime arrivedDate; DateTime? arrivedDate;
String cartonNumber; String? cartonNumber;
List<String> packageIDs; List<String> packageIDs;
List<Package> packages; List<Package> packages;
List<CargoType> cargoTypes; List<CargoType> cargoTypes = [];
DeliveryAddress deliveryAddress; DeliveryAddress? deliveryAddress;
Shipment shipment; Shipment? shipment;
//for mix box //for mix box
String mixBoxType; String? mixBoxType;
List<Carton> mixCartons; List<Carton> mixCartons;
List<String> mixCartonIDs; List<String> mixCartonIDs;
int get amount => rate != null && weight != null ? rate * weight : 0; int get amount => rate != null && weight != null ? (rate * weight) : 0;
// String get packageNumber => // String get packageNumber =>
// shipmentNumber + "-" + receiverNumber + " #" + boxNumber; // shipmentNumber + "-" + receiverNumber + " #" + boxNumber;
double get price => rate.toDouble() * weight;
double get actualWeight => double get actualWeight =>
cargoTypes == null ? 0 : cargoTypes.fold(0, (p, e) => e.weight + p); cargoTypes == null ? 0 : cargoTypes.fold(0, (p, e) => e.weight + p);
@@ -84,15 +83,15 @@ class Carton {
/// getCargoTypeForCalWeight returns carton with shipment weight /// getCargoTypeForCalWeight returns carton with shipment weight
List<CargoType> getCargoTypeForCalWeight(double volumetricRatio) { List<CargoType> getCargoTypeForCalWeight(double volumetricRatio) {
// get shipment weight // get shipment weight
double volume = (length ?? 0) * (width ?? 0) * (height ?? 0); double volume = length * width * height;
double sw = volume / volumetricRatio ?? 0; double sw = volume / volumetricRatio;
// get actual weight // get actual weight
double aw = cargoTypes.fold(0.0, (p, c) => p + c.weight); double aw = cargoTypes.fold(0.0, (p, c) => p + c.weight);
if (aw == 0 || sw == 0) return []; if (aw == 0 || sw == 0) return [];
cargoTypes.forEach((e) { cargoTypes.forEach((e) {
double calWeight = aw > sw ? e.weight : e.weight / aw * sw; double calWeight = aw > sw ? e.weight : (e.weight / aw) * sw;
e.calWeight = calWeight; e.calWeight = calWeight;
}); });
return cargoTypes; return cargoTypes;
@@ -116,7 +115,7 @@ class Carton {
double total = 0; double total = 0;
cargoTypes.forEach((e) { cargoTypes.forEach((e) {
double r = double r =
e.rate - (discountByWeight != null ? discountByWeight.discount : 0); e.rate - (discountByWeight != null ? (discountByWeight.discount) : 0);
double amount = e.weight * r; double amount = e.weight * r;
total += amount; total += amount;
}); });
@@ -134,9 +133,9 @@ class Carton {
this.senderName, this.senderName,
this.boxNumber, this.boxNumber,
this.desc, this.desc,
this.width, this.width = 0,
this.height, this.height = 0,
this.length, this.length = 0,
this.shipmentWeight, this.shipmentWeight,
this.isChecked = false, this.isChecked = false,
this.cartonType, this.cartonType,
@@ -151,13 +150,13 @@ class Carton {
this.status, this.status,
this.arrivedDate, this.arrivedDate,
this.cargoDesc, this.cargoDesc,
this.shipmentHistory, this.shipmentHistory = const [],
this.packages, this.packages = const [],
this.cargoTypes, this.cargoTypes = const [],
this.cartonNumber, this.cartonNumber,
this.fcsShipmentID, this.fcsShipmentID,
this.fcsShipmentNumber, this.fcsShipmentNumber,
this.packageIDs, this.packageIDs = const [],
this.mixCartonID, this.mixCartonID,
this.mixCartonNumber, this.mixCartonNumber,
this.isShipmentCarton = false, this.isShipmentCarton = false,
@@ -165,14 +164,14 @@ class Carton {
this.cartonSizeID, this.cartonSizeID,
this.cartonSizeName, this.cartonSizeName,
this.mixBoxType, this.mixBoxType,
this.mixCartons, this.mixCartons = const [],
this.mixCartonIDs, this.mixCartonIDs = const [],
this.cartonWeight}); this.cartonWeight});
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
List _cargoTypes = cargoTypes?.map((c) => c.toMap())?.toList() ?? []; List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
List _packages = packages?.map((c) => c.toJson())?.toList(); List _packages = packages.map((c) => c.toJson()).toList();
List _mixCartons = mixCartons?.map((c) => c.toJson())?.toList(); List _mixCartons = mixCartons.map((c) => c.toJson()).toList();
return { return {
'id': id, 'id': id,
'fcs_shipment_id': fcsShipmentID, 'fcs_shipment_id': fcsShipmentID,
@@ -213,9 +212,9 @@ class Carton {
shipmentNumber: map['shipment_number'], shipmentNumber: map['shipment_number'],
// receiverNumber: map['receiver_number'], // receiverNumber: map['receiver_number'],
boxNumber: map['box_number'], boxNumber: map['box_number'],
length: double.tryParse(map['length']?.toString()), length: double.tryParse(map['length'].toString()) ?? 0,
width: double.tryParse(map['width']?.toString()), width: double.tryParse(map['width'].toString()) ?? 0,
height: double.tryParse(map['height']?.toString()), height: double.tryParse(map['height'].toString()) ?? 0,
userName: map['user_name'], userName: map['user_name'],
fcsID: map['fcs_id'], fcsID: map['fcs_id'],
cartonType: map['carton_type'], cartonType: map['carton_type'],
@@ -242,8 +241,8 @@ class Carton {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList(); List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
List _packages = packages?.map((c) => c.toJson())?.toList(); List _packages = packages.map((c) => c.toJson()).toList();
List _mixCartons = mixCartons?.map((c) => c.toJson())?.toList(); List _mixCartons = mixCartons.map((c) => c.toJson()).toList();
return { return {
'id': id, 'id': id,
'fcs_shipment_id': fcsShipmentID, 'fcs_shipment_id': fcsShipmentID,

View File

@@ -1,10 +1,11 @@
class CartonSize { class CartonSize {
String id; String? id;
String name; String? name;
double length; double length;
double width; double width;
double height; double height;
CartonSize({this.id, this.name, this.length, this.width, this.height}); CartonSize(
{this.id, this.name, this.length = 0, this.width = 0, this.height = 0});
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
@@ -27,19 +28,10 @@ class CartonSize {
} }
@override @override
bool operator ==(other) { bool operator ==(Object other) => other is CartonSize && other.id == id;
if (identical(this, other)) {
return true;
}
return other.id == this.id;
}
@override @override
int get hashCode { int get hashCode => id.hashCode;
int result = 17;
result = 37 * result + id.hashCode;
return result;
}
bool isChangedForEdit(CartonSize cartonSize) { bool isChangedForEdit(CartonSize cartonSize) {
return cartonSize.name != this.name || return cartonSize.name != this.name ||

View File

@@ -1,11 +1,15 @@
class CustomDuty { class CustomDuty {
String id; String? id;
String productType; String? productType;
String desc; String? desc;
double fee; double fee;
double shipmentRate; double shipmentRate;
CustomDuty( CustomDuty(
{this.id, this.productType, this.desc, this.fee, this.shipmentRate}); {this.id,
this.productType,
this.desc,
this.fee = 0,
this.shipmentRate = 0});
factory CustomDuty.fromMap(Map<String, dynamic> map, String id) { factory CustomDuty.fromMap(Map<String, dynamic> map, String id) {
return CustomDuty( return CustomDuty(

View File

@@ -1,10 +1,8 @@
class Customer { class Customer {
String id; String? id;
String name; String? name;
String phoneNumber; String? phoneNumber;
String status; String? status;
Customer({ Customer({
this.id, this.id,

View File

@@ -1,9 +1,9 @@
class Discount { class Discount {
String id; String? id;
String code; String? code;
String customerId; String? customerId;
String customerName; String? customerName;
String status; String? status;
double amount; double amount;
Discount({ Discount({
@@ -11,7 +11,7 @@ class Discount {
this.code, this.code,
this.customerId, this.customerId,
this.customerName, this.customerName,
this.amount, this.amount = 0,
this.status, this.status,
}); });

View File

@@ -1,9 +1,9 @@
class DiscountByWeight { class DiscountByWeight {
String id; String? id;
double weight; double weight;
double discount; double discount;
DiscountByWeight({this.id, this.weight, this.discount}); DiscountByWeight({this.id, this.weight = 0, this.discount = 0});
factory DiscountByWeight.fromMap(Map<String, dynamic> map, String id) { factory DiscountByWeight.fromMap(Map<String, dynamic> map, String id) {
return DiscountByWeight( return DiscountByWeight(

View File

@@ -1,16 +1,17 @@
class FAQ { class FAQ {
String id; String? id;
int sn; int? sn;
String questionEng; String? questionEng;
String questionMm; String? questionMm;
String answerEng; String? answerEng;
String answerMm; String? answerMm;
String pageLinkLabelEng; String? pageLinkLabelEng;
String pageLinkLabelMm; String? pageLinkLabelMm;
String pageLink; String? pageLink;
String question(bool isEng) => isEng ? questionEng : questionMm; String question(bool isEng) =>
String answer(bool isEng) => isEng ? answerEng : answerMm; isEng ? (questionEng ?? "") : (questionMm ?? "");
String answer(bool isEng) => isEng ? (answerEng ?? "") : (answerMm ?? "");
FAQ( FAQ(
{this.id, {this.id,

View File

@@ -3,17 +3,18 @@ import 'package:cloud_firestore/cloud_firestore.dart';
import '../constants.dart'; import '../constants.dart';
class FcsShipment { class FcsShipment {
String id; String? id;
String shipmentNumber; String? shipmentNumber;
DateTime cutoffDate; DateTime? cutoffDate;
String shipType; String? shipType;
DateTime arrivalDate; DateTime? arrivalDate;
DateTime departureDate; DateTime? departureDate;
String consignee; String? consignee;
String port; String? port;
String destination; String? destination;
String status; String? status;
String reportName; String? reportName;
FcsShipment({ FcsShipment({
this.id, this.id,
this.shipmentNumber, this.shipmentNumber,
@@ -51,10 +52,10 @@ class FcsShipment {
return { return {
"id": id, "id": id,
'shipment_number': shipmentNumber, 'shipment_number': shipmentNumber,
'cutoff_date': cutoffDate?.toUtc()?.toIso8601String(), 'cutoff_date': cutoffDate?.toUtc().toIso8601String(),
'shipment_type': shipType, 'shipment_type': shipType,
'arrival_date': arrivalDate?.toUtc()?.toIso8601String(), 'arrival_date': arrivalDate?.toUtc().toIso8601String(),
'departure_date': departureDate?.toUtc()?.toIso8601String(), 'departure_date': departureDate?.toUtc().toIso8601String(),
'consignee': consignee, 'consignee': consignee,
'port': port, 'port': port,
'destination': destination, 'destination': destination,

View File

@@ -10,15 +10,15 @@ import 'package:fcs/domain/entities/rate.dart';
import 'package:fcs/domain/entities/shipment.dart'; import 'package:fcs/domain/entities/shipment.dart';
class Invoice { class Invoice {
String id; String? id;
String invoiceNumber; String? invoiceNumber;
DateTime invoiceDate; DateTime? invoiceDate;
String fcsShipmentID; String? fcsShipmentID;
String userID; String? userID;
String fcsID; String? fcsID;
String userName; String? userName;
String phoneNumber; String? phoneNumber;
String status; String? status;
double handlingFee; double handlingFee;
double deliveryFee; double deliveryFee;
@@ -30,9 +30,9 @@ class Invoice {
List<CargoType> cargoTypes; List<CargoType> cargoTypes;
List<Shipment> shipments; List<Shipment> shipments;
List<Payment> payments; List<Payment> payments;
Discount discount; Discount? discount;
PaymentMethod paymentMethod; PaymentMethod? paymentMethod;
String invoiceURL; String? invoiceURL;
List<CargoType> getCargoTypes(Rate rate) { List<CargoType> getCargoTypes(Rate rate) {
if (cargoTypes != null) return cargoTypes; if (cargoTypes != null) return cargoTypes;
@@ -40,7 +40,7 @@ class Invoice {
List<CargoType> _cargoTypes = []; List<CargoType> _cargoTypes = [];
double totalCalWeight = 0; double totalCalWeight = 0;
cartons.forEach((carton) { cartons.forEach((carton) {
if (carton.isChecked) { if (carton.isChecked ?? false) {
var _cartonsTypes = var _cartonsTypes =
carton.getCargoTypeForCalWeight(rate.volumetricRatio); carton.getCargoTypeForCalWeight(rate.volumetricRatio);
_cartonsTypes.forEach((ct) { _cartonsTypes.forEach((ct) {
@@ -68,15 +68,15 @@ class Invoice {
double getTotal(Rate rate) { double getTotal(Rate rate) {
List<CargoType> cargoTypes = getCargoTypes(rate); List<CargoType> cargoTypes = getCargoTypes(rate);
var total = cargoTypes.fold(0.0, (p, c) => c.calAmount + p); double total = cargoTypes.fold(0.0, (p, c) => c.calAmount + p);
return total; return total;
} }
double get balance => (amount ?? 0) - (paidAmount ?? 0); double get balance => amount - paidAmount;
double getNetAmount(Rate rate) { double getNetAmount(Rate rate) {
List<CargoType> cargoTypes = getCargoTypes(rate); List<CargoType> cargoTypes = getCargoTypes(rate);
var total = cargoTypes.fold(0.0, (p, c) => c.calAmount + p); double total = cargoTypes.fold(0.0, (p, c) => c.calAmount + p);
total += getCustomFee(); total += getCustomFee();
total += getDeliveryFee(); total += getDeliveryFee();
total += getHandlingFee(); total += getHandlingFee();
@@ -85,13 +85,13 @@ class Invoice {
} }
double getHandlingFee() { double getHandlingFee() {
return shipments?.where((sh) => sh.isSelected ?? false)?.fold(0, (p, s) { return shipments
return p + (s?.handlingFee ?? 0) - (s?.paidHandlingFee ?? 0); .where((sh) => sh.isSelected)
}); .fold(0, (p, s) => p + (s.handlingFee - s.paidHandlingFee));
} }
double getTotalBalance(Rate rate) { double getTotalBalance(Rate rate) {
return getNetAmount(rate) - (paidAmount ?? 0); return getNetAmount(rate) - paidAmount;
} }
double getCustomFee() { double getCustomFee() {
@@ -102,7 +102,7 @@ class Invoice {
return deliveryFee == null ? 0 : deliveryFee; return deliveryFee == null ? 0 : deliveryFee;
} }
double getDiscount() => discount == null ? 0 : discount.amount; double getDiscount() => discount == null ? 0 : discount!.amount;
Invoice( Invoice(
{this.id, {this.id,
@@ -111,19 +111,19 @@ class Invoice {
this.fcsID, this.fcsID,
this.userName, this.userName,
this.phoneNumber, this.phoneNumber,
this.amount, this.amount = 0,
this.paidAmount, this.paidAmount = 0,
this.discount, this.discount,
this.status, this.status,
this.customDuties, this.customDuties = const [],
this.cartons, this.cartons = const [],
this.cargoTypes, this.cargoTypes = const [],
this.handlingFee, this.handlingFee = 0,
this.deliveryFee, this.deliveryFee = 0,
this.fcsShipmentID, this.fcsShipmentID,
this.shipments, this.shipments = const [],
this.invoiceURL, this.invoiceURL,
this.payments, this.payments = const [],
this.paymentMethod}); this.paymentMethod});
factory Invoice.fromMap(Map<String, dynamic> map, String docID) { factory Invoice.fromMap(Map<String, dynamic> map, String docID) {
@@ -153,7 +153,7 @@ class Invoice {
return Invoice( return Invoice(
id: docID, id: docID,
invoiceNumber: map['invoice_number'], invoiceNumber: map['invoice_number'],
invoiceDate: invd?.toDate(), invoiceDate: invd.toDate(),
userName: map['user_name'], userName: map['user_name'],
fcsID: map['fcs_id'], fcsID: map['fcs_id'],
phoneNumber: map['phone_number'], phoneNumber: map['phone_number'],
@@ -174,12 +174,12 @@ class Invoice {
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList(); List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
List _customDuties = customDuties?.map((c) => c.toMap())?.toList(); List _customDuties = customDuties.map((c) => c.toMap()).toList();
List _cartons = cartons?.map((c) => c.toMap())?.toList() ?? []; List _cartons = cartons.map((c) => c.toMap()).toList();
List _shipments = shipments?.map((s) => s.toMap())?.toList() ?? []; List _shipments = shipments.map((s) => s.toMap()).toList();
return { return {
"id": id, "id": id,
"invoice_date": invoiceDate?.toUtc()?.toIso8601String(), "invoice_date": invoiceDate?.toUtc().toIso8601String(),
"user_id": userID, "user_id": userID,
"user_name": userName, "user_name": userName,
"invoice_number": invoiceNumber, "invoice_number": invoiceNumber,

View File

@@ -1,11 +1,8 @@
class Market { class Market {
String id; String? id;
String name; String? name;
Market({ Market({this.id, this.name});
this.id,
this.name,
});
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {

View File

@@ -5,35 +5,35 @@ import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:fcs/domain/vo/shipment_status.dart'; import 'package:fcs/domain/vo/shipment_status.dart';
class Package { class Package {
String id; String? id;
String trackingID; String? trackingID;
String userID; String? userID;
String fcsID; String? fcsID;
String userName; String? userName;
String phoneNumber; String? phoneNumber;
DateTime currentStatusDate; DateTime? currentStatusDate;
List<String> photoUrls; List<String> photoUrls;
List<ShipmentStatus> shipmentHistory; List<ShipmentStatus> shipmentHistory;
String desc; String? desc;
String status; String? status;
String shipmentNumber; String? shipmentNumber;
String senderFCSID; String? senderFCSID;
String senderName; String? senderName;
String senderPhoneNumber; String? senderPhoneNumber;
String boxNumber; String? boxNumber;
String cargoDesc; String? cargoDesc;
String market; String? market;
bool isChecked; bool isChecked;
int rate; int rate;
int weight; int weight;
String packageType; String? packageType;
String pickUpID; String? pickUpID;
List<String> photos; // List<String> photos;
String remark; String? remark;
DateTime arrivedDate; DateTime? arrivedDate;
DeliveryAddress deliveryAddress; DeliveryAddress? deliveryAddress;
//for packages in processing //for packages in processing
List<File> photoFiles; List<File> photoFiles;
@@ -42,8 +42,8 @@ class Package {
double get price => rate.toDouble() * weight; double get price => rate.toDouble() * weight;
Package({ Package(
this.id, {this.id,
this.trackingID, this.trackingID,
this.userID, this.userID,
this.userName, this.userName,
@@ -53,8 +53,8 @@ class Package {
this.senderFCSID, this.senderFCSID,
this.senderName, this.senderName,
this.boxNumber, this.boxNumber,
this.rate, this.rate = 0,
this.weight, this.weight = 0,
this.packageType, this.packageType,
this.pickUpID, this.pickUpID,
this.remark, this.remark,
@@ -62,15 +62,14 @@ class Package {
this.arrivedDate, this.arrivedDate,
this.cargoDesc, this.cargoDesc,
this.market, this.market,
this.shipmentHistory, this.shipmentHistory = const [],
this.currentStatusDate, this.currentStatusDate,
this.photoUrls, this.photoUrls = const [],
this.desc, this.desc,
this.deliveryAddress, this.deliveryAddress,
this.isChecked = false, this.isChecked = false,
this.photoFiles, this.photoFiles = const [],
this.senderPhoneNumber this.senderPhoneNumber});
});
factory Package.fromMap(Map<String, dynamic> map, String docID) { factory Package.fromMap(Map<String, dynamic> map, String docID) {
var _currentStatusDate = (map['status_date'] as Timestamp); var _currentStatusDate = (map['status_date'] as Timestamp);
@@ -98,9 +97,7 @@ class Package {
senderName: map['sender_name'], senderName: map['sender_name'],
senderPhoneNumber: map['sender_phone_number'], senderPhoneNumber: map['sender_phone_number'],
deliveryAddress: _da, deliveryAddress: _da,
currentStatusDate: _currentStatusDate != null currentStatusDate: _currentStatusDate.toDate().toLocal(),
? _currentStatusDate.toDate().toLocal()
: null,
photoUrls: _photoUrls, photoUrls: _photoUrls,
shipmentHistory: _shipmentStatus); shipmentHistory: _shipmentStatus);
} }

View File

@@ -1,11 +1,11 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
class Payment { class Payment {
String id; String? id;
String invoiceID; String? invoiceID;
DateTime paymentDate; DateTime? paymentDate;
String paymentReceiptURL; String? paymentReceiptURL;
String status; String? status;
double amount; double amount;
Payment( Payment(
@@ -14,13 +14,13 @@ class Payment {
this.paymentDate, this.paymentDate,
this.paymentReceiptURL, this.paymentReceiptURL,
this.status, this.status,
this.amount}); this.amount = 0});
factory Payment.fromMap(Map<String, dynamic> map, String id) { factory Payment.fromMap(Map<String, dynamic> map, String id) {
var _paymentDate = (map['payment_date'] as Timestamp); var _paymentDate = (map['payment_date'] as Timestamp);
return Payment( return Payment(
id: id, id: id,
paymentDate: _paymentDate?.toDate(), paymentDate: _paymentDate.toDate(),
paymentReceiptURL: map['payment_receipt_url'], paymentReceiptURL: map['payment_receipt_url'],
status: map['status'], status: map['status'],
amount: map['amount']?.toDouble() ?? 0, amount: map['amount']?.toDouble() ?? 0,
@@ -31,7 +31,7 @@ class Payment {
return { return {
"id": id, "id": id,
"invoice_id": invoiceID, "invoice_id": invoiceID,
'payment_date': paymentDate?.toUtc()?.toIso8601String(), 'payment_date': paymentDate?.toUtc().toIso8601String(),
'payment_receipt_url': paymentReceiptURL, 'payment_receipt_url': paymentReceiptURL,
'status': status, 'status': status,
'amount': amount, 'amount': amount,
@@ -39,7 +39,7 @@ class Payment {
} }
Payment clone() { Payment clone() {
return Payment.fromMap(toMap(), this.id); return Payment.fromMap(toMap(), this.id!);
} }
@override @override

View File

@@ -1,11 +1,11 @@
class PaymentMethod { class PaymentMethod {
String id; String? id;
String name; String? name;
String accountName; String? accountName;
String account; String? account;
String phone; String? phone;
String email; String? email;
String link; String? link;
PaymentMethod( PaymentMethod(
{this.id, {this.id,

View File

@@ -1,15 +1,15 @@
import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/domain/entities/package.dart';
class Processing { class Processing {
String id; String? id;
//for consignee //for consignee
String userID; String? userID;
String userName; String? userName;
String userPhoneNumber; String? userPhoneNumber;
//for shipper //for shipper
String fcsID; String? fcsID;
String shipperName; String? shipperName;
String shipperPhoneNumber; String? shipperPhoneNumber;
List<Package> packages; List<Package> packages;
@@ -21,7 +21,7 @@ class Processing {
this.fcsID, this.fcsID,
this.shipperName, this.shipperName,
this.shipperPhoneNumber, this.shipperPhoneNumber,
this.packages}); this.packages = const []});
@override @override
bool operator ==(Object other) => other is Processing && other.id == id; bool operator ==(Object other) => other is Processing && other.id == id;

View File

@@ -1,4 +1,3 @@
import 'package:fcs/domain/entities/discount_by_weight.dart'; import 'package:fcs/domain/entities/discount_by_weight.dart';
import 'cargo_type.dart'; import 'cargo_type.dart';
@@ -11,26 +10,25 @@ class Rate {
double diffDiscountWeight; double diffDiscountWeight;
double diffWeightRate; double diffWeightRate;
List<CargoType> cargoTypes; List<CargoType> cargoTypes = [];
List<CargoType> customDuties; List<CargoType> customDuties = [];
List<DiscountByWeight> discountByWeights; List<DiscountByWeight> discountByWeights = [];
DiscountByWeight getDiscountByWeight(double weight) { DiscountByWeight getDiscountByWeight(double weight) {
discountByWeights.sort((d1, d2) => d2.weight.compareTo(d1.weight)); discountByWeights.sort((d1, d2) => d2.weight.compareTo(d1.weight));
return discountByWeights.firstWhere((e) => e.weight < weight, return discountByWeights.firstWhere((e) => e.weight < weight);
orElse: () => null);
} }
CargoType get defaultCargoType => cargoTypes == null CargoType? get defaultCargoType => cargoTypes == null
? null ? null
: cargoTypes.firstWhere((e) => e.name == "General"); : cargoTypes.firstWhere((e) => e.name == "General");
Rate( Rate(
{this.deliveryFee, {this.deliveryFee = 0,
this.freeDeliveryWeight, this.freeDeliveryWeight = 0,
this.volumetricRatio, this.volumetricRatio = 0,
this.diffDiscountWeight, this.diffDiscountWeight = 0,
this.diffWeightRate}); this.diffWeightRate = 0});
factory Rate.fromMap(Map<String, dynamic> map) { factory Rate.fromMap(Map<String, dynamic> map) {
return Rate( return Rate(

View File

@@ -1,9 +1,9 @@
class Receipt { class Receipt {
String id; String? id;
int amount; int? amount = 0;
String date; String? date;
String status; String? status;
String fileUrl; String? fileUrl;
Receipt({this.id, this.amount, this.date, this.status, this.fileUrl}); Receipt({this.id, this.amount, this.date, this.status, this.fileUrl});
} }

View File

@@ -9,21 +9,20 @@ List<Day> dayLists = [
]; ];
class Setting { class Setting {
final int supportBuildNum; final int? supportBuildNum;
// contact page // contact page
String usaAddress; String? usaAddress;
String mmAddress; String? mmAddress;
String usaContactNumber; String? usaContactNumber;
String mmContactNumber; String? mmContactNumber;
String emailAddress; String? emailAddress;
String facebookLink; String? facebookLink;
bool inviteRequired; bool? inviteRequired;
String appUrl; String? appUrl;
final String termsEng; final String? termsEng;
final String termsMm; final String? termsMm;
String about; String? about;
String courierWebsite; String? courierWebsite;
List<String> shipmentTypes; List<String> shipmentTypes;
@@ -40,7 +39,7 @@ class Setting {
this.termsEng, this.termsEng,
this.termsMm, this.termsMm,
this.about, this.about,
this.shipmentTypes, this.shipmentTypes = const [],
this.courierWebsite}); this.courierWebsite});
factory Setting.fromMap(Map<String, dynamic> map) { factory Setting.fromMap(Map<String, dynamic> map) {
@@ -76,9 +75,9 @@ class Setting {
} }
class Day { class Day {
int id; int? id;
String name; String? name;
bool isChecked = false; bool? isChecked = false;
Day({this.id, this.name, this.isChecked}); Day({this.id, this.name, this.isChecked});
@override @override

View File

@@ -4,35 +4,35 @@ import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/domain/vo/delivery_address.dart'; import 'package:fcs/domain/vo/delivery_address.dart';
class Shipment { class Shipment {
String id; String? id;
String shipmentNumber; String? shipmentNumber;
String shipmentType; String? shipmentType;
DeliveryAddress pickupAddress; DeliveryAddress? pickupAddress;
DateTime pickupDate; DateTime? pickupDate;
String pickupTimeStart; String? pickupTimeStart;
String pickupTimeEnd; String? pickupTimeEnd;
String userName; String? userName;
String userID; String? userID;
String phoneNumber; String? phoneNumber;
int numberOfPackage; int numberOfPackage = 0;
int weight; int weight = 0;
double handlingFee; double handlingFee = 0;
double paidHandlingFee; double paidHandlingFee = 0;
String address; String? address;
String status; String? status;
bool isCourier; bool isCourier;
int radioIndex; int radioIndex;
List<Carton> boxes; List<Carton> boxes;
String pickupUserID; String? pickupUserID;
String pickupUserName; String? pickupUserName;
String pickupUserPhoneNumber; String? pickupUserPhoneNumber;
String fcsShipmentID; String? fcsShipmentID;
String fcsShipmentNumber; String? fcsShipmentNumber;
String shipmentLabelUrl; String? shipmentLabelUrl;
bool isSelected; bool isSelected = false;
Shipment( Shipment(
{this.id, {this.id,
@@ -43,28 +43,28 @@ class Shipment {
this.phoneNumber, this.phoneNumber,
this.pickupTimeStart, this.pickupTimeStart,
this.pickupTimeEnd, this.pickupTimeEnd,
this.numberOfPackage, this.numberOfPackage = 0,
this.weight, this.weight = 0,
this.handlingFee, this.handlingFee = 0,
this.paidHandlingFee, this.paidHandlingFee = 0,
this.address, this.address,
this.status, this.status,
this.pickupDate, this.pickupDate,
this.isCourier = false, this.isCourier = false,
this.radioIndex = 1, this.radioIndex = 1,
this.pickupAddress, required this.pickupAddress,
this.pickupUserID, this.pickupUserID,
this.pickupUserName, this.pickupUserName,
this.pickupUserPhoneNumber, this.pickupUserPhoneNumber,
this.fcsShipmentID, this.fcsShipmentID,
this.fcsShipmentNumber, this.fcsShipmentNumber,
this.shipmentLabelUrl, this.shipmentLabelUrl,
this.boxes}); this.boxes = const []});
int get last => DateTime.now().difference(pickupDate).inDays; // int get last => DateTime.now().difference(pickupDate).inDays;
double get totalWeight => boxes?.fold(0, (p, e) => p + e.actualWeight); double get totalWeight => boxes.fold(0, (p, e) => p + e.actualWeight);
int get totalCount => boxes?.length; int get totalCount => boxes.length;
bool get isPending => status == shipment_pending_status; bool get isPending => status == shipment_pending_status;
bool get isAssigned => status == shipment_assigned_status; bool get isAssigned => status == shipment_assigned_status;
@@ -100,15 +100,15 @@ class Shipment {
} }
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
List _boxes = boxes?.map((l) => l.toMap())?.toList() ?? []; List _boxes = boxes.map((l) => l.toMap()).toList();
return { return {
"id": id, "id": id,
'user_id': userID, 'user_id': userID,
'cartons': _boxes, 'cartons': _boxes,
'shipment_type': shipmentType, 'shipment_type': shipmentType,
'pickup_address': pickupAddress.toMap(), 'pickup_address': pickupAddress?.toMap(),
"pickup_date": pickupDate?.toUtc()?.toIso8601String(), "pickup_date": pickupDate?.toUtc().toIso8601String(),
'pickup_time_start': pickupTimeStart, 'pickup_time_start': pickupTimeStart,
'pickup_time_end': pickupTimeEnd, 'pickup_time_end': pickupTimeEnd,
'pickup_user_id': pickupUserID, 'pickup_user_id': pickupUserID,

View File

@@ -9,18 +9,19 @@ DateFormat timeFormat = DateFormat("HH:mm");
final DateFormat dateFormat = DateFormat("d MMM yyyy"); final DateFormat dateFormat = DateFormat("d MMM yyyy");
class User { class User {
String id; String? id;
String name; String? name;
String phoneNumber; String? phoneNumber;
String status; String? status;
String fcsID; String? fcsID;
DateTime lastMessageTime; DateTime? lastMessageTime;
String lastMessage; String? lastMessage;
int userUnseenCount; int? userUnseenCount;
int fcsUnseenCount; int? fcsUnseenCount;
String preferCurrency; String? preferCurrency;
String get initial => name != null && name != "" ? name.substring(0, 1) : "?"; String get initial =>
name != null && name != "" ? name!.substring(0, 1) : "?";
String get getLastMessage { String get getLastMessage {
var msg = lastMessage ?? "Say hi to $name"; var msg = lastMessage ?? "Say hi to $name";
@@ -31,27 +32,31 @@ class User {
String get getLastMessageTime { String get getLastMessageTime {
if (lastMessageTime == null) return ""; if (lastMessageTime == null) return "";
DateTime today = DateTime.now(); DateTime today = DateTime.now();
if (lastMessageTime.year == today.year && if (lastMessageTime!.year == today.year &&
lastMessageTime.month == today.month && lastMessageTime!.month == today.month &&
lastMessageTime.day == today.day) { lastMessageTime!.day == today.day) {
return timeFormat.format(lastMessageTime); return timeFormat.format(lastMessageTime!);
} else { } else {
return dateFormat.format(lastMessageTime); return dateFormat.format(lastMessageTime!);
} }
} }
String get getUserUnseenCount => userUnseenCount != null String get getUserUnseenCount => userUnseenCount != null
? userUnseenCount > 100 ? "99+" : userUnseenCount.toString() ? userUnseenCount! > 100
? "99+"
: userUnseenCount.toString()
: "0"; : "0";
String get getFcsUnseenCount => fcsUnseenCount != null String get getFcsUnseenCount => fcsUnseenCount != null
? fcsUnseenCount > 100 ? "99+" : fcsUnseenCount.toString() ? fcsUnseenCount! > 100
? "99+"
: fcsUnseenCount.toString()
: "0"; : "0";
List<String> privileges = []; List<String> privileges = [];
String get phone => phoneNumber != null && phoneNumber.startsWith("959") String get phone => phoneNumber != null && phoneNumber!.startsWith("959")
? "0${phoneNumber.substring(2)}" ? "0${phoneNumber!.substring(2)}"
: phoneNumber; : phoneNumber!;
bool get joined => status != null && status == user_joined_status; bool get joined => status != null && status == user_joined_status;
bool get invited => status != null && status == user_invited_status; bool get invited => status != null && status == user_invited_status;
bool get requested => status != null && status == user_requested_status; bool get requested => status != null && status == user_requested_status;
@@ -64,7 +69,7 @@ class User {
this.phoneNumber, this.phoneNumber,
this.fcsID, this.fcsID,
this.status, this.status,
this.privileges, this.privileges = const [],
this.lastMessage, this.lastMessage,
this.lastMessageTime, this.lastMessageTime,
this.userUnseenCount, this.userUnseenCount,

View File

@@ -1,12 +1,12 @@
class ServerException { class ServerException {
@override @override
List<Object> get props => null; List<Object>? get props => null;
call() { call() {
return null; return null;
} }
@override @override
bool get stringify => null; bool? get stringify => null;
} }

View File

@@ -1,12 +1,12 @@
import 'package:fcs/domain/entities/setting.dart'; import 'package:fcs/domain/entities/setting.dart';
class Contact { class Contact {
String usaAddress; String? usaAddress;
String mmAddress; String? mmAddress;
String usaContactNumber; String? usaContactNumber;
String mmContactNumber; String? mmContactNumber;
String emailAddress; String? emailAddress;
String facebookLink; String? facebookLink;
Contact({ Contact({
this.usaAddress, this.usaAddress,

View File

@@ -1,13 +1,14 @@
class DeliveryAddress { class DeliveryAddress {
String id; String? id;
String fullName; String? fullName;
String addressLine1; String? addressLine1;
String addressLine2; String? addressLine2;
String city; String? city;
String state; String? state;
String phoneNumber; String? phoneNumber;
bool isDefault; bool isDefault;
String userID; String? userID;
DeliveryAddress( DeliveryAddress(
{this.id, {this.id,
this.fullName, this.fullName,

View File

@@ -1,15 +1,15 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
class Message { class Message {
String id; String? id;
String message; String? message;
DateTime date; DateTime? date;
String receiverID; String? receiverID;
String receiverName; String? receiverName;
String senderID; String? senderID;
String senderName; String? senderName;
String messageType; String? messageType;
String messageID; String? messageID;
Message( Message(
{this.id, {this.id,
@@ -21,11 +21,13 @@ class Message {
this.senderName, this.senderName,
this.messageType, this.messageType,
this.messageID}); this.messageID});
bool fromToday() { bool fromToday() {
if (date == null) return false;
var now = DateTime.now(); var now = DateTime.now();
return date.day == now.day && return date!.day == now.day &&
date.month == now.month && date!.month == now.month &&
date.year == now.year; date!.year == now.year;
} }
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
@@ -36,9 +38,10 @@ class Message {
} }
bool sameDay(Message another) { bool sameDay(Message another) {
return date.year == another.date.year && if (date == null) return false;
date.month == another.date.month && return date!.year == another.date!.year &&
date.day == another.date.day; date!.month == another.date!.month &&
date!.day == another.date!.day;
} }
factory Message.fromMap(Map<String, dynamic> map, String id) { factory Message.fromMap(Map<String, dynamic> map, String id) {
@@ -52,7 +55,7 @@ class Message {
receiverName: map['receiver_name'], receiverName: map['receiver_name'],
messageType: map['msg_type'], messageType: map['msg_type'],
messageID: map['msg_id'], messageID: map['msg_id'],
date: date != null ? date.toDate() : null, date: date.toDate(),
); );
} }
} }

View File

@@ -1,20 +1,24 @@
import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/constants.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart'; import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class Privilege { class Privilege {
String id; String id;
String name; String? name;
String desc; String? desc;
bool sysAdminOnly = true; bool? sysAdminOnly = true;
bool isChecked = false; bool? isChecked = false;
IconData iconData; IconData? iconData;
Privilege( Privilege(
{this.id, this.name, this.desc, this.isChecked, this.sysAdminOnly}) { {required this.id,
this.name,
this.desc,
this.isChecked,
this.sysAdminOnly}) {
if (this.id == privilege_admin) { if (this.id == privilege_admin) {
iconData = MaterialCommunityIcons.account_tie; iconData = MaterialCommunityIcons.account_tie;
} else if (this.id == privilege_support) { } else if (this.id == privilege_support) {

View File

@@ -1,5 +0,0 @@
class RadioGroup {
String text;
int index;
RadioGroup({this.text, this.index});
}

View File

@@ -3,17 +3,21 @@ import 'package:cloud_firestore/cloud_firestore.dart';
class ShipmentStatus { class ShipmentStatus {
String status; String status;
DateTime date; DateTime date;
bool done; bool? done;
String staffId; String? staffId;
String staffName; String? staffName;
ShipmentStatus( ShipmentStatus(
{this.status, this.date, this.done, this.staffId, this.staffName}); {required this.status,
required this.date,
this.done,
this.staffId,
this.staffName});
factory ShipmentStatus.fromMap(Map<String, dynamic> map) { factory ShipmentStatus.fromMap(Map<String, dynamic> map) {
var _date = (map['date'] as Timestamp); var _date = (map['date'] as Timestamp);
return ShipmentStatus( return ShipmentStatus(
status: map['status'], status: map['status'],
date: _date == null ? null : _date.toDate(), date: _date.toDate(),
done: map['done'], done: map['done'],
staffId: map['staff_id'], staffId: map['staff_id'],
staffName: map['staff_name']); staffName: map['staff_name']);

View File

@@ -1,8 +1,7 @@
class Status { class Status {
String status; String? status;
String message; String? message;
String errorCode; String? errorCode;
Status(this.status, this.message); Status(this.status, this.message);
Status.fromJson(Map<String, dynamic> json) { Status.fromJson(Map<String, dynamic> json) {

View File

@@ -1,8 +1,8 @@
import 'package:fcs/domain/entities/setting.dart'; import 'package:fcs/domain/entities/setting.dart';
class Term { class Term {
String termEng; String? termEng;
String termMm; String? termMm;
Term({this.termEng, this.termMm}); Term({this.termEng, this.termMm});

View File

@@ -20,8 +20,8 @@ Future<dynamic> requestAPI(
String path, String path,
method, { method, {
dynamic payload, dynamic payload,
String token, String? token,
String url, String? url,
}) async { }) async {
DevInfo devInfo = await DevInfo.getDevInfo(); DevInfo devInfo = await DevInfo.getDevInfo();
@@ -33,7 +33,7 @@ Future<dynamic> requestAPI(
headers["Token"] = token; headers["Token"] = token;
} }
if (devInfo != null && devInfo.deviceID != null && deviceName != null) { if (devInfo != null && devInfo.deviceID != null && deviceName != null) {
headers["Device"] = devInfo.deviceID + ":" + deviceName; headers["Device"] = devInfo.deviceID??"" + ":" + deviceName;
} }
headers["Project-ID"] = Config.instance.reportProjectID; headers["Project-ID"] = Config.instance.reportProjectID;
@@ -66,7 +66,7 @@ Future<dynamic> requestAPI(
// request makes http request // request makes http request
// if token is null // if token is null
Future<dynamic> requestDownloadAPI(String path, method, Future<dynamic> requestDownloadAPI(String path, method,
{dynamic payload, String token, String url, String filePath}) async { {dynamic payload, String? token, String? url, String? filePath}) async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
String deviceName = "${androidInfo.model}(${androidInfo.id})"; String deviceName = "${androidInfo.model}(${androidInfo.id})";
@@ -81,7 +81,7 @@ Future<dynamic> requestDownloadAPI(String path, method,
log.info("Path:$baseUrl$path"); log.info("Path:$baseUrl$path");
HttpClient client = new HttpClient(); HttpClient client = new HttpClient();
var _downloadData = StringBuffer(); var _downloadData = StringBuffer();
var fileSave = new File(filePath); var fileSave = new File(filePath!);
var request = await client.getUrl(Uri.parse("$baseUrl$path")); var request = await client.getUrl(Uri.parse("$baseUrl$path"));
request.headers.set("Project-ID", Config.instance.reportProjectID); request.headers.set("Project-ID", Config.instance.reportProjectID);
request.headers request.headers
@@ -108,7 +108,7 @@ Future<dynamic> requestDownloadAPI(String path, method,
// request makes http request // request makes http request
// if token is null // if token is null
Future<dynamic> requestDownloadPDFAPI(String path, method, Future<dynamic> requestDownloadPDFAPI(String path, method,
{dynamic payload, String token, String url, String filePath}) async { {dynamic payload, String? token, String? url, String? filePath}) async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
String deviceName = "${androidInfo.model}(${androidInfo.id})"; String deviceName = "${androidInfo.model}(${androidInfo.id})";
@@ -123,7 +123,7 @@ Future<dynamic> requestDownloadPDFAPI(String path, method,
log.info("Path:$baseUrl$path"); log.info("Path:$baseUrl$path");
HttpClient client = new HttpClient(); HttpClient client = new HttpClient();
// var _downloadData = StringBuffer(); // var _downloadData = StringBuffer();
var fileSave = new File(filePath); var fileSave = new File(filePath!);
var request = await client.getUrl(Uri.parse("$baseUrl$path")); var request = await client.getUrl(Uri.parse("$baseUrl$path"));
request.headers.set("Project-ID", Config.instance.reportProjectID); request.headers.set("Project-ID", Config.instance.reportProjectID);
if (token != null) { if (token != null) {
@@ -135,7 +135,7 @@ Future<dynamic> requestDownloadPDFAPI(String path, method,
request.headers.set("payload", escapePayload); request.headers.set("payload", escapePayload);
var response = await request.close(); var response = await request.close();
print("headers:${response.headers}"); print("headers:${response.headers}");
var _downloadData = List<int>(); List<int> _downloadData = [];
response.listen((d) => _downloadData.addAll(d), onDone: () { response.listen((d) => _downloadData.addAll(d), onDone: () {
fileSave.writeAsBytes(_downloadData); fileSave.writeAsBytes(_downloadData);
@@ -155,10 +155,10 @@ typedef OnDownloadDone(File file);
// if token is null // if token is null
Future<dynamic> requestDownload(String path, method, Future<dynamic> requestDownload(String path, method,
{dynamic payload, {dynamic payload,
String token, required String token,
String url, required String url,
String filePath, required String filePath,
OnDownloadDone onDownloadDone}) async { OnDownloadDone? onDownloadDone}) async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
String deviceName = "${androidInfo.model}(${androidInfo.id})"; String deviceName = "${androidInfo.model}(${androidInfo.id})";
@@ -188,7 +188,7 @@ Future<dynamic> requestDownload(String path, method,
// request.write(escapePayload); // request.write(escapePayload);
var response = await request.close(); var response = await request.close();
print("headers:${response.headers}"); print("headers:${response.headers}");
var _downloadData = List<int>(); List<int> _downloadData = [];
var cd = response.headers.value("content-disposition"); var cd = response.headers.value("content-disposition");
String fileName = "download.csv"; String fileName = "download.csv";
if (cd != null && cd.contains("filename=")) { if (cd != null && cd.contains("filename=")) {

View File

@@ -2,13 +2,13 @@ import 'package:device_info/device_info.dart';
import 'dart:io' show Platform; import 'dart:io' show Platform;
class DevInfo { class DevInfo {
bool isAndroid; bool? isAndroid;
bool isIOS; bool? isIOS;
String deviceID; String? deviceID;
String id; String? id;
String model; String? model;
static DevInfo _instance; static DevInfo? _instance;
static Future<DevInfo> getDevInfo() async { static Future<DevInfo> getDevInfo() async {
if (_instance != null) return Future.value(_instance); if (_instance != null) return Future.value(_instance);
@@ -18,14 +18,14 @@ class DevInfo {
if (Platform.isAndroid) { if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
_instance.deviceID = androidInfo.androidId; _instance!.deviceID = androidInfo.androidId;
_instance.id = androidInfo.id; _instance!.id = androidInfo.id;
_instance.model = androidInfo.model; _instance!.model = androidInfo.model;
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
IosDeviceInfo iosDeviceInfo = await deviceInfo.iosInfo; IosDeviceInfo iosDeviceInfo = await deviceInfo.iosInfo;
_instance.deviceID = iosDeviceInfo.identifierForVendor; _instance!.deviceID = iosDeviceInfo.identifierForVendor;
_instance.id = iosDeviceInfo.utsname.release; _instance!.id = iosDeviceInfo.utsname.release;
_instance.model = iosDeviceInfo.model; _instance!.model = iosDeviceInfo.model;
} }
return Future.value(_instance); return Future.value(_instance);
} }

View File

@@ -1,32 +1,31 @@
import 'dart:io'; import 'dart:io';
import 'package:fcs/config.dart'; import 'package:firebase_auth/firebase_auth.dart' as fb;
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart'; import 'package:firebase_storage/firebase_storage.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
final log = Logger('firebaseHelper'); final log = Logger('firebaseHelper');
final FirebaseAuth auth = FirebaseAuth.instance; final fb.FirebaseAuth auth = fb.FirebaseAuth.instance;
Future<String> getToken() async { Future<String> getToken() async {
FirebaseUser firebaseUser = await auth.currentUser(); fb.User? firebaseUser = fb.FirebaseAuth.instance.currentUser;
IdTokenResult token = await firebaseUser.getIdToken(); String token = await firebaseUser?.getIdToken() ?? "";
return token.token; return token;
} }
Future<Map> getClaims({bool refreshIdToken = false}) async { Future<Map?> getClaims({bool refreshIdToken = false}) async {
FirebaseUser firebaseUser = await auth.currentUser(); fb.User? firebaseUser = auth.currentUser;
if (firebaseUser == null) return null; if (firebaseUser == null) return null;
IdTokenResult idToken = fb.IdTokenResult idToken =
await firebaseUser.getIdToken(refresh: refreshIdToken); await firebaseUser.getIdTokenResult(refreshIdToken);
return idToken.claims; return idToken.claims;
} }
// returns list of url // returns list of url
Future<List<String>> uploadFiles(String path, List<File> files, Future<List<String>> uploadFiles(String path, List<File> files,
{String fileName}) async { {String? fileName}) async {
List<Future<String>> fu = []; List<Future<String>> fu = [];
for (File f in files) { for (File f in files) {
Future<String> u = uploadStorage(path, f); Future<String> u = uploadStorage(path, f);
@@ -35,22 +34,27 @@ Future<List<String>> uploadFiles(String path, List<File> files,
return Future.wait(fu); return Future.wait(fu);
} }
Future<String> uploadStorage(String path, File file, {String fileName}) async { Future<String> uploadStorage(String path, File file, {String? fileName}) async {
if (fileName == null) { if (fileName == null) {
fileName = Uuid().v4(); fileName = Uuid().v4();
} }
StorageReference storageReference = Reference ref = FirebaseStorage.instance.ref().child('$path/$fileName');
FirebaseStorage(storageBucket: Config.instance.bucketName) UploadTask uploadTask = ref.putFile(file);
.ref() await uploadTask.resume();
.child('$path/$fileName'); String downloadUrl = await ref.getDownloadURL();
StorageUploadTask uploadTask = storageReference.putFile(file);
await uploadTask.onComplete;
String downloadUrl = await storageReference.getDownloadURL();
print("name:${await storageReference.getName()}");
print("bucket:${await storageReference.getBucket()}");
print("path:${await storageReference.getPath()}");
print("meta:${await storageReference.getMetadata()}");
return downloadUrl; return downloadUrl;
// StorageReference storageReference =
// FirebaseStorage(storageBucket: Config.instance.bucketName)
// .ref()
// .child('$path/$fileName');
// StorageUploadTask uploadTask = storageReference.putFile(file);
// await uploadTask.onComplete;
// String downloadUrl = await storageReference.getDownloadURL();
// print("name:${await storageReference.getName()}");
// print("bucket:${await storageReference.getBucket()}");
// print("path:${await storageReference.getPath()}");
// print("meta:${await storageReference.getMetadata()}");
// return downloadUrl;
} }
Future<void> deleteStorageFromUrls(List<String> urls) async { Future<void> deleteStorageFromUrls(List<String> urls) async {
@@ -62,10 +66,12 @@ Future<void> deleteStorageFromUrls(List<String> urls) async {
Future<void> deleteStorageFromUrl(String url) async { Future<void> deleteStorageFromUrl(String url) async {
try { try {
StorageReference storageReference = Reference ref = FirebaseStorage.instance.refFromURL(url);
await FirebaseStorage(storageBucket: Config.instance.bucketName) await ref.delete();
.getReferenceFromUrl(url); // StorageReference storageReference =
await storageReference.delete(); // await FirebaseStorage(storageBucket: Config.instance.bucketName)
// .getReferenceFromUrl(url);
// await storageReference.delete();
} catch (e) { } catch (e) {
log.warning("deleteStorage:$e"); log.warning("deleteStorage:$e");
} }

View File

@@ -11,7 +11,7 @@ class NetworkConnectivity {
final log = Logger('NetworkConnectivity'); final log = Logger('NetworkConnectivity');
static final NetworkConnectivity instance = NetworkConnectivity._internal(); static final NetworkConnectivity instance = NetworkConnectivity._internal();
static String hostName; static String? hostName;
NetworkConnectivity._internal() { NetworkConnectivity._internal() {
_initialise(); _initialise();
var uri = Uri.parse(Config.instance.apiURL); var uri = Uri.parse(Config.instance.apiURL);
@@ -38,7 +38,7 @@ class NetworkConnectivity {
// lookup if connectivity is not none // lookup if connectivity is not none
if (result != ConnectivityResult.none) { if (result != ConnectivityResult.none) {
try { try {
final hostNameLookup = await InternetAddress.lookup(hostName); final hostNameLookup = await InternetAddress.lookup(hostName ?? "");
if (hostNameLookup.isNotEmpty && if (hostNameLookup.isNotEmpty &&
hostNameLookup[0].rawAddress.isNotEmpty) { hostNameLookup[0].rawAddress.isNotEmpty) {
if (await checkHeartbeat()) { if (await checkHeartbeat()) {

View File

@@ -13,7 +13,7 @@ class Paginator<T> {
final log = Logger('Paginator'); final log = Logger('Paginator');
final int rowPerLoad; final int rowPerLoad;
DocumentSnapshot prev; DocumentSnapshot? prev;
bool ended = false; bool ended = false;
bool isLoading = false; bool isLoading = false;
List<T> values = []; List<T> values = [];
@@ -21,7 +21,7 @@ class Paginator<T> {
Query pageQuery; Query pageQuery;
Paginator(this.pageQuery, {this.rowPerLoad = 20, this.toObj}) { Paginator(this.pageQuery, {this.rowPerLoad = 20, required this.toObj}) {
_clearState(); _clearState();
} }
@@ -36,27 +36,27 @@ class Paginator<T> {
_clearState(); _clearState();
} }
Future<void> refresh({CallBack onFinished}) async { Future<void> refresh({CallBack? onFinished}) async {
_clearState(); _clearState();
await load(); await load();
if (onFinished != null) onFinished(); if (onFinished != null) onFinished();
} }
Future<bool> load({CallBack onFinished}) async { Future<bool?> load({CallBack? onFinished}) async {
if (ended) return null; if (ended) return null;
isLoading = true; isLoading = true;
Query _query = Query _query =
prev != null ? pageQuery.startAfterDocument(prev) : pageQuery; prev != null ? pageQuery.startAfterDocument(prev!) : pageQuery;
try { try {
await _query await _query
.limit(rowPerLoad) .limit(rowPerLoad)
.getDocuments(source: Source.server) .get(GetOptions(source: Source.server))
.then((QuerySnapshot snapshot) { .then((QuerySnapshot snapshot) {
int count = snapshot.documents.length; int count = snapshot.docs.length;
ended = count < rowPerLoad; ended = count < rowPerLoad;
prev = count > 0 ? snapshot.documents[count - 1] : prev; prev = count > 0 ? snapshot.docs[count - 1] : prev;
snapshot.documents.forEach((e) { snapshot.docs.forEach((e) {
values.add(toObj(e.data, e.documentID)); values.add(toObj(e.data() as Map<String, dynamic>, e.id));
}); });
}); });
} catch (e) { } catch (e) {

View File

@@ -7,17 +7,17 @@ class SharedPref {
static final SharedPref instance = SharedPref._(); static final SharedPref instance = SharedPref._();
SharedPref._(); SharedPref._();
static Future<bool> isFirstLaunch() async { static Future<bool?> isFirstLaunch() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getBool('first_launch'); return prefs.getBool('first_launch');
} }
static Future<void> finishFirstLaunch() async { static Future<void> finishFirstLaunch() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setBool('first_launch', false); prefs.setBool('first_launch', false);
} }
static Future<String> getLang() async { static Future<String?> getLang() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('language'); return prefs.getString('language');
} }
@@ -27,7 +27,7 @@ class SharedPref {
prefs.setString('language', lang); prefs.setString('language', lang);
} }
static Future<bool> getStaffMode() async { static Future<bool?> getStaffMode() async {
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getBool('staff_mode_on'); return prefs.getBool('staff_mode_on');
} }
@@ -41,7 +41,7 @@ class SharedPref {
await _save("user", user.toJson()); await _save("user", user.toJson());
} }
static Future<User> getUser() async { static Future<User?> getUser() async {
try { try {
return User.fromJson(await _read("user")); return User.fromJson(await _read("user"));
} catch (e) { } catch (e) {
@@ -57,7 +57,7 @@ class SharedPref {
await _save("skipped_recovery_email", skipped); await _save("skipped_recovery_email", skipped);
} }
static Future<bool> getSkippedRecoverEmail() async { static Future<bool?> getSkippedRecoverEmail() async {
try { try {
bool _skipped = await _read("skipped_recovery_email"); bool _skipped = await _read("skipped_recovery_email");
return _skipped; return _skipped;
@@ -69,7 +69,7 @@ class SharedPref {
static _read(String key) async { static _read(String key) async {
try { try {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
return json.decode(prefs.getString(key)); return json.decode(prefs.getString(key) ?? "");
} catch (e) { } catch (e) {
print("Error:$e"); print("Error:$e");
} }

View File

@@ -20,8 +20,10 @@ const TextStyle labelStyleMM = TextStyle(
fontFamily: "Myanmar3"); fontFamily: "Myanmar3");
const TextStyle subMenuStyle = const TextStyle subMenuStyle =
TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500); TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500);
const TextStyle subMenuStyleMM = const TextStyle subMenuStyleMM = TextStyle(
TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500, fontSize: 14,
color: Colors.white,
fontWeight: FontWeight.w500,
fontFamily: "Myanmar3"); fontFamily: "Myanmar3");
const TextStyle welcomeLabelStyle = const TextStyle welcomeLabelStyle =
@@ -31,11 +33,10 @@ const TextStyle welcomeSubLabelStyle =
const TextStyle siginButtonStyle = const TextStyle siginButtonStyle =
TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500); TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500);
TextStyle newLabelStyle( TextStyle newLabelStyle(
{Color color, {Color? color,
double fontSize, double? fontSize,
FontWeight fontWeight, FontWeight? fontWeight,
bool underline = false}) { bool underline = false}) {
return TextStyle( return TextStyle(
fontSize: fontSize == null ? 14 : fontSize, fontSize: fontSize == null ? 14 : fontSize,
@@ -45,9 +46,9 @@ TextStyle newLabelStyle(
} }
TextStyle newLabelStyleMM( TextStyle newLabelStyleMM(
{Color color, {Color? color,
double fontSize, double? fontSize,
FontWeight fontWeight, FontWeight? fontWeight,
bool underline = false}) { bool underline = false}) {
return TextStyle( return TextStyle(
fontSize: fontSize == null ? 13 : fontSize, fontSize: fontSize == null ? 13 : fontSize,
@@ -59,8 +60,8 @@ TextStyle newLabelStyleMM(
const TextStyle photoLabelStyle = const TextStyle photoLabelStyle =
TextStyle(color: Colors.black, fontSize: 13.0); TextStyle(color: Colors.black, fontSize: 13.0);
const TextStyle photoLabelStyleMM = TextStyle( const TextStyle photoLabelStyleMM =
color: Colors.black, fontSize: 13.0, fontFamily: "Myanmar3"); TextStyle(color: Colors.black, fontSize: 13.0, fontFamily: "Myanmar3");
const TextStyle textStyle = const TextStyle textStyle =
TextStyle(fontSize: 14, color: Colors.black87, fontWeight: FontWeight.w500); TextStyle(fontSize: 14, color: Colors.black87, fontWeight: FontWeight.w500);
const TextStyle textStyleOdd = TextStyle( const TextStyle textStyleOdd = TextStyle(

View File

@@ -54,7 +54,7 @@ Future<void> showConfirmDialog(
FlatButton( FlatButton(
color: Colors.grey[300], color: Colors.grey[300],
child: Text( child: Text(
AppTranslations.of(context).text('btn.cancel'), AppTranslations.of(context)!.text('btn.cancel'),
style: Provider.of<LanguageModel>(context).isEng style: Provider.of<LanguageModel>(context).isEng
? TextStyle() ? TextStyle()
: TextStyle(fontFamily: 'Myanmar3'), : TextStyle(fontFamily: 'Myanmar3'),
@@ -67,7 +67,7 @@ Future<void> showConfirmDialog(
), ),
FlatButton( FlatButton(
color: primaryColor, color: primaryColor,
child: Text(AppTranslations.of(context).text('btn.ok'), child: Text(AppTranslations.of(context)!.text('btn.ok'),
style: Provider.of<LanguageModel>(context).isEng style: Provider.of<LanguageModel>(context).isEng
? TextStyle( ? TextStyle(
color: Colors.white, color: Colors.white,
@@ -367,7 +367,7 @@ Widget fcsButton(BuildContext context, String text,
} }
String getLocalString(BuildContext context, String key) { String getLocalString(BuildContext context, String key) {
return AppTranslations.of(context).text(key); return AppTranslations.of(context)!.text(key);
} }
void showToast(GlobalKey key, String text) { void showToast(GlobalKey key, String text) {

View File

@@ -5,7 +5,7 @@ import 'package:fcs/pages/widgets/local_text.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_icons/flutter_icons.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class BottomWidgets extends StatelessWidget { class BottomWidgets extends StatelessWidget {

View File

@@ -3,20 +3,20 @@ import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/delivery_address/delivery_address_row.dart'; import 'package:fcs/pages/delivery_address/delivery_address_row.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'callbacks.dart'; import 'callbacks.dart';
import 'display_text.dart'; import 'display_text.dart';
import 'local_text.dart'; import 'local_text.dart';
class DefaultDeliveryAddress extends StatelessWidget { class DefaultDeliveryAddress extends StatelessWidget {
final DeliveryAddress deliveryAddress; final DeliveryAddress? deliveryAddress;
final String labelKey; final String? labelKey;
final OnTap onTap; final OnTap? onTap;
final IconData iconData; final IconData? iconData;
const DefaultDeliveryAddress( const DefaultDeliveryAddress(
{Key key, this.deliveryAddress, this.onTap, this.labelKey, this.iconData}) {Key? key, this.deliveryAddress, this.onTap, this.labelKey, this.iconData})
: super(key: key); : super(key: key);
@override @override
@@ -37,7 +37,7 @@ class DefaultDeliveryAddress extends StatelessWidget {
onTap == null onTap == null
? Container() ? Container()
: GestureDetector( : GestureDetector(
onTap: () => onTap(), onTap: () => onTap!(),
child: Chip( child: Chip(
label: LocalText( label: LocalText(
context, "delivery_address.change_address", context, "delivery_address.change_address",
@@ -50,8 +50,8 @@ class DefaultDeliveryAddress extends StatelessWidget {
child: deliveryAddress == null child: deliveryAddress == null
? Container() ? Container()
: DeliveryAddressRow( : DeliveryAddressRow(
key: ValueKey(deliveryAddress.id), key: ValueKey(deliveryAddress!.id),
deliveryAddress: deliveryAddress), deliveryAddress: deliveryAddress!),
), ),
], ],
); );

View File

@@ -10,11 +10,11 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class DeliveryAddressSelection extends StatefulWidget { class DeliveryAddressSelection extends StatefulWidget {
final DeliveryAddress deliveryAddress; final DeliveryAddress? deliveryAddress;
final User user; final User? user;
const DeliveryAddressSelection({ const DeliveryAddressSelection({
Key key, Key? key,
this.deliveryAddress, this.deliveryAddress,
this.user, this.user,
}) : super(key: key); }) : super(key: key);
@@ -38,7 +38,7 @@ class _DeliveryAddressSelectionState extends State<DeliveryAddressSelection> {
Provider.of<DeliveryAddressModel>(context, listen: false); Provider.of<DeliveryAddressModel>(context, listen: false);
var deliveryAddresses = var deliveryAddresses =
await addressModel.getDeliveryAddresses(widget.user.id); await addressModel.getDeliveryAddresses(widget.user!.id);
setState(() { setState(() {
this._deliveryAddresses = deliveryAddresses; this._deliveryAddresses = deliveryAddresses;
}); });
@@ -95,7 +95,7 @@ class _DeliveryAddressSelectionState extends State<DeliveryAddressSelection> {
padding: const EdgeInsets.all(10.0), padding: const EdgeInsets.all(10.0),
child: Icon(Icons.check, child: Icon(Icons.check,
color: widget.deliveryAddress != null && color: widget.deliveryAddress != null &&
_deliveryAddress.id == widget.deliveryAddress.id _deliveryAddress.id == widget.deliveryAddress!.id
? primaryColor ? primaryColor
: Colors.black26), : Colors.black26),
), ),

View File

@@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
import 'local_text.dart'; import 'local_text.dart';
class DialogInput extends StatefulWidget { class DialogInput extends StatefulWidget {
final String value; final String? value;
final String label; final String? label;
const DialogInput({Key key, this.label, this.value}) : super(key: key); const DialogInput({Key? key, this.label, this.value}) : super(key: key);
@override @override
_DialogInputState createState() => _DialogInputState(); _DialogInputState createState() => _DialogInputState();
} }
@@ -24,7 +24,7 @@ class _DialogInputState extends State<DialogInput> {
void initState() { void initState() {
super.initState(); super.initState();
if (widget.value != null) { if (widget.value != null) {
_controller.text = widget.value; _controller.text = widget.value!;
_focusNode.addListener(() { _focusNode.addListener(() {
if (_focusNode.hasFocus) { if (_focusNode.hasFocus) {
_controller.selection = TextSelection( _controller.selection = TextSelection(
@@ -41,7 +41,7 @@ class _DialogInputState extends State<DialogInput> {
child: AlertDialog( child: AlertDialog(
title: LocalText( title: LocalText(
context, context,
widget.label, widget.label!,
fontSize: 20, fontSize: 20,
color: primaryColor, color: primaryColor,
), ),
@@ -77,7 +77,7 @@ class _DialogInputState extends State<DialogInput> {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
onPressed: () async { onPressed: () async {
if (!_formKey.currentState.validate()) return; if (!_formKey.currentState!.validate()) return;
_save(); _save();
}) })
], ],

View File

@@ -6,13 +6,13 @@ import 'package:flutter/material.dart';
import 'local_text.dart'; import 'local_text.dart';
class DiscountDropdown<T> extends StatelessWidget { class DiscountDropdown<T> extends StatelessWidget {
final Function(T) callback; final Function(T)? callback;
final IconData iconData; final IconData? iconData;
final T selectedValue; final T? selectedValue;
final List<T> values; final List<T>? values;
const DiscountDropdown( const DiscountDropdown(
{Key key, this.callback, this.iconData, this.selectedValue, this.values}) {Key? key, this.callback, this.iconData, this.selectedValue, this.values})
: super(key: key); : super(key: key);
@override @override
@@ -46,11 +46,11 @@ class DiscountDropdown<T> extends StatelessWidget {
height: 1, height: 1,
color: primaryColor, color: primaryColor,
), ),
onChanged: (T newValue) { onChanged: (T? newValue) {
callback(newValue); callback!(newValue!);
}, },
isExpanded: true, isExpanded: true,
items: values.map<DropdownMenuItem<T>>((T value) { items: values!.map<DropdownMenuItem<T>>((T value) {
return DropdownMenuItem<T>( return DropdownMenuItem<T>(
value: value, value: value,
child: Text(value == null ? "" : (value as Discount).code, child: Text(value == null ? "" : (value as Discount).code,

View File

@@ -4,12 +4,12 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
class DisplayImageSource { class DisplayImageSource {
String url; String? url;
File file; File? file;
DisplayImageSource({this.url, this.file}); DisplayImageSource({this.url, this.file});
ImageProvider get imageProvider => ImageProvider? get imageProvider =>
file == null ? CachedNetworkImageProvider(url) : FileImage(file); file == null ? CachedNetworkImageProvider(url!) : FileImage(file!);
@override @override
bool operator ==(other) { bool operator ==(other) {

View File

@@ -62,7 +62,7 @@ class DisplayText extends StatelessWidget {
labelTextKey == null labelTextKey == null
? Container() ? Container()
: Text( : Text(
AppTranslations.of(context).text(labelTextKey!), AppTranslations.of(context)!.text(labelTextKey!),
style: labelStyle, style: labelStyle,
), ),
text == null text == null

View File

@@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
import 'callbacks.dart'; import 'callbacks.dart';
class FcsExpansionTile extends StatefulWidget { class FcsExpansionTile extends StatefulWidget {
final ValueChanged<bool> onExpansionChanged; final ValueChanged<bool>? onExpansionChanged;
final CallBack onEditPress; final CallBack? onEditPress;
final List<Widget> children; final List<Widget>? children;
final Widget title; final Widget? title;
final bool isEdit; final bool isEdit;
const FcsExpansionTile( const FcsExpansionTile(
{this.onExpansionChanged, {this.onExpansionChanged,
@@ -21,7 +21,7 @@ class FcsExpansionTile extends StatefulWidget {
} }
class _FcsExpansionTileState extends State<FcsExpansionTile> { class _FcsExpansionTileState extends State<FcsExpansionTile> {
bool expanded; bool? expanded;
@override @override
void initState() { void initState() {
this.expanded = false; this.expanded = false;
@@ -39,22 +39,22 @@ class _FcsExpansionTileState extends State<FcsExpansionTile> {
expanded = value; expanded = value;
}); });
if (widget.onExpansionChanged != null) if (widget.onExpansionChanged != null)
widget.onExpansionChanged(value); widget.onExpansionChanged!(value);
}, },
title: widget.title, title: widget.title != null ? widget.title! : Container(),
children: widget.children, children: widget.children != null ? widget.children! : [Container()],
trailing: widget.isEdit trailing: widget.isEdit
? IconButton( ? IconButton(
padding: EdgeInsets.all(0), padding: EdgeInsets.all(0),
iconSize: 20, iconSize: 20,
onPressed: () => onPressed: () =>
widget.onEditPress != null ? widget.onEditPress() : {}, widget.onEditPress != null ? widget.onEditPress!() : {},
icon: Icon( icon: Icon(
Icons.edit, Icons.edit,
color: primaryColor, color: primaryColor,
)) ))
: AnimatedSwitcher( : AnimatedSwitcher(
child: expanded child: expanded!
? Icon( ? Icon(
Icons.remove, Icons.remove,
color: primaryColor, color: primaryColor,

View File

@@ -1,4 +1,4 @@
import 'package:flutter_icons/flutter_icons.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart';
const cartonIconData = MaterialCommunityIcons.package; const cartonIconData = MaterialCommunityIcons.package;
const customFeeIconData = MaterialCommunityIcons.security; const customFeeIconData = MaterialCommunityIcons.security;

View File

@@ -1,7 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'local_text.dart'; import 'local_text.dart';
@@ -18,15 +18,15 @@ modelBottomSheet(BuildContext context, {final OnFile onFile}) {
} }
class ImageFile extends StatefulWidget { class ImageFile extends StatefulWidget {
final OnFile onFile; final OnFile? onFile;
const ImageFile({Key key, this.onFile}) : super(key: key); const ImageFile({Key? key, this.onFile}) : super(key: key);
@override @override
_ImageFileState createState() => _ImageFileState(); _ImageFileState createState() => _ImageFileState();
} }
class _ImageFileState extends State<ImageFile> { class _ImageFileState extends State<ImageFile> {
File selectedFile; File? selectedFile;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
@@ -44,7 +44,7 @@ class _ImageFileState extends State<ImageFile> {
onTap: () async { onTap: () async {
Navigator.pop(context); Navigator.pop(context);
selectedFile = await pickImage(ImageSource.gallery); selectedFile = await pickImage(ImageSource.gallery);
if (widget.onFile != null) widget.onFile(selectedFile); if (widget.onFile != null) widget.onFile!(selectedFile!);
}), }),
new ListTile( new ListTile(
leading: CircleAvatar( leading: CircleAvatar(
@@ -58,7 +58,7 @@ class _ImageFileState extends State<ImageFile> {
Navigator.pop(context); Navigator.pop(context);
selectedFile = await pickImage(ImageSource.camera); selectedFile = await pickImage(ImageSource.camera);
if (widget.onFile != null) widget.onFile(selectedFile); if (widget.onFile != null) widget.onFile!(selectedFile!);
}, },
), ),
new ListTile( new ListTile(
@@ -75,7 +75,7 @@ class _ImageFileState extends State<ImageFile> {
selectedFile = null; selectedFile = null;
}); });
if (widget.onFile != null) widget.onFile(selectedFile); if (widget.onFile != null) widget.onFile!(selectedFile!);
}, },
), ),
], ],

View File

@@ -8,10 +8,10 @@ import 'show_img.dart';
typedef OnFile = void Function(File); typedef OnFile = void Function(File);
class ImageUrl extends StatefulWidget { class ImageUrl extends StatefulWidget {
final String title; final String? title;
final String url; final String? url;
const ImageUrl({Key key, this.title, this.url}) : super(key: key); const ImageUrl({Key? key, this.title, this.url}) : super(key: key);
@override @override
_ImageUrlState createState() => _ImageUrlState(); _ImageUrlState createState() => _ImageUrlState();
} }
@@ -25,12 +25,12 @@ class _ImageUrlState extends State<ImageUrl> {
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) =>
ShowImage(url: widget.url, fileName: widget.title)), ShowImage(url: widget.url!, fileName: widget.title!)),
) )
}, },
child: Chip( child: Chip(
avatar: Icon(Icons.image), avatar: Icon(Icons.image),
label: Text(widget.title), label: Text(widget.title!),
), ),
); );
} }

View File

@@ -10,19 +10,19 @@ class InputDate extends StatelessWidget {
final String labelTextKey; final String labelTextKey;
final IconData iconData; final IconData iconData;
final TextEditingController controller; final TextEditingController controller;
final FormFieldValidator<String> validator; final FormFieldValidator<String>? validator;
final int maxLines; final int maxLines;
final bool withBorder; final bool withBorder;
final Color borderColor; final Color? borderColor;
final TextInputType textInputType; final TextInputType? textInputType;
final bool autoFocus; final bool autoFocus;
final String dateFormatString; final String dateFormatString;
const InputDate( const InputDate(
{Key key, {Key? key,
this.labelTextKey, required this.labelTextKey,
this.iconData, required this.iconData,
this.controller, required this.controller,
this.validator, this.validator,
this.maxLines = 1, this.maxLines = 1,
this.withBorder = false, this.withBorder = false,
@@ -72,7 +72,7 @@ class InputDate extends StatelessWidget {
), ),
labelText: labelTextKey == null labelText: labelTextKey == null
? null ? null
: AppTranslations.of(context).text(labelTextKey), : AppTranslations.of(context)!.text(labelTextKey),
labelStyle: languageModel.isEng labelStyle: languageModel.isEng
? newLabelStyle(color: Colors.black54, fontSize: 20) ? newLabelStyle(color: Colors.black54, fontSize: 20)
: newLabelStyleMM(color: Colors.black54, fontSize: 20), : newLabelStyleMM(color: Colors.black54, fontSize: 20),

View File

@@ -6,20 +6,20 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class InputText extends StatelessWidget { class InputText extends StatelessWidget {
final String labelTextKey; final String? labelTextKey;
final IconData iconData; final IconData? iconData;
final TextEditingController controller; final TextEditingController? controller;
final FormFieldValidator<String> validator; final FormFieldValidator<String>? validator;
final int maxLines; final int maxLines;
final bool withBorder; final bool withBorder;
final Color borderColor; final Color? borderColor;
final TextInputType textInputType; final TextInputType? textInputType;
final bool autoFocus; final bool autoFocus;
final TextAlign textAlign; final TextAlign textAlign;
final bool enabled; final bool enabled;
const InputText( const InputText(
{Key key, {Key? key,
this.labelTextKey, this.labelTextKey,
this.iconData, this.iconData,
this.controller, this.controller,
@@ -30,7 +30,7 @@ class InputText extends StatelessWidget {
this.autoFocus = false, this.autoFocus = false,
this.textInputType, this.textInputType,
this.enabled = true, this.enabled = true,
this.textAlign}) this.textAlign = TextAlign.start})
: super(key: key); : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -46,7 +46,7 @@ class InputText extends StatelessWidget {
style: textStyle, style: textStyle,
maxLines: maxLines, maxLines: maxLines,
keyboardType: textInputType, keyboardType: textInputType,
textAlign: textAlign ?? TextAlign.start, textAlign: textAlign,
decoration: new InputDecoration( decoration: new InputDecoration(
// hintText: '', // hintText: '',
hintStyle: TextStyle( hintStyle: TextStyle(
@@ -54,7 +54,7 @@ class InputText extends StatelessWidget {
), ),
labelText: labelTextKey == null labelText: labelTextKey == null
? null ? null
: AppTranslations.of(context).text(labelTextKey), : AppTranslations.of(context)!.text(labelTextKey!),
labelStyle: languageModel.isEng labelStyle: languageModel.isEng
? newLabelStyle(color: Colors.black54, fontSize: 20) ? newLabelStyle(color: Colors.black54, fontSize: 20)
: newLabelStyleMM(color: Colors.black54, fontSize: 20), : newLabelStyleMM(color: Colors.black54, fontSize: 20),

View File

@@ -7,18 +7,18 @@ import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class InputTime extends StatelessWidget { class InputTime extends StatelessWidget {
final String labelTextKey; final String? labelTextKey;
final IconData iconData; final IconData? iconData;
final TextEditingController controller; final TextEditingController? controller;
final FormFieldValidator<String> validator; final FormFieldValidator<String>? validator;
final int maxLines; final int maxLines;
final bool withBorder; final bool withBorder;
final Color borderColor; final Color? borderColor;
final TextInputType textInputType; final TextInputType? textInputType;
final bool autoFocus; final bool autoFocus;
const InputTime( const InputTime(
{Key key, {Key? key,
this.labelTextKey, this.labelTextKey,
this.iconData, this.iconData,
this.controller, this.controller,
@@ -45,14 +45,14 @@ class InputTime extends StatelessWidget {
try { try {
final format = DateFormat.jm(); //"6:00 AM" final format = DateFormat.jm(); //"6:00 AM"
initialDate = initialDate =
TimeOfDay.fromDateTime(format.parse(controller.text)); TimeOfDay.fromDateTime(format.parse(controller!.text));
// var values = controller.text.split(":"); // var values = controller.text.split(":");
// initialDate = TimeOfDay( // initialDate = TimeOfDay(
// hour: int.parse(values[0]), minute: int.parse(values[1])); // hour: int.parse(values[0]), minute: int.parse(values[1]));
} catch (e) {} // ignore error } catch (e) {} // ignore error
} }
TimeOfDay t = await showTimePicker( TimeOfDay? t = await showTimePicker(
initialTime: initialDate, initialTime: initialDate,
context: context, context: context,
); );
@@ -61,7 +61,7 @@ class InputTime extends StatelessWidget {
final now = new DateTime.now(); final now = new DateTime.now();
final dt = final dt =
DateTime(now.year, now.month, now.day, t.hour, t.minute); DateTime(now.year, now.month, now.day, t.hour, t.minute);
controller.text = "${format.format(dt)}"; controller!.text = "${format.format(dt)}";
} }
}, },
controller: controller, controller: controller,
@@ -77,7 +77,7 @@ class InputTime extends StatelessWidget {
), ),
labelText: labelTextKey == null labelText: labelTextKey == null
? null ? null
: AppTranslations.of(context).text(labelTextKey), : AppTranslations.of(context)!.text(labelTextKey!),
labelStyle: languageModel.isEng labelStyle: languageModel.isEng
? newLabelStyle(color: Colors.black54, fontSize: 20) ? newLabelStyle(color: Colors.black54, fontSize: 20)
: newLabelStyleMM(color: Colors.black54, fontSize: 20), : newLabelStyleMM(color: Colors.black54, fontSize: 20),

View File

@@ -10,13 +10,13 @@ const MAX_INC = 50.0;
const MAX_FEET = 25.0; const MAX_FEET = 25.0;
class LengthPicker extends StatefulWidget { class LengthPicker extends StatefulWidget {
final TextEditingController controller; final TextEditingController? controller;
final String lableKey; final String? lableKey;
final bool isReadOnly; final bool isReadOnly;
final bool displayFeet; final bool displayFeet;
const LengthPicker( const LengthPicker(
{Key key, {Key? key,
this.controller, this.controller,
this.lableKey, this.lableKey,
this.isReadOnly = false, this.isReadOnly = false,
@@ -35,14 +35,14 @@ class _LengthPickerState extends State<LengthPicker> {
super.initState(); super.initState();
if (widget.controller != null) { if (widget.controller != null) {
_setText(); _setText();
widget.controller.addListener(() { widget.controller!.addListener(() {
_setText(); _setText();
}); });
} }
} }
_setText() { _setText() {
double v = double.parse(widget.controller.text, (s) => 0); double v = double.parse(widget.controller!.text, (s) => 0);
int _v = v.toInt(); int _v = v.toInt();
int f = (v / 12).floor(); int f = (v / 12).floor();
@@ -72,8 +72,8 @@ class _LengthPickerState extends State<LengthPicker> {
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return LengthPickerDialog( return LengthPickerDialog(
controller: widget.controller, controller: widget.controller!,
labelKey: widget.lableKey, labelKey: widget.lableKey!,
displayFeet: widget.displayFeet, displayFeet: widget.displayFeet,
); );
}, },
@@ -82,12 +82,12 @@ class _LengthPickerState extends State<LengthPicker> {
} }
class LengthPickerDialog extends StatefulWidget { class LengthPickerDialog extends StatefulWidget {
final TextEditingController controller; final TextEditingController? controller;
final String labelKey; final String? labelKey;
final bool displayFeet; final bool? displayFeet;
const LengthPickerDialog( const LengthPickerDialog(
{Key key, this.controller, this.labelKey, this.displayFeet}) {Key? key, this.controller, this.labelKey, this.displayFeet})
: super(key: key); : super(key: key);
@override @override
@@ -95,8 +95,8 @@ class LengthPickerDialog extends StatefulWidget {
} }
class _LengthPickerDialogState extends State<LengthPickerDialog> { class _LengthPickerDialogState extends State<LengthPickerDialog> {
int _valueFeet; late int _valueFeet;
int _valueInc; late int _valueInc;
TextEditingController inchInputController = TextEditingController(); TextEditingController inchInputController = TextEditingController();
TextEditingController feetInputController = TextEditingController(); TextEditingController feetInputController = TextEditingController();
final _focusNode = FocusNode(); final _focusNode = FocusNode();
@@ -107,9 +107,9 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
_valueFeet = 0; _valueFeet = 0;
_valueInc = 0; _valueInc = 0;
if (widget.controller != null) { if (widget.controller != null) {
double v = double.parse(widget.controller.text, (s) => 0); double v = double.parse(widget.controller!.text, (s) => 0);
_valueFeet = (v / 12).floor(); _valueFeet = (v / 12).floor();
_valueInc = widget.displayFeet ? (v % 12).toInt() : v.toInt(); _valueInc = widget.displayFeet! ? (v % 12).toInt() : v.toInt();
inchInputController.text = _valueInc.toString(); inchInputController.text = _valueInc.toString();
feetInputController.text = _valueFeet.toString(); feetInputController.text = _valueFeet.toString();
} }
@@ -144,7 +144,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
borderSide: BorderSide(color: primaryColor, width: 1.0), borderSide: BorderSide(color: primaryColor, width: 1.0),
), ),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[400], width: 1.0), borderSide: BorderSide(color: Colors.grey.shade400, width: 1.0),
), ),
), ),
), ),
@@ -196,7 +196,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
borderSide: BorderSide(color: primaryColor, width: 1.0), borderSide: BorderSide(color: primaryColor, width: 1.0),
), ),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[400], width: 1.0), borderSide: BorderSide(color: Colors.grey.shade400, width: 1.0),
), ),
), ),
), ),
@@ -233,14 +233,14 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
title: Center( title: Center(
child: LocalText( child: LocalText(
context, context,
widget.labelKey, widget.labelKey!,
color: primaryColor, color: primaryColor,
fontSize: 16, fontSize: 16,
)), )),
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: widget.displayFeet children: widget.displayFeet!
? [ ? [
Container(width: 100, child: feetBox), Container(width: 100, child: feetBox),
Container(width: 100, child: inchBox), Container(width: 100, child: inchBox),
@@ -252,7 +252,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
SizedBox( SizedBox(
height: 10, height: 10,
), ),
widget.displayFeet widget.displayFeet!
? Column( ? Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@@ -295,11 +295,11 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
), ),
Slider( Slider(
activeColor: primaryColor, activeColor: primaryColor,
value: _valueInc.toDouble() > (widget.displayFeet ? 11 : MAX_INC) value: _valueInc.toDouble() > (widget.displayFeet! ? 11 : MAX_INC)
? 0 ? 0
: _valueInc.toDouble(), : _valueInc.toDouble(),
min: 0, min: 0,
max: widget.displayFeet ? 11 : MAX_INC, max: widget.displayFeet! ? 11 : MAX_INC,
divisions: 100, divisions: 100,
label: (_valueInc ?? 0).round().toString(), label: (_valueInc ?? 0).round().toString(),
onChanged: (double v) { onChanged: (double v) {
@@ -318,10 +318,10 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
}); });
int _v = _valueInc.round() + _valueFeet.round() * 12; int _v = _valueInc.round() + _valueFeet.round() * 12;
if (widget.controller != null) { if (widget.controller != null) {
widget.controller.text = _v.toString(); widget.controller!.text = _v.toString();
} }
feetInputController.text = feetInputController.text =
widget.displayFeet ? _valueFeet.round().toString() : _v.toString(); widget.displayFeet! ? _valueFeet.round().toString() : _v.toString();
} }
_updateInc(double v) { _updateInc(double v) {
@@ -330,8 +330,8 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
}); });
int _v = _valueInc.round() + _valueFeet.round() * 12; int _v = _valueInc.round() + _valueFeet.round() * 12;
if (widget.controller != null) { if (widget.controller != null) {
widget.controller.text = widget.controller!.text =
widget.displayFeet ? _v.toString() : _valueInc.toString(); widget.displayFeet! ? _v.toString() : _valueInc.toString();
} }
inchInputController.text = _valueInc.toString(); inchInputController.text = _valueInc.toString();
} }
@@ -343,8 +343,8 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
}); });
int _v = _valueInc.round() + _valueFeet.round() * 12; int _v = _valueInc.round() + _valueFeet.round() * 12;
if (widget.controller != null) { if (widget.controller != null) {
widget.controller.text = widget.controller!.text =
widget.displayFeet ? _v.toString() : _valueInc.toString(); widget.displayFeet! ? _v.toString() : _valueInc.toString();
} }
} }
@@ -355,7 +355,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
}); });
int _v = _valueInc.round() + _valueFeet.round() * 12; int _v = _valueInc.round() + _valueFeet.round() * 12;
if (widget.controller != null) { if (widget.controller != null) {
widget.controller.text = _v.toString(); widget.controller!.text = _v.toString();
} }
} }

View File

@@ -6,13 +6,13 @@ import 'package:flutter/material.dart';
import 'callbacks.dart'; import 'callbacks.dart';
class LocalButton extends StatelessWidget { class LocalButton extends StatelessWidget {
final CallBack callBack; final CallBack? callBack;
final IconData iconData; final IconData? iconData;
final String textKey; final String? textKey;
final Color color; final Color? color;
const LocalButton( const LocalButton(
{Key key, {Key? key,
this.callBack, this.callBack,
this.iconData, this.iconData,
this.textKey, this.textKey,
@@ -33,7 +33,7 @@ class LocalButton extends StatelessWidget {
minWidth: 900.0, minWidth: 900.0,
height: 100.0, height: 100.0,
child: FlatButton( child: FlatButton(
onPressed: callBack == null ? null : () => callBack(), onPressed: callBack == null ? null : () => callBack!(),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@@ -48,7 +48,7 @@ class LocalButton extends StatelessWidget {
), ),
LocalText( LocalText(
context, context,
textKey, textKey!,
color: Colors.white, color: Colors.white,
fontSize: 16, fontSize: 16,
), ),

View File

@@ -5,15 +5,15 @@ import 'package:flutter/material.dart';
import 'local_text.dart'; import 'local_text.dart';
class LocalDropdown<T> extends StatelessWidget { class LocalDropdown<T> extends StatelessWidget {
final Function(T) callback; final Function(T)? callback;
final IconData iconData; final IconData? iconData;
final T selectedValue; final T? selectedValue;
final List<T> values; final List<T>? values;
final Function(T) display; final Function(T)? display;
final String labelKey; final String? labelKey;
const LocalDropdown( const LocalDropdown(
{Key key, {Key? key,
this.callback, this.callback,
this.iconData, this.iconData,
this.selectedValue, this.selectedValue,
@@ -40,7 +40,7 @@ class LocalDropdown<T> extends StatelessWidget {
padding: const EdgeInsets.only(right: 18.0), padding: const EdgeInsets.only(right: 18.0),
child: LocalText( child: LocalText(
context, context,
labelKey, labelKey!,
color: Colors.black54, color: Colors.black54,
fontSize: 16, fontSize: 16,
), ),
@@ -53,20 +53,20 @@ class LocalDropdown<T> extends StatelessWidget {
height: 1, height: 1,
color: Colors.grey, color: Colors.grey,
), ),
onChanged: (T newValue) { onChanged: (T? newValue) {
callback(newValue); callback!(newValue!);
}, },
isExpanded: true, isExpanded: true,
items: values == null items: values == null
? [] ? []
: values.map<DropdownMenuItem<T>>((T value) { : values!.map<DropdownMenuItem<T>>((T value) {
return DropdownMenuItem<T>( return DropdownMenuItem<T>(
value: value, value: value,
child: Text( child: Text(
value == null value == null
? "" ? ""
: display != null : display != null
? display(value) ? display!(value)
: value.toString(), : value.toString(),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: TextStyle(color: primaryColor)), style: TextStyle(color: primaryColor)),

View File

@@ -7,15 +7,15 @@ import 'local_popupmenu.dart';
typedef PopupMenuCallback = Function(LocalPopupMenu popupMenu); typedef PopupMenuCallback = Function(LocalPopupMenu popupMenu);
class LocalPopupMenuButton extends StatefulWidget { class LocalPopupMenuButton extends StatefulWidget {
final PopupMenuCallback popupMenuCallback; final PopupMenuCallback? popupMenuCallback;
final List<LocalPopupMenu> popmenus; final List<LocalPopupMenu>? popmenus;
final bool multiSelect; final bool multiSelect;
final bool selectable; final bool selectable;
final IconData buttonIcon; final IconData? buttonIcon;
final Color buttonColor; final Color buttonColor;
const LocalPopupMenuButton( const LocalPopupMenuButton(
{Key key, {Key? key,
this.popupMenuCallback, this.popupMenuCallback,
this.popmenus, this.popmenus,
this.buttonIcon, this.buttonIcon,
@@ -29,11 +29,11 @@ class LocalPopupMenuButton extends StatefulWidget {
} }
class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> { class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
List<LocalPopupMenu> popmenus; late List<LocalPopupMenu> popmenus;
@override @override
void initState() { void initState() {
popmenus = widget.popmenus; popmenus = widget.popmenus!;
super.initState(); super.initState();
} }
@@ -64,7 +64,7 @@ class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
} }
} }
if (selected.enabled && widget.popupMenuCallback != null) if (selected.enabled && widget.popupMenuCallback != null)
widget.popupMenuCallback(selected); widget.popupMenuCallback!(selected);
}, },
icon: Container( icon: Container(
width: 30, width: 30,

View File

@@ -1,11 +1,11 @@
class LocalPopupMenu { class LocalPopupMenu {
int id; int id;
String textKey; String? textKey;
bool selected; bool selected;
bool highlight; bool highlight;
bool enabled; bool enabled;
LocalPopupMenu( LocalPopupMenu(
{this.id, {required this.id,
this.textKey, this.textKey,
this.selected = false, this.selected = false,
this.highlight = false, this.highlight = false,

View File

@@ -3,15 +3,15 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class LocalRadioButtons<T> extends StatelessWidget { class LocalRadioButtons<T> extends StatelessWidget {
final Function(T) callback; final Function(T)? callback;
final IconData iconData; final IconData? iconData;
final T selectedValue; final T? selectedValue;
final List<T> values; final List<T>? values;
final bool readOnly; final bool readOnly;
final bool hideUnselected; final bool hideUnselected;
const LocalRadioButtons( const LocalRadioButtons(
{Key key, {Key? key,
this.callback, this.callback,
this.iconData, this.iconData,
this.selectedValue, this.selectedValue,
@@ -26,19 +26,19 @@ class LocalRadioButtons<T> extends StatelessWidget {
} }
List<Widget> getChildren() { List<Widget> getChildren() {
return values return values!
.toList() .toList()
.map((e) => SizedBox( .map((e) => SizedBox(
height: 30, height: 30,
child: InkWell( child: InkWell(
onTap: () => callback(e), onTap: () => callback!(e),
child: Row(children: <Widget>[ child: Row(children: <Widget>[
Radio<T>( Radio<T>(
activeColor: primaryColor, activeColor: primaryColor,
groupValue: selectedValue, groupValue: selectedValue,
value: e, value: e,
onChanged: (T value) { onChanged: (T? value) {
callback(value); callback!(value!);
}, },
), ),
Text(e.toString()), Text(e.toString()),
@@ -48,7 +48,7 @@ class LocalRadioButtons<T> extends StatelessWidget {
} }
List<Widget> getReadonlyChildren() { List<Widget> getReadonlyChildren() {
return values return values!
.toList() .toList()
.map((e) => hideUnselected && e == selectedValue .map((e) => hideUnselected && e == selectedValue
? SizedBox( ? SizedBox(

View File

@@ -7,26 +7,26 @@ import 'package:fcs/helpers/theme.dart';
class LocalText extends Text { class LocalText extends Text {
final BuildContext context; final BuildContext context;
LocalText(this.context, String translationKey, LocalText(this.context, String translationKey,
{Color color, {Color? color,
double fontSize, double? fontSize,
FontWeight fontWeight, FontWeight? fontWeight,
List<String> translationVariables, List<String>? translationVariables,
String text, String? text,
bool underline = false}) bool underline = false})
: super( : super(
text ?? text ??
AppTranslations.of(context).text(translationKey, AppTranslations.of(context)!.text(translationKey,
translationVariables: translationVariables), translationVariables: translationVariables),
style: Provider.of<LanguageModel>(context, listen: false).isEng style: Provider.of<LanguageModel>(context, listen: false).isEng
? newLabelStyle( ? newLabelStyle(
color: color, color: color!,
fontSize: fontSize, fontSize: fontSize!,
fontWeight: fontWeight, fontWeight: fontWeight!,
underline: underline) underline: underline)
: newLabelStyleMM( : newLabelStyleMM(
color: color, color: color!,
fontSize: fontSize, fontSize: fontSize!,
fontWeight: fontWeight, fontWeight: fontWeight!,
underline: underline)); underline: underline));
} }
@@ -35,10 +35,10 @@ class LocalLargeTitle extends Text {
LocalLargeTitle( LocalLargeTitle(
this.context, this.context,
String translationKey, { String translationKey, {
Color color, Color? color,
List<String> translationVariables, List<String>? translationVariables,
}) : super( }) : super(
AppTranslations.of(context).text(translationKey, AppTranslations.of(context)!.text(translationKey,
translationVariables: translationVariables), translationVariables: translationVariables),
style: Provider.of<LanguageModel>(context).isEng style: Provider.of<LanguageModel>(context).isEng
? TextStyle(color: color) ? TextStyle(color: color)
@@ -48,7 +48,7 @@ class LocalLargeTitle extends Text {
class TextLocalStyle extends Text { class TextLocalStyle extends Text {
final BuildContext context; final BuildContext context;
TextLocalStyle(this.context, String text, TextLocalStyle(this.context, String text,
{Color color, double fontSize, FontWeight fontWeight}) {Color? color, double? fontSize, FontWeight? fontWeight})
: super(text, : super(text,
style: Provider.of<LanguageModel>(context).isEng style: Provider.of<LanguageModel>(context).isEng
? TextStyle( ? TextStyle(

View File

@@ -4,10 +4,10 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class LocalTitle extends StatelessWidget { class LocalTitle extends StatelessWidget {
final String textKey; final String? textKey;
final Widget trailing; final Widget? trailing;
const LocalTitle({Key key, this.textKey, this.trailing}) : super(key: key); const LocalTitle({Key? key, this.textKey, this.trailing}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -20,13 +20,13 @@ class LocalTitle extends StatelessWidget {
children: [ children: [
LocalText( LocalText(
context, context,
textKey, textKey!,
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: primaryColor, color: primaryColor,
), ),
trailing != null ? Spacer() : Container(), trailing != null ? Spacer() : Container(),
trailing != null ? trailing : Container() trailing != null ? trailing! : Container()
], ],
), ),
), ),

View File

@@ -79,16 +79,16 @@ class MultiImgController {
} }
List<File> get getUpdatedFile { List<File> get getUpdatedFile {
List<File> _addfiles = getAddedFile; List<File?> _addfiles = getAddedFile;
this.imageFiles.addAll(_addfiles); this.imageFiles.addAll(_addfiles);
return this.imageFiles; return this.imageFiles;
} }
List<File> get getAddedFile { List<File?> get getAddedFile {
return addedFiles.map((e) => e.file).toList(); return addedFiles.map((e) => e.file).toList();
} }
List<String> get getDeletedUrl { List<String?> get getDeletedUrl {
return removedFiles.map((e) => e.url).toList(); return removedFiles.map((e) => e.url).toList();
} }
} }

View File

@@ -8,7 +8,7 @@ import 'package:fcs/pages/widgets/show_img.dart';
import 'package:fcs/pages/widgets/show_multiple_img.dart'; import 'package:fcs/pages/widgets/show_multiple_img.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
@@ -18,13 +18,13 @@ import 'multi_img_controller.dart';
typedef OnFile = void Function(File); typedef OnFile = void Function(File);
class MultiImageFile extends StatefulWidget { class MultiImageFile extends StatefulWidget {
final String title; final String? title;
final bool enabled; final bool enabled;
final ImageSource imageSource; final ImageSource imageSource;
final MultiImgController controller; final MultiImgController? controller;
const MultiImageFile( const MultiImageFile(
{Key key, {Key? key,
this.title, this.title,
this.enabled = true, this.enabled = true,
this.controller, this.controller,
@@ -39,10 +39,10 @@ class _MultiImageFileState extends State<MultiImageFile> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
fileContainers = widget.controller.fileContainers; fileContainers = widget.controller!.fileContainers;
widget.controller.onChange(() { widget.controller!.onChange(() {
setState(() { setState(() {
this.fileContainers = widget.controller.fileContainers; this.fileContainers = widget.controller!.fileContainers;
}); });
}); });
} }
@@ -133,7 +133,7 @@ class _MultiImageFileState extends State<MultiImageFile> {
fit: BoxFit.cover, fit: BoxFit.cover,
width: 50, width: 50,
height: 50, height: 50,
imageUrl: fileContainers[index].url, imageUrl: fileContainers[index].url!,
placeholder: (context, url) => Column( placeholder: (context, url) => Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -150,7 +150,7 @@ class _MultiImageFileState extends State<MultiImageFile> {
: FittedBox( : FittedBox(
fit: BoxFit.cover, fit: BoxFit.cover,
child: Image.file( child: Image.file(
fileContainers[index].file, fileContainers[index].file!,
), ),
), ),
), ),
@@ -189,13 +189,13 @@ class _MultiImageFileState extends State<MultiImageFile> {
fileContainer.file = selectedFile; fileContainer.file = selectedFile;
setState(() { setState(() {
fileContainers.add(fileContainer); fileContainers.add(fileContainer);
widget.controller.addFile = fileContainer; widget.controller!.addFile = fileContainer;
}); });
} }
_fileRemove(DisplayImageSource fileContainer) { _fileRemove(DisplayImageSource fileContainer) {
setState(() { setState(() {
widget.controller.removeFile = fileContainer; widget.controller!.removeFile = fileContainer;
}); });
} }
@@ -232,11 +232,11 @@ class _MultiImageFileState extends State<MultiImageFile> {
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => ShowImage( builder: (context) => ShowImage(
imageFile: fileContainer.file, imageFile: fileContainer.file!,
url: fileContainer.file == null url: fileContainer.file == null
? fileContainer.url ? fileContainer.url!
: null, : '',
fileName: widget.title)), fileName: widget.title!)),
) )
}, },
child: Chip( child: Chip(
@@ -249,7 +249,7 @@ class _MultiImageFileState extends State<MultiImageFile> {
deleteIcon: Icon( deleteIcon: Icon(
Icons.close, Icons.close,
), ),
label: Text(widget.title + " - ${index + 1}"), label: Text("${widget.title}" + " - ${index + 1}"),
), ),
), ),
), ),
@@ -308,7 +308,7 @@ class _MultiImageFileState extends State<MultiImageFile> {
); );
} }
Widget actionIcon({OnTap onTap, Color color, IconData iconData}) { Widget actionIcon({OnTap? onTap, Color? color, IconData? iconData}) {
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
child: ClipOval( child: ClipOval(

View File

@@ -5,9 +5,9 @@ import 'package:fcs/helpers/theme.dart' as theme;
class NumberCell extends StatelessWidget { class NumberCell extends StatelessWidget {
final int number; final int number;
final numberFormatter; final numberFormatter;
final TextStyle textStyle; final TextStyle? textStyle;
NumberCell(this.number, {Key key, this.textStyle}) NumberCell(this.number, {Key? key, this.textStyle})
: numberFormatter = new NumberFormat("#,###"), : numberFormatter = new NumberFormat("#,###"),
super(key: key); super(key: key);

View File

@@ -6,14 +6,14 @@ import 'package:provider/provider.dart';
class OfflineRedirect extends StatefulWidget { class OfflineRedirect extends StatefulWidget {
final Widget child; final Widget child;
OfflineRedirect({@required this.child}); OfflineRedirect({required this.child});
@override @override
_OfflineRedirectState createState() => _OfflineRedirectState(); _OfflineRedirectState createState() => _OfflineRedirectState();
} }
class _OfflineRedirectState extends State<OfflineRedirect> { class _OfflineRedirectState extends State<OfflineRedirect> {
Timer offlineTimer; Timer? offlineTimer;
@override @override
void initState() { void initState() {
@@ -27,7 +27,7 @@ class _OfflineRedirectState extends State<OfflineRedirect> {
} }
_startOfflineTimer() async { _startOfflineTimer() async {
if (offlineTimer != null && offlineTimer.isActive) return; if (offlineTimer != null && offlineTimer!.isActive) return;
var _duration = new Duration(milliseconds: 500); var _duration = new Duration(milliseconds: 500);
this.offlineTimer = new Timer.periodic(_duration, offlineNav); this.offlineTimer = new Timer.periodic(_duration, offlineNav);
} }
@@ -41,7 +41,7 @@ class _OfflineRedirectState extends State<OfflineRedirect> {
} }
void dispose() { void dispose() {
offlineTimer.cancel(); offlineTimer!.cancel();
super.dispose(); super.dispose();
} }

View File

@@ -11,10 +11,10 @@ import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:share/share.dart'; import 'package:share/share.dart';
class PDFScreen extends StatefulWidget { class PDFScreen extends StatefulWidget {
final String title; final String? title;
final String url; final String? url;
PDFScreen({Key key, this.url, this.title}) : super(key: key); PDFScreen({Key? key, this.url, this.title}) : super(key: key);
_PDFScreenState createState() => _PDFScreenState(); _PDFScreenState createState() => _PDFScreenState();
} }
@@ -33,10 +33,10 @@ class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
download(); download();
} }
File file; File? file;
Future<void> download() async { Future<void> download() async {
try { try {
File f = await PdfCacheMgr.pdfs.getSingleFile(widget.url); File f = await PdfCacheMgr.pdfs.getSingleFile(widget.url!);
setState(() { setState(() {
file = f; file = f;
}); });
@@ -89,23 +89,23 @@ class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
fitPolicy: FitPolicy.BOTH, fitPolicy: FitPolicy.BOTH,
preventLinkNavigation: preventLinkNavigation:
false, // if set to true the link is handled in flutter false, // if set to true the link is handled in flutter
onRender: (_pages) { onRender: (int?_pages) {
print(('pages => $pages')); print(('pages => $pages'));
setState(() { setState(() {
pages = _pages; pages = _pages!;
isReady = true; isReady = true;
}); });
}, },
onViewCreated: (PDFViewController pdfViewController) { onViewCreated: (PDFViewController pdfViewController) {
_controller.complete(pdfViewController); _controller.complete(pdfViewController);
}, },
onLinkHandler: (String uri) { onLinkHandler: (String? uri) {
print('goto uri: $uri'); print('goto uri: $uri');
}, },
onPageChanged: (int page, int total) { onPageChanged: (int? page, int? total) {
print('page change: $page/$total'); print('page change: $page/$total');
setState(() { setState(() {
currentPage = page; currentPage = page!;
}); });
}, },
), ),
@@ -116,8 +116,8 @@ class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
} }
_share() async { _share() async {
final RenderBox box = context.findRenderObject(); final RenderBox box = context.findRenderObject() as RenderBox;
await Share.shareFiles([file.path], await Share.shareFiles([file!.path],
mimeTypes: ["application/pdf"], mimeTypes: ["application/pdf"],
subject: "File", subject: "File",
sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size); sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size);

View File

@@ -1,7 +1,7 @@
class PopupMenu { class PopupMenu {
int id; int id;
String status; String status;
PopupMenu({this.id, this.status}); PopupMenu({required this.id, required this.status});
} }
List<PopupMenu> menuPopup = <PopupMenu>[ List<PopupMenu> menuPopup = <PopupMenu>[

View File

@@ -4,7 +4,7 @@ import 'package:provider/provider.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
class LocalProgress extends Progress { class LocalProgress extends Progress {
LocalProgress({bool inAsyncCall, Widget child}) LocalProgress({required bool inAsyncCall, required Widget child})
: super( : super(
inAsyncCall: inAsyncCall, inAsyncCall: inAsyncCall,
child: child, child: child,

View File

@@ -6,12 +6,12 @@ import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view.dart';
class ShowImage extends StatefulWidget { class ShowImage extends StatefulWidget {
final String url; final String? url;
final File imageFile; final File? imageFile;
final String fileName; final String? fileName;
final String localImage; final String? localImage;
const ShowImage( const ShowImage(
{Key key, this.imageFile, this.fileName, this.url, this.localImage}) {Key? key, this.imageFile, this.fileName, this.url, this.localImage})
: super(key: key); : super(key: key);
@override @override
_ShowImageState createState() => _ShowImageState(); _ShowImageState createState() => _ShowImageState();
@@ -20,6 +20,13 @@ class ShowImage extends StatefulWidget {
class _ShowImageState extends State<ShowImage> { class _ShowImageState extends State<ShowImage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ImageProvider<Object>? p;
if (widget.imageFile != null) {
p = FileImage(widget.imageFile!);
} else {
p = AssetImage(widget.localImage!);
}
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
leading: new IconButton( leading: new IconButton(
@@ -35,11 +42,7 @@ class _ShowImageState extends State<ShowImage> {
backgroundDecoration: const BoxDecoration( backgroundDecoration: const BoxDecoration(
color: primaryColor, color: primaryColor,
), ),
imageProvider: widget.url != null imageProvider: widget.url != null ? NetworkImage(widget.url!) : p,
? NetworkImage(widget.url)
: widget.imageFile != null
? FileImage(widget.imageFile)
: AssetImage(widget.localImage),
minScale: PhotoViewComputedScale.contained * 1)), minScale: PhotoViewComputedScale.contained * 1)),
); );
} }

View File

@@ -43,7 +43,7 @@ dependencies:
permission_handler: ^8.1.4+2 permission_handler: ^8.1.4+2
country_code_picker: ^2.0.2 country_code_picker: ^2.0.2
pin_input_text_field: ^4.1.0 pin_input_text_field: ^4.1.0
# flutter_icons: ^1.1.0 flutter_icons_null_safety: ^1.1.0
country_icons: ^2.0.2 country_icons: ^2.0.2
timeline_list: ^0.0.5 timeline_list: ^0.0.5
# barcode_scan: ^2.0.2 # barcode_scan: ^2.0.2