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.
236 lines
7.2 KiB
236 lines
7.2 KiB
import 'dart:convert';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:supplier_new/common/settings.dart';
|
|
|
|
class CreateCreditAccountScreen extends StatefulWidget {
|
|
@override
|
|
_CreateCreditAccountScreenState createState() =>
|
|
_CreateCreditAccountScreenState();
|
|
}
|
|
|
|
class _CreateCreditAccountScreenState
|
|
extends State<CreateCreditAccountScreen> {
|
|
String? selectedCustomerId;
|
|
|
|
final creditLimitController = TextEditingController();
|
|
final openingBalanceController = TextEditingController();
|
|
|
|
bool isLoading = true;
|
|
|
|
List<Map<String, dynamic>> customers = [];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_fetchCustomers();
|
|
}
|
|
|
|
Future<void> _fetchCustomers() async {
|
|
try {
|
|
final response = await AppSettings.getAcceptedOrdersFromUsers();
|
|
final decoded = jsonDecode(response);
|
|
|
|
final List data = decoded["data"] ?? [];
|
|
|
|
/// Already having credit accounts
|
|
final existingCustomerIds = AppSettings.existingCreditCustomerIds;
|
|
|
|
/// 🔑 Track unique customers
|
|
final Set<String> seenCustomerIds = {};
|
|
final List<Map<String, dynamic>> filtered = [];
|
|
|
|
for (final e in data) {
|
|
final customerId = e["customerId"]?.toString();
|
|
|
|
if (customerId == null) continue;
|
|
|
|
// ❌ Skip if already has credit account
|
|
if (existingCustomerIds.contains(customerId)) continue;
|
|
|
|
// ❌ Skip duplicates
|
|
if (seenCustomerIds.contains(customerId)) continue;
|
|
|
|
seenCustomerIds.add(customerId);
|
|
|
|
filtered.add({
|
|
"customerId": customerId,
|
|
"name": e["customerName"] ?? "Unknown",
|
|
"date": e["createdAt"]?.toString().substring(0, 10) ?? "",
|
|
});
|
|
}
|
|
|
|
setState(() {
|
|
customers = filtered;
|
|
isLoading = false;
|
|
});
|
|
} catch (e) {
|
|
debugPrint("⚠️ Create account customer fetch error: $e");
|
|
setState(() => isLoading = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Create Credit Account'),
|
|
backgroundColor: Colors.white,
|
|
foregroundColor: Colors.black,
|
|
elevation: 1,
|
|
),
|
|
body: isLoading
|
|
? const Center(child: CircularProgressIndicator())
|
|
: Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: ListView(
|
|
children: [
|
|
/// SELECT CUSTOMER
|
|
const Text(
|
|
'SELECT CUSTOMER',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
const SizedBox(height: 12),
|
|
|
|
if (customers.isEmpty)
|
|
const Center(
|
|
child: Text(
|
|
"No eligible customers available",
|
|
style: TextStyle(color: Colors.grey),
|
|
),
|
|
),
|
|
|
|
...customers.map((customer) {
|
|
final isSelected =
|
|
selectedCustomerId == customer["customerId"];
|
|
|
|
return GestureDetector(
|
|
onTap: () {
|
|
setState(() {
|
|
selectedCustomerId = customer["customerId"];
|
|
});
|
|
},
|
|
child: Container(
|
|
margin: const EdgeInsets.only(bottom: 10),
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(
|
|
color:
|
|
isSelected ? Colors.black : Colors.grey.shade300,
|
|
width: 1.5,
|
|
),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
const CircleAvatar(
|
|
child: Icon(Icons.person),
|
|
),
|
|
const SizedBox(width: 10),
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
customer["name"],
|
|
style: const TextStyle(fontSize: 16),
|
|
),
|
|
Text(
|
|
customer["date"],
|
|
style:
|
|
const TextStyle(color: Colors.grey),
|
|
),
|
|
],
|
|
)
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
|
|
const SizedBox(height: 20),
|
|
|
|
/// ENTER DETAILS
|
|
const Text(
|
|
'ENTER DETAILS',
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
const SizedBox(height: 10),
|
|
|
|
TextField(
|
|
controller: creditLimitController,
|
|
keyboardType: TextInputType.number,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Credit Limit (₹) *',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 15),
|
|
|
|
TextField(
|
|
controller: openingBalanceController,
|
|
keyboardType: TextInputType.number,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Opening Balance (₹) *',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 10),
|
|
|
|
Row(
|
|
children: const [
|
|
Icon(Icons.info_outline,
|
|
color: Colors.orange, size: 18),
|
|
SizedBox(width: 8),
|
|
Expanded(
|
|
child: Text(
|
|
'Creating an account will notify the customer and request balance to start water delivery.',
|
|
style: TextStyle(fontSize: 13),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
|
|
const SizedBox(height: 20),
|
|
|
|
ElevatedButton(
|
|
onPressed: selectedCustomerId == null
|
|
? null
|
|
: () async{
|
|
final payload = {
|
|
"supplierId": AppSettings.supplierId,
|
|
"customerId": selectedCustomerId,
|
|
"advance_amount": double.tryParse(openingBalanceController.text) ?? 0,
|
|
"exceed_limit": double.tryParse(creditLimitController.text) ?? 0,
|
|
};
|
|
|
|
AppSettings.preLoaderDialog(context);
|
|
|
|
final success =
|
|
await AppSettings.createAdvanceRequest(payload);
|
|
|
|
Navigator.of(context, rootNavigator: true).pop();
|
|
|
|
if (success) {
|
|
AppSettings.longSuccessToast("Advance request sent successfully");
|
|
Navigator.pop(context, true);
|
|
} else {
|
|
AppSettings.longFailedToast("Failed to create account");
|
|
}
|
|
},
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: const Color(0xFF9375E8),
|
|
minimumSize: const Size(double.infinity, 50),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(30),
|
|
),
|
|
),
|
|
child: const Text('Create Account'),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|