add packages
This commit is contained in:
@@ -102,7 +102,8 @@
|
||||
"package.create.name":"Customer Name",
|
||||
"package.create.phone":"Phone Number",
|
||||
"package.tracking.id":"Tracking ID",
|
||||
"package.create.packages":"Create Packages",
|
||||
"package.create.packages":"Complete receiving",
|
||||
"package.create.market":"Market",
|
||||
|
||||
"package.edit.title":"PACKAGE",
|
||||
"package.arrival.date":"Arrival Date",
|
||||
@@ -111,10 +112,15 @@
|
||||
"package.weight":"Weight",
|
||||
"package.amount":"Amount",
|
||||
|
||||
"market.edit.title":"Markets",
|
||||
"market.edit.name":"Market Name",
|
||||
"market.remove.confirm":"Remove this market?",
|
||||
|
||||
"btn.save": "Save",
|
||||
"btn.approve":"Approve",
|
||||
"btn.delete":"Delete",
|
||||
"btn.select":"Select",
|
||||
"btn.cancel":"Cancel",
|
||||
|
||||
"================================================================":"",
|
||||
|
||||
|
||||
@@ -103,7 +103,8 @@
|
||||
"package.create.name":"နာမည်",
|
||||
"package.create.phone":"ဖုန်းနံပါတ်",
|
||||
"package.tracking.id":"Tracking ID",
|
||||
"package.create.packages":"အထုပ် အသစ်များ သိမ်းဆည်းရန်",
|
||||
"package.create.packages":"အထုပ် အသစ်များ လက်ခံမည်",
|
||||
"package.create.market":"Market",
|
||||
|
||||
"package.new":"New Package",
|
||||
"package.edit.title":"PACKAGE",
|
||||
@@ -113,10 +114,16 @@
|
||||
"package.weight":"Weight",
|
||||
"package.amount":"Amount",
|
||||
|
||||
"market.edit.title":"Markets",
|
||||
"market.edit.name":"Market Name",
|
||||
"market.remove.confirm":"Remove this market?",
|
||||
|
||||
"btn.save":"သိမ်းဆည်းရန်",
|
||||
"btn.approve":"အတည်ပြုရန်",
|
||||
"btn.delete":"ဖျက်ရန်",
|
||||
"btn.select":"ရွေးချယ်ပါ",
|
||||
"btn.cancel":"Cancel",
|
||||
|
||||
"================================================================":"",
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:fcs/fcs/common/pages/contact/model/contact_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/customers/model/customer_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/faq/model/faq_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/initial_language_selection.dart';
|
||||
import 'package:fcs/fcs/common/pages/market/model/market_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/model/language_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/model/main_model.dart' as fcs;
|
||||
import 'package:fcs/fcs/common/pages/package/model/package_model.dart';
|
||||
@@ -93,6 +94,7 @@ class _AppState extends State<App> {
|
||||
final StaffModel staffModel = new StaffModel();
|
||||
final ShipmentModel shipmentModel = new ShipmentModel();
|
||||
final PackageModel packageModel = new PackageModel();
|
||||
final MarketModel marketModel = new MarketModel();
|
||||
|
||||
AppTranslationsDelegate _newLocaleDelegate;
|
||||
static FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
||||
@@ -105,7 +107,8 @@ class _AppState extends State<App> {
|
||||
..addModel(customerModel)
|
||||
..addModel(staffModel)
|
||||
..addModel(shipmentModel)
|
||||
..addModel(packageModel);
|
||||
..addModel(packageModel)
|
||||
..addModel(marketModel);
|
||||
mainModel2.init();
|
||||
|
||||
_newLocaleDelegate = AppTranslationsDelegate(newLocale: null);
|
||||
@@ -256,6 +259,7 @@ class _AppState extends State<App> {
|
||||
ChangeNotifierProvider.value(value: contactModel),
|
||||
ChangeNotifierProvider.value(value: termModel),
|
||||
ChangeNotifierProvider.value(value: faqModel),
|
||||
ChangeNotifierProvider.value(value: marketModel),
|
||||
],
|
||||
child: Consumer<LanguageModel>(
|
||||
builder: (context, value, child) {
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:fcs/fcs/common/domain/constants.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/auth_result.dart' as fcs;
|
||||
import 'package:fcs/fcs/common/domain/entities/auth_status.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/setting.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/setting.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/user.dart';
|
||||
import 'package:fcs/fcs/common/domain/exceiptions/signin_exception.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
@@ -61,6 +60,7 @@ class AuthFb {
|
||||
_verificationId = verificationId;
|
||||
print("codeSent " + phoneNumber);
|
||||
codeSentCompleted = true;
|
||||
completer.complete(fcs.AuthResult(authStatus: AuthStatus.SMS_SENT));
|
||||
};
|
||||
|
||||
final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
|
||||
@@ -136,8 +136,10 @@ class AuthFb {
|
||||
user.privileges = privileges.split(":").toList();
|
||||
}
|
||||
User _user = await getUserFromFirestore(user.id);
|
||||
if (_user != null) {
|
||||
user.fcsID = _user.fcsID;
|
||||
user.name = _user.name;
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:fcs/fcs/common/domain/entities/package.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/user.dart';
|
||||
import 'package:fcs/fcs/common/helpers/api_helper.dart';
|
||||
import 'package:fcs/fcs/common/helpers/firebase_helper.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@@ -7,10 +6,9 @@ import 'package:logging/logging.dart';
|
||||
class PackageDataProvider {
|
||||
final log = Logger('PackageDataProvider');
|
||||
|
||||
Future<void> createPackages(User user, List<Package> packages) async {
|
||||
List<String> strs = packages.map((e) => e.trackingID).toList();
|
||||
Future<void> createPackages(List<Package> packages, String fcsID) async {
|
||||
List<Map<String, dynamic>> json = packages.map((e) => e.toJson()).toList();
|
||||
return await requestAPI("/packages", "POST",
|
||||
payload: {"fcs_id": user.fcsID, "tracking_ids": strs},
|
||||
token: await getToken());
|
||||
payload: {"packages": json, "fcs_id": fcsID}, token: await getToken());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ const user_collection = "users";
|
||||
const invitations_collection = "invitations";
|
||||
const setting_doc_id = "setting";
|
||||
const privilege_collection = "privileges";
|
||||
const markets_collection = "markets";
|
||||
const packages_collection = "packages";
|
||||
|
||||
const ok_doc_id = "ok";
|
||||
|
||||
|
||||
28
lib/fcs/common/domain/entities/market.dart
Normal file
28
lib/fcs/common/domain/entities/market.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
class Market {
|
||||
String id;
|
||||
String name;
|
||||
|
||||
Market({
|
||||
this.id,
|
||||
this.name,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
};
|
||||
}
|
||||
|
||||
factory Market.fromMap(Map<String, dynamic> map, String id) {
|
||||
return Market(
|
||||
id: id,
|
||||
name: map['name'],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Market{id: $id, name: $name}';
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:fcs/fcs/common/domain/vo/shipment_status.dart';
|
||||
|
||||
class Package {
|
||||
String id;
|
||||
String trackingID;
|
||||
String userID;
|
||||
String fcsID;
|
||||
String userName;
|
||||
String phoneNumber;
|
||||
String status;
|
||||
String currentStatus;
|
||||
DateTime currentStatusDate;
|
||||
List<Map<String, dynamic>> allStatus;
|
||||
List<String> photoUrls;
|
||||
|
||||
String status;
|
||||
String shipmentNumber;
|
||||
String senderFCSID;
|
||||
String senderName;
|
||||
@@ -39,6 +45,9 @@ class Package {
|
||||
this.id,
|
||||
this.trackingID,
|
||||
this.userID,
|
||||
this.userName,
|
||||
this.fcsID,
|
||||
this.phoneNumber,
|
||||
this.shipmentNumber,
|
||||
this.senderFCSID,
|
||||
this.senderName,
|
||||
@@ -57,5 +66,36 @@ class Package {
|
||||
this.cargoDesc,
|
||||
this.market,
|
||||
this.shipmentHistory,
|
||||
this.allStatus,
|
||||
this.currentStatus,
|
||||
this.currentStatusDate,
|
||||
this.photoUrls,
|
||||
});
|
||||
|
||||
factory Package.fromMap(Map<String, dynamic> map, String docID) {
|
||||
var _currentStatusDate = (map['current_status_date'] as Timestamp);
|
||||
|
||||
List<Map<String, dynamic>> _allStatus = List.from(map['all_status'])
|
||||
.map((e) => Map<String, dynamic>.from(e))
|
||||
.toList();
|
||||
List<String> _photoUrls =
|
||||
map['photo_urls'] == null ? [] : map['photo_urls'].cast<List<String>>();
|
||||
|
||||
return Package(
|
||||
id: docID,
|
||||
userID: map['user_id'],
|
||||
fcsID: map['fcs_id'],
|
||||
trackingID: map['tracking_id'],
|
||||
market: map['market'],
|
||||
userName: map['user_name'],
|
||||
phoneNumber: map['phone_number'],
|
||||
currentStatus: map['current_status'],
|
||||
currentStatusDate:
|
||||
_currentStatusDate != null ? _currentStatusDate.toDate() : null,
|
||||
photoUrls: _photoUrls,
|
||||
allStatus: _allStatus);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() =>
|
||||
{'id': id, 'tracking_id': trackingID, 'market': market, 'fcs_id': fcsID};
|
||||
}
|
||||
|
||||
@@ -116,6 +116,7 @@ class Setting {
|
||||
factory Setting.fromMap(Map<String, dynamic> map) {
|
||||
var ts = (map['price_last_update'] as Timestamp);
|
||||
var list = (map['bank_accounts'] as List);
|
||||
|
||||
List<BankAccount> bankAccounts = [];
|
||||
if (list != null) {
|
||||
list.asMap().forEach((index, item) {
|
||||
|
||||
@@ -23,7 +23,10 @@ class CustomerModel extends BaseModel {
|
||||
|
||||
@override
|
||||
logout() async {
|
||||
if (customerListener != null) customerListener.cancel();
|
||||
if (invitationListener != null) invitationListener.cancel();
|
||||
customers = [];
|
||||
invitations = [];
|
||||
}
|
||||
|
||||
Future<void> inviteUser(String userName, String phoneNumber) {
|
||||
|
||||
@@ -73,9 +73,11 @@ class _HomePageState extends State<HomePage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
User user = Provider.of<MainModel>(context).user;
|
||||
if (user == null) {
|
||||
return Container();
|
||||
}
|
||||
|
||||
login = Provider.of<MainModel>(context).isLogin();
|
||||
// var owner =true;// Provider.of<MainModel>(context).isOwner();
|
||||
var customer = Provider.of<MainModel>(context).isCustomer();
|
||||
LanguageModel languageModel = Provider.of<LanguageModel>(context);
|
||||
|
||||
final faqBtn = _buildBtn("faq.btn",
|
||||
|
||||
192
lib/fcs/common/pages/market/market_editor.dart
Normal file
192
lib/fcs/common/pages/market/market_editor.dart
Normal file
@@ -0,0 +1,192 @@
|
||||
import 'package:fcs/fcs/common/domain/entities/market.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/role.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/user.dart';
|
||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
||||
import 'package:fcs/fcs/common/localization/app_translations.dart';
|
||||
import 'package:fcs/fcs/common/pages/market/model/market_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/model/language_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/model/main_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/staff/model/staff_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/util.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/display_text.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/input_text.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/local_text.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
typedef void FindCallBack();
|
||||
|
||||
class MarketEditor extends StatefulWidget {
|
||||
const MarketEditor();
|
||||
@override
|
||||
_MarketEditorState createState() => _MarketEditorState();
|
||||
}
|
||||
|
||||
class _MarketEditorState extends State<MarketEditor> {
|
||||
TextEditingController _marketNameCtl = new TextEditingController();
|
||||
|
||||
bool _isLoading = false;
|
||||
List<String> markets = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
List<Widget> showMarkets(BuildContext context, List<Market> markets) {
|
||||
return markets.map((p) {
|
||||
return new ListTile(
|
||||
title: new Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new Text(
|
||||
p.name,
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove, color: primaryColor),
|
||||
onPressed: () => _remove(p),
|
||||
)
|
||||
],
|
||||
));
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Market> markets = Provider.of<MarketModel>(context).markets;
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: new IconButton(
|
||||
icon: new Icon(Icons.close, color: primaryColor, size: 30),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
shadowColor: Colors.transparent,
|
||||
backgroundColor: Colors.white,
|
||||
title: LocalText(
|
||||
context,
|
||||
"market.edit.title",
|
||||
fontSize: 20,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(left: 12.0, right: 12),
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 18.0),
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.add, color: primaryColor),
|
||||
onPressed: () => _showDialog(context),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: showMarkets(context, markets),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
_remove(Market market) {
|
||||
if (market == null) {
|
||||
showMsgDialog(context, "Esrror", "Invalid market!");
|
||||
return;
|
||||
}
|
||||
showConfirmDialog(
|
||||
context, "market.remove.confirm", () => _removeMarket(market));
|
||||
}
|
||||
|
||||
_removeMarket(Market market) async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
MarketModel marketModel = Provider.of<MarketModel>(context, listen: false);
|
||||
try {
|
||||
await marketModel.deleteMarket(market.id);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
} finally {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_add() async {
|
||||
if (_marketNameCtl.text == "") {
|
||||
showMsgDialog(context, "Esrror", "Invalid market name!");
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
MarketModel marketModel = Provider.of<MarketModel>(context, listen: false);
|
||||
try {
|
||||
await marketModel.addMarket(_marketNameCtl.text);
|
||||
_marketNameCtl.text = "";
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
} finally {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_showDialog(BuildContext context) async {
|
||||
await showDialog<String>(
|
||||
context: context,
|
||||
child: new AlertDialog(
|
||||
contentPadding: const EdgeInsets.all(16.0),
|
||||
content: new Row(
|
||||
children: <Widget>[
|
||||
new Expanded(
|
||||
child: InputText(
|
||||
labelTextKey: "market.edit.name",
|
||||
controller: _marketNameCtl,
|
||||
autoFocus: true,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
new FlatButton(
|
||||
child: LocalText(context, "btn.cancel", color: primaryColor),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
new FlatButton(
|
||||
child: LocalText(
|
||||
context,
|
||||
"btn.save",
|
||||
color: primaryColor,
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
_add();
|
||||
})
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
57
lib/fcs/common/pages/market/model/market_model.dart
Normal file
57
lib/fcs/common/pages/market/model/market_model.dart
Normal file
@@ -0,0 +1,57 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:fcs/fcs/common/domain/constants.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/market.dart';
|
||||
import 'package:fcs/fcs/common/helpers/firebase_helper.dart';
|
||||
import 'package:fcs/fcs/common/pages/model/base_model.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
class MarketModel extends BaseModel {
|
||||
final log = Logger('MarketModel');
|
||||
StreamSubscription<QuerySnapshot> listener;
|
||||
List<Market> markets = [];
|
||||
|
||||
void initUser(user) async {
|
||||
super.initUser(user);
|
||||
_loadMarkets();
|
||||
}
|
||||
|
||||
@override
|
||||
logout() async {
|
||||
markets = [];
|
||||
}
|
||||
|
||||
Future<void> _loadMarkets() async {
|
||||
if (user == null || !user.hasStaffs()) return;
|
||||
|
||||
try {
|
||||
if (listener != null) listener.cancel();
|
||||
|
||||
listener = Firestore.instance
|
||||
.collection("/$config_collection/$setting_doc_id/$markets_collection")
|
||||
.snapshots()
|
||||
.listen((QuerySnapshot snapshot) {
|
||||
markets.clear();
|
||||
markets = snapshot.documents.map((documentSnapshot) {
|
||||
var user = Market.fromMap(
|
||||
documentSnapshot.data, documentSnapshot.documentID);
|
||||
return user;
|
||||
}).toList();
|
||||
notifyListeners();
|
||||
});
|
||||
} catch (e) {
|
||||
log.warning("Error!! $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> addMarket(String marketName) async {
|
||||
await request("/markets", "POST",
|
||||
payload: {"name": marketName}, token: await getToken());
|
||||
}
|
||||
|
||||
Future<void> deleteMarket(String id) async {
|
||||
await request("/markets", "DELETE",
|
||||
payload: {"id": id}, token: await getToken());
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
import 'package:barcode_scan/barcode_scan.dart';
|
||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
||||
import 'package:fcs/vo/buyer.dart';
|
||||
import 'package:fcs/widget/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_icons/flutter_icons.dart';
|
||||
|
||||
class BarcodeScreenPage extends StatefulWidget {
|
||||
final BuyerProduct buyerProduct;
|
||||
const BarcodeScreenPage({Key key, this.buyerProduct}) : super(key: key);
|
||||
@override
|
||||
_BarcodeScreenPageState createState() => _BarcodeScreenPageState();
|
||||
}
|
||||
|
||||
class _BarcodeScreenPageState extends State<BarcodeScreenPage> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
bool _isLoading = false;
|
||||
String scanResult;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: primaryColor,
|
||||
title: Text("Bar Code Scranner"),
|
||||
),
|
||||
body: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
InkWell(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
"Scan : ",
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20),
|
||||
),
|
||||
Icon(
|
||||
Ionicons.ios_qr_scanner,
|
||||
size: 50,
|
||||
),
|
||||
],
|
||||
),
|
||||
onTap: () async {
|
||||
await scan();
|
||||
},
|
||||
)
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
Future scan() async {
|
||||
var result = await BarcodeScanner.scan();
|
||||
print("ScanResult => $result");
|
||||
setState(() => scanResult = result);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:fcs/fcs/common/domain/constants.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/package.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/user.dart';
|
||||
import 'package:fcs/fcs/common/domain/vo/shipment_status.dart';
|
||||
import 'package:fcs/fcs/common/pages/model/base_model.dart';
|
||||
import 'package:fcs/fcs/common/services/services.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@@ -12,174 +12,11 @@ class PackageModel extends BaseModel {
|
||||
final log = Logger('PackageModel');
|
||||
|
||||
StreamSubscription<QuerySnapshot> listener;
|
||||
static List<ShipmentStatus> statusHistory = [
|
||||
ShipmentStatus(status: "Received", date: DateTime(2020, 6, 1), done: true),
|
||||
ShipmentStatus(status: "Processed", date: DateTime(2020, 6, 1), done: true),
|
||||
ShipmentStatus(status: "Shipped", date: DateTime(2020, 6, 5), done: false),
|
||||
ShipmentStatus(status: "Arrived", date: DateTime(2020, 6, 7), done: false),
|
||||
ShipmentStatus(
|
||||
status: "Delivered", date: DateTime(2020, 6, 15), done: false)
|
||||
];
|
||||
|
||||
static List<Package> packages = [
|
||||
Package(
|
||||
shipmentNumber: "A202",
|
||||
receiverNumber: "3",
|
||||
receiverName: "Ko Myo Min",
|
||||
boxNumber: "1",
|
||||
rate: 7,
|
||||
packageType: "General",
|
||||
weight: 25,
|
||||
status: "Received",
|
||||
receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon',
|
||||
cargoDesc: "Computers",
|
||||
arrivedDate: DateTime(2020, 6, 1),
|
||||
market: "Amazon",
|
||||
id: "PKG2039",
|
||||
trackingID: "23-234s-asdfl",
|
||||
shipmentHistory: statusHistory),
|
||||
Package(
|
||||
shipmentNumber: "A202",
|
||||
receiverNumber: "3",
|
||||
receiverName: "Ko Myo Min",
|
||||
boxNumber: "2",
|
||||
rate: 7,
|
||||
packageType: "General",
|
||||
weight: 20,
|
||||
status: "Received",
|
||||
cargoDesc: "Clothes",
|
||||
arrivedDate: DateTime(2020, 6, 1),
|
||||
market: "Macy",
|
||||
trackingID: "asd-sdf-23498",
|
||||
id: "PKG2040",
|
||||
receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon',
|
||||
shipmentHistory: statusHistory),
|
||||
Package(
|
||||
shipmentNumber: "A202",
|
||||
receiverNumber: "3",
|
||||
receiverName: "Ko Myo Min",
|
||||
boxNumber: "3",
|
||||
rate: 7,
|
||||
packageType: "General",
|
||||
weight: 15,
|
||||
cargoDesc: "Shoes",
|
||||
status: "Processed",
|
||||
market: "Macy",
|
||||
trackingID: "8923-234-sd",
|
||||
id: "PKG2041",
|
||||
arrivedDate: DateTime(2020, 6, 1),
|
||||
receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon',
|
||||
shipmentHistory: statusHistory),
|
||||
Package(
|
||||
shipmentNumber: "A202",
|
||||
receiverNumber: "2",
|
||||
receiverName: "Ma Aye",
|
||||
boxNumber: "1",
|
||||
rate: 8,
|
||||
packageType: "Medicine",
|
||||
weight: 15,
|
||||
status: "Processed",
|
||||
market: "Macy",
|
||||
trackingID: "lsdf-sd09sdf",
|
||||
cargoDesc: "Dietary supplement",
|
||||
id: "PKG2042",
|
||||
arrivedDate: DateTime(2020, 6, 1),
|
||||
receiverAddress: '2 Shwe Taung Kyar St, Bahan Tsp, Yangon',
|
||||
shipmentHistory: statusHistory),
|
||||
Package(
|
||||
shipmentNumber: "A202",
|
||||
receiverNumber: "2",
|
||||
receiverName: "Ma Aye",
|
||||
boxNumber: "2",
|
||||
rate: 7,
|
||||
packageType: "General",
|
||||
cargoDesc: "Handbags",
|
||||
weight: 55,
|
||||
market: "Macy",
|
||||
trackingID: "234-sdflsdf-213",
|
||||
status: "Shipped",
|
||||
id: "PKG2043",
|
||||
arrivedDate: DateTime(2020, 6, 1),
|
||||
receiverAddress: '2 Shwe Taung Kyar St, Bahan Tsp, Yangon',
|
||||
shipmentHistory: statusHistory),
|
||||
Package(
|
||||
shipmentNumber: "A201",
|
||||
receiverNumber: "1",
|
||||
receiverName: "Ko Wai",
|
||||
boxNumber: "1",
|
||||
rate: 9,
|
||||
packageType: "Dangerous",
|
||||
cargoDesc: "Phones and Scooters",
|
||||
weight: 25,
|
||||
status: "Arrived",
|
||||
market: "Amazon",
|
||||
trackingID: "sdf-asdf-23489",
|
||||
id: "PKG2044",
|
||||
arrivedDate: DateTime(2020, 5, 21),
|
||||
receiverAddress: '3 Kambzwza St, Bahan Tsp, Yangon',
|
||||
shipmentHistory: statusHistory),
|
||||
Package(
|
||||
shipmentNumber: "A201",
|
||||
receiverNumber: "1",
|
||||
receiverName: "Ko Wai",
|
||||
boxNumber: "2",
|
||||
rate: 7,
|
||||
packageType: "General",
|
||||
cargoDesc: "Construction tools",
|
||||
weight: 5,
|
||||
status: "Processed",
|
||||
market: "Amazon",
|
||||
id: "PKG2045",
|
||||
trackingID: "oiuw-sdfpo-234",
|
||||
arrivedDate: DateTime(2020, 5, 21),
|
||||
receiverAddress: '3 Kambzwza St, Bahan Tsp, Yangon',
|
||||
shipmentHistory: statusHistory),
|
||||
];
|
||||
|
||||
List<Package> get getPackages {
|
||||
return packages
|
||||
..sort((e1, e2) {
|
||||
return e2.packageNumber.compareTo(e1.packageNumber);
|
||||
});
|
||||
}
|
||||
|
||||
List<Package> get completed {
|
||||
return packages.where((e) => e.status == "Processed").toList()
|
||||
..sort((e1, e2) {
|
||||
return e2.packageNumber.compareTo(e1.packageNumber);
|
||||
});
|
||||
}
|
||||
|
||||
List<Package> get shipped {
|
||||
return packages.where((e) => e.status == "Shipped").toList()
|
||||
..sort((e1, e2) {
|
||||
return e2.packageNumber.compareTo(e1.packageNumber);
|
||||
});
|
||||
}
|
||||
|
||||
List<Package> get arrived {
|
||||
return packages.where((e) => e.status == "Arrived").toList()
|
||||
..sort((e1, e2) {
|
||||
return e2.packageNumber.compareTo(e1.packageNumber);
|
||||
});
|
||||
}
|
||||
|
||||
List<Package> get delivered {
|
||||
return packages.where((e) => e.status == "Delivered").toList()
|
||||
..sort((e1, e2) {
|
||||
return e2.packageNumber.compareTo(e1.packageNumber);
|
||||
});
|
||||
}
|
||||
|
||||
List<Package> get upcoming {
|
||||
return packages.where((e) => e.status == "Received").toList()
|
||||
..sort((e1, e2) {
|
||||
return e2.packageNumber.compareTo(e1.packageNumber);
|
||||
});
|
||||
}
|
||||
List<Package> packages = [];
|
||||
|
||||
void initUser(user) {
|
||||
super.initUser(user);
|
||||
_loadPackages();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -188,9 +25,39 @@ class PackageModel extends BaseModel {
|
||||
packages = [];
|
||||
}
|
||||
|
||||
Future<void> _loadPackages() async {
|
||||
if (user == null) return;
|
||||
String path = "";
|
||||
if (user.isCustomer()) {
|
||||
path = "/$user_collection/${user.id}/$packages_collection";
|
||||
} else {
|
||||
path = "/$packages_collection";
|
||||
}
|
||||
try {
|
||||
listener = Firestore.instance
|
||||
.collection("$path")
|
||||
.where("is_delivered", isEqualTo: false)
|
||||
.snapshots()
|
||||
.listen((QuerySnapshot snapshot) {
|
||||
packages.clear();
|
||||
packages = snapshot.documents.map((documentSnapshot) {
|
||||
var package = Package.fromMap(
|
||||
documentSnapshot.data, documentSnapshot.documentID);
|
||||
return package;
|
||||
}).toList();
|
||||
notifyListeners();
|
||||
});
|
||||
} catch (e) {
|
||||
log.warning("Error!! $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<User>> searchUser(String term) {
|
||||
return Services.instance.userService.searchUser(term);
|
||||
}
|
||||
|
||||
createPackages(User user, List<Package> packages) {}
|
||||
Future<void> createPackages(User user, List<Package> packages) {
|
||||
return Services.instance.packageService
|
||||
.createPackages(packages, user.fcsID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:fcs/fcs/common/domain/vo/shipping_address.dart';
|
||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
||||
import 'package:fcs/fcs/common/localization/app_translations.dart';
|
||||
import 'package:fcs/fcs/common/pages/model/main_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/package/barcode_screen_page.dart';
|
||||
import 'package:fcs/fcs/common/pages/package/tracking_id_page.dart';
|
||||
import 'package:fcs/fcs/common/pages/package/shipping_address_editor.dart';
|
||||
import 'package:fcs/fcs/common/pages/package/shipping_address_list.dart';
|
||||
import 'package:fcs/fcs/common/pages/package/shipping_address_row.dart';
|
||||
@@ -12,6 +12,7 @@ import 'package:fcs/fcs/common/pages/widgets/bottom_up_page_route.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/fcs_expansion_tile.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/my_data_table.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/progress.dart';
|
||||
import 'package:fcs/pages/barcode_screen_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_icons/flutter_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
@@ -84,10 +84,10 @@ class _PackageListState extends State<PackageList> {
|
||||
scrollDirection: Axis.vertical,
|
||||
padding: EdgeInsets.only(top: 15),
|
||||
shrinkWrap: true,
|
||||
itemCount: packageModel.getPackages.length,
|
||||
itemCount: packageModel.packages.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PackageListRow(
|
||||
package: packageModel.getPackages[index],
|
||||
package: packageModel.packages[index],
|
||||
isReadOnly: false,
|
||||
);
|
||||
})),
|
||||
@@ -100,124 +100,4 @@ class _PackageListState extends State<PackageList> {
|
||||
BottomUpPageRoute(PackageNew()),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _upComing() {
|
||||
var packageModel = Provider.of<PackageModel>(context);
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
color: Colors.black,
|
||||
),
|
||||
scrollDirection: Axis.vertical,
|
||||
padding: EdgeInsets.only(top: 15),
|
||||
shrinkWrap: true,
|
||||
itemCount: packageModel.upcoming.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PackageListRow(
|
||||
package: packageModel.upcoming[index],
|
||||
isReadOnly: false,
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _completed() {
|
||||
var packageModel = Provider.of<PackageModel>(context);
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
color: Colors.black,
|
||||
),
|
||||
scrollDirection: Axis.vertical,
|
||||
padding: EdgeInsets.only(top: 15),
|
||||
shrinkWrap: true,
|
||||
itemCount: packageModel.completed.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PackageListRow(
|
||||
package: packageModel.completed[index],
|
||||
isReadOnly: false,
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _shipped() {
|
||||
var packageModel = Provider.of<PackageModel>(context);
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
color: Colors.black,
|
||||
),
|
||||
scrollDirection: Axis.vertical,
|
||||
padding: EdgeInsets.only(top: 15),
|
||||
shrinkWrap: true,
|
||||
itemCount: packageModel.shipped.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PackageListRow(
|
||||
package: packageModel.shipped[index],
|
||||
isReadOnly: false,
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _arrived() {
|
||||
var packageModel = Provider.of<PackageModel>(context);
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
color: Colors.black,
|
||||
),
|
||||
scrollDirection: Axis.vertical,
|
||||
padding: EdgeInsets.only(top: 15),
|
||||
shrinkWrap: true,
|
||||
itemCount: packageModel.arrived.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PackageListRow(
|
||||
package: packageModel.arrived[index],
|
||||
isReadOnly: false,
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _delivered() {
|
||||
var packageModel = Provider.of<PackageModel>(context);
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new ListView.separated(
|
||||
separatorBuilder: (context, index) => Divider(
|
||||
color: Colors.black,
|
||||
),
|
||||
scrollDirection: Axis.vertical,
|
||||
padding: EdgeInsets.only(top: 15),
|
||||
shrinkWrap: true,
|
||||
itemCount: packageModel.delivered.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PackageListRow(
|
||||
package: packageModel.delivered[index],
|
||||
isReadOnly: false,
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,12 +92,12 @@ class _PackageListRowtate extends State<PackageListRow> {
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(3.0),
|
||||
child: getStatus(_package.status),
|
||||
child: getStatus(_package.currentStatus),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(0),
|
||||
child: new Text(
|
||||
dateFormat.format(_package.arrivedDate),
|
||||
dateFormat.format(_package.currentStatusDate),
|
||||
style: new TextStyle(fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import 'package:barcode_scan/barcode_scan.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/package.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/user.dart';
|
||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
||||
import 'package:fcs/fcs/common/pages/package/tracking_id_page.dart';
|
||||
import 'package:fcs/fcs/common/pages/package/user_serach.dart';
|
||||
import 'package:fcs/fcs/common/pages/staff/model/staff_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/util.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/bottom_up_page_route.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/display_text.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/local_text.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'model/package_model.dart';
|
||||
|
||||
typedef void FindCallBack();
|
||||
|
||||
class PackageNew extends StatefulWidget {
|
||||
@@ -22,8 +23,6 @@ class PackageNew extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _PackageNewState extends State<PackageNew> {
|
||||
TextEditingController _phoneInput = new TextEditingController();
|
||||
|
||||
bool _isLoading = false;
|
||||
User user;
|
||||
|
||||
@@ -114,7 +113,7 @@ class _PackageNewState extends State<PackageNew> {
|
||||
Icons.add,
|
||||
color: primaryColor,
|
||||
),
|
||||
onPressed: _scan,
|
||||
onPressed: _addPackage,
|
||||
)
|
||||
],
|
||||
)),
|
||||
@@ -133,54 +132,23 @@ class _PackageNewState extends State<PackageNew> {
|
||||
));
|
||||
}
|
||||
|
||||
void _scan() async {
|
||||
PermissionStatus permission =
|
||||
await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
|
||||
if (permission != PermissionStatus.granted) {
|
||||
Map<PermissionGroup, PermissionStatus> permissions =
|
||||
await PermissionHandler()
|
||||
.requestPermissions([PermissionGroup.camera]);
|
||||
if (permissions[PermissionGroup.camera] != PermissionStatus.granted) {
|
||||
showMsgDialog(context, "Error", "Camera permission is not granted");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String barcode;
|
||||
try {
|
||||
barcode = await BarcodeScanner.scan();
|
||||
} on PlatformException catch (e) {
|
||||
if (e.code == BarcodeScanner.CameraAccessDenied) {
|
||||
print('The user did not grant the camera permission!');
|
||||
} else {
|
||||
print('Unknown error: $e');
|
||||
}
|
||||
} on FormatException {
|
||||
print(
|
||||
'null (User returned using the "back"-button before scanning anything. Result)');
|
||||
} catch (e) {
|
||||
print('Unknown error: $e');
|
||||
}
|
||||
|
||||
if (barcode != null) {
|
||||
if (packages.any((e) => e.trackingID == barcode)) {
|
||||
showMsgDialog(context, "Error", "Already scanned!");
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
packages.add(Package(trackingID: barcode));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget _packageItem(BuildContext context, int index) {
|
||||
return Row(
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8.0, left: 15),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: DisplayText(
|
||||
labelText: "Tracking ID",
|
||||
text: packages[index].trackingID,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(packages[index].market),
|
||||
Text(packages[index].trackingID),
|
||||
// DisplayText(
|
||||
// labelText: "Tracking ID",
|
||||
// text: packages[index].trackingID,
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
@@ -195,9 +163,27 @@ class _PackageNewState extends State<PackageNew> {
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_addPackage() async {
|
||||
Package package = await Navigator.push<Package>(
|
||||
context,
|
||||
BottomUpPageRoute(TrackingIDPage()),
|
||||
);
|
||||
|
||||
if (package != null) {
|
||||
if (packages.any((e) => e.trackingID == package.trackingID)) {
|
||||
showMsgDialog(context, "Error", "Already scanned!");
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
packages.add(package);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_create() async {
|
||||
if (user == null || packages == null || packages.length == 0) {
|
||||
showMsgDialog(context, "Error", "Invalid user!");
|
||||
@@ -206,9 +192,10 @@ class _PackageNewState extends State<PackageNew> {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
StaffModel staffModel = Provider.of<StaffModel>(context, listen: false);
|
||||
PackageModel packageModel =
|
||||
Provider.of<PackageModel>(context, listen: false);
|
||||
try {
|
||||
// await staffModel.updatePrivileges(this.selectedUser.id, privilegesIDs());
|
||||
await packageModel.createPackages(user, packages);
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
|
||||
175
lib/fcs/common/pages/package/tracking_id_page.dart
Normal file
175
lib/fcs/common/pages/package/tracking_id_page.dart
Normal file
@@ -0,0 +1,175 @@
|
||||
import 'package:barcode_scan/barcode_scan.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/market.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/package.dart';
|
||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
||||
import 'package:fcs/fcs/common/pages/market/market_editor.dart';
|
||||
import 'package:fcs/fcs/common/pages/market/model/market_model.dart';
|
||||
import 'package:fcs/fcs/common/pages/util.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/bottom_up_page_route.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/input_text.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/local_text.dart';
|
||||
import 'package:fcs/fcs/common/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_icons/flutter_icons.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
const MANAGE_MARKET = "Manage Market";
|
||||
|
||||
class TrackingIDPage extends StatefulWidget {
|
||||
const TrackingIDPage({Key key}) : super(key: key);
|
||||
@override
|
||||
_TrackingIDPageState createState() => _TrackingIDPageState();
|
||||
}
|
||||
|
||||
class _TrackingIDPageState extends State<TrackingIDPage> {
|
||||
TextEditingController _transcationIDCtl = new TextEditingController();
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
leading: new IconButton(
|
||||
icon: new Icon(Icons.close, color: primaryColor, size: 30),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
shadowColor: Colors.transparent,
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(18.0),
|
||||
child: ListView(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: InputText(
|
||||
labelTextKey: "package.tracking.id",
|
||||
controller: _transcationIDCtl,
|
||||
)),
|
||||
IconButton(
|
||||
icon: Icon(MaterialCommunityIcons.barcode_scan,
|
||||
size: 30, color: primaryColor),
|
||||
onPressed: _scan,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
dropDown(),
|
||||
SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
fcsButton(context, getLocalString(context, "btn.select"),
|
||||
callack: _select)
|
||||
],
|
||||
),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
String selectedMarket;
|
||||
Widget dropDown() {
|
||||
List<Market> _markets = Provider.of<MarketModel>(context).markets;
|
||||
List<String> markets = _markets.map((e) => e.name).toList();
|
||||
markets.insert(0, MANAGE_MARKET);
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 18.0),
|
||||
child: LocalText(
|
||||
context,
|
||||
"package.create.market",
|
||||
color: primaryColor,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 150,
|
||||
child: DropdownButton<String>(
|
||||
value: selectedMarket,
|
||||
style: TextStyle(color: Colors.black, fontSize: 14),
|
||||
underline: Container(
|
||||
height: 1,
|
||||
color: Colors.grey,
|
||||
),
|
||||
onChanged: (String newValue) {
|
||||
setState(() {
|
||||
if (newValue == MANAGE_MARKET) {
|
||||
selectedMarket = null;
|
||||
_manageMarket();
|
||||
return;
|
||||
}
|
||||
selectedMarket = newValue;
|
||||
});
|
||||
},
|
||||
isExpanded: true,
|
||||
items: markets.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
color: value == MANAGE_MARKET
|
||||
? secondaryColor
|
||||
: primaryColor)),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_manageMarket() {
|
||||
Navigator.push<Package>(
|
||||
context,
|
||||
BottomUpPageRoute(MarketEditor()),
|
||||
);
|
||||
}
|
||||
|
||||
_scan() async {
|
||||
PermissionStatus permission =
|
||||
await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
|
||||
if (permission != PermissionStatus.granted) {
|
||||
Map<PermissionGroup, PermissionStatus> permissions =
|
||||
await PermissionHandler()
|
||||
.requestPermissions([PermissionGroup.camera]);
|
||||
if (permissions[PermissionGroup.camera] != PermissionStatus.granted) {
|
||||
showMsgDialog(context, "Error", "Camera permission is not granted");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
String barcode = await BarcodeScanner.scan();
|
||||
if (barcode != null) {
|
||||
setState(() {
|
||||
_transcationIDCtl.text = barcode;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
print('error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
_select() {
|
||||
if (_transcationIDCtl.text == "" && selectedMarket == null) return;
|
||||
Navigator.pop(context,
|
||||
Package(trackingID: _transcationIDCtl.text, market: selectedMarket));
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ class UserSearchDelegate extends SearchDelegate<User> {
|
||||
UserSearchDelegate({this.callbackUserSelect});
|
||||
|
||||
@override
|
||||
String get searchFieldLabel => 'Enter FCS ID or Name';
|
||||
String get searchFieldLabel => 'Search by FCS ID or Name';
|
||||
|
||||
@override
|
||||
ThemeData appBarTheme(BuildContext context) {
|
||||
|
||||
@@ -54,7 +54,9 @@ class _ProfileState extends State<Profile> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
MainModel mainModel = Provider.of<MainModel>(context);
|
||||
|
||||
if (mainModel.user == null) {
|
||||
return Container();
|
||||
}
|
||||
final namebox = DisplayText(
|
||||
text: mainModel.user.name,
|
||||
labelText: getLocalString(context, "profile.name"),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:fcs/fcs/common/domain/constants.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/role.dart';
|
||||
@@ -9,6 +11,7 @@ import 'package:logging/logging.dart';
|
||||
|
||||
class StaffModel extends BaseModel {
|
||||
final log = Logger('StaffModel');
|
||||
StreamSubscription<QuerySnapshot> listener;
|
||||
|
||||
List<User> employees = [];
|
||||
List<Privilege> privileges = [];
|
||||
@@ -21,6 +24,7 @@ class StaffModel extends BaseModel {
|
||||
|
||||
@override
|
||||
logout() async {
|
||||
if (listener != null) listener.cancel();
|
||||
employees = [];
|
||||
}
|
||||
|
||||
@@ -28,7 +32,9 @@ class StaffModel extends BaseModel {
|
||||
if (user == null || !user.hasStaffs()) return;
|
||||
|
||||
try {
|
||||
Firestore.instance
|
||||
if (listener != null) listener.cancel();
|
||||
|
||||
listener = Firestore.instance
|
||||
.collection("/$user_collection")
|
||||
.where("is_employee", isEqualTo: true)
|
||||
.where("is_sys_admin", isEqualTo: false)
|
||||
@@ -41,8 +47,6 @@ class StaffModel extends BaseModel {
|
||||
return user;
|
||||
}).toList();
|
||||
notifyListeners();
|
||||
}).onError((e) {
|
||||
log.warning("Error! $e");
|
||||
});
|
||||
} catch (e) {
|
||||
log.warning("Error!! $e");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class BottomUpPageRoute extends PageRouteBuilder {
|
||||
class BottomUpPageRoute<T> extends PageRouteBuilder<T> {
|
||||
final Widget child;
|
||||
|
||||
BottomUpPageRoute(this.child)
|
||||
|
||||
@@ -40,7 +40,9 @@ class DisplayText extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 8.0, bottom: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Padding(
|
||||
iconData == null
|
||||
? Container()
|
||||
: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
iconData,
|
||||
|
||||
@@ -14,6 +14,7 @@ class InputText extends StatelessWidget {
|
||||
final bool withBorder;
|
||||
final Color borderColor;
|
||||
final TextInputType textInputType;
|
||||
final bool autoFocus;
|
||||
|
||||
const InputText(
|
||||
{Key key,
|
||||
@@ -24,6 +25,7 @@ class InputText extends StatelessWidget {
|
||||
this.maxLines = 1,
|
||||
this.withBorder = false,
|
||||
this.borderColor,
|
||||
this.autoFocus = false,
|
||||
this.textInputType})
|
||||
: super(key: key);
|
||||
@override
|
||||
@@ -34,7 +36,7 @@ class InputText extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 15.0, bottom: 5),
|
||||
child: TextFormField(
|
||||
controller: controller,
|
||||
autofocus: false,
|
||||
autofocus: autoFocus,
|
||||
cursorColor: primaryColor,
|
||||
style: textStyle,
|
||||
maxLines: maxLines,
|
||||
|
||||
@@ -15,7 +15,7 @@ class LocalText extends Text {
|
||||
: super(
|
||||
AppTranslations.of(context).text(translationKey,
|
||||
translationVariables: translationVariables),
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
style: Provider.of<LanguageModel>(context, listen: false).isEng
|
||||
? newLabelStyle(
|
||||
color: color,
|
||||
fontSize: fontSize,
|
||||
@@ -45,12 +45,15 @@ class LocalLargeTitle extends Text {
|
||||
|
||||
class TextLocalStyle extends Text {
|
||||
final BuildContext context;
|
||||
TextLocalStyle(this.context, String text, {Color color, double fontSize,FontWeight fontWeight})
|
||||
TextLocalStyle(this.context, String text,
|
||||
{Color color, double fontSize, FontWeight fontWeight})
|
||||
: super(text,
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
? TextStyle(color: color, fontSize: fontSize,fontWeight: fontWeight)
|
||||
? TextStyle(
|
||||
color: color, fontSize: fontSize, fontWeight: fontWeight)
|
||||
: TextStyle(
|
||||
color: color,
|
||||
fontFamily: "MyanmarUnicode",
|
||||
fontSize: fontSize,fontWeight: fontWeight));
|
||||
fontSize: fontSize,
|
||||
fontWeight: fontWeight));
|
||||
}
|
||||
|
||||
20
lib/fcs/common/services/package_imp.dart
Normal file
20
lib/fcs/common/services/package_imp.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
import 'package:fcs/fcs/common/data/providers/package_data_provider.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/connectivity.dart';
|
||||
import 'package:fcs/fcs/common/domain/entities/package.dart';
|
||||
import 'package:fcs/fcs/common/services/package_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PackageServiceImp implements PackageService {
|
||||
PackageServiceImp({
|
||||
@required this.connectivity,
|
||||
@required this.packageDataProvider,
|
||||
});
|
||||
|
||||
final Connectivity connectivity;
|
||||
final PackageDataProvider packageDataProvider;
|
||||
|
||||
@override
|
||||
Future<void> createPackages(List<Package> packages, String fcsID) {
|
||||
return packageDataProvider.createPackages(packages, fcsID);
|
||||
}
|
||||
}
|
||||
5
lib/fcs/common/services/package_service.dart
Normal file
5
lib/fcs/common/services/package_service.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
import 'package:fcs/fcs/common/domain/entities/package.dart';
|
||||
|
||||
abstract class PackageService {
|
||||
Future<void> createPackages(List<Package> packages, String fcsID);
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
import 'package:fcs/fcs/common/data/providers/auth_fb.dart';
|
||||
import 'package:fcs/fcs/common/data/providers/package_data_provider.dart';
|
||||
import 'package:fcs/fcs/common/data/providers/user_data_provider.dart';
|
||||
import 'package:fcs/fcs/common/services/auth_imp.dart';
|
||||
import 'package:fcs/fcs/common/services/messaging_imp.dart';
|
||||
import 'package:fcs/fcs/common/services/messaging_service.dart';
|
||||
import 'package:fcs/fcs/common/services/package_imp.dart';
|
||||
import 'package:fcs/fcs/common/services/package_service.dart';
|
||||
import 'package:fcs/fcs/common/services/user_imp.dart';
|
||||
import 'package:fcs/fcs/common/services/user_service.dart';
|
||||
|
||||
@@ -13,6 +16,7 @@ class Services {
|
||||
|
||||
AuthService _authService;
|
||||
UserService _userService;
|
||||
PackageService _packageService;
|
||||
MessagingService _messagingService;
|
||||
Services._() {
|
||||
_authService = AuthServiceImp(
|
||||
@@ -22,9 +26,12 @@ class Services {
|
||||
_userService = UserServiceImp(
|
||||
connectivity: null, userDataProvider: UserDataProvider());
|
||||
_messagingService = MessagingServiceImp();
|
||||
_packageService = PackageServiceImp(
|
||||
connectivity: null, packageDataProvider: PackageDataProvider());
|
||||
}
|
||||
|
||||
AuthService get authService => _authService;
|
||||
UserService get userService => _userService;
|
||||
MessagingService get messagingService => _messagingService;
|
||||
PackageService get packageService => _packageService;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user