|
|
import 'dart:convert';
|
|
|
|
|
|
import 'package:auto_size_text/auto_size_text.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:intl/intl.dart';
|
|
|
|
|
|
import '../../common/settings.dart';
|
|
|
import '../paln_requests_model.dart';
|
|
|
|
|
|
class PlanRequestsScreen extends StatefulWidget {
|
|
|
const PlanRequestsScreen({super.key});
|
|
|
|
|
|
@override
|
|
|
State<PlanRequestsScreen> createState() => _PlanRequestsScreenState();
|
|
|
}
|
|
|
|
|
|
class _PlanRequestsScreenState extends State<PlanRequestsScreen> {
|
|
|
|
|
|
bool isPlanRequestsDataLoading = false;
|
|
|
|
|
|
List<PlanRequestModel> planRequestsList = [];
|
|
|
List<PlanRequestModel> acceptedPlans = [];
|
|
|
List<PlanRequestModel> rejectedPlans = [];
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
|
super.initState();
|
|
|
getAcceptedPlansFromSupplier();
|
|
|
}
|
|
|
|
|
|
/// API CALL
|
|
|
Future<void> getAcceptedPlansFromSupplier() async {
|
|
|
|
|
|
isPlanRequestsDataLoading = true;
|
|
|
|
|
|
var response = await AppSettings.getAcceptedPlansFromSupplier();
|
|
|
var json = jsonDecode(response);
|
|
|
|
|
|
setState(() {
|
|
|
|
|
|
planRequestsList = (json['data'] as List)
|
|
|
.map((model) => PlanRequestModel.fromJson(model))
|
|
|
.toList();
|
|
|
|
|
|
groupPlansByStatus();
|
|
|
|
|
|
isPlanRequestsDataLoading = false;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// GROUP DATA
|
|
|
void groupPlansByStatus() {
|
|
|
|
|
|
acceptedPlans = planRequestsList
|
|
|
.where((plan) => plan.status.toLowerCase() == "accepted")
|
|
|
.toList();
|
|
|
|
|
|
rejectedPlans = planRequestsList
|
|
|
.where((plan) => plan.status.toLowerCase() == "rejected")
|
|
|
.toList();
|
|
|
}
|
|
|
|
|
|
/// TIME BADGE
|
|
|
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 "";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// PLAN CARD
|
|
|
Widget planCard(PlanRequestModel plan) {
|
|
|
|
|
|
final statusTime = getOrderTimeOnly(plan.acceptedTime);
|
|
|
|
|
|
Color statusColor = Color(0xFF1D7AFC);
|
|
|
|
|
|
if (statusTime == "Expired") {
|
|
|
statusColor = Color(0xFF757575);
|
|
|
}
|
|
|
|
|
|
int totalOrders = plan.dates.length;
|
|
|
|
|
|
double biddingPrice =
|
|
|
double.tryParse(plan.biddingPrice) ?? 0;
|
|
|
|
|
|
double totalAmount = totalOrders * biddingPrice;
|
|
|
|
|
|
return Padding(
|
|
|
padding: EdgeInsets.all(10),
|
|
|
child: Container(
|
|
|
decoration: BoxDecoration(
|
|
|
color: Colors.white,
|
|
|
borderRadius: BorderRadius.circular(12),
|
|
|
border: Border.all(color: Color(0XFF1D7AFC)),
|
|
|
),
|
|
|
child: Padding(
|
|
|
padding: EdgeInsets.all(14),
|
|
|
child: Column(
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: [
|
|
|
|
|
|
/// SUPPLIER + BADGE
|
|
|
Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
children: [
|
|
|
|
|
|
Text(
|
|
|
plan.supplierName,
|
|
|
style: fontTextStyle(
|
|
|
14, Color(0XFF343637), FontWeight.w600),
|
|
|
),
|
|
|
|
|
|
if (statusTime.isNotEmpty)
|
|
|
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),
|
|
|
),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 6),
|
|
|
|
|
|
/// ADDRESS
|
|
|
Text(
|
|
|
plan.displayAddress,
|
|
|
style: fontTextStyle(
|
|
|
10, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 4),
|
|
|
|
|
|
/// DATE RANGE
|
|
|
Text(
|
|
|
"${plan.startDate} to ${plan.endDate}",
|
|
|
style: fontTextStyle(
|
|
|
10, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 12),
|
|
|
|
|
|
/// WATER TYPE
|
|
|
Container(
|
|
|
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 3),
|
|
|
decoration: BoxDecoration(
|
|
|
color: plan.typeofwater.toLowerCase() == "bore water"
|
|
|
? Color(0xFF8877DD)
|
|
|
: Color(0xFFCA86B0),
|
|
|
borderRadius: BorderRadius.circular(4),
|
|
|
),
|
|
|
child: AutoSizeText(
|
|
|
capitalizeFirst(plan.typeofwater),
|
|
|
style: fontTextStyle(
|
|
|
12, Colors.white, FontWeight.w400),
|
|
|
),
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 8),
|
|
|
|
|
|
/// ACTUAL PRICE
|
|
|
Row(
|
|
|
children: [
|
|
|
Text(
|
|
|
"Actual Price: ",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
Text(
|
|
|
"₹${AppSettings.formDouble(plan.quotedAmount)}/${plan.capacity}",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF515253), FontWeight.w600),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
|
|
|
/// BIDDING PRICE
|
|
|
Row(
|
|
|
children: [
|
|
|
Text(
|
|
|
"Bidding Price: ",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
Text(
|
|
|
"₹${AppSettings.formDouble(plan.biddingPrice)}/${plan.capacity}",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF515253), FontWeight.w600),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
|
|
|
/// FREQUENCY
|
|
|
Row(
|
|
|
children: [
|
|
|
Text(
|
|
|
"Frequency: ",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
Text(
|
|
|
"${plan.frequency}/week",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF2D2E30), FontWeight.w600),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 10),
|
|
|
|
|
|
/// PAYMENT TYPE
|
|
|
Row(
|
|
|
children: [
|
|
|
Text(
|
|
|
"Payment Type: ",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
Text(
|
|
|
plan.paymentType,
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF515253), FontWeight.w600),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
|
|
|
/// ADVANCE / CREDIT
|
|
|
if (plan.paymentType != "after_delivery")
|
|
|
Row(
|
|
|
children: [
|
|
|
Text(
|
|
|
plan.paymentType == "credit"
|
|
|
? "Credit Limit: "
|
|
|
: "Advance Amount: ",
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
Text(
|
|
|
plan.advanceAmount,
|
|
|
style: fontTextStyle(
|
|
|
12, Color(0XFF515253), FontWeight.w600),
|
|
|
)
|
|
|
],
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 10),
|
|
|
|
|
|
/// TOTAL PLAN AMOUNT
|
|
|
Text.rich(
|
|
|
TextSpan(
|
|
|
children: [
|
|
|
TextSpan(
|
|
|
text: "Total amount for this plan orders ",
|
|
|
style: fontTextStyle(
|
|
|
12,
|
|
|
Color(0xFF939495),
|
|
|
FontWeight.w400,
|
|
|
),
|
|
|
),
|
|
|
TextSpan(
|
|
|
text:
|
|
|
"$totalOrders × ${biddingPrice.toStringAsFixed(0)} = ₹${totalAmount.toStringAsFixed(0)}",
|
|
|
style: fontTextStyle(
|
|
|
12,
|
|
|
Color(0xFF515253),
|
|
|
FontWeight.w500,
|
|
|
),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
/// UI
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
|
return Scaffold(
|
|
|
backgroundColor: Colors.white,
|
|
|
|
|
|
appBar: AppSettings.supplierAppBarWithoutActions(
|
|
|
"Plan Requests", context),
|
|
|
|
|
|
body: isPlanRequestsDataLoading
|
|
|
? Center(
|
|
|
child: CircularProgressIndicator(
|
|
|
color: primaryColor,
|
|
|
strokeWidth: 5,
|
|
|
))
|
|
|
: planRequestsList.isEmpty
|
|
|
? Center(
|
|
|
child: Text(
|
|
|
"No Data Available",
|
|
|
style: fontTextStyle(
|
|
|
12, Colors.black, FontWeight.w500),
|
|
|
),
|
|
|
)
|
|
|
: ListView(
|
|
|
children: [
|
|
|
|
|
|
/// NEW REQUESTS
|
|
|
Padding(
|
|
|
padding: EdgeInsets.all(10),
|
|
|
child: Text(
|
|
|
"PLAN REQUESTS",
|
|
|
style: fontTextStyle(
|
|
|
10, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
),
|
|
|
|
|
|
...acceptedPlans
|
|
|
.map((plan) => planCard(plan))
|
|
|
.toList(),
|
|
|
|
|
|
/// REJECTED
|
|
|
if (rejectedPlans.isNotEmpty) ...[
|
|
|
|
|
|
Padding(
|
|
|
padding: EdgeInsets.all(10),
|
|
|
child: Text(
|
|
|
"REJECTED REQUESTS",
|
|
|
style: fontTextStyle(
|
|
|
10, Color(0XFF646566), FontWeight.w400),
|
|
|
),
|
|
|
),
|
|
|
|
|
|
...rejectedPlans
|
|
|
.map((plan) => planCard(plan))
|
|
|
.toList()
|
|
|
]
|
|
|
],
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
} |