|
|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:intl/intl.dart';
|
|
|
|
|
import 'package:bookatanker/common/settings.dart';
|
|
|
|
|
import 'package:bookatanker/supplier/paymnets/top_up_page.dart';
|
|
|
|
|
|
|
|
|
|
class CreditAccountsDetails extends StatefulWidget {
|
|
|
|
|
var details;
|
|
|
|
|
CreditAccountsDetails({this.details});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<CreditAccountsDetails> createState() => _CreditAccountsDetailsState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _CreditAccountsDetailsState extends State<CreditAccountsDetails> {
|
|
|
|
|
List<Map<String, dynamic>> transactions = [];
|
|
|
|
|
bool isLoading = true;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
fetchTransactions();
|
|
|
|
|
super.initState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> fetchTransactions() async {
|
|
|
|
|
try {
|
|
|
|
|
final supplierId = widget.details.supplierId;
|
|
|
|
|
final customerId = AppSettings.customerId;
|
|
|
|
|
|
|
|
|
|
final response = await AppSettings.getAdvanceTransactionsBySupplierAndCustomer(
|
|
|
|
|
supplierId,
|
|
|
|
|
customerId,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final decoded = jsonDecode(response);
|
|
|
|
|
final List data = decoded["data"] ?? [];
|
|
|
|
|
|
|
|
|
|
setState(() {
|
|
|
|
|
transactions = data.map<Map<String, dynamic>>((e) {
|
|
|
|
|
final amount = (e["advance_amount"] ?? 0).toDouble();
|
|
|
|
|
final status = (e["status"] ?? "").toString().toLowerCase();
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
"title": status == "completed" ? "Advance Received" : "Water Delivery",
|
|
|
|
|
"subtitle": e["payment_type"] ?? "",
|
|
|
|
|
"amount": status == "completed" ? amount : -amount,
|
|
|
|
|
"date": DateFormat("dd MMM, yyyy").format(
|
|
|
|
|
DateTime.parse(e["date_of_transaction"]),
|
|
|
|
|
),
|
|
|
|
|
};
|
|
|
|
|
}).toList();
|
|
|
|
|
|
|
|
|
|
isLoading = false;
|
|
|
|
|
});
|
|
|
|
|
} catch (e) {
|
|
|
|
|
setState(() => isLoading = false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Scaffold(
|
|
|
|
|
backgroundColor: const Color(0XFFFFFFFF),
|
|
|
|
|
appBar: AppSettings.supplierAppBarWithoutActions(widget.details.name, context),
|
|
|
|
|
body: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
// Header
|
|
|
|
|
Container(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
padding: const EdgeInsets.all(20),
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
gradient: LinearGradient(
|
|
|
|
|
colors: [
|
|
|
|
|
widget.details.balance < 0 ? const Color(0XFFFADEDE) : const Color(0XFFC3DEC2),
|
|
|
|
|
const Color(0XFFFFFFFF)
|
|
|
|
|
],
|
|
|
|
|
begin: Alignment.topLeft,
|
|
|
|
|
end: Alignment.bottomRight,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
widget.details.name,
|
|
|
|
|
style: fontTextStyle(16, const Color(0XFF3B3B3B), FontWeight.w600),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 4),
|
|
|
|
|
Text(
|
|
|
|
|
"Credit Account",
|
|
|
|
|
style: fontTextStyle(12, const Color(0XFF3B3B3B), FontWeight.w500),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 12),
|
|
|
|
|
Text(
|
|
|
|
|
"Available Balance",
|
|
|
|
|
style: fontTextStyle(
|
|
|
|
|
12,
|
|
|
|
|
widget.details.balance < 0 ? const Color(0XFFE2483D) : const Color(0XFF0A9E04),
|
|
|
|
|
FontWeight.w500,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 6),
|
|
|
|
|
Text(
|
|
|
|
|
"+₹${AppSettings.formDouble(widget.details.balance.toStringAsFixed(2))}",
|
|
|
|
|
style: fontTextStyle(
|
|
|
|
|
36,
|
|
|
|
|
widget.details.balance < 0 ? const Color(0XFFE2483D) : const Color(0XFF0A9E04),
|
|
|
|
|
FontWeight.w700,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.all(0),
|
|
|
|
|
child: Row(
|
|
|
|
|
children: [
|
|
|
|
|
// ✅ TopUp navigation + reload after payment
|
|
|
|
|
Expanded(
|
|
|
|
|
child: GestureDetector(
|
|
|
|
|
onTap: () async {
|
|
|
|
|
final result = await Navigator.push(
|
|
|
|
|
context,
|
|
|
|
|
MaterialPageRoute(
|
|
|
|
|
builder: (_) => CreditTopUpConfirmScreen(
|
|
|
|
|
supplierName: widget.details.name,
|
|
|
|
|
supplierId: widget.details.supplierId,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (result == true) {
|
|
|
|
|
// 🔥 Reload transactions + you can also re-fetch balance from your profile API if needed
|
|
|
|
|
fetchTransactions();
|
|
|
|
|
setState(() {}); // keep safe
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
child: _actionButton(
|
|
|
|
|
'images/plus_credit_account.png',
|
|
|
|
|
"Top Up",
|
|
|
|
|
const Color(0XFF8270DB),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
if (widget.details.balance > 0) ...[
|
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
|
Expanded(child: _actionButton('images/request_credit_account.png', "Request", const Color(0XFF8270DB))),
|
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
|
Expanded(child: _actionButton('images/cross_credit_account.png', "Close", const Color(0XFFE2483D))),
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
Visibility(
|
|
|
|
|
visible: widget.details.balance < 0,
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
|
|
|
|
|
child: Text(
|
|
|
|
|
'Dues',
|
|
|
|
|
style: fontTextStyle(16, const Color(0XFF3B3B3B), FontWeight.w600),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.all(16),
|
|
|
|
|
child: Container(
|
|
|
|
|
padding: const EdgeInsets.all(16),
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: const Color(0xFF1D7AFC),
|
|
|
|
|
borderRadius: BorderRadius.circular(12),
|
|
|
|
|
),
|
|
|
|
|
child: Row(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Container(
|
|
|
|
|
width: 32,
|
|
|
|
|
height: 32,
|
|
|
|
|
decoration: const BoxDecoration(
|
|
|
|
|
shape: BoxShape.circle,
|
|
|
|
|
color: Color(0xFF1968D6),
|
|
|
|
|
),
|
|
|
|
|
child: Center(
|
|
|
|
|
child: Image.asset('images/truck-payments.png', width: 20, height: 20),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 8),
|
|
|
|
|
Text("Payment due", style: fontTextStyle(12, const Color(0xFFFFFFFF), FontWeight.w500)),
|
|
|
|
|
const SizedBox(height: 4),
|
|
|
|
|
Text(
|
|
|
|
|
"Due Today, ${DateFormat("MMM d, y").format(DateTime.now())}",
|
|
|
|
|
style: fontTextStyle(10, const Color(0xFFFFFFFF), FontWeight.w400),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
"₹ ${AppSettings.formDouble(widget.details.balance.abs().toStringAsFixed(2))}",
|
|
|
|
|
style: fontTextStyle(16, const Color(0xFFFFFFFF), FontWeight.w500),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 30),
|
|
|
|
|
Container(
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: const Color(0xFF36AF31),
|
|
|
|
|
borderRadius: BorderRadius.circular(12),
|
|
|
|
|
),
|
|
|
|
|
child: Text("Pay now", style: fontTextStyle(10, const Color(0xFFFFFFFF), FontWeight.w600)),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
Padding(
|
|
|
|
|
padding: EdgeInsets.fromLTRB(16, widget.details.balance < 0 ? 0 : 16, 16, 0),
|
|
|
|
|
child: Text('Transactions', style: fontTextStyle(16, const Color(0XFF3B3B3B), FontWeight.w600)),
|
|
|
|
|
),
|
|
|
|
|
SizedBox(height: MediaQuery.of(context).size.width * .012),
|
|
|
|
|
|
|
|
|
|
Expanded(
|
|
|
|
|
child: isLoading
|
|
|
|
|
? const Center(child: CircularProgressIndicator())
|
|
|
|
|
: ListView.separated(
|
|
|
|
|
itemCount: transactions.length,
|
|
|
|
|
separatorBuilder: (_, __) => const Divider(color: Color(0xFFE0E0E0)),
|
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
|
final t = transactions[index];
|
|
|
|
|
final double amount = (t["amount"] as num).toDouble();
|
|
|
|
|
final bool isCredit = amount > 0;
|
|
|
|
|
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: const EdgeInsets.all(12),
|
|
|
|
|
child: Row(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Text(t["title"].toString(), style: fontTextStyle(12, const Color(0XFF000000), FontWeight.w400)),
|
|
|
|
|
if (t["subtitle"].toString().isNotEmpty)
|
|
|
|
|
Text(t["subtitle"].toString(),
|
|
|
|
|
style: fontTextStyle(10, const Color(0XFF114690), FontWeight.w400)),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
|
|
children: [
|
|
|
|
|
Text(
|
|
|
|
|
"${isCredit ? '+' : ''}₹${amount.abs().toStringAsFixed(2)}",
|
|
|
|
|
style: fontTextStyle(
|
|
|
|
|
12,
|
|
|
|
|
isCredit ? const Color(0XFF0A9E04) : const Color(0XFFE2483D),
|
|
|
|
|
FontWeight.w500,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Text(t["date"].toString(), style: fontTextStyle(10, const Color(0XFF757575), FontWeight.w400)),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _actionButton(String path, String label, Color color) {
|
|
|
|
|
return Container(
|
|
|
|
|
height: 80,
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
border: Border.all(color: Colors.grey.shade300),
|
|
|
|
|
),
|
|
|
|
|
child: Center(
|
|
|
|
|
child: Column(
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
children: [
|
|
|
|
|
Image.asset(path, width: 24, height: 24, color: color),
|
|
|
|
|
const SizedBox(height: 6),
|
|
|
|
|
Text(label, style: fontTextStyle(14, const Color(0XFF2A2A2A), FontWeight.w400)),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|