Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -9,7 +9,7 @@ import 'package:fcs/domain/entities/user.dart';
|
||||
import 'package:fcs/domain/exceiptions/signin_exception.dart';
|
||||
import 'package:fcs/helpers/api_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';
|
||||
|
||||
class AuthFb {
|
||||
@@ -18,17 +18,17 @@ class AuthFb {
|
||||
static final AuthFb instance = AuthFb._();
|
||||
AuthFb._();
|
||||
|
||||
StreamController<User> controller;
|
||||
static final FirebaseAuth _fb = FirebaseAuth.instance;
|
||||
static String _verificationId;
|
||||
late StreamController<User?> controller;
|
||||
static final fb.FirebaseAuth _fb = fb.FirebaseAuth.instance;
|
||||
static String _verificationId = '';
|
||||
|
||||
Future<fcs.AuthResult> sendSmsCodeToPhoneNumber(String phoneNumber) {
|
||||
Completer<fcs.AuthResult> completer = Completer();
|
||||
bool codeSentCompleted = false;
|
||||
|
||||
final PhoneVerificationCompleted verificationCompleted =
|
||||
(AuthCredential credential) async {
|
||||
AuthResult _authResult;
|
||||
final fb.PhoneVerificationCompleted verificationCompleted =
|
||||
(fb.AuthCredential credential) async {
|
||||
fb.UserCredential _authResult;
|
||||
try {
|
||||
_authResult = await _fb.signInWithCredential(credential);
|
||||
print("PhoneVerificationCompleted :$_authResult");
|
||||
@@ -48,23 +48,23 @@ class AuthFb {
|
||||
'Inside _sendCodeToPhoneNumber: signInWithPhoneNumber auto succeeded: ${_authResult.user}');
|
||||
};
|
||||
|
||||
final PhoneVerificationFailed verificationFailed =
|
||||
(AuthException authException) async {
|
||||
final fb.PhoneVerificationFailed verificationFailed =
|
||||
(fb.FirebaseAuthException authException) async {
|
||||
print(
|
||||
'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}');
|
||||
completer.completeError(SigninException(
|
||||
"Phone number verification failed:${authException.message}"));
|
||||
};
|
||||
|
||||
final PhoneCodeSent codeSent =
|
||||
(String verificationId, [int forceResendingToken]) async {
|
||||
final fb.PhoneCodeSent codeSent =
|
||||
(String verificationId, [int? forceResendingToken]) async {
|
||||
_verificationId = verificationId;
|
||||
print("codeSent " + phoneNumber);
|
||||
codeSentCompleted = true;
|
||||
completer.complete(fcs.AuthResult(authStatus: AuthStatus.SMS_SENT));
|
||||
};
|
||||
|
||||
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
|
||||
final fb.PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
|
||||
(String verificationId) {
|
||||
print("codeAutoRetrievalTimeout $verificationId ");
|
||||
|
||||
@@ -89,11 +89,11 @@ class AuthFb {
|
||||
|
||||
Future<fcs.AuthResult> signInWithPhoneNumber(String smsCode) async {
|
||||
try {
|
||||
final AuthCredential credential = PhoneAuthProvider.getCredential(
|
||||
verificationId: _verificationId,
|
||||
smsCode: smsCode,
|
||||
);
|
||||
AuthResult _authResult = await _fb.signInWithCredential(credential);
|
||||
final fb.AuthCredential credential = fb.PhoneAuthProvider.credential(
|
||||
verificationId: _verificationId, smsCode: smsCode);
|
||||
|
||||
fb.UserCredential _authResult =
|
||||
await _fb.signInWithCredential(credential);
|
||||
if (_authResult == null) {
|
||||
throw SigninException("Sigin error!");
|
||||
}
|
||||
@@ -105,19 +105,21 @@ class AuthFb {
|
||||
}
|
||||
|
||||
Future<void> signout() async {
|
||||
if (userListener != null) await userListener.cancel();
|
||||
if (userListener != null) await userListener!.cancel();
|
||||
return _fb.signOut();
|
||||
}
|
||||
|
||||
Future<void> _addUserToStream({bool refreshIdToken = false}) async {
|
||||
FirebaseUser firebaseUser = await _fb.currentUser();
|
||||
fb.User? firebaseUser = _fb.currentUser;
|
||||
if (firebaseUser == null) return null;
|
||||
Map claims = await getClaims(refreshIdToken: refreshIdToken);
|
||||
Map<dynamic, dynamic>? claims =
|
||||
await getClaims(refreshIdToken: refreshIdToken);
|
||||
|
||||
log.info("Claims:$claims");
|
||||
if (claims == null) return;
|
||||
|
||||
String cid = claims["cid"];
|
||||
User user;
|
||||
User? user;
|
||||
if (cid != null && cid != "") {
|
||||
user = await _getUserFromFirestore(cid);
|
||||
}
|
||||
@@ -136,20 +138,20 @@ class AuthFb {
|
||||
controller.add(user);
|
||||
}
|
||||
|
||||
Future<User> _getUserFromFirestore(String userID) async {
|
||||
DocumentSnapshot snap = await Firestore.instance
|
||||
Future<User?> _getUserFromFirestore(String userID) async {
|
||||
DocumentSnapshot snap = await FirebaseFirestore.instance
|
||||
.collection(user_collection)
|
||||
.document(userID)
|
||||
.doc(userID)
|
||||
.get();
|
||||
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 null;
|
||||
}
|
||||
|
||||
Future<bool> isLogin() async {
|
||||
final FirebaseUser firebaseUser = await _fb.currentUser();
|
||||
final fb.User? firebaseUser = _fb.currentUser;
|
||||
return Future.value(firebaseUser != null);
|
||||
}
|
||||
|
||||
@@ -193,48 +195,50 @@ class AuthFb {
|
||||
}
|
||||
|
||||
Stream<Setting> settings() async* {
|
||||
Stream<DocumentSnapshot> snapshot = Firestore.instance
|
||||
Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
|
||||
.collection(config_collection)
|
||||
.document(setting_doc_id)
|
||||
.doc(setting_doc_id)
|
||||
.snapshots();
|
||||
|
||||
await for (var snap in snapshot) {
|
||||
Setting setting = Setting.fromMap(snap.data);
|
||||
Setting setting = Setting.fromMap(snap.data() as Map<String, dynamic>);
|
||||
yield setting;
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> _getCurrentUserID() async {
|
||||
FirebaseUser firebaseUser = await _fb.currentUser();
|
||||
Future<String?> _getCurrentUserID() async {
|
||||
fb.User? firebaseUser = _fb.currentUser;
|
||||
if (firebaseUser == null) return null;
|
||||
Map claims = await getClaims();
|
||||
Map? claims = await getClaims();
|
||||
if (claims == null) return null;
|
||||
String cid = claims["cid"];
|
||||
return cid;
|
||||
}
|
||||
|
||||
Future<void> _startUserListener() async {
|
||||
if (userListener != null) userListener.cancel();
|
||||
String _userID = await _getCurrentUserID();
|
||||
if (userListener != null) userListener!.cancel();
|
||||
String? _userID = await _getCurrentUserID();
|
||||
if (_userID == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Stream<DocumentSnapshot> snapshot = Firestore.instance
|
||||
Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
|
||||
.collection(user_collection)
|
||||
.document(_userID)
|
||||
.doc(_userID)
|
||||
.snapshots();
|
||||
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) {
|
||||
userListener.cancel();
|
||||
userListener?.cancel();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// get privilege from claim
|
||||
IdTokenResult idToken = await firebaseUser.getIdToken(refresh: true);
|
||||
String privileges = idToken.claims["pr"];
|
||||
fb.IdTokenResult idToken = await firebaseUser.getIdTokenResult(true);
|
||||
|
||||
String privileges = idToken.claims?["pr"] ?? '';
|
||||
if (privileges != null && privileges != "") {
|
||||
user.privileges = privileges.split(":").toList();
|
||||
}
|
||||
@@ -245,13 +249,13 @@ class AuthFb {
|
||||
});
|
||||
}
|
||||
|
||||
StreamSubscription<DocumentSnapshot> userListener;
|
||||
Stream<User> user() {
|
||||
StreamSubscription<DocumentSnapshot>? userListener;
|
||||
Stream<User?> user() {
|
||||
// ignore: close_sinks
|
||||
StreamSubscription<FirebaseUser> authListener;
|
||||
StreamSubscription<fb.User?>? authListener;
|
||||
|
||||
Future<void> _start() async {
|
||||
authListener = _fb.onAuthStateChanged.listen((firebaseUser) async {
|
||||
authListener = _fb.authStateChanges().listen((firebaseUser) {
|
||||
if (firebaseUser == null) {
|
||||
controller.add(null);
|
||||
} else {
|
||||
@@ -263,10 +267,10 @@ class AuthFb {
|
||||
|
||||
void _stop() {
|
||||
if (userListener != null) {
|
||||
userListener.cancel();
|
||||
userListener!.cancel();
|
||||
}
|
||||
if (authListener != null) {
|
||||
authListener.cancel();
|
||||
authListener!.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:fcs/domain/constants.dart';
|
||||
@@ -36,7 +35,7 @@ class CartonDataProvider {
|
||||
}
|
||||
|
||||
Future<List<Carton>> searchCarton(String term) async {
|
||||
if (term == null || term == '') return List();
|
||||
if (term == null || term == '') return [];
|
||||
|
||||
// var bytes = utf8.encode(term);
|
||||
// var base64Str = base64.encode(bytes);
|
||||
@@ -45,7 +44,7 @@ class CartonDataProvider {
|
||||
|
||||
try {
|
||||
String path = "/$cartons_collection";
|
||||
var querySnap = await Firestore.instance
|
||||
var querySnap = await FirebaseFirestore.instance
|
||||
.collection(path)
|
||||
.where("carton_number", isEqualTo: term)
|
||||
.where("carton_type",
|
||||
@@ -53,13 +52,11 @@ class CartonDataProvider {
|
||||
.where("status", isEqualTo: carton_packed_status)
|
||||
.where("is_deleted", isEqualTo: false)
|
||||
.orderBy("user_name")
|
||||
.getDocuments();
|
||||
return querySnap.documents
|
||||
.map((e) => Carton.fromMap(e.data, e.documentID))
|
||||
.toList();
|
||||
.get();
|
||||
return querySnap.docs.map((e) => Carton.fromMap(e.data(), e.id)).toList();
|
||||
} catch (e) {
|
||||
log.warning("carton error:" + e.toString());
|
||||
return null;
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,8 +56,8 @@ class PackageDataProvider {
|
||||
token: await getToken());
|
||||
}
|
||||
|
||||
Future<List<Package>> ftsSearchPackage(String term) async {
|
||||
if (term == null || term == '') return List();
|
||||
Future<List<Package>?> ftsSearchPackage(String term) async {
|
||||
if (term == null || term == '') return [];
|
||||
|
||||
var bytes = utf8.encode(term);
|
||||
var base64Str = base64.encode(bytes);
|
||||
@@ -72,7 +72,7 @@ class PackageDataProvider {
|
||||
"/api/fts/$packages_collection/$escapePackage/$limit", "GET",
|
||||
url: Config.instance.reportURL, token: await getToken());
|
||||
|
||||
if (data == null) return List();
|
||||
if (data == null) return [];
|
||||
|
||||
data.forEach((p) {
|
||||
var package = Package.fromJson(p);
|
||||
@@ -86,7 +86,7 @@ class PackageDataProvider {
|
||||
}
|
||||
|
||||
Future<List<Package>> searchPackage(String term) async {
|
||||
if (term == null || term == '') return List();
|
||||
if (term == null || term == '') return [];
|
||||
|
||||
List<Package> packages = [];
|
||||
|
||||
|
||||
@@ -16,33 +16,33 @@ class RateDataProvider {
|
||||
static final RateDataProvider instance = RateDataProvider._();
|
||||
RateDataProvider._();
|
||||
|
||||
StreamController<Rate> controller;
|
||||
late StreamController<Rate> controller;
|
||||
static Rate _rate = Rate();
|
||||
|
||||
Stream<Rate> _rateStream() async* {
|
||||
Stream<DocumentSnapshot> snapshot = Firestore.instance
|
||||
Stream<DocumentSnapshot> snapshot = FirebaseFirestore.instance
|
||||
.collection(config_collection)
|
||||
.document(rate_doc_id)
|
||||
.doc(rate_doc_id)
|
||||
.snapshots();
|
||||
await for (var snap in snapshot) {
|
||||
Rate rate = Rate.fromMap(snap.data);
|
||||
Rate rate = Rate.fromMap(snap.data() as Map<String, dynamic>);
|
||||
yield rate;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<List<CargoType>> _cargoTypeStream() async* {
|
||||
List<CargoType> cargoTypes = [];
|
||||
Stream<QuerySnapshot> snapshots = Firestore.instance
|
||||
Stream<QuerySnapshot> snapshots = FirebaseFirestore.instance
|
||||
.collection(config_collection)
|
||||
.document(rate_doc_id)
|
||||
.doc(rate_doc_id)
|
||||
.collection(cargo_types_collection)
|
||||
.where("custom_duty", isEqualTo: false)
|
||||
.snapshots();
|
||||
|
||||
await for (var snaps in snapshots) {
|
||||
cargoTypes = [];
|
||||
cargoTypes = snaps.documents.map((snap) {
|
||||
return CargoType.fromMap(snap.data, snap.documentID);
|
||||
cargoTypes = snaps.docs.map((snap) {
|
||||
return CargoType.fromMap(snap.data() as Map<String, dynamic>, snap.id);
|
||||
}).toList();
|
||||
|
||||
yield cargoTypes;
|
||||
@@ -51,17 +51,17 @@ class RateDataProvider {
|
||||
|
||||
Stream<List<CargoType>> _customDutiesStream() async* {
|
||||
List<CargoType> customDuries = [];
|
||||
Stream<QuerySnapshot> snapshots = Firestore.instance
|
||||
Stream<QuerySnapshot> snapshots = FirebaseFirestore.instance
|
||||
.collection(config_collection)
|
||||
.document(rate_doc_id)
|
||||
.doc(rate_doc_id)
|
||||
.collection(cargo_types_collection)
|
||||
.where("custom_duty", isEqualTo: true)
|
||||
.snapshots();
|
||||
|
||||
await for (var snaps in snapshots) {
|
||||
customDuries = [];
|
||||
customDuries = snaps.documents.map((snap) {
|
||||
return CargoType.fromMap(snap.data, snap.documentID);
|
||||
customDuries = snaps.docs.map((snap) {
|
||||
return CargoType.fromMap(snap.data() as Map<String, dynamic>, snap.id);
|
||||
}).toList();
|
||||
yield customDuries;
|
||||
}
|
||||
@@ -69,25 +69,26 @@ class RateDataProvider {
|
||||
|
||||
Stream<List<DiscountByWeight>> _discountByWeightStream() async* {
|
||||
List<DiscountByWeight> discountByWeight = [];
|
||||
Stream<QuerySnapshot> snapshots = Firestore.instance
|
||||
Stream<QuerySnapshot> snapshots = FirebaseFirestore.instance
|
||||
.collection(config_collection)
|
||||
.document(rate_doc_id)
|
||||
.doc(rate_doc_id)
|
||||
.collection(discounts_by_weights_collection)
|
||||
.snapshots();
|
||||
|
||||
await for (var snaps in snapshots) {
|
||||
discountByWeight = [];
|
||||
discountByWeight = snaps.documents.map((snap) {
|
||||
return DiscountByWeight.fromMap(snap.data, snap.documentID);
|
||||
discountByWeight = snaps.docs.map((snap) {
|
||||
return DiscountByWeight.fromMap(
|
||||
snap.data() as Map<String, dynamic>, snap.id);
|
||||
}).toList();
|
||||
yield discountByWeight;
|
||||
}
|
||||
}
|
||||
|
||||
StreamSubscription<Rate> rateListener;
|
||||
StreamSubscription<List<CargoType>> cargoListener;
|
||||
StreamSubscription<List<CargoType>> customListener;
|
||||
StreamSubscription<List<DiscountByWeight>> discountListener;
|
||||
late StreamSubscription<Rate> rateListener;
|
||||
late StreamSubscription<List<CargoType>> cargoListener;
|
||||
late StreamSubscription<List<CargoType>> customListener;
|
||||
late StreamSubscription<List<DiscountByWeight>> discountListener;
|
||||
Stream<Rate> rate() {
|
||||
Future<void> _start() async {
|
||||
rateListener = _rateStream().listen((rate) {
|
||||
|
||||
@@ -37,23 +37,23 @@ class UserDataProvider {
|
||||
payload: {"token": token}, token: await getToken());
|
||||
}
|
||||
|
||||
Future<User> findUser(String phoneNumber) async {
|
||||
QuerySnapshot querySnap = await Firestore.instance
|
||||
Future<User?> findUser(String phoneNumber) async {
|
||||
QuerySnapshot querySnap = await FirebaseFirestore.instance
|
||||
.collection(user_collection)
|
||||
.where("phone_number", isEqualTo: phoneNumber)
|
||||
.limit(1)
|
||||
.getDocuments();
|
||||
.get();
|
||||
|
||||
if (querySnap.documents.length > 0) {
|
||||
var snap = querySnap.documents.first;
|
||||
User user = User.fromMap(snap.data, snap.documentID);
|
||||
if (querySnap.docs.length > 0) {
|
||||
var snap = querySnap.docs.first;
|
||||
User user = User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
|
||||
return user;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<List<User>> searchUser(String term) async {
|
||||
if (term == null || term == '') return List();
|
||||
if (term == null || term == '') return [];
|
||||
|
||||
var bytes = utf8.encode(term);
|
||||
var base64Str = base64.encode(bytes);
|
||||
@@ -68,7 +68,7 @@ class UserDataProvider {
|
||||
"/api/fts/$user_collection/$escapeBuyer/$limit", "GET",
|
||||
url: Config.instance.reportURL, token: await getToken());
|
||||
|
||||
if (data == null) return List();
|
||||
if (data == null) return [];
|
||||
|
||||
data.forEach((buyer) {
|
||||
var user = User.fromJson(buyer);
|
||||
@@ -76,7 +76,7 @@ class UserDataProvider {
|
||||
});
|
||||
} catch (e) {
|
||||
log.warning("buyer error:" + e.toString());
|
||||
return null;
|
||||
// return null;
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@@ -3,17 +3,16 @@ import 'package:fcs/domain/entities/auth_result.dart';
|
||||
import 'package:fcs/domain/entities/connectivity.dart';
|
||||
import 'package:fcs/domain/entities/setting.dart';
|
||||
import 'package:fcs/domain/entities/user.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'auth_service.dart';
|
||||
|
||||
class AuthServiceImp implements AuthService {
|
||||
AuthServiceImp({
|
||||
@required this.authFb,
|
||||
@required this.connectivity,
|
||||
required this.authFb,
|
||||
required this.connectivity,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final AuthFb authFb;
|
||||
|
||||
@override
|
||||
@@ -32,7 +31,7 @@ class AuthServiceImp implements AuthService {
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<User> getUserStream() {
|
||||
Stream<User?> getUserStream() {
|
||||
return authFb.user();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,6 @@ abstract class AuthService {
|
||||
Future<void> updateProfileName(String newUserName);
|
||||
Future<void> updatePreferredCurrency(String currency);
|
||||
Future<bool> hasInvite();
|
||||
Stream<User> getUserStream();
|
||||
Stream<User?> getUserStream();
|
||||
Stream<Setting> getSetting();
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import 'package:fcs/data/provider/carton_data_provider.dart';
|
||||
import 'package:fcs/domain/entities/carton.dart';
|
||||
import 'package:fcs/domain/entities/connectivity.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'carton_service.dart';
|
||||
|
||||
class CartonServiceImp implements CartonService {
|
||||
CartonServiceImp({
|
||||
@required this.cartonDataProvider,
|
||||
@required this.connectivity,
|
||||
required this.cartonDataProvider,
|
||||
required this.connectivity,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final CartonDataProvider cartonDataProvider;
|
||||
|
||||
@override
|
||||
|
||||
@@ -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/payment_method.dart';
|
||||
import 'package:fcs/domain/vo/message.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'common_service.dart';
|
||||
|
||||
class CommonServiceImp implements CommonService {
|
||||
CommonServiceImp({
|
||||
@required this.commonDataProvider,
|
||||
required this.commonDataProvider,
|
||||
});
|
||||
|
||||
final CommonDataProvider commonDataProvider;
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import 'package:fcs/data/provider/delivery_address_data_provider.dart';
|
||||
import 'package:fcs/domain/entities/connectivity.dart';
|
||||
import 'package:fcs/domain/vo/delivery_address.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'delivery_address_service.dart';
|
||||
|
||||
class DeliveryAddressImp implements DeliveryAddressService {
|
||||
DeliveryAddressImp({
|
||||
@required this.connectivity,
|
||||
@required this.deliveryAddressDataProvider,
|
||||
required this.connectivity,
|
||||
required this.deliveryAddressDataProvider,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final DeliveryAddressDataProvider deliveryAddressDataProvider;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import 'package:fcs/data/provider/fcs_shipment_data_provider.dart';
|
||||
import 'package:fcs/domain/entities/connectivity.dart';
|
||||
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'fcs_shipment_service.dart';
|
||||
|
||||
class FcsShipmentServiceImp implements FcsShipmentService {
|
||||
FcsShipmentServiceImp({
|
||||
@required this.connectivity,
|
||||
@required this.shipmentDataProvider,
|
||||
required this.connectivity,
|
||||
required this.shipmentDataProvider,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final FcsShipmentDataProvider shipmentDataProvider;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
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/invoice.dart';
|
||||
import 'package:fcs/domain/entities/payment.dart';
|
||||
import 'package:fcs/domain/entities/shipment.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'invoice_service.dart';
|
||||
|
||||
class InvoiceServiceImp implements InvoiceService {
|
||||
InvoiceServiceImp({
|
||||
@required this.invoiceDataProvider,
|
||||
@required this.connectivity,
|
||||
required this.invoiceDataProvider,
|
||||
required this.connectivity,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final InvoiceDataProvider invoiceDataProvider;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import 'package:fcs/data/provider/package_data_provider.dart';
|
||||
import 'package:fcs/domain/entities/connectivity.dart';
|
||||
import 'package:fcs/domain/entities/package.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package_service.dart';
|
||||
|
||||
class PackageServiceImp implements PackageService {
|
||||
PackageServiceImp({
|
||||
@required this.connectivity,
|
||||
@required this.packageDataProvider,
|
||||
required this.connectivity,
|
||||
required this.packageDataProvider,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final PackageDataProvider packageDataProvider;
|
||||
|
||||
@override
|
||||
@@ -30,7 +29,7 @@ class PackageServiceImp implements PackageService {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<Package>> ftsSearchPackage(String term) {
|
||||
Future<List<Package>?> ftsSearchPackage(String term) {
|
||||
return packageDataProvider.ftsSearchPackage(term);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ abstract class PackageService {
|
||||
Future<void> deleteReceiving(Package package);
|
||||
Future<void> updateProcessing(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<void> changeDeliveryAddress(String packageID, String deliveryID);
|
||||
Future<void> packageReturn(String packageID);
|
||||
|
||||
@@ -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/custom_duty.dart';
|
||||
import 'package:fcs/domain/entities/rate.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'rate_service.dart';
|
||||
|
||||
class RateServiceImp implements RateService {
|
||||
RateServiceImp({
|
||||
@required this.rateDataProvider,
|
||||
@required this.connectivity,
|
||||
required this.rateDataProvider,
|
||||
required this.connectivity,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final RateDataProvider rateDataProvider;
|
||||
|
||||
@override
|
||||
|
||||
@@ -35,17 +35,18 @@ import 'user_service.dart';
|
||||
class Services {
|
||||
static final Services instance = Services._();
|
||||
|
||||
AuthService _authService;
|
||||
UserService _userService;
|
||||
PackageService _packageService;
|
||||
MessagingService _messagingService;
|
||||
CommonService _commonService;
|
||||
FcsShipmentService _fcsShipmentService;
|
||||
DeliveryAddressService _deliveryAddressService;
|
||||
RateService _rateService;
|
||||
ShipmentService _shipmentService;
|
||||
CartonService _cartonService;
|
||||
InvoiceService _invoiceService;
|
||||
late AuthService _authService;
|
||||
late UserService _userService;
|
||||
late PackageService _packageService;
|
||||
late MessagingService _messagingService;
|
||||
late CommonService _commonService;
|
||||
late FcsShipmentService _fcsShipmentService;
|
||||
late DeliveryAddressService _deliveryAddressService;
|
||||
late RateService _rateService;
|
||||
late ShipmentService _shipmentService;
|
||||
late CartonService _cartonService;
|
||||
late InvoiceService _invoiceService;
|
||||
|
||||
Services._() {
|
||||
_authService = AuthServiceImp(
|
||||
authFb: AuthFb.instance,
|
||||
|
||||
@@ -2,15 +2,14 @@ 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/shipment.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ShipmentServiceImp implements ShipmentService {
|
||||
ShipmentServiceImp({
|
||||
@required this.shipmentDataProvider,
|
||||
@required this.connectivity,
|
||||
required this.shipmentDataProvider,
|
||||
required this.connectivity,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final ShipmentDataProvider shipmentDataProvider;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import 'package:fcs/data/provider/user_data_provider.dart';
|
||||
import 'package:fcs/domain/entities/connectivity.dart';
|
||||
import 'package:fcs/domain/entities/user.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'user_service.dart';
|
||||
|
||||
class UserServiceImp implements UserService {
|
||||
UserServiceImp({
|
||||
@required this.connectivity,
|
||||
@required this.userDataProvider,
|
||||
required this.connectivity,
|
||||
required this.userDataProvider,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final Connectivity? connectivity;
|
||||
final UserDataProvider userDataProvider;
|
||||
|
||||
@override
|
||||
@@ -30,7 +29,7 @@ class UserServiceImp implements UserService {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<User> findUser(String phoneNumber) {
|
||||
Future<User?> findUser(String phoneNumber) {
|
||||
return userDataProvider.findUser(phoneNumber);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ abstract class UserService {
|
||||
Future<void> inviteUser(String userName, String phoneNumber);
|
||||
Future<void> deleteInvite(String phoneNumber);
|
||||
Future<void> acceptRequest(String userID);
|
||||
Future<User> findUser(String phoneNumber);
|
||||
Future<User?> findUser(String phoneNumber);
|
||||
Future<List<User>> searchUser(String term);
|
||||
Future<void> uploadMsgToken(String token);
|
||||
Future<void> removeMsgToken(String token);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'auth_status.dart';
|
||||
|
||||
class AuthResult {
|
||||
AuthStatus authStatus;
|
||||
String authErrorCode;
|
||||
String authErrorMsg;
|
||||
AuthStatus? authStatus;
|
||||
String? authErrorCode;
|
||||
String? authErrorMsg;
|
||||
|
||||
AuthResult({this.authStatus, this.authErrorCode, this.authErrorMsg});
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
class CargoType {
|
||||
String? id;
|
||||
String? name;
|
||||
double? rate;
|
||||
double? weight;
|
||||
bool? isChecked;
|
||||
int? qty;
|
||||
double rate;
|
||||
double weight;
|
||||
bool isChecked;
|
||||
int qty;
|
||||
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(
|
||||
{this.id,
|
||||
this.name,
|
||||
this.rate,
|
||||
this.weight,
|
||||
this.calWeight,
|
||||
this.calRate,
|
||||
this.rate = 0,
|
||||
this.weight = 0,
|
||||
this.calWeight = 0,
|
||||
this.calRate = 0,
|
||||
this.isChecked = false,
|
||||
this.qty = 0,
|
||||
this.isCutomDuty,
|
||||
this.customDutyFee});
|
||||
this.customDutyFee = 0});
|
||||
|
||||
factory CargoType.fromMap(Map<String, dynamic> map, String id) {
|
||||
return CargoType(
|
||||
@@ -63,7 +63,7 @@ class CargoType {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return name!;
|
||||
return name ?? "";
|
||||
}
|
||||
|
||||
bool isChangedForEdit(CargoType cargoType) {
|
||||
|
||||
@@ -9,61 +9,60 @@ import 'cargo_type.dart';
|
||||
import 'package.dart';
|
||||
|
||||
class Carton {
|
||||
String id;
|
||||
String shipmentID;
|
||||
String shipmentNumber;
|
||||
String senderID;
|
||||
String senderFCSID;
|
||||
String senderName;
|
||||
String? id;
|
||||
String? shipmentID;
|
||||
String? shipmentNumber;
|
||||
String? senderID;
|
||||
String? senderFCSID;
|
||||
String? senderName;
|
||||
|
||||
String boxNumber;
|
||||
String status;
|
||||
String cargoDesc;
|
||||
String desc;
|
||||
String? boxNumber;
|
||||
String? status;
|
||||
String? cargoDesc;
|
||||
String? desc;
|
||||
double width;
|
||||
double height;
|
||||
double length;
|
||||
int shipmentWeight;
|
||||
bool isChecked;
|
||||
bool isShipmentCarton;
|
||||
String cartonType;
|
||||
String fcsID;
|
||||
String userName;
|
||||
String userID;
|
||||
String fcsShipmentID;
|
||||
String fcsShipmentNumber;
|
||||
String mixCartonID;
|
||||
String mixCartonNumber;
|
||||
String cartonSizeID;
|
||||
String cartonSizeName;
|
||||
double cartonWeight;
|
||||
int? shipmentWeight;
|
||||
bool? isChecked;
|
||||
bool? isShipmentCarton;
|
||||
String? cartonType;
|
||||
String? fcsID;
|
||||
String? userName;
|
||||
String? userID;
|
||||
String? fcsShipmentID;
|
||||
String? fcsShipmentNumber;
|
||||
String? mixCartonID;
|
||||
String? mixCartonNumber;
|
||||
String? cartonSizeID;
|
||||
String? cartonSizeName;
|
||||
double? cartonWeight;
|
||||
|
||||
int rate;
|
||||
int weight;
|
||||
String packageType;
|
||||
String pickUpID;
|
||||
List<String> photos;
|
||||
String remark;
|
||||
DateTime arrivedDate;
|
||||
String cartonNumber;
|
||||
String? packageType;
|
||||
String? pickUpID;
|
||||
List<String> photos = [];
|
||||
String? remark;
|
||||
DateTime? arrivedDate;
|
||||
String? cartonNumber;
|
||||
|
||||
List<String> packageIDs;
|
||||
List<Package> packages;
|
||||
List<CargoType> cargoTypes;
|
||||
List<CargoType> cargoTypes = [];
|
||||
|
||||
DeliveryAddress deliveryAddress;
|
||||
Shipment shipment;
|
||||
DeliveryAddress? deliveryAddress;
|
||||
Shipment? shipment;
|
||||
|
||||
//for mix box
|
||||
String mixBoxType;
|
||||
String? mixBoxType;
|
||||
List<Carton> mixCartons;
|
||||
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 =>
|
||||
// shipmentNumber + "-" + receiverNumber + " #" + boxNumber;
|
||||
double get price => rate.toDouble() * weight;
|
||||
|
||||
double get actualWeight =>
|
||||
cargoTypes == null ? 0 : cargoTypes.fold(0, (p, e) => e.weight + p);
|
||||
@@ -84,15 +83,15 @@ class Carton {
|
||||
/// getCargoTypeForCalWeight returns carton with shipment weight
|
||||
List<CargoType> getCargoTypeForCalWeight(double volumetricRatio) {
|
||||
// get shipment weight
|
||||
double volume = (length ?? 0) * (width ?? 0) * (height ?? 0);
|
||||
double sw = volume / volumetricRatio ?? 0;
|
||||
double volume = length * width * height;
|
||||
double sw = volume / volumetricRatio;
|
||||
|
||||
// get actual weight
|
||||
double aw = cargoTypes.fold(0.0, (p, c) => p + c.weight);
|
||||
if (aw == 0 || sw == 0) return [];
|
||||
|
||||
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;
|
||||
});
|
||||
return cargoTypes;
|
||||
@@ -116,7 +115,7 @@ class Carton {
|
||||
double total = 0;
|
||||
cargoTypes.forEach((e) {
|
||||
double r =
|
||||
e.rate - (discountByWeight != null ? discountByWeight.discount : 0);
|
||||
e.rate - (discountByWeight != null ? (discountByWeight.discount) : 0);
|
||||
double amount = e.weight * r;
|
||||
total += amount;
|
||||
});
|
||||
@@ -134,9 +133,9 @@ class Carton {
|
||||
this.senderName,
|
||||
this.boxNumber,
|
||||
this.desc,
|
||||
this.width,
|
||||
this.height,
|
||||
this.length,
|
||||
this.width = 0,
|
||||
this.height = 0,
|
||||
this.length = 0,
|
||||
this.shipmentWeight,
|
||||
this.isChecked = false,
|
||||
this.cartonType,
|
||||
@@ -151,13 +150,13 @@ class Carton {
|
||||
this.status,
|
||||
this.arrivedDate,
|
||||
this.cargoDesc,
|
||||
this.shipmentHistory,
|
||||
this.packages,
|
||||
this.cargoTypes,
|
||||
this.shipmentHistory = const [],
|
||||
this.packages = const [],
|
||||
this.cargoTypes = const [],
|
||||
this.cartonNumber,
|
||||
this.fcsShipmentID,
|
||||
this.fcsShipmentNumber,
|
||||
this.packageIDs,
|
||||
this.packageIDs = const [],
|
||||
this.mixCartonID,
|
||||
this.mixCartonNumber,
|
||||
this.isShipmentCarton = false,
|
||||
@@ -165,14 +164,14 @@ class Carton {
|
||||
this.cartonSizeID,
|
||||
this.cartonSizeName,
|
||||
this.mixBoxType,
|
||||
this.mixCartons,
|
||||
this.mixCartonIDs,
|
||||
this.mixCartons = const [],
|
||||
this.mixCartonIDs = const [],
|
||||
this.cartonWeight});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
List _cargoTypes = cargoTypes?.map((c) => c.toMap())?.toList() ?? [];
|
||||
List _packages = packages?.map((c) => c.toJson())?.toList();
|
||||
List _mixCartons = mixCartons?.map((c) => c.toJson())?.toList();
|
||||
List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
|
||||
List _packages = packages.map((c) => c.toJson()).toList();
|
||||
List _mixCartons = mixCartons.map((c) => c.toJson()).toList();
|
||||
return {
|
||||
'id': id,
|
||||
'fcs_shipment_id': fcsShipmentID,
|
||||
@@ -213,9 +212,9 @@ class Carton {
|
||||
shipmentNumber: map['shipment_number'],
|
||||
// receiverNumber: map['receiver_number'],
|
||||
boxNumber: map['box_number'],
|
||||
length: double.tryParse(map['length']?.toString()),
|
||||
width: double.tryParse(map['width']?.toString()),
|
||||
height: double.tryParse(map['height']?.toString()),
|
||||
length: double.tryParse(map['length'].toString()) ?? 0,
|
||||
width: double.tryParse(map['width'].toString()) ?? 0,
|
||||
height: double.tryParse(map['height'].toString()) ?? 0,
|
||||
userName: map['user_name'],
|
||||
fcsID: map['fcs_id'],
|
||||
cartonType: map['carton_type'],
|
||||
@@ -242,8 +241,8 @@ class Carton {
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
|
||||
List _packages = packages?.map((c) => c.toJson())?.toList();
|
||||
List _mixCartons = mixCartons?.map((c) => c.toJson())?.toList();
|
||||
List _packages = packages.map((c) => c.toJson()).toList();
|
||||
List _mixCartons = mixCartons.map((c) => c.toJson()).toList();
|
||||
return {
|
||||
'id': id,
|
||||
'fcs_shipment_id': fcsShipmentID,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
class CartonSize {
|
||||
String id;
|
||||
String name;
|
||||
String? id;
|
||||
String? name;
|
||||
double length;
|
||||
double width;
|
||||
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() {
|
||||
return {
|
||||
@@ -27,19 +28,10 @@ class CartonSize {
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
return other.id == this.id;
|
||||
}
|
||||
bool operator ==(Object other) => other is CartonSize && other.id == id;
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
int result = 17;
|
||||
result = 37 * result + id.hashCode;
|
||||
return result;
|
||||
}
|
||||
int get hashCode => id.hashCode;
|
||||
|
||||
bool isChangedForEdit(CartonSize cartonSize) {
|
||||
return cartonSize.name != this.name ||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
class CustomDuty {
|
||||
String id;
|
||||
String productType;
|
||||
String desc;
|
||||
String? id;
|
||||
String? productType;
|
||||
String? desc;
|
||||
double fee;
|
||||
double shipmentRate;
|
||||
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) {
|
||||
return CustomDuty(
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
|
||||
|
||||
class Customer {
|
||||
String id;
|
||||
String name;
|
||||
String phoneNumber;
|
||||
String status;
|
||||
String? id;
|
||||
String? name;
|
||||
String? phoneNumber;
|
||||
String? status;
|
||||
|
||||
Customer({
|
||||
this.id,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class Discount {
|
||||
String id;
|
||||
String code;
|
||||
String customerId;
|
||||
String customerName;
|
||||
String status;
|
||||
String? id;
|
||||
String? code;
|
||||
String? customerId;
|
||||
String? customerName;
|
||||
String? status;
|
||||
double amount;
|
||||
|
||||
Discount({
|
||||
@@ -11,7 +11,7 @@ class Discount {
|
||||
this.code,
|
||||
this.customerId,
|
||||
this.customerName,
|
||||
this.amount,
|
||||
this.amount = 0,
|
||||
this.status,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class DiscountByWeight {
|
||||
String id;
|
||||
String? id;
|
||||
double weight;
|
||||
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) {
|
||||
return DiscountByWeight(
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
class FAQ {
|
||||
String id;
|
||||
int sn;
|
||||
String questionEng;
|
||||
String questionMm;
|
||||
String answerEng;
|
||||
String answerMm;
|
||||
String pageLinkLabelEng;
|
||||
String pageLinkLabelMm;
|
||||
String pageLink;
|
||||
String? id;
|
||||
int? sn;
|
||||
String? questionEng;
|
||||
String? questionMm;
|
||||
String? answerEng;
|
||||
String? answerMm;
|
||||
String? pageLinkLabelEng;
|
||||
String? pageLinkLabelMm;
|
||||
String? pageLink;
|
||||
|
||||
String question(bool isEng) => isEng ? questionEng : questionMm;
|
||||
String answer(bool isEng) => isEng ? answerEng : answerMm;
|
||||
String question(bool isEng) =>
|
||||
isEng ? (questionEng ?? "") : (questionMm ?? "");
|
||||
String answer(bool isEng) => isEng ? (answerEng ?? "") : (answerMm ?? "");
|
||||
|
||||
FAQ(
|
||||
{this.id,
|
||||
|
||||
@@ -3,17 +3,18 @@ import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import '../constants.dart';
|
||||
|
||||
class FcsShipment {
|
||||
String id;
|
||||
String shipmentNumber;
|
||||
DateTime cutoffDate;
|
||||
String shipType;
|
||||
DateTime arrivalDate;
|
||||
DateTime departureDate;
|
||||
String consignee;
|
||||
String port;
|
||||
String destination;
|
||||
String status;
|
||||
String reportName;
|
||||
String? id;
|
||||
String? shipmentNumber;
|
||||
DateTime? cutoffDate;
|
||||
String? shipType;
|
||||
DateTime? arrivalDate;
|
||||
DateTime? departureDate;
|
||||
String? consignee;
|
||||
String? port;
|
||||
String? destination;
|
||||
String? status;
|
||||
String? reportName;
|
||||
|
||||
FcsShipment({
|
||||
this.id,
|
||||
this.shipmentNumber,
|
||||
@@ -51,10 +52,10 @@ class FcsShipment {
|
||||
return {
|
||||
"id": id,
|
||||
'shipment_number': shipmentNumber,
|
||||
'cutoff_date': cutoffDate?.toUtc()?.toIso8601String(),
|
||||
'cutoff_date': cutoffDate?.toUtc().toIso8601String(),
|
||||
'shipment_type': shipType,
|
||||
'arrival_date': arrivalDate?.toUtc()?.toIso8601String(),
|
||||
'departure_date': departureDate?.toUtc()?.toIso8601String(),
|
||||
'arrival_date': arrivalDate?.toUtc().toIso8601String(),
|
||||
'departure_date': departureDate?.toUtc().toIso8601String(),
|
||||
'consignee': consignee,
|
||||
'port': port,
|
||||
'destination': destination,
|
||||
|
||||
@@ -10,15 +10,15 @@ import 'package:fcs/domain/entities/rate.dart';
|
||||
import 'package:fcs/domain/entities/shipment.dart';
|
||||
|
||||
class Invoice {
|
||||
String id;
|
||||
String invoiceNumber;
|
||||
DateTime invoiceDate;
|
||||
String fcsShipmentID;
|
||||
String userID;
|
||||
String fcsID;
|
||||
String userName;
|
||||
String phoneNumber;
|
||||
String status;
|
||||
String? id;
|
||||
String? invoiceNumber;
|
||||
DateTime? invoiceDate;
|
||||
String? fcsShipmentID;
|
||||
String? userID;
|
||||
String? fcsID;
|
||||
String? userName;
|
||||
String? phoneNumber;
|
||||
String? status;
|
||||
|
||||
double handlingFee;
|
||||
double deliveryFee;
|
||||
@@ -30,9 +30,9 @@ class Invoice {
|
||||
List<CargoType> cargoTypes;
|
||||
List<Shipment> shipments;
|
||||
List<Payment> payments;
|
||||
Discount discount;
|
||||
PaymentMethod paymentMethod;
|
||||
String invoiceURL;
|
||||
Discount? discount;
|
||||
PaymentMethod? paymentMethod;
|
||||
String? invoiceURL;
|
||||
|
||||
List<CargoType> getCargoTypes(Rate rate) {
|
||||
if (cargoTypes != null) return cargoTypes;
|
||||
@@ -40,7 +40,7 @@ class Invoice {
|
||||
List<CargoType> _cargoTypes = [];
|
||||
double totalCalWeight = 0;
|
||||
cartons.forEach((carton) {
|
||||
if (carton.isChecked) {
|
||||
if (carton.isChecked ?? false) {
|
||||
var _cartonsTypes =
|
||||
carton.getCargoTypeForCalWeight(rate.volumetricRatio);
|
||||
_cartonsTypes.forEach((ct) {
|
||||
@@ -68,15 +68,15 @@ class Invoice {
|
||||
|
||||
double getTotal(Rate 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;
|
||||
}
|
||||
|
||||
double get balance => (amount ?? 0) - (paidAmount ?? 0);
|
||||
double get balance => amount - paidAmount;
|
||||
|
||||
double getNetAmount(Rate 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 += getDeliveryFee();
|
||||
total += getHandlingFee();
|
||||
@@ -85,13 +85,13 @@ class Invoice {
|
||||
}
|
||||
|
||||
double getHandlingFee() {
|
||||
return shipments?.where((sh) => sh.isSelected ?? false)?.fold(0, (p, s) {
|
||||
return p + (s?.handlingFee ?? 0) - (s?.paidHandlingFee ?? 0);
|
||||
});
|
||||
return shipments
|
||||
.where((sh) => sh.isSelected)
|
||||
.fold(0, (p, s) => p + (s.handlingFee - s.paidHandlingFee));
|
||||
}
|
||||
|
||||
double getTotalBalance(Rate rate) {
|
||||
return getNetAmount(rate) - (paidAmount ?? 0);
|
||||
return getNetAmount(rate) - paidAmount;
|
||||
}
|
||||
|
||||
double getCustomFee() {
|
||||
@@ -102,7 +102,7 @@ class Invoice {
|
||||
return deliveryFee == null ? 0 : deliveryFee;
|
||||
}
|
||||
|
||||
double getDiscount() => discount == null ? 0 : discount.amount;
|
||||
double getDiscount() => discount == null ? 0 : discount!.amount;
|
||||
|
||||
Invoice(
|
||||
{this.id,
|
||||
@@ -111,19 +111,19 @@ class Invoice {
|
||||
this.fcsID,
|
||||
this.userName,
|
||||
this.phoneNumber,
|
||||
this.amount,
|
||||
this.paidAmount,
|
||||
this.amount = 0,
|
||||
this.paidAmount = 0,
|
||||
this.discount,
|
||||
this.status,
|
||||
this.customDuties,
|
||||
this.cartons,
|
||||
this.cargoTypes,
|
||||
this.handlingFee,
|
||||
this.deliveryFee,
|
||||
this.customDuties = const [],
|
||||
this.cartons = const [],
|
||||
this.cargoTypes = const [],
|
||||
this.handlingFee = 0,
|
||||
this.deliveryFee = 0,
|
||||
this.fcsShipmentID,
|
||||
this.shipments,
|
||||
this.shipments = const [],
|
||||
this.invoiceURL,
|
||||
this.payments,
|
||||
this.payments = const [],
|
||||
this.paymentMethod});
|
||||
|
||||
factory Invoice.fromMap(Map<String, dynamic> map, String docID) {
|
||||
@@ -153,7 +153,7 @@ class Invoice {
|
||||
return Invoice(
|
||||
id: docID,
|
||||
invoiceNumber: map['invoice_number'],
|
||||
invoiceDate: invd?.toDate(),
|
||||
invoiceDate: invd.toDate(),
|
||||
userName: map['user_name'],
|
||||
fcsID: map['fcs_id'],
|
||||
phoneNumber: map['phone_number'],
|
||||
@@ -174,12 +174,12 @@ class Invoice {
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
|
||||
List _customDuties = customDuties?.map((c) => c.toMap())?.toList();
|
||||
List _cartons = cartons?.map((c) => c.toMap())?.toList() ?? [];
|
||||
List _shipments = shipments?.map((s) => s.toMap())?.toList() ?? [];
|
||||
List _customDuties = customDuties.map((c) => c.toMap()).toList();
|
||||
List _cartons = cartons.map((c) => c.toMap()).toList();
|
||||
List _shipments = shipments.map((s) => s.toMap()).toList();
|
||||
return {
|
||||
"id": id,
|
||||
"invoice_date": invoiceDate?.toUtc()?.toIso8601String(),
|
||||
"invoice_date": invoiceDate?.toUtc().toIso8601String(),
|
||||
"user_id": userID,
|
||||
"user_name": userName,
|
||||
"invoice_number": invoiceNumber,
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
class Market {
|
||||
String id;
|
||||
String name;
|
||||
String? id;
|
||||
String? name;
|
||||
|
||||
Market({
|
||||
this.id,
|
||||
this.name,
|
||||
});
|
||||
Market({this.id, this.name});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
|
||||
@@ -5,35 +5,35 @@ import 'package:fcs/domain/vo/delivery_address.dart';
|
||||
import 'package:fcs/domain/vo/shipment_status.dart';
|
||||
|
||||
class Package {
|
||||
String id;
|
||||
String trackingID;
|
||||
String userID;
|
||||
String fcsID;
|
||||
String userName;
|
||||
String phoneNumber;
|
||||
DateTime currentStatusDate;
|
||||
String? id;
|
||||
String? trackingID;
|
||||
String? userID;
|
||||
String? fcsID;
|
||||
String? userName;
|
||||
String? phoneNumber;
|
||||
DateTime? currentStatusDate;
|
||||
List<String> photoUrls;
|
||||
List<ShipmentStatus> shipmentHistory;
|
||||
String desc;
|
||||
String? desc;
|
||||
|
||||
String status;
|
||||
String shipmentNumber;
|
||||
String senderFCSID;
|
||||
String senderName;
|
||||
String senderPhoneNumber;
|
||||
String boxNumber;
|
||||
String cargoDesc;
|
||||
String market;
|
||||
String? status;
|
||||
String? shipmentNumber;
|
||||
String? senderFCSID;
|
||||
String? senderName;
|
||||
String? senderPhoneNumber;
|
||||
String? boxNumber;
|
||||
String? cargoDesc;
|
||||
String? market;
|
||||
bool isChecked;
|
||||
|
||||
int rate;
|
||||
int weight;
|
||||
String packageType;
|
||||
String pickUpID;
|
||||
List<String> photos;
|
||||
String remark;
|
||||
DateTime arrivedDate;
|
||||
DeliveryAddress deliveryAddress;
|
||||
String? packageType;
|
||||
String? pickUpID;
|
||||
// List<String> photos;
|
||||
String? remark;
|
||||
DateTime? arrivedDate;
|
||||
DeliveryAddress? deliveryAddress;
|
||||
|
||||
//for packages in processing
|
||||
List<File> photoFiles;
|
||||
@@ -42,8 +42,8 @@ class Package {
|
||||
|
||||
double get price => rate.toDouble() * weight;
|
||||
|
||||
Package({
|
||||
this.id,
|
||||
Package(
|
||||
{this.id,
|
||||
this.trackingID,
|
||||
this.userID,
|
||||
this.userName,
|
||||
@@ -53,8 +53,8 @@ class Package {
|
||||
this.senderFCSID,
|
||||
this.senderName,
|
||||
this.boxNumber,
|
||||
this.rate,
|
||||
this.weight,
|
||||
this.rate = 0,
|
||||
this.weight = 0,
|
||||
this.packageType,
|
||||
this.pickUpID,
|
||||
this.remark,
|
||||
@@ -62,15 +62,14 @@ class Package {
|
||||
this.arrivedDate,
|
||||
this.cargoDesc,
|
||||
this.market,
|
||||
this.shipmentHistory,
|
||||
this.shipmentHistory = const [],
|
||||
this.currentStatusDate,
|
||||
this.photoUrls,
|
||||
this.photoUrls = const [],
|
||||
this.desc,
|
||||
this.deliveryAddress,
|
||||
this.isChecked = false,
|
||||
this.photoFiles,
|
||||
this.senderPhoneNumber
|
||||
});
|
||||
this.photoFiles = const [],
|
||||
this.senderPhoneNumber});
|
||||
|
||||
factory Package.fromMap(Map<String, dynamic> map, String docID) {
|
||||
var _currentStatusDate = (map['status_date'] as Timestamp);
|
||||
@@ -98,9 +97,7 @@ class Package {
|
||||
senderName: map['sender_name'],
|
||||
senderPhoneNumber: map['sender_phone_number'],
|
||||
deliveryAddress: _da,
|
||||
currentStatusDate: _currentStatusDate != null
|
||||
? _currentStatusDate.toDate().toLocal()
|
||||
: null,
|
||||
currentStatusDate: _currentStatusDate.toDate().toLocal(),
|
||||
photoUrls: _photoUrls,
|
||||
shipmentHistory: _shipmentStatus);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class Payment {
|
||||
String id;
|
||||
String invoiceID;
|
||||
DateTime paymentDate;
|
||||
String paymentReceiptURL;
|
||||
String status;
|
||||
String? id;
|
||||
String? invoiceID;
|
||||
DateTime? paymentDate;
|
||||
String? paymentReceiptURL;
|
||||
String? status;
|
||||
double amount;
|
||||
|
||||
Payment(
|
||||
@@ -14,13 +14,13 @@ class Payment {
|
||||
this.paymentDate,
|
||||
this.paymentReceiptURL,
|
||||
this.status,
|
||||
this.amount});
|
||||
this.amount = 0});
|
||||
|
||||
factory Payment.fromMap(Map<String, dynamic> map, String id) {
|
||||
var _paymentDate = (map['payment_date'] as Timestamp);
|
||||
return Payment(
|
||||
id: id,
|
||||
paymentDate: _paymentDate?.toDate(),
|
||||
paymentDate: _paymentDate.toDate(),
|
||||
paymentReceiptURL: map['payment_receipt_url'],
|
||||
status: map['status'],
|
||||
amount: map['amount']?.toDouble() ?? 0,
|
||||
@@ -31,7 +31,7 @@ class Payment {
|
||||
return {
|
||||
"id": id,
|
||||
"invoice_id": invoiceID,
|
||||
'payment_date': paymentDate?.toUtc()?.toIso8601String(),
|
||||
'payment_date': paymentDate?.toUtc().toIso8601String(),
|
||||
'payment_receipt_url': paymentReceiptURL,
|
||||
'status': status,
|
||||
'amount': amount,
|
||||
@@ -39,7 +39,7 @@ class Payment {
|
||||
}
|
||||
|
||||
Payment clone() {
|
||||
return Payment.fromMap(toMap(), this.id);
|
||||
return Payment.fromMap(toMap(), this.id!);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
class PaymentMethod {
|
||||
String id;
|
||||
String name;
|
||||
String accountName;
|
||||
String account;
|
||||
String phone;
|
||||
String email;
|
||||
String link;
|
||||
String? id;
|
||||
String? name;
|
||||
String? accountName;
|
||||
String? account;
|
||||
String? phone;
|
||||
String? email;
|
||||
String? link;
|
||||
|
||||
PaymentMethod(
|
||||
{this.id,
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import 'package:fcs/domain/entities/package.dart';
|
||||
|
||||
class Processing {
|
||||
String id;
|
||||
String? id;
|
||||
//for consignee
|
||||
String userID;
|
||||
String userName;
|
||||
String userPhoneNumber;
|
||||
String? userID;
|
||||
String? userName;
|
||||
String? userPhoneNumber;
|
||||
//for shipper
|
||||
String fcsID;
|
||||
String shipperName;
|
||||
String shipperPhoneNumber;
|
||||
String? fcsID;
|
||||
String? shipperName;
|
||||
String? shipperPhoneNumber;
|
||||
|
||||
List<Package> packages;
|
||||
|
||||
@@ -21,7 +21,7 @@ class Processing {
|
||||
this.fcsID,
|
||||
this.shipperName,
|
||||
this.shipperPhoneNumber,
|
||||
this.packages});
|
||||
this.packages = const []});
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => other is Processing && other.id == id;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
||||
|
||||
import 'cargo_type.dart';
|
||||
@@ -11,26 +10,25 @@ class Rate {
|
||||
double diffDiscountWeight;
|
||||
double diffWeightRate;
|
||||
|
||||
List<CargoType> cargoTypes;
|
||||
List<CargoType> customDuties;
|
||||
List<DiscountByWeight> discountByWeights;
|
||||
List<CargoType> cargoTypes = [];
|
||||
List<CargoType> customDuties = [];
|
||||
List<DiscountByWeight> discountByWeights = [];
|
||||
|
||||
DiscountByWeight getDiscountByWeight(double weight) {
|
||||
discountByWeights.sort((d1, d2) => d2.weight.compareTo(d1.weight));
|
||||
return discountByWeights.firstWhere((e) => e.weight < weight,
|
||||
orElse: () => null);
|
||||
return discountByWeights.firstWhere((e) => e.weight < weight);
|
||||
}
|
||||
|
||||
CargoType get defaultCargoType => cargoTypes == null
|
||||
CargoType? get defaultCargoType => cargoTypes == null
|
||||
? null
|
||||
: cargoTypes.firstWhere((e) => e.name == "General");
|
||||
|
||||
Rate(
|
||||
{this.deliveryFee,
|
||||
this.freeDeliveryWeight,
|
||||
this.volumetricRatio,
|
||||
this.diffDiscountWeight,
|
||||
this.diffWeightRate});
|
||||
{this.deliveryFee = 0,
|
||||
this.freeDeliveryWeight = 0,
|
||||
this.volumetricRatio = 0,
|
||||
this.diffDiscountWeight = 0,
|
||||
this.diffWeightRate = 0});
|
||||
|
||||
factory Rate.fromMap(Map<String, dynamic> map) {
|
||||
return Rate(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class Receipt {
|
||||
String id;
|
||||
int amount;
|
||||
String date;
|
||||
String status;
|
||||
String fileUrl;
|
||||
String? id;
|
||||
int? amount = 0;
|
||||
String? date;
|
||||
String? status;
|
||||
String? fileUrl;
|
||||
|
||||
Receipt({this.id, this.amount, this.date, this.status, this.fileUrl});
|
||||
}
|
||||
|
||||
@@ -9,21 +9,20 @@ List<Day> dayLists = [
|
||||
];
|
||||
|
||||
class Setting {
|
||||
final int supportBuildNum;
|
||||
|
||||
final int? supportBuildNum;
|
||||
// contact page
|
||||
String usaAddress;
|
||||
String mmAddress;
|
||||
String usaContactNumber;
|
||||
String mmContactNumber;
|
||||
String emailAddress;
|
||||
String facebookLink;
|
||||
bool inviteRequired;
|
||||
String appUrl;
|
||||
final String termsEng;
|
||||
final String termsMm;
|
||||
String about;
|
||||
String courierWebsite;
|
||||
String? usaAddress;
|
||||
String? mmAddress;
|
||||
String? usaContactNumber;
|
||||
String? mmContactNumber;
|
||||
String? emailAddress;
|
||||
String? facebookLink;
|
||||
bool? inviteRequired;
|
||||
String? appUrl;
|
||||
final String? termsEng;
|
||||
final String? termsMm;
|
||||
String? about;
|
||||
String? courierWebsite;
|
||||
|
||||
List<String> shipmentTypes;
|
||||
|
||||
@@ -40,7 +39,7 @@ class Setting {
|
||||
this.termsEng,
|
||||
this.termsMm,
|
||||
this.about,
|
||||
this.shipmentTypes,
|
||||
this.shipmentTypes = const [],
|
||||
this.courierWebsite});
|
||||
|
||||
factory Setting.fromMap(Map<String, dynamic> map) {
|
||||
@@ -76,9 +75,9 @@ class Setting {
|
||||
}
|
||||
|
||||
class Day {
|
||||
int id;
|
||||
String name;
|
||||
bool isChecked = false;
|
||||
int? id;
|
||||
String? name;
|
||||
bool? isChecked = false;
|
||||
Day({this.id, this.name, this.isChecked});
|
||||
|
||||
@override
|
||||
|
||||
@@ -4,35 +4,35 @@ import 'package:fcs/domain/entities/carton.dart';
|
||||
import 'package:fcs/domain/vo/delivery_address.dart';
|
||||
|
||||
class Shipment {
|
||||
String id;
|
||||
String shipmentNumber;
|
||||
String shipmentType;
|
||||
DeliveryAddress pickupAddress;
|
||||
DateTime pickupDate;
|
||||
String pickupTimeStart;
|
||||
String pickupTimeEnd;
|
||||
String? id;
|
||||
String? shipmentNumber;
|
||||
String? shipmentType;
|
||||
DeliveryAddress? pickupAddress;
|
||||
DateTime? pickupDate;
|
||||
String? pickupTimeStart;
|
||||
String? pickupTimeEnd;
|
||||
|
||||
String userName;
|
||||
String userID;
|
||||
String phoneNumber;
|
||||
int numberOfPackage;
|
||||
int weight;
|
||||
double handlingFee;
|
||||
double paidHandlingFee;
|
||||
String address;
|
||||
String status;
|
||||
String? userName;
|
||||
String? userID;
|
||||
String? phoneNumber;
|
||||
int numberOfPackage = 0;
|
||||
int weight = 0;
|
||||
double handlingFee = 0;
|
||||
double paidHandlingFee = 0;
|
||||
String? address;
|
||||
String? status;
|
||||
bool isCourier;
|
||||
int radioIndex;
|
||||
List<Carton> boxes;
|
||||
|
||||
String pickupUserID;
|
||||
String pickupUserName;
|
||||
String pickupUserPhoneNumber;
|
||||
String? pickupUserID;
|
||||
String? pickupUserName;
|
||||
String? pickupUserPhoneNumber;
|
||||
|
||||
String fcsShipmentID;
|
||||
String fcsShipmentNumber;
|
||||
String shipmentLabelUrl;
|
||||
bool isSelected;
|
||||
String? fcsShipmentID;
|
||||
String? fcsShipmentNumber;
|
||||
String? shipmentLabelUrl;
|
||||
bool isSelected = false;
|
||||
|
||||
Shipment(
|
||||
{this.id,
|
||||
@@ -43,28 +43,28 @@ class Shipment {
|
||||
this.phoneNumber,
|
||||
this.pickupTimeStart,
|
||||
this.pickupTimeEnd,
|
||||
this.numberOfPackage,
|
||||
this.weight,
|
||||
this.handlingFee,
|
||||
this.paidHandlingFee,
|
||||
this.numberOfPackage = 0,
|
||||
this.weight = 0,
|
||||
this.handlingFee = 0,
|
||||
this.paidHandlingFee = 0,
|
||||
this.address,
|
||||
this.status,
|
||||
this.pickupDate,
|
||||
this.isCourier = false,
|
||||
this.radioIndex = 1,
|
||||
this.pickupAddress,
|
||||
required this.pickupAddress,
|
||||
this.pickupUserID,
|
||||
this.pickupUserName,
|
||||
this.pickupUserPhoneNumber,
|
||||
this.fcsShipmentID,
|
||||
this.fcsShipmentNumber,
|
||||
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);
|
||||
int get totalCount => boxes?.length;
|
||||
double get totalWeight => boxes.fold(0, (p, e) => p + e.actualWeight);
|
||||
int get totalCount => boxes.length;
|
||||
|
||||
bool get isPending => status == shipment_pending_status;
|
||||
bool get isAssigned => status == shipment_assigned_status;
|
||||
@@ -100,15 +100,15 @@ class Shipment {
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
List _boxes = boxes?.map((l) => l.toMap())?.toList() ?? [];
|
||||
List _boxes = boxes.map((l) => l.toMap()).toList();
|
||||
|
||||
return {
|
||||
"id": id,
|
||||
'user_id': userID,
|
||||
'cartons': _boxes,
|
||||
'shipment_type': shipmentType,
|
||||
'pickup_address': pickupAddress.toMap(),
|
||||
"pickup_date": pickupDate?.toUtc()?.toIso8601String(),
|
||||
'pickup_address': pickupAddress?.toMap(),
|
||||
"pickup_date": pickupDate?.toUtc().toIso8601String(),
|
||||
'pickup_time_start': pickupTimeStart,
|
||||
'pickup_time_end': pickupTimeEnd,
|
||||
'pickup_user_id': pickupUserID,
|
||||
|
||||
@@ -9,18 +9,19 @@ DateFormat timeFormat = DateFormat("HH:mm");
|
||||
final DateFormat dateFormat = DateFormat("d MMM yyyy");
|
||||
|
||||
class User {
|
||||
String id;
|
||||
String name;
|
||||
String phoneNumber;
|
||||
String status;
|
||||
String fcsID;
|
||||
DateTime lastMessageTime;
|
||||
String lastMessage;
|
||||
int userUnseenCount;
|
||||
int fcsUnseenCount;
|
||||
String preferCurrency;
|
||||
String? id;
|
||||
String? name;
|
||||
String? phoneNumber;
|
||||
String? status;
|
||||
String? fcsID;
|
||||
DateTime? lastMessageTime;
|
||||
String? lastMessage;
|
||||
int? userUnseenCount;
|
||||
int? fcsUnseenCount;
|
||||
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 {
|
||||
var msg = lastMessage ?? "Say hi to $name";
|
||||
@@ -31,27 +32,31 @@ class User {
|
||||
String get getLastMessageTime {
|
||||
if (lastMessageTime == null) return "";
|
||||
DateTime today = DateTime.now();
|
||||
if (lastMessageTime.year == today.year &&
|
||||
lastMessageTime.month == today.month &&
|
||||
lastMessageTime.day == today.day) {
|
||||
return timeFormat.format(lastMessageTime);
|
||||
if (lastMessageTime!.year == today.year &&
|
||||
lastMessageTime!.month == today.month &&
|
||||
lastMessageTime!.day == today.day) {
|
||||
return timeFormat.format(lastMessageTime!);
|
||||
} else {
|
||||
return dateFormat.format(lastMessageTime);
|
||||
return dateFormat.format(lastMessageTime!);
|
||||
}
|
||||
}
|
||||
|
||||
String get getUserUnseenCount => userUnseenCount != null
|
||||
? userUnseenCount > 100 ? "99+" : userUnseenCount.toString()
|
||||
? userUnseenCount! > 100
|
||||
? "99+"
|
||||
: userUnseenCount.toString()
|
||||
: "0";
|
||||
String get getFcsUnseenCount => fcsUnseenCount != null
|
||||
? fcsUnseenCount > 100 ? "99+" : fcsUnseenCount.toString()
|
||||
? fcsUnseenCount! > 100
|
||||
? "99+"
|
||||
: fcsUnseenCount.toString()
|
||||
: "0";
|
||||
|
||||
List<String> privileges = [];
|
||||
|
||||
String get phone => phoneNumber != null && phoneNumber.startsWith("959")
|
||||
? "0${phoneNumber.substring(2)}"
|
||||
: phoneNumber;
|
||||
String get phone => phoneNumber != null && phoneNumber!.startsWith("959")
|
||||
? "0${phoneNumber!.substring(2)}"
|
||||
: phoneNumber!;
|
||||
bool get joined => status != null && status == user_joined_status;
|
||||
bool get invited => status != null && status == user_invited_status;
|
||||
bool get requested => status != null && status == user_requested_status;
|
||||
@@ -64,7 +69,7 @@ class User {
|
||||
this.phoneNumber,
|
||||
this.fcsID,
|
||||
this.status,
|
||||
this.privileges,
|
||||
this.privileges = const [],
|
||||
this.lastMessage,
|
||||
this.lastMessageTime,
|
||||
this.userUnseenCount,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
class ServerException {
|
||||
@override
|
||||
List<Object> get props => null;
|
||||
List<Object>? get props => null;
|
||||
|
||||
call() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get stringify => null;
|
||||
bool? get stringify => null;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'package:fcs/domain/entities/setting.dart';
|
||||
|
||||
class Contact {
|
||||
String usaAddress;
|
||||
String mmAddress;
|
||||
String usaContactNumber;
|
||||
String mmContactNumber;
|
||||
String emailAddress;
|
||||
String facebookLink;
|
||||
String? usaAddress;
|
||||
String? mmAddress;
|
||||
String? usaContactNumber;
|
||||
String? mmContactNumber;
|
||||
String? emailAddress;
|
||||
String? facebookLink;
|
||||
|
||||
Contact({
|
||||
this.usaAddress,
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
class DeliveryAddress {
|
||||
String id;
|
||||
String fullName;
|
||||
String addressLine1;
|
||||
String addressLine2;
|
||||
String city;
|
||||
String state;
|
||||
String phoneNumber;
|
||||
String? id;
|
||||
String? fullName;
|
||||
String? addressLine1;
|
||||
String? addressLine2;
|
||||
String? city;
|
||||
String? state;
|
||||
String? phoneNumber;
|
||||
bool isDefault;
|
||||
String userID;
|
||||
String? userID;
|
||||
|
||||
DeliveryAddress(
|
||||
{this.id,
|
||||
this.fullName,
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class Message {
|
||||
String id;
|
||||
String message;
|
||||
DateTime date;
|
||||
String receiverID;
|
||||
String receiverName;
|
||||
String senderID;
|
||||
String senderName;
|
||||
String messageType;
|
||||
String messageID;
|
||||
String? id;
|
||||
String? message;
|
||||
DateTime? date;
|
||||
String? receiverID;
|
||||
String? receiverName;
|
||||
String? senderID;
|
||||
String? senderName;
|
||||
String? messageType;
|
||||
String? messageID;
|
||||
|
||||
Message(
|
||||
{this.id,
|
||||
@@ -21,11 +21,13 @@ class Message {
|
||||
this.senderName,
|
||||
this.messageType,
|
||||
this.messageID});
|
||||
|
||||
bool fromToday() {
|
||||
if (date == null) return false;
|
||||
var now = DateTime.now();
|
||||
return date.day == now.day &&
|
||||
date.month == now.month &&
|
||||
date.year == now.year;
|
||||
return date!.day == now.day &&
|
||||
date!.month == now.month &&
|
||||
date!.year == now.year;
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
@@ -36,9 +38,10 @@ class Message {
|
||||
}
|
||||
|
||||
bool sameDay(Message another) {
|
||||
return date.year == another.date.year &&
|
||||
date.month == another.date.month &&
|
||||
date.day == another.date.day;
|
||||
if (date == null) return false;
|
||||
return date!.year == another.date!.year &&
|
||||
date!.month == another.date!.month &&
|
||||
date!.day == another.date!.day;
|
||||
}
|
||||
|
||||
factory Message.fromMap(Map<String, dynamic> map, String id) {
|
||||
@@ -52,7 +55,7 @@ class Message {
|
||||
receiverName: map['receiver_name'],
|
||||
messageType: map['msg_type'],
|
||||
messageID: map['msg_id'],
|
||||
date: date != null ? date.toDate() : null,
|
||||
date: date.toDate(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import 'package:fcs/domain/constants.dart';
|
||||
import 'package:flutter/cupertino.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';
|
||||
|
||||
class Privilege {
|
||||
String id;
|
||||
String name;
|
||||
String desc;
|
||||
bool sysAdminOnly = true;
|
||||
bool isChecked = false;
|
||||
String? name;
|
||||
String? desc;
|
||||
bool? sysAdminOnly = true;
|
||||
bool? isChecked = false;
|
||||
|
||||
IconData iconData;
|
||||
IconData? iconData;
|
||||
|
||||
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) {
|
||||
iconData = MaterialCommunityIcons.account_tie;
|
||||
} else if (this.id == privilege_support) {
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
class RadioGroup {
|
||||
String text;
|
||||
int index;
|
||||
RadioGroup({this.text, this.index});
|
||||
}
|
||||
@@ -3,17 +3,21 @@ import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
class ShipmentStatus {
|
||||
String status;
|
||||
DateTime date;
|
||||
bool done;
|
||||
String staffId;
|
||||
String staffName;
|
||||
bool? done;
|
||||
String? staffId;
|
||||
String? staffName;
|
||||
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) {
|
||||
var _date = (map['date'] as Timestamp);
|
||||
return ShipmentStatus(
|
||||
status: map['status'],
|
||||
date: _date == null ? null : _date.toDate(),
|
||||
date: _date.toDate(),
|
||||
done: map['done'],
|
||||
staffId: map['staff_id'],
|
||||
staffName: map['staff_name']);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
class Status {
|
||||
String status;
|
||||
String message;
|
||||
String errorCode;
|
||||
String? status;
|
||||
String? message;
|
||||
String? errorCode;
|
||||
Status(this.status, this.message);
|
||||
|
||||
Status.fromJson(Map<String, dynamic> json) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:fcs/domain/entities/setting.dart';
|
||||
|
||||
class Term {
|
||||
String termEng;
|
||||
String termMm;
|
||||
String? termEng;
|
||||
String? termMm;
|
||||
|
||||
Term({this.termEng, this.termMm});
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ Future<dynamic> requestAPI(
|
||||
String path,
|
||||
method, {
|
||||
dynamic payload,
|
||||
String token,
|
||||
String url,
|
||||
String? token,
|
||||
String? url,
|
||||
}) async {
|
||||
DevInfo devInfo = await DevInfo.getDevInfo();
|
||||
|
||||
@@ -33,7 +33,7 @@ Future<dynamic> requestAPI(
|
||||
headers["Token"] = token;
|
||||
}
|
||||
if (devInfo != null && devInfo.deviceID != null && deviceName != null) {
|
||||
headers["Device"] = devInfo.deviceID + ":" + deviceName;
|
||||
headers["Device"] = devInfo.deviceID??"" + ":" + deviceName;
|
||||
}
|
||||
headers["Project-ID"] = Config.instance.reportProjectID;
|
||||
|
||||
@@ -66,7 +66,7 @@ Future<dynamic> requestAPI(
|
||||
// request makes http request
|
||||
// if token is null
|
||||
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();
|
||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
String deviceName = "${androidInfo.model}(${androidInfo.id})";
|
||||
@@ -81,7 +81,7 @@ Future<dynamic> requestDownloadAPI(String path, method,
|
||||
log.info("Path:$baseUrl$path");
|
||||
HttpClient client = new HttpClient();
|
||||
var _downloadData = StringBuffer();
|
||||
var fileSave = new File(filePath);
|
||||
var fileSave = new File(filePath!);
|
||||
var request = await client.getUrl(Uri.parse("$baseUrl$path"));
|
||||
request.headers.set("Project-ID", Config.instance.reportProjectID);
|
||||
request.headers
|
||||
@@ -108,7 +108,7 @@ Future<dynamic> requestDownloadAPI(String path, method,
|
||||
// request makes http request
|
||||
// if token is null
|
||||
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();
|
||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
String deviceName = "${androidInfo.model}(${androidInfo.id})";
|
||||
@@ -123,7 +123,7 @@ Future<dynamic> requestDownloadPDFAPI(String path, method,
|
||||
log.info("Path:$baseUrl$path");
|
||||
HttpClient client = new HttpClient();
|
||||
// var _downloadData = StringBuffer();
|
||||
var fileSave = new File(filePath);
|
||||
var fileSave = new File(filePath!);
|
||||
var request = await client.getUrl(Uri.parse("$baseUrl$path"));
|
||||
request.headers.set("Project-ID", Config.instance.reportProjectID);
|
||||
if (token != null) {
|
||||
@@ -135,7 +135,7 @@ Future<dynamic> requestDownloadPDFAPI(String path, method,
|
||||
request.headers.set("payload", escapePayload);
|
||||
var response = await request.close();
|
||||
print("headers:${response.headers}");
|
||||
var _downloadData = List<int>();
|
||||
List<int> _downloadData = [];
|
||||
|
||||
response.listen((d) => _downloadData.addAll(d), onDone: () {
|
||||
fileSave.writeAsBytes(_downloadData);
|
||||
@@ -155,10 +155,10 @@ typedef OnDownloadDone(File file);
|
||||
// if token is null
|
||||
Future<dynamic> requestDownload(String path, method,
|
||||
{dynamic payload,
|
||||
String token,
|
||||
String url,
|
||||
String filePath,
|
||||
OnDownloadDone onDownloadDone}) async {
|
||||
required String token,
|
||||
required String url,
|
||||
required String filePath,
|
||||
OnDownloadDone? onDownloadDone}) async {
|
||||
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
String deviceName = "${androidInfo.model}(${androidInfo.id})";
|
||||
@@ -188,7 +188,7 @@ Future<dynamic> requestDownload(String path, method,
|
||||
// request.write(escapePayload);
|
||||
var response = await request.close();
|
||||
print("headers:${response.headers}");
|
||||
var _downloadData = List<int>();
|
||||
List<int> _downloadData = [];
|
||||
var cd = response.headers.value("content-disposition");
|
||||
String fileName = "download.csv";
|
||||
if (cd != null && cd.contains("filename=")) {
|
||||
|
||||
@@ -2,13 +2,13 @@ import 'package:device_info/device_info.dart';
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
class DevInfo {
|
||||
bool isAndroid;
|
||||
bool isIOS;
|
||||
String deviceID;
|
||||
String id;
|
||||
String model;
|
||||
bool? isAndroid;
|
||||
bool? isIOS;
|
||||
String? deviceID;
|
||||
String? id;
|
||||
String? model;
|
||||
|
||||
static DevInfo _instance;
|
||||
static DevInfo? _instance;
|
||||
|
||||
static Future<DevInfo> getDevInfo() async {
|
||||
if (_instance != null) return Future.value(_instance);
|
||||
@@ -18,14 +18,14 @@ class DevInfo {
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
_instance.deviceID = androidInfo.androidId;
|
||||
_instance.id = androidInfo.id;
|
||||
_instance.model = androidInfo.model;
|
||||
_instance!.deviceID = androidInfo.androidId;
|
||||
_instance!.id = androidInfo.id;
|
||||
_instance!.model = androidInfo.model;
|
||||
} else if (Platform.isIOS) {
|
||||
IosDeviceInfo iosDeviceInfo = await deviceInfo.iosInfo;
|
||||
_instance.deviceID = iosDeviceInfo.identifierForVendor;
|
||||
_instance.id = iosDeviceInfo.utsname.release;
|
||||
_instance.model = iosDeviceInfo.model;
|
||||
_instance!.deviceID = iosDeviceInfo.identifierForVendor;
|
||||
_instance!.id = iosDeviceInfo.utsname.release;
|
||||
_instance!.model = iosDeviceInfo.model;
|
||||
}
|
||||
return Future.value(_instance);
|
||||
}
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fcs/config.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart' as fb;
|
||||
import 'package:firebase_storage/firebase_storage.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
final log = Logger('firebaseHelper');
|
||||
|
||||
final FirebaseAuth auth = FirebaseAuth.instance;
|
||||
final fb.FirebaseAuth auth = fb.FirebaseAuth.instance;
|
||||
|
||||
Future<String> getToken() async {
|
||||
FirebaseUser firebaseUser = await auth.currentUser();
|
||||
IdTokenResult token = await firebaseUser.getIdToken();
|
||||
return token.token;
|
||||
fb.User? firebaseUser = fb.FirebaseAuth.instance.currentUser;
|
||||
String token = await firebaseUser?.getIdToken() ?? "";
|
||||
return token;
|
||||
}
|
||||
|
||||
Future<Map> getClaims({bool refreshIdToken = false}) async {
|
||||
FirebaseUser firebaseUser = await auth.currentUser();
|
||||
Future<Map?> getClaims({bool refreshIdToken = false}) async {
|
||||
fb.User? firebaseUser = auth.currentUser;
|
||||
if (firebaseUser == null) return null;
|
||||
IdTokenResult idToken =
|
||||
await firebaseUser.getIdToken(refresh: refreshIdToken);
|
||||
fb.IdTokenResult idToken =
|
||||
await firebaseUser.getIdTokenResult(refreshIdToken);
|
||||
return idToken.claims;
|
||||
}
|
||||
|
||||
// returns list of url
|
||||
Future<List<String>> uploadFiles(String path, List<File> files,
|
||||
{String fileName}) async {
|
||||
{String? fileName}) async {
|
||||
List<Future<String>> fu = [];
|
||||
for (File f in files) {
|
||||
Future<String> u = uploadStorage(path, f);
|
||||
@@ -35,22 +34,27 @@ Future<List<String>> uploadFiles(String path, List<File> files,
|
||||
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) {
|
||||
fileName = Uuid().v4();
|
||||
}
|
||||
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()}");
|
||||
Reference ref = FirebaseStorage.instance.ref().child('$path/$fileName');
|
||||
UploadTask uploadTask = ref.putFile(file);
|
||||
await uploadTask.resume();
|
||||
String downloadUrl = await ref.getDownloadURL();
|
||||
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 {
|
||||
@@ -62,10 +66,12 @@ Future<void> deleteStorageFromUrls(List<String> urls) async {
|
||||
|
||||
Future<void> deleteStorageFromUrl(String url) async {
|
||||
try {
|
||||
StorageReference storageReference =
|
||||
await FirebaseStorage(storageBucket: Config.instance.bucketName)
|
||||
.getReferenceFromUrl(url);
|
||||
await storageReference.delete();
|
||||
Reference ref = FirebaseStorage.instance.refFromURL(url);
|
||||
await ref.delete();
|
||||
// StorageReference storageReference =
|
||||
// await FirebaseStorage(storageBucket: Config.instance.bucketName)
|
||||
// .getReferenceFromUrl(url);
|
||||
// await storageReference.delete();
|
||||
} catch (e) {
|
||||
log.warning("deleteStorage:$e");
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class NetworkConnectivity {
|
||||
final log = Logger('NetworkConnectivity');
|
||||
|
||||
static final NetworkConnectivity instance = NetworkConnectivity._internal();
|
||||
static String hostName;
|
||||
static String? hostName;
|
||||
NetworkConnectivity._internal() {
|
||||
_initialise();
|
||||
var uri = Uri.parse(Config.instance.apiURL);
|
||||
@@ -38,7 +38,7 @@ class NetworkConnectivity {
|
||||
// lookup if connectivity is not none
|
||||
if (result != ConnectivityResult.none) {
|
||||
try {
|
||||
final hostNameLookup = await InternetAddress.lookup(hostName);
|
||||
final hostNameLookup = await InternetAddress.lookup(hostName ?? "");
|
||||
if (hostNameLookup.isNotEmpty &&
|
||||
hostNameLookup[0].rawAddress.isNotEmpty) {
|
||||
if (await checkHeartbeat()) {
|
||||
|
||||
@@ -13,7 +13,7 @@ class Paginator<T> {
|
||||
final log = Logger('Paginator');
|
||||
|
||||
final int rowPerLoad;
|
||||
DocumentSnapshot prev;
|
||||
DocumentSnapshot? prev;
|
||||
bool ended = false;
|
||||
bool isLoading = false;
|
||||
List<T> values = [];
|
||||
@@ -21,7 +21,7 @@ class Paginator<T> {
|
||||
|
||||
Query pageQuery;
|
||||
|
||||
Paginator(this.pageQuery, {this.rowPerLoad = 20, this.toObj}) {
|
||||
Paginator(this.pageQuery, {this.rowPerLoad = 20, required this.toObj}) {
|
||||
_clearState();
|
||||
}
|
||||
|
||||
@@ -36,27 +36,27 @@ class Paginator<T> {
|
||||
_clearState();
|
||||
}
|
||||
|
||||
Future<void> refresh({CallBack onFinished}) async {
|
||||
Future<void> refresh({CallBack? onFinished}) async {
|
||||
_clearState();
|
||||
await load();
|
||||
if (onFinished != null) onFinished();
|
||||
}
|
||||
|
||||
Future<bool> load({CallBack onFinished}) async {
|
||||
Future<bool?> load({CallBack? onFinished}) async {
|
||||
if (ended) return null;
|
||||
isLoading = true;
|
||||
Query _query =
|
||||
prev != null ? pageQuery.startAfterDocument(prev) : pageQuery;
|
||||
prev != null ? pageQuery.startAfterDocument(prev!) : pageQuery;
|
||||
try {
|
||||
await _query
|
||||
.limit(rowPerLoad)
|
||||
.getDocuments(source: Source.server)
|
||||
.get(GetOptions(source: Source.server))
|
||||
.then((QuerySnapshot snapshot) {
|
||||
int count = snapshot.documents.length;
|
||||
int count = snapshot.docs.length;
|
||||
ended = count < rowPerLoad;
|
||||
prev = count > 0 ? snapshot.documents[count - 1] : prev;
|
||||
snapshot.documents.forEach((e) {
|
||||
values.add(toObj(e.data, e.documentID));
|
||||
prev = count > 0 ? snapshot.docs[count - 1] : prev;
|
||||
snapshot.docs.forEach((e) {
|
||||
values.add(toObj(e.data() as Map<String, dynamic>, e.id));
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@@ -7,17 +7,17 @@ class SharedPref {
|
||||
static final SharedPref instance = SharedPref._();
|
||||
SharedPref._();
|
||||
|
||||
static Future<bool> isFirstLaunch() async {
|
||||
static Future<bool?> isFirstLaunch() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getBool('first_launch');
|
||||
}
|
||||
|
||||
static Future<void> finishFirstLaunch() async {
|
||||
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();
|
||||
return prefs.getString('language');
|
||||
}
|
||||
@@ -27,7 +27,7 @@ class SharedPref {
|
||||
prefs.setString('language', lang);
|
||||
}
|
||||
|
||||
static Future<bool> getStaffMode() async {
|
||||
static Future<bool?> getStaffMode() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getBool('staff_mode_on');
|
||||
}
|
||||
@@ -41,7 +41,7 @@ class SharedPref {
|
||||
await _save("user", user.toJson());
|
||||
}
|
||||
|
||||
static Future<User> getUser() async {
|
||||
static Future<User?> getUser() async {
|
||||
try {
|
||||
return User.fromJson(await _read("user"));
|
||||
} catch (e) {
|
||||
@@ -57,7 +57,7 @@ class SharedPref {
|
||||
await _save("skipped_recovery_email", skipped);
|
||||
}
|
||||
|
||||
static Future<bool> getSkippedRecoverEmail() async {
|
||||
static Future<bool?> getSkippedRecoverEmail() async {
|
||||
try {
|
||||
bool _skipped = await _read("skipped_recovery_email");
|
||||
return _skipped;
|
||||
@@ -69,7 +69,7 @@ class SharedPref {
|
||||
static _read(String key) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return json.decode(prefs.getString(key));
|
||||
return json.decode(prefs.getString(key) ?? "");
|
||||
} catch (e) {
|
||||
print("Error:$e");
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ const TextStyle labelStyleMM = TextStyle(
|
||||
fontFamily: "Myanmar3");
|
||||
const TextStyle subMenuStyle =
|
||||
TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500);
|
||||
const TextStyle subMenuStyleMM =
|
||||
TextStyle(fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500,
|
||||
const TextStyle subMenuStyleMM = TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontFamily: "Myanmar3");
|
||||
|
||||
const TextStyle welcomeLabelStyle =
|
||||
@@ -31,11 +33,10 @@ const TextStyle welcomeSubLabelStyle =
|
||||
const TextStyle siginButtonStyle =
|
||||
TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500);
|
||||
|
||||
|
||||
TextStyle newLabelStyle(
|
||||
{Color color,
|
||||
double fontSize,
|
||||
FontWeight fontWeight,
|
||||
{Color? color,
|
||||
double? fontSize,
|
||||
FontWeight? fontWeight,
|
||||
bool underline = false}) {
|
||||
return TextStyle(
|
||||
fontSize: fontSize == null ? 14 : fontSize,
|
||||
@@ -45,9 +46,9 @@ TextStyle newLabelStyle(
|
||||
}
|
||||
|
||||
TextStyle newLabelStyleMM(
|
||||
{Color color,
|
||||
double fontSize,
|
||||
FontWeight fontWeight,
|
||||
{Color? color,
|
||||
double? fontSize,
|
||||
FontWeight? fontWeight,
|
||||
bool underline = false}) {
|
||||
return TextStyle(
|
||||
fontSize: fontSize == null ? 13 : fontSize,
|
||||
@@ -59,8 +60,8 @@ TextStyle newLabelStyleMM(
|
||||
|
||||
const TextStyle photoLabelStyle =
|
||||
TextStyle(color: Colors.black, fontSize: 13.0);
|
||||
const TextStyle photoLabelStyleMM = TextStyle(
|
||||
color: Colors.black, fontSize: 13.0, fontFamily: "Myanmar3");
|
||||
const TextStyle photoLabelStyleMM =
|
||||
TextStyle(color: Colors.black, fontSize: 13.0, fontFamily: "Myanmar3");
|
||||
const TextStyle textStyle =
|
||||
TextStyle(fontSize: 14, color: Colors.black87, fontWeight: FontWeight.w500);
|
||||
const TextStyle textStyleOdd = TextStyle(
|
||||
|
||||
@@ -54,7 +54,7 @@ Future<void> showConfirmDialog(
|
||||
FlatButton(
|
||||
color: Colors.grey[300],
|
||||
child: Text(
|
||||
AppTranslations.of(context).text('btn.cancel'),
|
||||
AppTranslations.of(context)!.text('btn.cancel'),
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
? TextStyle()
|
||||
: TextStyle(fontFamily: 'Myanmar3'),
|
||||
@@ -67,7 +67,7 @@ Future<void> showConfirmDialog(
|
||||
),
|
||||
FlatButton(
|
||||
color: primaryColor,
|
||||
child: Text(AppTranslations.of(context).text('btn.ok'),
|
||||
child: Text(AppTranslations.of(context)!.text('btn.ok'),
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
? TextStyle(
|
||||
color: Colors.white,
|
||||
@@ -367,7 +367,7 @@ Widget fcsButton(BuildContext context, String text,
|
||||
}
|
||||
|
||||
String getLocalString(BuildContext context, String key) {
|
||||
return AppTranslations.of(context).text(key);
|
||||
return AppTranslations.of(context)!.text(key);
|
||||
}
|
||||
|
||||
void showToast(GlobalKey key, String text) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.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';
|
||||
|
||||
class BottomWidgets extends StatelessWidget {
|
||||
|
||||
@@ -3,20 +3,20 @@ import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/delivery_address/delivery_address_row.dart';
|
||||
import 'package:flutter/cupertino.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 'display_text.dart';
|
||||
import 'local_text.dart';
|
||||
|
||||
class DefaultDeliveryAddress extends StatelessWidget {
|
||||
final DeliveryAddress deliveryAddress;
|
||||
final String labelKey;
|
||||
final OnTap onTap;
|
||||
final IconData iconData;
|
||||
final DeliveryAddress? deliveryAddress;
|
||||
final String? labelKey;
|
||||
final OnTap? onTap;
|
||||
final IconData? iconData;
|
||||
|
||||
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);
|
||||
|
||||
@override
|
||||
@@ -37,7 +37,7 @@ class DefaultDeliveryAddress extends StatelessWidget {
|
||||
onTap == null
|
||||
? Container()
|
||||
: GestureDetector(
|
||||
onTap: () => onTap(),
|
||||
onTap: () => onTap!(),
|
||||
child: Chip(
|
||||
label: LocalText(
|
||||
context, "delivery_address.change_address",
|
||||
@@ -50,8 +50,8 @@ class DefaultDeliveryAddress extends StatelessWidget {
|
||||
child: deliveryAddress == null
|
||||
? Container()
|
||||
: DeliveryAddressRow(
|
||||
key: ValueKey(deliveryAddress.id),
|
||||
deliveryAddress: deliveryAddress),
|
||||
key: ValueKey(deliveryAddress!.id),
|
||||
deliveryAddress: deliveryAddress!),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -10,11 +10,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DeliveryAddressSelection extends StatefulWidget {
|
||||
final DeliveryAddress deliveryAddress;
|
||||
final User user;
|
||||
final DeliveryAddress? deliveryAddress;
|
||||
final User? user;
|
||||
|
||||
const DeliveryAddressSelection({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.deliveryAddress,
|
||||
this.user,
|
||||
}) : super(key: key);
|
||||
@@ -38,7 +38,7 @@ class _DeliveryAddressSelectionState extends State<DeliveryAddressSelection> {
|
||||
Provider.of<DeliveryAddressModel>(context, listen: false);
|
||||
|
||||
var deliveryAddresses =
|
||||
await addressModel.getDeliveryAddresses(widget.user.id);
|
||||
await addressModel.getDeliveryAddresses(widget.user!.id);
|
||||
setState(() {
|
||||
this._deliveryAddresses = deliveryAddresses;
|
||||
});
|
||||
@@ -95,7 +95,7 @@ class _DeliveryAddressSelectionState extends State<DeliveryAddressSelection> {
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: Icon(Icons.check,
|
||||
color: widget.deliveryAddress != null &&
|
||||
_deliveryAddress.id == widget.deliveryAddress.id
|
||||
_deliveryAddress.id == widget.deliveryAddress!.id
|
||||
? primaryColor
|
||||
: Colors.black26),
|
||||
),
|
||||
|
||||
@@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
|
||||
import 'local_text.dart';
|
||||
|
||||
class DialogInput extends StatefulWidget {
|
||||
final String value;
|
||||
final String label;
|
||||
final String? value;
|
||||
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
|
||||
_DialogInputState createState() => _DialogInputState();
|
||||
}
|
||||
@@ -24,7 +24,7 @@ class _DialogInputState extends State<DialogInput> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.value != null) {
|
||||
_controller.text = widget.value;
|
||||
_controller.text = widget.value!;
|
||||
_focusNode.addListener(() {
|
||||
if (_focusNode.hasFocus) {
|
||||
_controller.selection = TextSelection(
|
||||
@@ -41,7 +41,7 @@ class _DialogInputState extends State<DialogInput> {
|
||||
child: AlertDialog(
|
||||
title: LocalText(
|
||||
context,
|
||||
widget.label,
|
||||
widget.label!,
|
||||
fontSize: 20,
|
||||
color: primaryColor,
|
||||
),
|
||||
@@ -77,7 +77,7 @@ class _DialogInputState extends State<DialogInput> {
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
onPressed: () async {
|
||||
if (!_formKey.currentState.validate()) return;
|
||||
if (!_formKey.currentState!.validate()) return;
|
||||
_save();
|
||||
})
|
||||
],
|
||||
|
||||
@@ -6,13 +6,13 @@ import 'package:flutter/material.dart';
|
||||
import 'local_text.dart';
|
||||
|
||||
class DiscountDropdown<T> extends StatelessWidget {
|
||||
final Function(T) callback;
|
||||
final IconData iconData;
|
||||
final T selectedValue;
|
||||
final List<T> values;
|
||||
final Function(T)? callback;
|
||||
final IconData? iconData;
|
||||
final T? selectedValue;
|
||||
final List<T>? values;
|
||||
|
||||
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);
|
||||
|
||||
@override
|
||||
@@ -46,11 +46,11 @@ class DiscountDropdown<T> extends StatelessWidget {
|
||||
height: 1,
|
||||
color: primaryColor,
|
||||
),
|
||||
onChanged: (T newValue) {
|
||||
callback(newValue);
|
||||
onChanged: (T? newValue) {
|
||||
callback!(newValue!);
|
||||
},
|
||||
isExpanded: true,
|
||||
items: values.map<DropdownMenuItem<T>>((T value) {
|
||||
items: values!.map<DropdownMenuItem<T>>((T value) {
|
||||
return DropdownMenuItem<T>(
|
||||
value: value,
|
||||
child: Text(value == null ? "" : (value as Discount).code,
|
||||
|
||||
@@ -4,12 +4,12 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class DisplayImageSource {
|
||||
String url;
|
||||
File file;
|
||||
String? url;
|
||||
File? file;
|
||||
DisplayImageSource({this.url, this.file});
|
||||
|
||||
ImageProvider get imageProvider =>
|
||||
file == null ? CachedNetworkImageProvider(url) : FileImage(file);
|
||||
ImageProvider? get imageProvider =>
|
||||
file == null ? CachedNetworkImageProvider(url!) : FileImage(file!);
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
|
||||
@@ -62,7 +62,7 @@ class DisplayText extends StatelessWidget {
|
||||
labelTextKey == null
|
||||
? Container()
|
||||
: Text(
|
||||
AppTranslations.of(context).text(labelTextKey!),
|
||||
AppTranslations.of(context)!.text(labelTextKey!),
|
||||
style: labelStyle,
|
||||
),
|
||||
text == null
|
||||
|
||||
@@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
|
||||
import 'callbacks.dart';
|
||||
|
||||
class FcsExpansionTile extends StatefulWidget {
|
||||
final ValueChanged<bool> onExpansionChanged;
|
||||
final CallBack onEditPress;
|
||||
final List<Widget> children;
|
||||
final Widget title;
|
||||
final ValueChanged<bool>? onExpansionChanged;
|
||||
final CallBack? onEditPress;
|
||||
final List<Widget>? children;
|
||||
final Widget? title;
|
||||
final bool isEdit;
|
||||
const FcsExpansionTile(
|
||||
{this.onExpansionChanged,
|
||||
@@ -21,7 +21,7 @@ class FcsExpansionTile extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _FcsExpansionTileState extends State<FcsExpansionTile> {
|
||||
bool expanded;
|
||||
bool? expanded;
|
||||
@override
|
||||
void initState() {
|
||||
this.expanded = false;
|
||||
@@ -39,22 +39,22 @@ class _FcsExpansionTileState extends State<FcsExpansionTile> {
|
||||
expanded = value;
|
||||
});
|
||||
if (widget.onExpansionChanged != null)
|
||||
widget.onExpansionChanged(value);
|
||||
widget.onExpansionChanged!(value);
|
||||
},
|
||||
title: widget.title,
|
||||
children: widget.children,
|
||||
title: widget.title != null ? widget.title! : Container(),
|
||||
children: widget.children != null ? widget.children! : [Container()],
|
||||
trailing: widget.isEdit
|
||||
? IconButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
iconSize: 20,
|
||||
onPressed: () =>
|
||||
widget.onEditPress != null ? widget.onEditPress() : {},
|
||||
widget.onEditPress != null ? widget.onEditPress!() : {},
|
||||
icon: Icon(
|
||||
Icons.edit,
|
||||
color: primaryColor,
|
||||
))
|
||||
: AnimatedSwitcher(
|
||||
child: expanded
|
||||
child: expanded!
|
||||
? Icon(
|
||||
Icons.remove,
|
||||
color: primaryColor,
|
||||
|
||||
@@ -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 customFeeIconData = MaterialCommunityIcons.security;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
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 'local_text.dart';
|
||||
|
||||
@@ -18,15 +18,15 @@ modelBottomSheet(BuildContext context, {final OnFile onFile}) {
|
||||
}
|
||||
|
||||
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
|
||||
_ImageFileState createState() => _ImageFileState();
|
||||
}
|
||||
|
||||
class _ImageFileState extends State<ImageFile> {
|
||||
File selectedFile;
|
||||
File? selectedFile;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
@@ -44,7 +44,7 @@ class _ImageFileState extends State<ImageFile> {
|
||||
onTap: () async {
|
||||
Navigator.pop(context);
|
||||
selectedFile = await pickImage(ImageSource.gallery);
|
||||
if (widget.onFile != null) widget.onFile(selectedFile);
|
||||
if (widget.onFile != null) widget.onFile!(selectedFile!);
|
||||
}),
|
||||
new ListTile(
|
||||
leading: CircleAvatar(
|
||||
@@ -58,7 +58,7 @@ class _ImageFileState extends State<ImageFile> {
|
||||
Navigator.pop(context);
|
||||
selectedFile = await pickImage(ImageSource.camera);
|
||||
|
||||
if (widget.onFile != null) widget.onFile(selectedFile);
|
||||
if (widget.onFile != null) widget.onFile!(selectedFile!);
|
||||
},
|
||||
),
|
||||
new ListTile(
|
||||
@@ -75,7 +75,7 @@ class _ImageFileState extends State<ImageFile> {
|
||||
selectedFile = null;
|
||||
});
|
||||
|
||||
if (widget.onFile != null) widget.onFile(selectedFile);
|
||||
if (widget.onFile != null) widget.onFile!(selectedFile!);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -8,10 +8,10 @@ import 'show_img.dart';
|
||||
typedef OnFile = void Function(File);
|
||||
|
||||
class ImageUrl extends StatefulWidget {
|
||||
final String title;
|
||||
final String url;
|
||||
final String? title;
|
||||
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
|
||||
_ImageUrlState createState() => _ImageUrlState();
|
||||
}
|
||||
@@ -25,12 +25,12 @@ class _ImageUrlState extends State<ImageUrl> {
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
ShowImage(url: widget.url, fileName: widget.title)),
|
||||
ShowImage(url: widget.url!, fileName: widget.title!)),
|
||||
)
|
||||
},
|
||||
child: Chip(
|
||||
avatar: Icon(Icons.image),
|
||||
label: Text(widget.title),
|
||||
label: Text(widget.title!),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ class InputDate extends StatelessWidget {
|
||||
final String labelTextKey;
|
||||
final IconData iconData;
|
||||
final TextEditingController controller;
|
||||
final FormFieldValidator<String> validator;
|
||||
final FormFieldValidator<String>? validator;
|
||||
final int maxLines;
|
||||
final bool withBorder;
|
||||
final Color borderColor;
|
||||
final TextInputType textInputType;
|
||||
final Color? borderColor;
|
||||
final TextInputType? textInputType;
|
||||
final bool autoFocus;
|
||||
final String dateFormatString;
|
||||
|
||||
const InputDate(
|
||||
{Key key,
|
||||
this.labelTextKey,
|
||||
this.iconData,
|
||||
this.controller,
|
||||
{Key? key,
|
||||
required this.labelTextKey,
|
||||
required this.iconData,
|
||||
required this.controller,
|
||||
this.validator,
|
||||
this.maxLines = 1,
|
||||
this.withBorder = false,
|
||||
@@ -72,7 +72,7 @@ class InputDate extends StatelessWidget {
|
||||
),
|
||||
labelText: labelTextKey == null
|
||||
? null
|
||||
: AppTranslations.of(context).text(labelTextKey),
|
||||
: AppTranslations.of(context)!.text(labelTextKey),
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(color: Colors.black54, fontSize: 20),
|
||||
|
||||
@@ -6,20 +6,20 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class InputText extends StatelessWidget {
|
||||
final String labelTextKey;
|
||||
final IconData iconData;
|
||||
final TextEditingController controller;
|
||||
final FormFieldValidator<String> validator;
|
||||
final String? labelTextKey;
|
||||
final IconData? iconData;
|
||||
final TextEditingController? controller;
|
||||
final FormFieldValidator<String>? validator;
|
||||
final int maxLines;
|
||||
final bool withBorder;
|
||||
final Color borderColor;
|
||||
final TextInputType textInputType;
|
||||
final Color? borderColor;
|
||||
final TextInputType? textInputType;
|
||||
final bool autoFocus;
|
||||
final TextAlign textAlign;
|
||||
final bool enabled;
|
||||
|
||||
const InputText(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.labelTextKey,
|
||||
this.iconData,
|
||||
this.controller,
|
||||
@@ -30,7 +30,7 @@ class InputText extends StatelessWidget {
|
||||
this.autoFocus = false,
|
||||
this.textInputType,
|
||||
this.enabled = true,
|
||||
this.textAlign})
|
||||
this.textAlign = TextAlign.start})
|
||||
: super(key: key);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -46,7 +46,7 @@ class InputText extends StatelessWidget {
|
||||
style: textStyle,
|
||||
maxLines: maxLines,
|
||||
keyboardType: textInputType,
|
||||
textAlign: textAlign ?? TextAlign.start,
|
||||
textAlign: textAlign,
|
||||
decoration: new InputDecoration(
|
||||
// hintText: '',
|
||||
hintStyle: TextStyle(
|
||||
@@ -54,7 +54,7 @@ class InputText extends StatelessWidget {
|
||||
),
|
||||
labelText: labelTextKey == null
|
||||
? null
|
||||
: AppTranslations.of(context).text(labelTextKey),
|
||||
: AppTranslations.of(context)!.text(labelTextKey!),
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(color: Colors.black54, fontSize: 20),
|
||||
|
||||
@@ -7,18 +7,18 @@ import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class InputTime extends StatelessWidget {
|
||||
final String labelTextKey;
|
||||
final IconData iconData;
|
||||
final TextEditingController controller;
|
||||
final FormFieldValidator<String> validator;
|
||||
final String? labelTextKey;
|
||||
final IconData? iconData;
|
||||
final TextEditingController? controller;
|
||||
final FormFieldValidator<String>? validator;
|
||||
final int maxLines;
|
||||
final bool withBorder;
|
||||
final Color borderColor;
|
||||
final TextInputType textInputType;
|
||||
final Color? borderColor;
|
||||
final TextInputType? textInputType;
|
||||
final bool autoFocus;
|
||||
|
||||
const InputTime(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.labelTextKey,
|
||||
this.iconData,
|
||||
this.controller,
|
||||
@@ -45,14 +45,14 @@ class InputTime extends StatelessWidget {
|
||||
try {
|
||||
final format = DateFormat.jm(); //"6:00 AM"
|
||||
initialDate =
|
||||
TimeOfDay.fromDateTime(format.parse(controller.text));
|
||||
TimeOfDay.fromDateTime(format.parse(controller!.text));
|
||||
// var values = controller.text.split(":");
|
||||
// initialDate = TimeOfDay(
|
||||
// hour: int.parse(values[0]), minute: int.parse(values[1]));
|
||||
} catch (e) {} // ignore error
|
||||
}
|
||||
|
||||
TimeOfDay t = await showTimePicker(
|
||||
TimeOfDay? t = await showTimePicker(
|
||||
initialTime: initialDate,
|
||||
context: context,
|
||||
);
|
||||
@@ -61,7 +61,7 @@ class InputTime extends StatelessWidget {
|
||||
final now = new DateTime.now();
|
||||
final dt =
|
||||
DateTime(now.year, now.month, now.day, t.hour, t.minute);
|
||||
controller.text = "${format.format(dt)}";
|
||||
controller!.text = "${format.format(dt)}";
|
||||
}
|
||||
},
|
||||
controller: controller,
|
||||
@@ -77,7 +77,7 @@ class InputTime extends StatelessWidget {
|
||||
),
|
||||
labelText: labelTextKey == null
|
||||
? null
|
||||
: AppTranslations.of(context).text(labelTextKey),
|
||||
: AppTranslations.of(context)!.text(labelTextKey!),
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(color: Colors.black54, fontSize: 20),
|
||||
|
||||
@@ -10,13 +10,13 @@ const MAX_INC = 50.0;
|
||||
const MAX_FEET = 25.0;
|
||||
|
||||
class LengthPicker extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String lableKey;
|
||||
final TextEditingController? controller;
|
||||
final String? lableKey;
|
||||
final bool isReadOnly;
|
||||
final bool displayFeet;
|
||||
|
||||
const LengthPicker(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.controller,
|
||||
this.lableKey,
|
||||
this.isReadOnly = false,
|
||||
@@ -35,14 +35,14 @@ class _LengthPickerState extends State<LengthPicker> {
|
||||
super.initState();
|
||||
if (widget.controller != null) {
|
||||
_setText();
|
||||
widget.controller.addListener(() {
|
||||
widget.controller!.addListener(() {
|
||||
_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 f = (v / 12).floor();
|
||||
@@ -72,8 +72,8 @@ class _LengthPickerState extends State<LengthPicker> {
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return LengthPickerDialog(
|
||||
controller: widget.controller,
|
||||
labelKey: widget.lableKey,
|
||||
controller: widget.controller!,
|
||||
labelKey: widget.lableKey!,
|
||||
displayFeet: widget.displayFeet,
|
||||
);
|
||||
},
|
||||
@@ -82,12 +82,12 @@ class _LengthPickerState extends State<LengthPicker> {
|
||||
}
|
||||
|
||||
class LengthPickerDialog extends StatefulWidget {
|
||||
final TextEditingController controller;
|
||||
final String labelKey;
|
||||
final bool displayFeet;
|
||||
final TextEditingController? controller;
|
||||
final String? labelKey;
|
||||
final bool? displayFeet;
|
||||
|
||||
const LengthPickerDialog(
|
||||
{Key key, this.controller, this.labelKey, this.displayFeet})
|
||||
{Key? key, this.controller, this.labelKey, this.displayFeet})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
@@ -95,8 +95,8 @@ class LengthPickerDialog extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
int _valueFeet;
|
||||
int _valueInc;
|
||||
late int _valueFeet;
|
||||
late int _valueInc;
|
||||
TextEditingController inchInputController = TextEditingController();
|
||||
TextEditingController feetInputController = TextEditingController();
|
||||
final _focusNode = FocusNode();
|
||||
@@ -107,9 +107,9 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
_valueFeet = 0;
|
||||
_valueInc = 0;
|
||||
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();
|
||||
_valueInc = widget.displayFeet ? (v % 12).toInt() : v.toInt();
|
||||
_valueInc = widget.displayFeet! ? (v % 12).toInt() : v.toInt();
|
||||
inchInputController.text = _valueInc.toString();
|
||||
feetInputController.text = _valueFeet.toString();
|
||||
}
|
||||
@@ -144,7 +144,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
borderSide: BorderSide(color: primaryColor, width: 1.0),
|
||||
),
|
||||
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),
|
||||
),
|
||||
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(
|
||||
child: LocalText(
|
||||
context,
|
||||
widget.labelKey,
|
||||
widget.labelKey!,
|
||||
color: primaryColor,
|
||||
fontSize: 16,
|
||||
)),
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: widget.displayFeet
|
||||
children: widget.displayFeet!
|
||||
? [
|
||||
Container(width: 100, child: feetBox),
|
||||
Container(width: 100, child: inchBox),
|
||||
@@ -252,7 +252,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
widget.displayFeet
|
||||
widget.displayFeet!
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -295,11 +295,11 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
),
|
||||
Slider(
|
||||
activeColor: primaryColor,
|
||||
value: _valueInc.toDouble() > (widget.displayFeet ? 11 : MAX_INC)
|
||||
value: _valueInc.toDouble() > (widget.displayFeet! ? 11 : MAX_INC)
|
||||
? 0
|
||||
: _valueInc.toDouble(),
|
||||
min: 0,
|
||||
max: widget.displayFeet ? 11 : MAX_INC,
|
||||
max: widget.displayFeet! ? 11 : MAX_INC,
|
||||
divisions: 100,
|
||||
label: (_valueInc ?? 0).round().toString(),
|
||||
onChanged: (double v) {
|
||||
@@ -318,10 +318,10 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
});
|
||||
int _v = _valueInc.round() + _valueFeet.round() * 12;
|
||||
if (widget.controller != null) {
|
||||
widget.controller.text = _v.toString();
|
||||
widget.controller!.text = _v.toString();
|
||||
}
|
||||
feetInputController.text =
|
||||
widget.displayFeet ? _valueFeet.round().toString() : _v.toString();
|
||||
widget.displayFeet! ? _valueFeet.round().toString() : _v.toString();
|
||||
}
|
||||
|
||||
_updateInc(double v) {
|
||||
@@ -330,8 +330,8 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
});
|
||||
int _v = _valueInc.round() + _valueFeet.round() * 12;
|
||||
if (widget.controller != null) {
|
||||
widget.controller.text =
|
||||
widget.displayFeet ? _v.toString() : _valueInc.toString();
|
||||
widget.controller!.text =
|
||||
widget.displayFeet! ? _v.toString() : _valueInc.toString();
|
||||
}
|
||||
inchInputController.text = _valueInc.toString();
|
||||
}
|
||||
@@ -343,8 +343,8 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
});
|
||||
int _v = _valueInc.round() + _valueFeet.round() * 12;
|
||||
if (widget.controller != null) {
|
||||
widget.controller.text =
|
||||
widget.displayFeet ? _v.toString() : _valueInc.toString();
|
||||
widget.controller!.text =
|
||||
widget.displayFeet! ? _v.toString() : _valueInc.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
||||
});
|
||||
int _v = _valueInc.round() + _valueFeet.round() * 12;
|
||||
if (widget.controller != null) {
|
||||
widget.controller.text = _v.toString();
|
||||
widget.controller!.text = _v.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@ import 'package:flutter/material.dart';
|
||||
import 'callbacks.dart';
|
||||
|
||||
class LocalButton extends StatelessWidget {
|
||||
final CallBack callBack;
|
||||
final IconData iconData;
|
||||
final String textKey;
|
||||
final Color color;
|
||||
final CallBack? callBack;
|
||||
final IconData? iconData;
|
||||
final String? textKey;
|
||||
final Color? color;
|
||||
|
||||
const LocalButton(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.callBack,
|
||||
this.iconData,
|
||||
this.textKey,
|
||||
@@ -33,7 +33,7 @@ class LocalButton extends StatelessWidget {
|
||||
minWidth: 900.0,
|
||||
height: 100.0,
|
||||
child: FlatButton(
|
||||
onPressed: callBack == null ? null : () => callBack(),
|
||||
onPressed: callBack == null ? null : () => callBack!(),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@@ -48,7 +48,7 @@ class LocalButton extends StatelessWidget {
|
||||
),
|
||||
LocalText(
|
||||
context,
|
||||
textKey,
|
||||
textKey!,
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
),
|
||||
|
||||
@@ -5,15 +5,15 @@ import 'package:flutter/material.dart';
|
||||
import 'local_text.dart';
|
||||
|
||||
class LocalDropdown<T> extends StatelessWidget {
|
||||
final Function(T) callback;
|
||||
final IconData iconData;
|
||||
final T selectedValue;
|
||||
final List<T> values;
|
||||
final Function(T) display;
|
||||
final String labelKey;
|
||||
final Function(T)? callback;
|
||||
final IconData? iconData;
|
||||
final T? selectedValue;
|
||||
final List<T>? values;
|
||||
final Function(T)? display;
|
||||
final String? labelKey;
|
||||
|
||||
const LocalDropdown(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.callback,
|
||||
this.iconData,
|
||||
this.selectedValue,
|
||||
@@ -40,7 +40,7 @@ class LocalDropdown<T> extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(right: 18.0),
|
||||
child: LocalText(
|
||||
context,
|
||||
labelKey,
|
||||
labelKey!,
|
||||
color: Colors.black54,
|
||||
fontSize: 16,
|
||||
),
|
||||
@@ -53,20 +53,20 @@ class LocalDropdown<T> extends StatelessWidget {
|
||||
height: 1,
|
||||
color: Colors.grey,
|
||||
),
|
||||
onChanged: (T newValue) {
|
||||
callback(newValue);
|
||||
onChanged: (T? newValue) {
|
||||
callback!(newValue!);
|
||||
},
|
||||
isExpanded: true,
|
||||
items: values == null
|
||||
? []
|
||||
: values.map<DropdownMenuItem<T>>((T value) {
|
||||
: values!.map<DropdownMenuItem<T>>((T value) {
|
||||
return DropdownMenuItem<T>(
|
||||
value: value,
|
||||
child: Text(
|
||||
value == null
|
||||
? ""
|
||||
: display != null
|
||||
? display(value)
|
||||
? display!(value)
|
||||
: value.toString(),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: primaryColor)),
|
||||
|
||||
@@ -7,15 +7,15 @@ import 'local_popupmenu.dart';
|
||||
typedef PopupMenuCallback = Function(LocalPopupMenu popupMenu);
|
||||
|
||||
class LocalPopupMenuButton extends StatefulWidget {
|
||||
final PopupMenuCallback popupMenuCallback;
|
||||
final List<LocalPopupMenu> popmenus;
|
||||
final PopupMenuCallback? popupMenuCallback;
|
||||
final List<LocalPopupMenu>? popmenus;
|
||||
final bool multiSelect;
|
||||
final bool selectable;
|
||||
final IconData buttonIcon;
|
||||
final IconData? buttonIcon;
|
||||
final Color buttonColor;
|
||||
|
||||
const LocalPopupMenuButton(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.popupMenuCallback,
|
||||
this.popmenus,
|
||||
this.buttonIcon,
|
||||
@@ -29,11 +29,11 @@ class LocalPopupMenuButton extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
|
||||
List<LocalPopupMenu> popmenus;
|
||||
late List<LocalPopupMenu> popmenus;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
popmenus = widget.popmenus;
|
||||
popmenus = widget.popmenus!;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
|
||||
}
|
||||
}
|
||||
if (selected.enabled && widget.popupMenuCallback != null)
|
||||
widget.popupMenuCallback(selected);
|
||||
widget.popupMenuCallback!(selected);
|
||||
},
|
||||
icon: Container(
|
||||
width: 30,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
class LocalPopupMenu {
|
||||
int id;
|
||||
String textKey;
|
||||
String? textKey;
|
||||
bool selected;
|
||||
bool highlight;
|
||||
bool enabled;
|
||||
LocalPopupMenu(
|
||||
{this.id,
|
||||
{required this.id,
|
||||
this.textKey,
|
||||
this.selected = false,
|
||||
this.highlight = false,
|
||||
|
||||
@@ -3,15 +3,15 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LocalRadioButtons<T> extends StatelessWidget {
|
||||
final Function(T) callback;
|
||||
final IconData iconData;
|
||||
final T selectedValue;
|
||||
final List<T> values;
|
||||
final Function(T)? callback;
|
||||
final IconData? iconData;
|
||||
final T? selectedValue;
|
||||
final List<T>? values;
|
||||
final bool readOnly;
|
||||
final bool hideUnselected;
|
||||
|
||||
const LocalRadioButtons(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.callback,
|
||||
this.iconData,
|
||||
this.selectedValue,
|
||||
@@ -26,19 +26,19 @@ class LocalRadioButtons<T> extends StatelessWidget {
|
||||
}
|
||||
|
||||
List<Widget> getChildren() {
|
||||
return values
|
||||
return values!
|
||||
.toList()
|
||||
.map((e) => SizedBox(
|
||||
height: 30,
|
||||
child: InkWell(
|
||||
onTap: () => callback(e),
|
||||
onTap: () => callback!(e),
|
||||
child: Row(children: <Widget>[
|
||||
Radio<T>(
|
||||
activeColor: primaryColor,
|
||||
groupValue: selectedValue,
|
||||
value: e,
|
||||
onChanged: (T value) {
|
||||
callback(value);
|
||||
onChanged: (T? value) {
|
||||
callback!(value!);
|
||||
},
|
||||
),
|
||||
Text(e.toString()),
|
||||
@@ -48,7 +48,7 @@ class LocalRadioButtons<T> extends StatelessWidget {
|
||||
}
|
||||
|
||||
List<Widget> getReadonlyChildren() {
|
||||
return values
|
||||
return values!
|
||||
.toList()
|
||||
.map((e) => hideUnselected && e == selectedValue
|
||||
? SizedBox(
|
||||
|
||||
@@ -7,26 +7,26 @@ import 'package:fcs/helpers/theme.dart';
|
||||
class LocalText extends Text {
|
||||
final BuildContext context;
|
||||
LocalText(this.context, String translationKey,
|
||||
{Color color,
|
||||
double fontSize,
|
||||
FontWeight fontWeight,
|
||||
List<String> translationVariables,
|
||||
String text,
|
||||
{Color? color,
|
||||
double? fontSize,
|
||||
FontWeight? fontWeight,
|
||||
List<String>? translationVariables,
|
||||
String? text,
|
||||
bool underline = false})
|
||||
: super(
|
||||
text ??
|
||||
AppTranslations.of(context).text(translationKey,
|
||||
AppTranslations.of(context)!.text(translationKey,
|
||||
translationVariables: translationVariables),
|
||||
style: Provider.of<LanguageModel>(context, listen: false).isEng
|
||||
? newLabelStyle(
|
||||
color: color,
|
||||
fontSize: fontSize,
|
||||
fontWeight: fontWeight,
|
||||
color: color!,
|
||||
fontSize: fontSize!,
|
||||
fontWeight: fontWeight!,
|
||||
underline: underline)
|
||||
: newLabelStyleMM(
|
||||
color: color,
|
||||
fontSize: fontSize,
|
||||
fontWeight: fontWeight,
|
||||
color: color!,
|
||||
fontSize: fontSize!,
|
||||
fontWeight: fontWeight!,
|
||||
underline: underline));
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ class LocalLargeTitle extends Text {
|
||||
LocalLargeTitle(
|
||||
this.context,
|
||||
String translationKey, {
|
||||
Color color,
|
||||
List<String> translationVariables,
|
||||
Color? color,
|
||||
List<String>? translationVariables,
|
||||
}) : super(
|
||||
AppTranslations.of(context).text(translationKey,
|
||||
AppTranslations.of(context)!.text(translationKey,
|
||||
translationVariables: translationVariables),
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
? TextStyle(color: color)
|
||||
@@ -48,7 +48,7 @@ class LocalLargeTitle extends Text {
|
||||
class TextLocalStyle extends Text {
|
||||
final BuildContext context;
|
||||
TextLocalStyle(this.context, String text,
|
||||
{Color color, double fontSize, FontWeight fontWeight})
|
||||
{Color? color, double? fontSize, FontWeight? fontWeight})
|
||||
: super(text,
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
? TextStyle(
|
||||
|
||||
@@ -4,10 +4,10 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class LocalTitle extends StatelessWidget {
|
||||
final String textKey;
|
||||
final Widget trailing;
|
||||
final String? textKey;
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
@@ -20,13 +20,13 @@ class LocalTitle extends StatelessWidget {
|
||||
children: [
|
||||
LocalText(
|
||||
context,
|
||||
textKey,
|
||||
textKey!,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: primaryColor,
|
||||
),
|
||||
trailing != null ? Spacer() : Container(),
|
||||
trailing != null ? trailing : Container()
|
||||
trailing != null ? trailing! : Container()
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -79,16 +79,16 @@ class MultiImgController {
|
||||
}
|
||||
|
||||
List<File> get getUpdatedFile {
|
||||
List<File> _addfiles = getAddedFile;
|
||||
List<File?> _addfiles = getAddedFile;
|
||||
this.imageFiles.addAll(_addfiles);
|
||||
return this.imageFiles;
|
||||
}
|
||||
|
||||
List<File> get getAddedFile {
|
||||
List<File?> get getAddedFile {
|
||||
return addedFiles.map((e) => e.file).toList();
|
||||
}
|
||||
|
||||
List<String> get getDeletedUrl {
|
||||
List<String?> get getDeletedUrl {
|
||||
return removedFiles.map((e) => e.url).toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:fcs/pages/widgets/show_img.dart';
|
||||
import 'package:fcs/pages/widgets/show_multiple_img.dart';
|
||||
import 'package:flutter/cupertino.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:image_picker/image_picker.dart';
|
||||
|
||||
@@ -18,13 +18,13 @@ import 'multi_img_controller.dart';
|
||||
typedef OnFile = void Function(File);
|
||||
|
||||
class MultiImageFile extends StatefulWidget {
|
||||
final String title;
|
||||
final String? title;
|
||||
final bool enabled;
|
||||
final ImageSource imageSource;
|
||||
final MultiImgController controller;
|
||||
final MultiImgController? controller;
|
||||
|
||||
const MultiImageFile(
|
||||
{Key key,
|
||||
{Key? key,
|
||||
this.title,
|
||||
this.enabled = true,
|
||||
this.controller,
|
||||
@@ -39,10 +39,10 @@ class _MultiImageFileState extends State<MultiImageFile> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
fileContainers = widget.controller.fileContainers;
|
||||
widget.controller.onChange(() {
|
||||
fileContainers = widget.controller!.fileContainers;
|
||||
widget.controller!.onChange(() {
|
||||
setState(() {
|
||||
this.fileContainers = widget.controller.fileContainers;
|
||||
this.fileContainers = widget.controller!.fileContainers;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -133,7 +133,7 @@ class _MultiImageFileState extends State<MultiImageFile> {
|
||||
fit: BoxFit.cover,
|
||||
width: 50,
|
||||
height: 50,
|
||||
imageUrl: fileContainers[index].url,
|
||||
imageUrl: fileContainers[index].url!,
|
||||
placeholder: (context, url) => Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -150,7 +150,7 @@ class _MultiImageFileState extends State<MultiImageFile> {
|
||||
: FittedBox(
|
||||
fit: BoxFit.cover,
|
||||
child: Image.file(
|
||||
fileContainers[index].file,
|
||||
fileContainers[index].file!,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -189,13 +189,13 @@ class _MultiImageFileState extends State<MultiImageFile> {
|
||||
fileContainer.file = selectedFile;
|
||||
setState(() {
|
||||
fileContainers.add(fileContainer);
|
||||
widget.controller.addFile = fileContainer;
|
||||
widget.controller!.addFile = fileContainer;
|
||||
});
|
||||
}
|
||||
|
||||
_fileRemove(DisplayImageSource fileContainer) {
|
||||
setState(() {
|
||||
widget.controller.removeFile = fileContainer;
|
||||
widget.controller!.removeFile = fileContainer;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -232,11 +232,11 @@ class _MultiImageFileState extends State<MultiImageFile> {
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ShowImage(
|
||||
imageFile: fileContainer.file,
|
||||
imageFile: fileContainer.file!,
|
||||
url: fileContainer.file == null
|
||||
? fileContainer.url
|
||||
: null,
|
||||
fileName: widget.title)),
|
||||
? fileContainer.url!
|
||||
: '',
|
||||
fileName: widget.title!)),
|
||||
)
|
||||
},
|
||||
child: Chip(
|
||||
@@ -249,7 +249,7 @@ class _MultiImageFileState extends State<MultiImageFile> {
|
||||
deleteIcon: Icon(
|
||||
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(
|
||||
onTap: onTap,
|
||||
child: ClipOval(
|
||||
|
||||
@@ -5,9 +5,9 @@ import 'package:fcs/helpers/theme.dart' as theme;
|
||||
class NumberCell extends StatelessWidget {
|
||||
final int number;
|
||||
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("#,###"),
|
||||
super(key: key);
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import 'package:provider/provider.dart';
|
||||
|
||||
class OfflineRedirect extends StatefulWidget {
|
||||
final Widget child;
|
||||
OfflineRedirect({@required this.child});
|
||||
OfflineRedirect({required this.child});
|
||||
|
||||
@override
|
||||
_OfflineRedirectState createState() => _OfflineRedirectState();
|
||||
}
|
||||
|
||||
class _OfflineRedirectState extends State<OfflineRedirect> {
|
||||
Timer offlineTimer;
|
||||
Timer? offlineTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -27,7 +27,7 @@ class _OfflineRedirectState extends State<OfflineRedirect> {
|
||||
}
|
||||
|
||||
_startOfflineTimer() async {
|
||||
if (offlineTimer != null && offlineTimer.isActive) return;
|
||||
if (offlineTimer != null && offlineTimer!.isActive) return;
|
||||
var _duration = new Duration(milliseconds: 500);
|
||||
this.offlineTimer = new Timer.periodic(_duration, offlineNav);
|
||||
}
|
||||
@@ -41,7 +41,7 @@ class _OfflineRedirectState extends State<OfflineRedirect> {
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
offlineTimer.cancel();
|
||||
offlineTimer!.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,10 @@ import 'package:flutter_pdfview/flutter_pdfview.dart';
|
||||
import 'package:share/share.dart';
|
||||
|
||||
class PDFScreen extends StatefulWidget {
|
||||
final String title;
|
||||
final String url;
|
||||
final String? title;
|
||||
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();
|
||||
}
|
||||
@@ -33,10 +33,10 @@ class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
|
||||
download();
|
||||
}
|
||||
|
||||
File file;
|
||||
File? file;
|
||||
Future<void> download() async {
|
||||
try {
|
||||
File f = await PdfCacheMgr.pdfs.getSingleFile(widget.url);
|
||||
File f = await PdfCacheMgr.pdfs.getSingleFile(widget.url!);
|
||||
setState(() {
|
||||
file = f;
|
||||
});
|
||||
@@ -89,23 +89,23 @@ class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
|
||||
fitPolicy: FitPolicy.BOTH,
|
||||
preventLinkNavigation:
|
||||
false, // if set to true the link is handled in flutter
|
||||
onRender: (_pages) {
|
||||
onRender: (int?_pages) {
|
||||
print(('pages => $pages'));
|
||||
setState(() {
|
||||
pages = _pages;
|
||||
pages = _pages!;
|
||||
isReady = true;
|
||||
});
|
||||
},
|
||||
onViewCreated: (PDFViewController pdfViewController) {
|
||||
_controller.complete(pdfViewController);
|
||||
},
|
||||
onLinkHandler: (String uri) {
|
||||
onLinkHandler: (String? uri) {
|
||||
print('goto uri: $uri');
|
||||
},
|
||||
onPageChanged: (int page, int total) {
|
||||
onPageChanged: (int? page, int? total) {
|
||||
print('page change: $page/$total');
|
||||
setState(() {
|
||||
currentPage = page;
|
||||
currentPage = page!;
|
||||
});
|
||||
},
|
||||
),
|
||||
@@ -116,8 +116,8 @@ class _PDFScreenState extends State<PDFScreen> with WidgetsBindingObserver {
|
||||
}
|
||||
|
||||
_share() async {
|
||||
final RenderBox box = context.findRenderObject();
|
||||
await Share.shareFiles([file.path],
|
||||
final RenderBox box = context.findRenderObject() as RenderBox;
|
||||
await Share.shareFiles([file!.path],
|
||||
mimeTypes: ["application/pdf"],
|
||||
subject: "File",
|
||||
sharePositionOrigin: box.localToGlobal(Offset.zero) & box.size);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class PopupMenu {
|
||||
int id;
|
||||
String status;
|
||||
PopupMenu({this.id, this.status});
|
||||
PopupMenu({required this.id, required this.status});
|
||||
}
|
||||
|
||||
List<PopupMenu> menuPopup = <PopupMenu>[
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
|
||||
class LocalProgress extends Progress {
|
||||
LocalProgress({bool inAsyncCall, Widget child})
|
||||
LocalProgress({required bool inAsyncCall, required Widget child})
|
||||
: super(
|
||||
inAsyncCall: inAsyncCall,
|
||||
child: child,
|
||||
|
||||
@@ -6,12 +6,12 @@ import 'package:flutter/material.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
|
||||
class ShowImage extends StatefulWidget {
|
||||
final String url;
|
||||
final File imageFile;
|
||||
final String fileName;
|
||||
final String localImage;
|
||||
final String? url;
|
||||
final File? imageFile;
|
||||
final String? fileName;
|
||||
final String? localImage;
|
||||
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);
|
||||
@override
|
||||
_ShowImageState createState() => _ShowImageState();
|
||||
@@ -20,6 +20,13 @@ class ShowImage extends StatefulWidget {
|
||||
class _ShowImageState extends State<ShowImage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ImageProvider<Object>? p;
|
||||
if (widget.imageFile != null) {
|
||||
p = FileImage(widget.imageFile!);
|
||||
} else {
|
||||
p = AssetImage(widget.localImage!);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: new IconButton(
|
||||
@@ -35,11 +42,7 @@ class _ShowImageState extends State<ShowImage> {
|
||||
backgroundDecoration: const BoxDecoration(
|
||||
color: primaryColor,
|
||||
),
|
||||
imageProvider: widget.url != null
|
||||
? NetworkImage(widget.url)
|
||||
: widget.imageFile != null
|
||||
? FileImage(widget.imageFile)
|
||||
: AssetImage(widget.localImage),
|
||||
imageProvider: widget.url != null ? NetworkImage(widget.url!) : p,
|
||||
minScale: PhotoViewComputedScale.contained * 1)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ dependencies:
|
||||
permission_handler: ^8.1.4+2
|
||||
country_code_picker: ^2.0.2
|
||||
pin_input_text_field: ^4.1.0
|
||||
# flutter_icons: ^1.1.0
|
||||
flutter_icons_null_safety: ^1.1.0
|
||||
country_icons: ^2.0.2
|
||||
timeline_list: ^0.0.5
|
||||
# barcode_scan: ^2.0.2
|
||||
|
||||
Reference in New Issue
Block a user