Merge branch 'master' of https://git.mokkon.com/sainw/fcs
17
.vscode/launch.json
vendored
@@ -1,6 +1,18 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Prod",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"program": "lib/main-prod.dart",
|
||||||
|
"args": [
|
||||||
|
"-t",
|
||||||
|
"lib/main-prod.dart",
|
||||||
|
"--flavor",
|
||||||
|
"prod"
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Local Dev",
|
"name": "Local Dev",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
@@ -45,17 +57,14 @@
|
|||||||
"lib/main-dev.dart",
|
"lib/main-dev.dart",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Pro",
|
"name": "Prod iOS",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "dart",
|
"type": "dart",
|
||||||
"program": "lib/main-prod.dart",
|
"program": "lib/main-prod.dart",
|
||||||
"args": [
|
"args": [
|
||||||
"-t",
|
"-t",
|
||||||
"lib/main-prod.dart",
|
"lib/main-prod.dart",
|
||||||
"--flavor",
|
|
||||||
"prod"
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -39,14 +39,5 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<provider
|
|
||||||
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
|
|
||||||
android:authorities="${applicationId}.flutter_downloader.provider"
|
|
||||||
android:exported="false"
|
|
||||||
android:grantUriPermissions="true">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
||||||
android:resource="@xml/provider_paths"/>
|
|
||||||
</provider>
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
1
android/settings_aar.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
||||||
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 203 KiB |
BIN
assets/admin.png
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 48 KiB |
BIN
assets/block.png
|
Before Width: | Height: | Size: 26 KiB |
BIN
assets/buyer.png
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
|
Before Width: | Height: | Size: 239 KiB After Width: | Height: | Size: 239 KiB |
|
Before Width: | Height: | Size: 19 KiB |
51897
assets/demo.pdf
|
Before Width: | Height: | Size: 20 KiB |
BIN
assets/do.png
|
Before Width: | Height: | Size: 34 KiB |
BIN
assets/email.png
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
BIN
assets/logo.png
|
Before Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
BIN
assets/page.png
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 870 B |
BIN
assets/pay.png
|
Before Width: | Height: | Size: 2.2 KiB |
BIN
assets/pdo.png
|
Before Width: | Height: | Size: 10 KiB |
BIN
assets/phone.png
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 12 KiB |
BIN
assets/pin.png
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 17 KiB |
BIN
assets/quota.png
|
Before Width: | Height: | Size: 10 KiB |
BIN
assets/r.jpg
|
Before Width: | Height: | Size: 93 KiB |
BIN
assets/reg.png
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
BIN
assets/sales.png
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 10 KiB |
BIN
assets/term.png
|
Before Width: | Height: | Size: 42 KiB |
BIN
assets/truck.png
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 22 KiB |
BIN
assets/whole.png
|
Before Width: | Height: | Size: 36 KiB |
@@ -37,6 +37,8 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>Camera permission is required for barcode scanning.</string>
|
<string>Camera permission is required for barcode scanning.</string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>Photo library usage is required for FCS team to upload package photos</string>
|
||||||
<key>UIBackgroundModes</key>
|
<key>UIBackgroundModes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>fetch</string>
|
<string>fetch</string>
|
||||||
|
|||||||
175
lib/app.dart
@@ -1,54 +1,33 @@
|
|||||||
import 'package:fcs/fcs/common/localization/app_translations_delegate.dart';
|
import 'package:fcs/localization/app_translations_delegate.dart';
|
||||||
import 'package:fcs/fcs/common/localization/transalation.dart';
|
import 'package:fcs/localization/transalation.dart';
|
||||||
import 'package:fcs/fcs/common/pages/contact/model/contact_model.dart';
|
import 'package:fcs/pages/carton/model/carton_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/customer/model/customer_model.dart';
|
import 'package:fcs/pages/chat/model/message_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/faq/model/faq_model.dart';
|
import 'package:fcs/pages/contact/model/contact_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/initial_language_selection.dart';
|
import 'package:fcs/pages/customer/model/customer_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/market/model/market_model.dart';
|
import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/model/language_model.dart';
|
import 'package:fcs/pages/discount/model/discount_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/model/main_model.dart' as fcs;
|
import 'package:fcs/pages/faq/model/faq_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/package/model/package_model.dart';
|
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/package/model/shipment_model.dart';
|
import 'package:fcs/pages/main/home_page.dart';
|
||||||
import 'package:fcs/fcs/common/pages/payment_methods/model/payment_method_model.dart';
|
import 'package:fcs/pages/main/initial_language_selection.dart';
|
||||||
import 'package:fcs/fcs/common/pages/staff/model/staff_model.dart';
|
import 'package:fcs/pages/invoice/model/invoice_model.dart';
|
||||||
import 'package:fcs/fcs/common/pages/term/model/term_model.dart';
|
import 'package:fcs/pages/market/model/market_model.dart';
|
||||||
import 'package:fcs/model/buyer_model.dart';
|
import 'package:fcs/pages/main/model/language_model.dart';
|
||||||
import 'package:fcs/model/delivery_model.dart';
|
import 'package:fcs/pages/main/model/main_model.dart';
|
||||||
import 'package:fcs/model/discount_model.dart';
|
import 'package:fcs/pages/package/model/package_model.dart';
|
||||||
import 'package:fcs/model/manual_model.dart';
|
import 'package:fcs/pages/payment_methods/model/payment_method_model.dart';
|
||||||
import 'package:fcs/model/notification_model.dart';
|
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
|
||||||
import 'package:fcs/model/pd_model.dart';
|
import 'package:fcs/pages/shipment/model/shipment_model.dart';
|
||||||
import 'package:fcs/model/reg_model.dart';
|
import 'package:fcs/pages/main/splash_page.dart';
|
||||||
import 'package:fcs/model/report_model.dart';
|
import 'package:fcs/pages/staff/model/staff_model.dart';
|
||||||
import 'package:fcs/model/storage_model.dart';
|
import 'package:fcs/pages/term/model/term_model.dart';
|
||||||
import 'package:fcs/model/test_model.dart';
|
import 'package:fcs/pages/main/welcome_page.dart';
|
||||||
import 'package:fcs/pages/email_page.dart';
|
|
||||||
import 'package:fcs/pages/login_page.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'fcs/common/pages/chat/model/message_model.dart';
|
import 'pages/delivery/model/delivery_model.dart';
|
||||||
import 'fcs/common/pages/home_page.dart';
|
|
||||||
import 'fcs/common/pages/splash_page.dart';
|
|
||||||
import 'fcs/common/pages/welcome_page.dart';
|
|
||||||
import 'model/announcement_model.dart';
|
|
||||||
import 'model/chart_model.dart';
|
|
||||||
import 'model/device_model.dart';
|
|
||||||
import 'model/do_model.dart';
|
|
||||||
import 'model/invoice_model.dart';
|
|
||||||
import 'model/log_model.dart';
|
|
||||||
import 'model/main_model.dart';
|
|
||||||
import 'model/pickup_model.dart';
|
|
||||||
import 'model/po_model.dart';
|
|
||||||
import 'model/product_model.dart';
|
|
||||||
import 'model/report_user_model.dart';
|
|
||||||
import 'model/shipment_rate_model.dart';
|
|
||||||
import 'model/user_model.dart';
|
|
||||||
import 'model_fcs/box_model.dart';
|
|
||||||
import 'pages/term.dart';
|
|
||||||
|
|
||||||
class App extends StatefulWidget {
|
class App extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@@ -56,89 +35,48 @@ class App extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _AppState extends State<App> {
|
class _AppState extends State<App> {
|
||||||
final fcs.MainModel mainModel2 = new fcs.MainModel();
|
final MainModel mainModel = new MainModel();
|
||||||
final ContactModel contactModel = new ContactModel();
|
final ContactModel contactModel = new ContactModel();
|
||||||
final TermModel termModel = new TermModel();
|
final TermModel termModel = new TermModel();
|
||||||
final MainModel mainModel = new MainModel();
|
|
||||||
final FAQModel faqModel = new FAQModel();
|
final FAQModel faqModel = new FAQModel();
|
||||||
final PaymentMethodModel paymentMethodModel = new PaymentMethodModel();
|
final PaymentMethodModel paymentMethodModel = new PaymentMethodModel();
|
||||||
|
final FcsShipmentModel fcsShipmentModel = new FcsShipmentModel();
|
||||||
final UserModel userModel = new UserModel();
|
|
||||||
final ProductModel productModel = new ProductModel();
|
|
||||||
final POSubmissionModel poSubmissionModel = new POSubmissionModel();
|
|
||||||
final DOModel doModel = new DOModel();
|
|
||||||
final LanguageModel lanuguageModel = new LanguageModel();
|
final LanguageModel lanuguageModel = new LanguageModel();
|
||||||
final StorageModel storageModel = new StorageModel();
|
final ShipmentModel shipmentModel = new ShipmentModel();
|
||||||
final PDModel pdModel = new PDModel();
|
|
||||||
final RegModel regModel = new RegModel();
|
|
||||||
final BuyerModel buyerModel = new BuyerModel();
|
|
||||||
final NotificationModel notificationModel = new NotificationModel();
|
|
||||||
final ChartModel chartModel = new ChartModel();
|
|
||||||
final DeliveryModel deliveryModel = new DeliveryModel();
|
|
||||||
final ManualModel manualModel = new ManualModel();
|
|
||||||
final TestModel testModel = new TestModel();
|
|
||||||
final LogModel logModel = new LogModel();
|
|
||||||
final PhoneDeviceModel phoneDeviceModel = new PhoneDeviceModel();
|
|
||||||
final ReportModel reportModel = new ReportModel();
|
|
||||||
final AnnouncementModel announcementModel = new AnnouncementModel();
|
|
||||||
final ReportUserModel reportUserModel = new ReportUserModel();
|
|
||||||
final PickUpModel pickUpModel = new PickUpModel();
|
|
||||||
final ShipmentRateModel shipmentRateModel = new ShipmentRateModel();
|
final ShipmentRateModel shipmentRateModel = new ShipmentRateModel();
|
||||||
final BoxModel boxModel = new BoxModel();
|
final CartonModel boxModel = new CartonModel();
|
||||||
final MessageModel messageModel = new MessageModel();
|
final MessageModel messageModel = new MessageModel();
|
||||||
final InvoiceModel invoiceModel = new InvoiceModel();
|
final InvoiceModel invoiceModel = new InvoiceModel();
|
||||||
final CustomerModel customerModel = new CustomerModel();
|
final CustomerModel customerModel = new CustomerModel();
|
||||||
final DiscountModel discountModel = new DiscountModel();
|
final DiscountModel discountModel = new DiscountModel();
|
||||||
final StaffModel staffModel = new StaffModel();
|
final StaffModel staffModel = new StaffModel();
|
||||||
final ShipmentModel shipmentModel = new ShipmentModel();
|
final DeliveryAddressModel deliveryAddressModel = new DeliveryAddressModel();
|
||||||
final PackageModel packageModel = new PackageModel();
|
final PackageModel packageModel = new PackageModel();
|
||||||
final MarketModel marketModel = new MarketModel();
|
final MarketModel marketModel = new MarketModel();
|
||||||
|
final DeliveryModel deliveryModel = new DeliveryModel();
|
||||||
|
|
||||||
AppTranslationsDelegate _newLocaleDelegate;
|
AppTranslationsDelegate _newLocaleDelegate;
|
||||||
static FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
|
||||||
FlutterLocalNotificationsPlugin();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
mainModel2
|
mainModel
|
||||||
..addModel(customerModel)
|
..addModel(customerModel)
|
||||||
..addModel(staffModel)
|
..addModel(staffModel)
|
||||||
..addModel(shipmentModel)
|
..addModel(deliveryAddressModel)
|
||||||
..addModel(packageModel)
|
..addModel(packageModel)
|
||||||
..addModel(messageModel)
|
..addModel(messageModel)
|
||||||
..addModel(marketModel);
|
..addModel(fcsShipmentModel)
|
||||||
mainModel2.init();
|
..addModel(discountModel)
|
||||||
|
..addModel(shipmentRateModel)
|
||||||
|
..addModel(boxModel)
|
||||||
|
..addModel(shipmentModel)
|
||||||
|
..addModel(invoiceModel)
|
||||||
|
..addModel(marketModel)
|
||||||
|
..addModel(deliveryModel);
|
||||||
|
|
||||||
_newLocaleDelegate = AppTranslationsDelegate(newLocale: null);
|
_newLocaleDelegate = AppTranslationsDelegate(newLocale: null);
|
||||||
Translation().onLocaleChanged = onLocaleChange;
|
Translation().onLocaleChanged = onLocaleChange;
|
||||||
mainModel
|
|
||||||
..addModel(userModel)
|
|
||||||
..addModel(storageModel)
|
|
||||||
..addModel(regModel)
|
|
||||||
..addModel(poSubmissionModel)
|
|
||||||
..addModel(doModel)
|
|
||||||
..addModel(productModel)
|
|
||||||
..addModel(pdModel)
|
|
||||||
..addModel(buyerModel)
|
|
||||||
..addModel(notificationModel)
|
|
||||||
..addModel(chartModel)
|
|
||||||
..addModel(deliveryModel)
|
|
||||||
..addModel(logModel)
|
|
||||||
..addModel(manualModel)
|
|
||||||
..addModel(phoneDeviceModel)
|
|
||||||
..addModel(regModel)
|
|
||||||
..addModel(announcementModel)
|
|
||||||
..addModel(reportModel)
|
|
||||||
..addModel(testModel)
|
|
||||||
..addModel(reportUserModel)
|
|
||||||
..addModel(pickUpModel)
|
|
||||||
..addModel(shipmentRateModel)
|
|
||||||
..addModel(boxModel)
|
|
||||||
..addModel(shipmentRateModel)
|
|
||||||
..addModel(invoiceModel)
|
|
||||||
..addModel(discountModel);
|
|
||||||
this.mainModel.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onLocaleChange(Locale locale) {
|
void onLocaleChange(Locale locale) {
|
||||||
@@ -152,11 +90,6 @@ class _AppState extends State<App> {
|
|||||||
'/': (_) => SplashScreen(),
|
'/': (_) => SplashScreen(),
|
||||||
'/welcome': (_) => WelcomePage(),
|
'/welcome': (_) => WelcomePage(),
|
||||||
'/home': (_) => HomePage(),
|
'/home': (_) => HomePage(),
|
||||||
'/term': (context) => Term(
|
|
||||||
agreePage: true,
|
|
||||||
),
|
|
||||||
'/login': (context) => LoginPage(),
|
|
||||||
'/email': (context) => EmailPage(),
|
|
||||||
'/language_selection': (context) => InitialLanguageSelectionPage(),
|
'/language_selection': (context) => InitialLanguageSelectionPage(),
|
||||||
};
|
};
|
||||||
return routes;
|
return routes;
|
||||||
@@ -167,40 +100,24 @@ class _AppState extends State<App> {
|
|||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
ChangeNotifierProvider.value(value: mainModel),
|
ChangeNotifierProvider.value(value: mainModel),
|
||||||
ChangeNotifierProvider.value(value: userModel),
|
|
||||||
ChangeNotifierProvider.value(value: productModel),
|
|
||||||
ChangeNotifierProvider.value(value: staffModel),
|
ChangeNotifierProvider.value(value: staffModel),
|
||||||
ChangeNotifierProvider.value(value: poSubmissionModel),
|
|
||||||
ChangeNotifierProvider.value(value: doModel),
|
|
||||||
ChangeNotifierProvider.value(value: storageModel),
|
|
||||||
ChangeNotifierProvider.value(value: pdModel),
|
|
||||||
ChangeNotifierProvider.value(value: lanuguageModel),
|
ChangeNotifierProvider.value(value: lanuguageModel),
|
||||||
ChangeNotifierProvider.value(value: regModel),
|
|
||||||
ChangeNotifierProvider.value(value: buyerModel),
|
|
||||||
ChangeNotifierProvider.value(value: notificationModel),
|
|
||||||
ChangeNotifierProvider.value(value: chartModel),
|
|
||||||
ChangeNotifierProvider.value(value: deliveryModel),
|
|
||||||
ChangeNotifierProvider.value(value: logModel),
|
|
||||||
ChangeNotifierProvider.value(value: phoneDeviceModel),
|
|
||||||
ChangeNotifierProvider.value(value: reportModel),
|
|
||||||
ChangeNotifierProvider.value(value: announcementModel),
|
|
||||||
ChangeNotifierProvider.value(value: reportUserModel),
|
|
||||||
ChangeNotifierProvider.value(value: pickUpModel),
|
|
||||||
ChangeNotifierProvider.value(value: shipmentRateModel),
|
|
||||||
ChangeNotifierProvider.value(value: shipmentModel),
|
ChangeNotifierProvider.value(value: shipmentModel),
|
||||||
|
ChangeNotifierProvider.value(value: shipmentRateModel),
|
||||||
|
ChangeNotifierProvider.value(value: deliveryAddressModel),
|
||||||
ChangeNotifierProvider.value(value: packageModel),
|
ChangeNotifierProvider.value(value: packageModel),
|
||||||
ChangeNotifierProvider.value(value: boxModel),
|
ChangeNotifierProvider.value(value: boxModel),
|
||||||
ChangeNotifierProvider.value(value: messageModel),
|
ChangeNotifierProvider.value(value: messageModel),
|
||||||
ChangeNotifierProvider.value(value: invoiceModel),
|
ChangeNotifierProvider.value(value: invoiceModel),
|
||||||
ChangeNotifierProvider.value(value: customerModel),
|
ChangeNotifierProvider.value(value: customerModel),
|
||||||
ChangeNotifierProvider.value(value: discountModel),
|
ChangeNotifierProvider.value(value: discountModel),
|
||||||
ChangeNotifierProvider.value(value: testModel),
|
|
||||||
ChangeNotifierProvider.value(value: mainModel2),
|
|
||||||
ChangeNotifierProvider.value(value: contactModel),
|
ChangeNotifierProvider.value(value: contactModel),
|
||||||
ChangeNotifierProvider.value(value: termModel),
|
ChangeNotifierProvider.value(value: termModel),
|
||||||
ChangeNotifierProvider.value(value: faqModel),
|
ChangeNotifierProvider.value(value: faqModel),
|
||||||
ChangeNotifierProvider.value(value: paymentMethodModel),
|
ChangeNotifierProvider.value(value: paymentMethodModel),
|
||||||
ChangeNotifierProvider.value(value: marketModel),
|
ChangeNotifierProvider.value(value: marketModel),
|
||||||
|
ChangeNotifierProvider.value(value: fcsShipmentModel),
|
||||||
|
ChangeNotifierProvider.value(value: deliveryModel),
|
||||||
],
|
],
|
||||||
child: Consumer<LanguageModel>(
|
child: Consumer<LanguageModel>(
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
@@ -225,9 +142,7 @@ class _AppState extends State<App> {
|
|||||||
routes: route(context),
|
routes: route(context),
|
||||||
localizationsDelegates: [
|
localizationsDelegates: [
|
||||||
_newLocaleDelegate,
|
_newLocaleDelegate,
|
||||||
//provides localised strings
|
|
||||||
GlobalMaterialLocalizations.delegate,
|
GlobalMaterialLocalizations.delegate,
|
||||||
//provides RTL support
|
|
||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalWidgetsLocalizations.delegate,
|
||||||
],
|
],
|
||||||
supportedLocales: Translation().supportedLocales());
|
supportedLocales: Translation().supportedLocales());
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:charts_flutter/flutter.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/charts/qtyby_customer_table.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/model/product_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
class BarChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_BarChartState createState() => _BarChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _BarChartState extends State<BarChart> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
List<POChartData> chartSummary = new List();
|
|
||||||
List<charts.Series<POChartData, String>> series;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
var chartModel = Provider.of<ChartModel>(context, listen: false);
|
|
||||||
this.chartSummary = chartModel.chartSummary;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var productModel = Provider.of<ProductModel>(context);
|
|
||||||
if (this.chartSummary.isNotEmpty) {
|
|
||||||
this.chartSummary.forEach((s) {
|
|
||||||
productModel.products.forEach((p) {
|
|
||||||
if (p.id == s.productID) {
|
|
||||||
s.displayOrder = p.displayOrder;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this
|
|
||||||
.chartSummary
|
|
||||||
.sort((s1, s2) => s1.displayOrder.compareTo(s2.displayOrder));
|
|
||||||
}
|
|
||||||
List<charts.Series<POChartData, String>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: this.chartSummary,
|
|
||||||
domainFn: (POChartData series, _) => series.productName,
|
|
||||||
measureFn: (POChartData series, _) => series.balanceQty,
|
|
||||||
colorFn: (POChartData series, _) =>
|
|
||||||
charts.ColorUtil.fromDartColor(series.getColor),
|
|
||||||
labelAccessorFn: (POChartData series, _) =>
|
|
||||||
'${numberFormatter.format(series.balanceQty)}'),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, 'product.balance_qty',
|
|
||||||
color: primaryColor, fontSize: 16),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.refresh,
|
|
||||||
color: primaryColor,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
_load();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.BarChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
vertical: false,
|
|
||||||
defaultRenderer: new charts.BarRendererConfig(
|
|
||||||
barRendererDecorator: new charts.BarLabelDecorator<String>(
|
|
||||||
labelPosition: charts.BarLabelPosition.auto,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
selectionModels: [
|
|
||||||
SelectionModelConfig(changedListener: (SelectionModel model) {
|
|
||||||
final selectedDatum = model.selectedDatum;
|
|
||||||
if (selectedDatum.isNotEmpty) {
|
|
||||||
selectedDatum.forEach((charts.SeriesDatum datumPair) {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => QtyByCustomerTable(
|
|
||||||
poChartData: datumPair.datum,
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _load() async {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
var _s = await chartModel.loadSummary();
|
|
||||||
setState(() {
|
|
||||||
this.chartSummary = _s ?? [];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
import 'delivery_do_line_detail.dart';
|
|
||||||
|
|
||||||
class DODeliveryLineChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_DODeliveryLineChartState createState() => _DODeliveryLineChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DODeliveryLineChartState extends State<DODeliveryLineChart> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
List<charts.Series<Data, DateTime>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: chartModel.revenue.getDeliveryDo(),
|
|
||||||
domainFn: (Data series, _) => series.date,
|
|
||||||
measureFn: (Data series, _) => series.count,
|
|
||||||
colorFn: (_, __) => charts.ColorUtil.fromDartColor(primaryColor),
|
|
||||||
labelAccessorFn: (Data series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "delivery.do.title",
|
|
||||||
color: primaryColor, fontSize: 16),
|
|
||||||
InkWell(
|
|
||||||
child: LocalText(
|
|
||||||
context,
|
|
||||||
"delivery.do.details",
|
|
||||||
color: secondaryColor,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
|
||||||
builder: (_) => DODeliveryLineDetail()));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.TimeSeriesChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
defaultRenderer: new charts.LineRendererConfig(
|
|
||||||
includePoints: true,
|
|
||||||
),
|
|
||||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
|
||||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
|
|
||||||
zeroBound: false, desiredTickCount: 10),
|
|
||||||
renderSpec: new charts.GridlineRendererSpec(
|
|
||||||
lineStyle: charts.LineStyleSpec(
|
|
||||||
dashPattern: [4, 4],
|
|
||||||
))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class DODeliveryLineDetail extends StatefulWidget {
|
|
||||||
const DODeliveryLineDetail();
|
|
||||||
@override
|
|
||||||
_DODeliveryLineDetailState createState() => _DODeliveryLineDetailState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DODeliveryLineDetailState extends State<DODeliveryLineDetail> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: LocalText(
|
|
||||||
context,
|
|
||||||
'delivery.do.counts',
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: EdgeInsets.only(left: 20),
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 100,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "delivery.date")),
|
|
||||||
MyDataColumn(label: LocalText(context, "delivery.do.count")),
|
|
||||||
],
|
|
||||||
rows: getProductRow(chartModel.revenue.getDeliveryDo()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow(List<Data> doList) {
|
|
||||||
return doList.map((d) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(dateFormatter.format(d.date), style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(
|
|
||||||
numberFormatter.format(d.count),
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
import 'delivery_do_summary_details.dart';
|
|
||||||
|
|
||||||
class DeliveryDoSummaryChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_DeliveryDoSummaryChartState createState() => _DeliveryDoSummaryChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DeliveryDoSummaryChartState extends State<DeliveryDoSummaryChart> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
List<charts.Series<Data, String>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: chartModel.revenue.getDeliveryDoSummary(),
|
|
||||||
domainFn: (Data series, _) => "${series.totalDay}days",
|
|
||||||
measureFn: (Data series, _) => series.totalCount,
|
|
||||||
labelAccessorFn: (Data series, _) =>
|
|
||||||
'${numberFormatter.format(series.totalCount)}'),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "delivery.do.summary",
|
|
||||||
color: primaryColor, fontSize: 16),
|
|
||||||
InkWell(
|
|
||||||
child: LocalText(
|
|
||||||
context,
|
|
||||||
"delivery.do.details",
|
|
||||||
color: secondaryColor,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
|
||||||
builder: (_) => DeliveryDoSummaryDetail()));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.BarChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
vertical: false,
|
|
||||||
defaultRenderer: new charts.BarRendererConfig(
|
|
||||||
barRendererDecorator: new charts.BarLabelDecorator<String>(
|
|
||||||
labelPosition: charts.BarLabelPosition.auto,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class DeliveryDoSummaryDetail extends StatefulWidget {
|
|
||||||
const DeliveryDoSummaryDetail();
|
|
||||||
@override
|
|
||||||
_DeliveryDoSummaryDetailState createState() =>
|
|
||||||
_DeliveryDoSummaryDetailState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DeliveryDoSummaryDetailState extends State<DeliveryDoSummaryDetail> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: LocalText(
|
|
||||||
context,
|
|
||||||
'delivery.do.sum.counts',
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: EdgeInsets.only(left: 20),
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 100,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "delivery.days")),
|
|
||||||
MyDataColumn(label: LocalText(context, "delivery.do.count")),
|
|
||||||
],
|
|
||||||
rows: getProductRow(chartModel.revenue.getDeliveryDoSummary()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow(List<Data> doList) {
|
|
||||||
return doList.map((d) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(d.totalDay.toString(), style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(
|
|
||||||
numberFormatter.format(d.totalCount),
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
import 'delivery_line_data.dart';
|
|
||||||
|
|
||||||
class DeliveryBarChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_DeliveryBarChartState createState() => _DeliveryBarChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DeliveryBarChartState extends State<DeliveryBarChart> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
List<charts.Series<Data, String>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: chartModel.revenue.getDelivery(),
|
|
||||||
domainFn: (Data series, _) =>
|
|
||||||
"${series.date.day}-${series.date.month}-${series.date.year}",
|
|
||||||
measureFn: (Data series, _) => series.amount,
|
|
||||||
labelAccessorFn: (Data series, _) =>
|
|
||||||
'${numberFormatter.format(series.amount)}'),
|
|
||||||
];
|
|
||||||
|
|
||||||
List<charts.Series<Data, DateTime>> seriesLine = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: chartModel.revenue.getDelivery(),
|
|
||||||
domainFn: (Data series, _) => series.date,
|
|
||||||
measureFn: (Data series, _) => series.amount,
|
|
||||||
colorFn: (_, __) => charts.ColorUtil.fromDartColor(primaryColor),
|
|
||||||
labelAccessorFn: (Data series, _) =>
|
|
||||||
'${numberFormatter.format(series.amount)}',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "delivery", color: primaryColor, fontSize: 16),
|
|
||||||
InkWell(
|
|
||||||
child: LocalText(
|
|
||||||
context,
|
|
||||||
"delivery.detail",
|
|
||||||
color: secondaryColor,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(
|
|
||||||
MaterialPageRoute(builder: (_) => DeliveryBarData()));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.TimeSeriesChart(
|
|
||||||
seriesLine,
|
|
||||||
animate: true,
|
|
||||||
defaultRenderer: new charts.LineRendererConfig(
|
|
||||||
includePoints: true,
|
|
||||||
),
|
|
||||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
|
||||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
|
|
||||||
zeroBound: false, desiredTickCount: 10),
|
|
||||||
renderSpec: new charts.GridlineRendererSpec(
|
|
||||||
lineStyle: charts.LineStyleSpec(
|
|
||||||
dashPattern: [4, 4],
|
|
||||||
))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Expanded(
|
|
||||||
// child: charts.BarChart(
|
|
||||||
// series,
|
|
||||||
// animate: true,
|
|
||||||
// vertical: true,
|
|
||||||
// defaultRenderer: new charts.BarRendererConfig(
|
|
||||||
// barRendererDecorator: new charts.BarLabelDecorator<String>(
|
|
||||||
// labelPosition: charts.BarLabelPosition.auto,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/model/main_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/number_cell.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
import 'delivery_line_detail.dart';
|
|
||||||
|
|
||||||
class DeliveryBarData extends StatefulWidget {
|
|
||||||
const DeliveryBarData();
|
|
||||||
@override
|
|
||||||
_DeliveryBarDataState createState() => _DeliveryBarDataState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DeliveryBarDataState extends State<DeliveryBarData> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: LocalText(
|
|
||||||
context,
|
|
||||||
'delivery.data.title',
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: EdgeInsets.only(left: 20),
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 100,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "delivery.date")),
|
|
||||||
MyDataColumn(
|
|
||||||
label: LocalText(context, "delivery.qty"), numeric: true),
|
|
||||||
],
|
|
||||||
rows: getProductRow(chartModel.revenue.getDelivery()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow(List<Data> doList) {
|
|
||||||
return doList.map((d) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
onSelectChanged: (bool selected) async {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => DeliveryBarDetail(d.date)),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(dateFormatter.format(d.date), style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(NumberCell(d.amount)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/do_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/do.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/number_cell.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class DeliveryBarDetail extends StatefulWidget {
|
|
||||||
final DateTime date;
|
|
||||||
const DeliveryBarDetail(this.date);
|
|
||||||
@override
|
|
||||||
_DeliveryBarDetailState createState() => _DeliveryBarDetailState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DeliveryBarDetailState extends State<DeliveryBarDetail> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd-MMM-yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
List<DOSubmission> dos = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
DOModel dOModel = Provider.of<DOModel>(context, listen: false);
|
|
||||||
dOModel.getDOForDelivery(widget.date).then((dos) {
|
|
||||||
setState(() {
|
|
||||||
this.dos = dos;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: LocalText(
|
|
||||||
context,
|
|
||||||
'delivery.detail.title',
|
|
||||||
translationVariables: [dateFormatter.format(widget.date)],
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 5),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: EdgeInsets.only(left: 3),
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 20,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "do.name")),
|
|
||||||
MyDataColumn(label: LocalText(context, "do.do_num")),
|
|
||||||
MyDataColumn(
|
|
||||||
label: LocalText(context, "do.quantity"), numeric: true),
|
|
||||||
],
|
|
||||||
rows: getProductRow(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow() {
|
|
||||||
return dos.map((d) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(d.userName, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(d.doNumber, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(NumberCell(d.totalQty)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'delivery_summary_detail.dart';
|
|
||||||
|
|
||||||
class DeliverySummary extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_DeliverySummaryState createState() => _DeliverySummaryState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DeliverySummaryState extends State<DeliverySummary> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
List<charts.Series<Data, String>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: chartModel.revenue.getDeliverySummary(),
|
|
||||||
domainFn: (Data series, _) => "${series.totalDay}days",
|
|
||||||
measureFn: (Data series, _) => series.totalAmount,
|
|
||||||
labelAccessorFn: (Data series, _) =>
|
|
||||||
'${numberFormatter.format(series.totalAmount)}'),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "delivery.summary",
|
|
||||||
color: primaryColor, fontSize: 16),
|
|
||||||
InkWell(
|
|
||||||
child: LocalText(
|
|
||||||
context,
|
|
||||||
"delivery.detail",
|
|
||||||
color: secondaryColor,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(MaterialPageRoute(
|
|
||||||
builder: (_) => DeliverySummaryDetail()));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.BarChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
vertical: false,
|
|
||||||
defaultRenderer: new charts.BarRendererConfig(
|
|
||||||
barRendererDecorator: new charts.BarLabelDecorator<String>(
|
|
||||||
labelPosition: charts.BarLabelPosition.auto,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class DeliverySummaryDetail extends StatefulWidget {
|
|
||||||
const DeliverySummaryDetail();
|
|
||||||
@override
|
|
||||||
_DeliverySummaryDetailState createState() => _DeliverySummaryDetailState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DeliverySummaryDetailState extends State<DeliverySummaryDetail> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: LocalText(
|
|
||||||
context,
|
|
||||||
'delivery.sum.amounts',
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: EdgeInsets.only(left: 20),
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 100,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "delivery.days")),
|
|
||||||
MyDataColumn(label: LocalText(context, "delivery.amount")),
|
|
||||||
],
|
|
||||||
rows: getProductRow(chartModel.revenue.getDeliverySummary()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow(List<Data> doList) {
|
|
||||||
return doList.map((d) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(d.totalDay.toString(), style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(
|
|
||||||
numberFormatter.format(d.totalAmount),
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po_do_count.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
import 'do_line_detail.dart';
|
|
||||||
|
|
||||||
class DOLineChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_DOLineChartState createState() => _DOLineChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DOLineChartState extends State<DOLineChart> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
List<charts.Series<CountData, DateTime>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "pending",
|
|
||||||
data: chartModel.podoCount.getDODataCounts("pending"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 3, 2, 3],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "approved",
|
|
||||||
data: chartModel.podoCount.getDODataCounts("approved"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "canceled",
|
|
||||||
data: chartModel.podoCount.getDODataCounts("canceled"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.gray.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 3, 2, 3],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "rejected",
|
|
||||||
data: chartModel.podoCount.getDODataCounts("rejected"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 3, 2, 3],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "expired",
|
|
||||||
data: chartModel.podoCount.getDODataCounts("expired"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.purple.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 5, 2, 5],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "closed",
|
|
||||||
data: chartModel.podoCount.getDODataCounts("closed"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.indigo.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 5, 2, 5],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "do", color: primaryColor, fontSize: 16),
|
|
||||||
LocalText(context, 'chart.30_days',
|
|
||||||
color: primaryColor, fontSize: 14)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
InkWell(
|
|
||||||
child: LocalText(
|
|
||||||
context,
|
|
||||||
"do.details",
|
|
||||||
color: secondaryColor,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context)
|
|
||||||
.push(MaterialPageRoute(builder: (_) => DOLineDetail()));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.TimeSeriesChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
defaultRenderer: new charts.LineRendererConfig(
|
|
||||||
includePoints: true,
|
|
||||||
),
|
|
||||||
behaviors: [
|
|
||||||
new charts.SeriesLegend(
|
|
||||||
position: charts.BehaviorPosition.end,
|
|
||||||
outsideJustification:
|
|
||||||
charts.OutsideJustification.middleDrawArea,
|
|
||||||
entryTextStyle: charts.TextStyleSpec(
|
|
||||||
color: charts.Color(r: 127, g: 63, b: 191),
|
|
||||||
fontFamily: 'Georgia',
|
|
||||||
fontSize: 11),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
|
||||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
|
|
||||||
zeroBound: false, desiredTickCount: 10),
|
|
||||||
renderSpec: new charts.GridlineRendererSpec(
|
|
||||||
lineStyle: charts.LineStyleSpec(
|
|
||||||
dashPattern: [4, 4],
|
|
||||||
))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po_do_count.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class DOLineDetail extends StatefulWidget {
|
|
||||||
const DOLineDetail();
|
|
||||||
@override
|
|
||||||
_DOLineDetailState createState() => _DOLineDetailState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _DOLineDetailState extends State<DOLineDetail> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: LocalText(
|
|
||||||
context,
|
|
||||||
'do.counts',
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
child: ListView(
|
|
||||||
children: <Widget>[
|
|
||||||
Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.only(top: 20, left: 20, right: 20),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "chart.date"),
|
|
||||||
LocalText(context, "do.total_count")
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: getRowTotalCountWidget(
|
|
||||||
chartModel.podoCount.getDOTotalCounts()),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> getRowTotalCountWidget(List<TotalCountData> data) {
|
|
||||||
return data.map((d) {
|
|
||||||
return Container(
|
|
||||||
child: ExpansionTile(
|
|
||||||
title: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
Text(dateFormatter.format(d.date), style: textStyle),
|
|
||||||
Text(numberFormatter.format(d.totalCount), style: textStyle),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
children: <Widget>[
|
|
||||||
SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 100,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "do.count.status")),
|
|
||||||
MyDataColumn(label: LocalText(context, "do.count")),
|
|
||||||
],
|
|
||||||
rows: getStatusRow(d.detailCountsList),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getStatusRow(List<CountData> doList) {
|
|
||||||
doList.sort((a, b) => a.status.compareTo(b.status));
|
|
||||||
return doList.map((d) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(d.status, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(
|
|
||||||
numberFormatter.format(d.count),
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
|
|
||||||
import '../model/product_model.dart';
|
|
||||||
|
|
||||||
typedef void ProductClick(DateTime date, Map<String, int> measures);
|
|
||||||
|
|
||||||
class ProductsChart extends StatelessWidget {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
final ChartData chartData;
|
|
||||||
final ProductClick productClick;
|
|
||||||
const ProductsChart(this.chartData, {Key key, this.productClick})
|
|
||||||
: super(key: key);
|
|
||||||
factory ProductsChart.fromModel(ProductModel productModel,
|
|
||||||
{ProductClick productClick}) {
|
|
||||||
return new ProductsChart(_createData(productModel),
|
|
||||||
productClick: productClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ChartData _createData(ProductModel productModel) {
|
|
||||||
List<charts.Series<TimeSeriesSales, DateTime>> list = [];
|
|
||||||
var min = 9999, max = 0;
|
|
||||||
productModel.products.forEach((p) {
|
|
||||||
List<TimeSeriesSales> data = [];
|
|
||||||
if (p.priceHistory != null) {
|
|
||||||
var dateKeys = {};
|
|
||||||
p.priceHistory.entries.forEach((e) {
|
|
||||||
dateKeys[DateTime.parse(e.key)] = e.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
var sortedKeys = dateKeys.keys.toList()..sort((a, b) => b.compareTo(a));
|
|
||||||
sortedKeys.forEach((k) {
|
|
||||||
var v = dateKeys[k];
|
|
||||||
data.add(new TimeSeriesSales(k, v));
|
|
||||||
if (v < min) min = v;
|
|
||||||
if (v > max) max = v;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
list.add(new charts.Series<TimeSeriesSales, DateTime>(
|
|
||||||
id: p.name,
|
|
||||||
colorFn: (_, __) => charts.ColorUtil.fromDartColor(Color(p.color)),
|
|
||||||
domainFn: (TimeSeriesSales sales, _) => sales.time,
|
|
||||||
measureFn: (TimeSeriesSales sales, _) => sales.sales,
|
|
||||||
data: data,
|
|
||||||
labelAccessorFn: (TimeSeriesSales series, _) =>
|
|
||||||
'${numberFormatter.format(series.sales)}',
|
|
||||||
measureFormatterFn: (TimeSeriesSales series, _) => (n) => "s",
|
|
||||||
));
|
|
||||||
});
|
|
||||||
var chartData = ChartData(list, min, max);
|
|
||||||
return chartData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return charts.TimeSeriesChart(
|
|
||||||
chartData.seriesList,
|
|
||||||
animate: true,
|
|
||||||
defaultRenderer: new charts.LineRendererConfig(
|
|
||||||
includePoints: true,
|
|
||||||
),
|
|
||||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
|
||||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
|
|
||||||
zeroBound: false, desiredTickCount: 10),
|
|
||||||
renderSpec: new charts.GridlineRendererSpec(
|
|
||||||
lineStyle: charts.LineStyleSpec(
|
|
||||||
dashPattern: [4, 4],
|
|
||||||
))),
|
|
||||||
selectionModels: [
|
|
||||||
new charts.SelectionModelConfig(
|
|
||||||
type: charts.SelectionModelType.info,
|
|
||||||
updatedListener: _onSelectionChanged,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSelectionChanged(charts.SelectionModel model) {
|
|
||||||
final selectedDatum = model.selectedDatum;
|
|
||||||
if (selectedDatum.isNotEmpty) {
|
|
||||||
var _time = selectedDatum.first.datum.time;
|
|
||||||
Map<String, int> _measures = <String, int>{};
|
|
||||||
|
|
||||||
selectedDatum.forEach((charts.SeriesDatum datumPair) {
|
|
||||||
_measures[datumPair.series.displayName] = datumPair.datum.sales;
|
|
||||||
});
|
|
||||||
if (productClick != null) {
|
|
||||||
productClick(_time, _measures);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TimeSeriesSales {
|
|
||||||
final DateTime time;
|
|
||||||
final int sales;
|
|
||||||
|
|
||||||
TimeSeriesSales(this.time, this.sales);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ChartData {
|
|
||||||
final List<charts.Series> seriesList;
|
|
||||||
final num min, max;
|
|
||||||
ChartData(this.seriesList, this.min, this.max);
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:charts_flutter/flutter.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/charts/po_balance_table.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/model/product_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
class POBalanceChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_POBalanceChartState createState() => _POBalanceChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _POBalanceChartState extends State<POBalanceChart> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
List<POChartData> chartSummary = new List();
|
|
||||||
List<charts.Series<POChartData, String>> series;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
var chartModel = Provider.of<ChartModel>(context, listen: false);
|
|
||||||
if (mounted) {
|
|
||||||
load(chartModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> load(ChartModel chartModel) async {
|
|
||||||
var _u = await chartModel.loadPOBalancesForBuyer();
|
|
||||||
if (_u == null) return;
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
this.chartSummary = _u;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var productModel = Provider.of<ProductModel>(context);
|
|
||||||
if (this.chartSummary.isNotEmpty) {
|
|
||||||
this.chartSummary.forEach((s) {
|
|
||||||
productModel.products.forEach((p) {
|
|
||||||
if (p.id == s.productID) {
|
|
||||||
s.displayOrder = p.displayOrder;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this
|
|
||||||
.chartSummary
|
|
||||||
.sort((s1, s2) => s1.displayOrder.compareTo(s2.displayOrder));
|
|
||||||
}
|
|
||||||
List<charts.Series<POChartData, String>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: this.chartSummary,
|
|
||||||
domainFn: (POChartData series, _) => series.productName,
|
|
||||||
measureFn: (POChartData series, _) => series.balanceQty,
|
|
||||||
colorFn: (POChartData series, _) =>
|
|
||||||
charts.ColorUtil.fromDartColor(series.getColor),
|
|
||||||
labelAccessorFn: (POChartData series, _) =>
|
|
||||||
'${numberFormatter.format(series.balanceQty)}'),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, 'po.balances',
|
|
||||||
color: primaryColor, fontSize: 16),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.refresh,
|
|
||||||
color: primaryColor,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
_load();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.BarChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
vertical: false,
|
|
||||||
defaultRenderer: new charts.BarRendererConfig(
|
|
||||||
barRendererDecorator: new charts.BarLabelDecorator<String>(
|
|
||||||
labelPosition: charts.BarLabelPosition.auto,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
selectionModels: [
|
|
||||||
SelectionModelConfig(changedListener: (SelectionModel model) {
|
|
||||||
final selectedDatum = model.selectedDatum;
|
|
||||||
if (selectedDatum.isNotEmpty) {
|
|
||||||
selectedDatum.forEach((charts.SeriesDatum datumPair) {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => POBalanceTable(
|
|
||||||
poChartData: datumPair.datum,
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _load() async {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
var _s = await chartModel.loadPOBalancesForBuyer();
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
this.chartSummary = _s ?? [];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/model/language_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/localization/app_translations.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/number_cell.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class POBalanceTable extends StatefulWidget {
|
|
||||||
final POChartData poChartData;
|
|
||||||
const POBalanceTable({Key key, this.poChartData}) : super(key: key);
|
|
||||||
@override
|
|
||||||
_POBalanceTableState createState() => _POBalanceTableState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _POBalanceTableState extends State<POBalanceTable> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
List<POChartData> chartUser = new List();
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
var chartModel = Provider.of<ChartModel>(context, listen: false);
|
|
||||||
if (mounted) {
|
|
||||||
load(chartModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> load(ChartModel chartModel) async {
|
|
||||||
var _u = await chartModel.loadPOBalProductsForBuyer();
|
|
||||||
setState(() {
|
|
||||||
this.chartUser = _u;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
List<POChartData> data = this
|
|
||||||
.chartUser
|
|
||||||
.where((u) => u.productName == widget.poChartData.productName)
|
|
||||||
.toList();
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: Text(
|
|
||||||
AppTranslations.of(context).text("product.qtys"),
|
|
||||||
style: Provider.of<LanguageModel>(context).isEng
|
|
||||||
? TextStyle(fontSize: 18)
|
|
||||||
: TextStyle(fontSize: 18, fontFamily: 'MyanmarUnicode'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: MyDataTable(
|
|
||||||
headingRowHeight: 40,
|
|
||||||
columnSpacing: 40,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "buyer.name")),
|
|
||||||
MyDataColumn(label: LocalText(context, "buyer.product")),
|
|
||||||
MyDataColumn(
|
|
||||||
label: LocalText(context, "buyer.balQty"), numeric: true),
|
|
||||||
],
|
|
||||||
rows: getProductRow(data),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow(List<POChartData> poLines) {
|
|
||||||
return poLines.map((p) {
|
|
||||||
return MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(p.userName, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(
|
|
||||||
p.productName,
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
NumberCell(p.balanceQty),
|
|
||||||
//new Text(numberFormatter.format(p.balanceQty), style: textStyle),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
class POBalanceChart_ extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_POBalanceChartState createState() => _POBalanceChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _POBalanceChartState extends State<POBalanceChart_> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
List<POBuyerData> chartSummary = new List();
|
|
||||||
List<charts.Series<POBuyerData, String>> series;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
var chartModel = Provider.of<ChartModel>(context, listen: false);
|
|
||||||
if (mounted) {
|
|
||||||
load(chartModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> load(ChartModel chartModel) async {
|
|
||||||
var _u = await chartModel.loadPOBalancesForBuyer_();
|
|
||||||
if (_u == null) return;
|
|
||||||
setState(() {
|
|
||||||
this.chartSummary = _u;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
List<charts.Series<POBuyerData, String>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: this.chartSummary,
|
|
||||||
domainFn: (POBuyerData series, _) => series.status,
|
|
||||||
measureFn: (POBuyerData series, _) => series.amount,
|
|
||||||
colorFn: (POBuyerData series, _) =>
|
|
||||||
charts.ColorUtil.fromDartColor(series.getColor),
|
|
||||||
labelAccessorFn: (POBuyerData series, _) =>
|
|
||||||
'${numberFormatter.format(series.amount)}'),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, 'po.balances',
|
|
||||||
color: primaryColor, fontSize: 16),
|
|
||||||
IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
Icons.refresh,
|
|
||||||
color: primaryColor,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
_load();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.BarChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
vertical: false,
|
|
||||||
defaultRenderer: new charts.BarRendererConfig(
|
|
||||||
barRendererDecorator: new charts.BarLabelDecorator<String>(
|
|
||||||
labelPosition: charts.BarLabelPosition.auto,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _load() async {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
var _s = await chartModel.loadPOBalancesForBuyer_();
|
|
||||||
if (_s == null) return;
|
|
||||||
setState(() {
|
|
||||||
this.chartSummary = _s;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,155 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/charts/po_line_detail.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po_do_count.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
class POLineChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_POLineChartState createState() => _POLineChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _POLineChartState extends State<POLineChart> {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
List<charts.Series<CountData, DateTime>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "pending",
|
|
||||||
data: chartModel.podoCount.getPODataCounts('pending'),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 3, 2, 3],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "approved",
|
|
||||||
data: chartModel.podoCount.getPODataCounts("approved"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "canceled",
|
|
||||||
data: chartModel.podoCount.getPODataCounts("canceled"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.gray.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 3, 2, 3],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "rejected",
|
|
||||||
data: chartModel.podoCount.getPODataCounts("rejected"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 3, 2, 3],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "expired",
|
|
||||||
data: chartModel.podoCount.getPODataCounts("expired"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.purple.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 5, 2, 5],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
charts.Series(
|
|
||||||
id: "closed",
|
|
||||||
data: chartModel.podoCount.getPODataCounts("closed"),
|
|
||||||
domainFn: (CountData series, _) => series.date,
|
|
||||||
measureFn: (CountData series, _) =>
|
|
||||||
series.count == null ? 0 : series.count,
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.indigo.shadeDefault,
|
|
||||||
dashPatternFn: (_, __) => [8, 5, 2, 5],
|
|
||||||
labelAccessorFn: (CountData series, _) =>
|
|
||||||
'${numberFormatter.format(series.count)}',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "po", color: primaryColor, fontSize: 16),
|
|
||||||
LocalText(context, 'chart.30_days',
|
|
||||||
color: primaryColor, fontSize: 14)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
InkWell(
|
|
||||||
child: LocalText(
|
|
||||||
context,
|
|
||||||
"po.details",
|
|
||||||
color: secondaryColor,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context)
|
|
||||||
.push(MaterialPageRoute(builder: (_) => POLineDetail()));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.TimeSeriesChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
defaultRenderer: new charts.LineRendererConfig(
|
|
||||||
includePoints: true,
|
|
||||||
),
|
|
||||||
behaviors: [
|
|
||||||
new charts.SeriesLegend(
|
|
||||||
position: charts.BehaviorPosition.end,
|
|
||||||
outsideJustification:
|
|
||||||
charts.OutsideJustification.middleDrawArea,
|
|
||||||
entryTextStyle: charts.TextStyleSpec(
|
|
||||||
color: charts.Color(r: 127, g: 63, b: 191),
|
|
||||||
fontFamily: 'Georgia',
|
|
||||||
fontSize: 11),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
|
||||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
|
|
||||||
zeroBound: false, desiredTickCount: 10),
|
|
||||||
renderSpec: new charts.GridlineRendererSpec(
|
|
||||||
lineStyle: charts.LineStyleSpec(
|
|
||||||
dashPattern: [4, 4],
|
|
||||||
))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:http/http.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po_do_count.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class POLineDetail extends StatefulWidget {
|
|
||||||
const POLineDetail();
|
|
||||||
@override
|
|
||||||
_POLineDetailState createState() => _POLineDetailState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _POLineDetailState extends State<POLineDetail> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: LocalText(
|
|
||||||
context,
|
|
||||||
'po.counts',
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
child: ListView(
|
|
||||||
children: <Widget>[
|
|
||||||
Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.only(top: 20, left: 20, right: 20),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, "chart.date"),
|
|
||||||
LocalText(context, "po.total_count")
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: getRowTotalCountWidget(
|
|
||||||
chartModel.podoCount.getPOTotalCounts()),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> getRowTotalCountWidget(List<TotalCountData> data) {
|
|
||||||
return data.map((d) {
|
|
||||||
return Container(
|
|
||||||
child: ExpansionTile(
|
|
||||||
title: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
Text(dateFormatter.format(d.date), style: textStyle),
|
|
||||||
Text(numberFormatter.format(d.totalCount), style: textStyle),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
children: <Widget>[
|
|
||||||
SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 100,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "po.count.status")),
|
|
||||||
MyDataColumn(label: LocalText(context, "po.count")),
|
|
||||||
],
|
|
||||||
rows: getStatusRow(d.detailCountsList),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getStatusRow(List<CountData> po) {
|
|
||||||
po.sort((a, b) => a.status.compareTo(b.status));
|
|
||||||
return po.map((p) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(p.status, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(
|
|
||||||
p.count != null ? numberFormatter.format(p.count) : '0',
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/model/language_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/localization/app_translations.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/number_cell.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class QtyByCustomerTable extends StatefulWidget {
|
|
||||||
final POChartData poChartData;
|
|
||||||
const QtyByCustomerTable({Key key, this.poChartData}) : super(key: key);
|
|
||||||
@override
|
|
||||||
_QtyByCustomerTableState createState() => _QtyByCustomerTableState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _QtyByCustomerTableState extends State<QtyByCustomerTable> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
List<POChartData> chartUser = new List();
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
var chartModel = Provider.of<ChartModel>(context, listen: false);
|
|
||||||
if (mounted) {
|
|
||||||
load(chartModel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> load(ChartModel chartModel) async {
|
|
||||||
var _u = await chartModel.loadUsers();
|
|
||||||
setState(() {
|
|
||||||
this.chartUser = _u;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
List<POChartData> data = this
|
|
||||||
.chartUser
|
|
||||||
.where((u) => u.productName == widget.poChartData.productName)
|
|
||||||
.toList();
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: Text(
|
|
||||||
AppTranslations.of(context).text("product.qtys"),
|
|
||||||
style: Provider.of<LanguageModel>(context).isEng
|
|
||||||
? TextStyle(fontSize: 18)
|
|
||||||
: TextStyle(fontSize: 18, fontFamily: 'MyanmarUnicode'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
child: MyDataTable(
|
|
||||||
headingRowHeight: 40,
|
|
||||||
columnSpacing: 40,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "buyer.name")),
|
|
||||||
MyDataColumn(label: LocalText(context, "buyer.product")),
|
|
||||||
MyDataColumn(
|
|
||||||
label: LocalText(context, "buyer.balQty"), numeric: true),
|
|
||||||
],
|
|
||||||
rows: getProductRow(data),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow(List<POChartData> poLines) {
|
|
||||||
return poLines.map((p) {
|
|
||||||
return MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(p.userName, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(
|
|
||||||
p.productName,
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MyDataCell(NumberCell(p.balanceQty)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
/// Simple pie chart example.
|
|
||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:fcs/vo/buyer.dart';
|
|
||||||
import 'package:fcs/vo/product.dart';
|
|
||||||
import 'package:fcs/widget/localization/app_translations.dart';
|
|
||||||
|
|
||||||
class QuotaChart extends StatelessWidget {
|
|
||||||
static final numberFormatter = new NumberFormat("#,###");
|
|
||||||
|
|
||||||
final List<charts.Series> quotaSeries;
|
|
||||||
final String title;
|
|
||||||
|
|
||||||
QuotaChart(this.quotaSeries, this.title);
|
|
||||||
|
|
||||||
factory QuotaChart.dailyQuota(
|
|
||||||
BuildContext context, Buyer buyer, List<Product> products) {
|
|
||||||
List<Quota> data = [];
|
|
||||||
products.sort((p1, p2) => p1.displayOrder.compareTo(p2.displayOrder));
|
|
||||||
products.forEach((p) {
|
|
||||||
if (buyer.dailyQuotaUsedProducts.containsKey(p.id)) {
|
|
||||||
int value = buyer.dailyQuotaUsedProducts[p.id];
|
|
||||||
data.add(Quota(p.name, value, p.color));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
data.add(
|
|
||||||
new Quota(AppTranslations.of(context).text("chart.remaining"),
|
|
||||||
buyer.dailyQuota - buyer.dailyQuotaUsed, Colors.purple.value),
|
|
||||||
);
|
|
||||||
|
|
||||||
return new QuotaChart(
|
|
||||||
_createData(data),
|
|
||||||
AppTranslations.of(context).text("chart.daily.title",
|
|
||||||
translationVariables: [numberFormatter.format(buyer.dailyQuota)]));
|
|
||||||
}
|
|
||||||
|
|
||||||
factory QuotaChart.maxQuota(
|
|
||||||
BuildContext context, Buyer buyer, List<Product> products) {
|
|
||||||
List<Quota> data = [];
|
|
||||||
products.sort((p1, p2) => p1.displayOrder.compareTo(p2.displayOrder));
|
|
||||||
products.forEach((p) {
|
|
||||||
if (buyer.maxQuotaUsedProducts.containsKey(p.id)) {
|
|
||||||
int value = buyer.maxQuotaUsedProducts[p.id];
|
|
||||||
data.add(Quota(p.name, value, p.color));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
data.add(
|
|
||||||
new Quota(AppTranslations.of(context).text("chart.remaining"),
|
|
||||||
buyer.maxQuota - buyer.maxQuotaUsed, Colors.purple.value),
|
|
||||||
);
|
|
||||||
return new QuotaChart(
|
|
||||||
_createData(data),
|
|
||||||
AppTranslations.of(context).text("chart.max.title",
|
|
||||||
translationVariables: [numberFormatter.format(buyer.maxQuota)]));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Text(title),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Container(
|
|
||||||
height: 200,
|
|
||||||
child: charts.PieChart(
|
|
||||||
quotaSeries,
|
|
||||||
animate: false,
|
|
||||||
behaviors: [
|
|
||||||
new charts.DatumLegend(
|
|
||||||
position: charts.BehaviorPosition.end,
|
|
||||||
horizontalFirst: false,
|
|
||||||
cellPadding: new EdgeInsets.only(right: 4.0, bottom: 4.0),
|
|
||||||
entryTextStyle: charts.TextStyleSpec(
|
|
||||||
color: charts.MaterialPalette.purple.shadeDefault,
|
|
||||||
fontFamily: 'Georgia',
|
|
||||||
fontSize: 11),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
defaultRenderer: new charts.ArcRendererConfig(
|
|
||||||
arcWidth: 60,
|
|
||||||
arcRendererDecorators: [
|
|
||||||
new charts.ArcLabelDecorator(
|
|
||||||
labelPosition: charts.ArcLabelPosition.auto,
|
|
||||||
labelPadding: 0)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<charts.Series<Quota, String>> _createData(List<Quota> data) {
|
|
||||||
return [
|
|
||||||
new charts.Series<Quota, String>(
|
|
||||||
id: 'Daily Quota',
|
|
||||||
domainFn: (Quota quota, _) => "${quota.label}\n",
|
|
||||||
measureFn: (Quota quota, _) => quota.quota,
|
|
||||||
data: data,
|
|
||||||
colorFn: (Quota quota, i) =>
|
|
||||||
charts.ColorUtil.fromDartColor(Color(quota.color)),
|
|
||||||
labelAccessorFn: (Quota row, _) =>
|
|
||||||
'${numberFormatter.format(row.quota)}',
|
|
||||||
)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Quota {
|
|
||||||
final String label;
|
|
||||||
final int quota;
|
|
||||||
final int color;
|
|
||||||
|
|
||||||
Quota(this.label, this.quota, this.color);
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/model/main_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
|
|
||||||
import 'revenue_line_data.dart';
|
|
||||||
|
|
||||||
class RevenueLineChart extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_RevenueLineChartState createState() => _RevenueLineChartState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RevenueLineChartState extends State<RevenueLineChart> {
|
|
||||||
static final numberFormatter = NumberFormat.compact();
|
|
||||||
int actualChart = 0;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
var mainModel = Provider.of<MainModel>(context);
|
|
||||||
|
|
||||||
List<charts.Series<Data, DateTime>> series = [
|
|
||||||
charts.Series(
|
|
||||||
id: "Subscribers",
|
|
||||||
data: chartModel.revenue.getData(),
|
|
||||||
domainFn: (Data series, _) => series.date,
|
|
||||||
measureFn: (Data series, _) => series.amount,
|
|
||||||
colorFn: (_, __) => charts.ColorUtil.fromDartColor(primaryColor),
|
|
||||||
labelAccessorFn: (Data series, _) =>
|
|
||||||
'${numberFormatter.format(series.amount)}',
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
final moneyFormatter =
|
|
||||||
new charts.BasicNumericTickFormatterSpec.fromNumberFormat(
|
|
||||||
new NumberFormat.compact());
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
height: 200,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: <Widget>[
|
|
||||||
mainModel.user.isOwnerAndAbove()
|
|
||||||
? Row(
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, 'chart.revenue',
|
|
||||||
fontSize: 16, color: primaryColor),
|
|
||||||
LocalText(context, 'chart.30_days',
|
|
||||||
color: primaryColor, fontSize: 14),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Row(
|
|
||||||
children: <Widget>[
|
|
||||||
LocalText(context, 'chart.spending',
|
|
||||||
fontSize: 16, color: primaryColor),
|
|
||||||
LocalText(context, 'chart.30_days',
|
|
||||||
color: primaryColor, fontSize: 14)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"${chartModel.revenue.mapData == null ? "" : numberFormatter.format(chartModel.revenue.getTotal(actualChart))}",
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.black,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
fontSize: 17.0))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
InkWell(
|
|
||||||
child: LocalText(
|
|
||||||
context,
|
|
||||||
"revenue.detail",
|
|
||||||
color: secondaryColor,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.of(context).push(
|
|
||||||
MaterialPageRoute(builder: (_) => RevenueLineData()));
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: charts.TimeSeriesChart(
|
|
||||||
series,
|
|
||||||
animate: true,
|
|
||||||
defaultRenderer: new charts.LineRendererConfig(
|
|
||||||
includePoints: true,
|
|
||||||
),
|
|
||||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
|
||||||
tickFormatterSpec: moneyFormatter,
|
|
||||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
|
|
||||||
zeroBound: false, desiredTickCount: 10),
|
|
||||||
renderSpec: new charts.GridlineRendererSpec(
|
|
||||||
lineStyle: charts.LineStyleSpec(
|
|
||||||
dashPattern: [4, 4],
|
|
||||||
))),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/chart_model.dart';
|
|
||||||
import 'package:fcs/model/main_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/revenue.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/number_cell.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
import 'revenue_line_detail.dart';
|
|
||||||
|
|
||||||
class RevenueLineData extends StatefulWidget {
|
|
||||||
const RevenueLineData();
|
|
||||||
@override
|
|
||||||
_RevenueLineDataState createState() => _RevenueLineDataState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RevenueLineDataState extends State<RevenueLineData> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var chartModel = Provider.of<ChartModel>(context);
|
|
||||||
var mainModel = Provider.of<MainModel>(context);
|
|
||||||
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: mainModel.user.isOwnerAndAbove()
|
|
||||||
? LocalText(context, 'revenue.amounts',
|
|
||||||
color: Colors.white, fontSize: 18)
|
|
||||||
: LocalText(context, 'spending.amounts',
|
|
||||||
color: Colors.white, fontSize: 18),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: EdgeInsets.only(left: 20),
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 100,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "revenue.date")),
|
|
||||||
MyDataColumn(
|
|
||||||
label: LocalText(context, "revenue.amount"),
|
|
||||||
numeric: true),
|
|
||||||
],
|
|
||||||
rows: getProductRow(chartModel.revenue.getData()),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow(List<Data> revs) {
|
|
||||||
return revs.map((p) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
onSelectChanged: (bool selected) async {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(builder: (context) => RevenueLineDetail(p.date)),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(dateFormatter.format(p.date), style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(NumberCell(p.amount)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'package:fcs/model/main_model.dart';
|
|
||||||
import 'package:fcs/model/po_model.dart';
|
|
||||||
import 'package:fcs/fcs/common/helpers/theme.dart';
|
|
||||||
import 'package:fcs/vo/po.dart';
|
|
||||||
import 'package:fcs/widget/local_text.dart';
|
|
||||||
import 'package:fcs/widget/my_data_table.dart';
|
|
||||||
import 'package:fcs/widget/number_cell.dart';
|
|
||||||
import 'package:fcs/widget/progress.dart';
|
|
||||||
|
|
||||||
class RevenueLineDetail extends StatefulWidget {
|
|
||||||
final DateTime date;
|
|
||||||
const RevenueLineDetail(this.date);
|
|
||||||
@override
|
|
||||||
_RevenueLineDetailState createState() => _RevenueLineDetailState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RevenueLineDetailState extends State<RevenueLineDetail> {
|
|
||||||
final numberFormatter = new NumberFormat("#,###");
|
|
||||||
var dateFormatter = new DateFormat('dd-MMM-yyyy');
|
|
||||||
bool _isLoading = false;
|
|
||||||
List<POSubmission> pos = [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
POSubmissionModel pOModel =
|
|
||||||
Provider.of<POSubmissionModel>(context, listen: false);
|
|
||||||
pOModel.getPOForRevenue(widget.date).then((pos) {
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
this.pos = pos;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
var mainModel = Provider.of<MainModel>(context);
|
|
||||||
return LocalProgress(
|
|
||||||
inAsyncCall: _isLoading,
|
|
||||||
child: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
backgroundColor: primaryColor,
|
|
||||||
title: mainModel.user.isOwnerAndAbove()
|
|
||||||
? LocalText(
|
|
||||||
context,
|
|
||||||
'revenue.detail.title',
|
|
||||||
translationVariables: [dateFormatter.format(widget.date)],
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
)
|
|
||||||
: LocalText(
|
|
||||||
context,
|
|
||||||
'spending.detail.title',
|
|
||||||
translationVariables: [dateFormatter.format(widget.date)],
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Container(
|
|
||||||
padding: EdgeInsets.only(top: 5),
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.horizontal,
|
|
||||||
padding: EdgeInsets.only(left: 3),
|
|
||||||
child: MyDataTable(
|
|
||||||
columnSpacing: 20,
|
|
||||||
columns: [
|
|
||||||
MyDataColumn(label: LocalText(context, "po.name")),
|
|
||||||
MyDataColumn(label: LocalText(context, "po.po_num")),
|
|
||||||
MyDataColumn(
|
|
||||||
label: LocalText(context, "po.amount"), numeric: true),
|
|
||||||
],
|
|
||||||
rows: getProductRow(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<MyDataRow> getProductRow() {
|
|
||||||
return pos.map((p) {
|
|
||||||
var r = MyDataRow(
|
|
||||||
cells: [
|
|
||||||
MyDataCell(
|
|
||||||
new Text(p.userName, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(
|
|
||||||
new Text(p.poNumber, style: textStyle),
|
|
||||||
),
|
|
||||||
MyDataCell(NumberCell(p.amount)),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}).toList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/// Timeseries chart example
|
|
||||||
import 'package:charts_flutter/flutter.dart' as charts;
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class SimpleTimeSeriesChart extends StatelessWidget {
|
|
||||||
final List<charts.Series> seriesList;
|
|
||||||
final bool animate;
|
|
||||||
|
|
||||||
SimpleTimeSeriesChart(this.seriesList, {this.animate});
|
|
||||||
|
|
||||||
/// Creates a [TimeSeriesChart] with sample data and no transition.
|
|
||||||
factory SimpleTimeSeriesChart.withSampleData() {
|
|
||||||
return new SimpleTimeSeriesChart(
|
|
||||||
_createSampleData(),
|
|
||||||
// Disable animations for image tests.
|
|
||||||
animate: false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return new charts.TimeSeriesChart(
|
|
||||||
seriesList,
|
|
||||||
animate: animate,
|
|
||||||
// Optionally pass in a [DateTimeFactory] used by the chart. The factory
|
|
||||||
// should create the same type of [DateTime] as the data provided. If none
|
|
||||||
// specified, the default creates local date time.
|
|
||||||
dateTimeFactory: const charts.LocalDateTimeFactory(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create one series with sample hard coded data.
|
|
||||||
static List<charts.Series<TimeSeriesSales, DateTime>> _createSampleData() {
|
|
||||||
final data = [
|
|
||||||
new TimeSeriesSales(new DateTime(2017, 9, 19), 5),
|
|
||||||
new TimeSeriesSales(new DateTime(2017, 9, 26), 25),
|
|
||||||
new TimeSeriesSales(new DateTime(2017, 10, 3), 100),
|
|
||||||
new TimeSeriesSales(new DateTime(2017, 10, 10), 75),
|
|
||||||
];
|
|
||||||
|
|
||||||
return [
|
|
||||||
new charts.Series<TimeSeriesSales, DateTime>(
|
|
||||||
id: 'Sales',
|
|
||||||
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
|
|
||||||
domainFn: (TimeSeriesSales sales, _) => sales.time,
|
|
||||||
measureFn: (TimeSeriesSales sales, _) => sales.sales,
|
|
||||||
data: data,
|
|
||||||
)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sample time series data type.
|
|
||||||
class TimeSeriesSales {
|
|
||||||
final DateTime time;
|
|
||||||
final int sales;
|
|
||||||
|
|
||||||
TimeSeriesSales(this.time, this.sales);
|
|
||||||
}
|
|
||||||