bug fix
This commit is contained in:
parent
7ce3e95b17
commit
863c08b918
@ -55,6 +55,54 @@ class _NhanceTopBarState extends State<NhanceTopBar> {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, dynamic>? _decodeBranchToken(String token) {
|
||||
try {
|
||||
final parts = token.split('.');
|
||||
if (parts.length != 3) return null;
|
||||
|
||||
final payload = base64Url.normalize(parts[1]);
|
||||
final decoded = utf8.decode(base64Url.decode(payload));
|
||||
final parsed = json.decode(decoded);
|
||||
if (parsed is Map<String, dynamic>) return parsed;
|
||||
if (parsed is Map) return Map<String, dynamic>.from(parsed);
|
||||
return null;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Read post/pre client + branch ids from selected branch JWT payload.
|
||||
Map<String, String>? _clientDetailsParamsFromBranch(
|
||||
Map<String, dynamic> branch,
|
||||
) {
|
||||
final token = branch['token']?.toString() ??
|
||||
tokenStorage.getCurrentToken() ??
|
||||
'';
|
||||
if (token.isEmpty) return null;
|
||||
|
||||
final decoded = _decodeBranchToken(token);
|
||||
if (decoded == null) return null;
|
||||
|
||||
final postClientId = decoded['post_client_id']?.toString().trim() ?? '';
|
||||
final postBranchId = decoded['post_branch_id']?.toString().trim() ?? '';
|
||||
final preClientId = decoded['pre_client_id']?.toString().trim() ?? '';
|
||||
final preBranchId = decoded['pre_branch_id']?.toString().trim() ?? '';
|
||||
|
||||
if (postClientId.isEmpty &&
|
||||
postBranchId.isEmpty &&
|
||||
preClientId.isEmpty &&
|
||||
preBranchId.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
'post_client_id': postClientId,
|
||||
'post_branch_id': postBranchId,
|
||||
'pre_client_id': preClientId,
|
||||
'pre_branch_id': preBranchId,
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> _loadBranchLogos() async {
|
||||
final uniqueBranches = <String, Map<String, dynamic>>{};
|
||||
for (final branch in branches) {
|
||||
@ -89,23 +137,11 @@ class _NhanceTopBarState extends State<NhanceTopBar> {
|
||||
'';
|
||||
if (token.isEmpty) return null;
|
||||
|
||||
final clientId = branch['client_id']?.toString() ?? '';
|
||||
final branchId = branch['client_branch_id']?.toString() ?? '';
|
||||
final preBranchId = branch['pre_branch_id']?.toString() ?? branchId;
|
||||
if (clientId.isEmpty || branchId.isEmpty) return null;
|
||||
final params = _clientDetailsParamsFromBranch(branch);
|
||||
if (params == null) return null;
|
||||
|
||||
final isPre = branch['enrollment_type']?.toString() == 'pre';
|
||||
final postClientId = isPre ? '' : clientId;
|
||||
final postBranchId = isPre ? '' : branchId;
|
||||
final preClientId = isPre ? clientId : clientId;
|
||||
final preBranch = isPre ? branchId : preBranchId;
|
||||
|
||||
final url = Uri.parse(
|
||||
'${Environment.apiUrl}getClientDetails'
|
||||
'?post_client_id=$postClientId'
|
||||
'&post_branch_id=$postBranchId'
|
||||
'&pre_client_id=$preClientId'
|
||||
'&pre_branch_id=$preBranch',
|
||||
final url = Uri.parse('${Environment.apiUrl}getClientDetails').replace(
|
||||
queryParameters: params,
|
||||
);
|
||||
|
||||
final response = await http.get(
|
||||
|
||||
@ -141,15 +141,23 @@ class _ClaimsOverviewDashboardState extends State<ClaimsOverviewDashboard>
|
||||
|
||||
Future<void> _logHrActivity(String activity) async {
|
||||
try {
|
||||
final postId = await _tokenService.readValue('empHrId');
|
||||
final preId = await _tokenService.readValue('enrollmentEmpPrimaryId');
|
||||
final token = await _tokenService.getCurrentToken();
|
||||
if (token == null || token.isEmpty) return;
|
||||
|
||||
var postId = await _tokenService.readValue('empHrId');
|
||||
var preId = await _tokenService.readValue('enrollmentEmpPrimaryId');
|
||||
if (postId == null ||
|
||||
postId.isEmpty ||
|
||||
preId == null ||
|
||||
preId.isEmpty ||
|
||||
token == null ||
|
||||
token.isEmpty) {
|
||||
preId.isEmpty) {
|
||||
final decoded = _tokenService.getDecodedToken();
|
||||
postId ??= decoded?['post_hr_id']?.toString();
|
||||
preId ??= decoded?['pre_hr_id']?.toString();
|
||||
}
|
||||
if (postId == null ||
|
||||
postId.isEmpty ||
|
||||
preId == null ||
|
||||
preId.isEmpty) {
|
||||
return;
|
||||
}
|
||||
await _apiService.getPostLogHrActivity(postId, preId, token, activity);
|
||||
|
||||
@ -20,6 +20,7 @@ class ReminderEmailTemplateDialog extends StatefulWidget {
|
||||
final String defaultHtmlBody;
|
||||
final ReminderEmailTemplateMode mode;
|
||||
final Future<void> Function(String subject, String htmlBody)? onSend;
|
||||
final bool embedded;
|
||||
|
||||
const ReminderEmailTemplateDialog({
|
||||
super.key,
|
||||
@ -32,6 +33,7 @@ class ReminderEmailTemplateDialog extends StatefulWidget {
|
||||
required this.defaultHtmlBody,
|
||||
this.mode = ReminderEmailTemplateMode.config,
|
||||
this.onSend,
|
||||
this.embedded = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -460,10 +462,147 @@ class _ReminderEmailTemplateDialogState extends State<ReminderEmailTemplateDialo
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget _buildTemplateContent() {
|
||||
final primaryLabel =
|
||||
widget.mode == ReminderEmailTemplateMode.send ? 'Send' : 'Submit';
|
||||
|
||||
if (_isLoading) {
|
||||
return const Center(child: CircularProgressIndicator(color: _teal));
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, widget.embedded ? 12 : 16, 12, 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'Template Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _templateNameController,
|
||||
style: GoogleFonts.poppins(fontSize: 14),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF5F5F5),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!widget.embedded)
|
||||
IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: const Icon(Icons.close, size: 20),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Subject',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _subjectController,
|
||||
style: GoogleFonts.poppins(fontSize: 14),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF5F5F5),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_placeholdersMenu(),
|
||||
const SizedBox(width: 8),
|
||||
_webPointerGuard(
|
||||
child: _tealButton(
|
||||
label: 'Preview Mail',
|
||||
onPressed: () => _showPreviewMail(),
|
||||
width: 120,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: _buildEditorArea()),
|
||||
const Divider(height: 1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 12, 20, 16),
|
||||
child: Row(
|
||||
children: [
|
||||
_webPointerGuard(
|
||||
child: TextButton.icon(
|
||||
onPressed: () => _toggleHtmlEditMode(),
|
||||
icon: Icon(
|
||||
Icons.code,
|
||||
size: 16,
|
||||
color: _isHtmlEditMode ? _teal : Colors.black54,
|
||||
),
|
||||
label: Text(
|
||||
_isHtmlEditMode ? 'Visual Editor' : 'Dev HTML',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: _isHtmlEditMode ? _teal : Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
_webPointerGuard(
|
||||
child: _tealButton(
|
||||
label: primaryLabel,
|
||||
onPressed: _submit,
|
||||
loading: _isSubmitting,
|
||||
width: 120,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.embedded) {
|
||||
return _buildTemplateContent();
|
||||
}
|
||||
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
|
||||
return Dialog(
|
||||
@ -473,132 +612,7 @@ class _ReminderEmailTemplateDialogState extends State<ReminderEmailTemplateDialo
|
||||
child: SizedBox(
|
||||
width: size.width * 0.95,
|
||||
height: size.height * 0.92,
|
||||
child: _isLoading
|
||||
? const Center(child: CircularProgressIndicator(color: _teal))
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 16, 12, 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'Template Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _templateNameController,
|
||||
style: GoogleFonts.poppins(fontSize: 14),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF5F5F5),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: const Icon(Icons.close, size: 20),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Subject',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _subjectController,
|
||||
style: GoogleFonts.poppins(fontSize: 14),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF5F5F5),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_placeholdersMenu(),
|
||||
const SizedBox(width: 8),
|
||||
_webPointerGuard(
|
||||
child: _tealButton(
|
||||
label: 'Preview Mail',
|
||||
onPressed: () => _showPreviewMail(),
|
||||
width: 120,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: _buildEditorArea()),
|
||||
const Divider(height: 1),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 12, 20, 16),
|
||||
child: Row(
|
||||
children: [
|
||||
_webPointerGuard(
|
||||
child: TextButton.icon(
|
||||
onPressed: () => _toggleHtmlEditMode(),
|
||||
icon: Icon(
|
||||
Icons.code,
|
||||
size: 16,
|
||||
color: _isHtmlEditMode ? _teal : Colors.black54,
|
||||
),
|
||||
label: Text(
|
||||
_isHtmlEditMode ? 'Visual Editor' : 'Dev HTML',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: _isHtmlEditMode ? _teal : Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
_webPointerGuard(
|
||||
child: _tealButton(
|
||||
label: primaryLabel,
|
||||
onPressed: _submit,
|
||||
loading: _isSubmitting,
|
||||
width: 120,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: _buildTemplateContent(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import 'dart:math' as math;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:nhancepolicy/customAppBar/customAppBar.dart';
|
||||
@ -216,6 +217,10 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
localToken = widget.Token.isNotEmpty
|
||||
? widget.Token
|
||||
: await tokenService.readValue('hr_Token');
|
||||
// Browser refresh often drops constructor Token — use session token.
|
||||
if (localToken == null || localToken!.toString().trim().isEmpty) {
|
||||
localToken = tokenService.getCurrentToken();
|
||||
}
|
||||
|
||||
localTokenType = widget.TokenType.isNotEmpty
|
||||
? widget.TokenType
|
||||
@ -252,9 +257,65 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
? widget.is_ecard_bulk_download_for_employee
|
||||
: int.tryParse(savedBulk ?? '0') ?? 0;
|
||||
|
||||
// Persist so browser refresh can rebuild this page without empty API params.
|
||||
await _persistPolicyContext();
|
||||
|
||||
if (!_hasRequiredPolicyContext()) {
|
||||
logDebug(
|
||||
'hrPolicyDetails missing client/policy/branch after restore — '
|
||||
'skipping API and returning to policies',
|
||||
);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_isLoadingCards = false;
|
||||
isLoading = false;
|
||||
});
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
Navigator.pushReplacementNamed(context, 'policies');
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
getCDPoliciesDetails();
|
||||
}
|
||||
|
||||
bool _hasRequiredPolicyContext() {
|
||||
final clientId = (localClientId ?? '').toString().trim();
|
||||
final policyId = (localClientPolicyId ?? '').toString().trim();
|
||||
final branchId = (localClientBranchId ?? '').toString().trim();
|
||||
final token = (localToken ?? '').toString().trim();
|
||||
return clientId.isNotEmpty &&
|
||||
policyId.isNotEmpty &&
|
||||
branchId.isNotEmpty &&
|
||||
token.isNotEmpty;
|
||||
}
|
||||
|
||||
Future<void> _persistPolicyContext() async {
|
||||
Future<void> writeIfPresent(String key, dynamic value) async {
|
||||
final text = value?.toString().trim() ?? '';
|
||||
if (text.isEmpty) return;
|
||||
await tokenService.writeValue(key, text);
|
||||
}
|
||||
|
||||
await writeIfPresent('hr_ClientId', localClientId);
|
||||
await writeIfPresent('hr_policyTypeId', localPolicyTypeId);
|
||||
await writeIfPresent('hr_ClientPoliyId', localClientPolicyId);
|
||||
await writeIfPresent('hr_clientBranchId', localClientBranchId);
|
||||
await writeIfPresent('hr_Token', localToken);
|
||||
await writeIfPresent('hr_TokenType', localTokenType);
|
||||
await writeIfPresent('hr_cardType', localCardType);
|
||||
await writeIfPresent('hr_cardPolicyNo', localCardPolicyNo);
|
||||
await writeIfPresent('hr_cardInsurer_name', localCardInsurerName);
|
||||
await writeIfPresent('hr_cardPolicy_name', localCardPolicyName);
|
||||
await writeIfPresent('hr_cardPolicy_ExpDate', localCardPolicyExpDate);
|
||||
await writeIfPresent('hr_total_premium', localTotalPremium);
|
||||
await tokenService.writeValue(
|
||||
'hr_is_ecard_bulk_download_for_employee',
|
||||
localIsEcardBulkDownload.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> clearPolicyStorage() async {
|
||||
await tokenService.removeValue('hr_ClientId');
|
||||
await tokenService.removeValue('hr_policyTypeId');
|
||||
@ -377,10 +438,28 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
dynamic cardData,
|
||||
String? searchKey,
|
||||
}) async {
|
||||
final clientId = localClientId ?? widget.ClientId;
|
||||
final policyId = localClientPolicyId ?? widget.ClientPoliyId;
|
||||
final branchId = localClientBranchId ?? widget.clientBranchId;
|
||||
final token = localToken ?? widget.Token;
|
||||
final clientId = (localClientId ?? widget.ClientId).toString().trim();
|
||||
final policyId = (localClientPolicyId ?? widget.ClientPoliyId).toString().trim();
|
||||
final branchId =
|
||||
(localClientBranchId ?? widget.clientBranchId).toString().trim();
|
||||
var token = (localToken ?? widget.Token).toString().trim();
|
||||
if (token.isEmpty) {
|
||||
token = tokenService.getCurrentToken()?.trim() ?? '';
|
||||
localToken = token;
|
||||
}
|
||||
|
||||
if (clientId.isEmpty || policyId.isEmpty || branchId.isEmpty || token.isEmpty) {
|
||||
logDebug(
|
||||
'Skipping getEmployeeAndDependenceByClientId — empty params '
|
||||
'client=$clientId policy=$policyId branch=$branchId tokenEmpty=${token.isEmpty}',
|
||||
);
|
||||
return {
|
||||
'status': 'error',
|
||||
'code': 400,
|
||||
'message': 'Missing policy context',
|
||||
'data': [],
|
||||
};
|
||||
}
|
||||
|
||||
if (localTokenType == 'post') {
|
||||
return apiService.getEmployeeAndDependenceToApi(
|
||||
@ -397,7 +476,7 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
clientId,
|
||||
policyId,
|
||||
branchId,
|
||||
token!,
|
||||
token,
|
||||
cardData: cardData,
|
||||
searchKey: searchKey,
|
||||
);
|
||||
@ -1531,7 +1610,7 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openReminderConfigDialog() async {
|
||||
Future<void> _openReminderDialog() async {
|
||||
final clientId = localClientId ?? widget.ClientId;
|
||||
final clientPolicyId = localClientPolicyId ?? widget.ClientPoliyId;
|
||||
final clientBranchId = localClientBranchId ?? widget.clientBranchId;
|
||||
@ -1541,7 +1620,7 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (dialogContext) {
|
||||
return _ReminderMailConfigDialog(
|
||||
return _ReminderHubDialog(
|
||||
clientId: clientId,
|
||||
clientPolicyId: clientPolicyId,
|
||||
clientBranchId: clientBranchId,
|
||||
@ -1549,6 +1628,10 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
apiService: apiService,
|
||||
defaultSubject: _defaultReminderSubject(),
|
||||
defaultHtmlBody: _defaultReminderHtmlBody(),
|
||||
onSend: (subject, htmlBody) => _sendEnrollmentReminder(
|
||||
emailSubject: subject,
|
||||
emailBody: htmlBody,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -1563,34 +1646,6 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
return kDefaultEnrollmentReminderHtmlBody;
|
||||
}
|
||||
|
||||
Future<void> _openReminderTemplateDialog() async {
|
||||
final clientId = localClientId ?? widget.ClientId;
|
||||
final clientPolicyId = localClientPolicyId ?? widget.ClientPoliyId;
|
||||
final clientBranchId = localClientBranchId ?? widget.clientBranchId;
|
||||
final token = localToken ?? widget.Token;
|
||||
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (dialogContext) {
|
||||
return ReminderEmailTemplateDialog(
|
||||
clientId: clientId,
|
||||
clientPolicyId: clientPolicyId,
|
||||
clientBranchId: clientBranchId,
|
||||
token: token,
|
||||
apiService: apiService,
|
||||
defaultSubject: _defaultReminderSubject(),
|
||||
defaultHtmlBody: _defaultReminderHtmlBody(),
|
||||
mode: ReminderEmailTemplateMode.send,
|
||||
onSend: (subject, htmlBody) => _sendEnrollmentReminder(
|
||||
emailSubject: subject,
|
||||
emailBody: htmlBody,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _sendEnrollmentReminder({
|
||||
required String emailSubject,
|
||||
required String emailBody,
|
||||
@ -1920,15 +1975,9 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
if (localTokenType == 'pre') ...[
|
||||
(
|
||||
label: 'Reminder',
|
||||
icon: Icons.tune_rounded,
|
||||
icon: Icons.notifications_active_outlined,
|
||||
color: const Color(0xFF009195),
|
||||
onTap: _openReminderConfigDialog,
|
||||
),
|
||||
(
|
||||
label: 'Mail Template',
|
||||
icon: Icons.mail_outline_rounded,
|
||||
color: const Color(0xFFE26728),
|
||||
onTap: _isSendingReminder ? null : _openReminderTemplateDialog,
|
||||
onTap: _isSendingReminder ? null : _openReminderDialog,
|
||||
),
|
||||
],
|
||||
if (localTokenType == 'post') ...[
|
||||
@ -2364,18 +2413,12 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
),
|
||||
if (localTokenType == 'pre') ...[
|
||||
_buildHeaderActionButton(
|
||||
label: 'Reminder Config',
|
||||
label: 'Reminder',
|
||||
color: const Color(0xFF009195),
|
||||
width: isCompact ? 130 : 150,
|
||||
onPressed: _openReminderConfigDialog,
|
||||
),
|
||||
_buildHeaderActionButton(
|
||||
label: 'Reminder Mail Template',
|
||||
color: const Color(0xFFE26728),
|
||||
width: isCompact ? 170 : 210,
|
||||
width: isCompact ? 120 : 130,
|
||||
onPressed: _isSendingReminder
|
||||
? null
|
||||
: _openReminderTemplateDialog,
|
||||
: _openReminderDialog,
|
||||
isLoading: _isSendingReminder,
|
||||
),
|
||||
],
|
||||
@ -3193,7 +3236,9 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
}
|
||||
|
||||
Widget _buildCDDataTable(BuildContext context) {
|
||||
final showUHID = localPolicyTypeId != '6' && localPolicyTypeId != '7';
|
||||
final showUHID = localTokenType == 'post' &&
|
||||
localPolicyTypeId != '6' &&
|
||||
localPolicyTypeId != '7';
|
||||
final showLoggedIn = localTokenType == 'pre';
|
||||
final showAction =
|
||||
localTokenType != 'pre' && (hasAnyEcardLink || hasModule);
|
||||
@ -3205,7 +3250,7 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
pinned: true,
|
||||
delegate: _CDHeaderDelegate(
|
||||
showUHID: showUHID,
|
||||
uhidHeaderLabel: localTokenType == 'post' ? 'TPA ID' : 'UHID',
|
||||
uhidHeaderLabel: 'TPA ID',
|
||||
showLoggedIn: showLoggedIn,
|
||||
showAction: showAction,
|
||||
),
|
||||
@ -3256,14 +3301,14 @@ class _HrPolicyDetailsState extends State<hrPolicyDetails>
|
||||
),
|
||||
),
|
||||
|
||||
/// UHID / TPA ID
|
||||
if (localPolicyTypeId != '6' && localPolicyTypeId != '7')
|
||||
/// TPA ID (post only)
|
||||
if (localTokenType == 'post' &&
|
||||
localPolicyTypeId != '6' &&
|
||||
localPolicyTypeId != '7')
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
localTokenType == 'post'
|
||||
? (item['tpa_id'] ?? '-')
|
||||
: (item['uhid'] ?? '-'),
|
||||
item['tpa_id'] ?? '-',
|
||||
style: _dataBold,
|
||||
),
|
||||
),
|
||||
@ -4500,6 +4545,150 @@ class _PolicyTermsDialog extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _ReminderHubDialog extends StatefulWidget {
|
||||
final String clientId;
|
||||
final String clientPolicyId;
|
||||
final String clientBranchId;
|
||||
final String token;
|
||||
final ApiService apiService;
|
||||
final String defaultSubject;
|
||||
final String defaultHtmlBody;
|
||||
final Future<void> Function(String subject, String htmlBody) onSend;
|
||||
|
||||
const _ReminderHubDialog({
|
||||
required this.clientId,
|
||||
required this.clientPolicyId,
|
||||
required this.clientBranchId,
|
||||
required this.token,
|
||||
required this.apiService,
|
||||
required this.defaultSubject,
|
||||
required this.defaultHtmlBody,
|
||||
required this.onSend,
|
||||
});
|
||||
|
||||
@override
|
||||
State<_ReminderHubDialog> createState() => _ReminderHubDialogState();
|
||||
}
|
||||
|
||||
class _ReminderHubDialogState extends State<_ReminderHubDialog>
|
||||
with SingleTickerProviderStateMixin {
|
||||
static const _teal = Color(0xFF009195);
|
||||
late final TabController _tabController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabController = TabController(length: 2, vsync: this);
|
||||
_tabController.addListener(_onTabChanged);
|
||||
}
|
||||
|
||||
void _onTabChanged() {
|
||||
if (_tabController.indexIsChanging) return;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_tabController.removeListener(_onTabChanged);
|
||||
_tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.sizeOf(context);
|
||||
final isConfigTab = _tabController.index == 0;
|
||||
final dialogWidth = isConfigTab
|
||||
? math.min(520.0, size.width - 32)
|
||||
: size.width * 0.95;
|
||||
final dialogHeight = isConfigTab
|
||||
? math.min(460.0, size.height * 0.72)
|
||||
: size.height * 0.92;
|
||||
|
||||
return Dialog(
|
||||
insetPadding: const EdgeInsets.all(16),
|
||||
backgroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
child: SizedBox(
|
||||
width: dialogWidth,
|
||||
height: dialogHeight,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 16, 8, 0),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'Enrollment Reminder',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
icon: const Icon(Icons.close, size: 20),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
TabBar(
|
||||
controller: _tabController,
|
||||
labelColor: _teal,
|
||||
unselectedLabelColor: Colors.black54,
|
||||
indicatorColor: _teal,
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
unselectedLabelStyle: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
tabs: const [
|
||||
Tab(text: 'Setup'),
|
||||
Tab(text: 'Mail Template'),
|
||||
],
|
||||
),
|
||||
const Divider(height: 1),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
controller: _tabController,
|
||||
children: [
|
||||
_ReminderMailConfigDialog(
|
||||
clientId: widget.clientId,
|
||||
clientPolicyId: widget.clientPolicyId,
|
||||
clientBranchId: widget.clientBranchId,
|
||||
token: widget.token,
|
||||
apiService: widget.apiService,
|
||||
defaultSubject: widget.defaultSubject,
|
||||
defaultHtmlBody: widget.defaultHtmlBody,
|
||||
embedded: true,
|
||||
),
|
||||
ReminderEmailTemplateDialog(
|
||||
clientId: widget.clientId,
|
||||
clientPolicyId: widget.clientPolicyId,
|
||||
clientBranchId: widget.clientBranchId,
|
||||
token: widget.token,
|
||||
apiService: widget.apiService,
|
||||
defaultSubject: widget.defaultSubject,
|
||||
defaultHtmlBody: widget.defaultHtmlBody,
|
||||
mode: ReminderEmailTemplateMode.send,
|
||||
onSend: widget.onSend,
|
||||
embedded: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ReminderMailConfigDialog extends StatefulWidget {
|
||||
final String clientId;
|
||||
final String clientPolicyId;
|
||||
@ -4508,6 +4697,7 @@ class _ReminderMailConfigDialog extends StatefulWidget {
|
||||
final ApiService apiService;
|
||||
final String defaultSubject;
|
||||
final String defaultHtmlBody;
|
||||
final bool embedded;
|
||||
|
||||
const _ReminderMailConfigDialog({
|
||||
required this.clientId,
|
||||
@ -4517,6 +4707,7 @@ class _ReminderMailConfigDialog extends StatefulWidget {
|
||||
required this.apiService,
|
||||
required this.defaultSubject,
|
||||
required this.defaultHtmlBody,
|
||||
this.embedded = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -4854,9 +5045,11 @@ class _ReminderMailConfigDialogState extends State<_ReminderMailConfigDialog> {
|
||||
TextField(
|
||||
controller: _reminderDaysController,
|
||||
onChanged: (value) => _reminderDaysText = value,
|
||||
style: GoogleFonts.poppins(fontSize: 14),
|
||||
style: GoogleFonts.poppins(fontSize: 13),
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
hintText: helperText,
|
||||
hintStyle: GoogleFonts.poppins(fontSize: 12, color: Colors.black38),
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF5F5F5),
|
||||
border: OutlineInputBorder(
|
||||
@ -4897,9 +5090,188 @@ class _ReminderMailConfigDialogState extends State<_ReminderMailConfigDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildConfigContent() {
|
||||
final isBusy = _isSaving;
|
||||
final formMaxWidth = widget.embedded ? 420.0 : 560.0;
|
||||
|
||||
if (_isLoadingConfig) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
final form = ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: formMaxWidth),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Text(
|
||||
'Configure the schedule for automated enrollment reminder emails.',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF8FAFA),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: const Color(0xFFE8EEF0)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Enable scheduled reminders',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
Switch(
|
||||
value: _isEnabled,
|
||||
activeColor: const Color(0xFF009195),
|
||||
onChanged: isBusy
|
||||
? null
|
||||
: (value) => setState(() => _isEnabled = value),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Frequency',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: _frequency,
|
||||
isExpanded: true,
|
||||
isDense: true,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF5F5F5),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 8,
|
||||
),
|
||||
),
|
||||
items: _frequencies.entries
|
||||
.map(
|
||||
(entry) => DropdownMenuItem(
|
||||
value: entry.key,
|
||||
child: Text(
|
||||
entry.value,
|
||||
style: GoogleFonts.poppins(fontSize: 13),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: isBusy
|
||||
? null
|
||||
: (value) {
|
||||
if (value == null) return;
|
||||
setState(() {
|
||||
_frequency = value;
|
||||
_reminderDaysText = '';
|
||||
_reminderDaysController.clear();
|
||||
_selectedWorkingDays.clear();
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
_buildDaysField(),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(20, 16, 20, 8),
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: form,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildConfigActions() {
|
||||
final isBusy = _isSaving;
|
||||
final formMaxWidth = widget.embedded ? 420.0 : 560.0;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(20, 8, 20, 16),
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: formMaxWidth),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: isBusy ? null : () => Navigator.pop(context),
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: GoogleFonts.poppins(color: Colors.black54),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
ElevatedButton(
|
||||
onPressed: isBusy || _isLoadingConfig ? null : _saveConfig,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF009195),
|
||||
minimumSize: const Size(88, 36),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
),
|
||||
child: _isSaving
|
||||
? const SizedBox(
|
||||
width: 18,
|
||||
height: 18,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: Colors.white,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Save',
|
||||
style: GoogleFonts.poppins(color: Colors.white),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isBusy = _isSaving;
|
||||
if (widget.embedded) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: _buildConfigContent(),
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
_buildConfigActions(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
@ -4909,119 +5281,15 @@ class _ReminderMailConfigDialogState extends State<_ReminderMailConfigDialog> {
|
||||
),
|
||||
content: SizedBox(
|
||||
width: 560,
|
||||
child: _isLoadingConfig
|
||||
? const SizedBox(
|
||||
height: 180,
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Configure the schedule for automated enrollment reminder emails.',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SwitchListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(
|
||||
'Enable scheduled reminders',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
value: _isEnabled,
|
||||
activeColor: const Color(0xFF009195),
|
||||
onChanged: isBusy
|
||||
? null
|
||||
: (value) => setState(() => _isEnabled = value),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Frequency',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
DropdownButtonFormField<String>(
|
||||
value: _frequency,
|
||||
isExpanded: true,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: const Color(0xFFF5F5F5),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
),
|
||||
items: _frequencies.entries
|
||||
.map(
|
||||
(entry) => DropdownMenuItem(
|
||||
value: entry.key,
|
||||
child: Text(
|
||||
entry.value,
|
||||
style: GoogleFonts.poppins(fontSize: 14),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: isBusy
|
||||
? null
|
||||
: (value) {
|
||||
if (value == null) return;
|
||||
setState(() {
|
||||
_frequency = value;
|
||||
_reminderDaysText = '';
|
||||
_reminderDaysController.clear();
|
||||
_selectedWorkingDays.clear();
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
_buildDaysField(),
|
||||
const SizedBox(height: 20),
|
||||
// OutlinedButton.icon(
|
||||
// onPressed: isBusy ? null : _openTemplateEditor,
|
||||
// icon: const Icon(Icons.edit_outlined, size: 18),
|
||||
// label: Text(
|
||||
// 'Edit Email Template',
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 13,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// style: OutlinedButton.styleFrom(
|
||||
// foregroundColor: const Color(0xFF009195),
|
||||
// side: const BorderSide(color: Color(0xFF009195)),
|
||||
// padding: const EdgeInsets.symmetric(
|
||||
// horizontal: 16,
|
||||
// vertical: 12,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: _buildConfigContent(),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: isBusy ? null : () => Navigator.pop(context),
|
||||
onPressed: _isSaving ? null : () => Navigator.pop(context),
|
||||
child: Text('Cancel', style: GoogleFonts.poppins(color: Colors.black54)),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: isBusy || _isLoadingConfig ? null : _saveConfig,
|
||||
onPressed: _isSaving || _isLoadingConfig ? null : _saveConfig,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color(0xFF009195),
|
||||
),
|
||||
|
||||
@ -585,6 +585,46 @@ class _PolicyGrid extends StatelessWidget {
|
||||
return allocg == 'non-eb';
|
||||
}
|
||||
|
||||
/// Persist policy context so hrPolicyDetails survives browser refresh.
|
||||
Future<void> _persistHrPolicyContext(
|
||||
TokenStorageService tokenService, {
|
||||
required String clientId,
|
||||
required String policyTypeId,
|
||||
required String clientPolicyId,
|
||||
required String clientBranchId,
|
||||
required String token,
|
||||
required String tokenType,
|
||||
required String cardType,
|
||||
required String cardPolicyNo,
|
||||
required String cardInsurerName,
|
||||
required String cardPolicyName,
|
||||
required String cardPolicyExpDate,
|
||||
required String totalPremium,
|
||||
required dynamic isEcardBulkDownload,
|
||||
}) async {
|
||||
Future<void> write(String key, dynamic value) async {
|
||||
final text = value?.toString() ?? '';
|
||||
await tokenService.writeValue(key, text);
|
||||
}
|
||||
|
||||
await write('hr_ClientId', clientId);
|
||||
await write('hr_policyTypeId', policyTypeId);
|
||||
await write('hr_ClientPoliyId', clientPolicyId);
|
||||
await write('hr_clientBranchId', clientBranchId);
|
||||
await write('hr_Token', token);
|
||||
await write('hr_TokenType', tokenType);
|
||||
await write('hr_cardType', cardType);
|
||||
await write('hr_cardPolicyNo', cardPolicyNo);
|
||||
await write('hr_cardInsurer_name', cardInsurerName);
|
||||
await write('hr_cardPolicy_name', cardPolicyName);
|
||||
await write('hr_cardPolicy_ExpDate', cardPolicyExpDate);
|
||||
await write('hr_total_premium', totalPremium);
|
||||
await write(
|
||||
'hr_is_ecard_bulk_download_for_employee',
|
||||
isEcardBulkDownload ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
ResponsiveGridConfig _getGridConfig(
|
||||
BuildContext context,
|
||||
bool isEnrollment,
|
||||
@ -728,6 +768,23 @@ class _PolicyGrid extends StatelessWidget {
|
||||
return;
|
||||
}
|
||||
|
||||
await _persistHrPolicyContext(
|
||||
tokenService,
|
||||
clientId: clientId,
|
||||
policyTypeId: data['policy_type_id'].toString(),
|
||||
clientPolicyId: data['client_policy_id'].toString(),
|
||||
clientBranchId: branchId,
|
||||
token: token,
|
||||
tokenType: 'pre',
|
||||
cardType: data['type'].toString(),
|
||||
cardPolicyNo: data['policy_no'].toString(),
|
||||
cardInsurerName: data['insurer_short_name'].toString(),
|
||||
cardPolicyName: data['policy_name'].toString(),
|
||||
cardPolicyExpDate: data['policy_expiry_date'].toString(),
|
||||
totalPremium: '',
|
||||
isEcardBulkDownload: 0,
|
||||
);
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
@ -801,6 +858,24 @@ class _PolicyGrid extends StatelessWidget {
|
||||
return;
|
||||
}
|
||||
|
||||
await _persistHrPolicyContext(
|
||||
tokenService,
|
||||
clientId: clientId,
|
||||
policyTypeId: data['policy_type_id'].toString(),
|
||||
clientPolicyId: data['client_policy_id'].toString(),
|
||||
clientBranchId: branchId,
|
||||
token: token,
|
||||
tokenType: 'post',
|
||||
cardType: data['type'].toString(),
|
||||
cardPolicyNo: data['policy_no'].toString(),
|
||||
cardInsurerName: data['insurer_short_name'].toString(),
|
||||
cardPolicyName: data['policy_name'].toString(),
|
||||
cardPolicyExpDate: data['policy_expiry_date'].toString(),
|
||||
totalPremium: data['total_premium'].toString(),
|
||||
isEcardBulkDownload:
|
||||
data['is_ecard_bulk_download_for_employee'],
|
||||
);
|
||||
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
|
||||
@ -595,6 +595,7 @@ class ApiService {
|
||||
|
||||
final headers = {
|
||||
'Authorization': 'Bearer ${token ?? ''}',
|
||||
'Content-Type': 'application/json',
|
||||
'APP-SIGNATURE':
|
||||
'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user