Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sai Srinivas
GEN_ERP_2025
Commits
94df616d
Commit
94df616d
authored
May 16, 2025
by
Sai Srinivas
Browse files
16-05-2025 By Sai Srinivas
Finance Module requisition Lists and Details
parent
6a825b3f
Changes
44
Hide whitespace changes
Inline
Side-by-side
lib/Notifiers/financeProvider/RequesitionLidtDetailsProvider.dart
0 → 100644
View file @
94df616d
import
'package:flutter/foundation.dart'
;
import
'package:generp/Models/financeModels/paymentRequisitionDetailsResponse.dart'
;
import
'package:generp/Notifiers/HomeScreenNotifier.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:provider/provider.dart'
;
import
'approveRejectPaymentRequestResponse.dart'
;
class
Requesitionlidtdetailsprovider
extends
ChangeNotifier
{
PaymentDetails
_paymentDetails
=
PaymentDetails
();
RequestDetails
_requestDetails
=
RequestDetails
();
PaymentDetails
get
paymentsDetails
=>
_paymentDetails
;
RequestDetails
get
requestsDetails
=>
_requestDetails
;
List
<
PaymentAccounts
>
_paymentAccounts
=
[];
PaymentRequestDetails
_paymentRequestDetails
=
PaymentRequestDetails
();
List
<
PaymentModes
>
_paymentModes
=
[];
PaymentAccounts
?
_selectedPaymentAccounts
;
List
<
PaymentAccounts
>
get
paymentsAccounts
=>
_paymentAccounts
;
List
<
PaymentModes
>
get
paymentsModes
=>
_paymentModes
;
PaymentRequestDetails
get
paymentsReqDetails
=>
_paymentRequestDetails
;
PaymentAccounts
?
get
selectedPaymentAccounts
=>
_selectedPaymentAccounts
;
var
_selectedValue
;
var
_selectedID
;
get
selectedValue
=>
_selectedValue
;
get
selectedID
=>
_selectedID
;
List
<
String
>
_headings
=
[
];
List
<
String
>
_subHeadings
=[];
List
<
String
>
get
subHeadings
=>
_subHeadings
;
List
<
String
>
get
Headings
=>
_headings
;
set
selectedPaymentAccounts
(
PaymentAccounts
?
value
){
_selectedPaymentAccounts
=
value
;
_selectedValue
=
value
!.
name
!;
_selectedID
=
value
!.
id
;
notifyListeners
();
}
set
selectedValue
(
value
){
_selectedValue
=
value
;
notifyListeners
();
}
set
selectedID
(
value
){
_selectedID
=
value
;
notifyListeners
();
}
Future
<
void
>
paymentRequesitionDetails
(
context
,
payment_request_id
)
async
{
try
{
var
provider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
paymentRequestionDetailsAPI
(
provider
.
empId
,
provider
.
session
,
payment_request_id
);
if
(
data
!=
null
){
if
(
data
.
error
==
"0"
){
_headings
=
[
"Requested Account"
,
"Proposed Account Name"
,
"Branch"
,
"Requesting Propose"
,
"Payment Mode"
,
"Created Employee"
,
"Attachment"
,
"Requested Date"
,
"Note"
,
"Level 1 Remarks"
,
"Level 1 Approved By"
,
"Level 2 Remarks"
,
"Level 2 Approved By"
,
"Created Date/Time"
,
"Updated Date/Time"
,
];
_paymentDetails
=
data
.
paymentDetails
??
PaymentDetails
(
accountId:
""
,
accountName:
""
,
amount:
""
,
attachmentDirFilePath:
""
,
attachmentViewFileName:
""
,
bankAccountHolderName:
""
,
bankAccountNumber:
""
,
bankBranchName:
""
,
bankIfscCode:
""
,
bankName:
""
,
bankUpiId:
""
,
createdDatetime:
""
,
createdEmployeeId:
""
,
description:
""
,
id:
""
,
isExists:
""
,
mode:
""
,
paymentAccountId:
""
,
paymentAccountName:
""
,
paymentDate:
""
,
paymentEmployeeName:
""
,
paymentModeId:
""
,
paymentReferenceNumber:
""
,
paymentRemarks:
""
,
refId:
""
,
refType:
""
,
updatedDatetime:
""
);
_requestDetails
=
data
.
requestDetails
??
RequestDetails
(
updatedDatetime:
""
,
id:
""
,
description:
""
,
createdDatetime:
""
,
attachmentViewFileName:
""
,
attachmentDirFilePath:
""
,
amount:
""
,
accountName:
""
,
accountId:
""
,
branch:
""
,
createdEmployee:
""
,
date:
""
,
isProcessedPaymentRequest:
""
,
level1ApprovalRemarks:
""
,
level1Employee:
""
,
level2ApprovalRemarks:
""
,
level2Employee:
""
,
proposedAccount:
""
,
proposedAccountId:
""
,
requestedAmount:
""
,
requestingPurpose:
""
,
requestMode:
""
,
status:
""
,
transDis:
""
);
_subHeadings
=
[
_requestDetails
.
accountName
??
"-"
,
_requestDetails
.
proposedAccount
??
"-"
,
_requestDetails
.
branch
??
"-"
,
_requestDetails
.
requestingPurpose
??
"-"
,
_requestDetails
.
requestMode
??
"-"
,
_requestDetails
.
createdEmployee
??
"-"
,
_requestDetails
.
attachmentViewFileName
??
"-"
,
_requestDetails
.
date
??
"-"
,
_requestDetails
.
description
??
"-"
,
_requestDetails
.
level1ApprovalRemarks
??
"-"
,
_requestDetails
.
level1Employee
??
"-"
,
_requestDetails
.
level2ApprovalRemarks
??
"-"
,
_requestDetails
.
level2Employee
??
"-"
,
_requestDetails
.
createdDatetime
??
"-"
,
_requestDetails
.
updatedDatetime
??
"-"
];
notifyListeners
();
}
}
}
catch
(
e
,
s
){}
}
Future
<
void
>
approveRejectPaymentRequestAPIFunction
(
context
,
payment_request_id
)
async
{
try
{
var
provider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
approveRejectPaymentRequestAPI
(
provider
.
empId
,
provider
.
session
,
payment_request_id
);
if
(
data
!=
null
){
if
(
data
.
error
==
"0"
){
_paymentModes
=
data
.
paymentModes
!;
_paymentAccounts
=
data
.
paymentAccounts
!;
_paymentRequestDetails
=
data
.
paymentRequestDetails
!;
notifyListeners
();
}
}
}
catch
(
e
,
s
){}
}
Future
<
void
>
paymentrequisitionRejectSubmitAPIFunction
(
context
,
mode
,
payment_request_id
,
approve_remarks
)
async
{
try
{
var
provider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
RejectPaymentRequestSubmitAPI
(
provider
.
empId
,
provider
.
session
,
mode
,
payment_request_id
,
approve_remarks
);
}
catch
(
e
,
s
){
}
}
Future
<
void
>
paymentrequisitionApproveSubmitAPIFunction
(
context
,
mode
,
payment_request_id
,
approved_amount
,
approve_remarks
,
proposed_payment_account_id
)
async
{
try
{
var
provider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
ApprovePaymentRequestSubmitAPI
(
provider
.
empId
,
provider
.
session
,
mode
,
payment_request_id
,
approved_amount
,
approve_remarks
,
proposed_payment_account_id
);
}
catch
(
e
,
s
){
}
}
Future
<
void
>
paymentrequisitionProcessSubmitAPIFunction
(
context
,
mode
,
payment_request_id
,
approved_amount
,
approve_remarks
,
proposed_payment_account_id
,
payment_account_id
,
processing_remarks
,
attachment
)
async
{
try
{
var
provider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
processApproveRejectPaymentRequestSubmitAPI
(
provider
.
empId
,
provider
.
session
,
mode
,
payment_request_id
,
approved_amount
,
approve_remarks
,
proposed_payment_account_id
,
payment_account_id
,
processing_remarks
,
attachment
);
}
catch
(
e
,
s
){
}
}
}
\ No newline at end of file
lib/Notifiers/financeProvider/RequestionListProvider.dart
View file @
94df616d
...
@@ -3,37 +3,28 @@ import 'dart:io';
...
@@ -3,37 +3,28 @@ import 'dart:io';
import
'package:camera/camera.dart'
;
import
'package:camera/camera.dart'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_image_compress/flutter_image_compress.dart'
;
import
'package:flutter_image_compress/flutter_image_compress.dart'
;
import
'package:generp/Notifiers/HomeScreenNotifier.dart'
;
import
'package:generp/Notifiers/HomeScreenNotifier.dart'
;
import
'package:generp/Utils/commonServices.dart'
;
import
'package:generp/Utils/commonServices.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:image_picker/image_picker.dart'
;
import
'package:image_picker/image_picker.dart'
;
import
'package:permission_handler/permission_handler.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'package:share_plus/share_plus.dart'
;
import
'../../Models/financeModels/addPaymentRequestionResponse.dart'
;
import
'../../Models/financeModels/addPaymentRequestionResponse.dart'
;
import
'../../Models/financeModels/paymentRequesitionListsResponse.dart'
;
import
'package:csv/csv.dart'
;
import
'package:excel/excel.dart'
;
import
'package:path_provider/path_provider.dart'
;
import
'package:pdf/pdf.dart'
;
import
'package:pdf/widgets.dart'
as
pw
;
import
'package:printing/printing.dart'
;
class
Requestionlistprovider
extends
ChangeNotifier
{
class
Requestionlistprovider
extends
ChangeNotifier
{
var
res
=
{
"requesting_purposes"
:
[
"Salary Advance"
,
"Incentive Advance"
,
"Tour Advance"
,
],
"accounts"
:
[
{
"id"
:
"22"
,
"name"
:
"Super Admin"
},
],
"payment_modes"
:
[
{
"id"
:
"1"
,
"name"
:
"Cash"
},
{
"id"
:
"2"
,
"name"
:
"Cheque"
},
{
"id"
:
"3"
,
"name"
:
"RTGS"
},
{
"id"
:
"4"
,
"name"
:
"NEFT"
},
{
"id"
:
"5"
,
"name"
:
"IMPS"
},
{
"id"
:
"6"
,
"name"
:
"UPI"
},
{
"id"
:
"7"
,
"name"
:
"Online Portal"
},
],
"error"
:
"0"
,
"message"
:
"Fetched Successfully"
,
};
TextEditingController
reqPurposeController
=
TextEditingController
();
TextEditingController
reqPurposeController
=
TextEditingController
();
TextEditingController
descController
=
TextEditingController
();
TextEditingController
descController
=
TextEditingController
();
...
@@ -48,6 +39,7 @@ class Requestionlistprovider extends ChangeNotifier {
...
@@ -48,6 +39,7 @@ class Requestionlistprovider extends ChangeNotifier {
List
<
Accounts
>
_accounts
=
[];
List
<
Accounts
>
_accounts
=
[];
List
<
PaymentModes
>
_paymentModes
=
[];
List
<
PaymentModes
>
_paymentModes
=
[];
List
<
String
>
_requestingPurposes
=
[];
List
<
String
>
_requestingPurposes
=
[];
List
<
RequistionList
>
_requisitionList
=
[];
Accounts
?
_selectedAccounts
;
Accounts
?
_selectedAccounts
;
PaymentModes
?
_selectedPayment
;
PaymentModes
?
_selectedPayment
;
String
?
_selectReqPurpose
;
String
?
_selectReqPurpose
;
...
@@ -74,10 +66,9 @@ class Requestionlistprovider extends ChangeNotifier {
...
@@ -74,10 +66,9 @@ class Requestionlistprovider extends ChangeNotifier {
// bool _submitClicked = false;
// bool _submitClicked = false;
var
_image_picked
=
0
;
var
_image_picked
=
0
;
final
ImagePicker
_picker
=
ImagePicker
();
final
ImagePicker
_picker
=
ImagePicker
();
File
?
_image
;
File
?
_image
;
String
get
paymentModeId
=>
_paymentModeId
;
String
get
paymentModeId
=>
_paymentModeId
;
...
@@ -103,6 +94,8 @@ class Requestionlistprovider extends ChangeNotifier {
...
@@ -103,6 +94,8 @@ class Requestionlistprovider extends ChangeNotifier {
List
<
PaymentModes
>
get
paymentModes
=>
_paymentModes
;
List
<
PaymentModes
>
get
paymentModes
=>
_paymentModes
;
List
<
String
>
get
requestingPurposes
=>
_requestingPurposes
;
List
<
String
>
get
requestingPurposes
=>
_requestingPurposes
;
List
<
RequistionList
>
get
requisitionList
=>
_requisitionList
;
// bool get submitClicked => _submitClicked;
// bool get submitClicked => _submitClicked;
// set submitClicked(bool value){
// set submitClicked(bool value){
...
@@ -268,6 +261,270 @@ class Requestionlistprovider extends ChangeNotifier {
...
@@ -268,6 +261,270 @@ class Requestionlistprovider extends ChangeNotifier {
}
catch
(
e
,
s
)
{}
}
catch
(
e
,
s
)
{}
}
}
Future
<
void
>
paymentRequestionListsAPIFunction
(
context
,
mode
)
async
{
try
{
var
homeProvider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
,
);
final
data
=
await
ApiCalling
.
paymentRequestionListsAPI
(
homeProvider
.
empId
,
homeProvider
.
session
,
mode
,
);
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
_requisitionList
=
data
.
requistionList
!;
notifyListeners
();
}
else
{}
}
}
catch
(
e
,
s
)
{}
}
List
<
List
<
String
>>
prepareExportData
()
{
final
headers
=
[
'ID'
,
'Account Name'
,
'Branch'
,
'Purpose'
,
'Description'
,
'Amount'
,
'Mode'
,
'Status'
,
'Date'
,
];
final
rows
=
requisitionList
.
map
((
item
)
=>
[
item
.
id
??
''
,
item
.
accountName
??
''
,
item
.
branch
??
''
,
item
.
requestingPurpose
??
''
,
item
.
description
??
''
,
item
.
amount
??
''
,
item
.
requestMode
??
''
,
item
.
status
??
''
,
item
.
date
??
''
,
]).
toList
();
return
[
headers
,
...
rows
];
}
void
copyToClipboard
(
BuildContext
context
)
async
{
try
{
if
(
requisitionList
.
isEmpty
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"No data to copy"
)),
);
return
;
}
final
data
=
prepareExportData
();
String
raw
=
data
.
map
((
row
)
=>
row
.
join
(
'
\t
'
)).
join
(
'
\n
'
);
print
(
'Clipboard data:
$raw
'
);
await
Clipboard
.
setData
(
ClipboardData
(
text:
raw
));
toast
(
context
,
"Copied to Clipboard"
);
}
catch
(
e
)
{
print
(
'Error copying to clipboard:
$e
'
);
}
}
Future
<
String
>
getSaveDirectory
()
async
{
// Try Downloads directory first
try
{
if
(
Platform
.
isAndroid
)
{
// Request storage permission for Android
if
(
await
Permission
.
storage
.
request
().
isGranted
||
await
Permission
.
manageExternalStorage
.
request
().
isGranted
)
{
final
dir
=
await
getApplicationDocumentsDirectory
();
if
(
dir
!=
null
)
{
print
(
'Using Downloads directory:
${dir.path}
'
);
return
dir
.
path
;
}
}
}
}
catch
(
e
)
{
print
(
'Error accessing Downloads directory:
$e
'
);
}
// Fallback to shared Documents directory
try
{
final
dir
=
await
getDownloadsDirectory
();
if
(
dir
!=
null
)
{
final
customDir
=
Directory
(
'
${dir.path}
/RequisitionData'
);
if
(!
await
customDir
.
exists
())
{
await
customDir
.
create
(
recursive:
true
);
}
print
(
'Using custom Documents directory:
${customDir.path}
'
);
return
customDir
.
path
;
}
}
catch
(
e
)
{
print
(
'Error accessing Documents directory:
$e
'
);
}
// Final fallback to app's Documents directory
final
dir
=
await
getApplicationDocumentsDirectory
();
print
(
'Using app Documents directory:
${dir.path}
'
);
return
dir
.
path
;
}
Future
<
void
>
downloadCSV
(
BuildContext
context
)
async
{
try
{
if
(
requisitionList
.
isEmpty
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"No data to export"
)),
);
return
;
}
final
data
=
prepareExportData
();
final
csvData
=
const
ListToCsvConverter
().
convert
(
data
);
final
dirPath
=
await
getSaveDirectory
();
final
file
=
File
(
'
$dirPath
/requisition_data.csv'
);
await
file
.
writeAsString
(
csvData
);
print
(
'CSV saved at:
${file.path}
'
);
bool
exists
=
await
file
.
exists
();
print
(
'File exists:
$exists
'
);
// await OpenFile.open(file.path); // Open the file
// await Share.share(file.path); // Share the file
toast
(
context
,
"CSV Downloaded"
);
}
catch
(
e
)
{
print
(
'Error downloading CSV:
$e
'
);
}
}
Future
<
void
>
downloadXLS
(
BuildContext
context
)
async
{
try
{
if
(
requisitionList
.
isEmpty
)
{
toast
(
context
,
"No Data to export"
);
return
;
}
final
data
=
prepareExportData
();
var
excel
=
Excel
.
createExcel
();
Sheet
sheet
=
excel
[
'Sheet1'
];
for
(
var
row
in
data
)
{
sheet
.
appendRow
(
row
.
map
((
cell
)
=>
TextCellValue
(
cell
)).
toList
());
}
final
dirPath
=
await
getSaveDirectory
();
final
file
=
File
(
'
$dirPath
/requisition_data.xlsx'
);
final
bytes
=
excel
.
encode
();
if
(
bytes
==
null
)
throw
Exception
(
"Excel encoding failed"
);
await
file
.
writeAsBytes
(
bytes
);
print
(
'XLSX saved at:
${file.path}
'
);
bool
exists
=
await
file
.
exists
();
print
(
'File exists:
$exists
'
);
// await OpenFile.open(file.path); // Open the file
// await Share.share([file.path], text: 'Requisition Data XLSX'); // Share the file
toast
(
context
,
(
"XLSX Downloaded and opened"
));
}
catch
(
e
)
{
print
(
'Error downloading XLSX:
$e
'
);
}
}
Future
<
void
>
downloadPDF
(
BuildContext
context
)
async
{
try
{
if
(
requisitionList
.
isEmpty
)
{
toast
(
context
,
"No Data to export"
);
return
;
}
final
data
=
prepareExportData
();
final
pdf
=
pw
.
Document
();
pdf
.
addPage
(
pw
.
Page
(
build:
(
context
)
=>
pw
.
Table
.
fromTextArray
(
data:
data
),
),
);
final
dirPath
=
await
getSaveDirectory
();
final
file
=
File
(
'
$dirPath
/requisition_data.pdf'
);
await
file
.
writeAsBytes
(
await
pdf
.
save
());
print
(
'PDF saved at:
${file.path}
'
);
bool
exists
=
await
file
.
exists
();
print
(
'File exists:
$exists
'
);
// await OpenFile.open(file.path); // Open the file
// await Share.shareXFiles([file.path], text: 'Requisition Data PDF'); // Share the file
toast
(
context
,
"PDF Downloaded "
);
}
catch
(
e
)
{
print
(
'Error downloading PDF:
$e
'
);
}
}
Future
<
void
>
printData
(
BuildContext
context
)
async
{
try
{
if
(
requisitionList
.
isEmpty
)
{
toast
(
context
,
"No Data to Print"
);
return
;
}
final
data
=
prepareExportData
();
final
pdf
=
pw
.
Document
();
pdf
.
addPage
(
pw
.
Page
(
build:
(
context
)
=>
pw
.
Table
.
fromTextArray
(
data:
data
),
),
);
await
Printing
.
layoutPdf
(
onLayout:
(
PdfPageFormat
format
)
async
=>
pdf
.
save
(),
);
}
catch
(
e
)
{
print
(
'Error printing data:
$e
'
);
}
}
// void copyToClipboard(context) {
// final data = prepareExportData();
// String raw = data.map((row) => row.join('\t')).join('\n');
// Clipboard.setData(ClipboardData(text: raw));
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Copied to clipboard")));
// }
//
// Future<void> downloadCSV(context) async {
// final data = prepareExportData();
// final csvData = const ListToCsvConverter().convert(data);
// final dir = await getApplicationDocumentsDirectory();
// final file = File('${dir.path}/requisition_data.csv');
// await file.writeAsString(csvData);
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("CSV Downloaded")));
// }
//
// Future<void> downloadXLS(context) async {
// final data = prepareExportData();
// var excel = Excel.createExcel();
// Sheet sheet = excel['Sheet1'];
//
// for (var row in data) {
// sheet.appendRow(row.map((cell) => TextCellValue(cell)).toList());
// }
// final dir = await getApplicationDocumentsDirectory();
// final file = File('${dir.path}/requisition_data.xlsx');
// await file.writeAsBytes(excel.encode()!);
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("XLSX Downloaded")));
// }
//
// Future<void> downloadPDF(context) async {
// final data = prepareExportData();
// final pdf = pw.Document();
// pdf.addPage(
// pw.Page(
// build: (context) => pw.Table.fromTextArray(data: data),
// ),
// );
// final dir = await getApplicationDocumentsDirectory();
// final file = File('${dir.path}/requisition_data.pdf');
// await file.writeAsBytes(await pdf.save());
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("PDF Downloaded")));
// }
//
// Future<void> printData(context) async {
// final data = prepareExportData();
// final pdf = pw.Document();
// pdf.addPage(
// pw.Page(
// build: (context) => pw.Table.fromTextArray(data: data),
// ),
// );
// await Printing.layoutPdf(
// onLayout: (PdfPageFormat format) async => pdf.save(),
// );
// }
void
resetForm
()
{
void
resetForm
()
{
reqPurposeController
.
clear
();
reqPurposeController
.
clear
();
descController
.
clear
();
descController
.
clear
();
...
...
lib/Notifiers/financeProvider/approveRejectPaymentRequestResponse.dart
0 → 100644
View file @
94df616d
class
approveRejectPaymentRequestResponse
{
List
<
PaymentAccounts
>?
paymentAccounts
;
PaymentRequestDetails
?
paymentRequestDetails
;
List
<
PaymentModes
>?
paymentModes
;
String
?
error
;
String
?
message
;
approveRejectPaymentRequestResponse
(
{
this
.
paymentAccounts
,
this
.
paymentRequestDetails
,
this
.
paymentModes
,
this
.
error
,
this
.
message
});
approveRejectPaymentRequestResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
if
(
json
[
'payment_accounts'
]
!=
null
)
{
paymentAccounts
=
<
PaymentAccounts
>[];
json
[
'payment_accounts'
].
forEach
((
v
)
{
paymentAccounts
!.
add
(
new
PaymentAccounts
.
fromJson
(
v
));
});
}
paymentRequestDetails
=
json
[
'payment_request_details'
]
!=
null
?
new
PaymentRequestDetails
.
fromJson
(
json
[
'payment_request_details'
])
:
null
;
if
(
json
[
'payment_modes'
]
!=
null
)
{
paymentModes
=
<
PaymentModes
>[];
json
[
'payment_modes'
].
forEach
((
v
)
{
paymentModes
!.
add
(
new
PaymentModes
.
fromJson
(
v
));
});
}
error
=
json
[
'error'
];
message
=
json
[
'message'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
if
(
this
.
paymentAccounts
!=
null
)
{
data
[
'payment_accounts'
]
=
this
.
paymentAccounts
!.
map
((
v
)
=>
v
.
toJson
()).
toList
();
}
if
(
this
.
paymentRequestDetails
!=
null
)
{
data
[
'payment_request_details'
]
=
this
.
paymentRequestDetails
!.
toJson
();
}
if
(
this
.
paymentModes
!=
null
)
{
data
[
'payment_modes'
]
=
this
.
paymentModes
!.
map
((
v
)
=>
v
.
toJson
()).
toList
();
}
data
[
'error'
]
=
this
.
error
;
data
[
'message'
]
=
this
.
message
;
return
data
;
}
}
class
PaymentAccounts
{
String
?
id
;
String
?
name
;
String
?
accountBalance
;
PaymentAccounts
({
this
.
id
,
this
.
name
,
this
.
accountBalance
});
PaymentAccounts
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
id
=
json
[
'id'
];
name
=
json
[
'name'
];
accountBalance
=
json
[
'account_balance'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
data
[
'id'
]
=
this
.
id
;
data
[
'name'
]
=
this
.
name
;
data
[
'account_balance'
]
=
this
.
accountBalance
;
return
data
;
}
}
class
PaymentRequestDetails
{
String
?
id
;
String
?
accountId
;
String
?
requestingPurpose
;
String
?
description
;
String
?
amount
;
String
?
requestedAmount
;
String
?
paymentRequestModeId
;
String
?
bankName
;
String
?
bankBranchName
;
String
?
bankIfscCode
;
String
?
bankAccountHolderName
;
String
?
bankAccountNumber
;
String
?
bankUpiId
;
PaymentRequestDetails
(
{
this
.
id
,
this
.
accountId
,
this
.
requestingPurpose
,
this
.
description
,
this
.
amount
,
this
.
requestedAmount
,
this
.
paymentRequestModeId
,
this
.
bankName
,
this
.
bankBranchName
,
this
.
bankIfscCode
,
this
.
bankAccountHolderName
,
this
.
bankAccountNumber
,
this
.
bankUpiId
});
PaymentRequestDetails
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
id
=
json
[
'id'
];
accountId
=
json
[
'account_id'
];
requestingPurpose
=
json
[
'requesting_purpose'
];
description
=
json
[
'description'
];
amount
=
json
[
'amount'
];
requestedAmount
=
json
[
'requested_amount'
];
paymentRequestModeId
=
json
[
'payment_request_mode_id'
];
bankName
=
json
[
'bank_name'
];
bankBranchName
=
json
[
'bank_branch_name'
];
bankIfscCode
=
json
[
'bank_ifsc_code'
];
bankAccountHolderName
=
json
[
'bank_account_holder_name'
];
bankAccountNumber
=
json
[
'bank_account_number'
];
bankUpiId
=
json
[
'bank_upi_id'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
data
[
'id'
]
=
this
.
id
;
data
[
'account_id'
]
=
this
.
accountId
;
data
[
'requesting_purpose'
]
=
this
.
requestingPurpose
;
data
[
'description'
]
=
this
.
description
;
data
[
'amount'
]
=
this
.
amount
;
data
[
'requested_amount'
]
=
this
.
requestedAmount
;
data
[
'payment_request_mode_id'
]
=
this
.
paymentRequestModeId
;
data
[
'bank_name'
]
=
this
.
bankName
;
data
[
'bank_branch_name'
]
=
this
.
bankBranchName
;
data
[
'bank_ifsc_code'
]
=
this
.
bankIfscCode
;
data
[
'bank_account_holder_name'
]
=
this
.
bankAccountHolderName
;
data
[
'bank_account_number'
]
=
this
.
bankAccountNumber
;
data
[
'bank_upi_id'
]
=
this
.
bankUpiId
;
return
data
;
}
}
class
PaymentModes
{
String
?
id
;
String
?
name
;
PaymentModes
({
this
.
id
,
this
.
name
});
PaymentModes
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
id
=
json
[
'id'
];
name
=
json
[
'name'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
data
[
'id'
]
=
this
.
id
;
data
[
'name'
]
=
this
.
name
;
return
data
;
}
}
lib/Notifiers/loginNotifier.dart
View file @
94df616d
...
@@ -100,6 +100,7 @@ int get loginStatus => _loginStatus;
...
@@ -100,6 +100,7 @@ int get loginStatus => _loginStatus;
print
(
_deviceDetails
);
print
(
_deviceDetails
);
print
(
_deviceId
);
print
(
_deviceId
);
print
(
_androidId
);
print
(
_androidId
);
notifyListeners
();
}
}
Future
<
String
?>
getDevId
()
async
{
Future
<
String
?>
getDevId
()
async
{
...
@@ -107,6 +108,7 @@ int get loginStatus => _loginStatus;
...
@@ -107,6 +108,7 @@ int get loginStatus => _loginStatus;
var
iosDeviceInfo
=
await
deviceInfo
.
iosInfo
;
var
iosDeviceInfo
=
await
deviceInfo
.
iosInfo
;
_deviceId
=
iosDeviceInfo
.
identifierForVendor
!;
_deviceId
=
iosDeviceInfo
.
identifierForVendor
!;
_deviceDetails
=
iosDeviceInfo
.
toString
();
_deviceDetails
=
iosDeviceInfo
.
toString
();
notifyListeners
();
}
}
...
...
lib/main.dart
View file @
94df616d
...
@@ -33,6 +33,8 @@ import 'package:generp/screens/HomeScreen.dart';
...
@@ -33,6 +33,8 @@ import 'package:generp/screens/HomeScreen.dart';
import
'package:generp/screens/splash.dart'
;
import
'package:generp/screens/splash.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'Notifiers/financeProvider/RequesitionLidtDetailsProvider.dart'
;
const
AndroidNotificationChannel
channel
=
AndroidNotificationChannel
(
const
AndroidNotificationChannel
channel
=
AndroidNotificationChannel
(
'generp_channel'
,
// id
'generp_channel'
,
// id
'generp_channel_name'
,
'generp_channel_name'
,
...
@@ -209,6 +211,7 @@ class MyApp extends StatelessWidget {
...
@@ -209,6 +211,7 @@ class MyApp extends StatelessWidget {
///finance
///finance
ChangeNotifierProvider
(
create:
(
_
)
=>
Dashboardprovider
(),),
ChangeNotifierProvider
(
create:
(
_
)
=>
Dashboardprovider
(),),
ChangeNotifierProvider
(
create:
(
_
)
=>
Requestionlistprovider
(),),
ChangeNotifierProvider
(
create:
(
_
)
=>
Requestionlistprovider
(),),
ChangeNotifierProvider
(
create:
(
_
)
=>
Requesitionlidtdetailsprovider
(),),
],
],
child:
Builder
(
child:
Builder
(
builder:
(
BuildContext
context
)
{
builder:
(
BuildContext
context
)
{
...
...
lib/screens/HomeScreen.dart
View file @
94df616d
...
@@ -16,6 +16,7 @@ import 'package:generp/screens/finance/financeDashboard.dart';
...
@@ -16,6 +16,7 @@ import 'package:generp/screens/finance/financeDashboard.dart';
import
'package:generp/screens/genTracker/GenTrackerDashboard.dart'
;
import
'package:generp/screens/genTracker/GenTrackerDashboard.dart'
;
import
'package:generp/screens/serviceEngineer/NearbyGenerators.dart'
;
import
'package:generp/screens/serviceEngineer/NearbyGenerators.dart'
;
import
'package:generp/screens/serviceEngineer/serviceEngineerDashboard.dart'
;
import
'package:generp/screens/serviceEngineer/serviceEngineerDashboard.dart'
;
import
'package:generp/screens/webtest.dart'
;
import
'package:geolocator/geolocator.dart'
;
import
'package:geolocator/geolocator.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'package:cached_network_image/cached_network_image.dart'
;
import
'package:cached_network_image/cached_network_image.dart'
;
...
@@ -126,8 +127,8 @@ class _MyHomePageState extends State<MyHomePage> {
...
@@ -126,8 +127,8 @@ class _MyHomePageState extends State<MyHomePage> {
"Nearby"
,
"Nearby"
,
"Inventory"
,
"Inventory"
,
"Whizzdom"
,
"Whizzdom"
,
//
"CRM",
"CRM"
,
//
"Finance",
"Finance"
,
];
];
final
icons
=
[
final
icons
=
[
"assets/svg/home_icons_1.svg"
,
"assets/svg/home_icons_1.svg"
,
...
@@ -137,8 +138,8 @@ class _MyHomePageState extends State<MyHomePage> {
...
@@ -137,8 +138,8 @@ class _MyHomePageState extends State<MyHomePage> {
"assets/svg/home_icons_5.svg"
,
"assets/svg/home_icons_5.svg"
,
"assets/svg/home_icons_6.svg"
,
"assets/svg/home_icons_6.svg"
,
"assets/svg/home_icons_81.svg"
,
"assets/svg/home_icons_81.svg"
,
//
"assets/svg/home_icons_8.svg",
"assets/svg/home_icons_8.svg"
,
//
"assets/svg/home_icons_8.svg",
"assets/svg/home_icons_8.svg"
,
];
];
final
requiredRoles
=
[
final
requiredRoles
=
[
"430"
,
"430"
,
...
@@ -148,8 +149,8 @@ class _MyHomePageState extends State<MyHomePage> {
...
@@ -148,8 +149,8 @@ class _MyHomePageState extends State<MyHomePage> {
"433"
,
"433"
,
"432"
,
"432"
,
"431"
,
"431"
,
//
"431",
"431"
,
//
"431",
"431"
,
];
];
final
filteredItems
=
<
Map
<
String
,
String
>>[];
final
filteredItems
=
<
Map
<
String
,
String
>>[];
...
@@ -444,13 +445,13 @@ class _MyHomePageState extends State<MyHomePage> {
...
@@ -444,13 +445,13 @@ class _MyHomePageState extends State<MyHomePage> {
//res = await Navigator.push(context, MaterialPageRoute(builder: (context)=>CRMScreen()));
//res = await Navigator.push(context, MaterialPageRoute(builder: (context)=>CRMScreen()));
break
;
break
;
case
"Finance"
:
case
"Finance"
:
//
res = await Navigator.push(
res
=
await
Navigator
.
push
(
//
context,
context
,
//
MaterialPageRoute(
MaterialPageRoute
(
//
builder:
builder:
//
(context) => Financedashboard(),
(
context
)
=>
Financedashboard
(),
//
),
),
//
);
);
break
;
break
;
default
:
default
:
print
(
"111"
);
print
(
"111"
);
...
...
lib/screens/LoginScreen.dart
View file @
94df616d
...
@@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart';
...
@@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart';
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'
;
import
'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'
;
import
'package:flutter_svg/flutter_svg.dart'
;
import
'package:generp/Notifiers/loginNotifier.dart'
;
import
'package:generp/Notifiers/loginNotifier.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'package:share_plus/share_plus.dart'
;
import
'package:share_plus/share_plus.dart'
;
...
@@ -151,455 +152,453 @@ class _LoginScreenState extends State<LoginScreen>
...
@@ -151,455 +152,453 @@ class _LoginScreenState extends State<LoginScreen>
}
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
var
loginProv
=
Provider
.
of
<
Loginnotifier
>(
context
,
listen:
true
);
double
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
double
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
double
screenHeight
=
MediaQuery
.
of
(
context
).
size
.
height
;
double
screenHeight
=
MediaQuery
.
of
(
context
).
size
.
height
;
return
WillPopScope
(
return
Consumer
<
Loginnotifier
>(
onWillPop:
onBackPressed
,
builder:
(
context
,
loginProv
,
child
)
{
child:
Scaffold
(
return
WillPopScope
(
resizeToAvoidBottomInset:
true
,
onWillPop:
onBackPressed
,
backgroundColor:
AppColors
.
scaffold_bg_color
,
child:
Scaffold
(
body:
KeyboardVisibilityProvider
(
resizeToAvoidBottomInset:
true
,
controller:
_keyboardVisibilityController
,
backgroundColor:
AppColors
.
scaffold_bg_color
,
child:
Stack
(
body:
KeyboardVisibilityProvider
(
alignment:
Alignment
.
center
,
controller:
_keyboardVisibilityController
,
children:
[
child:
Stack
(
// Background scrolling logos
alignment:
Alignment
.
center
,
ListView
.
builder
(
children:
[
controller:
_scrollController
,
// Background scrolling logos
itemBuilder:
(
context
,
index
)
{
ListView
.
builder
(
int
logoIndex
=
index
%
logos
.
length
;
controller:
_scrollController
,
return
Padding
(
itemBuilder:
(
context
,
index
)
{
padding:
const
EdgeInsets
.
all
(
3.0
),
int
logoIndex
=
index
%
logos
.
length
;
child:
CustomGridRow
(
logos:
logos
,
logoIndex:
logoIndex
),
return
Padding
(
);
padding:
const
EdgeInsets
.
all
(
3.0
),
},
child:
CustomGridRow
(
logos:
logos
,
logoIndex:
logoIndex
),
),
);
AnimatedPositioned
(
},
bottom:
0
,
left:
0
,
right:
0
,
duration:
Duration
(
milliseconds:
300
),
child:
Container
(
clipBehavior:
Clip
.
antiAlias
,
decoration:
BoxDecoration
(
gradient:
LinearGradient
(
begin:
Alignment
(-
0.00
,
-
1.00
),
end:
Alignment
(
0
,
1
),
colors:
[
Colors
.
white
.
withOpacity
(
0.0
),
// Fully transparent at the very top
Colors
.
white
.
withOpacity
(
0.3
),
// Light fade-in
Colors
.
white
.
withOpacity
(
0.6
),
// Mid fade
Colors
.
white
,
// Solid white for the rest
],
stops:
[
0.0
,
0.05
,
0.1
,
0.15
],
),
),
),
child:
SingleChildScrollView
(
AnimatedPositioned
(
child:
Stack
(
bottom:
0
,
alignment:
Alignment
.
center
,
left:
0
,
children:
[
right:
0
,
Container
(
duration:
Duration
(
milliseconds:
300
),
child:
Container
(
clipBehavior:
Clip
.
antiAlias
,
decoration:
BoxDecoration
(
gradient:
LinearGradient
(
begin:
Alignment
(-
0.00
,
-
1.00
),
end:
Alignment
(
0
,
1
),
colors:
[
Colors
.
white
.
withOpacity
(
0.0
),
// Fully transparent at the very top
Colors
.
white
.
withOpacity
(
0.3
),
// Light fade-in
Colors
.
white
.
withOpacity
(
0.6
),
// Mid fade
Colors
.
white
,
// Solid white for the rest
],
stops:
[
0.0
,
0.05
,
0.1
,
0.15
],
),
),
child:
SingleChildScrollView
(
child:
Stack
(
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
padding:
EdgeInsets
.
symmetric
(
children:
[
horizontal:
15
,
Container
(
vertical:
10
,
alignment:
Alignment
.
center
,
),
padding:
EdgeInsets
.
symmetric
(
child:
Column
(
horizontal:
15
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
vertical:
10
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
AnimatedContainer
(
duration:
const
Duration
(
milliseconds:
1200
),
curve:
Curves
.
easeInOut
,
child:
_isTextFieldFocused
?
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
Expanded
(
flex:
1
,
child:
SizedBox
(
width:
10
),
),
Expanded
(
flex:
2
,
child:
Image
.
asset
(
"assets/images/gen_logo.png"
,
),
),
const
SizedBox
(
width:
10
),
Expanded
(
flex:
3
,
child:
Image
.
asset
(
"assets/images/gen_logo_grad.png"
),
),
Expanded
(
flex:
1
,
child:
SizedBox
(
width:
10
),
),
],
)
:
Column
(
children:
[
Container
(
width:
180
,
height:
120
,
child:
Image
.
asset
(
"assets/images/gen_logo.png"
,
),
),
Image
.
asset
(
"assets/images/gen_logo_grad.png"
,
width:
150
,),
],
),
),
SizedBox
(
height:
10
,),
Text
(
"Login to enter"
,
style:
TextStyle
(
fontSize:
14
,
fontFamily:
"JakartaMedium"
,
color:
AppColors
.
app_blue
,
),
),
Container
(
padding:
EdgeInsets
.
only
(
left:
10
,
bottom:
5
),
alignment:
Alignment
.
topLeft
,
child:
Text
(
"Email ID"
,
style:
TextStyle
(
color:
AppColors
.
semi_black
,
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
),
),
),
),
Container
(
child:
Column
(
height:
48
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
alignment:
Alignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
decoration:
BoxDecoration
(
children:
[
color:
AppColors
.
text_field_color
,
AnimatedContainer
(
borderRadius:
BorderRadius
.
circular
(
14
),
duration:
const
Duration
(
milliseconds:
1200
),
border:
_emailFocusNode
.
hasFocus
?
Border
.
all
(
color:
AppColors
.
app_blue
,
width:
0.5
):
null
curve:
Curves
.
easeInOut
,
),
child:
// alignment: Alignment.center,
_isTextFieldFocused
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
),
?
Row
(
child:
Padding
(
mainAxisAlignment:
padding:
const
EdgeInsets
.
fromLTRB
(
MainAxisAlignment
.
center
,
10.0
,
crossAxisAlignment:
0.0
,
CrossAxisAlignment
.
center
,
15
,
children:
[
0
,
Expanded
(
flex:
1
,
child:
SizedBox
(
width:
10
),
),
Expanded
(
flex:
2
,
child:
Image
.
asset
(
"assets/images/gen_logo.png"
,
),
),
const
SizedBox
(
width:
10
),
Expanded
(
flex:
3
,
child:
Image
.
asset
(
"assets/images/gen_logo_grad.png"
),
),
Expanded
(
flex:
1
,
child:
SizedBox
(
width:
10
),
),
],
)
:
Column
(
children:
[
Container
(
width:
180
,
height:
120
,
child:
Image
.
asset
(
"assets/images/gen_logo.png"
,
),
),
Image
.
asset
(
"assets/images/gen_logo_grad.png"
,
width:
150
,),
],
),
),
),
child:
TextField
(
SizedBox
(
height:
10
,),
controller:
email
,
Text
(
keyboardType:
TextInputType
.
emailAddress
,
"Login to enter"
,
focusNode:
_emailFocusNode
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
14
fontSize:
14
,
fontFamily:
"JakartaMedium"
,
color:
AppColors
.
app_blue
,
),
),
onChanged:
(
value
)
{
),
loginProv
.
updateEmail
(
email
.
text
);
Container
(
},
padding:
EdgeInsets
.
only
(
left:
10
,
bottom:
5
),
onTapOutside:
(
event
)
{
alignment:
Alignment
.
topLeft
,
// Handle onTapOutside
child:
Text
(
FocusScope
.
of
(
context
).
unfocus
();
"Email ID"
,
},
style:
TextStyle
(
decoration:
InputDecoration
(
color:
AppColors
.
semi_black
,
isDense:
true
,
fontFamily:
"JakartaMedium"
,
hintStyle:
TextStyle
(
fontWeight:
FontWeight
.
w400
,
fontSize:
14
,
fontSize:
14
,
color:
Color
(
0xFF818181
)
),
),
//contentPadding: EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0),
enabledBorder:
InputBorder
.
none
,
focusedBorder:
InputBorder
.
none
,
hintText:
'Enter Your Email'
,
),
),
),
),
),
Container
(
),
height:
48
,
if
(
loginProv
.
emailError
!=
null
)
...[
alignment:
Alignment
.
center
,
Container
(
decoration:
BoxDecoration
(
alignment:
Alignment
.
topLeft
,
color:
AppColors
.
text_field_color
,
margin:
EdgeInsets
.
only
(
borderRadius:
BorderRadius
.
circular
(
14
),
top:
2.5
,
border:
_emailFocusNode
.
hasFocus
?
Border
.
all
(
color:
AppColors
.
app_blue
,
width:
0.5
):
null
bottom:
2.5
,
left:
25
,
),
child:
Text
(
loginProv
.
emailError
,
textAlign:
TextAlign
.
start
,
style:
TextStyle
(
color:
Colors
.
red
),
),
),
]
else
...[
SizedBox
(
height:
10.0
),
],
Container
(
padding:
EdgeInsets
.
only
(
left:
10
,
bottom:
5
),
alignment:
Alignment
.
topLeft
,
child:
Text
(
"Password"
,
style:
TextStyle
(
color:
AppColors
.
semi_black
,
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
),
),
),
Container
(
height:
48
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
AppColors
.
text_field_color
,
borderRadius:
BorderRadius
.
circular
(
14
),
border:
_passwordFocusNode
.
hasFocus
?
Border
.
all
(
color:
AppColors
.
app_blue
,
width:
0.5
):
null
),
// alignment: Alignment.center,
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
),
child:
Padding
(
padding:
const
EdgeInsets
.
fromLTRB
(
10.0
,
0.0
,
0
,
0
,
),
child:
TextField
(
controller:
password
,
focusNode:
_passwordFocusNode
,
obscureText:
!
loginProv
.
pwdVisible
,
keyboardType:
TextInputType
.
visiblePassword
,
style:
TextStyle
(
fontSize:
14
,
),
),
onChanged:
(
value
)
{
// alignment: Alignment.center,
loginProv
.
updatePassword
(
password
.
text
);
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
),
},
child:
Padding
(
onEditingComplete:
()
{
padding:
const
EdgeInsets
.
fromLTRB
(
10.0
,
},
0.0
,
decoration:
InputDecoration
(
15
,
contentPadding:
EdgeInsets
.
fromLTRB
(
0
,
10
,
0
,
0
,
0
,
),
),
hintText:
"Enter Password"
,
child:
TextField
(
suffixIcon:
IconButton
(
controller:
email
,
icon:
Icon
(
keyboardType:
TextInputType
.
emailAddress
,
loginProv
.
pwdVisible
focusNode:
_emailFocusNode
,
?
CupertinoIcons
.
eye_solid
style:
TextStyle
(
:
CupertinoIcons
.
eye_slash_fill
,
fontSize:
14
size:
30
,
),
),
on
Pressed:
(
)
{
on
Changed:
(
value
)
{
loginProv
.
visibility_ov
(
);
loginProv
.
updateEmail
(
email
.
text
);
},
},
onTapOutside:
(
event
)
{
// Handle onTapOutside
FocusScope
.
of
(
context
).
unfocus
();
},
decoration:
InputDecoration
(
isDense:
true
,
hintStyle:
TextStyle
(
fontWeight:
FontWeight
.
w400
,
fontSize:
14
,
color:
Color
(
0xFF818181
)
),
//contentPadding: EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0),
enabledBorder:
InputBorder
.
none
,
focusedBorder:
InputBorder
.
none
,
hintText:
'Enter Your Email'
,
),
),
),
),
if
(
loginProv
.
emailError
!=
null
)
...[
Container
(
alignment:
Alignment
.
topLeft
,
margin:
EdgeInsets
.
only
(
top:
2.5
,
bottom:
2.5
,
left:
25
,
),
),
hintStyle:
TextStyle
(
child:
Text
(
loginProv
.
emailError
,
textAlign:
TextAlign
.
start
,
style:
TextStyle
(
color:
Colors
.
red
),
),
),
]
else
...[
SizedBox
(
height:
10.0
),
],
Container
(
padding:
EdgeInsets
.
only
(
left:
10
,
bottom:
5
),
alignment:
Alignment
.
topLeft
,
child:
Text
(
"Password"
,
style:
TextStyle
(
color:
AppColors
.
semi_black
,
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
fontSize:
14
,
color:
Color
(
0xFF818181
),
fontWeight:
FontWeight
.
w400
,
),
),
isDense:
true
,
enabledBorder:
InputBorder
.
none
,
focusedBorder:
InputBorder
.
none
,
),
),
),
),
),
Container
(
),
height:
48
,
if
(
loginProv
.
passwordError
!=
null
)
...[
Container
(
alignment:
Alignment
.
topLeft
,
margin:
EdgeInsets
.
only
(
top:
2.5
,
bottom:
2.5
,
left:
25
,
),
child:
Text
(
loginProv
.
passwordError
,
textAlign:
TextAlign
.
start
,
style:
TextStyle
(
color:
Colors
.
red
),
),
),
]
else
...[
SizedBox
(
height:
25.0
),
],
Container
(
child:
InkWell
(
onTap:
()
{
// LoginApiFunction();
loginProv
.
LoginApiFunction
(
context
,
email
.
text
,
password
.
text
);
var
f
=
FocusScope
.
of
(
context
);
if
(!
f
.
hasPrimaryFocus
)
{
f
.
unfocus
();
}
// Navigator.push(context,MaterialPageRoute(builder: (context)=>Profile()));
},
child:
Container
(
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
height:
45
,
width:
screenWidth
,
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
,
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
loginProv
.
isButtonEnabled
?
AppColors
.
app_blue
:
AppColors
.
button_disabled
,
//1487C9
color:
AppColors
.
text_field_color
,
borderRadius:
BorderRadius
.
circular
(
15.0
),
borderRadius:
BorderRadius
.
circular
(
14
),
border:
_passwordFocusNode
.
hasFocus
?
Border
.
all
(
color:
AppColors
.
app_blue
,
width:
0.5
):
null
),
),
child:
Center
(
// alignment: Alignment.center,
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
),
child:
Padding
(
padding:
const
EdgeInsets
.
fromLTRB
(
10.0
,
0.0
,
0
,
0
,
),
child:
TextField
(
controller:
password
,
focusNode:
_passwordFocusNode
,
obscureText:
!
loginProv
.
pwdVisible
,
keyboardType:
TextInputType
.
visiblePassword
,
style:
TextStyle
(
fontSize:
14
,
),
onChanged:
(
value
)
{
loginProv
.
updatePassword
(
password
.
text
);
},
onEditingComplete:
()
{
},
decoration:
InputDecoration
(
contentPadding:
EdgeInsets
.
fromLTRB
(
0
,
10
,
0
,
0
,
),
hintText:
"Enter Password"
,
suffixIcon:
IconButton
(
icon:
Icon
(
loginProv
.
pwdVisible
?
CupertinoIcons
.
eye_solid
:
CupertinoIcons
.
eye_slash_fill
,
size:
30
,
),
onPressed:
()
{
loginProv
.
visibility_ov
();
},
),
hintStyle:
TextStyle
(
fontSize:
14
,
color:
Color
(
0xFF818181
),
fontWeight:
FontWeight
.
w400
,
),
isDense:
true
,
enabledBorder:
InputBorder
.
none
,
focusedBorder:
InputBorder
.
none
,
),
),
),
),
if
(
loginProv
.
passwordError
!=
null
)
...[
Container
(
alignment:
Alignment
.
topLeft
,
margin:
EdgeInsets
.
only
(
top:
2.5
,
bottom:
2.5
,
left:
25
,
),
child:
Text
(
child:
Text
(
"Login"
,
loginProv
.
passwordError
,
textAlign:
TextAlign
.
center
,
textAlign:
TextAlign
.
start
,
style:
TextStyle
(
color:
Colors
.
white
,
style:
TextStyle
(
color:
Colors
.
red
),
fontFamily:
"JakartaRegular"
,),
),
),
]
else
...[
SizedBox
(
height:
25.0
),
],
Container
(
child:
InkWell
(
onTap:
()
{
// LoginApiFunction();
loginProv
.
LoginApiFunction
(
context
,
email
.
text
,
password
.
text
);
var
f
=
FocusScope
.
of
(
context
);
if
(!
f
.
hasPrimaryFocus
)
{
f
.
unfocus
();
}
// Navigator.push(context,MaterialPageRoute(builder: (context)=>Profile()));
},
child:
Container
(
alignment:
Alignment
.
center
,
height:
45
,
width:
screenWidth
,
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
,
),
decoration:
BoxDecoration
(
color:
loginProv
.
isButtonEnabled
?
AppColors
.
app_blue
:
AppColors
.
button_disabled
,
//1487C9
borderRadius:
BorderRadius
.
circular
(
15.0
),
),
child:
Center
(
child:
Text
(
"Login"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
color:
Colors
.
white
,
fontFamily:
"JakartaRegular"
,),
),
),
),
),
),
),
),
),
)
,
]
,
),
),
]
,
)
,
)
,
]
,
),
),
]
,
)
,
),
),
),
),
),
Positioned
(
),
top:
50
,
Positioned
(
right:
20
,
top:
50
,
child:
InkResponse
(
right:
20
,
child:
InkResponse
(
child:
GestureDetector
(
child:
GestureDetector
(
onTap:
()
async
{
onTap:
()
async
{
await
tooltipcontroller
.
showTooltip
();
await
tooltipcontroller
.
showTooltip
();
},
},
child:
SuperTooltip
(
child:
SuperTooltip
(
controller:
tooltipcontroller
,
controller:
tooltipcontroller
,
popupDirection:
TooltipDirection
.
down
,
popupDirection:
TooltipDirection
.
down
,
backgroundColor:
Colors
.
white
,
backgroundColor:
Colors
.
white
,
borderColor:
Colors
.
white
,
borderColor:
Colors
.
white
,
showCloseButton:
true
,
showCloseButton:
true
,
left:
50
,
left:
50
,
right:
30
,
right:
30
,
barrierColor:
Colors
.
transparent
,
barrierColor:
Colors
.
transparent
,
arrowTipDistance:
20.0
,
arrowTipDistance:
20.0
,
minimumOutsideMargin:
120
,
minimumOutsideMargin:
120
,
arrowBaseWidth:
20.0
,
arrowBaseWidth:
20.0
,
arrowLength:
20.0
,
arrowLength:
20.0
,
borderWidth:
2.0
,
borderWidth:
2.0
,
constraints:
const
BoxConstraints
(
constraints:
const
BoxConstraints
(
minHeight:
0.0
,
minHeight:
0.0
,
maxHeight:
100
,
maxHeight:
100
,
minWidth:
0.0
,
minWidth:
0.0
,
maxWidth:
100
,
maxWidth:
100
,
),
),
touchThroughAreaShape:
ClipAreaShape
.
rectangle
,
touchThroughAreaShape:
ClipAreaShape
.
rectangle
,
touchThroughAreaCornerRadius:
30
,
touchThroughAreaCornerRadius:
30
,
content:
Container
(
content:
Container
(
height:
100
,
height:
100
,
child:
Column
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
Text
(
"Device ID"
,
style:
TextStyle
(
fontSize:
16
,
fontFamily:
"JakartaMedium"
,
color:
AppColors
.
app_blue
),),
SizedBox
(
height:
15
,),
Row
(
mainAxisAlignment:
MainAxisAlignment
.
start
,
children:
[
children:
[
Container
(
Text
(
"Device ID"
,
height:
50
,
style:
TextStyle
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
10
),
fontSize:
16
,
decoration:
BoxDecoration
(
fontFamily:
"JakartaMedium"
,
borderRadius:
BorderRadius
.
circular
(
18
),
color:
AppColors
.
app_blue
color:
AppColors
.
text_field_color
),),
),
SizedBox
(
height:
15
,),
child:
Row
(
Row
(
children:
[
mainAxisAlignment:
MainAxisAlignment
.
start
,
Container
(
children:
[
width:
180
,
Container
(
height:
45
,
height:
50
,
alignment:
Alignment
.
center
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
10
),
margin:
EdgeInsets
.
only
(
right:
5.0
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
18
),
borderRadius:
BorderRadius
.
circular
(
10.0
)),
color:
AppColors
.
text_field_color
child:
Text
(
),
'
${loginProv.deviceId}
'
,
child:
Row
(
style:
TextStyle
(
children:
[
fontSize:
16
,
Container
(
color:
AppColors
.
semi_black
width:
180
,
height:
45
,
alignment:
Alignment
.
center
,
margin:
EdgeInsets
.
only
(
right:
5.0
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
10.0
)),
child:
Text
(
'
${loginProv.deviceId}
'
,
style:
TextStyle
(
fontSize:
16
,
color:
AppColors
.
semi_black
),
)),
Container
(
child:
InkWell
(
onTap:
()
async
{
Clipboard
.
setData
(
ClipboardData
(
text:
loginProv
.
deviceId
.
trim
()));
toast
(
context
,
"Device ID has been copied!"
);
},
child:
SvgPicture
.
asset
(
"assets/svg/copy_ic.svg"
),
),
),
)),
Container
(
child:
InkWell
(
onTap:
()
async
{
Clipboard
.
setData
(
ClipboardData
(
text:
loginProv
.
deviceId
.
trim
()));
toast
(
context
,
"Device ID has been copied!"
);
},
child:
Icon
(
Icons
.
copy
),
),
)
,
]
,
),
),
],
),
),
Spacer
(),
),
Container
(
Spacer
(),
width:
60
,
Container
(
height:
50
,
width:
60
,
decoration:
BoxDecoration
(
height:
50
,
color:
AppColors
.
app_blue
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
18
)
color:
AppColors
.
app_blue
,
borderRadius:
BorderRadius
.
circular
(
18
)
),
child:
InkWell
(
onTap:
()
{
Share
.
share
(
"
${loginProv.deviceId}
"
);
},
child:
Icon
(
Icons
.
share_outlined
,
color:
Colors
.
white
,
),
),
)),
child:
InkWell
(
onTap:
()
{
Share
.
share
(
"
${loginProv.deviceId}
"
);
},
child:
SvgPicture
.
asset
(
"assets/svg/share_ic.svg"
,
height:
25
,
width:
25
,
fit:
BoxFit
.
scaleDown
,),
)),
],
),
],
],
),
),
],
),
),
child:
Align
(
alignment:
Alignment
.
topRight
,
child:
Container
(
width:
100
,
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
5
),
decoration:
BoxDecoration
(
color:
AppColors
.
overlay_box_color
,
borderRadius:
BorderRadius
.
circular
(
8
),
border:
Border
.
all
(
color:
AppColors
.
app_blue
,
width:
0.5
),
),
),
child:
Center
(
child:
Align
(
child:
Text
(
alignment:
Alignment
.
topRight
,
"Device ID"
,
child:
Container
(
textAlign:
TextAlign
.
center
,
width:
100
,
style:
TextStyle
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
5
),
color:
AppColors
.
app_blue
,
decoration:
BoxDecoration
(
fontSize:
14
,
color:
AppColors
.
overlay_box_color
,
borderRadius:
BorderRadius
.
circular
(
8
),
border:
Border
.
all
(
color:
AppColors
.
app_blue
,
width:
0.5
),
),
child:
Center
(
child:
Text
(
"Device ID"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
color:
AppColors
.
app_blue
,
fontSize:
14
,
),
),
),
),
),
),
),
),
...
@@ -607,14 +606,14 @@ class _LoginScreenState extends State<LoginScreen>
...
@@ -607,14 +606,14 @@ class _LoginScreenState extends State<LoginScreen>
),
),
),
),
),
),
),
),
],
],
),
),
// bottomNavigationBar: ,
),
),
),
);
// bottomNavigationBar: ,
}
),
);
);
}
}
...
...
lib/screens/WebERPScreen.dart
View file @
94df616d
import
'dart:async'
;
import
'dart:async'
;
import
'dart:io'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_local_notifications/flutter_local_notifications.dart'
;
import
'package:generp/Utils/commonServices.dart'
;
import
'package:http/http.dart'
as
http
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_download_manager/flutter_download_manager.dart'
;
import
'package:flutter_download_manager/flutter_download_manager.dart'
;
...
@@ -9,10 +13,12 @@ import 'package:flutter_svg/svg.dart';
...
@@ -9,10 +13,12 @@ import 'package:flutter_svg/svg.dart';
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:path_provider/path_provider.dart'
;
import
'package:permission_handler/permission_handler.dart'
;
import
'package:permission_handler/permission_handler.dart'
;
import
'dart:math'
;
import
'dart:math'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:url_launcher/url_launcher.dart'
;
const
MAX_PROGRESS
=
100
;
const
MAX_PROGRESS
=
100
;
Future
main
(
)
async
{
Future
main
(
)
async
{
...
@@ -35,34 +41,57 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -35,34 +41,57 @@ class _WebErpScreenState extends State<WebErpScreen> {
var
empId
=
""
;
var
empId
=
""
;
var
sessionId
=
""
;
var
sessionId
=
""
;
bool
isLoading
=
true
;
bool
isLoading
=
true
;
InAppWebViewController
?
webViewController
;
InAppWebViewController
?
_
webViewController
;
PullToRefreshController
?
pullToRefreshController
;
PullToRefreshController
?
pullToRefreshController
;
PullToRefreshSettings
pullToRefreshSettings
=
PullToRefreshSettings
(
PullToRefreshSettings
pullToRefreshSettings
=
PullToRefreshSettings
(
color:
AppColors
.
app_blue
,
color:
AppColors
.
app_blue
,
);
);
bool
pullToRefreshEnabled
=
true
;
bool
pullToRefreshEnabled
=
true
;
final
FlutterLocalNotificationsPlugin
_notificationsPlugin
=
FlutterLocalNotificationsPlugin
();
static
const
platform
=
MethodChannel
(
'in.webgrid.generp/download'
);
final
GlobalKey
webViewKey
=
GlobalKey
();
final
GlobalKey
webViewKey
=
GlobalKey
();
var
dl
=
DownloadManager
();
var
dl
=
DownloadManager
();
@override
@override
void
initState
()
{
void
initState
()
{
// loadData();
// loadData();
super
.
initState
();
pullToRefreshController
=
kIsWeb
pullToRefreshController
=
kIsWeb
?
null
?
null
:
PullToRefreshController
(
:
PullToRefreshController
(
settings:
pullToRefreshSettings
,
settings:
pullToRefreshSettings
,
onRefresh:
()
async
{
onRefresh:
()
async
{
if
(
defaultTargetPlatform
==
TargetPlatform
.
android
)
{
if
(
defaultTargetPlatform
==
TargetPlatform
.
android
)
{
webViewController
?.
reload
();
_
webViewController
?.
reload
();
}
else
if
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
)
{
}
else
if
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
)
{
webViewController
?.
loadUrl
(
_
webViewController
?.
loadUrl
(
urlRequest:
urlRequest:
URLRequest
(
url:
await
webViewController
?.
getUrl
()));
URLRequest
(
url:
await
_
webViewController
?.
getUrl
()));
}
}
},
},
);
);
// print("URL:${widget.url}");
// print("URL:${widget.url}");
super
.
initState
();
_initializeNotifications
();
}
Future
<
void
>
_initializeNotifications
()
async
{
const
AndroidInitializationSettings
initializationSettingsAndroid
=
AndroidInitializationSettings
(
'@mipmap/ic_launcher'
);
final
InitializationSettings
initializationSettings
=
InitializationSettings
(
android:
initializationSettingsAndroid
,
);
await
_notificationsPlugin
.
initialize
(
initializationSettings
);
// Create a notification channel for Android
const
AndroidNotificationChannel
channel
=
AndroidNotificationChannel
(
'download_channel'
,
'Downloads'
,
description:
'Notifications for file downloads'
,
importance:
Importance
.
high
,
);
await
_notificationsPlugin
.
resolvePlatformSpecificImplementation
<
AndroidFlutterLocalNotificationsPlugin
>()
?.
createNotificationChannel
(
channel
);
}
}
@override
@override
...
@@ -73,8 +102,8 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -73,8 +102,8 @@ class _WebErpScreenState extends State<WebErpScreen> {
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
WillPopScope
(
return
WillPopScope
(
onWillPop:
()
async
{
onWillPop:
()
async
{
if
(
await
webViewController
!.
canGoBack
())
{
if
(
await
_
webViewController
!.
canGoBack
())
{
webViewController
!.
goBack
();
_
webViewController
!.
goBack
();
return
false
;
// Prevent default back button behavior
return
false
;
// Prevent default back button behavior
}
}
return
true
;
// Allow default back button behavior
return
true
;
// Allow default back button behavior
...
@@ -90,6 +119,10 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -90,6 +119,10 @@ class _WebErpScreenState extends State<WebErpScreen> {
InAppWebView
(
InAppWebView
(
initialUrlRequest:
URLRequest
(
initialUrlRequest:
URLRequest
(
url:
WebUri
(
widget
.
erp_url
),
url:
WebUri
(
widget
.
erp_url
),
allowsCellularAccess:
true
,
allowsConstrainedNetworkAccess:
true
,
allowsExpensiveNetworkAccess:
true
,
),
),
androidOnGeolocationPermissionsShowPrompt:
androidOnGeolocationPermissionsShowPrompt:
(
InAppWebViewController
controller
,
String
origin
)
async
{
(
InAppWebViewController
controller
,
String
origin
)
async
{
...
@@ -97,7 +130,9 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -97,7 +130,9 @@ class _WebErpScreenState extends State<WebErpScreen> {
origin:
origin
,
allow:
true
,
retain:
true
);
origin:
origin
,
allow:
true
,
retain:
true
);
},
},
initialOptions:
InAppWebViewGroupOptions
(
initialOptions:
InAppWebViewGroupOptions
(
android:
AndroidInAppWebViewOptions
(
android:
AndroidInAppWebViewOptions
(
useWideViewPort:
true
,
useWideViewPort:
true
,
loadWithOverviewMode:
true
,
loadWithOverviewMode:
true
,
allowContentAccess:
true
,
allowContentAccess:
true
,
...
@@ -111,10 +146,25 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -111,10 +146,25 @@ class _WebErpScreenState extends State<WebErpScreen> {
false
,
// Disables displaying zoom controls
false
,
// Disables displaying zoom controls
safeBrowsingEnabled:
true
,
// Enables Safe Browsing
safeBrowsingEnabled:
true
,
// Enables Safe Browsing
clearSessionCache:
true
,
clearSessionCache:
true
,
loadsImagesAutomatically:
true
,
thirdPartyCookiesEnabled:
true
,
blockNetworkImage:
false
,
supportMultipleWindows:
true
,
// Enable camera access
),
),
ios:
IOSInAppWebViewOptions
(
ios:
IOSInAppWebViewOptions
(
allowsInlineMediaPlayback:
true
,
allowsInlineMediaPlayback:
true
,
),
),
crossPlatform:
InAppWebViewOptions
(
javaScriptEnabled:
true
,
useOnDownloadStart:
true
,
allowFileAccessFromFileURLs:
true
,
allowUniversalAccessFromFileURLs:
true
,
mediaPlaybackRequiresUserGesture:
true
,
),
),
),
...
@@ -125,8 +175,22 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -125,8 +175,22 @@ class _WebErpScreenState extends State<WebErpScreen> {
action:
PermissionRequestResponseAction
.
GRANT
);
action:
PermissionRequestResponseAction
.
GRANT
);
},
},
onWebViewCreated:
(
controller
)
{
onWebViewCreated:
(
controller
)
{
webViewController
=
controller
;
_
webViewController
=
controller
;
_controller
.
complete
(
controller
);
_controller
.
complete
(
controller
);
_webViewController
!.
addJavaScriptHandler
(
handlerName:
'MobileAppJavascriptInterface'
,
callback:
(
args
)
{
print
(
"JavaScript called MobileAppJavascriptInterface with args:
$args
"
);
return
{
'status'
:
'success'
};
},
);
_webViewController
!.
addJavaScriptHandler
(
handlerName:
'downloadFile'
,
callback:
(
args
)
async
{
final
url
=
args
[
0
]
as
String
;
await
_handleDownload
(
url
,
''
,
'application/octet-stream'
,
''
);
},
);
},
},
pullToRefreshController:
pullToRefreshController
,
pullToRefreshController:
pullToRefreshController
,
onLoadStart:
(
controller
,
url
)
{
onLoadStart:
(
controller
,
url
)
{
...
@@ -134,6 +198,74 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -134,6 +198,74 @@ class _WebErpScreenState extends State<WebErpScreen> {
isLoading
=
true
;
isLoading
=
true
;
});
});
},
},
initialSettings:
InAppWebViewSettings
(
allowUniversalAccessFromFileURLs:
true
,
allowFileAccessFromFileURLs:
true
,
allowFileAccess:
true
,
allowsInlineMediaPlayback:
true
,
allowsPictureInPictureMediaPlayback:
true
,
allowsBackForwardNavigationGestures:
true
,
iframeAllow:
"camera;microphone;files;media;"
,
domStorageEnabled:
true
,
allowContentAccess:
true
,
javaScriptEnabled:
true
,
supportZoom:
true
,
builtInZoomControls:
true
,
displayZoomControls:
false
,
textZoom:
125
,
blockNetworkImage:
false
,
loadsImagesAutomatically:
true
,
safeBrowsingEnabled:
true
,
useWideViewPort:
true
,
loadWithOverviewMode:
true
,
javaScriptCanOpenWindowsAutomatically:
true
,
mediaPlaybackRequiresUserGesture:
false
,
geolocationEnabled:
true
,
useOnDownloadStart:
true
,
allowsLinkPreview:
true
,
databaseEnabled:
true
,
// Enables the WebView database
clearSessionCache:
true
,
mediaType:
"image/*"
,
),
shouldOverrideUrlLoading:
(
controller
,
navigationAction
)
async
{
var
uri
=
navigationAction
.
request
.
url
!;
print
(
"urib scgefes"
);
print
(
uri
);
print
(
uri
.
scheme
);
if
(
uri
.
scheme
==
"tel"
)
{
// Launch the phone dialer app with the specified phone number
if
(
await
canLaunch
(
uri
.
toString
()))
{
await
launch
(
uri
.
toString
());
return
NavigationActionPolicy
.
CANCEL
;
}
}
else
if
(
uri
.
scheme
==
"mailto"
)
{
if
(
await
canLaunch
(
uri
.
toString
()))
{
await
launch
(
uri
.
toString
());
return
NavigationActionPolicy
.
CANCEL
;
}
}
else
if
(
uri
.
scheme
==
"whatsapp"
)
{
// Launch WhatsApp with the specified chat or phone number
if
(
await
canLaunch
(
uri
.
toString
()))
{
await
launch
(
uri
.
toString
());
return
NavigationActionPolicy
.
CANCEL
;
}
}
// // Check if the URL is trying to access the camera for image upload
// if (uri.scheme == 'camera' && uri.path.contains('/camera/')) {
// // Handle camera image upload here
// // You might want to display a custom UI for image selection or directly trigger the camera
// // You can use platform-specific plugins like image_picker for this purpose
// // Once the image is selected, you can pass it to the web view using JavaScript injection
// if (await canLaunch(uri.toString())) {
// await launch(uri.toString());
// return NavigationActionPolicy.CANCEL;
// }
// }
return
NavigationActionPolicy
.
ALLOW
;
},
onLoadStop:
(
controller
,
url
)
{
onLoadStop:
(
controller
,
url
)
{
pullToRefreshController
?.
endRefreshing
();
pullToRefreshController
?.
endRefreshing
();
return
setState
(()
{
return
setState
(()
{
...
@@ -155,12 +287,28 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -155,12 +287,28 @@ class _WebErpScreenState extends State<WebErpScreen> {
debugPrint
(
debugPrint
(
"JavaScript console message:
${consoleMessage.message}
"
);
"JavaScript console message:
${consoleMessage.message}
"
);
},
},
onDownloadStartRequest:
(
controller
,
url
)
async
{
// onDownloadStartRequest: (controller, url) async {
await
ApiCalling
.
download_files
(
// await ApiCalling.download_files(
empId
,
sessionId
,
"
${url.url}
"
,
context
)
// empId, sessionId, "${url.url}", context)
.
then
((
data
)
=>
{
debugPrint
(
data
)});
// .then((data) => {debugPrint(data)});
//
// },
onDownloadStartRequest:
(
controller
,
downloadStartRequest
)
async
{
await
_handleDownload
(
downloadStartRequest
.
url
.
toString
(),
downloadStartRequest
.
suggestedFilename
!,
downloadStartRequest
.
mimeType
??
'application/octet-stream'
,
downloadStartRequest
.
suggestedFilename
??
''
,
);
},
},
shouldInterceptAjaxRequest:
(
controller
,
ajaxRequest
)
async
{
if
(
ajaxRequest
.
url
.
toString
().
contains
(
'download'
))
{
await
_handleDownload
(
ajaxRequest
.
url
.
toString
(),
''
,
'application/octet-stream'
,
''
);
return
ajaxRequest
;
}
return
ajaxRequest
;
},
),
),
if
(
isLoading
)
...[
Container
(
if
(
isLoading
)
...[
Container
(
color:
Colors
.
white
.
withOpacity
(
0.7
),
color:
Colors
.
white
.
withOpacity
(
0.7
),
...
@@ -200,6 +348,32 @@ class _WebErpScreenState extends State<WebErpScreen> {
...
@@ -200,6 +348,32 @@ class _WebErpScreenState extends State<WebErpScreen> {
),
),
);
);
}
}
Future
<
void
>
_handleDownload
(
String
url
,
String
contentDisposition
,
String
mimeType
,
String
suggestedFilename
)
async
{
// Request notification permission for Android 13+
if
(
await
Permission
.
notification
.
request
().
isGranted
)
{
try
{
// Show custom notification (optional, since DownloadManager shows its own)
// Call native Android Download Manager
final
userAgent
=
'Flutter InAppWebView'
;
await
platform
.
invokeMethod
(
'startDownload'
,
{
'url'
:
url
,
'userAgent'
:
userAgent
,
'contentDisposition'
:
contentDisposition
,
'mimeType'
:
mimeType
,
'suggestedFilename'
:
suggestedFilename
,
});
}
catch
(
e
)
{
print
(
"Download Error
$e
"
);
}
}
else
{
toast
(
context
,
"Notification Permission Denied"
);
}
}
}
}
...
...
lib/screens/finance/AllPaymentRequesitionListsByModes.dart
0 → 100644
View file @
94df616d
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_svg/svg.dart'
;
import
'package:generp/Notifiers/financeProvider/RequestionListProvider.dart'
;
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:generp/screens/finance/FileViewer.dart'
;
import
'package:provider/provider.dart'
;
import
'PaymentRequestionListDetails.dart'
;
class
Allpaymentrequesitionlistsbymodes
extends
StatefulWidget
{
final
String
mode
;
final
String
pageTitleName
;
const
Allpaymentrequesitionlistsbymodes
({
super
.
key
,
required
this
.
mode
,
required
this
.
pageTitleName
,
});
@override
State
<
Allpaymentrequesitionlistsbymodes
>
createState
()
=>
_AllpaymentrequesitionlistsbymodesState
();
}
class
_AllpaymentrequesitionlistsbymodesState
extends
State
<
Allpaymentrequesitionlistsbymodes
>
{
@override
void
initState
()
{
// TODO: implement initState
super
.
initState
();
WidgetsBinding
.
instance
.
addPostFrameCallback
((
timeStamp
)
{
var
provider
=
Provider
.
of
<
Requestionlistprovider
>(
context
,
listen:
false
,
);
provider
.
paymentRequestionListsAPIFunction
(
context
,
widget
.
mode
);
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
Consumer
<
Requestionlistprovider
>(
builder:
(
context
,
provider
,
child
)
{
final
requestLists
=
provider
.
requisitionList
;
return
WillPopScope
(
onWillPop:
()
{
return
onBackPressed
(
context
);
},
child:
Scaffold
(
appBar:
appbar2
(
context
,
widget
.
pageTitleName
,
Row
(
children:
[
InkResponse
(
onTap:
()
{
_showOptionsSheet
(
context
);
},
child:
Icon
(
CupertinoIcons
.
down_arrow
),
),
],
),
),
backgroundColor:
AppColors
.
scaffold_bg_color
,
body:
Container
(
child:
SingleChildScrollView
(
child:
Column
(
children:
[
ListView
.
builder
(
itemCount:
requestLists
.
length
,
shrinkWrap:
true
,
physics:
NeverScrollableScrollPhysics
(),
itemBuilder:
(
context
,
index
)
{
return
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
10
,
),
margin:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
10
,
),
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
16
),
),
child:
Column
(
children:
[
Row
(
children:
[
Expanded
(
flex:
1
,
child:
Container
(
height:
50
,
width:
35
,
padding:
EdgeInsets
.
all
(
8.0
),
decoration:
BoxDecoration
(
color:
Color
(
0xFFFFF3CE
),
borderRadius:
BorderRadius
.
circular
(
8
),
),
child:
SvgPicture
.
asset
(
"assets/svg/fin_ic.svg"
,
),
),
),
SizedBox
(
width:
10
),
Expanded
(
flex:
4
,
child:
SizedBox
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
requestLists
[
index
].
accountName
!,
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
AppColors
.
semi_black
,
),
),
Text
(
"₹"
"
${requestLists[index].amount}
"
,
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
AppColors
.
app_blue
,
),
),
],
),
),
),
Expanded
(
flex:
2
,
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
5
,
vertical:
10
,
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
),
color:
Color
(
0xFFE3FFE0
),
),
child:
Center
(
child:
Text
(
requestLists
[
index
].
status
!,
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
Color
(
0xFF0D9C00
),
),
),
),
),
),
],
),
Divider
(
thickness:
0.5
,
color:
Color
(
0xFFD7D7D7
)),
...
List
.
generate
(
4
,
(
j
)
{
final
headings
=
[
"Requesting Propose"
,
"Attachment"
,
"Requested Date"
,
"Note"
,
];
final
subHeadings
=
[
requestLists
[
index
].
requestingPurpose
,
"View"
,
// requestLists[index].attachmentDirFilePath
requestLists
[
index
].
date
,
requestLists
[
index
].
description
,
];
return
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
5
),
child:
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Expanded
(
child:
Text
(
headings
[
j
],
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
AppColors
.
semi_black
,
),
),
),
Expanded
(
child:
InkResponse
(
onTap:
j
!=
1
?
null
:
()
{
Navigator
.
push
(
context
,
MaterialPageRoute
(
builder:
(
context
,
)
=>
Fileviewer
(
fileName:
requestLists
[
index
]
.
attachmentViewFileName
!,
fileUrl:
requestLists
[
index
]
.
attachmentDirFilePath
!,
),
),
);
},
child:
Text
(
subHeadings
[
j
]!,
style:
TextStyle
(
fontSize:
14
,
color:
j
==
1
?
AppColors
.
app_blue
:
Color
(
0xFF818181
),
decoration:
j
==
1
?
TextDecoration
.
underline
:
TextDecoration
.
none
,
decorationColor:
j
==
1
?
AppColors
.
app_blue
:
AppColors
.
white
,
),
),
),
),
],
),
);
}),
InkResponse
(
onTap:
()
async
{
Navigator
.
push
(
context
,
MaterialPageRoute
(
builder:
(
context
)
=>
Paymentrequestionlistdetails
(
pageName:
widget
.
pageTitleName
,
mode:
widget
.
mode
,
paymentRequestId:
requestLists
[
index
].
id
,
),
),
);
},
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
5
),
child:
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
start
,
children:
[
Text
(
"View Details"
,
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
AppColors
.
app_blue
,
),
),
SizedBox
(
width:
5
),
SvgPicture
.
asset
(
"assets/svg/next_button.svg"
,
),
],
),
),
),
],
),
);
},
),
],
),
),
),
),
);
},
);
}
Future
<
void
>
_showOptionsSheet
(
BuildContext
context
)
{
return
showModalBottomSheet
(
useSafeArea:
true
,
isDismissible:
true
,
isScrollControlled:
true
,
showDragHandle:
true
,
backgroundColor:
Colors
.
white
,
enableDrag:
true
,
context:
context
,
builder:
(
context
)
{
return
StatefulBuilder
(
builder:
(
context
,
setState
)
{
return
SafeArea
(
child:
Consumer
<
Requestionlistprovider
>(
builder:
(
context
,
provider
,
child
)
{
return
Container
(
margin:
EdgeInsets
.
only
(
bottom:
15
,
left:
15
,
right:
15
,
top:
10
,
),
child:
SingleChildScrollView
(
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
SizedBox
(
height:
15
),
...
List
.
generate
(
5
,
(
index
)
{
final
assetnames
=
[
"se_locate_customer"
,
"se_locate_customer"
,
"se_update_complaint"
,
"se_payment_details"
,
"se_payment_details"
,
];
final
Headingnames
=
[
"Copy to Clipboard"
,
"Download CSV"
,
"Download XLSX"
,
"Download PDF"
,
"Print Data"
,
];
return
ListTile
(
onTap:
()
{
switch
(
index
)
{
case
0
:
provider
.
copyToClipboard
(
context
);
break
;
case
1
:
provider
.
downloadCSV
(
context
);
break
;
case
2
:
provider
.
downloadXLS
(
context
);
break
;
case
3
:
provider
.
downloadPDF
(
context
);
break
;
case
4
:
provider
.
printData
(
context
);
break
;
}
},
leading:
SvgPicture
.
asset
(
"assets/svg/
${assetnames[index]}
.svg"
,
),
title:
Text
(
Headingnames
[
index
],
style:
TextStyle
(
fontFamily:
"JakartaMedium"
),
),
trailing:
SvgPicture
.
asset
(
"assets/svg/arrow_right_new.svg"
,
),
);
}),
],
),
),
);
},
),
);
},
);
},
);
}
}
lib/screens/finance/FileViewer.dart
0 → 100644
View file @
94df616d
import
'dart:async'
;
import
'package:cached_network_image/cached_network_image.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_inappwebview/flutter_inappwebview.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'
;
import
'package:url_launcher/url_launcher.dart'
;
import
'package:flutter_pdfview/flutter_pdfview.dart'
;
import
'package:http/http.dart'
as
http
;
import
'dart:typed_data'
;
import
'../../Utils/app_colors.dart'
;
class
Fileviewer
extends
StatefulWidget
{
final
String
fileName
;
final
String
fileUrl
;
const
Fileviewer
({
super
.
key
,
required
this
.
fileName
,
required
this
.
fileUrl
});
@override
State
<
Fileviewer
>
createState
()
=>
_FileviewerState
();
}
class
_FileviewerState
extends
State
<
Fileviewer
>
{
final
Completer
<
InAppWebViewController
>
_controller
=
Completer
<
InAppWebViewController
>();
var
empId
=
""
;
var
sessionId
=
""
;
bool
isLoading
=
true
;
InAppWebViewController
?
webViewController
;
PullToRefreshController
?
pullToRefreshController
;
PullToRefreshSettings
pullToRefreshSettings
=
PullToRefreshSettings
(
color:
AppColors
.
app_blue
,
);
bool
pullToRefreshEnabled
=
true
;
final
GlobalKey
webViewKey
=
GlobalKey
();
String
getFileExtension
(
String
fileName
)
{
print
(
widget
.
fileUrl
);
return
fileName
.
split
(
'.'
).
last
.
toLowerCase
();
}
Future
<
void
>
_launchUrl
(
String
url
)
async
{
final
Uri
uri
=
Uri
.
parse
(
url
);
if
(
await
canLaunchUrl
(
uri
))
{
await
launchUrl
(
uri
,
mode:
LaunchMode
.
externalApplication
);
}
else
{
throw
'Could not launch
$url
'
;
}
}
var
Finalurl
;
@override
void
initState
()
{
// loadData();
pullToRefreshController
=
kIsWeb
?
null
:
PullToRefreshController
(
settings:
pullToRefreshSettings
,
onRefresh:
()
async
{
if
(
defaultTargetPlatform
==
TargetPlatform
.
android
)
{
webViewController
?.
reload
();
}
else
if
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
)
{
webViewController
?.
loadUrl
(
urlRequest:
URLRequest
(
url:
await
webViewController
?.
getUrl
()));
}
},
);
// print("URL:${widget.url}");
super
.
initState
();
}
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
appbar
(
context
,
"File Viewer"
),
body:
fileWidget
(
context
),
);
}
Widget
fileWidget
(
BuildContext
context
){
final
extension
=
getFileExtension
(
widget
.
fileName
);
switch
(
extension
)
{
case
'jpg'
:
case
'jpeg'
:
case
'png'
:
case
'gif'
:
return
CachedNetworkImage
(
imageUrl:
widget
.
fileUrl
,
placeholder:
(
context
,
url
)
=>
const
Center
(
child:
CircularProgressIndicator
()),
errorWidget:
(
context
,
url
,
error
)
=>
const
Icon
(
Icons
.
error
),
fit:
BoxFit
.
contain
,
);
case
'pdf'
:
return
SfPdfViewer
.
network
(
widget
.
fileUrl
,
key:
GlobalKey
(),
);
case
'doc'
:
case
'docx'
:
case
'xls'
:
case
'xlsx'
:
return
InAppWebView
(
initialUrlRequest:
URLRequest
(
url:
WebUri
(
widget
.
fileUrl
),
),
androidOnGeolocationPermissionsShowPrompt:
(
InAppWebViewController
controller
,
String
origin
)
async
{
return
GeolocationPermissionShowPromptResponse
(
origin:
origin
,
allow:
true
,
retain:
true
);
},
initialOptions:
InAppWebViewGroupOptions
(
android:
AndroidInAppWebViewOptions
(
useWideViewPort:
true
,
loadWithOverviewMode:
true
,
allowContentAccess:
true
,
geolocationEnabled:
true
,
allowFileAccess:
true
,
databaseEnabled:
true
,
// Enables the WebView database
domStorageEnabled:
true
,
// Enables DOM storage
builtInZoomControls:
true
,
// Enables the built-in zoom controls
displayZoomControls:
false
,
// Disables displaying zoom controls
safeBrowsingEnabled:
true
,
// Enables Safe Browsing
clearSessionCache:
true
,
),
ios:
IOSInAppWebViewOptions
(
allowsInlineMediaPlayback:
true
,
),
),
androidOnPermissionRequest:
(
InAppWebViewController
controller
,
String
origin
,
List
<
String
>
resources
)
async
{
return
PermissionRequestResponse
(
resources:
resources
,
action:
PermissionRequestResponseAction
.
GRANT
);
},
onWebViewCreated:
(
controller
)
{
webViewController
=
controller
;
_controller
.
complete
(
controller
);
},
pullToRefreshController:
pullToRefreshController
,
onLoadStart:
(
controller
,
url
)
{
return
setState
(()
{
isLoading
=
true
;
});
},
onLoadStop:
(
controller
,
url
)
{
pullToRefreshController
?.
endRefreshing
();
return
setState
(()
{
isLoading
=
false
;
});
},
onReceivedError:
(
controller
,
request
,
error
)
{
pullToRefreshController
?.
endRefreshing
();
},
onProgressChanged:
(
controller
,
progress
)
{
if
(
progress
==
100
)
{
pullToRefreshController
?.
endRefreshing
();
}
},
onConsoleMessage:
(
controller
,
consoleMessage
)
{
if
(
kDebugMode
)
{
debugPrint
(
"consoleMessage
${consoleMessage}
"
);
}
debugPrint
(
"JavaScript console message:
${consoleMessage.message}
"
);
},
);
default
:
return
Container
();
}
}
Future
<
Uint8List
?>
_loadPdf
(
String
url
)
async
{
try
{
final
response
=
await
http
.
get
(
Uri
.
parse
(
url
));
if
(
response
!=
null
){
if
(
response
.
statusCode
==
200
)
{
print
(
response
.
bodyBytes
);
return
response
.
bodyBytes
;
}
}
}
catch
(
e
)
{
print
(
'Error loading PDF:
$e
'
);
}
return
null
;
}
}
lib/screens/finance/PaymentRequestionListDetails.dart
0 → 100644
View file @
94df616d
import
'package:dropdown_button2/dropdown_button2.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_svg/svg.dart'
;
import
'package:generp/Notifiers/financeProvider/RequesitionLidtDetailsProvider.dart'
;
import
'package:generp/Notifiers/financeProvider/approveRejectPaymentRequestResponse.dart'
;
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:provider/provider.dart'
;
import
'FileViewer.dart'
;
class
Paymentrequestionlistdetails
extends
StatefulWidget
{
final
paymentRequestId
;
final
pageName
;
final
mode
;
const
Paymentrequestionlistdetails
({
super
.
key
,
required
this
.
mode
,
required
this
.
paymentRequestId
,
required
this
.
pageName
,
});
@override
State
<
Paymentrequestionlistdetails
>
createState
()
=>
_PaymentrequestionlistdetailsState
();
}
class
_PaymentrequestionlistdetailsState
extends
State
<
Paymentrequestionlistdetails
>
{
TextEditingController
requestedAmount
=
TextEditingController
();
TextEditingController
approvedAmount
=
TextEditingController
();
TextEditingController
remarks
=
TextEditingController
();
FocusNode
request
=
FocusNode
();
FocusNode
approve
=
FocusNode
();
FocusNode
remarkNode
=
FocusNode
();
@override
void
initState
()
{
// TODO: implement initState
super
.
initState
();
WidgetsBinding
.
instance
.
addPostFrameCallback
((
timeStamp
)
{
var
provider
=
Provider
.
of
<
Requesitionlidtdetailsprovider
>(
context
,
listen:
false
,
);
provider
.
paymentRequesitionDetails
(
context
,
widget
.
paymentRequestId
);
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
Consumer
<
Requesitionlidtdetailsprovider
>(
builder:
(
context
,
provider
,
child
)
{
var
payment_det
=
provider
.
paymentsDetails
;
var
req_det
=
provider
.
requestsDetails
;
return
WillPopScope
(
child:
Scaffold
(
appBar:
appbar
(
context
,
widget
.
pageName
),
backgroundColor:
AppColors
.
scaffold_bg_color
,
body:
Container
(
child:
SingleChildScrollView
(
child:
Container
(
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
16
),
),
margin:
EdgeInsets
.
symmetric
(
vertical:
10
,
horizontal:
10
),
padding:
EdgeInsets
.
symmetric
(
vertical:
10
,
horizontal:
10
),
child:
Column
(
children:
[
Row
(
children:
[
Expanded
(
flex:
1
,
child:
Container
(
height:
50
,
width:
35
,
padding:
EdgeInsets
.
all
(
8.0
),
decoration:
BoxDecoration
(
color:
Color
(
0xFFFFF3CE
),
borderRadius:
BorderRadius
.
circular
(
8
),
),
child:
SvgPicture
.
asset
(
"assets/svg/fin_ic.svg"
),
),
),
SizedBox
(
width:
10
),
Expanded
(
flex:
4
,
child:
SizedBox
(
child:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Text
(
req_det
.
accountName
!,
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
AppColors
.
semi_black
,
),
),
Text
(
"₹"
"
${req_det.amount}
"
,
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
AppColors
.
app_blue
,
),
),
],
),
),
),
Expanded
(
flex:
2
,
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
5
,
vertical:
10
,
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
),
color:
Color
(
0xFFE3FFE0
),
),
child:
Center
(
child:
Text
(
req_det
.
status
!,
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
Color
(
0xFF0D9C00
),
),
),
),
),
),
],
),
Divider
(
thickness:
0.5
,
color:
Color
(
0xFFD7D7D7
)),
...
List
.
generate
(
provider
.
subHeadings
.
length
,
(
j
)
{
return
Container
(
padding:
EdgeInsets
.
symmetric
(
vertical:
7
),
child:
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Expanded
(
child:
Text
(
provider
.
Headings
[
j
],
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontSize:
14
,
color:
AppColors
.
semi_black
,
),
),
),
Expanded
(
child:
InkResponse
(
onTap:
()
{
if
(
provider
.
Headings
[
j
]
==
"Attachment"
)
{
Navigator
.
push
(
context
,
MaterialPageRoute
(
builder:
(
context
)
=>
Fileviewer
(
fileName:
req_det
.
attachmentViewFileName
!,
fileUrl:
req_det
.
attachmentDirFilePath
!,
),
),
);
}
},
child:
Text
(
provider
.
Headings
[
j
]
==
"Attachment"
?
"View"
:
"
${provider.subHeadings[j]}
"
,
style:
TextStyle
(
fontSize:
14
,
color:
provider
.
Headings
[
j
]
==
"Attachment"
?
AppColors
.
app_blue
:
Color
(
0xFF818181
),
decoration:
provider
.
Headings
[
j
]
==
"Attachment"
?
TextDecoration
.
underline
:
TextDecoration
.
none
,
decorationColor:
provider
.
Headings
[
j
]
==
"Attachment"
?
AppColors
.
app_blue
:
AppColors
.
white
,
),
),
),
),
],
),
);
}),
],
),
),
),
),
bottomNavigationBar:
([
"admin"
,
"self"
].
contains
(
widget
.
mode
))
?
Container
(
height:
0
)
:
Container
(
margin:
EdgeInsets
.
symmetric
(
horizontal:
10
),
alignment:
Alignment
.
bottomCenter
,
height:
60
,
child:
Container
(
margin:
EdgeInsets
.
only
(
bottom:
10
),
alignment:
Alignment
.
center
,
height:
45
,
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Expanded
(
child:
InkResponse
(
onTap:
()
{
_showLevelRejectionSheet
(
context
);
},
child:
Container
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
),
color:
Color
(
0xFFFFEFEF
),
border:
Border
.
all
(
color:
Color
(
0xFFED3424
),
width:
0.5
,
),
),
child:
Center
(
child:
Text
(
"Reject"
,
style:
TextStyle
(
color:
Color
(
0xFFED3424
)),
),
),
),
),
),
SizedBox
(
width:
10
),
if
([
"apr_lvl1"
,
"apr_lvl2"
,
].
contains
(
widget
.
mode
))
...[
Expanded
(
child:
InkResponse
(
onTap:
()
{
provider
.
approveRejectPaymentRequestAPIFunction
(
context
,
provider
.
requestsDetails
.
id
);
_showLevelApprovalSheet
(
context
);
},
child:
Container
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
),
color:
Color
(
0xFFE7FFE5
),
border:
Border
.
all
(
color:
Color
(
0xFF0D9C00
),
width:
0.5
,
),
),
child:
Center
(
child:
Text
(
"Approve"
,
style:
TextStyle
(
color:
Color
(
0xFF0D9C00
),
),
),
),
),
),
),
]
else
if
(
widget
.
mode
==
"process"
)
...[
Expanded
(
child:
Container
(
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
8
),
color:
Color
(
0xFFE7FFE5
),
border:
Border
.
all
(
color:
Color
(
0xFF0D9C00
),
width:
0.5
,
),
),
child:
Center
(
child:
Text
(
"Add Payment"
,
style:
TextStyle
(
color:
Color
(
0xFF0D9C00
),
),
),
),
),
),
],
],
),
),
),
),
onWillPop:
()
{
return
onBackPressed
(
context
);
},
);
},
);
}
Future
<
void
>
_showLevelApprovalSheet
(
BuildContext
context
)
{
return
showModalBottomSheet
(
useSafeArea:
true
,
isDismissible:
true
,
isScrollControlled:
true
,
showDragHandle:
true
,
backgroundColor:
Colors
.
white
,
enableDrag:
true
,
context:
context
,
builder:
(
context
)
{
return
StatefulBuilder
(
builder:
(
context
,
setState
)
{
return
SafeArea
(
child:
Consumer
<
Requesitionlidtdetailsprovider
>(
builder:
(
context
,
provider
,
child
)
{
return
Container
(
margin:
EdgeInsets
.
only
(
bottom:
15
,
left:
15
,
right:
15
,
top:
10
,
),
child:
SingleChildScrollView
(
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Align
(
alignment:
Alignment
.
topLeft
,
child:
Text
(
"Level 1 Approval"
,
style:
TextStyle
(
color:
AppColors
.
app_blue
,
fontSize:
16
),
),
),
textControllerWidget
(
context
,
requestedAmount
,
"Enter Requested Amount"
,
(
p0
)
{},
),
textControllerWidget
(
context
,
approvedAmount
,
"Enter Approved Amount"
,
(
p0
)
{},
),
textControllerWidget
(
context
,
remarks
,
"Enter Remarks"
,
(
p0
)
{},
),
TextWidget
(
context
,
"Proposed Payment Account"
),
DropdownButtonHideUnderline
(
child:
Row
(
children:
[
Expanded
(
child:
DropdownButton2
<
PaymentAccounts
>(
isExpanded:
true
,
hint:
Text
(
'Select Payment mode'
,
style:
TextStyle
(
fontSize:
14
),
overflow:
TextOverflow
.
ellipsis
,
),
items:
provider
.
paymentsAccounts
.
map
(
(
paymenents
)
=>
DropdownMenuItem
<
PaymentAccounts
>(
value:
paymenents
,
child:
Text
(
paymenents
.
name
??
''
,
style:
const
TextStyle
(
fontSize:
14
,
),
overflow:
TextOverflow
.
ellipsis
,
),
),
)
.
toList
(),
value:
provider
.
selectedPaymentAccounts
,
onChanged:
(
PaymentAccounts
?
value
)
{
if
(
value
!=
null
)
{
if
(
provider
.
paymentsAccounts
.
isNotEmpty
)
{
provider
.
selectedPaymentAccounts
=
value
;
print
(
"Selected Complaint Type:
${value
.name}
, ID:
${value.id}
"
,
);
provider
.
selectedID
=
value
.
id
!;
provider
.
selectedValue
=
value
.
name
!;
print
(
"hfjkshfg"
+
provider
.
selectedID
.
toString
(),
);
}
}
},
buttonStyleData:
ButtonStyleData
(
height:
50
,
width:
160
,
padding:
const
EdgeInsets
.
only
(
left:
14
,
right:
14
,
),
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
14
),
color:
AppColors
.
text_field_color
,
),
),
iconStyleData:
const
IconStyleData
(
icon:
Icon
(
Icons
.
keyboard_arrow_down
),
iconSize:
12
,
iconEnabledColor:
Color
(
0xFF2D2D2D
),
iconDisabledColor:
Colors
.
grey
,
),
dropdownStyleData:
DropdownStyleData
(
maxHeight:
200
,
decoration:
BoxDecoration
(
borderRadius:
BorderRadius
.
circular
(
14
),
color:
AppColors
.
text_field_color
,
),
scrollbarTheme:
ScrollbarThemeData
(
radius:
const
Radius
.
circular
(
15
),
thickness:
MaterialStateProperty
.
all
<
double
>(
6
,
),
thumbVisibility:
MaterialStateProperty
.
all
<
bool
>(
true
),
),
),
menuItemStyleData:
const
MenuItemStyleData
(
height:
40
,
padding:
EdgeInsets
.
only
(
left:
14
,
right:
14
),
),
),
),
],
),
),
InkWell
(
onTap:
()
{
provider
.
paymentrequisitionApproveSubmitAPIFunction
(
context
,
widget
.
mode
,
provider
.
paymentsReqDetails
.
id
,
approvedAmount
.
text
,
remarks
.
text
,
provider
.
selectedID
);
},
child:
Container
(
alignment:
Alignment
.
center
,
height:
45
,
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
,
top:
5.0
,
bottom:
5.0
,
),
decoration:
BoxDecoration
(
color:
AppColors
.
app_blue
,
//1487C9
borderRadius:
BorderRadius
.
circular
(
30.0
),
),
child:
Center
(
child:
Text
(
"Submit"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
color:
Colors
.
white
),
),
),
),
),
],
),
),
);
},
),
);
},
);
},
);
}
Future
<
void
>
_showLevelRejectionSheet
(
BuildContext
context
)
{
return
showModalBottomSheet
(
useSafeArea:
true
,
isDismissible:
true
,
isScrollControlled:
true
,
showDragHandle:
true
,
backgroundColor:
Colors
.
white
,
enableDrag:
true
,
context:
context
,
builder:
(
context
)
{
return
StatefulBuilder
(
builder:
(
context
,
setState
)
{
return
SafeArea
(
child:
Consumer
<
Requesitionlidtdetailsprovider
>(
builder:
(
context
,
provider
,
child
)
{
return
Container
(
margin:
EdgeInsets
.
only
(
bottom:
15
,
left:
15
,
right:
15
,
top:
10
,
),
child:
SingleChildScrollView
(
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Align
(
alignment:
Alignment
.
topLeft
,
child:
Text
(
"Level 1 Rejection"
,
style:
TextStyle
(
color:
AppColors
.
app_blue
,
fontSize:
16
),
),
),
textControllerWidget
(
context
,
requestedAmount
,
"Enter Requested Amount"
,
(
p0
)
{},
),
textControllerWidget
(
context
,
remarks
,
"Enter Remarks"
,
(
p0
)
{},
),
InkWell
(
onTap:
()
{
provider
.
paymentrequisitionRejectSubmitAPIFunction
(
context
,
widget
.
mode
,
provider
.
paymentsReqDetails
.
id
,
remarks
.
text
);
},
child:
Container
(
alignment:
Alignment
.
center
,
height:
45
,
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
,
top:
5.0
,
bottom:
5.0
,
),
decoration:
BoxDecoration
(
color:
AppColors
.
app_blue
,
//1487C9
borderRadius:
BorderRadius
.
circular
(
30.0
),
),
child:
Center
(
child:
Text
(
"Submit"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
color:
Colors
.
white
),
),
),
),
),
],
),
),
);
},
),
);
},
);
},
);
}
Widget
TextWidget
(
context
,
text
)
{
return
Padding
(
padding:
const
EdgeInsets
.
only
(
bottom:
5.0
,
top:
8.0
),
child:
Text
(
text
),
);
}
Widget
ErrorWidget
(
context
,
text
)
{
if
(
text
!=
null
)
return
Text
(
text
!,
style:
TextStyle
(
color:
Colors
.
red
,
fontSize:
12
));
else
return
SizedBox
(
height:
10
);
}
Widget
textControllerWidget
(
context
,
controller
,
hintText
,
Function
(
String
)?
onChanged
,)
{
return
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
[
Padding
(
padding:
const
EdgeInsets
.
only
(
bottom:
5.0
,
top:
8.0
),
child:
Text
(
hintText
),
),
Container
(
height:
hintText
==
"Enter Description"
?
150
:
50
,
alignment:
Alignment
.
center
,
decoration:
BoxDecoration
(
color:
AppColors
.
text_field_color
,
borderRadius:
BorderRadius
.
circular
(
14
),
),
child:
Padding
(
padding:
const
EdgeInsets
.
fromLTRB
(
10.0
,
0.0
,
10
,
0
),
child:
TextFormField
(
controller:
controller
,
keyboardType:
TextInputType
.
text
,
maxLines:
hintText
==
"Enter Description"
?
60
:
1
,
onChanged:
onChanged
,
decoration:
InputDecoration
(
hintText:
hintText
,
hintStyle:
TextStyle
(
fontWeight:
FontWeight
.
w400
,
color:
Color
(
0xFFB4BEC0
),
fontSize:
14
,
),
enabledBorder:
InputBorder
.
none
,
focusedBorder:
InputBorder
.
none
,
),
),
),
),
],
);
}
}
lib/screens/finance/directPaymentRequesitionList.dart
0 → 100644
View file @
94df616d
import
'package:flutter/material.dart'
;
class
Directpaymentrequesitionlist
extends
StatefulWidget
{
const
Directpaymentrequesitionlist
({
super
.
key
});
@override
State
<
Directpaymentrequesitionlist
>
createState
()
=>
_DirectpaymentrequesitionlistState
();
}
class
_DirectpaymentrequesitionlistState
extends
State
<
Directpaymentrequesitionlist
>
{
@override
Widget
build
(
BuildContext
context
)
{
return
const
Placeholder
();
}
}
lib/screens/finance/financeDashboard.dart
View file @
94df616d
...
@@ -3,7 +3,9 @@ import 'package:flutter_svg/svg.dart';
...
@@ -3,7 +3,9 @@ import 'package:flutter_svg/svg.dart';
import
'package:generp/Notifiers/financeProvider/DashboardProvider.dart'
;
import
'package:generp/Notifiers/financeProvider/DashboardProvider.dart'
;
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:generp/screens/finance/paymentRequestionListsByMode.dart'
;
import
'package:generp/screens/finance/AllPaymentRequesitionListsByModes.dart'
;
import
'package:generp/screens/finance/directPaymentRequesitionList.dart'
;
import
'package:generp/screens/finance/submitPaymentRequestionListsByMode.dart'
;
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
class
Financedashboard
extends
StatefulWidget
{
class
Financedashboard
extends
StatefulWidget
{
...
@@ -61,35 +63,44 @@ class _FinancedashboardState extends State<Financedashboard> {
...
@@ -61,35 +63,44 @@ class _FinancedashboardState extends State<Financedashboard> {
SvgIcon
=
SvgPicture
.
asset
(
"assets/svg/fin_ic.svg"
);
SvgIcon
=
SvgPicture
.
asset
(
"assets/svg/fin_ic.svg"
);
break
;
break
;
}
}
return
Container
(
return
InkResponse
(
margin:
EdgeInsets
.
symmetric
(
onTap:
()
async
{
horizontal:
5
,
await
Navigator
.
push
(
context
,
MaterialPageRoute
(
vertical:
5
,
builder:
(
context
)
=>
),
Allpaymentrequesitionlistsbymodes
(
mode:
provider
.
accessiblePagesList
[
index
].
mode
!,
padding:
EdgeInsets
.
symmetric
(
pageTitleName:
provider
.
accessiblePagesList
[
index
].
pageName
!),));
horizontal:
10
,
},
vertical:
15
,
child:
Container
(
),
margin:
EdgeInsets
.
symmetric
(
decoration:
BoxDecoration
(
horizontal:
5
,
color:
Colors
.
white
,
vertical:
5
,
borderRadius:
BorderRadius
.
circular
(
14
),
),
),
padding:
EdgeInsets
.
symmetric
(
child:
Row
(
horizontal:
10
,
children:
[
vertical:
15
,
Expanded
(
flex:
1
,
child:
SvgIcon
),
),
Expanded
(
decoration:
BoxDecoration
(
flex:
5
,
color:
Colors
.
white
,
child:
Text
(
borderRadius:
BorderRadius
.
circular
(
14
),
"
${provider.accessiblePagesList[index].pageName}
"
,
),
child:
Row
(
children:
[
Expanded
(
flex:
1
,
child:
SvgIcon
),
Expanded
(
flex:
5
,
child:
Text
(
"
${provider.accessiblePagesList[index]
.pageName}
"
,
),
),
),
),
Expanded
(
Expanded
(
flex:
1
,
flex:
1
,
child:
SvgPicture
.
asset
(
child:
SvgPicture
.
asset
(
"assets/svg/arrow_right_new.svg"
,
"assets/svg/arrow_right_new.svg"
,
)
,
),
),
)
,
]
,
]
,
)
,
),
),
);
);
},
},
...
@@ -99,7 +110,7 @@ class _FinancedashboardState extends State<Financedashboard> {
...
@@ -99,7 +110,7 @@ class _FinancedashboardState extends State<Financedashboard> {
),
),
),
),
floatingActionButtonLocation:
floatingActionButtonLocation:
FloatingActionButtonLocation
.
centerFloat
,
FloatingActionButtonLocation
.
centerFloat
,
floatingActionButton:
InkResponse
(
floatingActionButton:
InkResponse
(
onTap:
()
{
onTap:
()
{
_showPaymentOptionsSheet
(
context
);
_showPaymentOptionsSheet
(
context
);
...
@@ -158,7 +169,8 @@ class _FinancedashboardState extends State<Financedashboard> {
...
@@ -158,7 +169,8 @@ class _FinancedashboardState extends State<Financedashboard> {
children:
[
children:
[
SizedBox
(
height:
15
),
SizedBox
(
height:
15
),
...
List
.
generate
(
provider
.
accessiblePagesList2
.
length
,
(
index
)
{
...
List
.
generate
(
provider
.
accessiblePagesList2
.
length
,
(
index
)
{
print
(
provider
.
accessiblePagesList2
[
index
].
mode
);
print
(
provider
.
accessiblePagesList2
[
index
].
mode
);
List
<
String
>
mode_lst
=
[
List
<
String
>
mode_lst
=
[
"self"
,
"self"
,
...
@@ -175,25 +187,38 @@ class _FinancedashboardState extends State<Financedashboard> {
...
@@ -175,25 +187,38 @@ class _FinancedashboardState extends State<Financedashboard> {
"Add Direct Payment"
,
"Add Direct Payment"
,
];
];
return
ListTile
(
return
ListTile
(
onTap:
()
{
onTap:
()
async
{
Navigator
.
pop
(
context
);
Navigator
.
pop
(
context
);
Navigator
.
push
(
var
res
;
context
,
if
(
provider
.
accessiblePagesList2
[
index
]
MaterialPageRoute
(
.
pageName
==
"Add Direct Payment"
)
{
builder:
res
=
await
Navigator
.
push
(
context
,
(
context
)
=>
MaterialPageRoute
(
builder:
(
context
)
=>
Paymentrequestionlistsbymode
(
Directpaymentrequesitionlist
(),));
mode:
"
${provider.accessiblePagesList2[index].mode}
"
,
}
else
{
pageTitleName:
"
${provider.accessiblePagesList2[index].pageName}
"
,
res
=
await
Navigator
.
push
(
),
context
,
),
MaterialPageRoute
(
);
builder:
(
context
)
=>
Submitpaymentrequestionlistsbymode
(
mode:
"
${provider
.accessiblePagesList2[index]
.mode}
"
,
pageTitleName:
"
${provider
.accessiblePagesList2[index]
.pageName}
"
,
),
),
);
}
},
},
leading:
SvgPicture
.
asset
(
leading:
SvgPicture
.
asset
(
"assets/svg/fin_ic.svg"
,
"assets/svg/fin_ic.svg"
,
),
),
title:
Text
(
title:
Text
(
"
${provider.accessiblePagesList2[index].pageName}
"
,
"
${provider.accessiblePagesList2[index]
.pageName}
"
,
style:
TextStyle
(
style:
TextStyle
(
fontSize:
14
,
fontSize:
14
,
fontFamily:
"JakartaMedium"
,
fontFamily:
"JakartaMedium"
,
...
...
lib/screens/finance/
p
aymentRequestionListsByMode.dart
→
lib/screens/finance/
submitP
aymentRequestionListsByMode.dart
View file @
94df616d
...
@@ -7,19 +7,19 @@ import 'package:provider/provider.dart';
...
@@ -7,19 +7,19 @@ import 'package:provider/provider.dart';
import
'../../Models/financeModels/addPaymentRequestionResponse.dart'
;
import
'../../Models/financeModels/addPaymentRequestionResponse.dart'
;
class
P
aymentrequestionlistsbymode
extends
StatefulWidget
{
class
Submitp
aymentrequestionlistsbymode
extends
StatefulWidget
{
final
String
mode
;
final
String
mode
;
final
String
pageTitleName
;
final
String
pageTitleName
;
const
P
aymentrequestionlistsbymode
({
super
.
key
,
required
this
.
mode
,
required
this
.
pageTitleName
});
const
Submitp
aymentrequestionlistsbymode
({
super
.
key
,
required
this
.
mode
,
required
this
.
pageTitleName
});
@override
@override
State
<
P
aymentrequestionlistsbymode
>
createState
()
=>
State
<
Submitp
aymentrequestionlistsbymode
>
createState
()
=>
_
P
aymentrequestionlistsbymodeState
();
_
Submitp
aymentrequestionlistsbymodeState
();
}
}
class
_
P
aymentrequestionlistsbymodeState
class
_
Submitp
aymentrequestionlistsbymodeState
extends
State
<
P
aymentrequestionlistsbymode
>
{
extends
State
<
Submitp
aymentrequestionlistsbymode
>
{
@override
@override
void
initState
()
{
void
initState
()
{
// TODO: implement initState
// TODO: implement initState
...
...
lib/screens/webtest.dart
0 → 100644
View file @
94df616d
import
'package:flutter/material.dart'
;
import
'package:flutter_inappwebview/flutter_inappwebview.dart'
;
import
'package:permission_handler/permission_handler.dart'
;
import
'package:flutter_local_notifications/flutter_local_notifications.dart'
;
import
'package:flutter/services.dart'
;
class
WebViewPage
extends
StatefulWidget
{
final
erp_url
;
const
WebViewPage
({
super
.
key
,
this
.
erp_url
});
@override
_WebViewPageState
createState
()
=>
_WebViewPageState
();
}
class
_WebViewPageState
extends
State
<
WebViewPage
>
{
InAppWebViewController
?
_webViewController
;
final
FlutterLocalNotificationsPlugin
_notificationsPlugin
=
FlutterLocalNotificationsPlugin
();
static
const
platform
=
MethodChannel
(
'in.webgrid.generp/download'
);
@override
void
initState
()
{
super
.
initState
();
_initializeNotifications
();
}
// Initialize notifications
Future
<
void
>
_initializeNotifications
()
async
{
const
AndroidInitializationSettings
initializationSettingsAndroid
=
AndroidInitializationSettings
(
'@mipmap/ic_launcher'
);
final
InitializationSettings
initializationSettings
=
InitializationSettings
(
android:
initializationSettingsAndroid
,
);
await
_notificationsPlugin
.
initialize
(
initializationSettings
);
// Create a notification channel for Android
const
AndroidNotificationChannel
channel
=
AndroidNotificationChannel
(
'download_channel'
,
'Downloads'
,
description:
'Notifications for file downloads'
,
importance:
Importance
.
high
,
);
await
_notificationsPlugin
.
resolvePlatformSpecificImplementation
<
AndroidFlutterLocalNotificationsPlugin
>()
?.
createNotificationChannel
(
channel
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
AppBar
(
title:
Text
(
"CRM WebView"
)),
body:
InAppWebView
(
initialUrlRequest:
URLRequest
(
url:
WebUri
(
widget
.
erp_url
)),
initialSettings:
InAppWebViewSettings
(
javaScriptEnabled:
true
,
domStorageEnabled:
true
,
allowFileAccess:
true
,
allowContentAccess:
true
,
useShouldInterceptAjaxRequest:
true
,
),
onWebViewCreated:
(
controller
)
{
_webViewController
=
controller
;
_webViewController
!.
addJavaScriptHandler
(
handlerName:
'MobileAppJavascriptInterface'
,
callback:
(
args
)
{
print
(
"JavaScript called MobileAppJavascriptInterface with args:
$args
"
);
return
{
'status'
:
'success'
};
},
);
_webViewController
!.
addJavaScriptHandler
(
handlerName:
'downloadFile'
,
callback:
(
args
)
async
{
final
url
=
args
[
0
]
as
String
;
await
_handleDownload
(
url
,
''
,
'application/octet-stream'
);
},
);
},
onDownloadStartRequest:
(
controller
,
downloadStartRequest
)
async
{
await
_handleDownload
(
downloadStartRequest
.
url
.
toString
(),
downloadStartRequest
.
suggestedFilename
!,
downloadStartRequest
.
mimeType
??
'application/octet-stream'
,
);
},
shouldInterceptAjaxRequest:
(
controller
,
ajaxRequest
)
async
{
if
(
ajaxRequest
.
url
.
toString
().
contains
(
'download'
))
{
await
_handleDownload
(
ajaxRequest
.
url
.
toString
(),
''
,
'application/octet-stream'
);
return
ajaxRequest
;
}
return
ajaxRequest
;
},
onConsoleMessage:
(
controller
,
consoleMessage
)
{
print
(
"JavaScript console message:
${consoleMessage.message}
"
);
},
),
);
}
Future
<
void
>
_handleDownload
(
String
url
,
String
contentDisposition
,
String
mimeType
)
async
{
// Request notification permission for Android 13+
if
(
await
Permission
.
notification
.
request
().
isGranted
)
{
try
{
// Show custom notification (optional, since DownloadManager shows its own)
await
_showNotification
(
id:
1
,
title:
'Download Started'
,
body:
'Downloading
${url.split('/').last}
'
,
);
// Call native Android Download Manager
final
userAgent
=
'Flutter InAppWebView'
;
await
platform
.
invokeMethod
(
'startDownload'
,
{
'url'
:
url
,
'userAgent'
:
userAgent
,
'contentDisposition'
:
contentDisposition
,
'mimeType'
:
mimeType
,
});
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"Download started for
${url.split('/').last}
"
)),
);
}
catch
(
e
)
{
await
_showNotification
(
id:
1
,
title:
'Download Error'
,
body:
'Error:
$e
'
,
);
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"Download error:
$e
"
)),
);
}
}
else
{
await
_showNotification
(
id:
1
,
title:
'Permission Denied'
,
body:
'Notification permission denied'
,
);
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"Notification permission denied"
)),
);
}
}
Future
<
void
>
_showNotification
({
required
int
id
,
required
String
title
,
required
String
body
,
})
async
{
final
AndroidNotificationDetails
androidPlatformChannelSpecifics
=
AndroidNotificationDetails
(
'download_channel'
,
'Downloads'
,
channelDescription:
'Notifications for file downloads'
,
importance:
Importance
.
high
,
priority:
Priority
.
high
,
onlyAlertOnce:
true
,
);
final
NotificationDetails
platformChannelSpecifics
=
NotificationDetails
(
android:
androidPlatformChannelSpecifics
,
);
await
_notificationsPlugin
.
show
(
id
,
title
,
body
,
platformChannelSpecifics
,
);
}
}
\ No newline at end of file
lib/services/api_calling.dart
View file @
94df616d
...
@@ -38,9 +38,12 @@ import '../Models/UpdatePasswordResponse.dart';
...
@@ -38,9 +38,12 @@ import '../Models/UpdatePasswordResponse.dart';
import
'../Models/VersionsResponse.dart'
;
import
'../Models/VersionsResponse.dart'
;
import
'../Models/ViewVisitDetailsResponse.dart'
;
import
'../Models/ViewVisitDetailsResponse.dart'
;
import
'../Models/financeModels/addPaymentRequestionResponse.dart'
;
import
'../Models/financeModels/addPaymentRequestionResponse.dart'
;
import
'../Models/financeModels/paymentRequesitionListsResponse.dart'
;
import
'../Models/financeModels/paymentRequisitionDetailsResponse.dart'
;
import
'../Models/generatorComplaintResponse.dart'
;
import
'../Models/generatorComplaintResponse.dart'
;
import
'../Models/loadGeneratorDetailsResponse.dart'
;
import
'../Models/loadGeneratorDetailsResponse.dart'
;
import
'../Models/financeModels/financeDashboardPagesResponse.dart'
;
import
'../Models/financeModels/financeDashboardPagesResponse.dart'
;
import
'../Notifiers/financeProvider/approveRejectPaymentRequestResponse.dart'
;
import
'../Utils/commonServices.dart'
;
import
'../Utils/commonServices.dart'
;
class
ApiCalling
{
class
ApiCalling
{
...
@@ -1131,10 +1134,8 @@ class ApiCalling {
...
@@ -1131,10 +1134,8 @@ class ApiCalling {
}
}
}
}
static
Future
<
financeDashboardPagesResponse
?>
addFormfinanceFormAccessPagesAPI
(
static
Future
<
financeDashboardPagesResponse
?>
empId
,
addFormfinanceFormAccessPagesAPI
(
empId
,
session
)
async
{
session
,
)
async
{
try
{
try
{
Map
<
String
,
String
>
data
=
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'emp_id'
:
(
empId
).
toString
(),
...
@@ -1194,7 +1195,7 @@ class ApiCalling {
...
@@ -1194,7 +1195,7 @@ class ApiCalling {
bank_ifsc_code
,
bank_ifsc_code
,
acc_holder_name
,
acc_holder_name
,
bank_upi_id
,
bank_upi_id
,
attachment
attachment
,
)
async
{
)
async
{
try
{
try
{
Map
<
String
,
String
>
data
=
{
Map
<
String
,
String
>
data
=
{
...
@@ -1216,14 +1217,19 @@ class ApiCalling {
...
@@ -1216,14 +1217,19 @@ class ApiCalling {
var
res
;
var
res
;
if
(
attachment
!=
null
)
{
if
(
attachment
!=
null
)
{
res
=
await
postImageNew
(
data
,
{},
addPaymentRequestionSubmitUrl
,
attachment
,
"attachment"
);
res
=
await
postImageNew
(
data
,
{},
addPaymentRequestionSubmitUrl
,
attachment
,
"attachment"
,
);
res
=
jsonDecode
(
res
);
res
=
jsonDecode
(
res
);
}
else
{
}
else
{
res
=
await
post
(
data
,
addPaymentRequestionSubmitUrl
,
{});
res
=
await
post
(
data
,
addPaymentRequestionSubmitUrl
,
{});
res
=
jsonDecode
(
res
);
res
=
jsonDecode
(
res
);
}
}
if
(
res
!=
null
)
{
if
(
res
!=
null
)
{
return
res
;
return
res
;
}
else
{
}
else
{
debugPrint
(
"Null Response"
);
debugPrint
(
"Null Response"
);
...
@@ -1234,4 +1240,193 @@ class ApiCalling {
...
@@ -1234,4 +1240,193 @@ class ApiCalling {
return
null
;
return
null
;
}
}
}
}
static
Future
<
paymentRequesitionListsResponse
?>
paymentRequestionListsAPI
(
empId
,
session
,
mode
,
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'session_id'
:
(
session
).
toString
(),
'mode'
:
(
mode
).
toString
(),
};
final
res
=
await
post
(
data
,
paymentRequestionListUrl
,
{});
if
(
res
!=
null
)
{
debugPrint
(
res
.
body
);
return
paymentRequesitionListsResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
'hello bev=bug
$e
'
);
return
null
;
}
}
static
Future
<
paymentRequisitionDetailsResponse
?>
paymentRequestionDetailsAPI
(
empId
,
session
,
payment_request_id
,
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'session_id'
:
(
session
).
toString
(),
'payment_request_id'
:
(
payment_request_id
).
toString
(),
};
final
res
=
await
post
(
data
,
paymentRequestionDetailsUrl
,
{});
if
(
res
!=
null
)
{
debugPrint
(
res
.
body
);
return
paymentRequisitionDetailsResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
'hello bev=bug
$e
'
);
return
null
;
}
}
static
Future
<
approveRejectPaymentRequestResponse
?>
approveRejectPaymentRequestAPI
(
empId
,
session
,
payment_request_id
,
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'session_id'
:
(
session
).
toString
(),
'payment_request_id'
:
(
payment_request_id
).
toString
(),
};
final
res
=
await
post
(
data
,
approveRejectPaymentRequestUrl
,
{});
if
(
res
!=
null
)
{
debugPrint
(
res
.
body
);
return
approveRejectPaymentRequestResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
'hello bev=bug
$e
'
);
return
null
;
}
}
static
Future
<
approveRejectPaymentRequestResponse
?>
RejectPaymentRequestSubmitAPI
(
empId
,
session
,
mode
,
payment_request_id
,
approve_remarks
,
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'session_id'
:
(
session
).
toString
(),
'type'
:
'reject'
,
'mode'
:
mode
.
toString
(),
'payment_request_id'
:
(
payment_request_id
).
toString
(),
'approve_remarks'
:
approve_remarks
,
};
final
res
=
await
post
(
data
,
approveRejectPaymentRequestSubmitUrl
,
{});
if
(
res
!=
null
)
{
debugPrint
(
res
.
body
);
return
approveRejectPaymentRequestResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
'hello bev=bug
$e
'
);
return
null
;
}
}
static
Future
<
approveRejectPaymentRequestResponse
?>
ApprovePaymentRequestSubmitAPI
(
empId
,
session
,
mode
,
payment_request_id
,
approved_amount
,
approve_remarks
,
proposed_payment_account_id
,
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'session_id'
:
(
session
).
toString
(),
'type'
:
'approve'
,
'mode'
:
mode
.
toString
(),
'payment_request_id'
:
(
payment_request_id
).
toString
(),
'approve_remarks'
:
approve_remarks
,
'proposed_payment_account_id'
:
proposed_payment_account_id
,
};
final
res
=
await
post
(
data
,
approveRejectPaymentRequestSubmitUrl
,
{});
if
(
res
!=
null
)
{
debugPrint
(
res
.
body
);
return
approveRejectPaymentRequestResponse
.
fromJson
(
jsonDecode
(
res
.
body
));
}
else
{
debugPrint
(
"Null Response"
);
return
null
;
}
}
catch
(
e
)
{
debugPrint
(
'hello bev=bug
$e
'
);
return
null
;
}
}
static
Future
<
approveRejectPaymentRequestResponse
?>
processApproveRejectPaymentRequestSubmitAPI
(
empId
,
session
,
mode
,
payment_request_id
,
approved_amount
,
approve_remarks
,
proposed_payment_account_id
,
payment_account_id
,
processing_remarks
,
attachment
)
async
{
try
{
Map
<
String
,
String
>
data
=
{
'emp_id'
:
(
empId
).
toString
(),
'session_id'
:
(
session
).
toString
(),
'type'
:
'approve'
,
'mode'
:
mode
.
toString
(),
'payment_request_id'
:
(
payment_request_id
).
toString
(),
'approved_amount'
:
approved_amount
,
'approve_remarks'
:
approve_remarks
,
'proposed_payment_account_id'
:
proposed_payment_account_id
,
'payment_account_id'
:
payment_account_id
,
'processing_remarks'
:
processing_remarks
,
};
var
res
;
if
(
attachment
!=
null
)
{
res
=
await
postImageNew
(
data
,
{},
approveRejectPaymentRequestSubmitUrl
,
attachment
,
"attachment"
,
);
res
=
jsonDecode
(
res
);
}
else
{
res
=
await
post
(
data
,
approveRejectPaymentRequestSubmitUrl
,
{});
res
=
jsonDecode
(
res
);
}
}
catch
(
e
)
{
debugPrint
(
'hello bev=bug
$e
'
);
return
null
;
}
}
}
}
lib/services/api_names.dart
View file @
94df616d
const
baseUrl
=
"https://erp.gengroup.in/ci/app/"
;
const
baseUrl
=
"https://erp.gengroup.in/ci/app/"
;
const
baseUrl_test
=
"https://erp.gengroup.in/ci/app/
Dheeraj
/"
;
const
baseUrl_test
=
"https://erp.gengroup.in/ci/app/
Api_home
/"
;
// var WEB_SOCKET_URL = "wss://ws.erp.gengroup.in/?type=user&route=employe_live_location_update&session_id=${Sessionid}";
// var WEB_SOCKET_URL = "wss://ws.erp.gengroup.in/?type=user&route=employe_live_location_update&session_id=${Sessionid}";
const
getAppVersionUrl
=
"https://erp.gengroup.in/ci/assets/appversion.json"
;
const
getAppVersionUrl
=
"https://erp.gengroup.in/ci/assets/appversion.json"
;
...
@@ -58,3 +58,6 @@ const financeAddFormPagesAccessUrl = "${baseUrl_test}finance_add_form_page_acces
...
@@ -58,3 +58,6 @@ const financeAddFormPagesAccessUrl = "${baseUrl_test}finance_add_form_page_acces
const
addPaymentRequestionViewUrl
=
"
${baseUrl_test}
add_payment_requisiton_view"
;
const
addPaymentRequestionViewUrl
=
"
${baseUrl_test}
add_payment_requisiton_view"
;
const
addPaymentRequestionSubmitUrl
=
"
${baseUrl_test}
add_payment_requsition_submit"
;
const
addPaymentRequestionSubmitUrl
=
"
${baseUrl_test}
add_payment_requsition_submit"
;
const
paymentRequestionListUrl
=
"
${baseUrl_test}
payment_requsition_list"
;
const
paymentRequestionListUrl
=
"
${baseUrl_test}
payment_requsition_list"
;
const
paymentRequestionDetailsUrl
=
"
${baseUrl_test}
payment_requisition_details"
;
const
approveRejectPaymentRequestUrl
=
"
${baseUrl_test}
approve_reject_payment_request_view"
;
const
approveRejectPaymentRequestSubmitUrl
=
"
${baseUrl_test}
approve_reject_payment_request_submit"
;
linux/flutter/generated_plugin_registrant.cc
View file @
94df616d
...
@@ -7,12 +7,16 @@
...
@@ -7,12 +7,16 @@
#include "generated_plugin_registrant.h"
#include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
#include <file_selector_linux/file_selector_plugin.h>
#include <printing/printing_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void
fl_register_plugins
(
FlPluginRegistry
*
registry
)
{
void
fl_register_plugins
(
FlPluginRegistry
*
registry
)
{
g_autoptr
(
FlPluginRegistrar
)
file_selector_linux_registrar
=
g_autoptr
(
FlPluginRegistrar
)
file_selector_linux_registrar
=
fl_plugin_registry_get_registrar_for_plugin
(
registry
,
"FileSelectorPlugin"
);
fl_plugin_registry_get_registrar_for_plugin
(
registry
,
"FileSelectorPlugin"
);
file_selector_plugin_register_with_registrar
(
file_selector_linux_registrar
);
file_selector_plugin_register_with_registrar
(
file_selector_linux_registrar
);
g_autoptr
(
FlPluginRegistrar
)
printing_registrar
=
fl_plugin_registry_get_registrar_for_plugin
(
registry
,
"PrintingPlugin"
);
printing_plugin_register_with_registrar
(
printing_registrar
);
g_autoptr
(
FlPluginRegistrar
)
url_launcher_linux_registrar
=
g_autoptr
(
FlPluginRegistrar
)
url_launcher_linux_registrar
=
fl_plugin_registry_get_registrar_for_plugin
(
registry
,
"UrlLauncherPlugin"
);
fl_plugin_registry_get_registrar_for_plugin
(
registry
,
"UrlLauncherPlugin"
);
url_launcher_plugin_register_with_registrar
(
url_launcher_linux_registrar
);
url_launcher_plugin_register_with_registrar
(
url_launcher_linux_registrar
);
...
...
linux/flutter/generated_plugins.cmake
View file @
94df616d
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
list
(
APPEND FLUTTER_PLUGIN_LIST
list
(
APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
file_selector_linux
printing
url_launcher_linux
url_launcher_linux
)
)
...
...
macos/Flutter/GeneratedPluginRegistrant.swift
View file @
94df616d
...
@@ -17,9 +17,11 @@ import geolocator_apple
...
@@ -17,9 +17,11 @@ import geolocator_apple
import
location
import
location
import
package_info_plus
import
package_info_plus
import
path_provider_foundation
import
path_provider_foundation
import
printing
import
share_plus
import
share_plus
import
shared_preferences_foundation
import
shared_preferences_foundation
import
sqflite_darwin
import
sqflite_darwin
import
syncfusion_pdfviewer_macos
import
url_launcher_macos
import
url_launcher_macos
import
webview_flutter_wkwebview
import
webview_flutter_wkwebview
...
@@ -36,9 +38,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
...
@@ -36,9 +38,11 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
LocationPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"LocationPlugin"
))
LocationPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"LocationPlugin"
))
FPPPackageInfoPlusPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"FPPPackageInfoPlusPlugin"
))
FPPPackageInfoPlusPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"FPPPackageInfoPlusPlugin"
))
PathProviderPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"PathProviderPlugin"
))
PathProviderPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"PathProviderPlugin"
))
PrintingPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"PrintingPlugin"
))
SharePlusMacosPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SharePlusMacosPlugin"
))
SharePlusMacosPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SharePlusMacosPlugin"
))
SharedPreferencesPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SharedPreferencesPlugin"
))
SharedPreferencesPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SharedPreferencesPlugin"
))
SqflitePlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SqflitePlugin"
))
SqflitePlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SqflitePlugin"
))
SyncfusionFlutterPdfViewerPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SyncfusionFlutterPdfViewerPlugin"
))
UrlLauncherPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"UrlLauncherPlugin"
))
UrlLauncherPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"UrlLauncherPlugin"
))
WebViewFlutterPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"WebViewFlutterPlugin"
))
WebViewFlutterPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"WebViewFlutterPlugin"
))
}
}
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment