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

Correction and changes

parent a5ccb211
...@@ -338,6 +338,7 @@ class _PaymentdetailspaymentrequisitionState ...@@ -338,6 +338,7 @@ class _PaymentdetailspaymentrequisitionState
fileUrl: fileUrl:
paymentDet paymentDet
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: true,
), ),
), ),
); );
...@@ -604,6 +605,7 @@ class _PaymentdetailspaymentrequisitionState ...@@ -604,6 +605,7 @@ class _PaymentdetailspaymentrequisitionState
fileUrl: fileUrl:
paymentDet paymentDet
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: true,
), ),
), ),
); );
......
...@@ -452,6 +452,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> { ...@@ -452,6 +452,7 @@ class _PaymentreceiptdetailsState extends State<Paymentreceiptdetails> {
fileUrl: fileUrl:
paymentDet paymentDet
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: true,
), ),
), ),
); );
......
import 'package:dotted_line/dotted_line.dart'; import 'package:dotted_line/dotted_line.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:generp/Utils/custom_snackbar.dart';
import 'package:geocoding/geocoding.dart'; import 'package:geocoding/geocoding.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
...@@ -246,12 +247,14 @@ class _AttendanceRequestDetailScreenState ...@@ -246,12 +247,14 @@ class _AttendanceRequestDetailScreenState
"Check In/Out Details", "Check In/Out Details",
scaleFactor, scaleFactor,
), ),
if (details.type == "Check In" || details.type == "Check In/Out")
_buildDate_TimeTile( _buildDate_TimeTile(
"Check In Date & Time", "Check In Date & Time",
details.date, details.date,
details.checkInTime, details.checkInTime,
scaleFactor, scaleFactor,
), ),
if (details.type == "Check Out" || details.type == "Check In/Out")
_buildDate_TimeTile( _buildDate_TimeTile(
"Check Out Date & Time", "Check Out Date & Time",
details.date, details.date,
...@@ -259,22 +262,28 @@ class _AttendanceRequestDetailScreenState ...@@ -259,22 +262,28 @@ class _AttendanceRequestDetailScreenState
scaleFactor, scaleFactor,
), ),
if (details.type == "Check In" || details.type == "Check In/Out")
_buildDetailTile( _buildDetailTile(
"Original Check In", "Original Check In",
checkInTime, checkInTime,
scaleFactor, scaleFactor,
), ),
if (details.type == "Check Out" || details.type == "Check In/Out")
_buildDetailTile( _buildDetailTile(
"Original Check Out", "Original Check Out",
"--", "--",
scaleFactor, scaleFactor,
), ),
if (details.type == "Check In" || details.type == "Check In/Out")
_buildDetailTile( _buildDetailTile(
"Original Check In Location", "Original Check In Location",
details.checkInLocation, details.checkInLocation,
scaleFactor, scaleFactor,
), ),
if (details.type == "Check Out" || details.type == "Check In/Out")
_buildDetailTile( _buildDetailTile(
"Original Check Out Location", "Original Check Out Location",
details.checkOutLocation, details.checkOutLocation,
...@@ -687,15 +696,11 @@ class _AttendanceRequestDetailScreenState ...@@ -687,15 +696,11 @@ class _AttendanceRequestDetailScreenState
await onSubmit(remark); await onSubmit(remark);
// SnackBar here // SnackBar here
Navigator.pop(context); Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar( CustomSnackBar.showSuccess(
SnackBar( context: context,
content: Text( message: "Request submitted successfully"
"Request submitted successfully",
),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
),
); );
} }
}, },
child: Container( child: Container(
...@@ -967,6 +972,7 @@ class _AttendanceRequestDetailScreenState ...@@ -967,6 +972,7 @@ class _AttendanceRequestDetailScreenState
(context) => Fileviewer( (context) => Fileviewer(
fileName: filePath ?? "", fileName: filePath ?? "",
fileUrl: filePath ?? "", fileUrl: filePath ?? "",
downloadEnable: false,
), ),
), ),
); );
......
...@@ -242,6 +242,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen> { ...@@ -242,6 +242,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen> {
(context) => Fileviewer( (context) => Fileviewer(
fileName: t.imageDirFilePath ?? "", fileName: t.imageDirFilePath ?? "",
fileUrl: t.imageDirFilePath ?? "", fileUrl: t.imageDirFilePath ?? "",
downloadEnable: false,
), ),
), ),
); );
...@@ -301,6 +302,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen> { ...@@ -301,6 +302,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen> {
(context) => Fileviewer( (context) => Fileviewer(
fileName: h.imageDirFilePath ?? "", fileName: h.imageDirFilePath ?? "",
fileUrl: h.imageDirFilePath ?? "", fileUrl: h.imageDirFilePath ?? "",
downloadEnable: false,
), ),
), ),
); );
...@@ -359,6 +361,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen> { ...@@ -359,6 +361,7 @@ class _TourExpensesDetailsScreenState extends State<TourExpensesDetailsScreen> {
(context) => Fileviewer( (context) => Fileviewer(
fileName: o.imageDirFilePath ?? "", fileName: o.imageDirFilePath ?? "",
fileUrl: o.imageDirFilePath ?? "", fileUrl: o.imageDirFilePath ?? "",
downloadEnable: false,
), ),
), ),
); );
......
...@@ -986,6 +986,7 @@ class _GeneratorPartDetailsScreenState ...@@ -986,6 +986,7 @@ class _GeneratorPartDetailsScreenState
provider provider
.partData .partData
.imageDirFilePath!, .imageDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -328,6 +328,7 @@ class _AllpaymentrequesitionlistsbymodesoldState ...@@ -328,6 +328,7 @@ class _AllpaymentrequesitionlistsbymodesoldState
fileUrl: fileUrl:
requestLists[index] requestLists[index]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -316,6 +316,7 @@ class _PaymentlistpaymentrequisitionOldState ...@@ -316,6 +316,7 @@ class _PaymentlistpaymentrequisitionOldState
fileUrl: fileUrl:
requestLists[index] requestLists[index]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -271,6 +271,7 @@ class _PaymentreceiptlistOldState extends State<PaymentreceiptlistOld> { ...@@ -271,6 +271,7 @@ class _PaymentreceiptlistOldState extends State<PaymentreceiptlistOld> {
fileUrl: fileUrl:
requestLists[index] requestLists[index]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -1035,6 +1035,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> { ...@@ -1035,6 +1035,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> {
fileUrl: fileUrl:
feedbackHistory[lp] feedbackHistory[lp]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
...@@ -1146,6 +1147,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> { ...@@ -1146,6 +1147,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> {
fileUrl: fileUrl:
feedbackHistory[lp] feedbackHistory[lp]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
...@@ -1439,6 +1441,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> { ...@@ -1439,6 +1441,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> {
fileUrl: fileUrl:
feedbackHistory[lp] feedbackHistory[lp]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
...@@ -2280,6 +2283,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> { ...@@ -2280,6 +2283,7 @@ class _OrdersdetailsbymodesState extends State<Ordersdetailsbymodes> {
fileUrl: fileUrl:
orderDetails orderDetails
.tpcPaymentAttachmentDirFilePath!, .tpcPaymentAttachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -1170,6 +1170,7 @@ class _PaymentdetailsbymodeState extends State<Paymentdetailsbymode> { ...@@ -1170,6 +1170,7 @@ class _PaymentdetailsbymodeState extends State<Paymentdetailsbymode> {
fileUrl: fileUrl:
paymentDetails paymentDetails
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -329,6 +329,7 @@ class _TpcagentdetailsbymodeState extends State<Tpcagentdetailsbymode> { ...@@ -329,6 +329,7 @@ class _TpcagentdetailsbymodeState extends State<Tpcagentdetailsbymode> {
fileUrl: fileUrl:
tpcAgentDetails.idProofDirFilePath ?? tpcAgentDetails.idProofDirFilePath ??
"", "",
downloadEnable: false,
), ),
), ),
); );
...@@ -805,6 +806,7 @@ class _TpcagentdetailsbymodeState extends State<Tpcagentdetailsbymode> { ...@@ -805,6 +806,7 @@ class _TpcagentdetailsbymodeState extends State<Tpcagentdetailsbymode> {
fileUrl: fileUrl:
tpcAgentDetails tpcAgentDetails
.idProofDirFilePath!, .idProofDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -851,6 +851,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> { ...@@ -851,6 +851,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> {
fileUrl: fileUrl:
feedbackHistory[lp] feedbackHistory[lp]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
...@@ -965,6 +966,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> { ...@@ -965,6 +966,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> {
fileUrl: fileUrl:
feedbackHistory[lp] feedbackHistory[lp]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
...@@ -1263,6 +1265,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> { ...@@ -1263,6 +1265,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> {
fileUrl: fileUrl:
feedbackHistory[lp] feedbackHistory[lp]
.attachmentDirFilePath!, .attachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
...@@ -1878,6 +1881,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> { ...@@ -1878,6 +1881,7 @@ class _TpcagentissuelistdetailsState extends State<Tpcagentissuelistdetails> {
fileUrl: fileUrl:
orderDetails orderDetails
.tpcPaymentAttachmentDirFilePath!, .tpcPaymentAttachmentDirFilePath!,
downloadEnable: false,
), ),
), ),
); );
......
...@@ -442,6 +442,7 @@ class _TpcagentlistbymodeState extends State<Tpcagentlistbymode> { ...@@ -442,6 +442,7 @@ class _TpcagentlistbymodeState extends State<Tpcagentlistbymode> {
tpcAgentsLists[index] tpcAgentsLists[index]
.idProofDirFilePath ?? .idProofDirFilePath ??
"-", "-",
downloadEnable: false,
), ),
), ),
); );
......
...@@ -102,6 +102,7 @@ class _FollowupdetailsState extends State<Followupdetails> { ...@@ -102,6 +102,7 @@ class _FollowupdetailsState extends State<Followupdetails> {
(context) => Fileviewer( (context) => Fileviewer(
fileName: followups[index].fsrExt!, fileName: followups[index].fsrExt!,
fileUrl: "https://erp.gengroup.in/files_genservices/tech_fsr_report/${followups[index].fsrExt!}", fileUrl: "https://erp.gengroup.in/files_genservices/tech_fsr_report/${followups[index].fsrExt!}",
downloadEnable: false,
), ),
), ),
); );
......
...@@ -12,10 +12,12 @@ import 'package:pin_code_fields/pin_code_fields.dart'; ...@@ -12,10 +12,12 @@ import 'package:pin_code_fields/pin_code_fields.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../Models/TechnicianLoadNumbersResponse.dart'; import '../../Models/TechnicianLoadNumbersResponse.dart';
import '../../Notifiers/HomeScreenNotifier.dart';
import '../../Utils/dropdownTheme.dart'; import '../../Utils/dropdownTheme.dart';
import 'RazorpayQrScreen.dart';
class Paymentdetails extends StatefulWidget { class Paymentdetails extends StatefulWidget {
final accountName, referenceID, name, genId; final accountName, referenceID, name, genId, complaintType;
const Paymentdetails({ const Paymentdetails({
super.key, super.key,
...@@ -23,6 +25,7 @@ class Paymentdetails extends StatefulWidget { ...@@ -23,6 +25,7 @@ class Paymentdetails extends StatefulWidget {
required this.name, required this.name,
required this.genId, required this.genId,
required this.referenceID, required this.referenceID,
this.complaintType,
}); });
@override @override
...@@ -43,6 +46,7 @@ class _PaymentdetailsState extends State<Paymentdetails> { ...@@ -43,6 +46,7 @@ class _PaymentdetailsState extends State<Paymentdetails> {
context, context,
listen: false, listen: false,
); );
provider.resetErrors();
provider.LoadNumbersAPI( provider.LoadNumbersAPI(
context, context,
widget.accountName, widget.accountName,
...@@ -267,7 +271,7 @@ class _PaymentdetailsState extends State<Paymentdetails> { ...@@ -267,7 +271,7 @@ class _PaymentdetailsState extends State<Paymentdetails> {
), ),
], ],
), ),
items: items:// here i have payment option
provider.paymentModeDropDown provider.paymentModeDropDown
.map( .map(
(paymentMode) => DropdownMenuItem< (paymentMode) => DropdownMenuItem<
...@@ -358,46 +362,43 @@ class _PaymentdetailsState extends State<Paymentdetails> { ...@@ -358,46 +362,43 @@ class _PaymentdetailsState extends State<Paymentdetails> {
), ),
errorWidget(context, provider.selectAmountError), errorWidget(context, provider.selectAmountError),
SizedBox(height: 10), SizedBox(height: 10),
Padding( if (provider.selectPaymentMode?.name?.toLowerCase() != 'upi') ...[
padding: const EdgeInsets.only(bottom: 5.0), Padding(
child: Text("Reference Number"), padding: const EdgeInsets.only(bottom: 5.0),
), child: Text("Reference Number"),
Container(
height: 50,
alignment: Alignment.center,
decoration: BoxDecoration(
color: AppColors.text_field_color,
borderRadius: BorderRadius.circular(14),
), ),
child: Padding( Container(
padding: const EdgeInsets.fromLTRB( height: 50,
10.0, alignment: Alignment.center,
0.0, decoration: BoxDecoration(
10, color: AppColors.text_field_color,
0, borderRadius: BorderRadius.circular(14),
), ),
child: TextFormField( child: Padding(
controller: provider.Referencecontroller, padding: const EdgeInsets.fromLTRB(10.0, 0.0, 10, 0),
keyboardType: TextInputType.text, child: TextFormField(
onChanged: (value) { controller: provider.Referencecontroller,
provider.ReferenceError = null; keyboardType: TextInputType.text,
}, onChanged: (value) {
decoration: InputDecoration( provider.ReferenceError = null;
hintText: "Enter Reference Number", },
hintStyle: TextStyle( decoration: const InputDecoration(
fontWeight: FontWeight.w400, hintText: "Enter Reference Number",
color: Color(0xFFB4BEC0), hintStyle: TextStyle(
fontSize: 14, fontWeight: FontWeight.w400,
color: Color(0xFFB4BEC0),
fontSize: 14,
),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
), ),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
), ),
), ),
), ),
), errorWidget(context, provider.ReferenceError),
errorWidget(context, provider.ReferenceError), ],
// errorWidget(context, provider.ReferenceError),
SizedBox(height: 10), SizedBox(height: 10),
InkResponse( InkResponse(
onTap: () { onTap: () {
...@@ -479,11 +480,65 @@ class _PaymentdetailsState extends State<Paymentdetails> { ...@@ -479,11 +480,65 @@ class _PaymentdetailsState extends State<Paymentdetails> {
? null ? null
: () { : () {
HapticFeedback.selectionClick(); HapticFeedback.selectionClick();
provider.PaymentUpdateAPI(
context, // 🧩 Common validation
provider.Referencecontroller.text, if (provider.selectContact == null) {
provider.Amountcontroller.text, provider.selectContactError = "Please select phone number";
); provider.notifyListeners();
return;
}
if (provider.Amountcontroller.text.isEmpty) {
provider.selectAmountError = "Please enter amount";
provider.notifyListeners();
return;
}
// 🧩 For UPI payment
if (provider.selectPaymentMode?.name?.toLowerCase() == 'upi') {
if (provider.imagePicked == 0 || provider.imagePath == null) {
provider.imageError = "Please upload reference document";
provider.notifyListeners();
return;
}
// All validations passed ✅
var homeProvider = Provider.of<HomescreenNotifier>(
context,
listen: false,
);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RazorpayQrScreen(
sessionId: homeProvider.session,
empId: homeProvider.empId,
amount: provider.Amountcontroller.text,
refType: widget.complaintType,
refId: widget.referenceID,
),
),
);
} else {
// 🧩 For non-UPI payments
if (provider.Referencecontroller.text.isEmpty) {
provider.ReferenceError = "Please enter reference number";
provider.notifyListeners();
return;
}
if (provider.imagePicked == 0 || provider.imagePath == null) {
provider.imageError = "Please upload reference document";
provider.notifyListeners();
return;
}
provider.PaymentUpdateAPI(
context,
provider.Referencecontroller.text,
provider.Amountcontroller.text,
);
}
}, },
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
...@@ -505,10 +560,12 @@ class _PaymentdetailsState extends State<Paymentdetails> { ...@@ -505,10 +560,12 @@ class _PaymentdetailsState extends State<Paymentdetails> {
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
), ),
) )
: const Text( : Text(
"Send OTP", provider.selectPaymentMode?.name?.toLowerCase() == 'upi'
? "Show QR"
: "Send OTP",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: const TextStyle(
fontSize: 15, fontSize: 15,
fontFamily: "JakartaMedium", fontFamily: "JakartaMedium",
color: Colors.white, color: Colors.white,
...@@ -516,7 +573,9 @@ class _PaymentdetailsState extends State<Paymentdetails> { ...@@ -516,7 +573,9 @@ class _PaymentdetailsState extends State<Paymentdetails> {
), ),
), ),
), ),
) ),
), ),
), ),
), ),
......
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import '../../Notifiers/QrProvider.dart';
import '../../Utils/app_colors.dart';
import '../../Utils/commonWidgets.dart';
import '../../Utils/custom_snackbar.dart';
class RazorpayQrScreen extends StatefulWidget {
final String sessionId;
final String empId;
final String amount;
final String refType;
final String refId;
const RazorpayQrScreen({
super.key,
required this.sessionId,
required this.empId,
required this.amount,
required this.refType,
required this.refId,
});
@override
State<RazorpayQrScreen> createState() => _RazorpayQrScreenState();
}
class _RazorpayQrScreenState extends State<RazorpayQrScreen> {
Timer? _statusTimer;
@override
void initState() {
super.initState();
Future.microtask(() async {
final qrProvider = context.read<QrProvider>();
// Step 1: Create QR
await qrProvider.fetchRazorpayQr(
sessionId: widget.sessionId,
empId: widget.empId,
amount: widget.amount,
refType: widget.refType,
refId: widget.refId,
);
// Step 2: Start polling only if QR generated successfully
if (qrProvider.qrResponse?.error == "0" &&
qrProvider.qrResponse?.qrCode != null) {
_startStatusPolling(qrProvider);
}
});
}
void _startStatusPolling(QrProvider provider) {
_statusTimer = Timer.periodic(const Duration(seconds: 5), (timer) async {
if (!mounted) return;
final razorpayOrderId = provider.qrResponse?.qrId;
if (razorpayOrderId == null) return;
final response = await provider.fetchRazorpayUpiQrStatus(
context: context,
sessionId: widget.sessionId,
empId: widget.empId,
razorpayOrderId: razorpayOrderId,
);
if (response != null && response.error == "0") {//
CustomSnackBar.showSuccess(
context: context,
message:"Payment received successfully ",
);
// Fluttertoast.showToast(
// msg:
// backgroundColor: Colors.green,
// textColor: Colors.white,
// );
// Stop timer
timer.cancel();
// Go back two screens
if (mounted) {
Navigator.pop(context); // close QR screen
Navigator.pop(context); // close previous screen
}
}
});
}
@override
void dispose() {
_statusTimer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: appbarNew(context, "Scan QR to Pay", 0xFFFFFFFF),
backgroundColor: Colors.black,
body: SafeArea(
child: Consumer<QrProvider>(
builder: (context, provider, _) {
if (provider.isLoading) {
return _buildLoadingState();
}
if (provider.errorMessage != null) {
return _buildErrorState(provider.errorMessage!);
}
if (provider.qrResponse == null || provider.qrResponse?.qrCode == null) {
return _buildNoQrState();
}
if (provider.secondsLeft == 0) {
Future.delayed(Duration.zero, () {
if (mounted) Navigator.pop(context);
});
return _buildExpiredState();
}
return _buildQrScreen(provider);
},
),
),
);
}
Widget _buildLoadingState() {
return Container(
color: Colors.black,
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
SizedBox(height: 20),
Text(
"Generating QR Code...",
style: TextStyle(
color: Colors.white,
fontSize: 16,
),
),
],
),
),
);
}
Widget _buildErrorState(String errorMessage) {
return Container(
color: Colors.black,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.error_outline,
size: 60,
color: Colors.redAccent,
),
const SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: Text(
errorMessage,
style: const TextStyle(
color: Colors.white,
fontSize: 16,
),
textAlign: TextAlign.center,
),
),
const SizedBox(height: 30),
_buildBackButton(),
],
),
),
);
}
Widget _buildNoQrState() {
return Container(
color: Colors.black,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.qr_code_2,
size: 60,
color: Colors.grey,
),
const SizedBox(height: 20),
const Text(
"No QR Code Found",
style: TextStyle(
color: Colors.white,
fontSize: 18,
),
),
const SizedBox(height: 30),
_buildBackButton(),
],
),
),
);
}
Widget _buildExpiredState() {
return Container(
color: Colors.black,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.timer_off_rounded,
size: 60,
color: Colors.redAccent,
),
const SizedBox(height: 20),
const Text(
"QR Expired",
style: TextStyle(
fontSize: 20,
color: Colors.redAccent,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 10),
const Text(
"Returning to previous screen...",
style: TextStyle(
color: Colors.white70,
fontSize: 14,
),
),
],
),
),
);
}
Widget _buildQrScreen(QrProvider provider) {
final screenHeight = MediaQuery.of(context).size.height;
final screenWidth = MediaQuery.of(context).size.width;
return Stack(
children: [
// Full Screen QR Code Background - Preserving all text
Positioned.fill(
child: Image.network(
provider.qrResponse!.qrCode!,
fit: BoxFit.contain, // Use contain to preserve all content
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return Container(
color: Colors.black,
child: const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
),
);
},
errorBuilder: (context, error, stackTrace) {
return Container(
color: Colors.black,
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error, size: 60, color: Colors.red),
SizedBox(height: 16),
Text(
"Failed to load QR code",
style: TextStyle(color: Colors.white, fontSize: 16),
),
],
),
),
);
},
),
),
// Top Bar - Timer and Close
Positioned(
top: 0,
left: 0,
right: 0,
child: Container(
height: 80,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black.withOpacity(0.8),
Colors.transparent,
],
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Timer on left
Container(
margin: const EdgeInsets.only(left: 20, top: 40),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.7),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: Colors.orange,
width: 1,
),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.timer,
color: Colors.orange,
size: 16,
),
const SizedBox(width: 6),
Text(
"${provider.secondsLeft}s",
style: const TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w600,
),
),
],
),
),
// Close button on right
Container(
margin: const EdgeInsets.only(right: 20, top: 40),
child: CircleAvatar(
radius: 20,
backgroundColor: Colors.transparent,
child: IconButton(
icon: const Icon(Icons.close, size: 18),
color: Colors.transparent,
onPressed: () => Navigator.pop(context),
),
),
),
],
),
),
),
// Bottom Section - Amount and Action Buttons
// Positioned at the very bottom to avoid covering QR content
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Colors.black.withOpacity(0.9),
Colors.black.withOpacity(0.6),
Colors.transparent,
],
),
),
child: Column(
children: [
// Amount Display
// Container(
// width: double.infinity,
// padding: const EdgeInsets.all(16),
// decoration: BoxDecoration(
// color: AppColors.app_blue.withOpacity(0.9),
// borderRadius: BorderRadius.circular(12),
// boxShadow: [
// BoxShadow(
// color: Colors.black.withOpacity(0.3),
// blurRadius: 10,
// offset: const Offset(0, 4),
// ),
// ],
// ),
// child: Column(
// children: [
// const Text(
// "Amount to Pay",
// style: TextStyle(
// color: Colors.white70,
// fontSize: 14,
// fontWeight: FontWeight.w500,
// ),
// ),
// const SizedBox(height: 8),
// Text(
// "₹${widget.amount}",
// style: const TextStyle(
// fontSize: 28,
// fontWeight: FontWeight.bold,
// color: Colors.white,
// ),
// ),
// ],
// ),
// ),
const SizedBox(height: 20),
// Action Buttons
Row(
children: [
// Cancel Button
Expanded(
child: ElevatedButton.icon(
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.close, size: 18),
label: const Text("Cancel"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red.withOpacity(0.9),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.symmetric(vertical: 12),
elevation: 3,
),
),
),
const SizedBox(width: 12),
// Instructions Button
Expanded(
child: ElevatedButton.icon(
onPressed: _showInstructions,
icon: const Icon(Icons.help_outline, size: 18),
label: const Text("Help"),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey.withOpacity(0.8),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.symmetric(vertical: 12),
elevation: 3,
),
),
),
],
),
],
),
),
),
// Small status indicator at the top center (minimal space usage)
Positioned(
top: 40,
left: 0,
right: 0,
child: Center(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.9),
borderRadius: BorderRadius.circular(12),
),
child: const Text(
"READY TO SCAN",
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w600,
letterSpacing: 1.0,
),
),
),
),
),
],
);
}
void _showInstructions() {
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
builder: (context) => Container(
decoration: BoxDecoration(
color: AppColors.scaffold_bg_color,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 40,
height: 4,
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 20),
const Text(
"How to Pay",
style: TextStyle(
color: Colors.blue,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16),
_buildInstructionStep("1", "Open any UPI app on your phone"),
_buildInstructionStep("2", "Tap on 'Scan QR Code'"),
_buildInstructionStep("3", "Point your camera at this QR code"),
_buildInstructionStep("4", "Enter UPI PIN to complete payment"),
const SizedBox(height: 20),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.app_blue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.symmetric(vertical: 12),
),
child: const Text("Got It"),
),
),
const SizedBox(height: 10),
],
),
),
);
}
Widget _buildInstructionStep(String number, String text) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 24,
height: 24,
decoration: BoxDecoration(
color: AppColors.app_blue,
shape: BoxShape.circle,
),
child: Center(
child: Text(
number,
style: const TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.bold,
),
),
),
),
const SizedBox(width: 12),
Expanded(
child: Text(
text,
style: const TextStyle(
color: Colors.black87,
fontSize: 14,
),
),
),
],
),
);
}
Widget _buildBackButton() {
return ElevatedButton.icon(
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.arrow_back),
label: const Text("Go Back"),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.app_blue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
),
);
}
}
\ No newline at end of file
...@@ -942,6 +942,7 @@ class _VisitdetailsState extends State<Visitdetails> { ...@@ -942,6 +942,7 @@ class _VisitdetailsState extends State<Visitdetails> {
.fsrExt!, .fsrExt!,
fileUrl: fileUrl:
"https://erp.gengroup.in/files_genservices/tech_fsr_report/${followups[lp].fsrExt!}", "https://erp.gengroup.in/files_genservices/tech_fsr_report/${followups[lp].fsrExt!}",
downloadEnable: false,
), ),
), ),
); );
...@@ -1022,6 +1023,7 @@ class _VisitdetailsState extends State<Visitdetails> { ...@@ -1022,6 +1023,7 @@ class _VisitdetailsState extends State<Visitdetails> {
provider provider
.complaintDetailsNew .complaintDetailsNew
.complaintId, .complaintId,
complaintType: provider.complaintDetailsNew.complaintType,
), ),
), ),
); );
......
...@@ -244,7 +244,7 @@ class _ServiceengineerdashboardState extends State<Serviceengineerdashboard> { ...@@ -244,7 +244,7 @@ class _ServiceengineerdashboardState extends State<Serviceengineerdashboard> {
child: Container( child: Container(
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: 10, left: 10,
top: 10, top: 9,
bottom: 10, bottom: 10,
right: 10, right: 10,
), ),
...@@ -272,7 +272,7 @@ class _ServiceengineerdashboardState extends State<Serviceengineerdashboard> { ...@@ -272,7 +272,7 @@ class _ServiceengineerdashboardState extends State<Serviceengineerdashboard> {
child: Text( child: Text(
"${numbers[index].toString()}", "${numbers[index].toString()}",
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 18,
color: Color(textColorCodes[index]), color: Color(textColorCodes[index]),
), ),
), ),
......
...@@ -24,6 +24,7 @@ import 'package:generp/Models/crmModels/crmNewLeadsProspectsViewResponse.dart'; ...@@ -24,6 +24,7 @@ import 'package:generp/Models/crmModels/crmNewLeadsProspectsViewResponse.dart';
import 'package:generp/Models/crmModels/crmProspectDetailsAddFollowUpAppointmentResponse.dart'; import 'package:generp/Models/crmModels/crmProspectDetailsAddFollowUpAppointmentResponse.dart';
import 'package:generp/Models/crmModels/crmProspectDetailsAddLeadsResponse.dart'; import 'package:generp/Models/crmModels/crmProspectDetailsAddLeadsResponse.dart';
import 'package:generp/Models/crmModels/crmProspectDetailsResponse.dart'; import 'package:generp/Models/crmModels/crmProspectDetailsResponse.dart';
import 'package:generp/Models/financeModels/ValidateGstNumResponse.dart';
import 'package:generp/Models/financeModels/addDirectPaymentResponse.dart'; import 'package:generp/Models/financeModels/addDirectPaymentResponse.dart';
import 'package:generp/Models/financeModels/paymentRequisitionPaymentsListResponse.dart'; import 'package:generp/Models/financeModels/paymentRequisitionPaymentsListResponse.dart';
import 'package:generp/Models/hrmModels/advanceListResponse.dart'; import 'package:generp/Models/hrmModels/advanceListResponse.dart';
...@@ -85,6 +86,7 @@ import '../Models/crmModels/crmDashboardResponse.dart'; ...@@ -85,6 +86,7 @@ import '../Models/crmModels/crmDashboardResponse.dart';
import '../Models/crmModels/crmPendingTasksResponse.dart'; import '../Models/crmModels/crmPendingTasksResponse.dart';
import '../Models/crmModels/crmSelectedProductDetailsResponse.dart'; import '../Models/crmModels/crmSelectedProductDetailsResponse.dart';
import '../Models/crmModels/crmUniversalSearchResponse.dart'; import '../Models/crmModels/crmUniversalSearchResponse.dart';
import '../Models/financeModels/ValidateBankAccountDetailsResponse.dart';
import '../Models/financeModels/paymentRequestionBankDetailsResponse.dart'; import '../Models/financeModels/paymentRequestionBankDetailsResponse.dart';
import '../Models/commonModels/commonAccountLedgerFilterResponse.dart'; import '../Models/commonModels/commonAccountLedgerFilterResponse.dart';
import '../Models/commonModels/commonAccountLedgerResponse.dart'; import '../Models/commonModels/commonAccountLedgerResponse.dart';
...@@ -1694,6 +1696,60 @@ class ApiCalling { ...@@ -1694,6 +1696,60 @@ class ApiCalling {
} }
} }
/// validate Gst Number Api
static Future<ValidateGstNumResponse?> validateGstNumberApi(
empId,
session,
gstNumber,
) async {
try {
Map<String, String> data = {
'emp_id': (empId).toString(),
'session_id': (session).toString(),
'gst_number': (gstNumber).toString(),
};
final res = await post(data, validateGstNumberUrl, {});
if (res != null) {
debugPrint(res.body);
return ValidateGstNumResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint('hello validateGstNumberApi $e ');
return null;
}
}
/// validate bank account details api
static Future<ValidateBankAccountDetailsResponse?> validateBankAccountDetailsApi(
empId,
session,
accountNum,
ifscCode
) async {
try {
Map<String, String> data = {
'emp_id': (empId).toString(),
'session_id': (session).toString(),
'account_number': (accountNum).toString(),
'ifsc_code': (ifscCode).toString(),
};
final res = await post(data, validateBankAccountDetailsUrl, {});
if (res != null) {
debugPrint(res.body);
return ValidateBankAccountDetailsResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint('hello validateBankAccountDetails $e ');
return null;
}
}
static Future<paymentRequestionBankDetailsResponse?> static Future<paymentRequestionBankDetailsResponse?>
paymentRequestionBankDetailsAPI(empId, session, accountId) async { paymentRequestionBankDetailsAPI(empId, session, accountId) async {
try { try {
...@@ -3787,7 +3843,7 @@ class ApiCalling { ...@@ -3787,7 +3843,7 @@ class ApiCalling {
alphabet, alphabet,
pageNumber, pageNumber,
) async { ) async {
debugPrint('crmLeadListFilterSubmitAPI Input data:'); debugPrint('#########crmLeadListFilterSubmitAPI Input data:');
debugPrint('empId: $empId'); debugPrint('empId: $empId');
debugPrint('session: $session'); debugPrint('session: $session');
debugPrint('mode: $mode'); debugPrint('mode: $mode');
...@@ -5666,6 +5722,67 @@ class ApiCalling { ...@@ -5666,6 +5722,67 @@ class ApiCalling {
} }
} }
static Future<CommonResponse?> fetchRazorpayUpiQrApi(
session,
empId,
amount,
refType,
refId
) async {
try {
Map<String, String> data = {
'session_id': (session).toString(),
'emp_id': (empId).toString(),
'amount': (amount),
'ref_type': (refType).toString(),
'ref_id': (refId),
};
final res = await post(data, createRazorpayUpiQrUrl, {});
if (res != null) {
print(data);
debugPrint(res.body);
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint('hello bev=bug $e ');
return null;
}
}
static Future<CommonResponse?> fetchRazorpayUpiQrStatusApi(
session,
empId,
razorpayOrderId,
) async {
try {
Map<String, String> data = {
'session_id': (session).toString(),
'emp_id': (empId).toString(),
'razorpay_order_id': (razorpayOrderId),
};
final res = await post(data, fetchRazorpayUpiQrStatusUrl, {});
if (res != null) {
print(data);
debugPrint(res.body);
return CommonResponse.fromJson(jsonDecode(res.body));
} else {
debugPrint("Null Response");
return null;
}
} catch (e) {
debugPrint('hello bev=bug $e ');
return null;
}
}
// static Future<CommonResponse?> TpcIssueListApprovalAPI( // static Future<CommonResponse?> TpcIssueListApprovalAPI(
// empId, // empId,
// session, // session,
......
...@@ -74,7 +74,8 @@ const paymentRequesitionPaymentsDetailsUrl = "${baseUrl_test}payment_requisition ...@@ -74,7 +74,8 @@ const paymentRequesitionPaymentsDetailsUrl = "${baseUrl_test}payment_requisition
const paymentRequesitionPaymentsReceiptsListUrl = "${baseUrl_test}payment_receipts_list_v2"; const paymentRequesitionPaymentsReceiptsListUrl = "${baseUrl_test}payment_receipts_list_v2";
const paymentRequesitionPaymentsReceiptsDetailsUrl = "${baseUrl_test}payment_receipt_details"; const paymentRequesitionPaymentsReceiptsDetailsUrl = "${baseUrl_test}payment_receipt_details";
const paymentRequesitionEditProcessedPaymentUrl = "${baseUrl_test}edit_processes_payment"; const paymentRequesitionEditProcessedPaymentUrl = "${baseUrl_test}edit_processes_payment";
const validateGstNumberUrl = "${baseUrl_test}validate_gst_number";
const validateBankAccountDetailsUrl = "${baseUrl_test}validate_bank_account_details";
///common Module ///common Module
const commonAccessiblePagesUrl = "${baseUrl_test}common_accessible_pages"; const commonAccessiblePagesUrl = "${baseUrl_test}common_accessible_pages";
...@@ -208,5 +209,6 @@ const CasuaLeaveHistoryUrl ="${baseUrl_test}casual_leave_history"; ...@@ -208,5 +209,6 @@ const CasuaLeaveHistoryUrl ="${baseUrl_test}casual_leave_history";
const EmployeeContactListUrl ="${baseUrl_test}employee_contact_list"; const EmployeeContactListUrl ="${baseUrl_test}employee_contact_list";
const AdvanceListUrl ="${baseUrl_test}advance_list"; const AdvanceListUrl ="${baseUrl_test}advance_list";
const createRazorpayUpiQrUrl ="${baseUrl_test}create_razorpay_upi_qr";
const fetchRazorpayUpiQrStatusUrl ="${baseUrl_test}fetch_razorpay_upi_qr_status";
\ No newline at end of file
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