From 6afd505a96697a335567b6abc465f6ad55e104a1 Mon Sep 17 00:00:00 2001 From: kratikpal Date: Wed, 7 Aug 2024 09:29:30 +0530 Subject: [PATCH] reject kyc --- lib/constants/only_uppercase.dart | 11 + lib/models/rejected_applicaton_response.dart | 208 +++++++++++++++++++ lib/provider/rejected_provider.dart | 40 ++++ lib/screens/Visit_Dealers_screen.dart | 14 +- lib/screens/change_password_screen.dart | 2 +- lib/screens/daily_tasks_screen.dart | 2 +- lib/screens/home_screen.dart | 17 ++ lib/screens/rejected_application_screen.dart | 204 ++++++++++++++++++ lib/screens/retailer_details_screen.dart | 7 + lib/services/api_urls.dart | 1 + 10 files changed, 499 insertions(+), 7 deletions(-) create mode 100644 lib/constants/only_uppercase.dart create mode 100644 lib/models/rejected_applicaton_response.dart create mode 100644 lib/provider/rejected_provider.dart create mode 100644 lib/screens/rejected_application_screen.dart diff --git a/lib/constants/only_uppercase.dart b/lib/constants/only_uppercase.dart new file mode 100644 index 0000000..909139a --- /dev/null +++ b/lib/constants/only_uppercase.dart @@ -0,0 +1,11 @@ +import 'package:flutter/services.dart'; + +class UpperCaseTextFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) { + return newValue.copyWith( + text: newValue.text.toUpperCase(), + selection: newValue.selection, + ); + } +} \ No newline at end of file diff --git a/lib/models/rejected_applicaton_response.dart b/lib/models/rejected_applicaton_response.dart new file mode 100644 index 0000000..3b097f4 --- /dev/null +++ b/lib/models/rejected_applicaton_response.dart @@ -0,0 +1,208 @@ +class RejectedApplicationResponse { + String? sId; + String? name; + String? tradeName; + String? address; + String? state; + String? city; + String? district; + String? pincode; + String? mobileNumber; + PrincipalDistributer? principalDistributer; + String? panNumber; + PanImg? panImg; + String? aadharNumber; + PanImg? aadharImg; + String? gstNumber; + PanImg? gstImg; + PanImg? pesticideLicenseImg; + PanImg? fertilizerLicenseImg; + PanImg? selfieEntranceImg; + String? status; + String? addedBy; + List? notes; + String? createdAt; + String? updatedAt; + int? iV; + + RejectedApplicationResponse( + {this.sId, + this.name, + this.tradeName, + this.address, + this.state, + this.city, + this.district, + this.pincode, + this.mobileNumber, + this.principalDistributer, + this.panNumber, + this.panImg, + this.aadharNumber, + this.aadharImg, + this.gstNumber, + this.gstImg, + this.pesticideLicenseImg, + this.fertilizerLicenseImg, + this.selfieEntranceImg, + this.status, + this.addedBy, + this.notes, + this.createdAt, + this.updatedAt, + this.iV}); + + RejectedApplicationResponse.fromJson(Map json) { + sId = json['_id']; + name = json['name']; + tradeName = json['trade_name']; + address = json['address']; + state = json['state']; + city = json['city']; + district = json['district']; + pincode = json['pincode']; + mobileNumber = json['mobile_number']; + principalDistributer = json['principal_distributer'] != null + ? PrincipalDistributer.fromJson(json['principal_distributer']) + : null; + panNumber = json['pan_number']; + panImg = + json['pan_img'] != null ? PanImg.fromJson(json['pan_img']) : null; + aadharNumber = json['aadhar_number']; + aadharImg = json['aadhar_img'] != null + ? PanImg.fromJson(json['aadhar_img']) + : null; + gstNumber = json['gst_number']; + gstImg = + json['gst_img'] != null ? PanImg.fromJson(json['gst_img']) : null; + pesticideLicenseImg = json['pesticide_license_img'] != null + ? PanImg.fromJson(json['pesticide_license_img']) + : null; + fertilizerLicenseImg = json['fertilizer_license_img'] != null + ? PanImg.fromJson(json['fertilizer_license_img']) + : null; + selfieEntranceImg = json['selfie_entrance_img'] != null + ? PanImg.fromJson(json['selfie_entrance_img']) + : null; + status = json['status']; + // addedBy = json['addedBy']; + if (json['notes'] != null) { + notes = []; + json['notes'].forEach((v) { + notes!.add(Notes.fromJson(v)); + }); + } + createdAt = json['createdAt']; + updatedAt = json['updatedAt']; + iV = json['__v']; + } + + Map toJson() { + final Map data = {}; + data['_id'] = sId; + data['name'] = name; + data['trade_name'] = tradeName; + data['address'] = address; + data['state'] = state; + data['city'] = city; + data['district'] = district; + data['pincode'] = pincode; + data['mobile_number'] = mobileNumber; + if (principalDistributer != null) { + data['principal_distributer'] = principalDistributer!.toJson(); + } + data['pan_number'] = panNumber; + if (panImg != null) { + data['pan_img'] = panImg!.toJson(); + } + data['aadhar_number'] = aadharNumber; + if (aadharImg != null) { + data['aadhar_img'] = aadharImg!.toJson(); + } + data['gst_number'] = gstNumber; + if (gstImg != null) { + data['gst_img'] = gstImg!.toJson(); + } + if (pesticideLicenseImg != null) { + data['pesticide_license_img'] = pesticideLicenseImg!.toJson(); + } + if (fertilizerLicenseImg != null) { + data['fertilizer_license_img'] = fertilizerLicenseImg!.toJson(); + } + if (selfieEntranceImg != null) { + data['selfie_entrance_img'] = selfieEntranceImg!.toJson(); + } + data['status'] = status; + data['addedBy'] = addedBy; + if (notes != null) { + data['notes'] = notes!.map((v) => v.toJson()).toList(); + } + data['createdAt'] = createdAt; + data['updatedAt'] = updatedAt; + data['__v'] = iV; + return data; + } +} + +class PrincipalDistributer { + String? sId; + String? name; + + PrincipalDistributer({this.sId, this.name}); + + PrincipalDistributer.fromJson(Map json) { + sId = json['_id']; + name = json['name']; + } + + Map toJson() { + final Map data = {}; + data['_id'] = sId; + data['name'] = name; + return data; + } +} + +class PanImg { + String? publicId; + String? url; + + PanImg({this.publicId, this.url}); + + PanImg.fromJson(Map json) { + publicId = json['public_id']; + url = json['url']; + } + + Map toJson() { + final Map data = {}; + data['public_id'] = publicId; + data['url'] = url; + return data; + } +} + +class Notes { + String? message; + String? user; + String? replyDate; + String? sId; + + Notes({this.message, this.user, this.replyDate, this.sId}); + + Notes.fromJson(Map json) { + message = json['message']; + user = json['user']; + replyDate = json['replyDate']; + sId = json['_id']; + } + + Map toJson() { + final Map data = {}; + data['message'] = message; + data['user'] = user; + data['replyDate'] = replyDate; + data['_id'] = sId; + return data; + } +} diff --git a/lib/provider/rejected_provider.dart b/lib/provider/rejected_provider.dart new file mode 100644 index 0000000..c0d6402 --- /dev/null +++ b/lib/provider/rejected_provider.dart @@ -0,0 +1,40 @@ +import 'package:cheminova/models/rejected_applicaton_response.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import '../services/api_client.dart'; +import '../services/api_urls.dart'; + +class RejectedProvider extends ChangeNotifier { + RejectedProvider() { + getRejectedApplication(); + } + final _apiClient = ApiClient(); + RejectedApplicationResponse? rejectedApplicationResponse; + List rejectedApplicationList = []; + + bool _isLoading = false; + + bool get isLoading => _isLoading; + + void setLoading(bool loading) { + _isLoading = loading; + notifyListeners(); + } + + Future getRejectedApplication() async { + setLoading(true); + try { + Response response = await _apiClient.get(ApiUrls.rejectedApplication); + setLoading(false); + if (response.statusCode == 200) { + rejectedApplicationList = (response.data as List) + .map((e) => RejectedApplicationResponse.fromJson(e)) + .toList(); + notifyListeners(); + } + } catch (e) { + setLoading(false); + } + } +} diff --git a/lib/screens/Visit_Dealers_screen.dart b/lib/screens/Visit_Dealers_screen.dart index 9bd3581..9b18276 100644 --- a/lib/screens/Visit_Dealers_screen.dart +++ b/lib/screens/Visit_Dealers_screen.dart @@ -19,7 +19,7 @@ class VisitDealersScreenState extends State { text: DateFormat('dd/MM/yyyy').format(DateTime.now())); final timeController = - TextEditingController(text: DateFormat('hh:mm a').format(DateTime.now())); + TextEditingController(text: DateFormat('hh:mm a').format(DateTime.now())); final notesController = TextEditingController(); final dealerController = TextEditingController(); @@ -28,7 +28,11 @@ class VisitDealersScreenState extends State { final nextVisitDateController = TextEditingController(); String selectedPurpose = 'Sales/Liquidation'; - List purposeOptions = ['Sales/Liquidation', 'Dues collection', 'Others']; + List purposeOptions = [ + 'Sales/Liquidation', + 'Dues collection', + 'Others' + ]; Future _pickImage() async { final ImagePicker picker = ImagePicker(); @@ -72,8 +76,8 @@ class VisitDealersScreenState extends State { const SizedBox(height: 16), Container( padding: - const EdgeInsets.all(20.0).copyWith(top: 30, bottom: 30), - margin: const EdgeInsets.symmetric(horizontal: 30.0), + const EdgeInsets.all(20.0).copyWith(top: 30, bottom: 30), + // margin: const EdgeInsets.symmetric(horizontal: 30.0), decoration: BoxDecoration( border: Border.all(color: Colors.white), color: const Color(0xffB4D1E5).withOpacity(0.9), @@ -172,4 +176,4 @@ class VisitDealersScreenState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/screens/change_password_screen.dart b/lib/screens/change_password_screen.dart index f792ca7..574c614 100644 --- a/lib/screens/change_password_screen.dart +++ b/lib/screens/change_password_screen.dart @@ -158,7 +158,7 @@ class _ChangePasswordPageState extends State { borderRadius: 30, width: double.infinity, height: kToolbarHeight - 10, - text: 'SIGN IN', + text: 'RESET PASSWORD', isLoading: _isLoading, onPressed: () { _changePassword().then( diff --git a/lib/screens/daily_tasks_screen.dart b/lib/screens/daily_tasks_screen.dart index 849cdd1..99efd8c 100644 --- a/lib/screens/daily_tasks_screen.dart +++ b/lib/screens/daily_tasks_screen.dart @@ -2,7 +2,7 @@ import 'package:cheminova/screens/collect_kyc_screen.dart'; import 'package:cheminova/screens/update_inventory_screen.dart'; import 'package:cheminova/screens/display_sales_screen.dart'; import 'package:flutter/material.dart'; -import 'package:cheminova/screens/Visit_Dealers_screen.dart'; +import 'package:cheminova/screens/visit_Dealers_screen.dart'; import 'package:cheminova/widgets/common_app_bar.dart'; import 'package:cheminova/widgets/common_drawer.dart'; import 'package:cheminova/widgets/common_background.dart'; diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index ab40c99..652405a 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -5,6 +5,7 @@ import 'package:cheminova/screens/collect_kyc_screen.dart'; import 'package:cheminova/screens/mark_attendence_screen.dart'; import 'package:cheminova/screens/notification_screen.dart'; import 'package:cheminova/screens/products_manual_screen.dart'; +import 'package:cheminova/screens/rejected_application_screen.dart'; import 'package:cheminova/screens/summary_screen.dart'; import 'package:cheminova/screens/product_sales_data.dart'; import 'package:cheminova/screens/update_inventory_screen.dart'; @@ -199,6 +200,22 @@ class _HomePageState extends State { ], ), const SizedBox(height: 5), + Row( + children: [ + Expanded( + child: _buildCustomCard('Rejected Applications', + 'Re-upload Rejected Documents', onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + const RejectedApplicationScreen(), + )); + }), + ), + ], + ), + const SizedBox(height: 5), Row( children: [ Expanded( diff --git a/lib/screens/rejected_application_screen.dart b/lib/screens/rejected_application_screen.dart new file mode 100644 index 0000000..db7c8f5 --- /dev/null +++ b/lib/screens/rejected_application_screen.dart @@ -0,0 +1,204 @@ +import 'package:cheminova/models/rejected_applicaton_response.dart'; +import 'package:flutter/material.dart'; +import 'package:cheminova/widgets/common_background.dart'; +import 'package:cheminova/widgets/common_drawer.dart'; +import 'package:cheminova/widgets/common_app_bar.dart'; +import 'package:cheminova/widgets/common_elevated_button.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; + +import '../provider/rejected_provider.dart'; + +class RejectedApplicationScreen extends StatefulWidget { + const RejectedApplicationScreen({super.key}); + + @override + State createState() => _RejectedApplicationScreenState(); +} + +class _RejectedApplicationScreenState extends State { + late RejectedProvider _rejectedProvider; + + @override + void initState() { + _rejectedProvider = RejectedProvider(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + create: (context) => _rejectedProvider, + child: CommonBackground( + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: CommonAppBar( + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Image.asset('assets/Back_attendance.png'), + padding: const EdgeInsets.only(right: 20), + ), + ], + title: const Text('Rejected Application', + style: TextStyle( + fontSize: 20, + color: Colors.black, + fontWeight: FontWeight.w400, + fontFamily: 'Anek')), + backgroundColor: Colors.transparent, + elevation: 0, + ), + drawer: const CommonDrawer(), + body: Consumer( + builder: (context, value, child) => value.isLoading + ? const Center(child: CircularProgressIndicator()) + : MyListView(value: value), + // child: Padding( + // padding: const EdgeInsets.all(16.0), + // child: SingleChildScrollView( + // physics: const BouncingScrollPhysics(), + // child: Column( + // mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // const SizedBox(height: 16), + // Container( + // padding: const EdgeInsets.all(20.0).copyWith( + // top: 30, bottom: 30), + // decoration: BoxDecoration( + // border: Border.all(color: Colors.white), + // color: const Color(0xffB4D1E5).withOpacity(0.9), + // borderRadius: BorderRadius.circular(26.0), + // ), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // _buildProductButton('Trade Name 1'), + // _buildProductButton('Trade Name 2'), + // _buildProductButton('Trade Name 3'), + // // _buildProductButton('Product 4'), + // // _buildProductButton('Product 5'), + // // _buildProductButton('Product 6'), + // // _buildProductButton('Product 7'), + // ], + // ), + // ), + // ], + // ), + // ), + // ), + ), + ), + ) + ); + } +} + Widget _buildProductButton(String productName) { + return Padding( + padding: const EdgeInsets.only(bottom: 15), + child: CommonElevatedButton( + borderRadius: 30, + width: double.infinity, + height: kToolbarHeight - 10, + text: productName, + backgroundColor: const Color(0xff004791), + onPressed: () { + // Handle product button press + debugPrint('$productName pressed'); + }, + ), + ); + } + +class MyListView extends StatelessWidget { + final RejectedProvider value; + const MyListView( {super.key, required this.value}); + + @override + Widget build(BuildContext context) { + return ListView.builder( + padding: const EdgeInsets.only(top: 15), + itemCount: value.rejectedApplicationList.length, + itemBuilder: (context, index) { + RejectedApplicationResponse item = value.rejectedApplicationList[index]; + return Padding( + padding: const EdgeInsets.only(bottom: 10,left: 10,right: 10), + child: ExpansionTile( + + collapsedBackgroundColor: Colors.white, + backgroundColor: Colors.white, + + title: Text(item.tradeName ?? '',style: const TextStyle(fontSize: 17,fontWeight:FontWeight.w500),), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text((DateFormat("dd/MM/yyyy") + .format(DateTime.parse(item.createdAt ?? '')))), + Text(item.sId ?? ''), + ], + ), + children: [ + ListTile( + title: Text('Address: ${item.address ?? ''}'), + ), + ListTile( + title: Text('City: ${item.city ?? ''}'), + ), + ListTile( + title: Text('State: ${item.state ?? ''}'), + ), + ListTile( + title: Text('Pincode: ${item.pincode ?? ''}'), + ), + ListTile( + title: Text('Mobile: ${item.mobileNumber ?? ''}'), + ), + ListTile( + title: Text('Status: ${item.status ?? ''}'), + ), + ListTile( + title: Text('Principal Distributor: ${item.principalDistributer!.name ?? ''}'), + ), + ListTile( + title: Text('PAN Number: ${item.panNumber ?? ''}'), + ), + Image.network(item.panImg!.url ?? '',height: 250,width: 250), + ListTile( + title: Text('Aadhar Number: ${item.aadharNumber?? ''}'), + ), + Image.network(item.aadharImg?.url ?? '',height: 250,width: 250), + ListTile( + title: Text('GST Number: ${item.gstNumber ?? ''}'), + ), + Image.network(item.gstImg!.url ?? '',height: 250,width: 250),const ListTile( + title: Text('Pesticide License: '), + ), + + if (item.pesticideLicenseImg != null) + Image.network(item.pesticideLicenseImg!.url ?? '',height: 250,width: 250), + // if (item['fertilizer_license_img'] != null) + // Image.network(item['fertilizer_license_img']['url'] ?? ''), + const ListTile( + title: Text('selfieEntranceImg: '), + ), + Image.network(item.selfieEntranceImg!.url ?? '',height: 250,width: 250), + const ListTile( + title: Text('Notes:'), + ), + if (item.notes != null) + for (var note in item.notes!) + ListTile( + contentPadding: const EdgeInsets.only(left: 20), + title: Text(note.message ?? ''), + ), + + ], + ), + ); + }, + ); + } +} \ No newline at end of file diff --git a/lib/screens/retailer_details_screen.dart b/lib/screens/retailer_details_screen.dart index 261ce59..9763b68 100644 --- a/lib/screens/retailer_details_screen.dart +++ b/lib/screens/retailer_details_screen.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import '../constants/only_uppercase.dart'; import '../widgets/common_elevated_button.dart'; import '../widgets/common_text_form_field.dart'; @@ -152,6 +153,9 @@ class RetailerDetailsScreenState extends State { controller: value.aadharNumberController), const SizedBox(height: 15), CommonTextFormField( + inputFormatters: [ + UpperCaseTextFormatter(), + ], maxLength: 10, title: 'PAN Number', fillColor: Colors.white, @@ -164,6 +168,9 @@ class RetailerDetailsScreenState extends State { controller: value.panNumberController), const SizedBox(height: 15), CommonTextFormField( + inputFormatters: [ + UpperCaseTextFormatter(), + ], maxLength: 15, title: 'GST Number', fillColor: Colors.white, diff --git a/lib/services/api_urls.dart b/lib/services/api_urls.dart index d02e770..d9a943a 100644 --- a/lib/services/api_urls.dart +++ b/lib/services/api_urls.dart @@ -8,4 +8,5 @@ class ApiUrls { static const String changePasswordUrl = 'territorymanager/password/update'; static const String createCollectKycUrl = '${baseUrl}kyc/create-tm'; static const String getPdUrl = 'kyc/get-pd-tm'; + static const String rejectedApplication = '${baseUrl}kyc/getAllrejected-tm'; }