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
7ba7402c
Commit
7ba7402c
authored
Nov 21, 2025
by
Sai Srinivas
Committed by
Sai Srinivas
Nov 28, 2025
Browse files
Edit form and some fixes added
parent
d2939607
Changes
40
Expand all
Show whitespace changes
Inline
Side-by-side
android/app/build.gradle.kts
View file @
7ba7402c
...
...
@@ -42,7 +42,7 @@ android {
defaultConfig
{
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId
=
"in.webgrid.generp"
minSdk
=
23
minSdk
=
flutter
.
minSdkVersion
targetSdk
=
36
versionCode
=
flutter
.
versionCode
versionName
=
flutter
.
versionName
...
...
android/app/src/main/AndroidManifest.xml
View file @
7ba7402c
...
...
@@ -22,6 +22,7 @@
<uses-permission
android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.READ_CONTACTS"
/>
<uses-permission
android:name=
"android.permission.WRITE_CONTACTS"
/>
<uses-permission
android:name=
"android.permission.WAKE_LOCK"
/>
<application
android:name=
"${applicationName}"
...
...
@@ -77,6 +78,12 @@
</intent-filter>
</activity>
<service
android:name=
"com.pravera.flutter_foreground_task.service.ForegroundService"
android:foregroundServiceType=
"location"
android:exported=
"false"
/>
<meta-data
android:name=
"flutter_deeplinking_enabled"
android:value=
"true"
/>
...
...
assets/svg/compliant_list_ic.svg
0 → 100644
View file @
7ba7402c
<svg
id=
"Layer_1"
enable-background=
"new 0 0 64 64"
height=
"64"
viewBox=
"0 0 64 64"
width=
"64"
xmlns=
"http://www.w3.org/2000/svg"
><g><g
id=
"ARC_17_"
><g><path
d=
"m31.996 31.008c-3.292 0-6.583-1.09-9.33-3.271-.433-.344-.504-.973-.161-1.406.345-.432.973-.502 1.405-.16 4.761 3.783 11.412 3.783 16.171 0 .432-.344 1.062-.271 1.405.16.344.434.271 1.063-.161 1.406-2.746 2.181-6.038 3.271-9.329 3.271z"
/></g></g><g
id=
"ARC_18_"
><g><path
d=
"m16.307 41.711c-.455 0-.866-.313-.973-.773-1.432-6.156 1.748-12.424 7.561-14.904.509-.217 1.096.02 1.313.527.217.508-.02 1.096-.527 1.313-4.919 2.098-7.61 7.402-6.398 12.611.125.537-.209 1.074-.748 1.199-.077.019-.153.027-.228.027z"
/></g></g><g
id=
"ARC_19_"
><g><path
d=
"m47.684 41.711c-.075 0-.151-.008-.228-.027-.538-.125-.873-.662-.747-1.199 1.212-5.209-1.479-10.514-6.398-12.611-.508-.217-.744-.805-.527-1.313.217-.51.809-.744 1.313-.527 5.813 2.48 8.994 8.748 7.561 14.904-.109.46-.52.773-.974.773z"
/></g></g><g
id=
"CIRCLE_14_"
><g><path
d=
"m32.013 26.967c-2.701 0-5.284-.963-7.273-2.709-3.782-3.32-4.823-8.957-2.475-13.398 1.881-3.561 5.723-5.861 9.788-5.861.888 0 1.772.107 2.629.324 4.817 1.209 8.314 5.695 8.314 10.668 0 3.559-1.735 6.916-4.642 8.979-1.844 1.305-4.038 1.997-6.341 1.997zm.039-19.969c-3.333 0-6.48 1.881-8.019 4.795-1.92 3.635-1.068 8.244 2.026 10.963 1.624 1.426 3.738 2.211 5.954 2.211 1.888 0 3.68-.563 5.184-1.629 2.379-1.689 3.799-4.436 3.799-7.348 0-4.068-2.86-7.74-6.801-8.729-.699-.175-1.419-.263-2.143-.263z"
/></g></g><g
id=
"ARC_20_"
><g><path
d=
"m24.573 43.184c-.034 0-.067-.002-.102-.006-2.83-.287-5.66-.791-8.412-1.498-.535-.139-.857-.684-.719-1.219.137-.535.684-.857 1.217-.719 2.655.684 5.386 1.17 8.115 1.445.55.057.95.547.895 1.096-.052.516-.487.901-.994.901z"
/></g></g><g
id=
"ARC_21_"
><g><path
d=
"m39.418 43.184c-.507 0-.941-.385-.994-.9-.056-.549.345-1.039.895-1.096 2.73-.275 5.46-.762 8.115-1.445.529-.137 1.08.184 1.218.719s-.185 1.08-.72 1.219c-2.752.707-5.582 1.211-8.412 1.498-.035.003-.069.005-.102.005z"
/></g></g><g
id=
"LINE_65_"
><g><path
d=
"m31.995 53.99c-.195 0-.392-.057-.565-.176-.455-.313-.571-.936-.258-1.391l7.423-10.807c.312-.455.938-.57 1.391-.258.455.313.57.936.258 1.391l-7.424 10.808c-.194.283-.507.433-.825.433z"
/></g></g><g
id=
"LINE_66_"
><g><path
d=
"m31.997 53.99c-.318 0-.631-.15-.825-.434l-7.424-10.806c-.313-.455-.197-1.078.258-1.391.457-.314 1.078-.197 1.391.258l7.424 10.807c.312.455.197 1.078-.258 1.391-.174.119-.372.175-.566.175z"
/></g></g><g
id=
"LWPOLYLINE_14_"
><g><path
d=
"m32.453 59.002c-.709 0-1.429-.012-2.159-.037-4.484-.15-8.824-.424-12.622-2.088-.71-.311-2.386-1.189-2.613-2.623-.083-.527-.001-1.32.866-2.09 2.129-1.893 5.448-2.318 8.114-2.66l.896-.117c.541-.07 1.052.309 1.126.855s-.308 1.053-.855 1.127l-.913.119c-2.394.307-5.372.688-7.039 2.17-.177.156-.223.264-.22.283.034.213.553.715 1.44 1.104 3.473 1.521 7.604 1.777 11.886 1.922 4.494.148 8.578-.178 12.126-.98 3.9-.879 4.438-1.734 4.508-1.898.011-.025.029-.07-.06-.217-.367-.598-1.497-.996-2.245-1.26-1.851-.652-3.845-.959-5.896-1.242-.548-.074-.93-.578-.854-1.125.074-.547.577-.938 1.126-.855 2.157.297 4.262.621 6.289 1.336 1.014.357 2.548.898 3.285 2.102.518.846.393 1.576.196 2.041-.554 1.311-2.415 2.283-5.856 3.059-3.175.717-6.699 1.074-10.526 1.074z"
/></g></g></g></svg>
\ No newline at end of file
lib/Models/FollowUpResponse.dart
View file @
7ba7402c
...
...
@@ -9,7 +9,7 @@ class FollowupListResponse {
if
(
json
[
'list'
]
!=
null
)
{
list
=
<
Followuplist
>[];
json
[
'list'
].
forEach
((
v
)
{
list
!.
add
(
Followuplist
.
fromJson
(
v
));
list
!.
add
(
new
Followuplist
.
fromJson
(
v
));
});
}
error
=
json
[
'error'
];
...
...
@@ -17,12 +17,12 @@ class FollowupListResponse {
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
<
String
,
dynamic
>
{}
;
if
(
list
!=
null
)
{
data
[
'list'
]
=
list
!.
map
((
v
)
=>
v
.
toJson
()).
toList
();
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>
()
;
if
(
this
.
list
!=
null
)
{
data
[
'list'
]
=
this
.
list
!.
map
((
v
)
=>
v
.
toJson
()).
toList
();
}
data
[
'error'
]
=
error
;
data
[
'session_exists'
]
=
sessionExists
;
data
[
'error'
]
=
this
.
error
;
data
[
'session_exists'
]
=
this
.
sessionExists
;
return
data
;
}
}
...
...
@@ -42,8 +42,8 @@ class Followuplist {
String
?
time
;
String
?
ename
;
Followuplist
(
{
this
.
id
,
Followuplist
(
{
this
.
id
,
this
.
empId
,
this
.
compId
,
this
.
inTime
,
...
...
@@ -55,8 +55,7 @@ class Followuplist {
this
.
fsrExt
,
this
.
runningHrs
,
this
.
time
,
this
.
ename
,
});
this
.
ename
});
Followuplist
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
id
=
json
[
'id'
];
...
...
@@ -75,20 +74,20 @@ class Followuplist {
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
<
String
,
dynamic
>
{}
;
data
[
'id'
]
=
id
;
data
[
'emp_id'
]
=
empId
;
data
[
'comp_id'
]
=
compId
;
data
[
'in_time'
]
=
inTime
;
data
[
'out_time'
]
=
outTime
;
data
[
'feedback'
]
=
feedback
;
data
[
'type'
]
=
type
;
data
[
'date'
]
=
date
;
data
[
'fsr_no'
]
=
fsrNo
;
data
[
'fsr_ext'
]
=
fsrExt
;
data
[
'running_hrs'
]
=
runningHrs
;
data
[
'time'
]
=
time
;
data
[
'ename'
]
=
ename
;
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>
()
;
data
[
'id'
]
=
this
.
id
;
data
[
'emp_id'
]
=
this
.
empId
;
data
[
'comp_id'
]
=
this
.
compId
;
data
[
'in_time'
]
=
this
.
inTime
;
data
[
'out_time'
]
=
this
.
outTime
;
data
[
'feedback'
]
=
this
.
feedback
;
data
[
'type'
]
=
this
.
type
;
data
[
'date'
]
=
this
.
date
;
data
[
'fsr_no'
]
=
this
.
fsrNo
;
data
[
'fsr_ext'
]
=
this
.
fsrExt
;
data
[
'running_hrs'
]
=
this
.
runningHrs
;
data
[
'time'
]
=
this
.
time
;
data
[
'ename'
]
=
this
.
ename
;
return
data
;
}
}
lib/Models/ServiceComplaintBillListResponse.dart
0 → 100644
View file @
7ba7402c
class
ServiceComplaintBillListResponse
{
List
<
ComplaintList
>?
complaintList
;
int
?
error
;
int
?
sessionExists
;
ServiceComplaintBillListResponse
(
{
this
.
complaintList
,
this
.
error
,
this
.
sessionExists
});
ServiceComplaintBillListResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
if
(
json
[
'complaint_list'
]
!=
null
)
{
complaintList
=
<
ComplaintList
>[];
json
[
'complaint_list'
].
forEach
((
v
)
{
complaintList
!.
add
(
new
ComplaintList
.
fromJson
(
v
));
});
}
error
=
json
[
'error'
];
sessionExists
=
json
[
'session_exists'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
if
(
this
.
complaintList
!=
null
)
{
data
[
'complaint_list'
]
=
this
.
complaintList
!.
map
((
v
)
=>
v
.
toJson
()).
toList
();
}
data
[
'error'
]
=
this
.
error
;
data
[
'session_exists'
]
=
this
.
sessionExists
;
return
data
;
}
}
class
ComplaintList
{
String
?
billId
;
String
?
totalAmount
;
String
?
rawAmount
;
String
?
narration
;
String
?
billDate
;
String
?
dueDate
;
String
?
billPaid
;
ComplaintList
(
{
this
.
billId
,
this
.
totalAmount
,
this
.
rawAmount
,
this
.
narration
,
this
.
billDate
,
this
.
dueDate
,
this
.
billPaid
});
ComplaintList
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
billId
=
json
[
'bill_id'
];
totalAmount
=
json
[
'total_amount'
];
rawAmount
=
json
[
'raw_amount'
];
narration
=
json
[
'narration'
];
billDate
=
json
[
'bill_date'
];
dueDate
=
json
[
'due_date'
];
billPaid
=
json
[
'bill_paid'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
data
[
'bill_id'
]
=
this
.
billId
;
data
[
'total_amount'
]
=
this
.
totalAmount
;
data
[
'raw_amount'
]
=
this
.
rawAmount
;
data
[
'narration'
]
=
this
.
narration
;
data
[
'bill_date'
]
=
this
.
billDate
;
data
[
'due_date'
]
=
this
.
dueDate
;
data
[
'bill_paid'
]
=
this
.
billPaid
;
return
data
;
}
}
lib/Models/commonModels/EditCommonAccFormDetailsResponse.dart
0 → 100644
View file @
7ba7402c
class
EditCommonAccFormDetailsResponse
{
List
<
AccountList
>?
accountList
;
String
?
error
;
String
?
message
;
int
?
sessionExists
;
EditCommonAccFormDetailsResponse
(
{
this
.
accountList
,
this
.
error
,
this
.
message
,
this
.
sessionExists
});
EditCommonAccFormDetailsResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
if
(
json
[
'account_list'
]
!=
null
)
{
accountList
=
<
AccountList
>[];
json
[
'account_list'
].
forEach
((
v
)
{
accountList
!.
add
(
new
AccountList
.
fromJson
(
v
));
});
}
error
=
json
[
'error'
];
message
=
json
[
'message'
];
sessionExists
=
json
[
'session_exists'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
if
(
this
.
accountList
!=
null
)
{
data
[
'account_list'
]
=
this
.
accountList
!.
map
((
v
)
=>
v
.
toJson
()).
toList
();
}
data
[
'error'
]
=
this
.
error
;
data
[
'message'
]
=
this
.
message
;
data
[
'session_exists'
]
=
this
.
sessionExists
;
return
data
;
}
}
class
AccountList
{
String
?
id
;
String
?
isPaymentAccount
;
String
?
createdEmployeeId
;
String
?
type
;
String
?
refId
;
String
?
name
;
String
?
subLocality
;
String
?
district
;
String
?
state
;
String
?
address
;
String
?
datetime
;
String
?
empId
;
String
?
bankName
;
String
?
bankBranchName
;
String
?
bankIfscCode
;
String
?
bankAccountHolderName
;
String
?
bankAccountNumber
;
String
?
bankUpiId
;
String
?
bankUpiName
;
String
?
gstNumber
;
Null
?
cashfreeAccountId
;
String
?
isGstNumberVerified
;
String
?
isBankAccountVerified
;
String
?
remarks
;
String
?
isExists
;
String
?
createdDatetime
;
String
?
updatedDatetime
;
String
?
mob1
;
String
?
email
;
String
?
contactName
;
AccountList
(
{
this
.
id
,
this
.
isPaymentAccount
,
this
.
createdEmployeeId
,
this
.
type
,
this
.
refId
,
this
.
name
,
this
.
subLocality
,
this
.
district
,
this
.
state
,
this
.
address
,
this
.
datetime
,
this
.
empId
,
this
.
bankName
,
this
.
bankBranchName
,
this
.
bankIfscCode
,
this
.
bankAccountHolderName
,
this
.
bankAccountNumber
,
this
.
bankUpiId
,
this
.
bankUpiName
,
this
.
gstNumber
,
this
.
cashfreeAccountId
,
this
.
isGstNumberVerified
,
this
.
isBankAccountVerified
,
this
.
remarks
,
this
.
isExists
,
this
.
createdDatetime
,
this
.
updatedDatetime
,
this
.
mob1
,
this
.
email
,
this
.
contactName
});
AccountList
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
id
=
json
[
'id'
];
isPaymentAccount
=
json
[
'is_payment_account'
];
createdEmployeeId
=
json
[
'created_employee_id'
];
type
=
json
[
'type'
];
refId
=
json
[
'ref_id'
];
name
=
json
[
'name'
];
subLocality
=
json
[
'sub_locality'
];
district
=
json
[
'district'
];
state
=
json
[
'state'
];
address
=
json
[
'address'
];
datetime
=
json
[
'datetime'
];
empId
=
json
[
'emp_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'
];
bankUpiName
=
json
[
'bank_upi_name'
];
gstNumber
=
json
[
'gst_number'
];
cashfreeAccountId
=
json
[
'cashfree_account_id'
];
isGstNumberVerified
=
json
[
'is_gst_number_verified'
];
isBankAccountVerified
=
json
[
'is_bank_account_verified'
];
remarks
=
json
[
'remarks'
];
isExists
=
json
[
'is_exists'
];
createdDatetime
=
json
[
'created_datetime'
];
updatedDatetime
=
json
[
'updated_datetime'
];
mob1
=
json
[
'mob1'
];
email
=
json
[
'email'
];
contactName
=
json
[
'contact_name'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
data
[
'id'
]
=
this
.
id
;
data
[
'is_payment_account'
]
=
this
.
isPaymentAccount
;
data
[
'created_employee_id'
]
=
this
.
createdEmployeeId
;
data
[
'type'
]
=
this
.
type
;
data
[
'ref_id'
]
=
this
.
refId
;
data
[
'name'
]
=
this
.
name
;
data
[
'sub_locality'
]
=
this
.
subLocality
;
data
[
'district'
]
=
this
.
district
;
data
[
'state'
]
=
this
.
state
;
data
[
'address'
]
=
this
.
address
;
data
[
'datetime'
]
=
this
.
datetime
;
data
[
'emp_id'
]
=
this
.
empId
;
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
;
data
[
'bank_upi_name'
]
=
this
.
bankUpiName
;
data
[
'gst_number'
]
=
this
.
gstNumber
;
data
[
'cashfree_account_id'
]
=
this
.
cashfreeAccountId
;
data
[
'is_gst_number_verified'
]
=
this
.
isGstNumberVerified
;
data
[
'is_bank_account_verified'
]
=
this
.
isBankAccountVerified
;
data
[
'remarks'
]
=
this
.
remarks
;
data
[
'is_exists'
]
=
this
.
isExists
;
data
[
'created_datetime'
]
=
this
.
createdDatetime
;
data
[
'updated_datetime'
]
=
this
.
updatedDatetime
;
data
[
'mob1'
]
=
this
.
mob1
;
data
[
'email'
]
=
this
.
email
;
data
[
'contact_name'
]
=
this
.
contactName
;
return
data
;
}
}
lib/Notifiers/CheckInProvider.dart
View file @
7ba7402c
...
...
@@ -14,6 +14,7 @@ import 'package:provider/provider.dart';
import
'../Utils/BackgroundLocationService.dart'
;
import
'../Utils/SharedpreferencesService.dart'
;
import
'../Utils/backgroundServiceNew.dart'
;
import
'../Utils/background_service.dart'
;
import
'../Utils/commonServices.dart'
;
import
'../services/api_calling.dart'
;
...
...
@@ -229,6 +230,8 @@ class CheckInOutProvider with ChangeNotifier {
if
(
data
.
error
==
0
)
{
toast
(
context
,
"CheckedIn Successfully"
);
await
BackgroundLocationService
.
startLocationService
(
context
);
await
BackgroundLocationServiceNew
.
init
();
await
BackgroundLocationServiceNew
.
start
();
locationController
.
clear
();
dispose
();
Navigator
.
pop
(
context
,
true
);
...
...
@@ -266,6 +269,7 @@ class CheckInOutProvider with ChangeNotifier {
if
(
data
.
error
==
0
)
{
toast
(
context
,
"Check-Out Successful"
);
await
BackgroundLocationService
.
stopLocationService
();
await
BackgroundLocationServiceNew
.
stop
();
locationController
.
clear
();
dispose
();
Navigator
.
pop
(
context
,
true
);
...
...
lib/Notifiers/HomeScreenNotifier.dart
View file @
7ba7402c
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:generp/Utils/SharedpreferencesService.dart'
;
import
'package:generp/Utils/backgroundServiceNew.dart'
;
import
'package:generp/screens/LoginScreen.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:intl/intl.dart'
;
...
...
@@ -77,6 +78,8 @@ class HomescreenNotifier extends ChangeNotifier {
var
lastLocationTime
=
await
SharedpreferencesService
().
getString
(
"lastLocationTime"
,
);
notifyListeners
();
print
(
"lastLocationTime:
$lastLocationTime
"
);
...
...
@@ -112,6 +115,7 @@ class HomescreenNotifier extends ChangeNotifier {
if
(
_att_status
==
0
)
{
webSocketManager
.
close
();
await
BackgroundLocationService
.
stopLocationService
();
BackgroundLocationServiceNew
.
stop
();
_onlineStatus
=
"Offline"
;
...
...
@@ -151,11 +155,14 @@ class HomescreenNotifier extends ChangeNotifier {
// print("Status knlknn offine");
}
await
BackgroundLocationService
.
startLocationService
(
context
);
await
BackgroundLocationServiceNew
.
init
();
await
BackgroundLocationServiceNew
.
start
();
// print("setstatus:$setstatus");
}
else
if
(
_att_status
==
2
)
{
// print("att_status:$att_status");
webSocketManager
.
close
();
await
BackgroundLocationService
.
stopLocationService
();
await
BackgroundLocationServiceNew
.
stop
();
_onlineStatus
=
"Offline"
;
...
...
lib/Notifiers/LogoutNotifier.dart
View file @
7ba7402c
...
...
@@ -5,6 +5,7 @@ import 'package:generp/screens/LoginScreen.dart';
import
'package:generp/services/api_calling.dart'
;
import
'../Utils/BackgroundLocationService.dart'
;
import
'../Utils/backgroundServiceNew.dart'
;
class
LogoutNotifier
extends
ChangeNotifier
{
bool
_logoutButtonClicked
=
false
;
...
...
@@ -33,6 +34,8 @@ class LogoutNotifier extends ChangeNotifier {
_isLoading
=
false
;
_logoutButtonClicked
=
false
;
await
BackgroundLocationService
.
stopLocationService
();
await
BackgroundLocationServiceNew
.
stop
();
SharedpreferencesService
().
clearPreferences
();
Navigator
.
push
(
context
,
...
...
lib/Notifiers/PendingComplaintsProvider.dart
View file @
7ba7402c
...
...
@@ -17,6 +17,7 @@ import '../Utils/commonServices.dart';
import
'../screens/splash.dart'
;
class
Pendingcomplaintsprovider
extends
ChangeNotifier
{
TextEditingController
fsrNumberController
=
TextEditingController
();
TextEditingController
runningHoursController
=
TextEditingController
();
TextEditingController
feedbackController
=
TextEditingController
();
...
...
lib/Notifiers/QrProvider.dart
View file @
7ba7402c
import
'dart:async'
;
import
'package:flutter/material.dart'
;
import
'../Models/ordersModels/commonResponse.dart'
;
import
'../Utils/custom_snackbar.dart'
;
import
'../services/api_calling.dart'
;
class
QrProvider
extends
ChangeNotifier
{
CommonResponse
?
_qrResponse
;
bool
_isLoading
=
false
;
...
...
@@ -19,7 +17,6 @@ class QrProvider extends ChangeNotifier {
Timer
?
_timer
;
/// Fetch Razorpay QR API
Future
<
void
>
fetchRazorpayQr
({
required
String
sessionId
,
required
String
empId
,
...
...
@@ -54,7 +51,6 @@ class QrProvider extends ChangeNotifier {
}
}
/// Start 2-minute countdown
void
_startTimer
()
{
_secondsLeft
=
120
;
_timer
?.
cancel
();
...
...
@@ -68,12 +64,12 @@ class QrProvider extends ChangeNotifier {
});
}
/// Dispose timer properly
@override
void
dispose
()
{
_timer
?.
cancel
();
super
.
dispose
();
}
bool
_isPaymentUpdating
=
false
;
bool
get
isPaymentUpdating
=>
_isPaymentUpdating
;
...
...
@@ -83,6 +79,7 @@ class QrProvider extends ChangeNotifier {
}
/// Fetch Razorpay QR Payment Status
/// NOTE: This method no longer shows snackbars itself. It simply returns the response.
Future
<
CommonResponse
?>
fetchRazorpayUpiQrStatus
({
required
BuildContext
context
,
required
String
sessionId
,
...
...
@@ -100,25 +97,22 @@ class QrProvider extends ChangeNotifier {
if
(
response
!=
null
)
{
if
(
response
.
sessionExists
==
1
&&
response
.
error
==
"0"
)
{
debugPrint
(
"
Payment Status:
${response.message}
"
);
debugPrint
(
"Payment Status:
${response.message}
"
);
}
else
{
CustomSnackBar
.
showWarning
(
context:
context
,
message:
"⚠️ Payment not yet completed or failed"
);
debugPrint
(
"⚠️ Payment not yet completed or failed"
);
// IMPORTANT: do not show UI here (no repeated warnings).
// The caller (screen) should decide when to show failure messages.
debugPrint
(
"Payment still pending or failed:
${response.message}
"
);
}
}
else
{
debugPrint
(
"
❌
Null response from Razorpay QR Status API"
);
debugPrint
(
"Null response from Razorpay QR Status API"
);
}
return
response
;
// return here
return
response
;
}
catch
(
e
)
{
debugPrint
(
"
❌
fetchRazorpayUpiQrStatus error:
$e
"
);
debugPrint
(
"fetchRazorpayUpiQrStatus error:
$e
"
);
return
null
;
}
finally
{
isPaymentUpdating
=
false
;
}
}
}
lib/Notifiers/VisitDetailsProvider.dart
View file @
7ba7402c
...
...
@@ -4,6 +4,7 @@ import 'package:generp/services/api_calling.dart';
import
'package:provider/provider.dart'
;
import
'../Models/FollowUpResponse.dart'
;
import
'../Models/ServiceComplaintBillListResponse.dart'
;
import
'../Models/ViewVisitDetailsResponseNew.dart'
;
import
'../Utils/commonServices.dart'
;
...
...
@@ -14,26 +15,79 @@ class Visitdetailsprovider extends ChangeNotifier {
GeneratorDetails
_generatorDetails
=
GeneratorDetails
();
ComplaintDetailsNew
_complaintDetailsNew
=
ComplaintDetailsNew
();
List
<
Followuplist
>
_followupList
=
[];
List
<
ComplaintList
>
_complaintList
=
[];
bool
_isLoading
=
false
;
CustomerDetails
get
customerDetails
=>
_customerDetails
;
GeneratorDetails
get
generatorDetails
=>
_generatorDetails
;
ComplaintDetailsNew
get
complaintDetailsNew
=>
_complaintDetailsNew
;
List
<
Followuplist
>
get
followUpList
=>
_followupList
;
List
<
ComplaintList
>
get
complaintList
=>
_complaintList
;
bool
get
isLoading
=>
_isLoading
;
bool
get
showMoreDetails
=>
_showMoreDetails
;
// ==== FIX FOR THE CRASH ====
bool
_disposed
=
false
;
@override
void
dispose
()
{
_disposed
=
true
;
super
.
dispose
();
}
void
safeNotifyListeners
()
{
if
(!
_disposed
)
notifyListeners
();
}
// ===========================
set
showMoreDetails
(
bool
value
)
{
_showMoreDetails
=
value
;
n
otifyListeners
();
safeN
otifyListeners
();
}
Future
<
void
>
LoadVisitDetailsAPI
(
BuildContext
context
,
ComplaintID
)
async
{
ServiceComplaintBillListResponse
?
complaintBillListResponse
;
String
?
error
;
Future
<
void
>
serviceComplaintBillList
(
BuildContext
context
,
String
complaintId
)
async
{
try
{
var
HomeProvider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
,
var
homeProvider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
_isLoading
=
true
;
safeNotifyListeners
();
final
data
=
await
ApiCalling
.
serviceComplaintBillListAPI
(
homeProvider
.
empId
,
homeProvider
.
session
,
complaintId
,
);
if
(
data
!=
null
)
{
if
(
data
.
error
==
0
)
{
_complaintList
=
data
.
complaintList
??
[];
_isLoading
=
false
;
safeNotifyListeners
();
}
else
{
toast
(
context
,
"Something Went Wrong, Please try again!"
);
}
}
else
{
toast
(
context
,
"No response From the server, Please try Again!"
);
}
complaintBillListResponse
=
data
;
error
=
null
;
}
catch
(
e
)
{
error
=
e
.
toString
();
complaintBillListResponse
=
null
;
}
finally
{
_isLoading
=
false
;
safeNotifyListeners
();
}
}
Future
<
void
>
LoadVisitDetailsAPI
(
BuildContext
context
,
ComplaintID
)
async
{
try
{
var
HomeProvider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
loadVisitDetailsAPI
(
HomeProvider
.
empId
,
HomeProvider
.
session
,
...
...
@@ -42,31 +96,26 @@ class Visitdetailsprovider extends ChangeNotifier {
if
(
data
!=
null
)
{
if
(
data
.
error
==
0
)
{
// complaintdetails = data.complaintDetails!;
_customerDetails
=
data
.
customerDetails
!;
_generatorDetails
=
data
.
generatorDetails
!;
_complaintDetailsNew
=
data
.
complaintDetailsNew
!;
_isLoading
=
false
;
n
otifyListeners
();
safeN
otifyListeners
();
}
else
{
toast
(
context
,
"Something Went Wrong, Please try again!"
);
print
(
"error"
);
}
}
else
{
toast
(
context
,
"No response From the server, Please try Again!"
);
print
(
"error2"
);
}
}
on
Error
catch
(
e
)
{
}
catch
(
e
)
{
print
(
e
.
toString
());
}
}
Future
<
void
>
LoadFollowupListAPI
(
BuildContext
context
,
ComplaintID
)
async
{
try
{
var
HomeProvider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
,
);
var
HomeProvider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
loadFollowupListAPI
(
HomeProvider
.
empId
,
HomeProvider
.
session
,
...
...
@@ -75,20 +124,19 @@ class Visitdetailsprovider extends ChangeNotifier {
if
(
data
!=
null
)
{
if
(
data
.
error
==
0
)
{
// complaintdetails = data.complaintDetails!;
_followupList
=
data
.
list
??
[];
_isLoading
=
false
;
n
otifyListeners
();
safeN
otifyListeners
();
}
else
{
toast
(
context
,
"Something Went Wrong, Please try again!"
);
print
(
"error"
);
}
}
else
{
toast
(
context
,
"No response From the server, Please try Again!"
);
print
(
"error2"
);
}
}
on
Error
catch
(
e
)
{
}
catch
(
e
)
{
print
(
e
.
toString
());
}
}
}
lib/Notifiers/commonProvider/ValidationProvider.dart
View file @
7ba7402c
import
'package:flutter/material.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'../../Models/financeModels/ValidateBankAccountDetailsResponse.dart'
;
import
'../../Models/financeModels/ValidateGstNumResponse.dart'
;
class
ValidationProvider
extends
ChangeNotifier
{
bool
isLoading
=
false
;
ValidateGstNumResponse
?
gstResponse
;
ValidateBankAccountDetailsResponse
?
bankResponse
;
String
?
errorMessage
;
/// Validate GST Number
/// -----------------------------
Future
<
void
>
validateGstNumber
(
String
empId
,
String
sessionId
,
String
gstNumber
)
async
{
try
{
isLoading
=
true
;
errorMessage
=
null
;
notifyListeners
();
gstResponse
=
await
ApiCalling
.
validateGstNumberApi
(
empId
,
sessionId
,
gstNumber
,
);
if
(
gstResponse
==
null
)
{
errorMessage
=
"Failed to validate GST number"
;
}
}
catch
(
e
)
{
errorMessage
=
e
.
toString
();
}
isLoading
=
false
;
notifyListeners
();
}
/// Validate Bank Account Details
/// -----------------------------
Future
<
void
>
validateBankDetails
(
String
empId
,
String
sessionId
,
String
accountNumber
)
async
{
try
{
isLoading
=
true
;
errorMessage
=
null
;
notifyListeners
();
bankResponse
=
await
ApiCalling
.
validateBankAccountDetailsApi
(
empId
,
sessionId
,
accountNumber
,
""
);
if
(
bankResponse
==
null
)
{
errorMessage
=
"Failed to validate bank account"
;
}
}
catch
(
e
)
{
errorMessage
=
e
.
toString
();
}
isLoading
=
false
;
notifyListeners
();
}
/// Reset before calling again
void
clear
()
{
gstResponse
=
null
;
bankResponse
=
null
;
errorMessage
=
null
;
notifyListeners
();
}
}
//
//
// import 'package:flutter/cupertino.dart';
// import 'package:generp/Models/ordersModels/commonResponse.dart';
// import 'package:generp/services/api_calling.dart';
//
// class EditCommonAccountProvider extends ChangeNotifier{
// bool isLoading = false;
// String? errorMessage;
// CommonResponse? updateResponse;
//
// Future<void> updateAccountForm() async{
//
// try{
// isLoading = true;
// errorMessage = null;
// notifyListeners();
//
// updateResponse = await ApiCalling.commonUpdateAccountDetailsAPI(
// empId,
// sessionId,
// type,
// name,
// mob1,
// mob2,
// tel,
// email,
// designation,
// address,
// state,
// district,
// subLocality,
// bankName,
// branchName,
// bankIfscCode,
// accHolderName,
// bankAccNumber,
// bankUpiId
// );
//
// if (updateResponse == null){
// errorMessage = "No Response from server";
// }
// }
//
//
// }
//
// }
\ No newline at end of file
lib/Notifiers/commonProvider/accountDetailsProvider.dart
View file @
7ba7402c
...
...
@@ -7,6 +7,8 @@ import '../../Models/commonModels/commonAccountdetailsResponse.dart';
class
Accountdetailsprovider
extends
ChangeNotifier
{
bool
_showMoreDetails
=
false
;
bool
_isLoading
=
false
;
bool
get
isLoading
=>
_isLoading
;
AccountDetails
_accountDetails
=
AccountDetails
();
BalanceDetails
_balanceDetails
=
BalanceDetails
();
...
...
@@ -27,6 +29,8 @@ class Accountdetailsprovider extends ChangeNotifier {
}
Future
<
void
>
accountdetailsAPIFunction
(
context
,
accountID
)
async
{
_isLoading
=
true
;
notifyListeners
();
try
{
var
prov
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
commonAccountDetailsAPI
(
...
...
@@ -56,6 +60,8 @@ class Accountdetailsprovider extends ChangeNotifier {
}
}
}
catch
(
e
)
{}
_isLoading
=
false
;
notifyListeners
();
}
Map
<
String
,
List
<
LedgerList
>>
groupByDate
(
List
<
LedgerList
>
list
)
{
...
...
lib/Notifiers/commonProvider/accountsListProvider.dart
View file @
7ba7402c
...
...
@@ -2,8 +2,10 @@
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:generp/Models/ordersModels/commonResponse.dart'
;
import
'package:generp/Notifiers/HomeScreenNotifier.dart'
;
import
'package:generp/Utils/commonServices.dart'
;
import
'package:generp/Utils/custom_snackbar.dart'
;
import
'package:generp/screens/commom/accountsListDetails.dart'
;
import
'package:generp/screens/finance/financeDashboard.dart'
;
import
'package:generp/services/api_calling.dart'
;
...
...
@@ -103,6 +105,7 @@ class Accountslistprovider extends ChangeNotifier {
}
ValidateGstNumResponse
?
gstResponse
;
commonAddAccountsViewResponse
?
commonResponse
;
ValidateBankAccountDetailsResponse
?
bankResponse
;
String
?
errorMessage
;
...
...
@@ -284,6 +287,7 @@ class Accountslistprovider extends ChangeNotifier {
type
,
value
,
);
commonResponse
=
data
;
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
nameError
=
null
;
...
...
@@ -425,6 +429,181 @@ class Accountslistprovider extends ChangeNotifier {
}
}
Future
<
void
>
checkAndApplyGst
(
BuildContext
context
,
String
gstNumber
)
async
{
// clear previous GST error when user actively changed
gstNumberError
=
null
;
notifyListeners
();
final
trimmed
=
gstNumber
.
trim
();
if
(
trimmed
.
isEmpty
)
{
// user cleared GST: clear response + errors
gstResponse
=
null
;
gstNumberError
=
null
;
notifyListeners
();
return
;
}
try
{
isLoading
=
true
;
final
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
resp
=
await
ApiCalling
.
validateGstNumberApi
(
homeProv
.
empId
,
homeProv
.
session
,
trimmed
,
);
gstResponse
=
resp
;
if
(
resp
==
null
)
{
gstNumberError
=
"Failed to validate GST number"
;
notifyListeners
();
return
;
}
if
(
resp
.
error
==
"0"
)
{
// success -> autofill address and compare company name
// Use response field names you mentioned: legal_name_of_business and address
final
apiName
=
(
resp
.
legalNameOfBusiness
??
""
).
trim
();
final
apiAddress
=
(
resp
.
address
??
""
).
trim
();
// Autofill/override address in Step 2
if
(
apiAddress
.
isNotEmpty
)
{
// Only override if response contains useful address
addressController
.
text
=
apiAddress
;
}
// Compare company name vs gst name
final
enteredName
=
(
nameController
.
text
??
""
).
trim
();
debugPrint
(
"################# Entered text:
$enteredName
\n
response name:
$apiName
"
);
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
// Set error on step 1
nameError
=
"Company name does not match GST record ('
$apiName
'). Please correct."
;
}
else
{
nameError
=
null
;
}
}
gstNumberError
=
null
;
notifyListeners
();
return
;
}
else
{
// API returned invalid GST
gstNumberError
=
resp
.
message
??
"Invalid GST number"
;
notifyListeners
();
return
;
}
}
catch
(
e
)
{
gstNumberError
=
"Error validating GST"
;
if
(
kDebugMode
)
debugPrint
(
"checkAndApplyGst error:
$e
"
);
notifyListeners
();
return
;
}
finally
{
isLoading
=
false
;
notifyListeners
();
}
}
void
recheckNameWithGst
()
{
if
(
gstResponse
==
null
)
return
;
final
apiName
=
(
gstResponse
?.
legalNameOfBusiness
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
nameError
=
"Company name does not match GST record ('
$apiName
')"
;
}
else
{
nameError
=
null
;
}
}
notifyListeners
();
}
/// New helper: check bank account + ifsc and call bank API when both present.
/// Called by UI when user finishes account/ifsc input or when IFSC changes.
Future
<
void
>
checkAndApplyBank
(
BuildContext
context
,
String
accountNumber
)
async
{
bankAcNumberError
=
null
;
bankIFSCError
=
null
;
notifyListeners
();
final
acc
=
accountNumber
.
trim
();
final
ifsc
=
bankIfscCotroller
.
text
.
trim
();
if
(
acc
.
isEmpty
&&
ifsc
.
isEmpty
)
{
// user cleared both
bankResponse
=
null
;
bankAcNumberError
=
null
;
bankIFSCError
=
null
;
notifyListeners
();
return
;
}
// If account entered, IFSC required
if
(
acc
.
isNotEmpty
&&
ifsc
.
isEmpty
)
{
bankIFSCError
=
"IFSC is required when account number is entered"
;
notifyListeners
();
return
;
}
// validate IFSC format (basic)
final
ifscReg
=
RegExp
(
r'^[A-Za-z]{4}0[A-Za-z0-9]{6}$'
);
if
(
ifsc
.
isNotEmpty
&&
!
ifscReg
.
hasMatch
(
ifsc
))
{
bankIFSCError
=
"Invalid IFSC format"
;
notifyListeners
();
return
;
}
if
(
acc
.
isNotEmpty
&&
ifsc
.
isNotEmpty
)
{
try
{
isLoading
=
true
;
final
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
resp
=
await
ApiCalling
.
validateBankAccountDetailsApi
(
homeProv
.
empId
,
homeProv
.
session
,
acc
,
ifsc
,
);
bankResponse
=
resp
;
if
(
resp
==
null
)
{
bankAcNumberError
=
"Failed to validate bank details"
;
notifyListeners
();
return
;
}
if
(
resp
.
error
==
"0"
)
{
// success -> autofill bank fields
bankNameController
.
text
=
resp
.
bankName
??
bankNameController
.
text
;
branchNameController
.
text
=
resp
.
branch
??
branchNameController
.
text
;
bankHolderNameController
.
text
=
resp
.
nameAtBank
??
bankHolderNameController
.
text
;
// clear errors
bankAcNumberError
=
null
;
bankIFSCError
=
null
;
banknameError
=
null
;
bankBranchError
=
null
;
bankHolderNameError
=
null
;
notifyListeners
();
return
;
}
else
{
bankAcNumberError
=
resp
.
message
??
"Invalid account details"
;
notifyListeners
();
return
;
}
}
catch
(
e
)
{
bankAcNumberError
=
"Error validating bank:
${e.toString()}
"
;
if
(
kDebugMode
)
debugPrint
(
"checkAndApplyBank error:
$e
"
);
notifyListeners
();
return
;
}
finally
{
isLoading
=
false
;
notifyListeners
();
}
}
}
bool
hasFilledAdditionalDetails
=
false
;
bool
_submitClicked
=
false
;
...
...
@@ -504,7 +683,7 @@ class Accountslistprovider extends ChangeNotifier {
}
}
bool
validateStep1
()
{
bool
validateStep1
(
BuildContext
context
)
{
accountError
=
null
;
nameError
=
null
;
mobileError
=
null
;
...
...
@@ -518,10 +697,53 @@ class Accountslistprovider extends ChangeNotifier {
nameError
=
"Please Enter a Name"
;
isValid
=
false
;
}
if
(
nameError
!=
null
&&
nameError
!=
""
)
{
isValid
=
false
;
}
if
(
mobileController
.
text
.
trim
().
isNotEmpty
&&
mobileController
.
text
.
length
<
10
)
{
mobileError
=
"Mobile Number should be 10 digits"
;
isValid
=
false
;
}
if
(
gstResponse
!=
null
){
final
apiName
=
(
gstResponse
?.
legalNameOfBusiness
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
final
msg
=
"Company name does not match GST record ('
$apiName
')"
;
CustomSnackBar
.
showWarning
(
context:
context
,
message:
msg
);
isValid
=
false
;
}
else
{
isValid
=
true
;
nameError
=
null
;
}
}
}
if
(
commonResponse
!=
null
){
final
message
=
(
commonResponse
?.
message
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
message
!=
"Can Proceed"
)
{
isValid
=
false
;
CustomSnackBar
.
showWarning
(
context:
context
,
message:
message
);
}
else
{
isValid
=
true
;
}
}
final
apiName
=
(
gstResponse
?.
legalNameOfBusiness
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
nameError
=
"Company name does not match GST record ('
$apiName
')"
;
}
else
{
nameError
=
null
;
}
}
if
(
mobileController
.
text
.
trim
().
isEmpty
)
{
mobileError
=
"Please Enter Mobile Number"
;
isValid
=
false
;
...
...
@@ -535,6 +757,8 @@ class Accountslistprovider extends ChangeNotifier {
return
isValid
;
}
bool
validateStep2
()
{
stateError
=
null
;
districtError
=
null
;
...
...
@@ -547,7 +771,7 @@ class Accountslistprovider extends ChangeNotifier {
return
isValid
;
}
bool
validateStep3
()
{
bool
validateStep3
(
BuildContext
context
)
{
banknameError
=
null
;
bankBranchError
=
null
;
bankIFSCError
=
null
;
...
...
@@ -557,6 +781,21 @@ class Accountslistprovider extends ChangeNotifier {
gstNumberError
=
null
;
bool
isValid
=
true
;
_submitClicked
=
false
;
if
(
gstResponse
!=
null
){
final
apiName
=
(
gstResponse
?.
legalNameOfBusiness
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
final
msg
=
"Company name does not match GST record ('
$apiName
')"
;
CustomSnackBar
.
showWarning
(
context:
context
,
message:
msg
);
isValid
=
false
;
}
else
{
isValid
=
true
;
nameError
=
null
;
}
}
}
notifyListeners
();
return
isValid
;
}
...
...
@@ -564,6 +803,20 @@ class Accountslistprovider extends ChangeNotifier {
bool
validateStep4
()
{
bool
isValid
=
true
;
_submitClicked
=
false
;
if
(
gstResponse
!=
null
){
final
apiName
=
(
gstResponse
?.
legalNameOfBusiness
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
isValid
=
false
;
}
else
{
isValid
=
true
;
nameError
=
null
;
}
}
}
notifyListeners
();
return
isValid
;
}
...
...
@@ -607,6 +860,31 @@ class Accountslistprovider extends ChangeNotifier {
isValid
=
false
;
}
if
(
commonResponse
!=
null
){
final
message
=
(
commonResponse
?.
message
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
message
!=
"Can Proceed"
)
{
isValid
=
false
;
CustomSnackBar
.
showWarning
(
context:
context
,
message:
message
);
}
else
{
isValid
=
true
;
}
}
final
apiName
=
(
gstResponse
?.
legalNameOfBusiness
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
isValid
=
false
;
CustomSnackBar
.
showWarning
(
context:
context
,
message:
"Company name does not match GST record ('
$apiName
')"
);
nameError
=
"Company name does not match GST record ('
$apiName
')"
;
}
else
{
isValid
=
true
;
nameError
=
null
;
}
}
_submitClicked
=
false
;
notifyListeners
();
return
isValid
;
...
...
@@ -633,13 +911,13 @@ class Accountslistprovider extends ChangeNotifier {
}
/// simplified update - kept for compatibility if UI uses it
Future
<
void
>
updateGSTNumber
(
BuildContext
context
,
String
value
)
async
{
// We won't call the GST API here — UI flow calls validateGstNumber explicitly.
// This function simply clears previous error on typing.
void
updateGSTNumber
(
String
value
)
{
// just clear the error when user edits GST
gstNumberError
=
null
;
notifyListeners
();
}
void
updateBankBranch
(
String
value
)
{
bankBranchError
=
null
;
notifyListeners
();
...
...
lib/Notifiers/commonProvider/editCommonAccountProvider.dart
0 → 100644
View file @
7ba7402c
This diff is collapsed.
Click to expand it.
lib/Notifiers/crmProvider/CrmNearByGeneratorsProvider.dart
0 → 100644
View file @
7ba7402c
import
'dart:async'
;
import
'dart:io'
;
import
'dart:ui'
as
ui
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter_svg/svg.dart'
;
import
'package:generp/Notifiers/HomeScreenNotifier.dart'
;
import
'package:generp/Utils/SharedpreferencesService.dart'
;
import
'package:generp/screens/LoginScreen.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:geolocator/geolocator.dart'
;
import
'package:google_maps_flutter/google_maps_flutter.dart'
;
import
'package:image_picker/image_picker.dart'
;
import
'package:geocoding/geocoding.dart'
as
geocoding
;
import
'package:location/location.dart'
as
Location
;
import
'package:permission_handler/permission_handler.dart'
;
import
'package:provider/provider.dart'
;
import
'../../Models/NearbyGeneratorsResponse.dart'
;
import
'../../Utils/commonServices.dart'
;
class
CrmNearByGeneratorsProvider
extends
ChangeNotifier
{
final
ImagePicker
_picker
=
ImagePicker
();
List
<
Nearbygenerators
>
_generatorslist
=
[];
final
TextEditingController
_locationController
=
TextEditingController
();
final
String
_googleApikey
=
"AIzaSyBGzvgMMKwPBAANTwaoRsAnrCpiWCj8wVs"
;
GoogleMapController
?
_mapController
;
CameraPosition
?
_cameraPosition
;
final
LatLng
_startLocation
=
const
LatLng
(
17.439112226708446
,
78.43292499146135
,
);
String
_latlongs
=
""
;
List
<
Marker
>
_markers
=
[];
List
<
String
>
_addresses
=
[];
Location
.
LocationData
?
_currentLocation
;
bool
_isLocationEnabled
=
false
;
bool
_hasLocationPermission
=
false
;
Timer
?
_timer
;
File
?
_image
;
bool
_isLoading
=
true
;
String
_selectedItem
=
'Active'
;
double
_currentValue
=
1.0
;
Timer
?
_debounceTimer
;
List
<
Nearbygenerators
>
get
generatorsList
=>
_generatorslist
;
TextEditingController
get
LocationController
=>
_locationController
;
String
get
googleAPIKey
=>
_googleApikey
;
GoogleMapController
?
get
mapController
=>
_mapController
;
CameraPosition
?
get
cameraPosition
=>
_cameraPosition
;
LatLng
get
startLocation
=>
_startLocation
;
String
get
latlongs
=>
_latlongs
;
List
<
Marker
>
get
markers
=>
_markers
;
List
<
String
>
get
addresses
=>
_addresses
;
Location
.
LocationData
?
get
currentLocation
=>
_currentLocation
;
bool
get
isLocationEnabled
=>
_isLocationEnabled
;
bool
get
hasLocationPermission
=>
_hasLocationPermission
;
bool
get
isLoading
=>
_isLoading
;
Timer
?
get
timer
=>
_timer
;
File
?
get
image
=>
_image
;
String
get
selectedItem
=>
_selectedItem
;
double
get
currentValue
=>
_currentValue
;
set
currentValue
(
value
)
{
_currentValue
=
value
;
notifyListeners
();
}
set
selectedItem
(
String
value
)
{
_selectedItem
=
value
;
notifyListeners
();
}
set
markers
(
List
<
Marker
>
value
)
{
_markers
=
value
;
notifyListeners
();
}
set
mapController
(
value
)
{
_mapController
=
value
;
notifyListeners
();
}
void
resetAll
()
{
_currentValue
=
1.0
;
_selectedItem
=
""
;
_markers
=
[];
_addresses
=
[];
}
Future
<
void
>
getLocationPermission
(
context
)
async
{
// Check if location services are enabled
_isLocationEnabled
=
await
Geolocator
.
isLocationServiceEnabled
();
// Check if the app has been granted location permission
LocationPermission
permission
=
await
Geolocator
.
checkPermission
();
_hasLocationPermission
=
permission
==
LocationPermission
.
always
||
permission
==
LocationPermission
.
whileInUse
;
final
Location
.
Location
location
=
Location
.
Location
();
bool
serviceEnabled
;
Location
.
PermissionStatus
permissionGranted
;
serviceEnabled
=
await
location
.
serviceEnabled
();
if
(!
serviceEnabled
)
{
serviceEnabled
=
await
location
.
requestService
();
if
(!
serviceEnabled
)
{
return
;
}
}
_isLoading
=
false
;
permissionGranted
=
(
await
location
.
hasPermission
());
if
(
permissionGranted
==
PermissionStatus
)
{
permissionGranted
=
(
await
location
.
requestPermission
());
if
(
permissionGranted
!=
PermissionStatus
)
{
return
;
}
}
final
Location
.
LocationData
locData
=
await
location
.
getLocation
();
_currentLocation
=
locData
;
if
(
_currentLocation
!=
null
)
{
_mapController
?.
animateCamera
(
CameraUpdate
.
newLatLng
(
LatLng
(
_currentLocation
!.
latitude
!,
_currentLocation
!.
longitude
!),
),
);
final
lat
=
_currentLocation
!.
latitude
;
final
lang
=
_currentLocation
!.
longitude
!;
_latlongs
=
'
$lat
,
$lang
'
;
LoadNearbyGeneratorsAPI
(
context
,
_currentValue
);
}
}
void
onCameraMove
(
context
,
CameraPosition
position
)
{
_timer
?.
cancel
();
// Cancel any previous timer
_timer
=
Timer
(
Duration
(
seconds:
1
),
()
{
getLocationPermission
(
context
);
});
}
void
debounce
(
VoidCallback
callback
,
Duration
duration
)
{
_debounceTimer
?.
cancel
();
_debounceTimer
=
Timer
(
duration
,
callback
);
}
Future
<
void
>
LoadNearbyGeneratorsAPI
(
BuildContext
context
,
radius
)
async
{
if
(
_latlongs
.
isEmpty
||
_currentValue
<=
0
)
{
print
(
"Invalid parameters: latlongs=
$_latlongs
, currentValue=
$_currentValue
"
,
);
return
;
}
try
{
var
provider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
loadCrmNearbyGeneratorsAPI
(
provider
.
empId
,
provider
.
session
,
_latlongs
,
_currentValue
,
_selectedItem
,
);
if
(
data
!=
null
)
{
if
(
data
.
sessionExists
==
1
)
{
if
(
data
.
error
==
0
)
{
_generatorslist
=
data
.
list
!;
await
updateMarkersFromApiResponse
(
context
,
data
.
list
!);
_isLoading
=
false
;
notifyListeners
();
}
else
{}
}
else
{
// SharedpreferencesService().clearPreferences();
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => LoginScreen()),
// );
}
}
else
{
toast
(
context
,
"Something went wrong, Please try again."
);
}
}
on
Exception
catch
(
e
)
{
print
(
"
$e
"
);
}
}
Future
<
void
>
updateMarkersFromApiResponse
(
BuildContext
context
,
List
<
Nearbygenerators
>
generatorslist
,
)
async
{
_markers
=
await
createMarkersFromApiResponse
(
context
,
generatorslist
);
_addresses
.
clear
();
await
Future
.
forEach
(
generatorslist
,
(
store
)
async
{
String
address
=
await
_getAddressFromLatLng
(
store
.
loc
);
_addresses
.
add
(
address
);
});
notifyListeners
();
// for (int i = 0; i < _addresses.length; i++) {
// //print('List of Addresses:' "${addresses[i]}");
// // print('List of Addresses:' "${addresses[1]}" );
// }
}
Future
<
List
<
Marker
>>
createMarkersFromApiResponse
(
BuildContext
context
,
List
<
Nearbygenerators
>
generatorslist
,
)
async
{
List
<
Marker
>
markers
=
[];
// print("Hello Nutsby!");
ByteData
data
=
await
rootBundle
.
load
(
"assets/images/dg_set.png"
);
Uint8List
bytes
=
data
.
buffer
.
asUint8List
();
await
Future
.
forEach
(
generatorslist
,
(
generator
)
async
{
ui
.
Codec
codec
=
await
ui
.
instantiateImageCodec
(
bytes
,
targetWidth:
75
,
targetHeight:
95
,
);
ui
.
FrameInfo
fi
=
await
codec
.
getNextFrame
();
Uint8List
resizedBytes
=
(
await
fi
.
image
.
toByteData
(
format:
ui
.
ImageByteFormat
.
png
,
))!.
buffer
.
asUint8List
();
markers
.
add
(
Marker
(
markerId:
MarkerId
(
generator
.
generatorId
.
toString
()),
position:
_parseLatLng
(
generator
.
loc
),
icon:
BitmapDescriptor
.
fromBytes
(
resizedBytes
),
infoWindow:
InfoWindow
(
onTap:
()
{
print
(
"INFO WINDOW TAP"
);
},
title:
"Customer Name:
${generator.accName}
"
,
snippet:
"Product Name:
${generator.productName}
"
,
),
zIndex:
100
,
),
);
});
return
markers
;
}
LatLng
_parseLatLng
(
String
?
location
)
{
if
(
location
!=
null
)
{
List
<
String
>
parts
=
location
.
split
(
','
);
if
(
parts
.
length
==
2
)
{
double
lat
=
double
.
tryParse
(
parts
[
0
])
??
0.0
;
double
lng
=
double
.
tryParse
(
parts
[
1
])
??
0.0
;
return
LatLng
(
lat
,
lng
);
}
}
return
const
LatLng
(
0.0
,
0.0
);
}
Future
<
String
>
_getAddressFromLatLng
(
String
?
location
)
async
{
if
(
location
!=
null
)
{
List
<
String
>
parts
=
location
.
split
(
','
);
if
(
parts
.
length
==
2
)
{
double
lat
=
double
.
tryParse
(
parts
[
0
])
??
0.0
;
double
lng
=
double
.
tryParse
(
parts
[
1
])
??
0.0
;
List
<
geocoding
.
Placemark
>
placemarks
=
await
geocoding
.
placemarkFromCoordinates
(
lat
,
lng
);
if
(
placemarks
.
isNotEmpty
)
{
final
placemark
=
placemarks
.
first
;
String
address
=
'
${placemark.street ?? ''}
, '
'
${placemark.thoroughfare ?? ''}
'
// '${placemark.subThoroughfare ?? ''}, '
// '${placemark.name ?? ''}, '
'
${placemark.subLocality ?? ''}
, '
'
${placemark.locality ?? ''}
, '
'
${placemark.administrativeArea ?? ''}
, '
'
${placemark.subAdministrativeArea ?? ''}
'
'
${placemark.postalCode ?? ''}
, '
'
${placemark.country ?? ''}
'
;
return
address
.
trim
();
}
}
}
return
"Address not found"
;
}
}
lib/Notifiers/financeProvider/RequesitionLidtDetailsProvider.dart
View file @
7ba7402c
...
...
@@ -302,27 +302,45 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
}
catch
(
e
)
{}
}
preValues
()
{
preValues
()
{
// safeNormalizeAmount()
print
(
"here 212ssass1"
);
requestedAmount
.
text
=
_requestDetails
.
requestedAmount
??
"-"
;
requestedAmount
.
text
=
safeNormalizeAmount
(
_requestDetails
.
requestedAmount
)
;
proposedPaymentAccount
.
text
=
_requestDetails
.
proposedAccount
??
"-"
;
approvedAmountReadonly
.
text
=
_requestDetails
.
formattedAmount
??
"-"
;
approvedAmount
.
text
=
_requestDetails
.
amount
??
"-"
;
accountName
.
text
=
_requestDetails
.
accountName
??
"
-
"
;
branch
.
text
=
_requestDetails
.
branch
??
"
-
"
;
requestingPurpose
.
text
=
_requestDetails
.
requestingPurpose
??
"
-
"
;
description
.
text
=
_requestDetails
.
description
??
"
-
"
;
amount
.
text
=
_requestDetails
.
amount
??
"-"
;
paymentMode
.
text
=
_requestDetails
.
requestMode
??
"
-
"
;
bankUpiID
.
text
=
_requestDetails
.
bankUpiId
??
"
-
"
;
bankName
.
text
=
_requestDetails
.
bankName
??
"
-
"
;
bankBranchName
.
text
=
_requestDetails
.
bankBranchname
??
"
-
"
;
bankAccountNumber
.
text
=
_requestDetails
.
bankAccountNumber
??
"
-
"
;
bankIfscCode
.
text
=
_requestDetails
.
bankIfscCode
??
"
-
"
;
bankHolderName
.
text
=
_requestDetails
.
bankAccountHolderName
??
"
-
"
;
approvedAmountReadonly
.
text
=
safeNormalizeAmount
(
_requestDetails
.
amount
)
;
approvedAmount
.
text
=
safeNormalizeAmount
(
_requestDetails
.
amount
)
;
accountName
.
text
=
_requestDetails
.
accountName
??
""
;
branch
.
text
=
_requestDetails
.
branch
??
""
;
requestingPurpose
.
text
=
_requestDetails
.
requestingPurpose
??
""
;
description
.
text
=
_requestDetails
.
description
??
""
;
amount
.
text
=
safeNormalizeAmount
(
_requestDetails
.
amount
)
;
paymentMode
.
text
=
_requestDetails
.
requestMode
??
""
;
bankUpiID
.
text
=
_requestDetails
.
bankUpiId
??
""
;
bankName
.
text
=
_requestDetails
.
bankName
??
""
;
bankBranchName
.
text
=
_requestDetails
.
bankBranchname
??
""
;
bankAccountNumber
.
text
=
_requestDetails
.
bankAccountNumber
??
""
;
bankIfscCode
.
text
=
_requestDetails
.
bankIfscCode
??
""
;
bankHolderName
.
text
=
_requestDetails
.
bankAccountHolderName
??
""
;
notifyListeners
();
}
String
safeNormalizeAmount
(
String
?
input
)
{
if
(
input
==
null
||
input
.
trim
().
isEmpty
)
return
"0"
;
// Remove currency symbols, commas and spaces - keep digits and dots
String
cleaned
=
input
.
replaceAll
(
RegExp
(
r'[^0-9.]'
),
''
);
// Handle multiple decimal points: keep only first dot
int
firstDot
=
cleaned
.
indexOf
(
'.'
);
if
(
firstDot
!=
-
1
)
{
String
before
=
cleaned
.
substring
(
0
,
firstDot
+
1
);
String
after
=
cleaned
.
substring
(
firstDot
+
1
).
replaceAll
(
'.'
,
''
);
cleaned
=
before
+
after
;
}
return
cleaned
.
isEmpty
?
"0"
:
cleaned
;
}
Future
<
void
>
approveRejectPaymentRequestAPIFunction
(
context
,
paymentRequestId
,
...
...
@@ -363,31 +381,31 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
paymentRequestId
,
approveRemarks
,
)
async
{
print
(
"
🎯
=== REJECT PROVIDER METHOD STARTED ==="
);
print
(
" === REJECT PROVIDER METHOD STARTED ==="
);
// Set loading to true at the start
_isLoading
=
true
;
notifyListeners
();
print
(
"
🔄
Loading set to TRUE in reject method"
);
print
(
" Loading set to TRUE in reject method"
);
bool
success
=
false
;
try
{
print
(
"
🔍
Starting validation for rejection..."
);
print
(
" Starting validation for rejection..."
);
if
(
approveRemarks
.
toString
().
trim
().
isEmpty
)
{
print
(
"
❌
Remarks validation failed"
);
remarksError
=
"Please Enter Remarks"
;
_isLoading
=
false
;
notifyListeners
();
return
false
;
}
//
if (approveRemarks.toString().trim().isEmpty) {
//
print(" Remarks validation failed");
//
remarksError = "Please Enter Remarks";
//
_isLoading = false;
//
notifyListeners();
//
return false;
//
}
print
(
"
✅
Validation passed"
);
print
(
" Validation passed"
);
var
provider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
print
(
"
🌐
Calling reject API..."
);
print
(
" Calling reject API..."
);
final
data
=
await
ApiCalling
.
RejectPaymentRequestSubmitAPI
(
provider
.
empId
,
provider
.
session
,
...
...
@@ -395,36 +413,36 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
paymentRequestId
,
approveRemarks
,
);
print
(
"
🌐
Reject API call completed"
);
print
(
" Reject API call completed"
);
if
(
data
!=
null
)
{
print
(
"
📡
Reject API Response: error=
${data.error}
, message=
${data.message}
"
);
print
(
" Reject API Response: error=
${data.error}
, message=
${data.message}
"
);
if
(
data
.
error
==
"0"
)
{
print
(
"
✅
Reject API SUCCESS"
);
print
(
" Reject API SUCCESS"
);
success
=
true
;
if
(
context
.
mounted
)
{
print
(
"
🎯
Context mounted - performing UI operations"
);
print
(
" Context mounted - performing UI operations"
);
paymentRequesitionDetails
(
context
,
paymentRequestId
);
resetAll
();
toast
(
context
,
data
.
message
);
Navigator
.
pop
(
context
,
true
);
// Pass true to indicate success
}
}
else
{
print
(
"
❌
Reject API returned error:
${data.message}
"
);
print
(
" Reject API returned error:
${data.message}
"
);
if
(
context
.
mounted
)
{
toast
(
context
,
data
.
message
??
"Rejection failed"
);
}
}
}
else
{
print
(
"
❌
NULL response from reject API"
);
print
(
" NULL response from reject API"
);
if
(
context
.
mounted
)
{
toast
(
context
,
"No response from server"
);
}
}
}
catch
(
e
)
{
print
(
"
💥
EXCEPTION in reject provider method:
$e
"
);
print
(
" EXCEPTION in reject provider method:
$e
"
);
if
(
context
.
mounted
)
{
toast
(
context
,
"Error:
${e.toString()}
"
);
}
...
...
@@ -433,10 +451,10 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
_isLoading
=
false
;
notifyListeners
();
print
(
"
🔄
Loading set to FALSE in reject method finally block"
);
print
(
" Loading set to FALSE in reject method finally block"
);
}
print
(
"
🎯
=== REJECT PROVIDER METHOD COMPLETED ==="
);
print
(
" === REJECT PROVIDER METHOD COMPLETED ==="
);
return
success
;
}
...
...
@@ -457,27 +475,27 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
String
approve_remarks
,
String
proposed_payment_account_id
,
)
async
{
print
(
"
🎯
=== PROVIDER METHOD STARTED ==="
);
print
(
" === PROVIDER METHOD STARTED ==="
);
// Set loading to true at the start
_isLoading
=
true
;
notifyListeners
();
try
{
print
(
"
🔍
Starting validation..."
);
print
(
" Starting validation..."
);
if
(!
validateApproval
(
approved_amount
,
approve_remarks
,
proposed_payment_account_id
))
{
print
(
"
❌
VALIDATION FAILED - Stopping execution"
);
print
(
" VALIDATION FAILED - Stopping execution"
);
_isLoading
=
false
;
notifyListeners
();
return
;
}
print
(
"
✅
Validation passed"
);
print
(
" Validation passed"
);
print
(
"
👤
Getting home provider..."
);
print
(
" Getting home provider..."
);
var
homeProvider
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
print
(
"
👤
Emp ID:
${homeProvider.empId}
, Session:
${homeProvider.session}
"
);
print
(
" Emp ID:
${homeProvider.empId}
, Session:
${homeProvider.session}
"
);
print
(
"
🌐
Calling API..."
);
print
(
" Calling API..."
);
final
data
=
await
ApiCalling
.
ApprovePaymentRequestSubmitAPI
(
homeProvider
.
empId
,
homeProvider
.
session
,
...
...
@@ -487,43 +505,43 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
approve_remarks
,
proposed_payment_account_id
,
);
print
(
"
🌐
API call completed"
);
print
(
" API call completed"
);
if
(
data
!=
null
)
{
print
(
"
📡
API Response: error=
${data.error}
, message=
${data.message}
"
);
print
(
" API Response: error=
${data.error}
, message=
${data.message}
"
);
if
(
data
.
error
==
"0"
)
{
print
(
"
✅
API SUCCESS - Processing..."
);
print
(
" API SUCCESS - Processing..."
);
// Check if context is still valid before UI operations
if
(
context
.
mounted
)
{
print
(
"
🎯
Context mounted - performing UI operations"
);
print
(
" Context mounted - performing UI operations"
);
paymentRequesitionDetails
(
context
,
payment_request_id
);
resetAll
();
toast
(
context
,
data
.
message
);
Navigator
.
pop
(
context
,
true
);
print
(
"
✅
UI operations completed"
);
print
(
" UI operations completed"
);
}
else
{
print
(
"
⚠
️ Context not mounted - skipping UI operations"
);
print
(
"️ Context not mounted - skipping UI operations"
);
}
notifyListeners
();
print
(
"
✅
Notify listeners called"
);
print
(
" Notify listeners called"
);
}
else
{
print
(
"
❌
API returned error:
${data.message}
"
);
print
(
" API returned error:
${data.message}
"
);
if
(
context
.
mounted
)
{
toast
(
context
,
data
.
message
??
"Submission failed"
);
}
}
}
else
{
print
(
"
❌
NULL response from API"
);
print
(
" NULL response from API"
);
if
(
context
.
mounted
)
{
toast
(
context
,
"No response from server"
);
}
}
}
catch
(
e
,
s
)
{
print
(
"
💥
EXCEPTION in provider method:
$e
"
);
print
(
"
📋
Stack trace:
$s
"
);
print
(
" EXCEPTION in provider method:
$e
"
);
print
(
" Stack trace:
$s
"
);
// Show error to user
if
(
context
.
mounted
)
{
toast
(
context
,
"Error:
${e.toString()}
"
);
...
...
@@ -532,10 +550,10 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
// Set loading to false when everything is done (success or error)
_isLoading
=
false
;
notifyListeners
();
print
(
"
🔄
Loading state set to false"
);
print
(
" Loading state set to false"
);
}
print
(
"
🎯
=== PROVIDER METHOD COMPLETED ==="
);
print
(
" === PROVIDER METHOD COMPLETED ==="
);
}
...
...
@@ -640,11 +658,11 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
}
bool
validateApproval
(
String
approvedAmount
,
//
Add type for clarity
String
approveRemarks
,
//
Add type for clarity
String
proposedPaymentAccountId
,
//
Add type for clarity
String
approvedAmount
,
//
String
approveRemarks
,
//
String
proposedPaymentAccountId
,
//
)
{
print
(
"
🔍
=== VALIDATION STARTED ==="
);
print
(
" === VALIDATION STARTED ==="
);
print
(
" Approved Amount: '
$approvedAmount
'"
);
print
(
" Requested Amount: '
${requestedAmount.text}
'"
);
print
(
" Remarks: '
$approveRemarks
'"
);
...
...
@@ -664,11 +682,11 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
}
// Fix 2: Use the String parameter directly (no .text)
if
(
approveRemarks
.
trim
().
isEmpty
)
{
remarksError
=
"Please Enter Remarks"
;
isValid
=
false
;
print
(
"❌ Remarks are empty"
);
}
//
if (approveRemarks.trim().isEmpty) {
//
remarksError = "Please Enter Remarks";
//
isValid = false;
//
print("❌ Remarks are empty");
//
}
// Fix 3: Parse the String parameters, not .text
if
(
approvedAmount
.
trim
().
isNotEmpty
&&
requestedAmount
.
text
.
trim
().
isNotEmpty
)
{
...
...
@@ -677,35 +695,35 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
double
approved
=
numberFormat
.
parse
(
approvedAmount
.
trim
()).
toDouble
();
double
requested
=
numberFormat
.
parse
(
requestedAmount
.
text
.
trim
()).
toDouble
();
print
(
"
💰
Amount Comparison: Approved:
$approved
, Requested:
$requested
"
);
print
(
" Amount Comparison: Approved:
$approved
, Requested:
$requested
"
);
if
(
approved
>
requested
)
{
ApprovedAmountError
=
"Approved Amount should not be greater than requested amount"
;
isValid
=
false
;
print
(
"
❌
Approved amount exceeds requested amount"
);
print
(
" Approved amount exceeds requested amount"
);
}
}
catch
(
e
)
{
print
(
"
💥
Error parsing amounts:
$e
"
);
print
(
" Error parsing amounts:
$e
"
);
ApprovedAmountError
=
"Invalid amount format"
;
isValid
=
false
;
}
}
// Fix 4: Use the parameter OR check both for consistency
if
(
proposedPaymentAccountId
.
isEmpty
&&
_selectedID
.
isEmpty
)
{
selectpaymentAccountError
=
"Please select an account"
;
isValid
=
false
;
print
(
"
❌
No payment account selected"
);
}
else
if
(
proposedPaymentAccountId
.
isNotEmpty
&&
_selectedID
.
isEmpty
)
{
// If parameter has value but _selectedID doesn't, sync them
_selectedID
=
proposedPaymentAccountId
;
print
(
"
🔄
Synced selected ID from parameter:
$_selectedID
"
);
}
//
if (proposedPaymentAccountId.isEmpty && _selectedID.isEmpty) {
//
selectpaymentAccountError = "Please select an account";
//
isValid = false;
// //
print(" No payment account selected");
//
} else if (proposedPaymentAccountId.isNotEmpty && _selectedID.isEmpty) {
//
// If parameter has value but _selectedID doesn't, sync them
//
_selectedID = proposedPaymentAccountId;
// //
print(" Synced selected ID from parameter: $_selectedID");
//
}
_submitClicked
=
false
;
notifyListeners
();
print
(
"
🔍
=== VALIDATION RESULT:
$isValid
==="
);
//
print(" === VALIDATION RESULT: $isValid ===");
return
isValid
;
}
...
...
@@ -779,6 +797,12 @@ class Requesitionlidtdetailsprovider extends ChangeNotifier {
notifyListeners
();
}
resetRequired
()
{
remarksError
=
null
;
selectpaymentAccountError
=
null
;
notifyListeners
();
}
onChangeApprov
(
value
)
{
final
numberFormat
=
NumberFormat
.
decimalPattern
();
if
(
numberFormat
.
parse
(
approvedAmount
.
text
)
>
...
...
lib/Notifiers/loginNotifier.dart
View file @
7ba7402c
...
...
@@ -184,6 +184,12 @@ class Loginnotifier extends ChangeNotifier {
SharedpreferencesService
().
saveString
(
"UserName"
,
data
.
name
!);
SharedpreferencesService
().
saveString
(
"UserEmail"
,
data
.
emailId
!);
SharedpreferencesService
().
saveString
(
"Session_id"
,
data
.
sessionId
!);
SharedpreferencesService
().
saveString
(
"user"
,
data
.
userId
!);
SharedpreferencesService
().
saveString
(
"session"
,
data
.
sessionId
!);
print
(
"USER ID :
${data.userId}
"
);
print
(
"SESSISON ID:
${data.sessionId}
"
);
var
roles
=
data
.
permissions
!.
toString
();
SharedpreferencesService
().
saveString
(
"roles"
,
roles
);
...
...
lib/Utils/backgroundServiceNew.dart
0 → 100644
View file @
7ba7402c
// lib/services/background_location_service.dart
import
'dart:async'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter_foreground_task/flutter_foreground_task.dart'
;
import
'package:geolocator/geolocator.dart'
;
import
'package:provider/provider.dart'
;
import
'../Notifiers/HomeScreenNotifier.dart'
;
import
'../services/api_calling.dart'
;
import
'SharedpreferencesService.dart'
;
@pragma
(
'vm:entry-point'
)
void
startCallback
(
)
{
FlutterForegroundTask
.
setTaskHandler
(
LocationTaskHandler
());
}
class
LocationTaskHandler
extends
TaskHandler
{
StreamSubscription
<
Position
>?
_stream
;
String
?
_empId
;
String
?
_sessionId
;
@override
Future
<
void
>
onStart
(
DateTime
timestamp
,
TaskStarter
starter
)
async
{
// Load user data
_empId
=
await
SharedpreferencesService
().
getString
(
"user"
);
_sessionId
=
await
SharedpreferencesService
().
getString
(
"session"
);
// var prov = Provider.of<HomescreenNotifier>(context, listen: false);
// _empId = prov.empId;
// _sessionId = prov.session;
print
(
"DATA :
${_empId}
"
);
print
(
"DATA :
${_sessionId}
"
);
if
(
_empId
==
null
||
_sessionId
==
null
)
{
FlutterForegroundTask
.
updateService
(
notificationTitle:
"GEN ERP"
,
notificationText:
"Please login first"
,
);
return
;
}
// Start real-time location stream (when moving)
_stream
=
Geolocator
.
getPositionStream
(
locationSettings:
const
LocationSettings
(
accuracy:
LocationAccuracy
.
high
,
distanceFilter:
20
,
// Only send if moved 20 meters
),
).
listen
((
position
)
{
_sendLocationToApi
(
position
);
});
// Send first location immediately
_sendCurrentLocationOnce
();
FlutterForegroundTask
.
updateService
(
notificationTitle:
"GEN ERP"
,
notificationText:
"Live tracking active"
,
);
}
Future
<
void
>
_sendCurrentLocationOnce
()
async
{
try
{
final
position
=
await
Geolocator
.
getCurrentPosition
(
desiredAccuracy:
LocationAccuracy
.
high
,
timeLimit:
const
Duration
(
seconds:
15
),
);
await
_sendLocationToApi
(
position
);
}
catch
(
e
)
{
if
(
kDebugMode
)
print
(
"Initial location failed:
$e
"
);
}
}
Future
<
void
>
_sendLocationToApi
(
Position
position
)
async
{
final
location
=
"
${position.latitude}
,
${position.longitude}
"
;
_empId
=
await
SharedpreferencesService
().
getString
(
"user"
);
_sessionId
=
await
SharedpreferencesService
().
getString
(
"session"
);
print
(
"DATA111 :
${_empId}
"
);
print
(
"DATA111 :
${_sessionId}
"
);
try
{
final
result
=
await
ApiCalling
.
trackLiveLocationEmpolyeeAPI
(
_empId
!,
_sessionId
!,
location
,
);
if
(
result
!=
null
&&
result
.
error
==
"0"
)
{
FlutterForegroundTask
.
updateService
(
notificationTitle:
"GEN ERP"
,
notificationText:
"Location sent •
${DateTime.now().toString().substring(11, 19)}
"
,
);
}
else
{
FlutterForegroundTask
.
updateService
(
notificationText:
"Sync failed • Retrying..."
,
);
}
}
catch
(
e
)
{
FlutterForegroundTask
.
updateService
(
notificationText:
"No network • Retrying..."
,
);
}
// Save last sent time
final
time
=
DateTime
.
now
().
toString
().
substring
(
11
,
19
);
SharedpreferencesService
().
saveString
(
"lastLocationTime"
,
time
);
}
// This runs every 6 minutes (fallback when not moving)
@override
void
onRepeatEvent
(
DateTime
timestamp
)
{
_sendCurrentLocationOnce
();
}
@override
Future
<
void
>
onDestroy
(
DateTime
timestamp
,
bool
isTimeout
)
async
{
_stream
?.
cancel
();
}
}
// Main Service Controller
class
BackgroundLocationServiceNew
{
static
Future
<
void
>
init
()
async
{
FlutterForegroundTask
.
init
(
androidNotificationOptions:
AndroidNotificationOptions
(
channelId:
'gen_erp_location_channel'
,
channelName:
'GEN ERP Tracking'
,
channelDescription:
'Sends location every 6 minutes'
,
channelImportance:
NotificationChannelImportance
.
HIGH
,
priority:
NotificationPriority
.
HIGH
,
showBadge:
true
,
visibility:
NotificationVisibility
.
VISIBILITY_SECRET
),
iosNotificationOptions:
const
IOSNotificationOptions
(),
foregroundTaskOptions:
ForegroundTaskOptions
(
eventAction:
ForegroundTaskEventAction
.
repeat
(
360000
),
// Every 6 minutes
autoRunOnBoot:
false
,
// Prevents crash on boot
allowWakeLock:
true
,
allowWifiLock:
true
,
),
);
}
static
Future
<
bool
>
get
isRunning
=>
FlutterForegroundTask
.
isRunningService
;
static
Future
<
void
>
start
()
async
{
if
(
await
isRunning
)
{
await
FlutterForegroundTask
.
restartService
();
}
else
{
await
FlutterForegroundTask
.
startService
(
notificationTitle:
'GEN ERP'
,
notificationText:
'Starting location tracking...'
,
callback:
startCallback
,
);
}
}
static
Future
<
void
>
stop
()
async
{
await
FlutterForegroundTask
.
stopService
();
}
}
\ No newline at end of file
Prev
1
2
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