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.

813 lines
33 KiB

import 'dart:convert';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:bookatanker/supplier/order_details.dart';
import '../common/settings.dart';
import 'supplier_orders_model.dart';
class OrderRequestsPage extends StatefulWidget {
const OrderRequestsPage({super.key});
@override
State<OrderRequestsPage> createState() => _OrderRequestsPageState();
}
class _OrderRequestsPageState extends State<OrderRequestsPage> {
bool isSupplierOrdersDataLoading = false;
List<SupplierOrdersModel> supplierOrdersList = [];
List<SupplierOrdersModel> acceptedOrders = [];
List<SupplierOrdersModel> acceptedByUserOrders = [];
List<SupplierOrdersModel> rejectedOrders = [];
void groupOrdersByStatus() {
acceptedOrders = supplierOrdersList
.where((order) => order.status == "accept") // adjust field name
.toList();
acceptedByUserOrders = supplierOrdersList
.where(
(order) => order.status == "accepted_by_user") // adjust field name
.toList();
rejectedOrders = supplierOrdersList
.where(
(order) => order.status == "rejected_by_user") // adjust field name
.toList();
}
@override
void initState() {
// TODO: implement initState
super.initState();
getAcceptedOrdersFromSupplier();
}
Future<void> getAcceptedOrdersFromSupplier() async {
isSupplierOrdersDataLoading = true;
var response1 = await AppSettings.getAcceptedOrdersDataFromSupplier();
var json = jsonDecode(response1);
setState(() {
supplierOrdersList = (json['data'] as List)
.map((model) => SupplierOrdersModel.fromJson(model))
.toList();
groupOrdersByStatus();
isSupplierOrdersDataLoading = false;
});
}
String getOrderTimeOnly(String orderTimeStr) {
if (orderTimeStr.isEmpty) return "";
try {
final format = DateFormat("dd-MM-yyyy HH:mm");
final orderTime = format.parse(orderTimeStr);
final now = DateTime.now();
final difference = now.difference(orderTime);
if (difference.inDays < 2) {
return "New";
} else if (difference.inDays < 10) {
final remaining = 10 - difference.inDays;
return "Expires in ${remaining}d";
} else {
return "Expired";
}
} catch (e) {
return "";
}
}
showRejectOrdersDialog(var object) async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return AlertDialog(
backgroundColor: Color(0XFFFFFFFF),// Set your desired background color
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12), // Optional: Rounded corners
),
title: Center(
child: Text('Reject Order Request' ,style: fontTextStyle(16,Color(0XFF3B3B3B),FontWeight.w600),),
),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Container(
child: Text('Do u want to reject order request',style: fontTextStyle(14,Color(0XFF101214),FontWeight.w600),),
),
],
),
),
actions: <Widget>[
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(child: GestureDetector(
onTap: (){
Navigator.pop(context);
},
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Color(0XFFFFFFFF),
border: Border.all(
width: 1,
color: Color(0XFF1D7AFC)),
borderRadius: BorderRadius.circular(
12,
)),
alignment: Alignment.center,
child: Visibility(
visible: true,
child: Padding(
padding: EdgeInsets.fromLTRB(16,12,16,12),
child: Text('Cancel', style: fontTextStyle(12, Color(0XFF1D7AFC), FontWeight.w600)),
),
),
),
),),
SizedBox(width:MediaQuery.of(context).size.width * .016,),
Expanded(child: GestureDetector(
onTap: ()async{
var payload = <String, dynamic>{};
payload["supplierId"] = object.supplierId;
payload["action"] = 'reject';
payload["paymentId"] = '';
try {
bool status = await AppSettings.acceptOrderRequests(payload, object.dbId);
if (!mounted) return;
if (status) {
AppSettings.longSuccessToast('Rejected');
Navigator.pop(context);
getAcceptedOrdersFromSupplier();
} else {
AppSettings.longFailedToast('Failed to reject order request');
}
} catch (e) {
AppSettings.longFailedToast('Error: $e');
}
},
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: Color(0XFFE2483D),
border: Border.all(
width: 1,
color: Color(0XFFE2483D)),
borderRadius: BorderRadius.circular(
12,
)),
alignment: Alignment.center,
child: Visibility(
visible: true,
child: Padding(
padding: EdgeInsets.fromLTRB(16,12,16,12),
child: Text(
'Reject',
style: fontTextStyle(
12,
Color(0XFFFFFFFF),
FontWeight.w600)),
),
),
)
),)
],
),
),
],
);
});
},
);
}
Widget orderCard(SupplierOrdersModel order) {
final orderDateTime = "${order.acceptedTime}".trim();
final statusTime = getOrderTimeOnly(orderDateTime);
// status badge color
Color statusColor = Color(0xFF1D7AFC);
if (statusTime == "Expired")
statusColor = Color(0xFF757575);
else if (statusTime == "New")
statusColor = Color(0XFF1D7AFC);
else if (statusTime.endsWith("m")) statusColor = Color(0XFFE56910);
return Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
color: Color(0XFFFFFFFF), // Same as Card color
borderRadius: BorderRadius.circular(12), // Rounded corners
border: Border.all(
color: Color(0XFF9F9F9F), // Border color
width: 0.5, // Border width
),
),
//color: Color(0XFFFFFFFF),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: order.supplierName != '',
child: Text(
order.supplierName,
style: fontTextStyle(
14, Color(0XFF343637), FontWeight.w600),
),
),
Visibility(
visible: statusTime.isNotEmpty,
child: Padding(
padding: const EdgeInsets.only(top: 4.0, bottom: 4.0),
child: Container(
padding:
EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: statusColor,
borderRadius: BorderRadius.circular(4),
),
child: Text(
statusTime,
style: fontTextStyle(
10, Colors.white, FontWeight.w500),
),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: order.displayAddress != '',
child: Text(
order.displayAddress,
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400),
),
),
Visibility(
visible: order.date != '',
child: Text(
order.date + ' ' + order.time,
style: fontTextStyle(
9, Color(0XFF646566), FontWeight.w400),
),
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * .012,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
padding:
EdgeInsets.symmetric(horizontal: 4, vertical: 2),
decoration: BoxDecoration(
color: order.typeofwater.toString().toLowerCase() ==
'bore water'
? Color(0xFF8877DD)
: Color(0xFFCA86B0),
borderRadius: BorderRadius.circular(4),
border: Border.all(
width: 1,
color:
order.typeofwater.toString().toLowerCase() ==
'bore water'
? Color(0xFF8877DD)
: Color(0xFFCA86B0),
),
),
child: AutoSizeText(
capitalizeFirst(order.typeofwater),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: fontTextStyle(
12, Color(0xFFFFFFFF), FontWeight.w400),
),
),
Row(
children: [
Text(
'' +
AppSettings.formDouble(order.quotedAmount) +
'/',
style: fontTextStyle(
20, Color(0XFF515253), FontWeight.w600),
),
Text(
order.capacity,
style: fontTextStyle(
12, Color(0XFF2D2E30), FontWeight.w600),
)
],
),
],
),
Row(
children: [
GestureDetector(
onTap: statusTime == "Expired"
? null
: () {
showRejectOrdersDialog(order);
},
child: ColorFiltered(
colorFilter: statusTime == "Expired"
? ColorFilter.mode(
Color(0XFF9F9F9F), BlendMode.srcIn)
: ColorFilter.mode(
Colors.transparent, BlendMode.multiply),
child: Image.asset(
'images/wrong_button.png',
width: 44,
height: 44,
),
),
),
SizedBox(
width: MediaQuery.of(context).size.width * .012,
),
GestureDetector(
onTap: statusTime == "Expired"
? null
: () {
//showAcceptOrdersDialog(order);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OrderDetails(
supplierDetails: order,
),
),
);
},
child: ColorFiltered(
colorFilter: statusTime == "Expired"
? ColorFilter.mode(
Color(0XFF9F9F9F), BlendMode.srcIn)
: ColorFilter.mode(
Colors.transparent, BlendMode.multiply),
child: Image.asset(
'images/right_button.png',
width: 44,
height: 44,
),
),
),
],
)
],
)
],
)),
),
);
}
Widget acceptedOrdersCard(SupplierOrdersModel order) {
final orderDateTime = "${order.acceptedTime}".trim();
final statusTime = getOrderTimeOnly(orderDateTime);
// status badge color
Color statusColor = Color(0xFF1D7AFC);
if (statusTime == "Expired")
statusColor = Color(0xFF757575);
else if (statusTime == "New")
statusColor = Color(0XFF1D7AFC);
else if (statusTime.endsWith("m")) statusColor = Color(0XFFE56910);
return Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
color: Color(0XFFFFFFFF), // Same as Card color
borderRadius: BorderRadius.circular(12), // Rounded corners
border: Border.all(
color: Color(0XFF9F9F9F), // Border color
width: 0.5, // Border width
),
),
//color: Color(0XFFFFFFFF),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: order.supplierName != '',
child: Text(
order.supplierName,
style: fontTextStyle(
14, Color(0XFF343637), FontWeight.w600),
),
),
Visibility(
visible: order.date != '',
child: Text(
order.date + ' ' + order.time,
style: fontTextStyle(
9, Color(0XFF646566), FontWeight.w400),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: order.displayAddress != '',
child: Text(
order.displayAddress,
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400),
),
),
Row(
children: [
Image.asset(
'images/paid.png',
fit: BoxFit.cover,
width:
16, // Match the diameter of the CircleAvatar
height: 16,
),
SizedBox(
width:
MediaQuery.of(context).size.width *
.004,
),
Text(capitalizeFirst('Paid'), style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400)),
SizedBox(
width: MediaQuery.of(context).size.width * .012,
),
Text(
'' + AppSettings.formDouble(order.advancePaid),
style: fontTextStyle(
12,
Color(0XFF515253),
FontWeight.w400),
),
],
)
],
),
SizedBox(
height: MediaQuery.of(context).size.height * .004,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 2),
decoration: BoxDecoration(
color: order.typeofwater.toString().toLowerCase() == 'bore water'
? Color(0xFF8877DD)
: Color(0xFFCA86B0),
borderRadius: BorderRadius.circular(4),
border: Border.all(
width: 1,
color: order.typeofwater.toString().toLowerCase() == 'bore water'
? Color(0xFF8877DD)
: Color(0xFFCA86B0),
),
),
child: AutoSizeText(
capitalizeFirst(order.typeofwater),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: fontTextStyle(12, Color(0xFFFFFFFF), FontWeight.w400),
),
),
Row(
children: [
Image.asset(
'images/warning.png',
fit: BoxFit.cover,
width:
16, // Match the diameter of the CircleAvatar
height: 16,
),
SizedBox(
width:
MediaQuery.of(context).size.width *
.004,
),
Text(capitalizeFirst('Due'), style: fontTextStyle(12, Color(0XFF515253), FontWeight.w400)),
SizedBox(
width: MediaQuery.of(context).size.width * .012,
),
Text(
'' + AppSettings.formDouble(order.advancePaid),
style: fontTextStyle(
12,
Color(0XFF515253),
FontWeight.w400),
),
],
)
],
),
Row(
children: [
Text(
'' + AppSettings.formDouble(order.quotedAmount) + '/',
style: fontTextStyle(20, Color(0XFF515253), FontWeight.w600),
),
Text(
order.capacity,
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w600),
),
],
),
],
),
),
],
)
],
)),
),
);
}
Widget rejectedOrdersCard(SupplierOrdersModel order) {
final orderDateTime = "${order.acceptedTime}".trim();
final statusTime = getOrderTimeOnly(orderDateTime);
// status badge color
Color statusColor = Color(0xFF1D7AFC);
if (statusTime == "Expired")
statusColor = Color(0xFF757575);
else if (statusTime == "New")
statusColor = Color(0XFF1D7AFC);
else if (statusTime.endsWith("m")) statusColor = Color(0XFFE56910);
return Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
color: Color(0XFFFFFFFF), // Same as Card color
borderRadius: BorderRadius.circular(12), // Rounded corners
border: Border.all(
color: Color(0XFF9F9F9F), // Border color
width: 0.5, // Border width
),
),
//color: Color(0XFFFFFFFF),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: order.supplierName != '',
child: Text(
order.supplierName,
style: fontTextStyle(
14, Color(0XFF343637), FontWeight.w600),
),
),
Visibility(
visible: order.date != '',
child: Text(
order.date + ' ' + order.time,
style: fontTextStyle(
9, Color(0XFF646566), FontWeight.w400),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: order.displayAddress != '',
child: Text(
order.displayAddress,
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400),
),
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * .004,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 4, vertical: 2),
decoration: BoxDecoration(
color: order.typeofwater.toString().toLowerCase() == 'bore water'
? Color(0xFF8877DD)
: Color(0xFFCA86B0),
borderRadius: BorderRadius.circular(4),
border: Border.all(
width: 1,
color: order.typeofwater.toString().toLowerCase() == 'bore water'
? Color(0xFF8877DD)
: Color(0xFFCA86B0),
),
),
child: AutoSizeText(
capitalizeFirst(order.typeofwater),
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: fontTextStyle(12, Color(0xFFFFFFFF), FontWeight.w400),
),
),
],
),
Row(
children: [
Text(
'' + AppSettings.formDouble(order.quotedAmount) + '/',
style: fontTextStyle(20, Color(0XFF515253), FontWeight.w600),
),
Text(
order.capacity,
style: fontTextStyle(12, Color(0XFF2D2E30), FontWeight.w600),
),
],
),
],
),
),
],
)
],
)),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0XFFFFFFFF),
appBar:
AppSettings.supplierAppBarWithoutActions('Order Requests', context),
body: Center(
child: isSupplierOrdersDataLoading
? Center(
child: CircularProgressIndicator(
color: primaryColor,
strokeWidth: 5.0,
),
)
: supplierOrdersList.length != 0
? Column(
children: [
Expanded(
child: ListView(
children: [
// Accepted by User Orders
if (acceptedByUserOrders.isNotEmpty) ...[
Padding(
padding: EdgeInsets.all(10),
child: Text(
"ACCEPTED REQUESTS",
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400),
),
),
...acceptedByUserOrders
.map((order) => acceptedOrdersCard(order))
.toList(),
],
// Group acceptedOrders
if (acceptedOrders.isNotEmpty) ...[
// Active / New Orders
if (acceptedOrders.any((o) =>
getOrderTimeOnly(o.acceptedTime) !=
"Expired")) ...[
Padding(
padding: EdgeInsets.all(10),
child: Text(
"NEW REQUESTS",
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400),
),
),
...acceptedOrders
.where((o) =>
getOrderTimeOnly(o.acceptedTime) !=
"Expired")
.map((order) => orderCard(order))
.toList(),
],
// Expired Orders
if (acceptedOrders.any((o) =>
getOrderTimeOnly(o.acceptedTime) ==
"Expired")) ...[
Padding(
padding: EdgeInsets.all(10),
child: Text(
"EXPIRED REQUESTS",
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400),
),
),
...acceptedOrders
.where((o) =>
getOrderTimeOnly(o.acceptedTime) ==
"Expired")
.map((order) => orderCard(order))
.toList(),
],
],
//rejected orders]
if (rejectedOrders.isNotEmpty) ...[
Padding(
padding: EdgeInsets.all(10),
child: Text(
"REJECTED REQUESTS",
style: fontTextStyle(
10, Color(0XFF646566), FontWeight.w400),
),
),
...rejectedOrders
.map((order) => rejectedOrdersCard(order))
.toList(),
],
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height * .010,
),
],
)
: Center(
child: Text(
'No Data Available',
style:
fontTextStyle(12, Color(0XFF000000), FontWeight.w500),
),
),
),
);
}
}