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.
652 lines
28 KiB
652 lines
28 KiB
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 OrderDetails extends StatefulWidget {
|
|
var supplierDetails;
|
|
OrderDetails({this.supplierDetails});
|
|
|
|
@override
|
|
State<OrderDetails> createState() => _OrderDetailsState();
|
|
}
|
|
|
|
class _OrderDetailsState extends State<OrderDetails> {
|
|
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["supplierId"] = object.supplierId;
|
|
payload["action"] = 'accepted';
|
|
payload["paymentId"] = response.paymentId;
|
|
|
|
try {
|
|
bool status = await AppSettings.acceptOrderRequests(payload, object.dbId);
|
|
|
|
if (!mounted) return;
|
|
|
|
if (status) {
|
|
AppSettings.longSuccessToast('Accepted');
|
|
|
|
Navigator.pop(context, true);
|
|
} 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) {
|
|
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: Text(
|
|
widget.supplierDetails.capacity +
|
|
' - ' +
|
|
widget.supplierDetails.typeofwater,
|
|
style: fontTextStyle(
|
|
12, Color(0XFF2D2E30), FontWeight.w500),
|
|
),
|
|
),
|
|
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(
|
|
'Date',
|
|
style: fontTextStyle(12,
|
|
Color(0XFF515253), FontWeight.w500),
|
|
),
|
|
Text(
|
|
widget.supplierDetails.date,
|
|
style: fontTextStyle(12,
|
|
Color(0XFF232527), FontWeight.w500),
|
|
)
|
|
],
|
|
),
|
|
SizedBox(
|
|
height:
|
|
MediaQuery.of(context).size.height * .012,
|
|
),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
'Time',
|
|
style: fontTextStyle(12,
|
|
Color(0XFF515253), FontWeight.w500),
|
|
),
|
|
Text(
|
|
widget.supplierDetails.time,
|
|
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(total.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(
|
|
subtotal.toString())),
|
|
Divider(),
|
|
_itemRow('Item Total',
|
|
'₹${AppSettings.moneyConvertion(total.toString())}'),
|
|
_itemRow('Delivery Charges',
|
|
'₹${AppSettings.moneyConvertion(deliveryCharges.toString())}'),
|
|
_itemRow('Platform Fee', '₹${AppSettings.moneyConvertion(platformFee.toString())}'),
|
|
_itemRow('Taxes', '₹${AppSettings.moneyConvertion(totalTaxes.toString())}'),
|
|
Divider(),
|
|
_itemRow('Total Bill',
|
|
'₹${AppSettings.moneyConvertion(total.toString())}',
|
|
bold: true),
|
|
Divider(),
|
|
_itemRow('Advance', '₹${AppSettings.moneyConvertion(advance.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(advance);
|
|
/*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,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
|
|
);
|
|
}
|
|
}
|