"macos/git@183.82.99.133:saisrinivas/gen_erp_2025.git" did not exist on "ee178d554d5bd36b89913992e15992d4e891e0c2"
Commit 94df616d authored by Sai Srinivas's avatar Sai Srinivas
Browse files

16-05-2025 By Sai Srinivas

Finance Module requisition Lists and Details
parent 6a825b3f
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
...@@ -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();
......
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;
}
}
...@@ -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();
} }
......
...@@ -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) {
......
...@@ -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");
......
...@@ -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,9 +152,10 @@ class _LoginScreenState extends State<LoginScreen> ...@@ -151,9 +152,10 @@ 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 Consumer<Loginnotifier>(
builder: (context,loginProv,child) {
return WillPopScope( return WillPopScope(
onWillPop: onBackPressed, onWillPop: onBackPressed,
child: Scaffold( child: Scaffold(
...@@ -553,9 +555,7 @@ class _LoginScreenState extends State<LoginScreen> ...@@ -553,9 +555,7 @@ class _LoginScreenState extends State<LoginScreen>
Clipboard.setData(ClipboardData(text: loginProv.deviceId.trim())); Clipboard.setData(ClipboardData(text: loginProv.deviceId.trim()));
toast(context, "Device ID has been copied!"); toast(context, "Device ID has been copied!");
}, },
child: Icon( child: SvgPicture.asset("assets/svg/copy_ic.svg"),
Icons.copy
),
), ),
), ),
], ],
...@@ -573,10 +573,7 @@ class _LoginScreenState extends State<LoginScreen> ...@@ -573,10 +573,7 @@ class _LoginScreenState extends State<LoginScreen>
onTap: () { onTap: () {
Share.share("${loginProv.deviceId}"); Share.share("${loginProv.deviceId}");
}, },
child: Icon( child: SvgPicture.asset("assets/svg/share_ic.svg",height: 25,width: 25,fit: BoxFit.scaleDown,),
Icons.share_outlined,
color: Colors.white,
),
)), )),
], ],
), ),
...@@ -617,6 +614,8 @@ class _LoginScreenState extends State<LoginScreen> ...@@ -617,6 +614,8 @@ class _LoginScreenState extends State<LoginScreen>
), ),
); );
} }
);
}
} }
......
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");
}
}
} }
......
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",
),
);
}),
],
),
),
);
},
),
);
},
);
},
);
}
}
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;
}
}
This diff is collapsed.
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();
}
}
...@@ -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,7 +63,14 @@ class _FinancedashboardState extends State<Financedashboard> { ...@@ -61,7 +63,14 @@ 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(
onTap: () async {
await Navigator.push(context, MaterialPageRoute(
builder: (context) =>
Allpaymentrequesitionlistsbymodes(mode: provider.accessiblePagesList[index].mode!,
pageTitleName: provider.accessiblePagesList[index].pageName!),));
},
child: Container(
margin: EdgeInsets.symmetric( margin: EdgeInsets.symmetric(
horizontal: 5, horizontal: 5,
vertical: 5, vertical: 5,
...@@ -80,7 +89,8 @@ class _FinancedashboardState extends State<Financedashboard> { ...@@ -80,7 +89,8 @@ class _FinancedashboardState extends State<Financedashboard> {
Expanded( Expanded(
flex: 5, flex: 5,
child: Text( child: Text(
"${provider.accessiblePagesList[index].pageName}", "${provider.accessiblePagesList[index]
.pageName}",
), ),
), ),
Expanded( Expanded(
...@@ -91,6 +101,7 @@ class _FinancedashboardState extends State<Financedashboard> { ...@@ -91,6 +101,7 @@ class _FinancedashboardState extends State<Financedashboard> {
), ),
], ],
), ),
),
); );
}, },
), ),
...@@ -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;
if (provider.accessiblePagesList2[index]
.pageName == "Add Direct Payment") {
res = await Navigator.push(context,
MaterialPageRoute(builder: (context) =>
Directpaymentrequesitionlist(),));
} else {
res = await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: builder:
(context) => (context) =>
Paymentrequestionlistsbymode( Submitpaymentrequestionlistsbymode(
mode: "${provider.accessiblePagesList2[index].mode}", mode: "${provider
pageTitleName: "${provider.accessiblePagesList2[index].pageName}", .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",
......
...@@ -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 Paymentrequestionlistsbymode extends StatefulWidget { class Submitpaymentrequestionlistsbymode extends StatefulWidget {
final String mode; final String mode;
final String pageTitleName; final String pageTitleName;
const Paymentrequestionlistsbymode({super.key, required this.mode,required this.pageTitleName}); const Submitpaymentrequestionlistsbymode({super.key, required this.mode,required this.pageTitleName});
@override @override
State<Paymentrequestionlistsbymode> createState() => State<Submitpaymentrequestionlistsbymode> createState() =>
_PaymentrequestionlistsbymodeState(); _SubmitpaymentrequestionlistsbymodeState();
} }
class _PaymentrequestionlistsbymodeState class _SubmitpaymentrequestionlistsbymodeState
extends State<Paymentrequestionlistsbymode> { extends State<Submitpaymentrequestionlistsbymode> {
@override @override
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
......
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
...@@ -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;
}
}
} }
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";
...@@ -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);
......
...@@ -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
) )
......
...@@ -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"))
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment