Commit dc88a3f9 authored by Sai Srinivas's avatar Sai Srinivas
Browse files

gen erp 08-10

parent d2c9404a
import 'dart:io';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:generp/Models/VersionsResponse.dart';
import 'package:generp/Notifiers/HomeScreenNotifier.dart';
import 'package:generp/Notifiers/loginNotifier.dart';
import 'package:generp/Utils/SharedpreferencesService.dart';
import 'package:generp/screens/HomeScreen.dart';
......@@ -55,7 +54,7 @@ class SplashVersionNotifier extends ChangeNotifier {
if (data != null) {
if (kDebugMode) {
print("Current Build: $currentBuild");
print("Server Response: $data");
print("Server Response: ${data.latestVersionCode}");
}
if (Platform.isAndroid &&
currentBuild < (data.latestVersionCode ?? 0)) {
......
import 'dart:convert';
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
......@@ -10,56 +11,138 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_ringtone_player/flutter_ringtone_player.dart';
import 'package:generp/Models/hrmModels/leaveApplicationLIstResponse.dart';
import 'package:generp/Utils/app_colors.dart';
import 'package:generp/screens/AttendanceScreen.dart';
import 'package:generp/screens/crm/LeadDetailsByMode.dart';
import 'package:generp/screens/crm/ProspectListByMode.dart';
import 'package:generp/screens/crm/crmDashboard.dart';
import 'package:generp/screens/hrm/Attendancelist.dart';
import 'package:generp/screens/hrm/OrganizationStructureScreen.dart';
import 'package:generp/screens/hrm/TourExpensesListScreen.dart';
import 'Notifiers/hrmProvider/advanceProvider.dart';
import 'screens/notifierExports.dart';
import 'package:generp/Utils/SharedpreferencesService.dart';
import 'package:generp/screens/splash.dart';
import 'package:provider/provider.dart';
import 'Utils/commonWidgets.dart';
// Navigator Key for global navigation
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// Notification Channel
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'generp_channel', // id
'generp_channel',
'generp_channel_name',
importance: Importance.max,
playSound: false,
playSound: true,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
FlutterLocalNotificationsPlugin();
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
String type = message.data['type'] ?? '';
debugPrint("📩 Background notification received: ${message.data}");
}
if (type == 'offline_reminder') {
FlutterRingtonePlayer().play(
// fromAsset: "assets/offline_reminder.mp3",
ios: IosSounds.glass, // Specify the iOS sound
);
} else if (type == 'normal') {
FlutterRingtonePlayer().play(
// fromAsset: "assets/notification_sound.mp3",
ios: IosSounds.glass, // Specify the iOS sound
);
} else if (type == 'web_erp_notification') {
FlutterRingtonePlayer().play(
// fromAsset: "assets/notification_sound.mp3",
ios: IosSounds.glass, // Specify the iOS sound
);
} else {
FlutterRingtonePlayer().play(
// fromAsset: "assets/notification_sound.mp3",
// will be the sound on Android
ios: IosSounds.glass, // will be the sound on iOS
);
}
if (kDebugMode) {
print('A Background message just showed up: ${message.messageId}');
void handleNotificationTap(Map<String, dynamic> data) {
debugPrint("👉 Handling notification tap: $data");
try {
String type = data['type'] ?? '';
String? rollId = data['RoleID'] ?? data['rollId'];
String? notificationId = data['notification_id'] ?? data['notificationId'];
String? url = data['url'];
String? mode = data['Parameter'];
debugPrint("👉 Handling notification tap: $mode");
if (type.toLowerCase() == "app") {
// 🔥 Navigation based on RoleID
switch (rollId) {
case "1":
navigatorKey.currentState?.pushNamed('/crm_lead_list');
break;
case "4":
navigatorKey.currentState?.pushNamed('/crm_prospect_list');
break;
case "5":
navigatorKey.currentState?.pushNamed(
'/crm_prospect_details',
arguments: {"id": notificationId},
);
break;
case "6":
navigatorKey.currentState?.pushNamed(
'/crm_lead_details',
arguments: {"id": notificationId},
);
break;
case "7":
navigatorKey.currentState?.pushNamed('/dashboard');
break;
case "8":
navigatorKey.currentState?.pushNamed('/crm_new_customer_new_lead_register');
break;
case "10":
navigatorKey.currentState?.pushNamed('/crm_prospect_list_team');
break;
case "11":
navigatorKey.currentState?.pushNamed('/crm_prospect_list_admin');
break;
case "15":
navigatorKey.currentState?.pushNamed('/finance_list_employee');
break;
case "16":
navigatorKey.currentState?.pushNamed('/finance_list_admin');
break;
case "17":
navigatorKey.currentState?.pushNamed('/dispatch_list_executive');
break;
case "312":
navigatorKey.currentState?.pushNamed('/tour_bill_list');
break;
case "601":
navigatorKey.currentState?.pushNamed('/manual_attendance_request_list');
break;
default:
navigatorKey.currentState?.pushNamed('/home'); // fallback
}
} else if (type.toLowerCase() == "web" && url != null && url.isNotEmpty) {
// Open in WebView or browser
navigatorKey.currentState?.pushNamed(
'/webview',
arguments: {"url": url},
);
} else {
// fallback
navigatorKey.currentState?.pushNamed('/home');
}
} catch (e) {
debugPrint("❌ Error handling notification tap: $e");
}
}
// FlutterLocalNotificationsPlugin cannot auto-detect foreground taps
void showInAppNotification(BuildContext context, Map<String, dynamic> data) {
final snackBar = SnackBar(
content: Text(data['type'] ?? "New Notification"),
action: SnackBarAction(
label: 'Open',
onPressed: () {
debugPrint("👉 Foreground notification tapped: $data");
handleNotificationTap(data);
},
),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Firebase init
if (Platform.isAndroid) {
await Firebase.initializeApp(
options: FirebaseOptions(
......@@ -72,60 +155,147 @@ void main() async {
} else if (Platform.isIOS) {
await Firebase.initializeApp();
}
if (kDebugMode) {
if (Firebase.apps.isNotEmpty) {
print("Firebase is initialized");
} else {
print("Firebase is not initialized");
// 🔔 Local Notification Init
const AndroidInitializationSettings initSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings initSettingsIOS = DarwinInitializationSettings();
const InitializationSettings initializationSettings = InitializationSettings(
android: initSettingsAndroid,
iOS: initSettingsIOS,
);
flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse notificationResponse) async {
if (notificationResponse.payload != null) {
handleNotificationTap(jsonDecode(notificationResponse.payload!));
debugPrint("📩 Notification clicked: $notificationResponse");
}
}
}
);
// Firebase Messaging
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging messaging = FirebaseMessaging.instance;
await messaging.requestPermission(alert: true, badge: true, sound: true);
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: true,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: false,
);
// Foreground notification
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
print("msg");
String type = message.data['type'] ?? '';
if (type == 'offline_reminder') {
FlutterRingtonePlayer().play(
fromAsset: "assets/offline_reminder.mp3",
ios: IosSounds.glass, // Specify the iOS sound
);
} else if (type == 'normal') {
FlutterRingtonePlayer().play(
fromAsset: "assets/notification_sound.mp3",
ios: IosSounds.glass, // Specify the iOS sound
);
} else if (type == 'web_erp_notification') {
FlutterRingtonePlayer().play(
fromAsset: "assets/notification_sound.mp3",
ios: IosSounds.glass, // Specify the iOS sound
);
} else {
FlutterRingtonePlayer().play(
fromAsset:
"assets/notification_sound.mp3", // will be the sound on Android
ios: IosSounds.glass, // will be the sound on iOS
final notification = message.notification;
final android = message.notification?.android;
debugPrint("😊 Foreground msg received: ${message.data}");
if (notification != null && android != null) {
// flutterLocalNotificationsPlugin.show(
// notification.hashCode,
// notification.title,
// notification.body,
// NotificationDetails(
// android: AndroidNotificationDetails(
// channel.id,
// channel.name,
// importance: Importance.max,
// priority: Priority.high,
// icon: '@mipmap/ic_launcher',
// ),
// ),
// payload: jsonEncode({
// "type": message.data['type'],
// "rollId": message.data['RoleID'],
// "notificationId": message.data['notification_id'],
// }),
// );
}
// ⚡ Foreground tap alternative:
// Show an in-app banner or SnackBar with a tap action
final context = navigatorKey.currentContext;
if (context != null) {
// Add haptic feedback
HapticFeedback.mediumImpact();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
SizedBox(
child: Image.asset(
"assets/images/ic_splash.jpg",
height: 30,
width: 30,
),
),
SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
notification?.title ?? "New Notification",
style: TextStyle(
fontSize: 14,
color: AppColors.app_blue,
fontFamily: "JakartaMedium",
),
),
if (notification?.body != null) SizedBox(height: 2),
if (notification?.body != null)
Text(
notification!.body!,
style: TextStyle(
fontSize: 12,
color: AppColors.semi_black,
fontFamily: "JakartaMedium",
),
),
],
),
),
],
),
action: SnackBarAction(
label: "Open",
textColor: AppColors.app_blue,
onPressed: () {
// Add haptic feedback for button press
HapticFeedback.lightImpact();
debugPrint("👉 Foreground notification tapped: ${message.data}");
// Use the same payload structure as local notifications
handleNotificationTap({
"type": message.data['type'],
"rollId": message.data['RoleID'],
"notificationId": message.data['notification_id'],
});
},
),
backgroundColor: AppColors.white,
behavior: SnackBarBehavior.floating,
elevation: 6,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
margin: const EdgeInsets.all(16),
duration: const Duration(seconds: 4),
),
);
}
});
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin
>()
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
......@@ -134,13 +304,27 @@ void main() async {
sound: true,
);
await FirebaseMessaging.instance.getToken().then((value) {
String? token = value;
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
String type = message.data['type'] ?? '';
String redirectUrl = message.data['redirect_url'] ?? '';
handleNotificationTap(message.data);
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => Dashboard()),
// );
if (kDebugMode) {
// print("fbstoken:{$token}");
print('A new onMessageOpenedApp event was published!');
}
});
SharedpreferencesService().saveString("fbstoken", token!);
// Save FCM Token
await FirebaseMessaging.instance.getToken().then((value) {
if (value != null) {
SharedpreferencesService().saveString("fbstoken", value);
debugPrint("🔑 FCM Token: $value");
}
});
runApp(const MyApp());
......@@ -153,19 +337,19 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// SystemChrome.setApplicationSwitcherDescription(ApplicationSwitcherDescription());
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
String type = message.data['type'] ?? '';
String redirectUrl = message.data['redirect_url'] ?? '';
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => Dashboard()),
// );
if (kDebugMode) {
print('A new onMessageOpenedApp event was published!');
}
});
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
// FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// String type = message.data['type'] ?? '';
// String redirectUrl = message.data['redirect_url'] ?? '';
//
// // Navigator.push(
// // context,
// // MaterialPageRoute(builder: (context) => Dashboard()),
// // );
// if (kDebugMode) {
// print('A new onMessageOpenedApp event was published!');
// }
// });
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => SplashVersionNotifier()),
......@@ -226,9 +410,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => Dispatchorderprovider()),
ChangeNotifierProvider(create: (_) => followUpUpdateProvider()),
ChangeNotifierProvider(create: (_) => Appointmentcalendarprovider()),
ChangeNotifierProvider(
create: (_) => Addnewleadsandprospectsprovider(),
),
ChangeNotifierProvider(create: (_) => Addnewleadsandprospectsprovider()),
ChangeNotifierProvider(create: (_) => HrmAccessiblePagesProvider()),
ChangeNotifierProvider(create: (_) => Attendancelistprovider()),
ChangeNotifierProvider(create: (_) => AttendanceDetailsProvider()),
......@@ -237,12 +419,36 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => RewardListProvider()),
ChangeNotifierProvider(create: (_) => LeaveApplicationListProvider()),
ChangeNotifierProvider(create: (_) => Orgprovider()),
ChangeNotifierProvider(create: (_) => AdvanceListProvider()),
ChangeNotifierProvider(create: (_) => CasualLeaveHistoryProvider()),
],
child: Builder(
builder: (BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
routes: {
'/home': (context) => const AttendanceScreen(),
'/chat': (context) => AttendanceScreen(),
'/product_details': (context) => AttendanceScreen(),
'/order_details': (context) => AttendanceScreen(),
'/crm_lead_list': (context) => LeadDetailsByMode(mode: "", pageTitleName: "Lead Details", leadId: ""),
'/crm_prospect_list': (context) => ProspectListByMode(),
'/crm_prospect_details': (context) => AttendanceScreen(),
'/crm_lead_details': (context) => AttendanceScreen(),
'/dashboard': (context) => CrmdashboardScreen(),
'/crm_new_customer_new_lead_register': (context) => AttendanceScreen(),
'/crm_prospect_list_team': (context) => AttendanceScreen(),
'/crm_prospect_list_admin': (context) => AttendanceScreen(),
'/finance_list_employee': (context) => AttendanceScreen(),
'/finance_list_admin': (context) => AttendanceScreen(),
'/dispatch_list_executive': (context) => AttendanceScreen(),
'/tour_bill_list': (context) => TourExpensesListScreen(),
'/manual_attendance_request_list': (context) => AttendanceListScreen(mode: "",),
},
scrollBehavior: const MaterialScrollBehavior().copyWith(
dragDevices: {PointerDeviceKind.touch, PointerDeviceKind.mouse},
dragDevices: {PointerDeviceKind.touch,PointerDeviceKind.mouse},
),
navigatorObservers: [MyNavigatorObserver()],
......@@ -261,6 +467,7 @@ class MyApp extends StatelessWidget {
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
scaffoldBackgroundColor: Colors.white,
dialogBackgroundColor: Colors.white,
cardColor: Colors.white,
shadowColor: Colors.white54,
searchBarTheme: const SearchBarThemeData(),
......@@ -304,8 +511,8 @@ class MyApp extends StatelessWidget {
dragHandleSize: Size(60.0, 6.0),
),
colorScheme: const ColorScheme.light(
surface: Colors.white,
).copyWith(surface: Colors.white),
background: Colors.white,
).copyWith(background: Colors.white),
scrollbarTheme: ScrollbarThemeData(
minThumbLength: 20,
interactive: true,
......@@ -316,8 +523,10 @@ class MyApp extends StatelessWidget {
),
),
checkboxTheme: CheckboxThemeData(
side: BorderSide(width: 0.5),
checkColor: WidgetStatePropertyAll(AppColors.white),
),
useMaterial3: true,
// inputDecorationTheme: InputDecorationTheme(
......
......@@ -1779,12 +1779,12 @@ class _MyHomePageState extends State<MyHomePage> {
}
Future<void> _showProfileBottomSheet(BuildContext context) {
final profileNotifier = Provider.of<ProfileNotifer>(context, listen: false);
// final profileNotifier = Provider.of<ProfileNotifer>(context, listen: false);
profileNotifier.fetchJobDescription(
Provider.of<HomescreenNotifier>(context, listen: false),
context,
);
// profileNotifier.fetchJobDescription(
// Provider.of<HomescreenNotifier>(context, listen: false),
// context,
// );
return showModalBottomSheet(
useSafeArea: true,
isDismissible: true,
......@@ -1975,18 +1975,7 @@ class _MyHomePageState extends State<MyHomePage> {
AppColors.semi_black,
),
),
if (profileNotifier
.response
?.jobDescription
?.jobDescription !=
null &&
profileNotifier
.response!
.jobDescription!
.jobDescription !=
"")
if (index ==
2) // only for Designation
if (index == 2) // only for Designation
InkWell(
onTap:
index == 2
......
......@@ -797,7 +797,7 @@ class _LeadDetailsByModeState extends State<LeadDetailsByMode> {
if (productsNotEmpty) ...[
SizedBox(
width: double.infinity,
height: 130,
height: 150,
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
......@@ -872,7 +872,7 @@ class _LeadDetailsByModeState extends State<LeadDetailsByMode> {
);
},
child: Container(
height: 130,
height: 140,
width:
MediaQuery.of(context).size.width *
0.9,
......@@ -966,7 +966,7 @@ class _LeadDetailsByModeState extends State<LeadDetailsByMode> {
AppColors.grey_semi,
),
),
SizedBox(height: 5),
SizedBox(height: 3),
DottedLine(
dashGapLength: 4,
dashGapColor:
......@@ -988,6 +988,24 @@ class _LeadDetailsByModeState extends State<LeadDetailsByMode> {
.semi_black,
),
),
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
provider.leadProducts[lp].remarks ?? "",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.semi_black,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
)
],
),
),
......@@ -3458,6 +3476,34 @@ class _LeadDetailsByModeState extends State<LeadDetailsByMode> {
),
],
),
const SizedBox(height: 10),
TextWidget(context, "Remarks"),
Container(
margin: EdgeInsets.only(bottom: 6),
decoration: BoxDecoration(
color: AppColors.text_field_color,
borderRadius: BorderRadius.circular(14),
),
child: TextFormField(
controller: editProvider.addEditRemarkController,
maxLines: 3,
enabled: true,
style: TextStyle(
color: Colors.black,
fontSize: 14,
),
decoration: InputDecoration(
hintText: "Enter remark",
hintStyle: TextStyle(
color: Colors.grey.shade500,
fontSize: 14,
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
horizontal: 12, vertical: 12),
),
),
),
// IconButton(
// icon: const Icon(Icons.delete),
// onPressed: editProvider.editProductPriceControllers.length > 1
......@@ -3476,8 +3522,8 @@ class _LeadDetailsByModeState extends State<LeadDetailsByMode> {
provider.leadDetails.id!,
type,
leadProductId,
editProvider
.selectedAddEditProductId,
editProvider.selectedAddEditProductId,
editProvider.addEditRemarkController
);
},
child: Container(
......
......@@ -267,24 +267,22 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
),
),
SizedBox(width: 10),
Expanded(
flex: 1,
child: InkResponse(
onTap: () {
HapticFeedback.selectionClick();
launch(
'tel://${crmLists[index].mob1}',
);
},
child: SizedBox(
height: 35,
width: 35,
child: SvgPicture.asset(
"assets/svg/crm/lead_list_call_ic.svg",
),
),
),
),
Expanded(
flex: 1,
child: InkResponse(
onTap: () {
HapticFeedback.selectionClick();
_showContactOptions(context, crmLists[index].mob1);
},
child: SizedBox(
height: 35,
width: 35,
child: SvgPicture.asset(
"assets/svg/crm/lead_list_call_ic.svg",
),
),
),
),
],
),
],
......@@ -930,6 +928,91 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
},
);
}
void _showContactOptions(BuildContext context, String? phoneNumber) {
if (phoneNumber == null || phoneNumber.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("No phone number available")),
);
return;
}
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
backgroundColor: Colors.white,
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.grey.shade400,
borderRadius: BorderRadius.circular(10),
),
),
const SizedBox(height: 16),
const Text(
"Contact Options",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
fontFamily: "JakartaMedium",
color: Colors.black
),
),
const SizedBox(height: 20),
// --- Call Option ---
ListTile(
leading: const Icon(Icons.phone, color: Colors.green),
title: const Text("Call", style: TextStyle(
fontSize: 16,
fontFamily: "JakartaMedium",
)
),
onTap: () async {
Navigator.pop(context);
final uri = Uri.parse("tel:$phoneNumber");
await launchUrl(uri, mode: LaunchMode.externalApplication);
},
),
// --- WhatsApp Option ---
ListTile(
leading: const Icon(Icons.chat, color: Colors.teal),
title: const Text("WhatsApp", style: TextStyle(
fontSize: 16,
fontFamily: "JakartaMedium",
)
),
onTap: () async {
Navigator.pop(context);
final message = Uri.encodeComponent("Hello, I’d like to connect with you.");
final whatsappUri = Uri.parse("https://wa.me/$phoneNumber?text=$message");
if (await canLaunchUrl(whatsappUri)) {
await launchUrl(whatsappUri, mode: LaunchMode.externalApplication);
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("WhatsApp not installed or invalid number")),
);
}
},
),
],
),
);
},
);
}
bool _isFilterSelected(Leadlistprovider provider, int index) {
switch (index) {
......
......@@ -3375,43 +3375,43 @@ class ProspectDetailsByModeState extends State<ProspectDetailsByMode> {
children: [
Expanded(
child: DropdownButton2<String>(
hint: Text(
"Select Status",
style: TextStyle(fontSize: 14),
isExpanded: true,
hint: const Row(
children: [
Expanded(
child: Text(
'Select Lead Status',
style: TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
),
],
),
items:
addleadProvider.statusList
.map(
(slist) =>
DropdownMenuItem<String>(
value: slist,
child: Text(
slist,
style: TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
<String>['All', 'Cold', 'Hot', 'Warm']
.map(
(value) => DropdownMenuItem<String>(
value: value,
child: Text(
value ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
),
)
.toList(),
value: addleadProvider.selectedStatus,
onChanged: (String? value) {
if (value != null) {
if (addleadProvider
.statusList
.isNotEmpty) {
addleadProvider.selectedStatus =
value;
}
}
onChanged: (String? newValue) {
setState(() {
addleadProvider.selectedStatus = newValue!;
});
},
isExpanded: true,
buttonStyleData: ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
menuItemStyleData: ddtheme.menuItemStyleData,
dropdownStyleData: ddtheme.dropdownStyleData,
),
),
],
......@@ -3421,6 +3421,34 @@ class ProspectDetailsByModeState extends State<ProspectDetailsByMode> {
errorWidget(context, addleadProvider.statusError),
],
TextWidget(context, "Remarks"),
Container(
margin: EdgeInsets.only(bottom: 6),
decoration: BoxDecoration(
color: AppColors.text_field_color,
borderRadius: BorderRadius.circular(14),
),
child: TextFormField(
controller: addleadProvider.addLeadProductRemarksController,
maxLines: 3,
enabled: true,
style: TextStyle(
color: Colors.black,
fontSize: 14,
),
decoration: InputDecoration(
hintText: "Enter remark",
hintStyle: TextStyle(
color: Colors.grey.shade500,
fontSize: 14,
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
horizontal: 12, vertical: 12),
),
),
),
InkResponse(
onTap:
addleadProvider.submitLoading
......
......@@ -29,7 +29,6 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
@override
void initState() {
// TODO: implement initState
super.initState();
_connectivity.initialise();
_connectivity.myStream.listen((source) {
......@@ -47,17 +46,15 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
provider.addProductPriceController.clear();
provider.addQuantityController.clear();
provider.addTotalAmountController.clear();
provider.remarkController.clear(); // Clear remarks too
} else {
provider.prefillProductForEdit(widget.editIndex!);
}
// provider.addEditInitializeForm(context);
});
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_connectivity.disposeStream();
}
......@@ -77,15 +74,15 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
}
return (connection == "Online")
? Platform.isAndroid
? WillPopScope(
onWillPop: () => onBackPressed(context),
child: SafeArea(
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
? WillPopScope(
onWillPop: () => onBackPressed(context),
child: SafeArea(
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
: NoNetwork(context);
}
......@@ -94,7 +91,6 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
builder: (context, provider, child) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: appbarNew(context, "Generate Quotation", 0xFFFFFFFF),
backgroundColor: AppColors.scaffold_bg_color,
body: SingleChildScrollView(
......@@ -109,7 +105,6 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
horizontal: 10,
vertical: 10,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
......@@ -129,67 +124,55 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
style: TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
items:
provider.productsList
.map(
(ord) => DropdownMenuItem<Products>(
value: ord,
child: Text(
"${ord.name}",
style: const TextStyle(
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
),
)
.toList(),
// provider.selectedOrderIds[index] != null?
// provider
// .orderList
// .firstWhere(
// (product) =>
// product
// .orderId ==
// provider
// .selectedOrderIds[index],
// )
value:
provider.selectedProducts != null
? provider.productsList.firstWhere(
(element) =>
element.id ==
provider.selectedProductsId,
)
: null,
items: provider.productsList
.map(
(ord) => DropdownMenuItem<Products>(
value: ord,
child: Text(
"${ord.name}",
style: const TextStyle(
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
),
)
.toList(),
value: provider.selectedProducts != null
? provider.productsList.firstWhere(
(element) =>
element.id ==
provider.selectedProductsId,
)
: null,
onChanged: (Products? value) {
if (value != null) {
provider.selectedProducts = value;
provider.selectedProductsId = value.id!;
provider.selectedProductsValue = value.name;
provider.selectedProductsRemark = value.remarks;
provider.crmSelectedProductDetailsApiFunction(
context,
value.id.toString(),
);
}
provider.crmSelectedProductDetailsApiFunction(
context,
value!.id.toString(),
);
},
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider.productSearchController,
provider.productSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider.productSearchController,
provider.productSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Product...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
......@@ -201,10 +184,10 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
),
searchMatchFn: (item, searchValue) {
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -222,7 +205,6 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
],
),
),
const SizedBox(height: 10),
textControllerWidget(
context,
......@@ -255,7 +237,7 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
provider.addTotalAmountController,
"Amount",
"Total Amount",
(_) {},
(_) {},
TextInputType.number,
true,
FilteringTextInputFormatter.digitsOnly,
......@@ -263,54 +245,133 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
),
],
),
// IconButton(
// icon: const Icon(Icons.delete),
// onPressed: provider.editProductPriceControllers.length > 1
// ? () => provider.editRemoveRow(j)
// : null,
// ),
TextWidget(context, "Remarks"),
Container(
margin: EdgeInsets.only(bottom: 6),
decoration: BoxDecoration(
color: AppColors.text_field_color,
borderRadius: BorderRadius.circular(14),
),
child: TextFormField(
controller: provider.remarkController,
maxLines: 3,
enabled: true,
style: TextStyle(
color: Colors.black,
fontSize: 14,
),
decoration: InputDecoration(
hintText: "Enter remark",
hintStyle: TextStyle(
color: Colors.grey.shade500,
fontSize: 14,
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(
horizontal: 12, vertical: 12),
),
),
)
],
),
),
],
),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
FloatingActionButtonLocation.centerFloat,
floatingActionButton: InkWell(
onTap: () {
HapticFeedback.selectionClick();
if (provider.selectedProducts != null) {
final productData = {
"product_id": provider.selectedProductsId!,
"price": provider.addProductPriceController.text,
"qty": provider.addQuantityController.text,
"net_price": provider.addTotalAmountController.text,
};
if (widget.editIndex != null) {
provider.updateProduct(widget.editIndex!, productData);
} else {
provider.addProduct(productData);
}
print(provider.getJsonEncodedProducts());
Navigator.pop(context, provider.getJsonEncodedProducts());
// Validate required fields
if (provider.selectedProducts == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Please select a product"),
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
),
);
return;
}
if (provider.addProductPriceController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Please enter product price"),
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
),
);
return;
}
if (provider.addQuantityController.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Please enter quantity"),
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
),
);
return;
}
// Prepare product data - FIX: Use .text for remarks
final productData = {
"product_id": provider.selectedProductsId!,
"price": provider.addProductPriceController.text,
"qty": provider.addQuantityController.text,
"net_price": provider.addTotalAmountController.text,
"remarks": provider.remarkController.text, // FIXED: Use .text
};
if (widget.editIndex != null) {
provider.updateProduct(widget.editIndex!, productData);
print("Product updated at index ${widget.editIndex}");
} else {
provider.addProduct(productData);
print("New product added");
}
print("Product data: ${provider.getJsonEncodedProducts()}");
// Show success message
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(widget.editIndex != null
? "Product updated successfully!"
: "Product added successfully!"),
backgroundColor: Colors.green,
duration: Duration(seconds: 2),
),
);
// Close screen after a short delay to show the success message
Future.delayed(Duration(milliseconds: 1500), () {
if (mounted) {
Navigator.pop(context, true); // Return true to indicate success
}
});
},
child: Container(
alignment: Alignment.center,
height: 45,
decoration: BoxDecoration(
color: AppColors.app_blue, //1487C9
color: AppColors.app_blue,
borderRadius: BorderRadius.circular(14.0),
),
margin: EdgeInsets.symmetric(horizontal: 10),
child: Center(
child: Text(
"Submit",
widget.editIndex != null ? "Update Product" : "Add Product",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
),
......@@ -319,4 +380,18 @@ class _AddleadproductscreenState extends State<Addleadproductscreen> {
},
);
}
}
Widget TextWidget(context, text) {
return Padding(
padding: const EdgeInsets.only(bottom: 5.0, top: 8.0),
child: Text(
text,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.semi_black,
),
),
);
}
}
\ No newline at end of file
......@@ -299,27 +299,28 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
),
errorWidget(context, provider.companynameError),
textControllerWidget(
context,
provider.contactPersonNameController,
"Contact Person Name",
"Enter Name",
provider.onChangeContactPersonName,
TextInputType.name,
false,
null,
focusNodes[1],
focusNodes[2],
TextInputAction.next,
),
errorWidget(context, provider.nameError),
textControllerWidget(
context,
provider.contactPersonNameController,
"Contact Person Name",
"Enter Name",
(value) => provider.onChangeContactPersonName(context, value),
TextInputType.name,
false,
null,
focusNodes[1],
focusNodes[2],
TextInputAction.next,
),
errorWidget(context, provider.nameError),
textControllerWidget(
context,
provider.mobileController,
"Mobile Number",
"Enter Mobile Number",
provider.onChangemobile,
(value) => provider.onChangemobile(context, value),
TextInputType.phone,
false,
FilteringTextInputFormatter.digitsOnly,
......@@ -931,40 +932,36 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
scrollDirection: Axis.horizontal,
itemCount: provider.productRows.length,
itemBuilder: (context, index) {
final product =
provider.productRows[index];
final productName =
provider.productsList
.firstWhere(
(p) =>
p.id ==
product['product_id'],
orElse:
() => Products(
id: '',
name: 'Unknown',
),
)
.name;
final product = provider.productRows[index];
final productName = provider.productsList
.firstWhere(
(p) => p.id == product['product_id'],
orElse: () => Products(
id: '',
name: 'Unknown',
),
)
.name;
final prodPrice = product['price'] ?? '-';
final prodQty = product['qty'] ?? '-';
final totalPrice =
product['net_price'] ?? '-';
final totalPrice = product['net_price'] ?? '-';
// FIX: Get the text from TextEditingController, not the controller itself
final remark = product['remarks'] is TextEditingController
? (product['remarks'] as TextEditingController).text
: product['remarks']?.toString() ?? '';
return InkResponse(
onTap: () async {
var res = await Navigator.push(
context,
MaterialPageRoute(
builder:
(context) =>
Addleadproductscreen(
type: "Edit",
editIndex: index,
),
builder: (context) => Addleadproductscreen(
type: "Edit",
editIndex: index,
),
settings: RouteSettings(
name:
'Generatequotationaddeditproduct',
name: 'Generatequotationaddeditproduct',
),
),
);
......@@ -973,21 +970,10 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
}
},
child: Container(
width:
MediaQuery.of(
context,
).size.width *
0.8,
width: MediaQuery.of(context).size.width * 0.8,
margin: EdgeInsets.only(
left: index == 0 ? 10 : 5,
right:
index ==
provider
.productRows
.length -
1
? 10
: 5,
right: index == provider.productRows.length - 1 ? 10 : 5,
bottom: 5,
),
padding: EdgeInsets.symmetric(
......@@ -996,15 +982,11 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
),
decoration: BoxDecoration(
color: Color(0xFFE6F6FF),
borderRadius: BorderRadius.circular(
14,
),
borderRadius: BorderRadius.circular(14),
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 1,
......@@ -1016,10 +998,8 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
Expanded(
flex: 6,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
......@@ -1028,32 +1008,23 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
child: Text(
productName ?? "-",
maxLines: 2,
overflow:
TextOverflow
.ellipsis,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontFamily:
"JakartaMedium",
fontFamily: "JakartaMedium",
fontSize: 14,
color:
AppColors
.semi_black,
color: AppColors.semi_black,
),
),
),
Expanded(
flex: 3,
child: Text(
textAlign:
TextAlign.right,
textAlign: TextAlign.right,
"₹$prodPrice",
style: TextStyle(
fontFamily:
"JakartaMedium",
fontFamily: "JakartaMedium",
fontSize: 14,
color:
AppColors
.semi_black,
color: AppColors.semi_black,
),
),
),
......@@ -1062,42 +1033,51 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
Text(
"x $prodQty",
style: TextStyle(
fontFamily:
"JakartaMedium",
fontFamily: "JakartaMedium",
fontSize: 14,
color:
AppColors.grey_semi,
color: AppColors.grey_semi,
),
),
SizedBox(height: 5),
DottedLine(
dashGapLength: 4,
dashGapColor:
Colors.white,
dashColor:
AppColors.grey_semi,
dashGapColor: Colors.white,
dashColor: AppColors.grey_semi,
dashLength: 2,
lineThickness: 0.5,
),
SizedBox(height: 5),
Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"₹$totalPrice",
style: TextStyle(
fontFamily:
"JakartaMedium",
fontFamily: "JakartaMedium",
fontSize: 14,
color:
AppColors
.semi_black,
color: AppColors.semi_black,
),
),
],
),
SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
remark, // Now this is a String, not a TextEditingController
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.semi_black,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
)
],
),
),
......
......@@ -11,6 +11,8 @@ import 'package:generp/Utils/commonWidgets.dart';
import 'package:generp/Utils/dropdownTheme.dart';
import 'package:provider/provider.dart';
import '../order/ordersListByModes.dart';
class Followupupdatescreen extends StatefulWidget {
final leadID;
final mode;
......@@ -391,7 +393,7 @@ class _FollowupupdatescreenState extends State<Followupupdatescreen> {
),
items:
<String>[
// 'Order Gain',
'Order Gain',
'Order Lost',
'No Requirement',
]
......@@ -709,6 +711,9 @@ class _FollowupupdatescreenState extends State<Followupupdatescreen> {
provider.selectedCompetitor,
provider.selectedLeadStatus,
provider.selectNextAppointmentType,
provider.followUpFeedbackController,
provider.selectedTime,
provider.currentLocationLatLng,
provider.smsSent,
widget.mode,
);
......
......@@ -166,23 +166,28 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
MaterialPageRoute(
builder:
(context) =>
Generatequotationaddeditproduct(
leadId: widget.leadId,
type: "add",
),
Generatequotationaddeditproduct(
leadId: widget.leadId,
type: "add",
),
settings: RouteSettings(
name: 'Generatequotationaddeditproduct',
),
),
);
if (res != null) {
if (res != null && res == true) {
print("result $res");
// provider
// .crmLeadDetailsGenerateQuoteViewAPIFunction(
// context,
// widget.leadId,
// );
// Force refresh the provider and UI
await provider.crmLeadDetailsGenerateQuoteViewAPIFunction(
context,
widget.leadId,
);
// Force UI update
if (mounted) {
setState(() {});
}
}
},
child: Container(
......@@ -229,30 +234,39 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
MaterialPageRoute(
builder:
(
context,
context,
) => Generatequotationaddeditproduct(
leadId: widget.leadId,
type: "edit",
product:
provider
.leadProductsList[lp],
index: lp,
),
leadId: widget.leadId,
type: "edit",
product:
provider
.leadProductsList[lp],
index: lp,
),
settings: RouteSettings(
name:
'Generatequotationaddeditproduct',
'Generatequotationaddeditproduct',
),
),
);
if (res != null) {
if (res != null && res == true) {
print("result $res");
// Force refresh after editing
await provider.crmLeadDetailsGenerateQuoteViewAPIFunction(
context,
widget.leadId,
);
// Force UI update
if (mounted) {
setState(() {});
}
}
},
child: Container(
height: 115,
width:
MediaQuery.of(context).size.width *
0.8,
height: 125,
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
color: Color(0xFFE6F6FF),
borderRadius: BorderRadius.circular(14),
......@@ -261,17 +275,12 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
horizontal: 10,
vertical: 8,
),
margin: EdgeInsets.symmetric(
horizontal: 5,
// vertical: 10,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 1,
......@@ -282,87 +291,77 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
SizedBox(width: 10),
Expanded(
flex: 6,
child: SizedBox(
child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Row(
children: [
Expanded(
flex: 4,
child: Text(
provider
.leadProductsList[lp]
.productName ??
"-",
maxLines: 1,
overflow:
TextOverflow
.ellipsis,
style: TextStyle(
fontFamily:
"JakartaMedium",
fontSize: 14,
color:
AppColors
.semi_black,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween, // Changed to spaceBetween
children: [
// Top section - Product name and price
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
flex: 4,
child: Text(
provider.leadProductsList[lp].productName ?? "-",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.semi_black,
),
),
),
),
Expanded(
flex: 2,
child: Text(
textAlign:
TextAlign.right,
"₹${provider.leadProductsList[lp].price ?? "-"}",
style: TextStyle(
fontFamily:
"JakartaMedium",
fontSize: 14,
color:
AppColors
.semi_black,
Expanded(
flex: 3,
child: Text(
textAlign: TextAlign.right,
maxLines: 1,
"₹${provider.leadProductsList[lp].price ?? "-"}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.semi_black,
),
),
),
],
),
SizedBox(height: 1), // Reduced spacing
Text(
"x ${provider.leadProductsList[lp].qty ?? "-"}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 12, // Slightly smaller font
color: AppColors.grey_semi,
),
],
),
Text(
"x ${provider.leadProductsList[lp].qty ?? "-"}",
style: TextStyle(
fontFamily:
"JakartaMedium",
fontSize: 14,
color:
AppColors.grey_semi,
),
),
SizedBox(height: 5),
DottedLine(
],
),
// Middle section - Dotted line
Center(
child: DottedLine(
dashGapLength: 4,
dashGapColor: Colors.white,
dashColor:
AppColors.grey_semi,
dashColor: AppColors.grey_semi,
dashLength: 2,
lineThickness: 0.5,
),
SizedBox(height: 5),
Text(
"₹${provider.leadProductsList[lp].prodTotalPrice ?? " - "}",
style: TextStyle(
fontFamily:
"JakartaMedium",
fontSize: 14,
color:
AppColors.semi_black,
),
),
// Bottom section - Total price
Text(
"₹${provider.leadProductsList[lp].prodTotalPrice ?? " - "}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.semi_black,
),
],
),
),
],
),
),
],
......@@ -374,192 +373,6 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
),
],
errorWidget(context, provider.productRowsError),
// if (provider.leadProductsList.isNotEmpty ||
// provider
// .editProductPriceControllers
// .isNotEmpty) ...[
// ListView.builder(
// itemCount:
// provider.editProductPriceControllers.length,
// physics: const NeverScrollableScrollPhysics(),
// shrinkWrap: true,
// itemBuilder: (context, j) {
// return Container(
// padding: const EdgeInsets.symmetric(
// horizontal: 10,
// vertical: 10,
// ),
// margin: const EdgeInsets.symmetric(
// vertical: 10,
// ),
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(20),
// ),
// child: Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// TextWidget(context, "Product"),
// DropdownButtonHideUnderline(
// child: Row(
// children: [
// Expanded(
// child: DropdownButton2<
// LeadProducts
// >(
// isExpanded: true,
// hint: const Text(
// 'Select Product',
// style: TextStyle(
// fontSize: 14,
// ),
// overflow:
// TextOverflow.ellipsis,
// ),
// items:
// provider.leadProductsList
// .map(
// (
// ord,
// ) => DropdownMenuItem<
// LeadProducts
// >(
// value: ord,
// child: Text(
// "(Product Name: ${ord.productName})",
// style:
// const TextStyle(
// fontSize:
// 14,
// ),
// overflow:
// TextOverflow
// .ellipsis,
// ),
// ),
// )
// .toList(),
// value:
// provider.selectedProductIds[j] !=
// null
// ? provider
// .leadProductsList
// .firstWhere(
// (ord) =>
// ord.id ==
// provider
// .selectedProductIds[j],
// orElse:
// () =>
// provider
// .leadProductsList[0],
// )
// : null,
// onChanged: (
// LeadProducts? value,
// ) {
// if (value != null) {
// provider
// .updateSelectedProductIds(
// j,
// value,
// );
// provider.selectedProductIds[j] =
// value.id?.toString() ??
// '';
// provider.updateTotalAmount(
// j,
// );
// }
// },
// buttonStyleData:
// ddtheme.buttonStyleData,
// iconStyleData:
// ddtheme.iconStyleData,
// menuItemStyleData:
// ddtheme.menuItemStyleData,
// dropdownStyleData:
// ddtheme.dropdownStyleData,
// ),
// ),
// ],
// ),
// ),
// const SizedBox(height: 10),
// Row(
// children: [
// Expanded(
// flex: 2,
// child: textControllerWidget(
// context,
// provider
// .editProductPriceControllers[j],
// "Product Price",
// "Enter Product Price",
// (value) =>
// provider.updateTotalAmount(j),
// TextInputType.number,
// false,
// FilteringTextInputFormatter
// .digitsOnly,
// ),
// ),
// ],
// ),
// const SizedBox(height: 10),
// Row(
// children: [
// Expanded(
// flex: 2,
// child: textControllerWidget(
// context,
// provider
// .editQuantityControllers[j],
// "Quantity",
// "Enter Quantity",
// (value) =>
// provider.updateTotalAmount(j),
// TextInputType.number,
// false,
// FilteringTextInputFormatter
// .digitsOnly,
// ),
// ),
// ],
// ),
// const SizedBox(height: 10),
// Row(
// children: [
// Expanded(
// flex: 2,
// child: textControllerWidget(
// context,
// provider
// .editTotalAmountControllers[j],
// "Amount",
// "Total Amount",
// (_) {},
// TextInputType.number,
// true,
// FilteringTextInputFormatter
// .digitsOnly,
// ),
// ),
// ],
// ),
// // IconButton(
// // icon: const Icon(Icons.delete),
// // onPressed: provider.editProductPriceControllers.length > 1
// // ? () => provider.editRemoveRow(j)
// // : null,
// // ),
// ],
// ),
// );
// },
// ),
// ],
],
),
),
......@@ -599,22 +412,22 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
],
),
items:
<String>["Extra", "Including"]
.map(
(value) =>
DropdownMenuItem<String>(
value: value,
child: Text(
value ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow:
TextOverflow.ellipsis,
),
),
)
.toList(),
<String>["Extra", "Including"]
.map(
(value) =>
DropdownMenuItem<String>(
value: value,
child: Text(
value ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow:
TextOverflow.ellipsis,
),
),
)
.toList(),
value: provider.selectedTaxes,
onChanged: (String? newValue) {
setState(() {
......@@ -624,9 +437,9 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
buttonStyleData: ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -689,7 +502,7 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
FloatingActionButtonLocation.centerFloat,
bottomNavigationBar: Material(
elevation: 2,
shadowColor: Colors.black12,
......@@ -708,239 +521,195 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:
provider.buttonsLoading
? [
SizedBox(width: 25),
CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation(
AppColors.app_blue,
),
),
SizedBox(width: 25),
]
: [
Expanded(
child: InkResponse(
onTap:
provider.buttonsLoading
? null
: () {
HapticFeedback.mediumImpact();
provider.buttonsLoading = true;
//genquotedown
final insertedData =
provider.productRows;
print(insertedData);
provider
.crmLeadDetailsGenerateQuoteSubmitAPIFunction(
context,
widget.leadId,
insertedData,
"genquotedown",
);
},
child: Container(
height: 45,
alignment: Alignment.center,
provider.buttonsLoading
? [
SizedBox(width: 25),
CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation(
AppColors.app_blue,
),
),
SizedBox(width: 25),
]
: [
Expanded(
child: InkResponse(
onTap:
provider.buttonsLoading
? null
: () {
HapticFeedback.mediumImpact();
provider.buttonsLoading = true;
//genquotedown
final insertedData =
provider.productRows;
print(insertedData);
provider
.crmLeadDetailsGenerateQuoteSubmitAPIFunction(
context,
widget.leadId,
insertedData,
"genquotedown",
);
},
child: Container(
height: 45,
alignment: Alignment.center,
decoration: BoxDecoration(
// color: AppColors.app_blue,
borderRadius: BorderRadius.circular(10),
),
child:
provider.submitLoading
? CircularProgressIndicator.adaptive(
valueColor:
AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
),
)
: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/svg/crm/download_quote_ic.svg",
),
SizedBox(width: 10),
Text(
"Download",
style: TextStyle(
fontSize: 14,
fontFamily:
"JakartaRegular",
),
),
],
),
decoration: BoxDecoration(
// color: AppColors.app_blue,
borderRadius: BorderRadius.circular(10),
),
child:
provider.submitLoading
? CircularProgressIndicator.adaptive(
valueColor:
AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
),
)
: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/svg/crm/download_quote_ic.svg",
),
SizedBox(width: 10),
Text(
"Download",
style: TextStyle(
fontSize: 14,
fontFamily:
"JakartaRegular",
),
),
),
SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg",
),
Expanded(
child: InkResponse(
onTap:
provider.buttonsLoading
? null
: () {
HapticFeedback.mediumImpact();
provider.buttonsLoading = true;
//genquotemail,
final insertedData =
provider.productRows;
print(insertedData);
provider
.crmLeadDetailsGenerateQuoteSubmitAPIFunction(
context,
widget.leadId,
insertedData,
"genquotemail",
);
},
child: Container(
height: 45,
alignment: Alignment.center,
],
),
),
),
),
SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg",
),
Expanded(
child: InkResponse(
onTap:
provider.buttonsLoading
? null
: () {
HapticFeedback.mediumImpact();
provider.buttonsLoading = true;
//genquotemail,
final insertedData =
provider.productRows;
print(insertedData);
provider
.crmLeadDetailsGenerateQuoteSubmitAPIFunction(
context,
widget.leadId,
insertedData,
"genquotemail",
);
},
child: Container(
height: 45,
alignment: Alignment.center,
decoration: BoxDecoration(
// color: AppColors.app_blue,
borderRadius: BorderRadius.circular(10),
),
child:
provider.submitLoading
? CircularProgressIndicator.adaptive(
valueColor:
AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
),
)
: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/svg/crm/email_quote_ic.svg",
),
SizedBox(width: 10),
Text(
"Email",
style: TextStyle(
fontSize: 14,
fontFamily:
"JakartaRegular",
),
),
],
),
decoration: BoxDecoration(
// color: AppColors.app_blue,
borderRadius: BorderRadius.circular(10),
),
child:
provider.submitLoading
? CircularProgressIndicator.adaptive(
valueColor:
AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
),
)
: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/svg/crm/email_quote_ic.svg",
),
SizedBox(width: 10),
Text(
"Email",
style: TextStyle(
fontSize: 14,
fontFamily:
"JakartaRegular",
),
),
),
SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg",
),
Expanded(
child: InkResponse(
onTap:
provider.buttonsLoading
? null
: () {
HapticFeedback.mediumImpact();
provider.buttonsLoading = true;
//genquotewhatsapp,
final insertedData =
provider.productRows;
print(insertedData);
provider
.crmLeadDetailsGenerateQuoteSubmitAPIFunction(
context,
widget.leadId,
insertedData,
"genquotewhatsapp",
);
},
child: Container(
height: 45,
alignment: Alignment.center,
],
),
),
),
),
SvgPicture.asset(
"assets/svg/crm/vertical_line_ic.svg",
),
Expanded(
child: InkResponse(
onTap:
provider.buttonsLoading
? null
: () {
HapticFeedback.mediumImpact();
provider.buttonsLoading = true;
//genquotewhatsapp,
final insertedData =
provider.productRows;
print(insertedData);
provider
.crmLeadDetailsGenerateQuoteSubmitAPIFunction(
context,
widget.leadId,
insertedData,
"genquotewhatsapp",
);
},
child: Container(
height: 45,
alignment: Alignment.center,
decoration: BoxDecoration(
// color: AppColors.app_blue,
borderRadius: BorderRadius.circular(10),
),
child:
provider.submitLoading
? CircularProgressIndicator.adaptive(
valueColor:
AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
),
)
: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/svg/crm/whatsapp_quote_ic.svg",
),
SizedBox(width: 10),
Text(
"Whatsapp",
style: TextStyle(
fontSize: 14,
fontFamily:
"JakartaRegular",
),
),
],
),
decoration: BoxDecoration(
// color: AppColors.app_blue,
borderRadius: BorderRadius.circular(10),
),
child:
provider.submitLoading
? CircularProgressIndicator.adaptive(
valueColor:
AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
),
)
: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SvgPicture.asset(
"assets/svg/crm/whatsapp_quote_ic.svg",
),
SizedBox(width: 10),
Text(
"Whatsapp",
style: TextStyle(
fontSize: 14,
fontFamily:
"JakartaRegular",
),
),
),
// Expanded(
// child: InkResponse(
// onTap:
// provider.submitLoading
// ? null
// : () {
// //genquotewhatsappbymynum,
// final insertedData = provider.getFormData();
// provider
// .crmLeadDetailsGenerateQuoteSubmitAPIFunction(
// context,
// widget.leadId,
// insertedData,
// "genquotewhatsappbymynum",
// );
// },
// child: Container(
// height: 45,
// alignment: Alignment.center,
// margin: const EdgeInsets.symmetric(
// horizontal: 10,
// vertical: 15,
// ),
// padding: const EdgeInsets.symmetric(
// horizontal: 10,
// vertical: 5,
// ),
// decoration: BoxDecoration(
// // color: AppColors.app_blue,
// borderRadius: BorderRadius.circular(10),
// ),
// child:
// provider.submitLoading
// ? CircularProgressIndicator.adaptive(
// valueColor: AlwaysStoppedAnimation<Color>(
// AppColors.app_blue,
// ),
// )
// : SvgPicture.asset(
// "assets/svg/whatsapp_quote_self.svg",
// ),
// ),
// ),
// ),
],
],
),
),
),
),
],
),
),
),
......@@ -950,4 +719,4 @@ class _GeneratequotationscreenState extends State<Generatequotationscreen> {
},
);
}
}
}
\ No newline at end of file
......@@ -77,7 +77,7 @@ class _AllpaymentrequesitionlistsbymodesState
_scrollController.addListener(() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent - 200 &&
_scrollController.position.maxScrollExtent - 200 &&
!provider.isLoadingMore &&
provider.hasMoreData) {
provider.paymentRequestionListsAPIFunction(
......@@ -213,17 +213,17 @@ class _AllpaymentrequesitionlistsbymodesState
}
return connection == "Online"
? Platform.isAndroid
? WillPopScope(
onWillPop: () {
return onBackPressed(context);
},
child: SafeArea(
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
? WillPopScope(
onWillPop: () {
return onBackPressed(context);
},
child: SafeArea(
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
: NoNetwork(context);
}
......@@ -246,11 +246,11 @@ class _AllpaymentrequesitionlistsbymodesState
} else if (widget.mode == "apr_lvl2") {
shouldShowButtons =
!isLevel2Finalized &&
[
"Requested",
"Level 1 Approved",
"Level 1 approved",
].contains(status);
[
"Requested",
"Level 1 Approved",
"Level 1 approved",
].contains(status);
} else if (widget.mode == "process") {
shouldShowButtons = [
"Level 2 Approved",
......@@ -338,311 +338,311 @@ class _AllpaymentrequesitionlistsbymodesState
),
backgroundColor: AppColors.scaffold_bg_color,
body:
provider.isLoading && requestLists.isEmpty
? Center(
child: CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
provider.isLoading && requestLists.isEmpty
? Center(
child: CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation<Color>(
AppColors.app_blue,
),
),
)
: requestLists.isNotEmpty
? RefreshIndicator(
onRefresh: () async {
provider.resetPagination();
await provider.paymentRequestionListsAPIFunction(
context,
widget.mode,
"",
"",
);
},
child: Scrollbar(
controller: _scrollController, // attach here
thumbVisibility: false,
child: ListView.builder(
controller: _scrollController,
physics: const AlwaysScrollableScrollPhysics(),
itemCount:
requestLists.length +
(provider.hasMoreData ? 1 : 0),
itemBuilder: (context, index) {
// loader row for pagination
if (index == requestLists.length) {
return provider.isLoadingMore
? const Padding(
padding: EdgeInsets.all(16),
child: Center(
child: CircularProgressIndicator(),
),
),
)
: requestLists.isNotEmpty
? RefreshIndicator(
onRefresh: () async {
provider.resetPagination();
await provider.paymentRequestionListsAPIFunction(
)
: const SizedBox.shrink();
}
// Your swipe logic untouched
final request = requestLists[index];
shouldShowSwipeButtons(request.status);
return InkResponse(
onTap: () async {
HapticFeedback.selectionClick();
var res = await Navigator.push(
context,
widget.mode,
"",
"",
MaterialPageRoute(
builder:
(context) => Paymentrequestionlistdetails(
pageName: widget.pageTitleName,
mode: widget.mode,
paymentRequestId:
requestLists[index].id,
),
settings: RouteSettings(
name: "Paymentrequestionlistdetails",
),
),
);
if (routeSettingName ==
"Paymentrequestionlistdetails") {
print("croos refresh");
provider.paymentRequestionListsAPIFunction(
context,
widget.mode,
"",
"",
);
}
},
child: Scrollbar(
controller: _scrollController, // attach here
thumbVisibility: false,
child: ListView.builder(
controller: _scrollController,
physics: const AlwaysScrollableScrollPhysics(),
itemCount:
requestLists.length +
(provider.hasMoreData ? 1 : 0),
itemBuilder: (context, index) {
// loader row for pagination
if (index == requestLists.length) {
return provider.isLoadingMore
? const Padding(
padding: EdgeInsets.all(16),
child: Center(
child: CircularProgressIndicator(),
),
)
: const SizedBox.shrink();
}
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Slidable(
startActionPane:
shouldShowButtons
? ActionPane(
motion: const ScrollMotion(),
dragDismissible: false,
// Your swipe logic untouched
final request = requestLists[index];
shouldShowSwipeButtons(request.status);
// dismissible: DismissiblePane(onDismissed: () {}),
children: [
if (shouldShowButtons &&
![
"admin",
"self",
].contains(widget.mode)) ...[
SlidableAction(
onPressed: (context) {
_showLevelRejectionSheet(
context,
requestLists[index].id,
);
},
backgroundColor: Color(
0xFFFFE5E5,
),
foregroundColor: Color(
0xFFEF3739,
),
icon: Icons.clear,
label: 'Reject',
),
],
return InkResponse(
onTap: () async {
HapticFeedback.selectionClick();
var res = await Navigator.push(
context,
MaterialPageRoute(
builder:
(context) => Paymentrequestionlistdetails(
pageName: widget.pageTitleName,
mode: widget.mode,
paymentRequestId:
requestLists[index].id,
),
settings: RouteSettings(
name: "Paymentrequestionlistdetails",
if (widget.mode == "process") ...[
SlidableAction(
onPressed: (context) {
detailsProvider
.approveRejectPaymentRequestAPIFunction(
context,
requestLists[index]
.id,
);
detailsProvider.preValues();
_showAddPaymentSheet(
context,
requestLists[index].id,
);
},
backgroundColor: Color(
0xFFFFF8E5,
),
foregroundColor: Color(
0xFFFFB600,
),
icon: Icons.add,
label: 'Add Payment',
),
);
if (routeSettingName ==
"Paymentrequestionlistdetails") {
print("croos refresh");
provider.paymentRequestionListsAPIFunction(
context,
widget.mode,
"",
"",
);
}
},
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Slidable(
startActionPane:
shouldShowButtons
? ActionPane(
motion: const ScrollMotion(),
dragDismissible: false,
],
],
)
: null,
endActionPane:
shouldShowButtons
? ActionPane(
motion: const ScrollMotion(),
key: ValueKey(
requestLists[index].id,
),
dragDismissible: false,
// dismissible: DismissiblePane(onDismissed: () {}),
children: [
if (shouldShowButtons &&
![
"admin",
"self",
].contains(widget.mode)) ...[
SlidableAction(
onPressed: (context) {
_showLevelRejectionSheet(
context,
requestLists[index].id,
);
},
backgroundColor: Color(
0xFFFFE5E5,
),
foregroundColor: Color(
0xFFEF3739,
),
icon: Icons.clear,
label: 'Reject',
),
],
// dismissible: DismissiblePane(
//
// onDismissed: () {},
// closeOnCancel: true,
// resizeDuration: Duration(milliseconds: 300),),
children: [
if ([
"apr_lvl1",
"apr_lvl2",
"self_apr_lvl2",
].contains(widget.mode)) ...[
SlidableAction(
onPressed: (context) {
detailsProvider
.paymentRequesitionDetails(
context,
requestLists[index]
.id,
);
detailsProvider.preValues();
detailsProvider
.approveRejectPaymentRequestAPIFunction(
context,
requestLists[index]
.id,
);
_showLevelApprovalSheet(
context,
requestLists[index].id,
);
},
backgroundColor: Color(
0xFFE9FFE8,
),
foregroundColor: Color(
0xFF4CB443,
),
icon: Icons.check,
label: 'Approve',
),
],
],
)
: null,
if (widget.mode == "process") ...[
SlidableAction(
onPressed: (context) {
detailsProvider
.approveRejectPaymentRequestAPIFunction(
context,
requestLists[index]
.id,
);
detailsProvider.preValues();
_showAddPaymentSheet(
context,
requestLists[index].id,
);
},
backgroundColor: Color(
0xFFFFF8E5,
),
foregroundColor: Color(
0xFFFFB600,
),
icon: Icons.add,
label: 'Add Payment',
),
],
],
)
: null,
endActionPane:
shouldShowButtons
? ActionPane(
motion: const ScrollMotion(),
key: ValueKey(
requestLists[index].id,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: Container(
height: 50,
width: 50,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: getDecorationColor(
requestLists[index].status,
),
shape: BoxShape.circle,
),
child: Center(
child: Text(
getText(
requestLists[index]
.status,
),
dragDismissible: false,
// dismissible: DismissiblePane(
//
// onDismissed: () {},
// closeOnCancel: true,
// resizeDuration: Duration(milliseconds: 300),),
children: [
if ([
"apr_lvl1",
"apr_lvl2",
"self_apr_lvl2",
].contains(widget.mode)) ...[
SlidableAction(
onPressed: (context) {
detailsProvider
.paymentRequesitionDetails(
context,
requestLists[index]
.id,
);
detailsProvider.preValues();
detailsProvider
.approveRejectPaymentRequestAPIFunction(
context,
requestLists[index]
.id,
);
_showLevelApprovalSheet(
context,
requestLists[index].id,
);
},
backgroundColor: Color(
0xFFE9FFE8,
),
foregroundColor: Color(
0xFF4CB443,
),
icon: Icons.check,
label: 'Approve',
),
],
],
)
: null,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: Container(
height: 50,
width: 50,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: getDecorationColor(
requestLists[index].status,
),
shape: BoxShape.circle,
),
child: Center(
child: Text(
getText(
requestLists[index]
.status,
),
style: TextStyle(
color: getTextColor(
requestLists[index]
.status,
),
fontSize: getSize(
requestLists[index]
.status,
),
fontFamily: "JakartaBold",
),
),
),
style: TextStyle(
color: getTextColor(
requestLists[index]
.status,
),
fontSize: getSize(
requestLists[index]
.status,
),
fontFamily: "JakartaBold",
),
SizedBox(width: 10),
Expanded(
flex: 4,
child: SizedBox(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
requestLists[index]
.accountName!,
maxLines: 1,
overflow:
TextOverflow.ellipsis,
style: TextStyle(
fontFamily:
"JakartaRegular",
fontSize: 14,
color:
AppColors
.semi_black,
),
),
Text(
"${requestLists[index].date}",
style: TextStyle(
fontFamily:
"JakartaRegular",
fontSize: 14,
color:
AppColors.app_blue,
),
),
],
),
),
),
),
),
SizedBox(width: 10),
Expanded(
flex: 4,
child: SizedBox(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
requestLists[index]
.accountName!,
maxLines: 1,
overflow:
TextOverflow.ellipsis,
style: TextStyle(
fontFamily:
"JakartaRegular",
fontSize: 14,
color:
AppColors
.semi_black,
),
),
Expanded(
flex: 3,
child: Text(
maxLines: 1,
"₹ ${requestLists[index].amount!}",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.app_blue,
),
Text(
"${requestLists[index].date}",
style: TextStyle(
fontFamily:
"JakartaRegular",
fontSize: 14,
color:
AppColors.app_blue,
),
),
],
),
],
),
),
),
Expanded(
flex: 3,
child: Text(
maxLines: 1,
"₹ ${requestLists[index].amount!}",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.app_blue,
),
),
),
],
),
),
],
),
);
},
),
),
),
),
)
: Emptywidget(context),
);
},
),
),
)
: Emptywidget(context),
);
},
);
......@@ -708,7 +708,7 @@ class _AllpaymentrequesitionlistsbymodesState
provider.requestedAmount,
"Requested Amount",
"Enter Requested Amount",
(p0) {},
(p0) {},
TextInputType.numberWithOptions(),
true,
null,
......@@ -721,7 +721,7 @@ class _AllpaymentrequesitionlistsbymodesState
provider.approvedAmount,
"Approved Amount",
"Enter Approved Amount",
(p0) {
(p0) {
provider.onChangeApprov(p0);
},
TextInputType.numberWithOptions(),
......@@ -739,7 +739,7 @@ class _AllpaymentrequesitionlistsbymodesState
remarks,
"Remarks",
"Enter Remarks",
(p0) {},
(p0) {},
TextInputType.text,
false,
null,
......@@ -761,23 +761,23 @@ class _AllpaymentrequesitionlistsbymodesState
overflow: TextOverflow.ellipsis,
),
items:
provider.paymentsAccounts
.map(
(paymenents) => DropdownMenuItem<
PaymentAccounts
>(
value: paymenents,
child: Text(
paymenents.name ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow:
TextOverflow.ellipsis,
),
),
)
.toList(),
provider.paymentsAccounts
.map(
(paymenents) => DropdownMenuItem<
PaymentAccounts
>(
value: paymenents,
child: Text(
paymenents.name ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow:
TextOverflow.ellipsis,
),
),
)
.toList(),
value: provider.selectedPaymentAccounts,
onChanged: (PaymentAccounts? value) {
if (value != null) {
......@@ -792,7 +792,8 @@ class _AllpaymentrequesitionlistsbymodesState
provider.selectedID = value.id!;
provider.selectedValue = value.name!;
print(
"hfjkshfg${provider.selectedID}",
"hfjkshfg" +
provider.selectedID.toString(),
);
}
}
......@@ -800,35 +801,35 @@ class _AllpaymentrequesitionlistsbymodesState
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.paymentAccountSearchController,
provider
.paymentAccountSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.paymentAccountSearchController,
provider
.paymentAccountSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search account...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
......@@ -843,9 +844,9 @@ class _AllpaymentrequesitionlistsbymodesState
buttonStyleData: ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -856,13 +857,13 @@ class _AllpaymentrequesitionlistsbymodesState
HapticFeedback.selectionClick();
provider
.paymentrequisitionApproveSubmitAPIFunction(
context,
widget.mode,
paymentID,
provider.approvedAmount.text,
remarks.text,
provider.selectedID,
);
context,
widget.mode,
paymentID,
provider.approvedAmount.text,
remarks.text,
provider.selectedID,
);
},
child: Container(
alignment: Alignment.center,
......@@ -898,26 +899,33 @@ class _AllpaymentrequesitionlistsbymodesState
},
);
},
).whenComplete(() {
).then((value) {
// This runs only when the bottom sheet is explicitly popped
print("closing Sheet");
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
var provider = Provider.of<Requestionlistprovider>(
context,
listen: false,
);
final detailsprov = Provider.of<Requesitionlidtdetailsprovider>(
context,
listen: false,
);
detailsprov.resetAll();
provider.paymentRequestionListsAPIFunction(
context,
widget.mode,
"",
"",
);
});
// Use the original context with mounted check
if (context.mounted) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
if (context.mounted) {
var provider = Provider.of<Requestionlistprovider>(
context,
listen: false,
);
final detailsprov = Provider.of<Requesitionlidtdetailsprovider>(
context,
listen: false,
);
detailsprov.resetAll();
provider.paymentRequestionListsAPIFunction(
context,
widget.mode,
"",
"",
);
}
});
}
});
}
......@@ -978,7 +986,7 @@ class _AllpaymentrequesitionlistsbymodesState
context,
provider.requestedAmount,
"Requested Amount",
(p0) {},
(p0) {},
),
textControllerWidget(
......@@ -986,7 +994,7 @@ class _AllpaymentrequesitionlistsbymodesState
remarks,
"Remarks",
"Enter Remarks",
(p0) {},
(p0) {},
TextInputType.text,
false,
null,
......@@ -1000,11 +1008,11 @@ class _AllpaymentrequesitionlistsbymodesState
HapticFeedback.selectionClick();
provider
.paymentrequisitionRejectSubmitAPIFunction(
context,
widget.mode,
paymentID,
remarks.text,
);
context,
widget.mode,
paymentID,
remarks.text,
);
},
child: Container(
alignment: Alignment.center,
......@@ -1098,7 +1106,7 @@ class _AllpaymentrequesitionlistsbymodesState
child: Padding(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(context).viewInsets.bottom,
MediaQuery.of(context).viewInsets.bottom,
),
child: Column(
mainAxisSize: MainAxisSize.min,
......@@ -1108,7 +1116,7 @@ class _AllpaymentrequesitionlistsbymodesState
Expanded(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Align(
......@@ -1125,7 +1133,7 @@ class _AllpaymentrequesitionlistsbymodesState
context,
provider.proposedPaymentAccount,
"Enter Proposed Payment Account",
(p0) {},
(p0) {},
),
TextWidget(
context,
......@@ -1136,7 +1144,7 @@ class _AllpaymentrequesitionlistsbymodesState
children: [
Expanded(
child: DropdownButton2<
PaymentAccounts
PaymentAccounts
>(
isExpanded: true,
hint: Text(
......@@ -1145,41 +1153,41 @@ class _AllpaymentrequesitionlistsbymodesState
fontSize: 14,
),
overflow:
TextOverflow
.ellipsis,
TextOverflow
.ellipsis,
),
items:
provider
.paymentsAccounts
.map(
(
paymenents,
) => DropdownMenuItem<
PaymentAccounts
>(
value:
paymenents,
child: Text(
paymenents
.name ??
'',
style: TextStyle(
fontSize:
14,
),
overflow:
TextOverflow
.ellipsis,
),
),
)
.toList(),
provider
.paymentsAccounts
.map(
(
paymenents,
) => DropdownMenuItem<
PaymentAccounts
>(
value:
paymenents,
child: Text(
paymenents
.name ??
'',
style: TextStyle(
fontSize:
14,
),
overflow:
TextOverflow
.ellipsis,
),
),
)
.toList(),
value:
provider
.selectedPaymentAccounts,
provider
.selectedPaymentAccounts,
onChanged: (
PaymentAccounts? value,
) {
PaymentAccounts? value,
) {
if (value != null &&
provider
.paymentsAccounts
......@@ -1188,9 +1196,9 @@ class _AllpaymentrequesitionlistsbymodesState
provider.selectedPaymentAccounts =
value;
provider.selectedID =
value.id!;
value.id!;
provider.selectedValue =
value.name!;
value.name!;
print(
"Selected Account: ${value.name}, ID: ${value.id}",
);
......@@ -1199,56 +1207,56 @@ class _AllpaymentrequesitionlistsbymodesState
},
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight:
50,
50,
searchController:
provider
.paymentAccountSearchController,
provider
.paymentAccountSearchController,
searchInnerWidget: Padding(
padding:
const EdgeInsets.all(
8,
),
const EdgeInsets.all(
8,
),
child: TextFormField(
controller:
provider
.paymentAccountSearchController,
provider
.paymentAccountSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
EdgeInsets.symmetric(
horizontal:
10,
vertical: 8,
),
EdgeInsets.symmetric(
horizontal:
10,
vertical: 8,
),
hintText:
'Search account...',
'Search account...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(
8,
),
BorderRadius.circular(
8,
),
),
),
),
),
searchMatchFn: (
item,
searchValue,
) {
item,
searchValue,
) {
return item
.value
?.name
?.toLowerCase()
.contains(
searchValue
.toLowerCase(),
) ??
.value
?.name
?.toLowerCase()
.contains(
searchValue
.toLowerCase(),
) ??
false;
},
),
onMenuStateChange: (
isOpen,
) {
isOpen,
) {
if (!isOpen) {
provider
.paymentAccountSearchController
......@@ -1256,16 +1264,16 @@ class _AllpaymentrequesitionlistsbymodesState
}
},
buttonStyleData:
ddtheme
.buttonStyleData,
ddtheme
.buttonStyleData,
iconStyleData:
ddtheme.iconStyleData,
ddtheme.iconStyleData,
menuItemStyleData:
ddtheme
.menuItemStyleData,
ddtheme
.menuItemStyleData,
dropdownStyleData:
ddtheme
.dropdownStyleData,
ddtheme
.dropdownStyleData,
),
),
],
......@@ -1275,29 +1283,29 @@ class _AllpaymentrequesitionlistsbymodesState
context,
provider.approvedAmountReadonly,
"Approved Amount",
(p0) {},
(p0) {},
),
textControllerWidget(
context,
provider.approvedAmount,
"Payment Amount",
"Enter Payment Amount",
(p0) {
(p0) {
if (numberFormat.parse(
provider
.approvedAmountReadonly
.text,
) <
provider
.approvedAmountReadonly
.text,
) <
numberFormat.parse(
provider
.approvedAmount
.text,
)) {
provider.proposedAmountError =
"Amount should not be greater than Approved amount";
"Amount should not be greater than Approved amount";
} else {
provider.proposedAmountError =
"";
"";
}
},
TextInputType.numberWithOptions(),
......@@ -1313,7 +1321,7 @@ class _AllpaymentrequesitionlistsbymodesState
paymentReferenceNumber,
"Enter Payment Reference Number",
"Payment Reference Number",
(p0) {},
(p0) {},
TextInputType.text,
false,
null,
......@@ -1326,7 +1334,7 @@ class _AllpaymentrequesitionlistsbymodesState
remarks,
"Remarks",
"Enter Remarks",
(p0) {},
(p0) {},
TextInputType.text,
false,
null,
......@@ -1345,13 +1353,13 @@ class _AllpaymentrequesitionlistsbymodesState
),
height: 45,
width:
MediaQuery.of(
context,
).size.width,
MediaQuery.of(
context,
).size.width,
decoration: BoxDecoration(
color: Color(0xFFE6F6FF),
borderRadius:
BorderRadius.circular(12),
BorderRadius.circular(12),
border: Border.all(
color: AppColors.app_blue,
width: 0.5,
......@@ -1362,7 +1370,7 @@ class _AllpaymentrequesitionlistsbymodesState
"Add Attachment",
style: TextStyle(
fontFamily:
"JakartaMedium",
"JakartaMedium",
color: AppColors.app_blue,
),
),
......@@ -1373,23 +1381,23 @@ class _AllpaymentrequesitionlistsbymodesState
provider.imagePath != null) ...[
Padding(
padding:
const EdgeInsets.symmetric(
vertical: 4.0,
),
const EdgeInsets.symmetric(
vertical: 4.0,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
MainAxisAlignment
.spaceBetween,
children: [
Text(
"${provider.imagePath}",
style: TextStyle(
color:
AppColors
.semi_black,
AppColors
.semi_black,
fontSize: 11,
fontWeight:
FontWeight.w600,
FontWeight.w600,
),
),
InkResponse(
......@@ -1397,11 +1405,11 @@ class _AllpaymentrequesitionlistsbymodesState
HapticFeedback.selectionClick();
setState(() {
provider.imagePicked =
0;
0;
provider.imagePath =
null;
null;
provider.imageFilePath =
null;
null;
});
},
child: SvgPicture.asset(
......@@ -1418,73 +1426,73 @@ class _AllpaymentrequesitionlistsbymodesState
context,
provider.accountName,
"Enter Account Name",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.branch,
"Enter Branch Name",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.requestingPurpose,
"Enter Requesting Purpose",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.description,
"Enter Description",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.amount,
"Enter Amount",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.paymentMode,
"Enter Payment Mode",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.bankHolderName,
"Bank Account Holder Name",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.bankAccountNumber,
"Bank Account Number",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.bankName,
"Bank Name",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.bankBranchName,
"Bank Branch Name",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.bankIfscCode,
"Bank IFSC Code",
(p0) {},
(p0) {},
),
textControllerReadonlyWidget(
context,
provider.bankUpiID,
"Bank UPI ID",
(p0) {},
(p0) {},
),
],
),
......@@ -1509,15 +1517,15 @@ class _AllpaymentrequesitionlistsbymodesState
HapticFeedback.selectionClick();
provider
.paymentrequisitionProcessSubmitAPIFunction(
context,
widget.mode,
paymentReferenceNumber.text,
provider.approvedAmount.text,
paymentID,
provider.selectedID,
remarks.text,
provider.imagePath,
);
context,
widget.mode,
paymentReferenceNumber.text,
provider.approvedAmount.text,
paymentID,
provider.selectedID,
remarks.text,
provider.imagePath,
);
},
child: Container(
height: 45,
......@@ -1585,9 +1593,9 @@ class _AllpaymentrequesitionlistsbymodesState
return Padding(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(
context,
).viewInsets.bottom, // This handles keyboard
MediaQuery.of(
context,
).viewInsets.bottom, // This handles keyboard
),
child: Container(
margin: EdgeInsets.only(
......
......@@ -10,6 +10,7 @@ import 'package:url_launcher/url_launcher.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:http/http.dart' as http;
import 'dart:typed_data';
import 'package:photo_view/photo_view.dart';
import '../../Utils/app_colors.dart';
......@@ -24,7 +25,7 @@ class Fileviewer extends StatefulWidget {
class _FileviewerState extends State<Fileviewer> {
final Completer<InAppWebViewController> _controller =
Completer<InAppWebViewController>();
Completer<InAppWebViewController>();
var empId = "";
var sessionId = "";
bool isLoading = true;
......@@ -36,6 +37,11 @@ class _FileviewerState extends State<Fileviewer> {
bool pullToRefreshEnabled = true;
final GlobalKey webViewKey = GlobalKey();
// Zoom control variables
PhotoViewController _photoViewController = PhotoViewController();
PhotoViewScaleStateController _scaleStateController = PhotoViewScaleStateController();
String getFileExtension(String fileName) {
print(widget.fileUrl);
return fileName.split('.').last.toLowerCase();
......@@ -51,36 +57,52 @@ class _FileviewerState extends State<Fileviewer> {
}
var Finalurl;
@override
void initState() {
// loadData();
pullToRefreshController =
kIsWeb
? null
: PullToRefreshController(
settings: pullToRefreshSettings,
onRefresh: () async {
if (defaultTargetPlatform == TargetPlatform.android) {
webViewController?.reload();
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
webViewController?.loadUrl(
urlRequest: URLRequest(
url: await webViewController?.getUrl(),
),
);
}
},
);
// print("URL:${widget.url}");
kIsWeb
? null
: PullToRefreshController(
settings: pullToRefreshSettings,
onRefresh: () async {
if (defaultTargetPlatform == TargetPlatform.android) {
webViewController?.reload();
} else if (defaultTargetPlatform == TargetPlatform.iOS) {
webViewController?.loadUrl(
urlRequest: URLRequest(
url: await webViewController?.getUrl(),
),
);
}
},
);
// Initialize photo view controllers
_photoViewController = PhotoViewController();
_scaleStateController = PhotoViewScaleStateController();
super.initState();
}
@override
void dispose() {
_photoViewController.dispose();
_scaleStateController.dispose();
pullToRefreshController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: appbarNew(context, "File Viewer", 0xFFFFFFFF),
body: SafeArea(child: Center(child: fileWidget(context))),
body: SafeArea(
child: Center(
child: fileWidget(context)
),
),
);
}
......@@ -91,28 +113,91 @@ class _FileviewerState extends State<Fileviewer> {
case 'jpeg':
case 'png':
case 'gif':
return CachedNetworkImage(
imageUrl: widget.fileUrl,
placeholder:
(context, url) =>
const Center(child: CircularProgressIndicator()),
errorWidget: (context, url, error) => const Icon(Icons.error),
fit: BoxFit.contain,
);
case 'bmp':
case 'webp':
return _buildImageViewer();
case 'pdf':
return SfPdfViewer.network(widget.fileUrl, key: GlobalKey());
return _buildPdfViewer();
case 'doc':
case 'docx':
case 'xls':
case 'xlsx':
return InAppWebView(
case 'ppt':
case 'pptx':
return _buildDocumentViewer();
default:
return _buildUnsupportedViewer();
}
}
Widget _buildImageViewer() {
return PhotoView(
imageProvider: CachedNetworkImageProvider(widget.fileUrl),
loadingBuilder: (context, event) => Center(
child: Container(
width: 40,
height: 40,
child: CircularProgressIndicator(
value: event == null ? 0 : event.cumulativeBytesLoaded / (event.expectedTotalBytes ?? 1),
),
),
),
errorBuilder: (context, error, stackTrace) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error_outline, color: Colors.red, size: 50),
SizedBox(height: 10),
Text(
'Failed to load image',
style: TextStyle(fontSize: 16, color: Colors.grey),
),
],
),
),
backgroundDecoration: BoxDecoration(color: Colors.white),
minScale: PhotoViewComputedScale.contained * 0.5,
maxScale: PhotoViewComputedScale.covered * 4.0,
initialScale: PhotoViewComputedScale.contained,
basePosition: Alignment.center,
scaleStateController: _scaleStateController,
controller: _photoViewController,
enableRotation: true,
gestureDetectorBehavior: HitTestBehavior.deferToChild,
filterQuality: FilterQuality.high,
);
}
Widget _buildPdfViewer() {
return SfPdfViewer.network(
widget.fileUrl,
key: GlobalKey(),
canShowScrollHead: true,
canShowPaginationDialog: true,
pageLayoutMode: PdfPageLayoutMode.single,
interactionMode: PdfInteractionMode.pan,
enableDoubleTapZooming: true,
enableTextSelection: true,
onZoomLevelChanged: (PdfZoomDetails details) {
// Use the correct property name
//print('Zoom level changed: ${details.zoomLevel}');
},
);
}
Widget _buildDocumentViewer() {
return Stack(
children: [
InAppWebView(
key: webViewKey,
initialUrlRequest: URLRequest(url: WebUri(widget.fileUrl)),
androidOnGeolocationPermissionsShowPrompt: (
InAppWebViewController controller,
String origin,
) async {
InAppWebViewController controller,
String origin,
) async {
return GeolocationPermissionShowPromptResponse(
origin: origin,
allow: true,
......@@ -120,27 +205,41 @@ class _FileviewerState extends State<Fileviewer> {
);
},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
useShouldOverrideUrlLoading: true,
mediaPlaybackRequiresUserGesture: false,
javaScriptEnabled: true,
clearCache: true,
supportZoom: true,
),
android: AndroidInAppWebViewOptions(
useWideViewPort: true,
loadWithOverviewMode: true,
allowContentAccess: true,
geolocationEnabled: true,
allowFileAccess: true,
databaseEnabled: true, // Enables the WebView database
domStorageEnabled: true, // Enables DOM storage
builtInZoomControls: true, // Enables the built-in zoom controls
displayZoomControls: false, // Disables displaying zoom controls
safeBrowsingEnabled: true, // Enables Safe Browsing
databaseEnabled: true,
domStorageEnabled: true,
builtInZoomControls: true,
displayZoomControls: false,
safeBrowsingEnabled: true,
clearSessionCache: true,
supportMultipleWindows: false,
),
ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
allowsAirPlayForMediaPlayback: true,
allowsPictureInPictureMediaPlayback: true,
allowsBackForwardNavigationGestures: true,
allowsLinkPreview: true,
isFraudulentWebsiteWarningEnabled: true,
),
ios: IOSInAppWebViewOptions(allowsInlineMediaPlayback: true),
),
androidOnPermissionRequest: (
InAppWebViewController controller,
String origin,
List<String> resources,
) async {
InAppWebViewController controller,
String origin,
List<String> resources,
) async {
return PermissionRequestResponse(
resources: resources,
action: PermissionRequestResponseAction.GRANT,
......@@ -152,18 +251,29 @@ class _FileviewerState extends State<Fileviewer> {
},
pullToRefreshController: pullToRefreshController,
onLoadStart: (controller, url) {
return setState(() {
setState(() {
isLoading = true;
});
},
onLoadStop: (controller, url) {
pullToRefreshController?.endRefreshing();
return setState(() {
setState(() {
isLoading = false;
});
// Enable zooming in WebView
controller.evaluateJavascript(source: """
var meta = document.createElement('meta');
meta.name = 'viewport';
meta.content = 'width=device-width, initial-scale=1.0, maximum-scale=4.0, user-scalable=yes';
document.getElementsByTagName('head')[0].appendChild(meta);
""");
},
onReceivedError: (controller, request, error) {
pullToRefreshController?.endRefreshing();
setState(() {
isLoading = false;
});
},
onProgressChanged: (controller, progress) {
if (progress == 100) {
......@@ -172,21 +282,101 @@ class _FileviewerState extends State<Fileviewer> {
},
onConsoleMessage: (controller, consoleMessage) {
if (kDebugMode) {
debugPrint("consoleMessage$consoleMessage");
debugPrint("consoleMessage: ${consoleMessage.message}");
}
debugPrint("JavaScript console message: ${consoleMessage.message}");
},
);
default:
return Container();
}
),
// Loading indicator for documents
if (isLoading)
Positioned.fill(
child: Container(
color: Colors.black.withOpacity(0.3),
child: Center(
child: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10,
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(AppColors.app_blue),
),
SizedBox(height: 10),
Text(
'Loading Document...',
style: TextStyle(
fontSize: 14,
color: Colors.grey[700],
),
),
],
),
),
),
),
),
],
);
}
Widget _buildUnsupportedViewer() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.insert_drive_file,
size: 64,
color: Colors.grey[400],
),
SizedBox(height: 16),
Text(
'Unsupported File Format',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Colors.grey[600],
),
),
SizedBox(height: 8),
Text(
'Format: ${getFileExtension(widget.fileName).toUpperCase()}',
style: TextStyle(
fontSize: 14,
color: Colors.grey[500],
),
),
SizedBox(height: 16),
ElevatedButton.icon(
onPressed: () {
_launchUrl(widget.fileUrl);
},
icon: Icon(Icons.open_in_new),
label: Text('Open in External App'),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.app_blue,
foregroundColor: Colors.white,
),
),
],
),
);
}
Future<Uint8List?> _loadPdf(String url) async {
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
print(response.bodyBytes);
return response.bodyBytes;
}
} catch (e) {
......@@ -194,4 +384,4 @@ class _FileviewerState extends State<Fileviewer> {
}
return null;
}
}
}
\ No newline at end of file
......@@ -1360,14 +1360,14 @@ class _PaymentrequestionlistdetailsState
context,
provider.requestedAmount,
"Enter Requested Amount",
(p0) {},
(p0) {},
),
textControllerWidget(
context,
provider.approvedAmount,
"Approved Amount",
"Enter Approved Amount",
(p0) {
(p0) {
provider.onChangeApprov(p0);
},
TextInputType.numberWithOptions(),
......@@ -1383,7 +1383,7 @@ class _PaymentrequestionlistdetailsState
remarks,
"Remarks",
"Enter Remarks",
(p0) {
(p0) {
provider.remarksError = null;
provider.notifyListeners();
},
......@@ -1408,30 +1408,30 @@ class _PaymentrequestionlistdetailsState
overflow: TextOverflow.ellipsis,
),
items:
provider.paymentsAccounts
.map(
(paymenents) => DropdownMenuItem<
PaymentAccounts
>(
value: paymenents,
child: Text(
paymenents.name ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow:
TextOverflow.ellipsis,
),
),
)
.toList(),
provider.paymentsAccounts
.map(
(paymenents) => DropdownMenuItem<
PaymentAccounts
>(
value: paymenents,
child: Text(
paymenents.name ?? '',
style: const TextStyle(
fontSize: 14,
),
overflow:
TextOverflow.ellipsis,
),
),
)
.toList(),
value:
provider.paymentsAccounts.contains(
provider.selectedPaymentAccounts,
)
? provider.selectedPaymentAccounts
: null,
provider.paymentsAccounts.contains(
provider.selectedPaymentAccounts,
)
? provider.selectedPaymentAccounts
: null,
// value: provider.selectedPaymentAccounts,
onChanged: (PaymentAccounts? value) {
if (value != null) {
......@@ -1446,7 +1446,8 @@ class _PaymentrequestionlistdetailsState
provider.selectedID = value.id!;
provider.selectedValue = value.name!;
print(
"hfjkshfg${provider.selectedID}",
"hfjkshfg" +
provider.selectedID.toString(),
);
}
}
......@@ -1454,35 +1455,35 @@ class _PaymentrequestionlistdetailsState
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.paymentAccountSearchController,
provider
.paymentAccountSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.paymentAccountSearchController,
provider
.paymentAccountSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search account...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
......@@ -1497,9 +1498,9 @@ class _PaymentrequestionlistdetailsState
buttonStyleData: ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -1511,15 +1512,21 @@ class _PaymentrequestionlistdetailsState
),
InkWell(
onTap: () {
print("🖱️ === SUBMIT BUTTON TAPPED ===");
print("📋 Mode: ${widget.mode}");
print("📋 Payment ID: $paymentID");
print("📋 Approved Amount: ${provider.approvedAmount.text}");
print("📋 Remarks: ${remarks.text}");
print("📋 Selected Account ID: ${provider.selectedID}");
provider
.paymentrequisitionApproveSubmitAPIFunction(
context,
widget.mode,
paymentID,
provider.approvedAmount.text,
remarks.text,
provider.selectedID,
);
context,
widget.mode,
paymentID,
provider.approvedAmount.text,
remarks.text,
provider.selectedID,
);
},
child: Container(
alignment: Alignment.center,
......
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../Notifiers/HomeScreenNotifier.dart';
import '../../Models/hrmModels/advanceListResponse.dart';
import 'package:intl/intl.dart';
import 'package:flutter_svg/svg.dart';
import '../../Notifiers/hrmProvider/advanceProvider.dart';
import '../../Utils/app_colors.dart';
class AdvanceListScreen extends StatefulWidget {
const AdvanceListScreen({super.key});
@override
State<AdvanceListScreen> createState() => _AdvanceListScreenState();
}
class _AdvanceListScreenState extends State<AdvanceListScreen> {
final ScrollController _scrollController = ScrollController();
@override
void initState() {
super.initState();
final provider = Provider.of<AdvanceListProvider>(context, listen: false);
final homeProvider = Provider.of<HomescreenNotifier>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) {
provider.fetchAdvanceList(context, homeProvider.session, homeProvider.empId);
});
_scrollController.addListener(() {
if (_scrollController.position.pixels >=
_scrollController.position.maxScrollExtent - 200) {
provider.loadMoreAdvanceList(context, homeProvider.session, homeProvider.empId);
}
});
}
@override
Widget build(BuildContext context) {
final double screenWidth = MediaQuery.of(context).size.width;
final double screenHeight = MediaQuery.of(context).size.height;
final bool isSmallScreen = screenWidth < 360;
final bool isLargeScreen = screenWidth > 600;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
title: Row(
children: [
InkResponse(
onTap: () => Navigator.pop(context, true),
child: SvgPicture.asset(
"assets/svg/appbar_back_button.svg",
height: isSmallScreen ? 22 : 25,
),
),
SizedBox(width: isSmallScreen ? 8 : 10),
Text(
"Advance List",
style: TextStyle(
fontSize: isSmallScreen ? 16 : 18,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
],
),
),
backgroundColor: AppColors.scaffold_bg_color,
body: Consumer<AdvanceListProvider>(
builder: (context, provider, _) {
if (provider.isLoading && provider.advanceList.isEmpty) {
return const Center(child: CircularProgressIndicator());
}
if (provider.errorMessage != null) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: isSmallScreen ? 16 : 20),
child: Center(
child: Text(
provider.errorMessage!,
style: TextStyle(
color: Colors.red,
fontSize: isSmallScreen ? 14 : 16,
fontFamily: "Plus Jakarta Sans",
),
textAlign: TextAlign.center,
),
),
);
}
if (provider.advanceList.isEmpty) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: isSmallScreen ? 16 : 20),
child: Center(
child: Text(
"No records found.",
style: TextStyle(
fontSize: isSmallScreen ? 14 : 16,
fontFamily: "Plus Jakarta Sans",
color: AppColors.grey_semi,
),
),
),
);
}
return ListView.builder(
controller: _scrollController,
padding: EdgeInsets.all(isSmallScreen ? 8 : isLargeScreen ? 16 : 12),
itemCount: provider.advanceList.length +
(provider.isLoading ? 1 : 0), // for pagination loader
itemBuilder: (context, index) {
if (index == provider.advanceList.length) {
return Padding(
padding: EdgeInsets.all(isSmallScreen ? 12.0 : 16.0),
child: const Center(child: CircularProgressIndicator()),
);
}
AdvanceList item = provider.advanceList[index];
return _buildAdvanceCard(item, screenWidth);
},
);
},
),
);
}
Widget _buildAdvanceCard(AdvanceList item, double screenWidth) {
final bool isSmallScreen = screenWidth < 360;
final bool isLargeScreen = screenWidth > 600;
final date = item.createdDatetime != null
? _formatDate(item.createdDatetime!)
: "-";
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(isSmallScreen ? 12 : 16)),
margin: EdgeInsets.symmetric(
vertical: isSmallScreen ? 5 : 7,
horizontal: isLargeScreen ? 4 : 0,
),
elevation: 0,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: isSmallScreen ? 12 : isLargeScreen ? 18 : 14,
vertical: isSmallScreen ? 10 : isLargeScreen ? 14 : 12,
),
child: Row(
children: [
// Circular Avatar - Responsive size
CircleAvatar(
backgroundColor: _getAvatarColor(item.type),
radius: isSmallScreen ? 18 : isLargeScreen ? 26 : 22,
child: Text(
(item.narration?.isNotEmpty == true)
? item.type![0].toUpperCase()
: "?",
style: TextStyle(
color: _getAvatarTxtColor(item.type),
fontWeight: FontWeight.bold,
fontSize: isSmallScreen ? 12 : isLargeScreen ? 16 : 14,
),
),
),
SizedBox(width: isSmallScreen ? 12 : isLargeScreen ? 16 : 14),
// Title + Subtitle
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.narration ?? "No Title",
style: TextStyle(
fontFamily: "JakartaRegular",
fontSize: isSmallScreen ? 13 : isLargeScreen ? 16 : 14,
color: AppColors.semi_black,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: isSmallScreen ? 2 : 4),
Text(
date,
style: TextStyle(
fontFamily: "JakartaRegular",
fontSize: isSmallScreen ? 12 : isLargeScreen ? 14 : 13,
color: AppColors.grey_semi,
),
),
],
),
),
SizedBox(width: isSmallScreen ? 8 : isLargeScreen ? 12 : 10),
// Right side amounts
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
if (item.issuedAmount != "₹ 0.00")
Text(
"${item.issuedAmount ?? "0"}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: isSmallScreen ? 13 : isLargeScreen ? 16 : 14,
color: const Color(0xff1487c9),
),
textAlign: TextAlign.end,
),
if (item.deductedAmount != "₹ 0.00")
SizedBox(height: isSmallScreen ? 1 : 2),
if (item.deductedAmount != "₹ 0.00")
Text(
"-${item.deductedAmount ?? "0"}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: isSmallScreen ? 13 : isLargeScreen ? 16 : 14,
color: AppColors.red,
),
textAlign: TextAlign.end,
),
],
),
],
),
),
);
}
String _formatDate(String dateStr) {
try {
final date = DateTime.parse(dateStr);
return DateFormat("dd MMM yy").format(date);
} catch (_) {
return dateStr;
}
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
/// Avatar color generator
Color _getAvatarColor(value) {
var color = AppColors.approved_bg_color;
switch (value) {
case 'issued':
return AppColors.requested_bg_color;
case 'received':
return AppColors.approved_bg_color;
}
return color;
}
Color _getAvatarTxtColor(value) {
var color = AppColors.approved_text_color;
switch (value) {
case 'issued':
return AppColors.requested_text_color;
case 'received':
return AppColors.approved_text_color;
}
return color;
}
String getText(value) {
switch (value) {
case 'issued':
return "I";
case 'received':
return "R";
default:
return "-";
}
}
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
import '../../Notifiers/hrmProvider/CasualLeaveHistoryProvider.dart';
import '../../Utils/app_colors.dart';
class CasualLeaveHistoryScreen extends StatefulWidget {
const CasualLeaveHistoryScreen({super.key});
@override
State<CasualLeaveHistoryScreen> createState() =>
_CasualLeaveHistoryScreenState();
}
class _CasualLeaveHistoryScreenState extends State<CasualLeaveHistoryScreen> {
@override
void initState() {
super.initState();
// Fetch data once when the screen loads
Future.delayed(Duration.zero, () {
final provider =
Provider.of<CasualLeaveHistoryProvider>(context, listen: false);
provider.fetchCasualLeaveHistory(context);
});
}
@override
Widget build(BuildContext context) {
final double screenWidth = MediaQuery.of(context).size.width;
final double screenHeight = MediaQuery.of(context).size.height;
final bool isSmallScreen = screenWidth < 360;
final bool isLargeScreen = screenWidth > 600;
final bool isTablet = screenWidth > 768;
return Scaffold(
backgroundColor: AppColors.scaffold_bg_color,
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.white,
title: Row(
children: [
InkResponse(
onTap: () => Navigator.pop(context, true),
child: SvgPicture.asset(
"assets/svg/appbar_back_button.svg",
height: isSmallScreen ? 22 : isTablet ? 28 : 25,
),
),
SizedBox(width: isSmallScreen ? 8 : isTablet ? 12 : 10),
Text(
"Casual Leave History",
style: TextStyle(
fontSize: isSmallScreen ? 16 : isTablet ? 20 : 18,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w600,
color: Colors.black87,
),
),
],
),
),
body: Consumer<CasualLeaveHistoryProvider>(
builder: (context, provider, _) {
if (provider.isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (provider.errorMessage != null) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: isSmallScreen ? 16 : 20),
child: Center(
child: Text(
provider.errorMessage!,
style: TextStyle(
color: Colors.white,
fontSize: isSmallScreen ? 14 : 16,
fontFamily: "Plus Jakarta Sans",
),
textAlign: TextAlign.center,
),
),
);
}
if (provider.casualLeaveHistoryList.isEmpty) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: isSmallScreen ? 16 : 20),
child: Center(
child: Text(
"No leave history found",
style: TextStyle(
color: Colors.white,
fontSize: isSmallScreen ? 14 : 16,
fontFamily: "Plus Jakarta Sans",
),
),
),
);
}
return ListView.builder(
padding: EdgeInsets.all(isSmallScreen ? 8 : isTablet ? 16 : 12),
itemCount: provider.casualLeaveHistoryList.length,
itemBuilder: (context, index) {
final item = provider.casualLeaveHistoryList[index];
return Padding(
padding: EdgeInsets.symmetric(
vertical: isSmallScreen ? 4 : isTablet ? 8 : 6,
),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(
isSmallScreen ? 12 : isTablet ? 20 : 16,
),
),
padding: EdgeInsets.symmetric(
horizontal: isSmallScreen ? 12 : isTablet ? 18 : 14,
vertical: isSmallScreen ? 8 : isTablet ? 14 : 10,
),
child: Row(
children: [
// --- Avatar Circle ---
Container(
height: isSmallScreen ? 40 : isTablet ? 54 : 46,
width: isSmallScreen ? 40 : isTablet ? 54 : 46,
decoration: BoxDecoration(
color: _getAvatarColor(item.type),
shape: BoxShape.circle,
),
child: Center(
child: Text(
getText(item.type),
style: TextStyle(
fontSize: isSmallScreen ? 13 : isTablet ? 17 : 15,
fontFamily: "Plus Jakarta Sans",
fontWeight: FontWeight.w500,
color: _getAvatarTxtColor(item.type),
),
),
),
),
SizedBox(width: isSmallScreen ? 10 : isTablet ? 16 : 12),
// --- Main Content ---
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.des ?? "No Description",
style: TextStyle(
fontFamily: "JakartaRegular",
fontSize: isSmallScreen ? 13 : isTablet ? 16 : 14,
color: AppColors.semi_black,
height: 1.2,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: isSmallScreen ? 2 : isTablet ? 6 : 4),
Text(
item.year ?? "",
style: TextStyle(
fontFamily: "JakartaRegular",
fontSize: isSmallScreen ? 12 : isTablet ? 14 : 13,
color: AppColors.grey_semi,
),
),
],
),
),
// --- Duration Badge (like "1 Day") ---
Container(
decoration: BoxDecoration(
color: Colors.blue.shade50,
borderRadius: BorderRadius.circular(
isSmallScreen ? 16 : isTablet ? 24 : 20,
),
),
padding: EdgeInsets.symmetric(
horizontal: isSmallScreen ? 12 : isTablet ? 16 : 14,
vertical: isSmallScreen ? 4 : isTablet ? 8 : 6,
),
child: Text(
"${item.cnt ?? '0'} Day${(item.cnt ?? '0') == '1' ? '' : 's'}",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: isSmallScreen ? 12 : isTablet ? 15 : 14,
color: Color(0xff1487c9),
),
),
),
],
),
),
);
},
);
},
),
);
}
/// Avatar color generator
Color _getAvatarColor(value) {
var color = AppColors.approved_bg_color;
switch (value) {
case 'minus':
return AppColors.rejected_bg_color;
case 'plus':
return AppColors.approved_bg_color;
}
return color;
}
Color _getAvatarTxtColor(value) {
var color = AppColors.approved_text_color;
switch (value) {
case 'minus':
return AppColors.rejected_text_color;
case 'plus':
return AppColors.approved_text_color;
}
return color;
}
String getText(value) {
switch (value) {
case 'minus':
return "M";
case 'plus':
return "P";
default:
return "-";
}
}
}
\ No newline at end of file
......@@ -3,6 +3,8 @@ import 'package:flutter_svg/svg.dart';
import 'package:generp/screens/hrm/Attendancelist.dart';
import 'package:provider/provider.dart';
import '../../Utils/app_colors.dart';
import 'AdvanceListScreen.dart';
import 'CasualLeaveHistoryScreen.dart';
import 'LeaveApplicationScreen.dart';
import 'TourExpensesListScreen.dart';
import 'RewardListScreen.dart';
......@@ -24,6 +26,8 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
"Tour Bill List",
"Rewards List",
"Attendance Request List",
"Advance List",
"Casual Leave List"
];
@override
......@@ -215,7 +219,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
crossAxisCount: (constraints.maxWidth /
180)
.floor()
.clamp(2, 4),
.clamp(2, 6),
crossAxisSpacing: 1,
mainAxisSpacing: 2,
childAspectRatio: 1.8,
......@@ -224,7 +228,7 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
final page = pages[index];
return _buildTile(
label: page.pageName ?? "",
label: page.pageName ?? "",//in page number there is 6 items comming from serever it showing only four
subtitle: _getSubtitle(
page.pageName ?? "",
),
......@@ -244,6 +248,11 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
);
},
),
////////////
SizedBox(height: 40,)
],
),
],
......@@ -355,6 +364,10 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
return "";
case "Team Attendance Approval":
return "";
case "Advance List":
return "Advance Payment";
case "Casual Leave List":
return "Track Casual Leave";
default:
return "";
}
......@@ -375,6 +388,10 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
return "assets/svg/hrm/logout_ic.svg";
case "Team Attendance Approval":
return "assets/svg/hrm/check_ic.svg";
case "Advance List":
return "assets/svg/hrm/advance_list_ic.svg";
case "Casual Leave List":
return "assets/svg/hrm/casual_leave_history_ic.svg";
default:
return "assets/svg/hrm/groupIc.svg";
}
......@@ -432,6 +449,24 @@ class _HrmdashboardScreenState extends State<HrmdashboardScreen> {
),
);
break;
case "Advance List":
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AdvanceListScreen(),
),
);
break;
case "Casual Leave List":
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CasualLeaveHistoryScreen(),
),
);
break;
}
}
}
......@@ -65,6 +65,6 @@ export 'package:generp/Notifiers/hrmProvider/tourExpensesDetailsProvider.dart';
export 'package:generp/Notifiers/hrmProvider/rewardListProvider.dart';
export 'package:generp/Notifiers/hrmProvider/LeaveApplicationListProvider.dart';
export 'package:generp/Notifiers/hrmProvider/LeaveApplicationDetailsProvider.dart';
export 'package:generp/Notifiers/hrmProvider/CasualLeaveHistoryProvider.dart';
export 'package:generp/Notifiers/hrmprovider/orgprovider.dart';
......@@ -25,8 +25,14 @@ import 'package:dropdown_search/dropdown_search.dart';
class AddorderScreen extends StatefulWidget {
final pageTitleName;
final mode;
final leadId;
final feedback;
final followupType;
final inTime;
final loc;
const AddorderScreen({super.key, this.pageTitleName, this.mode});
const AddorderScreen({super.key, this.pageTitleName, this.mode, this.leadId, this.feedback, this.followupType, this.inTime, this.loc});
@override
State<AddorderScreen> createState() => _AddorderScreenState();
......@@ -45,30 +51,99 @@ class _AddorderScreenState extends State<AddorderScreen> {
@override
void initState() {
// TODO: implement initState
super.initState();
_connectivity.initialise();
_connectivity.myStream.listen((source) {
setState(() => _source = source);
});
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
var provider = Provider.of<Addorderprovider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) async {
final provider = Provider.of<Addorderprovider>(context, listen: false);
final homeProvider = Provider.of<HomescreenNotifier>(context, listen: false);
if (provider.dateNow == null) {
provider.setDate(DateTime.now());
}
provider.getLocationPermission(context);
provider.getCurrentLocation();
provider.ordersAddOrderAPIViewFunction(context, widget.mode);
provider.ordersAddOrderSelectAccountAPIFunction(
// fetch select account API
await provider.ordersAddOrderSelectAccountAPIFunction(
context,
widget.mode,
provider.selectedAccountID,
'',
);
if (widget.pageTitleName != "Add Order") {
provider.ordersAddOrderAPIViewFunction(
context,
widget.mode,
"",
"",
"",
"",
"",
);
}
if (widget.pageTitleName == "Add Order") {
await provider.fetchAddOrderViewData(
context,
homeProvider.empId,
homeProvider.session,
widget.mode,
widget.leadId,
widget.feedback,
widget.followupType,
widget.inTime,
widget.loc,
);
debugPrint(" fetchAddOrderViewData finished");
debugPrint("Assign data to all fields##################################");
final account = provider.accountDetails;
if (account != null) {
await provider.ordersAddOrderSelectAccountAPIFunction(
context,
widget.mode,
account.id,
"",
);
// provider.getDistrictAPI(context, account.district);
// provider.getSubLocationAPI(context, account.subLocality);
provider.ordersAddOrderAccountDetailsAPIFunction(context, account.id);
provider.selectedAccountID = account.id;
provider.selectedAccountName = account.name;
provider.selectedBillingStateID = account.state;
// Fill text controllers
provider.billingNameController.text = account.name ?? "";
provider.billingAddressController.text = account.address ?? "";
provider.billingPincodeController.text = account.pincode ?? "";
provider.orderReceivedDateController.text = account.date ?? "";
provider.billingStateSearchController.text = account.state!;
provider.selecetdBillingStates = "account.state" as States?;
debugPrint("Auto filled");
provider.accountList.first = account.name as AccountList;
// provider.billingDistrictSearchController.text = district as String;
// provider.selectedBillingDistricts = district as Districts?;
//
// provider.billingSubLocSearchController.text = account.subLocality!;
// provider.selectedBillingSubLocations = account.subLocality as SubLocations?;
provider.dropDownSearchController.text = account.name!;
provider.selectedAccountName = account.name;
provider.notifyListeners();
}
}
});
}
@override
void dispose() {
focusNodes.map((e) => e.dispose());
......@@ -137,21 +212,22 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
return (connection == "Online")
? Platform.isAndroid
? WillPopScope(
onWillPop: () => onBackPressed(context),
child: SafeArea(
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
? WillPopScope(
onWillPop: () => onBackPressed(context),
child: SafeArea(
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
: NoNetwork(context);
}
Widget _scaffold(BuildContext context) {
return Consumer<Addorderprovider>(
builder: (context, provider, child) {
return WillPopScope(
child: SafeArea(
top: false,
......@@ -198,9 +274,9 @@ class _AddorderScreenState extends State<AddorderScreen> {
return CircleAvatar(
radius: 12,
backgroundColor:
stepIndex <= _currentStep
? AppColors.app_blue
: Colors.grey[300],
stepIndex <= _currentStep
? AppColors.app_blue
: Colors.grey[300],
);
},
steps: [
......@@ -225,14 +301,14 @@ class _AddorderScreenState extends State<AddorderScreen> {
showSearchBox: true,
searchFieldProps: TextFieldProps(
controller:
provider.dropDownSearchController,
provider.dropDownSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Account...',
border: OutlineInputBorder(
borderSide: BorderSide(
......@@ -242,14 +318,14 @@ class _AddorderScreenState extends State<AddorderScreen> {
borderRadius: BorderRadius.circular(8),
),
suffixIcon:
provider.isLoading
? const CircularProgressIndicator()
: null,
provider.isLoading
? const CircularProgressIndicator()
: null,
),
onChanged: (value) {
Timer(
const Duration(milliseconds: 500),
() {
() {
print('Search query: $value');
// Items are fetched via the items parameter
},
......@@ -264,21 +340,21 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
itemBuilder:
(context, item, isDisabled, isSelected) =>
Padding(
padding: EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
),
child: SizedBox(
height: 20,
child: Text(
item.text!,
style: const TextStyle(
fontSize: 14,
),
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
),
child: SizedBox(
height: 20,
child: Text(
item.text!,
style: const TextStyle(
fontSize: 14,
),
),
),
),
),
items: (filter, infiniteScrollProps) async {
print('Fetching items for filter: $filter');
......@@ -295,13 +371,14 @@ class _AddorderScreenState extends State<AddorderScreen> {
if (value != null) {
print('Selected account: ${value.text}');
provider.selectedAccountList = (value);
provider.selectedAccountID = value.id!;
provider.selectedAccountName = value.text!;
provider.selectedAccountID = value!.id!;
provider.selectedAccountName = value!.text!;
provider
.ordersAddOrderAccountDetailsAPIFunction(
context,
value.id,
);
context,
value.id,
);
}
},
selectedItem: provider.selectedAccountList,
......@@ -336,7 +413,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
borderRadius: BorderRadius.circular(8),
),
contentPadding:
ddtheme.buttonStyleData.padding,
ddtheme.buttonStyleData.padding,
fillColor: AppColors.text_field_color,
filled: true,
),
......@@ -351,6 +428,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
// },
),
if (provider.selectAccountError != null) ...[
errorWidget(
context,
......@@ -371,39 +449,39 @@ class _AddorderScreenState extends State<AddorderScreen> {
overflow: TextOverflow.ellipsis,
),
items:
provider.employees
.map(
(e) => DropdownMenuItem<
Employees
>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.employees
.map(
(e) => DropdownMenuItem<
Employees
>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedEmployees,
onChanged: (Employees? value) {
if (provider.employees.isNotEmpty) {
provider.selectedEmployees =
value;
provider.selectedEmployeeID =
value!.id!;
value!.id!;
provider.selectedEmployeeName =
value.name!;
value.name!;
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -437,14 +515,14 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
child: TextFormField(
controller:
provider
.orderReceivedDateController,
provider
.orderReceivedDateController,
keyboardType: TextInputType.text,
enabled: false,
maxLines: 1,
readOnly: true,
onChanged:
provider.onChangeOrderDate,
provider.onChangeOrderDate,
decoration: InputDecoration(
hintText: "Enter Date",
hintStyle: TextStyle(
......@@ -497,39 +575,39 @@ class _AddorderScreenState extends State<AddorderScreen> {
overflow: TextOverflow.ellipsis,
),
items:
provider.billingStates
.map(
(e) =>
DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.billingStates
.map(
(e) =>
DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value:
// provider.selecetdBillingStates,
value:
provider.billingStates.isNotEmpty
? provider.selecetdBillingStates !=
null
? provider.billingStates.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingStateID,
orElse:
() =>
provider
.billingStates[0],
)
: null
: null,
provider.billingStates.isNotEmpty
? provider.selecetdBillingStates !=
null
? provider.billingStates.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingStateID,
orElse:
() =>
provider
.billingStates[0],
)
: null
: null,
onChanged: (States? value) {
if (provider
.billingStates
......@@ -541,20 +619,20 @@ class _AddorderScreenState extends State<AddorderScreen> {
provider.billingSubLocations
.clear();
provider.selectedBillingDistrictId =
null;
null;
provider.selectedBillingDistrictValue =
"";
"";
provider.selectedBillingSubLocID =
null;
null;
provider.selectedBillingSubLocValue =
'';
'';
}
provider.selecetdBillingStates =
value;
provider.selectedBillingStateID =
value!.id!;
value!.id!;
provider.selectedBillingStateName =
value.name!;
value.name!;
provider.getDistrictAPI(
context,
provider.selectedBillingStateID,
......@@ -564,35 +642,35 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.billingStateSearchController,
provider
.billingStateSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.billingStateSearchController,
provider
.billingStateSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Sate...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -604,12 +682,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -635,56 +713,56 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.billingDistricts
.map(
(e) => DropdownMenuItem<
Districts
>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.billingDistricts
.map(
(e) => DropdownMenuItem<
Districts
>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value:
// provider
// .selectedBillingDistricts,
value:
provider.billingDistricts.isNotEmpty
? provider.selectedBillingDistricts !=
null
? provider.billingDistricts.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingDistrictId,
orElse: () {
provider.selectedBillingDistricts =
provider
.billingDistricts[0];
provider.selectedBillingDistrictId =
provider
.billingDistricts[0]
.id;
provider.selectedBillingDistrictValue =
provider
.billingDistricts[0]
.district;
provider.getSubLocationAPI(
context,
provider
.selectedBillingDistrictId,
);
return provider
.billingDistricts[0];
},
)
: null
: null,
provider.billingDistricts.isNotEmpty
? provider.selectedBillingDistricts !=
null
? provider.billingDistricts.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingDistrictId,
orElse: () {
provider.selectedBillingDistricts =
provider
.billingDistricts[0];
provider.selectedBillingDistrictId =
provider
.billingDistricts[0]
.id;
provider.selectedBillingDistrictValue =
provider
.billingDistricts[0]
.district;
provider.getSubLocationAPI(
context,
provider
.selectedBillingDistrictId,
);
return provider
.billingDistricts[0];
},
)
: null
: null,
onChanged: (Districts? value) {
if (provider
.billingDistricts
......@@ -695,16 +773,16 @@ class _AddorderScreenState extends State<AddorderScreen> {
provider.billingSubLocations
.clear();
provider.selectedBillingSubLocID =
null;
null;
provider.selectedBillingSubLocValue =
"";
"";
}
provider.selectedBillingDistricts =
value;
provider.selectedBillingDistrictId =
value!.id!;
value!.id!;
provider.selectedBillingDistrictValue =
value.district!;
value.district!;
provider.getSubLocationAPI(
context,
......@@ -716,35 +794,35 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.billingDistrictSearchController,
provider
.billingDistrictSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.billingDistrictSearchController,
provider
.billingDistrictSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search District...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.district
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -756,12 +834,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -786,54 +864,54 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.billingSubLocations
.map(
(e) => DropdownMenuItem<
SubLocations
>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.billingSubLocations
.map(
(e) => DropdownMenuItem<
SubLocations
>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value:
// provider
// .selectedBillingSubLocations,
value:
provider
.billingSubLocations
.isNotEmpty
? provider.selectedBillingSubLocations !=
null
? provider.billingSubLocations.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingSubLocID,
orElse: () {
provider.selectedBillingSubLocations =
provider
.billingSubLocations
.isNotEmpty
? provider.selectedBillingSubLocations !=
null
? provider.billingSubLocations.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingSubLocID,
orElse: () {
provider.selectedBillingSubLocations =
provider
.billingSubLocations[0];
provider.selectedBillingSubLocID =
provider
.billingSubLocations[0]
.id;
provider.selectedBillingSubLocValue =
provider
.billingSubLocations[0]
.subLocality;
.billingSubLocations[0];
provider.selectedBillingSubLocID =
provider
.billingSubLocations[0]
.id;
provider.selectedBillingSubLocValue =
provider
.billingSubLocations[0]
.subLocality;
return provider
.billingSubLocations[0];
},
)
: null
: null,
return provider
.billingSubLocations[0];
},
)
: null
: null,
onChanged: (SubLocations? value) {
if (provider
.billingSubLocations
......@@ -841,44 +919,44 @@ class _AddorderScreenState extends State<AddorderScreen> {
provider.selectedBillingSubLocations =
value;
provider.selectedBillingSubLocID =
value!.id!;
value!.id!;
provider.selectedBillingSubLocValue =
value.subLocality!;
value.subLocality!;
}
},
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.billingSubLocSearchController,
provider
.billingSubLocSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.billingSubLocSearchController,
provider
.billingSubLocSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText:
'Search Sub Location...',
'Search Sub Location...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.subLocality
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -890,12 +968,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -982,41 +1060,41 @@ class _AddorderScreenState extends State<AddorderScreen> {
overflow: TextOverflow.ellipsis,
),
items:
provider.dispatchStates
.map(
(e) =>
DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.dispatchStates
.map(
(e) =>
DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value:
// provider.selecetdDispatchStates,
value:
provider.dispatchStates.isNotEmpty
? provider.selecetdDispatchStates !=
null
? provider.dispatchStates
.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchStateID,
provider.dispatchStates.isNotEmpty
? provider.selecetdDispatchStates !=
null
? provider.dispatchStates
.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchStateID,
orElse:
() =>
provider
.dispatchStates[0],
)
: null
: null,
orElse:
() =>
provider
.dispatchStates[0],
)
: null
: null,
onChanged: (States? value) {
if (provider
.dispatchStates
......@@ -1030,20 +1108,20 @@ class _AddorderScreenState extends State<AddorderScreen> {
.clear();
// provider.selectedDispatchDistricts = null;
provider.selectedDispatchDistrictId =
null;
null;
provider.selectedDispatchDistrictValue =
"";
"";
provider.selectedDispatchSubLocID =
null;
null;
provider.selectedDispatchSubLocValue =
"";
"";
}
provider.selecetdDispatchStates =
value;
provider.selectedDispatchStateID =
value!.id!;
value!.id!;
provider.selectedDispatchStateName =
value.name!;
value.name!;
provider.getDispatchDistrictAPI(
context,
......@@ -1054,35 +1132,35 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.dispatchStateSearchController,
provider
.dispatchStateSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.dispatchStateSearchController,
provider
.dispatchStateSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Sate...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -1094,12 +1172,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -1126,63 +1204,64 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.dispatchDistricts
.map(
(e) => DropdownMenuItem<
Districts
>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.dispatchDistricts
.map(
(e) => DropdownMenuItem<
Districts
>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value:
// provider
// .selectedDispatchDistricts,
value:
provider
.dispatchDistricts
.isNotEmpty
? provider.selectedDispatchDistricts !=
null
? provider.dispatchDistricts.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchDistrictId,
provider
.dispatchDistricts
.isNotEmpty
? provider.selectedDispatchDistricts !=
null
? provider.dispatchDistricts
.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchDistrictId,
orElse: () {
provider.selectedDispatchDistricts =
provider
.dispatchDistricts[0];
provider.selectedDispatchDistrictId =
provider
.dispatchDistricts[0]
.id;
provider.selectedDispatchDistrictValue =
provider
.dispatchDistricts[0]
.district;
provider.getDispatchSubLocationAPI(
context,
provider
.selectedBillingDistrictId,
);
return provider
.dispatchDistricts[0];
},
// orElse:
// () =>
// provider
// .dispatchDistricts[0],
)
: null
: null,
orElse: () {
provider.selectedDispatchDistricts =
provider
.dispatchDistricts[0];
provider.selectedDispatchDistrictId =
provider
.dispatchDistricts[0]
.id;
provider.selectedDispatchDistrictValue =
provider
.dispatchDistricts[0]
.district;
provider.getDispatchSubLocationAPI(
context,
provider
.selectedBillingDistrictId,
);
return provider
.dispatchDistricts[0];
},
// orElse:
// () =>
// provider
// .dispatchDistricts[0],
)
: null
: null,
onChanged: (Districts? value) {
if (provider
.dispatchDistricts
......@@ -1194,16 +1273,16 @@ class _AddorderScreenState extends State<AddorderScreen> {
.clear();
// provider.selectedDispatchSubLocations=null;
provider.selectedDispatchSubLocID =
null;
null;
provider.selectedDispatchSubLocValue =
"";
"";
}
provider.selectedDispatchDistricts =
value;
provider.selectedDispatchDistrictId =
value!.id!;
value!.id!;
provider.selectedDispatchDistrictValue =
value.district!;
value.district!;
provider.getDispatchSubLocationAPI(
context,
......@@ -1215,35 +1294,35 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.dispatchDistrictSearchController,
provider
.dispatchDistrictSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.dispatchDistrictSearchController,
provider
.dispatchDistrictSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search District...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.district
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -1255,12 +1334,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -1283,60 +1362,62 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.dispatchSubLocations
.map(
(e) => DropdownMenuItem<
SubLocations
>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.dispatchSubLocations
.map(
(e) => DropdownMenuItem<
SubLocations
>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value:
// provider
// .selectedDispatchSubLocations,
value:
provider
.dispatchSubLocations
.isNotEmpty
? provider.selectedDispatchSubLocations !=
null
? provider.dispatchSubLocations.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchSubLocID,
provider
.dispatchSubLocations
.isNotEmpty
? provider.selectedDispatchSubLocations !=
null
? provider
.dispatchSubLocations
.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchSubLocID,
orElse: () {
provider.selectedDispatchSubLocations =
provider
.dispatchSubLocations[0];
provider.selectedDispatchSubLocID =
provider
.dispatchSubLocations[0]
.id;
provider.selectedDispatchSubLocValue =
provider
.dispatchSubLocations[0]
.subLocality;
orElse: () {
provider.selectedDispatchSubLocations =
provider
.dispatchSubLocations[0];
provider.selectedDispatchSubLocID =
provider
.dispatchSubLocations[0]
.id;
provider.selectedDispatchSubLocValue =
provider
.dispatchSubLocations[0]
.subLocality;
return provider
.dispatchSubLocations[0];
},
return provider
.dispatchSubLocations[0];
},
// orElse:
// () =>
// provider
// .dispatchSubLocations[0],
)
: null
: null,
// orElse:
// () =>
// provider
// .dispatchSubLocations[0],
)
: null
: null,
onChanged: (SubLocations? value) {
if (provider
.dispatchSubLocations
......@@ -1344,44 +1425,44 @@ class _AddorderScreenState extends State<AddorderScreen> {
provider.selectedDispatchSubLocations =
value;
provider.selectedDispatchSubLocID =
value!.id!;
value!.id!;
provider.selectedDispatchSubLocValue =
value.subLocality!;
value.subLocality!;
}
},
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider
.dispatchSubLocSearchController,
provider
.dispatchSubLocSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.dispatchSubLocSearchController,
provider
.dispatchSubLocSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText:
'Search Sub Location...',
'Search Sub Location...',
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8),
BorderRadius.circular(8),
),
),
),
),
searchMatchFn: (item, searchValue) {
return item.value?.subLocality
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -1393,12 +1474,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -1500,7 +1581,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
MainAxisAlignment.spaceBetween,
children: [
Text(
"${provider.imagePath}",
......@@ -1561,21 +1642,21 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.unloadingScope
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.unloadingScope
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedUnloadingScope,
onChanged: (String? value) {
if (provider
......@@ -1586,12 +1667,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -1616,21 +1697,21 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.freightScope
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.freightScope
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedFreightScope,
onChanged: (String? value) {
if (provider
......@@ -1675,23 +1756,23 @@ class _AddorderScreenState extends State<AddorderScreen> {
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(15),
thickness:
WidgetStateProperty.all<double>(
6,
),
MaterialStateProperty.all<
double
>(6),
thumbVisibility:
WidgetStateProperty.all<bool>(
true,
),
MaterialStateProperty.all<bool>(
true,
),
),
),
menuItemStyleData:
const MenuItemStyleData(
height: 40,
padding: EdgeInsets.only(
left: 14,
right: 14,
),
),
const MenuItemStyleData(
height: 40,
padding: EdgeInsets.only(
left: 14,
right: 14,
),
),
),
),
],
......@@ -1716,21 +1797,21 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.erectionScope
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.erectionScope
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedErectionScope,
onChanged: (String? value) {
if (provider
......@@ -1741,12 +1822,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -1771,21 +1852,21 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.tpcApplicable
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.tpcApplicable
.map(
(e) =>
DropdownMenuItem<String>(
value: e,
child: Text(
e,
style:
const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedTpcStatus,
onChanged: (String? value) {
if (provider
......@@ -1795,12 +1876,12 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
},
buttonStyleData:
ddtheme.buttonStyleData,
ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData:
ddtheme.menuItemStyleData,
ddtheme.menuItemStyleData,
dropdownStyleData:
ddtheme.dropdownStyleData,
ddtheme.dropdownStyleData,
),
),
],
......@@ -1821,14 +1902,14 @@ class _AddorderScreenState extends State<AddorderScreen> {
showSearchBox: true,
searchFieldProps: TextFieldProps(
controller:
provider.dropDownTpcSearchController,
provider.dropDownTpcSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search ...',
border: OutlineInputBorder(
borderSide: BorderSide(
......@@ -1840,14 +1921,14 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
),
suffixIcon:
provider.isLoading
? const CircularProgressIndicator()
: null,
provider.isLoading
? const CircularProgressIndicator()
: null,
),
onChanged: (value) {
Timer(
const Duration(milliseconds: 500),
() {
() {
print('Search query: $value');
// Items are fetched via the items parameter
},
......@@ -1862,25 +1943,25 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
itemBuilder:
(
context,
item,
isDisabled,
isSelected,
context,
item,
isDisabled,
isSelected,
) => Padding(
padding: EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
),
child: SizedBox(
height: 20,
child: Text(
item.text!,
style: const TextStyle(
fontSize: 14,
),
),
padding: EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
),
child: SizedBox(
height: 20,
child: Text(
item.text!,
style: const TextStyle(
fontSize: 14,
),
),
),
),
),
items: (filter, infiniteScrollProps) async {
print('Fetching items for filter: $filter');
......@@ -1896,9 +1977,9 @@ class _AddorderScreenState extends State<AddorderScreen> {
if (value != null) {
print('Selected account: ${value.text}');
provider.selectedTpcAgent = (value);
provider.selectedTpcAgentID = value.id!;
provider.selectedTpcAgentID = value!.id!;
provider.selectedTpcAgentValue =
value.text!;
value!.text!;
}
},
selectedItem: provider.selectedTpcAgent,
......@@ -1933,7 +2014,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
borderRadius: BorderRadius.circular(8),
),
contentPadding:
ddtheme.buttonStyleData.padding,
ddtheme.buttonStyleData.padding,
fillColor: AppColors.text_field_color,
filled: true,
),
......@@ -2130,52 +2211,51 @@ class _AddorderScreenState extends State<AddorderScreen> {
children: [
if (_currentStep == 3) ...[
InkResponse(
onTap:
provider.submitClicked
? null
: () {
print(_currentStep);
if (provider.validateForm4()) {
if (provider.productRows.isNotEmpty) {
provider.submitClicked = true;
print(
"Encoded Products : ${provider.getJsonEncodedProducts()}",
);
provider.getCurrentLocation();
provider
.ordersAddOrderAPISubmitFunction(
context,
widget.mode,
provider.selectedEmployeeID,
provider.selectedAccountID,
provider
.selectedDispatchStateID,
provider
.selectedDispatchDistrictId,
provider
.selectedDispatchSubLocID,
provider.selectedUnloadingScope,
provider.selectedFreightScope,
provider.selectedErectionScope,
provider.selectedTpcStatus,
provider.selectedBillingStateID,
provider
.selectedBillingDistrictId,
provider
.selectedBillingSubLocID,
provider.selectedTpcAgentID,
provider
.getJsonEncodedProducts(),
);
} else {
toast(context, "Add min. 1 product");
}
} else {
provider.submitClicked = false;
}
},
onTap:
provider.submitClicked
? null
: () {
print(_currentStep);
if (provider.validateForm4()) {
if (provider.productRows.isNotEmpty) {
provider.submitClicked = true;
print(
"Encoded Products : ${provider.getJsonEncodedProducts()}",
);
provider.getCurrentLocation();
provider
.ordersAddOrderAPISubmitFunction(
context,
widget.mode,
provider.selectedEmployeeID,
provider.selectedAccountID,
provider.selectedDispatchStateID,
provider
.selectedDispatchDistrictId,
provider
.selectedDispatchSubLocID,
provider.selectedUnloadingScope,
provider.selectedFreightScope,
provider.selectedErectionScope,
provider.selectedTpcStatus,
provider.selectedBillingStateID,
provider
.selectedBillingDistrictId,
provider
.selectedBillingSubLocID,
provider.selectedTpcAgentID,
provider
.getJsonEncodedProducts(),
);
} else {
toast(context, "Add min. 1 product");
}
} else {
provider.submitClicked = false;
}
},
child: Container(
height: 45,
alignment: Alignment.center,
......@@ -2416,14 +2496,14 @@ class _AddorderScreenState extends State<AddorderScreen> {
onChanged: (value) async {
Future.delayed(
Duration(milliseconds: 100),
() async {
() async {
await provider
.ordersAddOrderSelectAccountAPIFunction(
context,
widget.mode,
provider.selectedAccountID,
value,
);
context,
widget.mode,
provider.selectedAccountID,
value,
);
},
);
},
......@@ -2486,25 +2566,27 @@ class _AddorderScreenState extends State<AddorderScreen> {
onTap: () async {
if (provider.accountList.isNotEmpty) {
provider.selectedAccountList =
provider.accountList[index];
provider.accountList[index];
print(
"Selected Complaint Type: ${provider.accountList[index].text}, ID: ${provider.accountList[index].id}",
);
provider.selectedAccountID =
provider.accountList[index].id!;
provider.accountList[index].id!;
provider.selectedAccountName =
provider.accountList[index].text!;
provider.accountList[index].text!;
print(
"hfjkshfg${provider.selectedAccountID}",
"hfjkshfg" +
provider.selectedAccountID
.toString(),
);
provider.dropDownSearchController.text =
provider.accountList[index].text!;
provider.accountList[index].text!;
provider
.ordersAddOrderAccountDetailsAPIFunction(
context,
provider.selectedAccountID,
);
context,
provider.selectedAccountID,
);
}
// provider.ordersAddPaymentSelectOrderAPIFunction(context, provider.selectedAccountID);
provider.accountList = [];
......@@ -2540,26 +2622,26 @@ class _AddorderScreenState extends State<AddorderScreen> {
overflow: TextOverflow.ellipsis,
),
items:
provider.employees
.map(
(e) => DropdownMenuItem<Employees>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.employees
.map(
(e) => DropdownMenuItem<Employees>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedEmployees,
onChanged: (Employees? value) {
if (provider.employees.isNotEmpty) {
provider.selectedEmployees = value;
provider.selectedEmployeeID = value!.id!;
provider.selectedEmployeeName =
value.name!;
value.name!;
}
},
buttonStyleData: ddtheme.buttonStyleData,
......@@ -2597,7 +2679,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
child: TextFormField(
controller:
provider.orderReceivedDateController,
provider.orderReceivedDateController,
keyboardType: TextInputType.text,
enabled: false,
maxLines: 1,
......@@ -2637,7 +2719,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
null,
TextInputAction.done,
),
if (provider.billingNameError != null)
if(provider.billingNameError!=null)
errorWidget(context, provider.billingNameError),
TextWidget(context, "Billing State"),
//dd
......@@ -2653,34 +2735,34 @@ class _AddorderScreenState extends State<AddorderScreen> {
overflow: TextOverflow.ellipsis,
),
items:
provider.billingStates
.map(
(e) => DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.billingStates
.map(
(e) => DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value: provider.selecetdBillingStates,
value:
provider.billingStates.isNotEmpty
? provider.selecetdBillingStates != null
? provider.billingStates.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingStateID,
orElse:
() =>
provider.billingStates[0],
)
: null
: null,
provider.billingStates.isNotEmpty
? provider.selecetdBillingStates != null
? provider.billingStates.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingStateID,
orElse:
() =>
provider.billingStates[0],
)
: null
: null,
onChanged: (States? value) {
if (provider.billingStates.isNotEmpty) {
if (provider.billingDistricts.isNotEmpty) {
......@@ -2688,15 +2770,15 @@ class _AddorderScreenState extends State<AddorderScreen> {
provider.billingSubLocations.clear();
provider.selectedBillingDistrictId = null;
provider.selectedBillingDistrictValue =
"";
"";
provider.selectedBillingSubLocID = null;
provider.selectedBillingSubLocValue = '';
}
provider.selecetdBillingStates = value;
provider.selectedBillingStateID =
value!.id!;
value!.id!;
provider.selectedBillingStateName =
value.name!;
value.name!;
provider.getDistrictAPI(
context,
provider.selectedBillingStateID,
......@@ -2706,19 +2788,19 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider.billingStateSearchController,
provider.billingStateSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider.billingStateSearchController,
provider.billingStateSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Sate...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
......@@ -2730,10 +2812,10 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
searchMatchFn: (item, searchValue) {
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -2752,11 +2834,8 @@ class _AddorderScreenState extends State<AddorderScreen> {
],
),
),
if (provider.selectedBillingStateError != null)
errorWidget(
context,
provider.selectedBillingStateError,
),
if(provider.selectedBillingStateError!=null)
errorWidget(context, provider.selectedBillingStateError),
TextWidget(context, "Billing District"),
//dd
DropdownButtonHideUnderline(
......@@ -2770,36 +2849,36 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.billingDistricts
.map(
(e) => DropdownMenuItem<Districts>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.billingDistricts
.map(
(e) => DropdownMenuItem<Districts>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value: provider.selectedBillingDistricts,
value:
provider.billingDistricts.isNotEmpty
? provider.selectedBillingDistricts !=
null
? provider.billingDistricts.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingDistrictId,
orElse:
() =>
provider
.billingDistricts[0],
)
: null
: null,
provider.billingDistricts.isNotEmpty
? provider.selectedBillingDistricts !=
null
? provider.billingDistricts.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingDistrictId,
orElse:
() =>
provider
.billingDistricts[0],
)
: null
: null,
onChanged: (Districts? value) {
if (provider.billingDistricts.isNotEmpty) {
if (provider
......@@ -2811,9 +2890,9 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
provider.selectedBillingDistricts = value;
provider.selectedBillingDistrictId =
value!.id!;
value!.id!;
provider.selectedBillingDistrictValue =
value.district!;
value.district!;
provider.getSubLocationAPI(
context,
......@@ -2824,20 +2903,20 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider.billingDistrictSearchController,
provider.billingDistrictSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.billingDistrictSearchController,
provider
.billingDistrictSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search District...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
......@@ -2849,10 +2928,10 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
searchMatchFn: (item, searchValue) {
return item.value?.district
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -2871,7 +2950,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
],
),
),
if (provider.selectedBillingDistrictError != null)
if(provider.selectedBillingDistrictError!=null)
errorWidget(
context,
provider.selectedBillingDistrictError,
......@@ -2888,63 +2967,63 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.billingSubLocations
.map(
(e) => DropdownMenuItem<SubLocations>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.billingSubLocations
.map(
(e) => DropdownMenuItem<SubLocations>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value: provider.selectedBillingSubLocations,
value:
provider.billingSubLocations.isNotEmpty
? provider.selectedBillingSubLocations !=
null
? provider.billingSubLocations.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingSubLocID,
orElse:
() =>
provider
.billingSubLocations[0],
)
: null
: null,
provider.billingSubLocations.isNotEmpty
? provider.selectedBillingSubLocations !=
null
? provider.billingSubLocations.firstWhere(
(ord) =>
ord.id ==
provider
.selectedBillingSubLocID,
orElse:
() =>
provider
.billingSubLocations[0],
)
: null
: null,
onChanged: (SubLocations? value) {
if (provider.billingSubLocations.isNotEmpty) {
provider.selectedBillingSubLocations =
value;
provider.selectedBillingSubLocID =
value!.id!;
value!.id!;
provider.selectedBillingSubLocValue =
value.subLocality!;
value.subLocality!;
}
},
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider.billingSubLocSearchController,
provider.billingSubLocSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.billingSubLocSearchController,
provider
.billingSubLocSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Sub Location...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
......@@ -2956,10 +3035,10 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
searchMatchFn: (item, searchValue) {
return item.value?.subLocality
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -2978,11 +3057,8 @@ class _AddorderScreenState extends State<AddorderScreen> {
],
),
),
if (provider.selectedBillingSubLocError != null)
errorWidget(
context,
provider.selectedBillingSubLocError,
),
if(provider.selectedBillingSubLocError!=null)
errorWidget(context, provider.selectedBillingSubLocError),
textControllerWidget(
context,
provider.billingAddressController,
......@@ -2996,7 +3072,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
focusNodes[2],
TextInputAction.next,
),
if (provider.billingAddressError != null)
if(provider.billingAddressError!=null)
errorWidget(context, provider.billingAddressError),
textControllerWidget(
......@@ -3013,7 +3089,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
TextInputAction.done,
6,
),
if (provider.billingPincodeError != null)
if(provider.billingPincodeError!=null)
errorWidget(context, provider.billingPincodeError),
TextWidget(context, "Dispatch State"),
......@@ -3029,36 +3105,36 @@ class _AddorderScreenState extends State<AddorderScreen> {
overflow: TextOverflow.ellipsis,
),
items:
provider.dispatchStates
.map(
(e) => DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.dispatchStates
.map(
(e) => DropdownMenuItem<States>(
value: e,
child: Text(
e.name!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value: provider.selecetdDispatchStates,
value:
provider.dispatchStates.isNotEmpty
? provider.selecetdDispatchStates !=
null
? provider.dispatchStates.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchStateID,
orElse:
() =>
provider
.dispatchStates[0],
)
: null
: null,
provider.dispatchStates.isNotEmpty
? provider.selecetdDispatchStates !=
null
? provider.dispatchStates.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchStateID,
orElse:
() =>
provider
.dispatchStates[0],
)
: null
: null,
onChanged: (States? value) {
if (provider.dispatchStates.isNotEmpty) {
if (provider.dispatchDistricts.isNotEmpty) {
......@@ -3066,17 +3142,17 @@ class _AddorderScreenState extends State<AddorderScreen> {
provider.billingSubLocations.clear();
// provider.selectedDispatchDistricts = null;
provider.selectedDispatchDistrictId =
null;
null;
provider.selectedDispatchDistrictValue =
"";
"";
provider.selectedDispatchSubLocID = null;
provider.selectedDispatchSubLocValue = "";
}
provider.selecetdDispatchStates = value;
provider.selectedDispatchStateID =
value!.id!;
value!.id!;
provider.selectedDispatchStateName =
value.name!;
value.name!;
provider.getDispatchDistrictAPI(
context,
......@@ -3087,20 +3163,20 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider.dispatchStateSearchController,
provider.dispatchStateSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.dispatchStateSearchController,
provider
.dispatchStateSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Sate...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
......@@ -3112,10 +3188,10 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
searchMatchFn: (item, searchValue) {
return item.value?.name
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -3149,36 +3225,36 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.dispatchDistricts
.map(
(e) => DropdownMenuItem<Districts>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.dispatchDistricts
.map(
(e) => DropdownMenuItem<Districts>(
value: e,
child: Text(
e.district!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value: provider.selectedDispatchDistricts,
value:
provider.dispatchDistricts.isNotEmpty
? provider.selectedDispatchDistricts !=
null
? provider.dispatchDistricts.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchDistrictId,
orElse:
() =>
provider
.dispatchDistricts[0],
)
: null
: null,
provider.dispatchDistricts.isNotEmpty
? provider.selectedDispatchDistricts !=
null
? provider.dispatchDistricts.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchDistrictId,
orElse:
() =>
provider
.dispatchDistricts[0],
)
: null
: null,
onChanged: (Districts? value) {
if (provider.dispatchDistricts.isNotEmpty) {
if (provider
......@@ -3191,9 +3267,9 @@ class _AddorderScreenState extends State<AddorderScreen> {
}
provider.selectedDispatchDistricts = value;
provider.selectedDispatchDistrictId =
value!.id!;
value!.id!;
provider.selectedDispatchDistrictValue =
value.district!;
value.district!;
provider.getDispatchSubLocationAPI(
context,
......@@ -3204,20 +3280,20 @@ class _AddorderScreenState extends State<AddorderScreen> {
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider.dispatchDistrictSearchController,
provider.dispatchDistrictSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.dispatchDistrictSearchController,
provider
.dispatchDistrictSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search District...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
......@@ -3229,10 +3305,10 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
searchMatchFn: (item, searchValue) {
return item.value?.district
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -3266,37 +3342,37 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.dispatchSubLocations
.map(
(e) => DropdownMenuItem<SubLocations>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.dispatchSubLocations
.map(
(e) => DropdownMenuItem<SubLocations>(
value: e,
child: Text(
e.subLocality!,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
// value:
// provider.selectedDispatchSubLocations,
value:
provider.dispatchSubLocations.isNotEmpty
? provider.selectedDispatchSubLocations !=
null
? provider.dispatchSubLocations.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchSubLocID,
orElse:
() =>
provider
.dispatchSubLocations[0],
)
: null
: null,
provider.dispatchSubLocations.isNotEmpty
? provider.selectedDispatchSubLocations !=
null
? provider.dispatchSubLocations.firstWhere(
(ord) =>
ord.id ==
provider
.selectedDispatchSubLocID,
orElse:
() =>
provider
.dispatchSubLocations[0],
)
: null
: null,
onChanged: (SubLocations? value) {
if (provider
.dispatchSubLocations
......@@ -3304,28 +3380,28 @@ class _AddorderScreenState extends State<AddorderScreen> {
provider.selectedDispatchSubLocations =
value;
provider.selectedDispatchSubLocID =
value!.id!;
value!.id!;
provider.selectedDispatchSubLocValue =
value.subLocality!;
value.subLocality!;
}
},
dropdownSearchData: DropdownSearchData(
searchInnerWidgetHeight: 50,
searchController:
provider.dispatchSubLocSearchController,
provider.dispatchSubLocSearchController,
searchInnerWidget: Padding(
padding: const EdgeInsets.all(8),
child: TextFormField(
controller:
provider
.dispatchSubLocSearchController,
provider
.dispatchSubLocSearchController,
decoration: InputDecoration(
isDense: true,
contentPadding:
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
const EdgeInsets.symmetric(
horizontal: 10,
vertical: 8,
),
hintText: 'Search Sub Location...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(
......@@ -3337,10 +3413,10 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
searchMatchFn: (item, searchValue) {
return item.value?.subLocality
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
?.toLowerCase()
.contains(
searchValue.toLowerCase(),
) ??
false;
},
),
......@@ -3481,19 +3557,19 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.unloadingScope
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.unloadingScope
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedUnloadingScope,
onChanged: (String? value) {
if (provider.unloadingScope.isNotEmpty) {
......@@ -3521,19 +3597,19 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.freightScope
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.freightScope
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedFreightScope,
onChanged: (String? value) {
if (provider.freightScope.isNotEmpty) {
......@@ -3570,11 +3646,10 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(15),
thickness: WidgetStateProperty.all<double>(
6,
),
thickness:
MaterialStateProperty.all<double>(6),
thumbVisibility:
WidgetStateProperty.all<bool>(true),
MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: const MenuItemStyleData(
......@@ -3598,19 +3673,19 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.erectionScope
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.erectionScope
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedErectionScope,
onChanged: (String? value) {
if (provider.erectionScope.isNotEmpty) {
......@@ -3638,19 +3713,19 @@ class _AddorderScreenState extends State<AddorderScreen> {
style: const TextStyle(fontSize: 14),
),
items:
provider.tpcApplicable
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
provider.tpcApplicable
.map(
(e) => DropdownMenuItem<String>(
value: e,
child: Text(
e,
style: const TextStyle(
fontSize: 14,
),
),
),
)
.toList(),
value: provider.selectedTpcStatus,
onChanged: (String? value) {
if (provider.tpcApplicable.isNotEmpty) {
......@@ -3687,13 +3762,13 @@ class _AddorderScreenState extends State<AddorderScreen> {
onChanged: (value) async {
Future.delayed(
Duration(milliseconds: 100),
() async {
() async {
await provider
.ordersAddOrderTPCAgentFunction(
context,
widget.mode,
value,
);
context,
widget.mode,
value,
);
},
);
},
......@@ -3754,22 +3829,24 @@ class _AddorderScreenState extends State<AddorderScreen> {
onTap: () async {
if (provider.tpcAgent.isNotEmpty) {
provider.selectedTpcAgent =
provider.tpcAgent[index];
provider.tpcAgent[index];
print(
"Selected Complaint Type: ${provider.tpcAgent[index].text}, ID: ${provider.tpcAgent[index].id}",
);
provider.selectedTpcAgentID =
provider.tpcAgent[index].id!;
provider.tpcAgent[index].id!;
provider.selectedTpcAgentValue =
provider.tpcAgent[index].text!;
provider.tpcAgent[index].text!;
print(
"hfjkshfg${provider.selectedTpcAgentID}",
"hfjkshfg" +
provider.selectedTpcAgentID
.toString(),
);
provider
.dropDownTpcSearchController
.text =
provider.tpcAgent[index].text!;
.dropDownTpcSearchController
.text =
provider.tpcAgent[index].text!;
}
// provider.ordersAddPaymentSelectOrderAPIFunction(context, provider.selectedAccountID);
// provider.tpcAgent = [];
......@@ -3815,37 +3892,37 @@ class _AddorderScreenState extends State<AddorderScreen> {
),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
FloatingActionButtonLocation.centerFloat,
bottomNavigationBar: InkResponse(
onTap:
provider.submitClicked
? null
: () {
provider.submitClicked = true;
// var order_prod_data = provider.getFormData();
provider.submitClicked
? null
: () {
provider.submitClicked = true;
// var order_prod_data = provider.getFormData();
///[{"product_id":"1","qty":"1","price":"500","cgst_p":"9","sgst_p":"9","igst_p":"0","total_price":"500"},
///{"product_id":"2","qty":"1","price":"1000","cgst_p":"9","sgst_p":"9","igst_p":"0","total_price":"1000"}]
provider.getCurrentLocation();
provider.ordersAddOrderAPISubmitFunction(
context,
widget.mode,
provider.selectedEmployeeID,
provider.selectedAccountID,
provider.selectedDispatchStateID,
provider.selectedDispatchDistrictId,
provider.selectedDispatchSubLocID,
provider.selectedUnloadingScope,
provider.selectedFreightScope,
provider.selectedErectionScope,
provider.selectedTpcStatus,
provider.selectedBillingStateID,
provider.selectedBillingDistrictId,
provider.selectedBillingSubLocID,
provider.selectedTpcAgentID,
{},
);
},
///[{"product_id":"1","qty":"1","price":"500","cgst_p":"9","sgst_p":"9","igst_p":"0","total_price":"500"},
///{"product_id":"2","qty":"1","price":"1000","cgst_p":"9","sgst_p":"9","igst_p":"0","total_price":"1000"}]
provider.getCurrentLocation();
provider.ordersAddOrderAPISubmitFunction(
context,
widget.mode,
provider.selectedEmployeeID,
provider.selectedAccountID,
provider.selectedDispatchStateID,
provider.selectedDispatchDistrictId,
provider.selectedDispatchSubLocID,
provider.selectedUnloadingScope,
provider.selectedFreightScope,
provider.selectedErectionScope,
provider.selectedTpcStatus,
provider.selectedBillingStateID,
provider.selectedBillingDistrictId,
provider.selectedBillingSubLocID,
provider.selectedTpcAgentID,
{},
);
},
child: Container(
height: 45,
alignment: Alignment.center,
......@@ -3856,20 +3933,20 @@ class _AddorderScreenState extends State<AddorderScreen> {
borderRadius: BorderRadius.circular(15),
),
child:
provider.submitClicked
? CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation<Color>(
AppColors.white,
),
)
: Text(
"Submit",
style: TextStyle(
fontSize: 15,
fontFamily: "JakartaMedium",
color: Colors.white,
),
),
provider.submitClicked
? CircularProgressIndicator.adaptive(
valueColor: AlwaysStoppedAnimation<Color>(
AppColors.white,
),
)
: Text(
"Submit",
style: TextStyle(
fontSize: 15,
fontFamily: "JakartaMedium",
color: Colors.white,
),
),
),
),
),
......@@ -3901,9 +3978,9 @@ class _AddorderScreenState extends State<AddorderScreen> {
return Padding(
padding: EdgeInsets.only(
bottom:
MediaQuery.of(
context,
).viewInsets.bottom, // This handles keyboard
MediaQuery.of(
context,
).viewInsets.bottom, // This handles keyboard
),
child: Container(
margin: EdgeInsets.only(
......@@ -3935,7 +4012,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
Navigator.of(context).pop(false);
provider.imgFromGallery(context);
},
child: SizedBox(
child: Container(
height: 35,
child: Text("Select photo from gallery"),
),
......@@ -3946,7 +4023,7 @@ class _AddorderScreenState extends State<AddorderScreen> {
Navigator.of(context).pop(false);
provider.imgFromCamera(context);
},
child: SizedBox(
child: Container(
height: 35,
child: Text("Capture photo from camera"),
),
......@@ -3997,7 +4074,7 @@ class OrderForm extends StatelessWidget {
),
);
if (res != null) {
print("result $res");
print("result ${res}");
}
},
child: Container(
......@@ -4035,10 +4112,10 @@ class OrderForm extends StatelessWidget {
provider.saleProducts
.firstWhere(
(p) => p.id == product['product_id'],
orElse:
() =>
SaleProducts(id: '', prodName: 'Unknown'),
)
orElse:
() =>
SaleProducts(id: '', prodName: 'Unknown'),
)
.prodName;
final prodPrice = product['price'] ?? '-';
final prodQty = product['qty'] ?? '-';
......@@ -4054,14 +4131,14 @@ class OrderForm extends StatelessWidget {
MaterialPageRoute(
builder:
(context) => Addorderaddproduct(
type: "Edit",
editIndex: index,
),
type: "Edit",
editIndex: index,
),
settings: RouteSettings(name: 'Addorderaddproduct'),
),
);
if (res != null) {
print("result $res");
print("result ${res}");
}
},
child: Container(
......@@ -4069,7 +4146,7 @@ class OrderForm extends StatelessWidget {
margin: EdgeInsets.only(
left: index == 0 ? 10 : 5,
right:
index == provider.productRows.length - 1 ? 10 : 5,
index == provider.productRows.length - 1 ? 10 : 5,
bottom: 5,
),
padding: EdgeInsets.symmetric(
......@@ -4097,7 +4174,7 @@ class OrderForm extends StatelessWidget {
flex: 6,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
......
......@@ -25,7 +25,9 @@ import 'package:generp/Models/crmModels/crmProspectDetailsAddLeadsResponse.dart'
import 'package:generp/Models/crmModels/crmProspectDetailsResponse.dart';
import 'package:generp/Models/financeModels/addDirectPaymentResponse.dart';
import 'package:generp/Models/financeModels/paymentRequisitionPaymentsListResponse.dart';
import 'package:generp/Models/hrmModels/advanceListResponse.dart';
import 'package:generp/Models/hrmModels/attendanceRequestListResponse.dart';
import 'package:generp/Models/hrmModels/casualLeaveHistoryResponse.dart';
import 'package:generp/Models/hrmModels/jobDescriptionResponse.dart';
import 'package:generp/Models/hrmModels/leaveApplicationDetailsResponse.dart';
import 'package:generp/Models/hrmModels/leaveApplicationLIstResponse.dart';
......@@ -2368,19 +2370,41 @@ class ApiCalling {
}
static Future<AddOrderViewResponse?> addOrderViewAPI(
empId,
session,
mode,
empId,
session,
mode,
leadId,
feedback,
followupType,
inTime,
loc
) async {
try {
Map<String, String> data = {
'emp_id': (empId).toString(),
'session_id': (session).toString(),
'mode': (mode).toString(),
'lead_id': (leadId).toString(),
'feedback': (feedback).toString(),
'followup_type': (followupType).toString(),
'in_time': (inTime).toString(),
'loc': (loc).toString(),
};
debugPrint("===========================Input to api ");
debugPrint("Lead Id: ${leadId}");
debugPrint("Follow Type: ${followupType}");
debugPrint("In Time: ${inTime}");
debugPrint("Location: ${loc}");
debugPrint("Mode: ${mode}");
debugPrint("feedback: ${feedback}");
debugPrint("=================End of INput=================");
final res = await post(data, ordersAddOrderViewUrl, {});
if (res != null) {
debugPrint(res.body);
// debugPrint("Response start ================== ${AddOrderViewResponse.fromJson(jsonDecode(res.body)).accountDetails?.name}");
return AddOrderViewResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
......@@ -3604,6 +3628,7 @@ class ApiCalling {
'lead_status': leadStatus.toString(),
'products': products.toString(),
};
debugPrint("✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ Product deteails ${products}");
final res = await post(data, crmNewProspectLeadSubmitUrl, {});
if (res != null) {
print(data);
......@@ -3738,6 +3763,21 @@ class ApiCalling {
alphabet,
pageNumber,
) async {
debugPrint('crmLeadListFilterSubmitAPI Input data:');
debugPrint('empId: $empId');
debugPrint('session: $session');
debugPrint('mode: $mode');
debugPrint('status: $status');
debugPrint('openStatus: $openStatus');
debugPrint('mob: $mob');
debugPrint('com: $com');
debugPrint('source: $source');
debugPrint('reference: $reference');
debugPrint('team: $team');
debugPrint('segment: $segment');
debugPrint('alphabet: $alphabet');
debugPrint('pageNumber: $pageNumber');
debugPrint('End of input data');
try {
Map<String, String> data = {
'emp_id': (empId).toString(),
......@@ -3936,8 +3976,10 @@ class ApiCalling {
productId,
qty,
amount,
remark,
) async {
try {
debugPrint("💡💡💡💡💡💡💡💡💡AddEditProducts: ${remark}");
Map<String, String> data = {
'emp_id': (empId).toString(),
'session_id': (session).toString(),
......@@ -3947,7 +3989,9 @@ class ApiCalling {
'product_id': (productId).toString(),
'qty': (qty).toString(),
'amount': (amount).toString(),
'remarks': (remark).toString(),
};
final res = await post(data, crmLeadDetailsAddEditProductsUrl, {});
if (res != null) {
print("AddEditProducts $data");
......@@ -4591,8 +4635,10 @@ class ApiCalling {
quantity,
amount,
leadStatus,
remarks,
) async {
try {
debugPrint("💡💡💡💡💡💡 remarks $remarks");
Map<String, String> data = {
'emp_id': (empId).toString(),
'session_id': (session).toString(),
......@@ -4601,6 +4647,7 @@ class ApiCalling {
'quantity': quantity.toString(),
'amount': amount.toString(),
'lead_status': leadStatus.toString(),
'remarks' : remarks.toString(),
};
final res = await post(data, crmProspectDetailsAddLeadUrl, {});
if (res != null) {
......@@ -5445,6 +5492,31 @@ class ApiCalling {
return null;
}
}
/// CasualLeaveHistory api
static Future<CasualLeaveHistoryResponse?> casualLeaveHistoryAPI(
session,
empId,
) async {
debugPrint("🔥🔥🔥🔥🔥🔥🔥Response");
try {
Map<String, String> data = {
'session_id': (session).toString(),
'emp_id': (empId).toString(),
};
final res = await post(data, CasuaLeaveHistoryUrl, {});
if (res != null) {
print(data);
debugPrint(res.body);
return CasualLeaveHistoryResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint('hello bev=bug $e ');
return null;
}
}
//add leave request
static Future<CommonResponse?> leaveRequestAddAPI(
......@@ -5515,6 +5587,34 @@ class ApiCalling {
}
}
/// AdvanceListApi
static Future<AdvanceListResponse?> advanceListAPI(
session,
empId,
pageNumber
) async {
debugPrint("🔥🔥🔥🔥🔥🔥🔥Response");
try {
Map<String, String> data = {
'session_id': (session).toString(),
'emp_id': (empId).toString(),
'page_number': (pageNumber).toString(), // FIX: Use pageNumber parameter, not empId
};
final res = await post(data, AdvanceListUrl, {});
if (res != null) {
print("Request Data: $data");
debugPrint("🔥🔥🔥🔥🔥🔥🔥 Response: ${res.body}");
return AdvanceListResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint('API Error: $e');
return null;
}
}
// static Future<CommonResponse?> TpcIssueListApprovalAPI(
// empId,
// session,
......
......@@ -181,9 +181,9 @@ const crmDashboardQuotationsUrl = "${baseUrl_test}crm_dashboard_quotations_list"
const ogcharturl = "${baseUrl_test}organisation_structures";
const JobDesciptionUrl ="${baseUrl_test}job_description";
///HRM
//Attendance
const HrmAccessiblePagesUrl ="${baseUrl_test}hrm_accessible_pages";
const AttendanceRequestListUrl ="${baseUrl_test}attendance_request_list";
const AttendanceRequestDetailsUrl ="${baseUrl_test}attendance_request_details";
......@@ -203,9 +203,9 @@ const LeaveApplicationDetailsUrl ="${baseUrl_test}leave_request_details";
const LeaveRequestAdditionUrl ="${baseUrl_test}add_leave_request";
const LeaveRequestRejectAprroveUrl ="${baseUrl_test}leaves_approve_reject";
const CasuaLeaveHistoryUrl ="${baseUrl_test}casual_leave_history";
const AdvanceListUrl ="${baseUrl_test}advance_list";
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment