You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

769 lines
32 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'package:flutter/material.dart';
import 'package:bookatanker/common/settings.dart';
import 'package:bookatanker/supplier/payment_example2.dart';
import 'package:bookatanker/supplier/payment_screen.dart';
import 'package:razorpay_flutter/razorpay_flutter.dart';
class PlanDetails extends StatefulWidget {
var supplierDetails;
PlanDetails({this.supplierDetails});
@override
State<PlanDetails> createState() => _PlanDetailsState();
}
class _PlanDetailsState extends State<PlanDetails> {
bool isExpanded = false;
double actualPrice = 0.0;
int quantity = 0;
double deliveryCharges = 0.0;
double subtotal = 0.0;
double cgst = 0.0;
double sgst = 0.0;
double total = 0.0;
double platformFee = 0.0;
double totalTaxes = 0.0;
double advance = 0.0;
double balance = 0.0;
late Razorpay _razorpay;
@override
void initState() {
super.initState();
actualPrice =
double.tryParse(widget.supplierDetails.quotedAmount ?? '0') ?? 0;
quantity = int.tryParse(widget.supplierDetails.quantity ?? '0') ?? 0;
//deliveryCharges = double.tryParse(widget.supplierDetails.bookingCharges ?? '0') ?? 0;;
platformFee = 11;
subtotal = actualPrice * quantity;
cgst = subtotal * 0.09;
sgst = subtotal * 0.09;
totalTaxes = cgst + sgst;
total = subtotal + cgst + sgst + deliveryCharges + platformFee;
advance = deliveryCharges;
//balance = total - advance;
_razorpay = Razorpay();
_razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, (PaymentSuccessResponse response) {
_handleSuccess(response, widget.supplierDetails);
});
_razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handleError);
_razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet);
}
Widget _buildAddressRow(String label, String address, Color color) {
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Row(
children: [
Image.asset(
'images/location_supplier_landing.png',
height: 24,
width: 24,
fit: BoxFit.contain,
color: Color(0XFF939495),
),
SizedBox(
width: MediaQuery.of(context).size.width * .012,
),
Text(
'$label ',
style: fontTextStyle(14, color, FontWeight.bold),
),
Expanded(
child: Text(
address,
overflow: TextOverflow.ellipsis,
style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400),
),
)
],
),
);
}
Widget _itemRow(String title, String price, {bool bold = false}) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title,
style: fontTextStyle(12, Color(0XFF646566), FontWeight.w400)),
Text(price,
style: fontTextStyle(12, Color(0XFF646566), FontWeight.w400)),
],
),
);
}
void _openCheckout(double amountInRupees) {
var options = {
'key': 'rzp_test_1VCCWqEXUHdINz', // Replace with your Razorpay Key
'amount': (amountInRupees * 100)
.toInt(), // Convert rupees to paise and ensure integer
'name': 'Test Payment',
'description': 'Water Order',
'prefill': {
'contact': '9876543210',
'email': 'test@example.com',
}
};
try {
_razorpay.open(options);
} catch (e) {
print('Error: $e');
}
}
/* void _handleSuccess(PaymentSuccessResponse response) {
_showAlert('Payment Successful', 'Payment ID: ${response.paymentId}');
}*/
void _handleSuccess(PaymentSuccessResponse response, dynamic object) async {
if (!mounted) return; // ensure widget is still active
var payload = <String, dynamic>{};
payload["action"] = 'accept';
payload["ref_number"] = response.paymentId;
payload["payment_type"] = object.paymentType;
try {
bool status = await AppSettings.acceptPlanRequestsWithPayment(payload, object.dbId);
if (!mounted) return;
if (status) {
AppSettings.longSuccessToast('Accepted');
Navigator.pop(context, true);
// Use Navigator safely
/* Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => OrderDetails(supplierDetails: object),
),
);*/
} else {
AppSettings.longFailedToast('Failed to accept order request');
}
} catch (e) {
AppSettings.longFailedToast('Error: $e');
}
}
void _handleError(PaymentFailureResponse response) {
_showAlert('Payment Failed', '${response.code} - ${response.message}');
}
void _handleExternalWallet(ExternalWalletResponse response) {
_showAlert('Wallet Selected', '${response.walletName}');
}
void _showAlert(String title, String content) {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text(title),
content: Text(content),
actions: [
TextButton(onPressed: () => Navigator.pop(context), child: Text('OK'))
],
),
);
}
@override
void dispose() {
_razorpay.clear();
super.dispose();
}
@override
Widget build(BuildContext context) {
final int totalOrders = widget.supplierDetails.dates.length;
final double biddingPrice =
double.tryParse(widget.supplierDetails.biddingPrice) ?? 0;
final double totalAmount = totalOrders * biddingPrice;
final num total = totalAmount is num
? totalAmount
: num.tryParse(totalAmount.toString()) ?? 0;
final num advance = widget.supplierDetails.advanceAmount is num
? widget.supplierDetails.advanceAmount
: num.tryParse(widget.supplierDetails.advanceAmount.toString()) ?? 0;
final num balance = total - advance;
return Scaffold(
backgroundColor: Color(0XFFFFFFFF),
appBar: AppSettings.supplierAppBarWithoutActions(
widget.supplierDetails.supplierName, context),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(12, 8, 12, 8),
child: Column(
children: [
_buildAddressRow(widget.supplierDetails.supplierName,
'| ' + widget.supplierDetails.address, Color(0XFF4692FD)),
Padding(
padding: const EdgeInsets.only(
left: 8.0, bottom: 4.0), // 👈 Shift right
child: Align(
alignment: Alignment.centerLeft,
child: Image.asset(
'images/Line.png',
height: 12,
width: 6,
fit: BoxFit.contain,
),
),
),
_buildAddressRow('Home', '| ' + AppSettings.userAddress,
Color(0XFF2D2E30)),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Card(
color: Color(0XFFFFFFFF),
child: Padding(
padding: EdgeInsets.all(4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
width: double
.infinity, // makes it expand within the Card's width
decoration: BoxDecoration(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(8),
top: Radius.circular(8),
), // match Card border
gradient: LinearGradient(
colors: [
Color(0xFFFFF8DF),
Color(0xFFFFFFFF),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
padding: EdgeInsets.symmetric(vertical: 12),
alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.fromLTRB(12, 0, 12, 0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
widget
.supplierDetails.supplierName,
style: fontTextStyle(
16,
Color(0XFF2D2E30),
FontWeight.w600)),
Text(
widget.supplierDetails
.distanceInMeters
.toString() +
' Km',
style: fontTextStyle(
12,
Color(0XFF2D2E30),
FontWeight.w600)),
],
),
Text(
widget.supplierDetails.displayAddress,
style: fontTextStyle(
12,
Color(0XFF515253),
FontWeight.w400)),
],
))),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Container(
width: double
.infinity, // makes it expand within the Card's width
decoration: BoxDecoration(
color: Color(0XFFF5F6F6), // Same as Card color
borderRadius:
BorderRadius.circular(4), // Rounded corners
border: Border.all(
color: Color(0XFFF5F6F6), // Border color
width: 0.5, // Border width
),
),
padding: EdgeInsets.symmetric(vertical: 4),
child: Padding(
padding: EdgeInsets.fromLTRB(12, 0, 12, 0),
child: Text('ITEMS',
style: fontTextStyle(10, Color(0XFF646566),
FontWeight.w400)),
)),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Padding(
padding: EdgeInsets.fromLTRB(4, 0, 4, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.supplierDetails.capacity +
' - ' +
widget.supplierDetails.typeofwater+' - ' +
widget.supplierDetails.frequency+'/week',
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w500),
),
Row(
children: [
Text('Actual Price: ', style: fontTextStyle(
12,
Color(0XFF646566),
FontWeight.w400),),
Text(
'' +
AppSettings.formDouble(widget.supplierDetails.quotedAmount) +
'/',
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w500),
),
Text(
widget.supplierDetails.capacity,
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w500),
)
],
),
Row(
children: [
Text('Bidding Price: ', style: fontTextStyle(
12,
Color(0XFF646566),
FontWeight.w400),),
Text(
'' +
AppSettings.formDouble(widget.supplierDetails.biddingPrice) +
'/',
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w500),
),
Text(
widget.supplierDetails.capacity,
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w500),
)
],
),
Row(
children: [
Text('Payment Type: ', style: fontTextStyle(
12,
Color(0XFF646566),
FontWeight.w400),),
Text(
widget.supplierDetails.paymentType,
style: fontTextStyle(
12,
Color(0XFF515253),
FontWeight.w600),
),
],
),
Visibility(
visible:widget.supplierDetails.paymentType!='after_delivery' ,
child: Row(
children: [
Text(widget.supplierDetails.paymentType=='credit'?'Credit Limit: ':'Advance Amount: ', style: fontTextStyle(
12,
Color(0XFF646566),
FontWeight.w400),),
Text(
widget.supplierDetails.advanceAmount,
style: fontTextStyle(
12,
Color(0XFF515253),
FontWeight.w600),
),
],
),),
Text.rich(
TextSpan(
children: [
TextSpan(
text: "Total amount for this plan orders ",
style: fontTextStyle(
12,
const Color(0xFF939495),
FontWeight.w400,
),
),
TextSpan(
text:
'$totalOrders × ${biddingPrice.toStringAsFixed(0)} = ₹${totalAmount.toStringAsFixed(0)}',
style: fontTextStyle(
12,
const Color(0xFF515253),
FontWeight.w500,
),
),
],
),
softWrap: true,
maxLines: 2,
overflow: TextOverflow.visible,
textAlign: TextAlign.center,
)
],
)
),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Container(
width: double
.infinity, // makes it expand within the Card's width
decoration: BoxDecoration(
color: Color(0XFFF5F6F6), // Same as Card color
borderRadius:
BorderRadius.circular(4), // Rounded corners
border: Border.all(
color: Color(0XFFF5F6F6), // Border color
width: 0.5, // Border width
),
),
padding: EdgeInsets.symmetric(vertical: 4),
child: Padding(
padding: EdgeInsets.fromLTRB(12, 0, 12, 0),
child: Text('DELIVERY DETAILS',
style: fontTextStyle(10, Color(0XFF646566),
FontWeight.w400)),
)),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Padding(
padding: EdgeInsets.fromLTRB(4, 0, 4, 0),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'Plan Period',
style: fontTextStyle(12,
Color(0XFF515253), FontWeight.w500),
),
Visibility(
visible: widget.supplierDetails.startDate !=
'',
child: Text(
widget.supplierDetails.startDate +
' to ' +
widget.supplierDetails.endDate,
style: fontTextStyle(
12,
Color(0XFF232527),
FontWeight
.w500),
),
)
],
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Align(
alignment: Alignment.center,
child: Container(
decoration: BoxDecoration(
color:
Color(0XFFFFFFFF), // Same as Card color
borderRadius: BorderRadius.circular(
4), // Rounded corners
border: Border.all(
color: Color(0XFF939495), // Border color
width: 0.5, // Border width
),
),
padding: EdgeInsets.symmetric(vertical: 4),
child: Padding(
padding: EdgeInsets.fromLTRB(12, 0, 12, 0),
child: Text('Change Delivery Details',
style: fontTextStyle(14,
Color(0XFF646566), FontWeight.w500)),
)),
),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
],
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Card(
color: Color(0XFFFFFFFF),
child: Padding(
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('SAVINGS',
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400)),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Row(
children: [
Image.asset(
'images/coupon.png',
height: 16,
width: 16,
fit: BoxFit.contain,
),
SizedBox(
width: MediaQuery.of(context).size.width *
.012),
Text(
'Apply Coupon',
style: fontTextStyle(
12,
Color(0XFF2D2E30),
FontWeight.w500,
),
),
Spacer(), // pushes the arrow to the right
Image.asset(
'images/arrow-right.png',
height: 20,
width: 20,
fit: BoxFit.contain,
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
],
),
)),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Column(
children: [
// Header card
GestureDetector(
onTap: () => setState(() => isExpanded = !isExpanded),
child: Card(
color: Color(0XFFFFFFFF),
child: Padding(
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
child: Row(
children: [
Image.asset(
'images/receipt.png',
height: 16,
width: 16,
fit: BoxFit.contain,
),
SizedBox(
width:
MediaQuery.of(context).size.width * .012,
),
Expanded(
child: Text(
'To Pay ₹${AppSettings.moneyConvertion(widget.supplierDetails.advanceAmount.toString())}',
style: fontTextStyle(12,
Color(0XFF2E302D), FontWeight.w600)),
),
isExpanded
? Image.asset(
'images/arrow-up.png',
height: 20,
width: 20,
fit: BoxFit.contain,
)
: Image.asset(
'images/arrow-down.png',
height: 20,
width: 20,
fit: BoxFit.contain,
)
],
),
),
),
),
AnimatedContainer(
duration: Duration(milliseconds: 300),
curve: Curves.easeInOut,
height: isExpanded ? null : 0,
padding:
isExpanded ? EdgeInsets.all(0) : EdgeInsets.zero,
child: isExpanded
? Card(
color: Color(0XFFFFFFFF),
child: Padding(
padding: EdgeInsets.all(8),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text('ITEMS',
style: fontTextStyle(
14,
Color(0XFF2D2E30),
FontWeight.w500)),
SizedBox(
height:
MediaQuery.of(context).size.height *
.012,
),
_itemRow(
widget.supplierDetails.capacity +
' ' +
widget
.supplierDetails.typeofwater +
' x ' +
widget.supplierDetails.quantity,
'' +
AppSettings.moneyConvertion(
biddingPrice.toString())),
Divider(),
_itemRow('Total Amount For Plan',
'${AppSettings.moneyConvertion(totalAmount.toStringAsFixed(0))}'),
_itemRow('Delivery Charges',
'₹ 0.0'),
//_itemRow('Platform Fee', '₹${AppSettings.moneyConvertion(platformFee.toString())}'),
_itemRow('Platform Fee', '₹ 0.0'),
_itemRow('Taxes', '₹ 0.0'),
Divider(),
_itemRow('Total Bill',
'${AppSettings.moneyConvertion(totalAmount.toString())}',
bold: true),
Divider(),
_itemRow('Advance', '${AppSettings.moneyConvertion(widget.supplierDetails.advanceAmount.toString())}'),
_itemRow('To pay(after delivery)',
'${AppSettings.moneyConvertion(balance.toString())}'),
],
),
),
)
: null,
),
],
)
],
)),
),
bottomNavigationBar: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border(
top: BorderSide(color: Color(0XFFC3C4C4), width: 0.8),
),
boxShadow: [
BoxShadow(
color: Color(0XFFC3C4C4),
blurRadius: 0,
offset: Offset(0, 0),
),
],
),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Row(
children: [
// Button 1: Pay Advance
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Color(0XFF0A9E04),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
padding: EdgeInsets.symmetric(vertical: 12), // Only vertical padding
),
onPressed: () {
/*Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RazorpayScreen()),
);*/
/*Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PaymentOptionsPage(amount: advance),
),
);*/
_openCheckout(double.parse(widget.supplierDetails.advanceAmount));
/*Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UpiIntentLauncher(),
),
);*/
},
child: Text(
"Pay advance ₹${AppSettings.moneyConvertion(advance.toString())}",
style: fontTextStyle(14, Color(0XFFFFFFFF), FontWeight.w600),
textAlign: TextAlign.center,
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * .012,
),// spacing between buttons
// Button 2: Pay Full
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Color(0XFF1D7AFC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
padding: EdgeInsets.symmetric(vertical: 12),
),
onPressed: () {
// Handle full payment
},
child: Text(
"Pay full ₹${AppSettings.moneyConvertion(total.toStringAsFixed(2))}",
style: fontTextStyle(14, Color(0XFFFFFFFF), FontWeight.w600),
textAlign: TextAlign.center,
),
),
),
],
),
),
);
}
}