Excel Mapping

This commit is contained in:
sanjeev.p 2026-04-03 15:45:40 +05:30
parent 9a6685382a
commit e65290cc7b
2 changed files with 87 additions and 32 deletions

View File

@ -923,7 +923,7 @@ class ApiService {
final roleTrimmed = role?.trim(); final roleTrimmed = role?.trim();
final fileIdTrimmed = fileId?.trim(); final fileIdTrimmed = fileId?.trim();
final endpoint = Uri.parse('${Env.apiUrl}grid'); final endpoint = Uri.parse('${Env.apiUrl}grid');
// final endpoint = Uri.parse('http://localhost/nhance_partner_be/grid');
final queryParameters = <String, String>{}; final queryParameters = <String, String>{};
if (roleTrimmed != null && roleTrimmed.isNotEmpty) { if (roleTrimmed != null && roleTrimmed.isNotEmpty) {
queryParameters['role'] = roleTrimmed; queryParameters['role'] = roleTrimmed;
@ -957,7 +957,7 @@ class ApiService {
} }
final endpoint = Uri.parse('${Env.apiUrl}grid/download'); final endpoint = Uri.parse('${Env.apiUrl}grid/download');
// final endpoint = Uri.parse('http://localhost/nhance_partner_be/grid/download');
final queryParameters = <String, String>{}; final queryParameters = <String, String>{};
void addQuery(String key, String? value) { void addQuery(String key, String? value) {
@ -1944,13 +1944,14 @@ class ApiService {
dynamic url; dynamic url;
print('fetchAGENTNameDropDown 1'); print('fetchAGENTNameDropDown 1');
// url = Uri.parse( url = Uri.parse(
// '${Env.apiUrl}invoice/getAgentUnusedCommissionList?manager_id=$id', '${Env.apiUrl}invoice/getAgentUnusedCommissionList?manager_id=$id',
// ); );
// url = Uri.parse( // url = Uri.parse(
// 'http://localhost/nhance_partner_be/invoice/getAgentUnusedCommissionList?manager_id=$id', // 'http://localhost/nhance_partner_be/invoice/getAgentUnusedCommissionList?manager_id=$id',
// ); // );
print('fetchAGENTNameDropDown 2'); print('fetchAGENTNameDropDown 2');
final headers = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
@ -2050,8 +2051,7 @@ class ApiService {
// --------------------------------- PayOut Module---------------------------------------------- // --------------------------------- PayOut Module----------------------------------------------
Future<Map<String, dynamic>> getCommissionRateList(data) async { Future<Map<String, dynamic>> getCommissionRateList(data) async {
print("getCommissionRateList------- $data}"); print("getCommissionRateList------- $data}");
// final url = Uri.parse('${Env.apiUrl}/invoice/commission-rate-list'); final url = Uri.parse('${Env.apiUrl}/invoice/commission-rate-list');
// final url = Uri.parse('http://localhost/nhance_partner_be/invoice/commission-rate-list');
print("getCommissionRateList 1"); print("getCommissionRateList 1");
// final token = await getToken(); // Fetch token // final token = await getToken(); // Fetch token
@ -2078,7 +2078,6 @@ class ApiService {
Future<Map<String, dynamic>> getCreateOrUpdate(data) async { Future<Map<String, dynamic>> getCreateOrUpdate(data) async {
final url = Uri.parse('${Env.apiUrl}invoice/create-or-update'); final url = Uri.parse('${Env.apiUrl}invoice/create-or-update');
// final url = Uri.parse('http://localhost/nhance_partner_be/invoice/create-or-update');
// final token = await getToken(); // Fetch token // final token = await getToken(); // Fetch token
@ -2122,7 +2121,6 @@ class ApiService {
} }
final url = Uri.parse('${Env.apiUrl}invoice/list'); final url = Uri.parse('${Env.apiUrl}invoice/list');
//final url = Uri.parse('http://localhost/nhance_partner_be/invoice/list');
final headers = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
@ -2188,7 +2186,6 @@ class ApiService {
} }
final url = Uri.parse('${Env.apiUrl}invoice/add-payment'); final url = Uri.parse('${Env.apiUrl}invoice/add-payment');
// final url = Uri.parse('http://localhost/nhance_partner_be/invoice/add-payment');
final headers = { final headers = {
'Authorization': 'Bearer $_token', 'Authorization': 'Bearer $_token',
@ -2206,7 +2203,6 @@ class ApiService {
} }
final url = Uri.parse('${Env.apiUrl}invoice/utrDetails?invoice_id=$invoiceId'); final url = Uri.parse('${Env.apiUrl}invoice/utrDetails?invoice_id=$invoiceId');
//final url = Uri.parse('http://localhost/nhance_partner_be/invoice/utrDetails?invoice_id=$invoiceId');
final headers = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
@ -2224,7 +2220,7 @@ class ApiService {
} }
final url = Uri.parse('${Env.apiUrl}invoice/updateUtrDetails'); final url = Uri.parse('${Env.apiUrl}invoice/updateUtrDetails');
// final url = Uri.parse('http://localhost/nhance_partner_be/invoice/updateUtrDetails');
final headers = { final headers = {
'Authorization': 'Bearer $_token', 'Authorization': 'Bearer $_token',
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -2242,9 +2238,6 @@ class ApiService {
final url = Uri.parse( final url = Uri.parse(
'${Env.apiUrl}invoice/add-payment-history?invoice_id=$invoiceId', '${Env.apiUrl}invoice/add-payment-history?invoice_id=$invoiceId',
); );
// final url = Uri.parse(
// 'http://localhost/nhance_partner_be/invoice/add-payment-history?invoice_id=$invoiceId',
// );
final headers = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
@ -2262,9 +2255,7 @@ class ApiService {
final url = Uri.parse( final url = Uri.parse(
'${Env.apiUrl}invoice/listUtrDetails?invoice_id=$invoiceId', '${Env.apiUrl}invoice/listUtrDetails?invoice_id=$invoiceId',
); );
// final url = Uri.parse(
// 'http://localhost/nhance_partner_be/invoice/listUtrDetails?invoice_id=$invoiceId',
// );
final headers = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
'app-signature': Env.App_Signature, 'app-signature': Env.App_Signature,
@ -2485,7 +2476,6 @@ class ApiService {
Future<Map<String, dynamic>> updatePolicyCommissionApi(data) async { Future<Map<String, dynamic>> updatePolicyCommissionApi(data) async {
final url = Uri.parse('${Env.apiUrl}policy/updatePolicyCommission'); final url = Uri.parse('${Env.apiUrl}policy/updatePolicyCommission');
//final url = Uri.parse('http://localhost/nhance_partner_be/policy/updatePolicyCommission');
if (_token == null) { if (_token == null) {
throw Exception('Token not found. Please log in.'); throw Exception('Token not found. Please log in.');

View File

@ -614,11 +614,19 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
} }
String _normalizePolicyNo(dynamic value) { String _normalizePolicyNo(dynamic value) {
return (value ?? '') var text = (value ?? '').toString().trim();
.toString() if (text.isEmpty) return '';
.trim()
.toLowerCase() // Remove common Excel text-protection wrappers around policy number.
.replaceAll(RegExp(r'\s+'), ''); text = text.replaceAll(RegExp(r"^[`']+"), '').replaceAll(RegExp(r"[`']+$"), '');
// Excel often turns large integer-looking values into "12345.0".
final trailingPointZero = RegExp(r'^(\d+)\.0+$').firstMatch(text);
if (trailingPointZero != null) {
text = trailingPointZero.group(1) ?? text;
}
return text.toLowerCase().replaceAll(RegExp(r'\s+'), '');
} }
String _displayText(dynamic value) { String _displayText(dynamic value) {
@ -638,6 +646,37 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
return double.tryParse(cleaned); return double.tryParse(cleaned);
} }
PlatformFile? _buildSanitizedCommissionUploadFile(
List<Map<String, String>> rows,
) {
if (rows.isEmpty) return null;
final excelOut = Excel.createExcel();
final defaultSheet = excelOut.getDefaultSheet();
final sheet = excelOut[defaultSheet ?? 'Sheet1'];
sheet.appendRow([
TextCellValue('Agent Code'),
TextCellValue('Policy Number'),
TextCellValue('Payout Amount'),
]);
for (final row in rows) {
sheet.appendRow([
TextCellValue((row['agent_code'] ?? '').trim()),
TextCellValue((row['policy_no'] ?? '').trim()),
TextCellValue((row['payout_amount'] ?? '').trim()),
]);
}
final bytes = excelOut.encode();
if (bytes == null || bytes.isEmpty) return null;
return PlatformFile(
name: 'policy_commission_upload_cleaned.xlsx',
size: bytes.length,
bytes: Uint8List.fromList(bytes),
);
}
List<Map<String, dynamic>> _buildUtrPayloadForSelectedPolicies({ List<Map<String, dynamic>> _buildUtrPayloadForSelectedPolicies({
required String defaultUtrDate, required String defaultUtrDate,
}) { }) {
@ -910,19 +949,36 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
return; return;
} }
int headerRowIndex = -1;
int policyNoCol = -1; int policyNoCol = -1;
int commissionCol = -1; int commissionCol = -1;
int agentCodeCol = -1; int agentCodeCol = -1;
for (int i = 0; i < rows.first.length; i++) { final int headerScanLimit = rows.length < 5 ? rows.length : 5;
final normalized = _normalizeHeader(_excelCellValue(rows.first[i])); for (int r = 0; r < headerScanLimit; r++) {
if (normalized == 'policynumber') policyNoCol = i; int pCol = -1;
if (normalized == 'payoutamount' || normalized == 'commissionamount') commissionCol = i; int cCol = -1;
if (normalized == 'agentcode') agentCodeCol = i; int aCol = -1;
final currentRow = rows[r];
for (int i = 0; i < currentRow.length; i++) {
final normalized = _normalizeHeader(_excelCellValue(currentRow[i]));
if (normalized == 'policynumber') pCol = i;
if (normalized == 'payoutamount' || normalized == 'commissionamount') {
cCol = i;
}
if (normalized == 'agentcode') aCol = i;
}
if (pCol != -1 && cCol != -1) {
headerRowIndex = r;
policyNoCol = pCol;
commissionCol = cCol;
agentCodeCol = aCol;
break;
}
} }
if (policyNoCol == -1 || commissionCol == -1) { if (policyNoCol == -1 || commissionCol == -1) {
ToastHelper.showWarningToast( ToastHelper.showWarningToast(
context, context,
'Excel is missing required columns: Policy Number and Payout Amount.', 'Excel header not found. Required columns: Policy Number and Payout Amount.',
); );
return; return;
} }
@ -930,8 +986,9 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
final Map<String, double> uploadMap = {}; final Map<String, double> uploadMap = {};
final Map<String, String> uploadPolicyDisplay = {}; final Map<String, String> uploadPolicyDisplay = {};
final Map<String, String> uploadAgentCodeMap = {}; final Map<String, String> uploadAgentCodeMap = {};
final List<Map<String, String>> sanitizedRowsForUpload = [];
int invalidRows = 0; int invalidRows = 0;
for (int rowIndex = 1; rowIndex < rows.length; rowIndex++) { for (int rowIndex = headerRowIndex + 1; rowIndex < rows.length; rowIndex++) {
final row = rows[rowIndex]; final row = rows[rowIndex];
final policyRaw = row.length > policyNoCol ? _excelCellValue(row[policyNoCol]) : ''; final policyRaw = row.length > policyNoCol ? _excelCellValue(row[policyNoCol]) : '';
final commissionRaw = row.length > commissionCol ? _excelCellValue(row[commissionCol]) : ''; final commissionRaw = row.length > commissionCol ? _excelCellValue(row[commissionCol]) : '';
@ -954,6 +1011,11 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
if (agentCodeRaw.trim().isNotEmpty) { if (agentCodeRaw.trim().isNotEmpty) {
uploadAgentCodeMap[normalizedPolicy] = agentCodeRaw.trim().toUpperCase(); uploadAgentCodeMap[normalizedPolicy] = agentCodeRaw.trim().toUpperCase();
} }
sanitizedRowsForUpload.add({
'agent_code': agentCodeRaw.trim().toUpperCase(),
'policy_no': policyRaw.trim(),
'payout_amount': parsedCommission.toStringAsFixed(2),
});
} }
if (uploadMap.isEmpty) { if (uploadMap.isEmpty) {
@ -1027,9 +1089,12 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
} }
} }
final sanitizedUploadFile = _buildSanitizedCommissionUploadFile(
sanitizedRowsForUpload,
);
final response = await apiService.uploadPolicyCommissionExcel( final response = await apiService.uploadPolicyCommissionExcel(
id: selectedAgentId!.first, id: selectedAgentId!.first,
file: selectedFile, file: sanitizedUploadFile ?? selectedFile,
proceedPartnerMismatch: partnerMismatchCount > 0, proceedPartnerMismatch: partnerMismatchCount > 0,
); );
if (response['status'] != 'success' && response['status'] != 200) { if (response['status'] != 'success' && response['status'] != 200) {