diff --git a/frontend/mgramseva/lib/model/reports/InactiveConsumerReportData.dart b/frontend/mgramseva/lib/model/reports/InactiveConsumerReportData.dart new file mode 100644 index 000000000..0de92354a --- /dev/null +++ b/frontend/mgramseva/lib/model/reports/InactiveConsumerReportData.dart @@ -0,0 +1,31 @@ +class InactiveConsumerReportData { + String? tenantName; + String? connectionNo; + String? status; + num? inactiveDate; + String? inactivatedByUuid; + String? inactivatedByName; + + InactiveConsumerReportData(this.tenantName, this.connectionNo, this.status, + this.inactiveDate, this.inactivatedByUuid, this.inactivatedByName); + + InactiveConsumerReportData.fromJson(Map json) { + tenantName = json['tenantName']; + connectionNo = json['connectionno']; + status = json['status']; + inactiveDate = json['inactiveDate']; + inactivatedByUuid = json['inactivatedByUuid']; + inactivatedByName = json['inactivatedByName']; + } + + Map toJson() { + final Map data = new Map(); + data['tenantName'] = this.tenantName; + data['connectionno'] = this.connectionNo; + data['status'] = this.status; + data['inactiveDate'] = this.inactiveDate; + data['inactivatedByUuid'] = this.inactivatedByUuid; + data['inactivatedByName'] = this.inactivatedByName; + return data; + } +} \ No newline at end of file diff --git a/frontend/mgramseva/lib/providers/reports_provider.dart b/frontend/mgramseva/lib/providers/reports_provider.dart index 498aefdab..8404596c3 100644 --- a/frontend/mgramseva/lib/providers/reports_provider.dart +++ b/frontend/mgramseva/lib/providers/reports_provider.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:mgramseva/model/reports/InactiveConsumerReportData.dart'; import 'package:mgramseva/utils/common_widgets.dart'; import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_xlsio/xlsio.dart'; @@ -35,6 +36,7 @@ class ReportsProvider with ChangeNotifier { var billingcycleCtrl = TextEditingController(); List? demandreports; List? collectionreports; + List? inactiveconsumers; BillsTableData genericTableData = BillsTableData([], []); int limit = 10; int offset = 1; @@ -81,6 +83,13 @@ class ReportsProvider with ChangeNotifier { TableHeader(i18.common.PAYMENT_METHOD), TableHeader(i18.billDetails.TOTAL_AMOUNT), ]; + List get inactiveConsumerHeaderList => [ + TableHeader(i18.common.CONNECTION_ID), + TableHeader(i18.common.STATUS), + TableHeader(i18.common.INACTIVATED_DATE), + TableHeader(i18.common.INACTIVATED_BY_NAME), + TableHeader(i18.common.INACTIVATED_BY_UUID), + ]; void onChangeOfPageLimit( PaginationResponse response, String type, BuildContext context) { @@ -90,6 +99,9 @@ class ReportsProvider with ChangeNotifier { if (type == i18.dashboard.COLLECTION_REPORT) { getCollectionReport(limit: response.limit, offset: response.offset); } + if (type == i18.dashboard.INACTIVE_CONSUMER_REPORT) { + getInactiveConsumerReport(limit: response.limit, offset: response.offset); + } } List getDemandsData(List list, @@ -139,7 +151,30 @@ class ReportsProvider with ChangeNotifier { TableData('${data.paymentAmount ?? '0'}'), ]); } + List getInactiveConsumersData(List list, + {bool isExcel = false}) { + return list.map((e) => getInactiveConsumersDataRow(e, isExcel: isExcel)).toList(); + } + TableDataRow getInactiveConsumersDataRow(InactiveConsumerReportData data, + {bool isExcel = false}) { + String? inactivatedBy = CommonMethods.truncateWithEllipsis(20, data.inactivatedByName!); + if (data.connectionNo != null && data.connectionNo!.isEmpty) { + data.connectionNo = '-'; + } + var inactivatedDate = DateFormats.timeStampToDate(data.inactiveDate?.toInt(),format: "dd/MM/yyyy"); + return TableDataRow([ + TableData( + isExcel + ? '${data.connectionNo ?? '-'}' + : '${data.connectionNo?.split('/').first ?? ''}/...${data.connectionNo?.split('/').last ?? ''}', + ), + TableData('${data.status??'-'}'), + TableData('${inactivatedDate ?? '-'}'), + TableData('${inactivatedBy ?? '-'}'), + TableData('${data.inactivatedByUuid ?? ''}'), + ]); + } void callNotifier() { notifyListeners(); } @@ -378,6 +413,71 @@ class ReportsProvider with ChangeNotifier { } } + Future getInactiveConsumerReport( + {bool download = false, + int offset = 1, + int limit = 10, + String sortOrder = "ASC"}) async { + try { + var commonProvider = Provider.of( + navigatorKey.currentContext!, + listen: false); + if (selectedBillPeriod == null) { + throw Exception('Select Billing Cycle'); + } + Map params = { + 'tenantId': commonProvider.userDetails!.selectedtenant!.code, + 'monthStartDate': selectedBillPeriod?.split('-')[0], + 'monthEndDate': selectedBillPeriod?.split('-')[1], + 'offset': '${offset - 1}', + 'limit': '${download ? -1 : limit}', + 'sortOrder': '$sortOrder' + }; + var response = await ReportsRepo().fetchInactiveConsumerReport(params); + if (response != null) { + inactiveconsumers = response; + if (download) { + generateExcel( + inactiveConsumerHeaderList + .map((e) => + '${ApplicationLocalizations.of(navigatorKey.currentContext!).translate(e.label)}') + .toList(), + getInactiveConsumersData(inactiveconsumers!, isExcel: true) + .map>( + (e) => e.tableRow.map((e) => e.label).toList()) + .toList() ?? + [], + title: + 'InactiveConsumers_${commonProvider.userDetails?.selectedtenant?.code?.substring(3)}_${selectedBillPeriod.toString().replaceAll('/', '_')}', + optionalData: [ + 'Collection Report', + '$selectedBillPeriod', + '${ApplicationLocalizations.of(navigatorKey.currentContext!).translate(commonProvider.userDetails!.selectedtenant!.code!)} ${commonProvider.userDetails?.selectedtenant?.code?.substring(3)}', + 'Downloaded On ${DateFormats.timeStampToDate(DateTime.now().millisecondsSinceEpoch, format: 'dd/MMM/yyyy')}' + ]); + } else { + if (inactiveconsumers != null && inactiveconsumers!.isNotEmpty) { + this.limit = limit; + this.offset = offset; + this.genericTableData = BillsTableData( + inactiveConsumerHeaderList, getInactiveConsumersData(inactiveconsumers!)); + } + } + streamController.add(response); + callNotifier(); + } else { + streamController.add('error'); + throw Exception('API Error'); + } + callNotifier(); + } catch (e, s) { + inactiveconsumers = []; + ErrorHandler().allExceptionsHandler(navigatorKey.currentContext!, e, s); + streamController.addError('error'); + callNotifier(); + } + } + void clearBuildTableData() { genericTableData = BillsTableData([], []); callNotifier(); diff --git a/frontend/mgramseva/lib/repository/reports_repo.dart b/frontend/mgramseva/lib/repository/reports_repo.dart index 1c736de9f..a8472860d 100644 --- a/frontend/mgramseva/lib/repository/reports_repo.dart +++ b/frontend/mgramseva/lib/repository/reports_repo.dart @@ -2,6 +2,7 @@ import 'package:mgramseva/services/urls.dart'; import 'package:mgramseva/services/base_service.dart'; import 'package:provider/provider.dart'; +import '../model/reports/InactiveConsumerReportData.dart'; import '../model/reports/bill_report_data.dart'; import '../model/reports/collection_report_data.dart'; import '../providers/common_provider.dart'; @@ -83,4 +84,41 @@ class ReportsRepo extends BaseService{ } return billreports; } + + Future?> fetchInactiveConsumerReport(Map params, + [String? token]) async { + var commonProvider = Provider.of( + navigatorKey.currentContext!, + listen: false); + List? inactiveConsumers; + final requestInfo = RequestInfo( + APIConstants.API_MODULE_NAME, + APIConstants.API_VERSION, + APIConstants.API_TS, + '_get', + APIConstants.API_DID, + APIConstants.API_KEY, + APIConstants.API_MESSAGE_ID, + commonProvider.userDetails?.accessToken, + commonProvider.userDetails?.userRequest?.toJson()); + + var res = await makeRequest( + url: Url.INACTIVE_CONSUMER_REPORT, + queryParameters: params, + requestInfo: requestInfo, + body: {}, + method: RequestType.POST); + if (res != null && res['InactiveConsumerReportData'] != null) { + try { + inactiveConsumers = []; + res['InactiveConsumerReportData'].forEach((val){ + inactiveConsumers?.add(InactiveConsumerReportData.fromJson(val)); + }); + } catch (e) { + print(e); + inactiveConsumers = null; + } + } + return inactiveConsumers; + } } \ No newline at end of file diff --git a/frontend/mgramseva/lib/screeens/reports/inactive_consumer_report.dart b/frontend/mgramseva/lib/screeens/reports/inactive_consumer_report.dart new file mode 100644 index 000000000..f5ee4fa51 --- /dev/null +++ b/frontend/mgramseva/lib/screeens/reports/inactive_consumer_report.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:mgramseva/model/common/BillsTableData.dart'; +import 'package:provider/provider.dart'; + +import '../../providers/reports_provider.dart'; +import '../../utils/localization/application_localizations.dart'; + +import 'package:mgramseva/utils/constants/i18_key_constants.dart'; + +import '../../utils/notifiers.dart'; +import '../../utils/testing_keys/testing_keys.dart'; +import '../../widgets/button.dart'; +import 'generic_report_table.dart'; + +class InactiveConsumerReport extends StatefulWidget { + final Function onViewClick; + + InactiveConsumerReport({Key? key, required this.onViewClick}) : super(key: key); + + @override + State createState() { + return _CollectionReport(); + } +} + +class _CollectionReport extends State + with SingleTickerProviderStateMixin { + @override + Widget build(BuildContext context) { + return LayoutBuilder(builder: (context, constraints) { + return Consumer(builder: (_, reportProvider, child) { + return Container( + margin: constraints.maxWidth > 700 + ? const EdgeInsets.only(top: 5.0, bottom: 5, right: 20, left: 10) + : const EdgeInsets.only(top: 5.0, bottom: 5, right: 8, left: 8), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 30, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Text("3. ", + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.w700)), + Text( + ApplicationLocalizations.of(context) + .translate(i18.dashboard.INACTIVE_CONSUMER_REPORT), + style: TextStyle( + fontSize: 16, fontWeight: FontWeight.w700)), + ], + ), + Row( + children: [ + Container( + width: 50, + child: Button( + "View", + () { + if (reportProvider.selectedBillPeriod == null) { + Notifiers.getToastMessage( + context, 'Select Billing Cycle', 'ERROR'); + } else { + reportProvider.clearTableData(); + reportProvider.getInactiveConsumerReport(); + widget.onViewClick( + true, i18.dashboard.INACTIVE_CONSUMER_REPORT); + } + }, + key: Keys.billReport.INACTIVE_CONSUMER_REPORT_VIEW_BUTTON, + ), + ), + SizedBox( + width: 10, + ), + TextButton.icon( + onPressed: () { + if (reportProvider.selectedBillPeriod == null) { + Notifiers.getToastMessage( + context, 'Select Billing Cycle', 'ERROR'); + } else { + reportProvider.getInactiveConsumerReport( + download: true); + } + }, + icon: Icon(Icons.download_sharp), + label: Text(ApplicationLocalizations.of(context) + .translate(i18.common.CORE_DOWNLOAD))), + ], + ), + ], + ), + ], + ), + ); + }); + }); + } +} diff --git a/frontend/mgramseva/lib/screeens/reports/reports.dart b/frontend/mgramseva/lib/screeens/reports/reports.dart index 33d350705..8f00250ed 100644 --- a/frontend/mgramseva/lib/screeens/reports/reports.dart +++ b/frontend/mgramseva/lib/screeens/reports/reports.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:mgramseva/screeens/reports/inactive_consumer_report.dart'; import 'package:mgramseva/screeens/reports/view_table.dart'; import 'package:provider/provider.dart'; @@ -212,6 +213,7 @@ class _Reports extends State with SingleTickerProviderStateMixin { children: [ BillReport(onViewClick: showTable), CollectionReport(onViewClick: showTable), + InactiveConsumerReport(onViewClick: showTable,) ], ), ), diff --git a/frontend/mgramseva/lib/services/urls.dart b/frontend/mgramseva/lib/services/urls.dart index 8e7cd886d..9972db9f3 100644 --- a/frontend/mgramseva/lib/services/urls.dart +++ b/frontend/mgramseva/lib/services/urls.dart @@ -91,6 +91,8 @@ class Url { 'ws-services/wc/_billReport'; static const String COLLECTION_REPORT= 'ws-services/wc/_collectionReport'; + static const String INACTIVE_CONSUMER_REPORT= + 'ws-services/wc/_inactiveConsumerReport'; } diff --git a/frontend/mgramseva/lib/utils/constants/i18_key_constants.dart b/frontend/mgramseva/lib/utils/constants/i18_key_constants.dart index c7d8aab91..51a0a367b 100644 --- a/frontend/mgramseva/lib/utils/constants/i18_key_constants.dart +++ b/frontend/mgramseva/lib/utils/constants/i18_key_constants.dart @@ -224,6 +224,9 @@ class Common { String get RATE_PERCENTAGE => 'RATE_PERCENTAGE'; String get REGION_NAME => 'REGION_NAME'; + String get INACTIVATED_BY_NAME => 'INACTIVATED_BY_NAME'; + String get INACTIVATED_DATE => 'INACTIVATED_DATE'; + String get INACTIVATED_BY_UUID => 'INACTIVATED_BY_UUID'; } class Password { @@ -671,6 +674,7 @@ class _DashBoard { String get CORE_REPORTS => 'CORE_REPORTS'; String get BILL_REPORT => 'BILL_REPORT'; String get COLLECTION_REPORT => 'COLLECTION_REPORT'; + String get INACTIVE_CONSUMER_REPORT => 'INACTIVE_CONSUMER_REPORT'; String get GPWSC_RATE_INFO => 'GPWSC_RATE_INFO'; } diff --git a/frontend/mgramseva/lib/utils/testing_keys/testing_keys.dart b/frontend/mgramseva/lib/utils/testing_keys/testing_keys.dart index 87133b09b..abae97452 100644 --- a/frontend/mgramseva/lib/utils/testing_keys/testing_keys.dart +++ b/frontend/mgramseva/lib/utils/testing_keys/testing_keys.dart @@ -134,6 +134,7 @@ class BillReportKeys { Key get BILL_REPORT_VIEW_BUTTON => Key("bill_report_view_button"); Key get BILL_REPORT_DOWNLOAD_BUTTON => Key("bill_report_download_button"); Key get COLLECTION_REPORT_VIEW_BUTTON => Key("collection_report_view_button"); + Key get INACTIVE_CONSUMER_REPORT_VIEW_BUTTON => Key("inactive_consumer_report_view_button"); Key get COLLECTION_REPORT_DOWNLOAD_BUTTON => Key("collection_report_download_button"); Key get BILL_REPORT_BILLING_YEAR => Key("bill_report_billing_year"); Key get BILL_REPORT_BILLING_CYCLE => Key("bill_report_billing_cycle");