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
b35acfea
Commit
b35acfea
authored
Nov 28, 2025
by
Sai Srinivas
Browse files
local fix
parents
ebb11608
2a087139
Changes
65
Hide whitespace changes
Inline
Side-by-side
android/app/src/main/AndroidManifest.xml
View file @
b35acfea
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
>
<uses-feature
android:name=
"android.hardware.camera"
...
...
@@ -12,16 +14,18 @@
<uses-permission
android:name=
"android.permission.FOREGROUND_SERVICE"
/>
<uses-permission
android:name=
"android.permission.FOREGROUND_SERVICE_LOCATION"
/>
<uses-permission
android:name=
"android.permission.CAMERA"
/>
<uses-permission
android:name=
"android.permission.READ_MEDIA_IMAGES"
/>
<uses-permission
android:name=
"android.permission.READ_MEDIA_VIDEO"
/>
<uses-permission
android:name=
"android.permission.READ_MEDIA_AUDIO"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<uses-permission
android:name=
"android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"
/>
<uses-permission
android:name=
"com.google.android.gms.permission.AD_ID"
/>
<uses-permission
android:name=
"android.permission.POST_NOTIFICATIONS"
/>
<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"
/>
<uses-permission
tools:node=
"remove"
android:name=
"android.permission.READ_MEDIA_IMAGES"
/>
<uses-permission
tools:node=
"remove"
android:name=
"android.permission.READ_MEDIA_VIDEO"
/>
<uses-permission
tools:node=
"remove"
android:name=
"android.permission.READ_MEDIA_AUDIO"
/>
<uses-permission
tools:node=
"remove"
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<application
android:name=
"${applicationName}"
...
...
@@ -77,6 +81,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 @
b35acfea
<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 @
b35acfea
...
...
@@ -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,21 +42,20 @@ class Followuplist {
String
?
time
;
String
?
ename
;
Followuplist
({
this
.
id
,
this
.
empId
,
this
.
compId
,
this
.
inTime
,
this
.
outTime
,
this
.
feedback
,
this
.
type
,
this
.
date
,
this
.
fsrNo
,
this
.
fsrExt
,
this
.
runningHrs
,
this
.
time
,
this
.
ename
,
});
Followuplist
(
{
this
.
id
,
this
.
empId
,
this
.
compId
,
this
.
inTime
,
this
.
outTime
,
this
.
feedback
,
this
.
type
,
this
.
date
,
this
.
fsrNo
,
this
.
fsrExt
,
this
.
runningHrs
,
this
.
time
,
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 @
b35acfea
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 @
b35acfea
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/Models/financeModels/ValidateBankAccountDetailsResponse.dart
0 → 100644
View file @
b35acfea
class
ValidateBankAccountDetailsResponse
{
String
?
nameAtBank
;
String
?
bankName
;
String
?
branch
;
String
?
error
;
String
?
message
;
int
?
sessionExists
;
ValidateBankAccountDetailsResponse
(
{
this
.
nameAtBank
,
this
.
bankName
,
this
.
branch
,
this
.
error
,
this
.
message
,
this
.
sessionExists
});
ValidateBankAccountDetailsResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
nameAtBank
=
json
[
'name_at_bank'
];
bankName
=
json
[
'bank_name'
];
branch
=
json
[
'branch'
];
error
=
json
[
'error'
];
message
=
json
[
'message'
];
sessionExists
=
json
[
'session_exists'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
data
[
'name_at_bank'
]
=
this
.
nameAtBank
;
data
[
'bank_name'
]
=
this
.
bankName
;
data
[
'branch'
]
=
this
.
branch
;
data
[
'error'
]
=
this
.
error
;
data
[
'message'
]
=
this
.
message
;
data
[
'session_exists'
]
=
this
.
sessionExists
;
return
data
;
}
}
lib/Models/financeModels/ValidateGstNumResponse.dart
0 → 100644
View file @
b35acfea
class
ValidateGstNumResponse
{
String
?
legalNameOfBusiness
;
String
?
address
;
String
?
error
;
String
?
message
;
int
?
sessionExists
;
ValidateGstNumResponse
(
{
this
.
legalNameOfBusiness
,
this
.
address
,
this
.
error
,
this
.
message
,
this
.
sessionExists
});
ValidateGstNumResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
legalNameOfBusiness
=
json
[
'legal_name_of_business'
];
address
=
json
[
'address'
];
error
=
json
[
'error'
];
message
=
json
[
'message'
];
sessionExists
=
json
[
'session_exists'
];
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
new
Map
<
String
,
dynamic
>();
data
[
'legal_name_of_business'
]
=
this
.
legalNameOfBusiness
;
data
[
'address'
]
=
this
.
address
;
data
[
'error'
]
=
this
.
error
;
data
[
'message'
]
=
this
.
message
;
data
[
'session_exists'
]
=
this
.
sessionExists
;
return
data
;
}
}
lib/Models/ordersModels/commonResponse.dart
View file @
b35acfea
class
CommonResponse
{
String
?
error
;
String
?
message
;
String
?
qrCode
;
String
?
qrId
;
int
?
sessionExists
;
CommonResponse
({
this
.
error
,
this
.
message
,
this
.
sessionExists
});
CommonResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
error
=
json
[
'error'
];
qrCode
=
json
[
'qr_code'
];
qrId
=
json
[
'razorpay_order_id'
];
message
=
json
[
'message'
];
sessionExists
=
json
[
'session_exists'
];
}
...
...
@@ -15,6 +18,8 @@ class CommonResponse {
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
<
String
,
dynamic
>{};
data
[
'error'
]
=
error
;
data
[
'qr_code'
]
=
qrCode
;
data
[
'razorpay_order_id'
]
=
qrId
;
data
[
'message'
]
=
message
;
data
[
'session_exists'
]
=
sessionExists
;
return
data
;
...
...
lib/Notifiers/CheckInProvider.dart
View file @
b35acfea
...
...
@@ -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 @
b35acfea
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 @
b35acfea
...
...
@@ -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/PaymentDetailsProvider.dart
View file @
b35acfea
...
...
@@ -208,6 +208,7 @@ class Paymentdetailsprovider extends ChangeNotifier {
_imageName
=
null
;
_image_picked
=
0
;
resetErrors
();
notifyListeners
();
}
else
{}
}
else
{
...
...
@@ -775,6 +776,22 @@ class Paymentdetailsprovider extends ChangeNotifier {
}
}
void
resetErrors
()
{
nameError
=
null
;
designationError
=
null
;
mobError
=
null
;
altMobError
=
null
;
telError
=
null
;
emailError
=
null
;
selectContactError
=
null
;
selectPaymentError
=
null
;
selectAmountError
=
null
;
ReferenceError
=
null
;
imageError
=
null
;
notifyListeners
();
}
resetAddContect
()
{
Amountcontroller
.
clear
();
Referencecontroller
.
clear
();
...
...
lib/Notifiers/PendingComplaintsProvider.dart
View file @
b35acfea
...
...
@@ -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
0 → 100644
View file @
b35acfea
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
;
String
?
_errorMessage
;
int
_secondsLeft
=
120
;
// 2 minutes
CommonResponse
?
get
qrResponse
=>
_qrResponse
;
bool
get
isLoading
=>
_isLoading
;
String
?
get
errorMessage
=>
_errorMessage
;
int
get
secondsLeft
=>
_secondsLeft
;
Timer
?
_timer
;
Future
<
void
>
fetchRazorpayQr
({
required
String
sessionId
,
required
String
empId
,
required
String
amount
,
required
String
refType
,
required
String
refId
,
})
async
{
_isLoading
=
true
;
_errorMessage
=
null
;
notifyListeners
();
try
{
final
response
=
await
ApiCalling
.
fetchRazorpayUpiQrApi
(
sessionId
,
empId
,
amount
,
refType
,
refId
,
);
if
(
response
!=
null
&&
response
.
error
==
"0"
)
{
_qrResponse
=
response
;
_startTimer
();
}
else
{
_errorMessage
=
response
?.
message
??
"Something went wrong"
;
}
}
catch
(
e
)
{
_errorMessage
=
e
.
toString
();
}
finally
{
_isLoading
=
false
;
notifyListeners
();
}
}
void
_startTimer
()
{
_secondsLeft
=
120
;
_timer
?.
cancel
();
_timer
=
Timer
.
periodic
(
const
Duration
(
seconds:
1
),
(
timer
)
{
if
(
_secondsLeft
>
0
)
{
_secondsLeft
--;
notifyListeners
();
}
else
{
timer
.
cancel
();
}
});
}
@override
void
dispose
()
{
_timer
?.
cancel
();
super
.
dispose
();
}
bool
_isPaymentUpdating
=
false
;
bool
get
isPaymentUpdating
=>
_isPaymentUpdating
;
set
isPaymentUpdating
(
bool
value
)
{
_isPaymentUpdating
=
value
;
notifyListeners
();
}
/// 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
,
required
String
empId
,
required
String
razorpayOrderId
,
})
async
{
try
{
isPaymentUpdating
=
true
;
final
response
=
await
ApiCalling
.
fetchRazorpayUpiQrStatusApi
(
sessionId
,
empId
,
razorpayOrderId
,
);
if
(
response
!=
null
)
{
if
(
response
.
sessionExists
==
1
&&
response
.
error
==
"0"
)
{
debugPrint
(
"Payment Status:
${response.message}
"
);
}
else
{
// 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"
);
}
return
response
;
}
catch
(
e
)
{
debugPrint
(
"fetchRazorpayUpiQrStatus error:
$e
"
);
return
null
;
}
finally
{
isPaymentUpdating
=
false
;
}
}
}
lib/Notifiers/VisitDetailsProvider.dart
View file @
b35acfea
...
...
@@ -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
0 → 100644
View file @
b35acfea
//
//
// 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 @
b35acfea
...
...
@@ -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 @
b35acfea
// accountsListProvider.dart
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'
;
...
...
@@ -12,6 +15,8 @@ import '../../Models/commonModels/DistrictsResponse.dart';
import
'../../Models/commonModels/SubLocationsResponse.dart'
;
import
'../../Models/commonModels/commonAccountlistResponse.dart'
;
import
'../../Models/commonModels/commonAddAccountsViewResponse.dart'
;
import
'../../Models/financeModels/ValidateBankAccountDetailsResponse.dart'
;
import
'../../Models/financeModels/ValidateGstNumResponse.dart'
;
class
Accountslistprovider
extends
ChangeNotifier
{
TextEditingController
nameController
=
TextEditingController
();
...
...
@@ -21,11 +26,11 @@ class Accountslistprovider extends ChangeNotifier {
TextEditingController
branchNameController
=
TextEditingController
();
TextEditingController
bankIfscCotroller
=
TextEditingController
();
TextEditingController
bankHolderNameController
=
TextEditingController
();
TextEditingController
gstNumberController
=
TextEditingController
();
TextEditingController
bankAcNumberController
=
TextEditingController
();
TextEditingController
bankUpiController
=
TextEditingController
();
TextEditingController
contactPersonController
=
TextEditingController
();
TextEditingController
contectPersonDesignationController
=
TextEditingController
();
TextEditingController
contectPersonDesignationController
=
TextEditingController
();
TextEditingController
contectPersonAltMobController
=
TextEditingController
();
TextEditingController
contectPersonTeleController
=
TextEditingController
();
TextEditingController
contectPersonMailController
=
TextEditingController
();
...
...
@@ -43,6 +48,7 @@ class Accountslistprovider extends ChangeNotifier {
String
?
districtError
;
String
?
localityError
;
String
?
addressError
;
String
?
gstNumberError
;
String
?
banknameError
;
String
?
bankBranchError
;
String
?
bankIFSCError
;
...
...
@@ -98,6 +104,12 @@ class Accountslistprovider extends ChangeNotifier {
notifyListeners
();
}
ValidateGstNumResponse
?
gstResponse
;
commonAddAccountsViewResponse
?
commonResponse
;
ValidateBankAccountDetailsResponse
?
bankResponse
;
String
?
errorMessage
;
States
?
_selectedState
;
Districts
?
_selectedDistricts
;
SubLocations
?
_selectedSubLocations
;
...
...
@@ -132,6 +144,12 @@ class Accountslistprovider extends ChangeNotifier {
String
?
get
selectedAccountType
=>
_selectedAccountType
;
// --- NEW: setter for isLoading so callers can do `isLoading = true;` ---
set
isLoading
(
bool
value
)
{
_isLoading
=
value
;
notifyListeners
();
}
set
selectedAccountType
(
String
?
value
)
{
_selectedAccountType
=
value
;
accountError
=
null
;
...
...
@@ -140,24 +158,24 @@ class Accountslistprovider extends ChangeNotifier {
set
selectedState
(
States
?
value
)
{
_selectedState
=
value
;
_selectedStateID
=
value
!
.
id
;
_selectedStateValue
=
value
.
name
;
_selectedStateID
=
value
?
.
id
;
_selectedStateValue
=
value
?
.
name
;
stateError
=
null
;
notifyListeners
();
}
set
selectedDistricts
(
Districts
?
value
)
{
_selectedDistricts
=
value
;
_selectedDistrictID
=
value
!
.
id
;
_selectedDistrictValue
=
value
.
district
;
_selectedDistrictID
=
value
?
.
id
;
_selectedDistrictValue
=
value
?
.
district
;
districtError
=
null
;
notifyListeners
();
}
set
selectedSubLocations
(
SubLocations
?
value
)
{
_selectedSubLocations
=
value
;
_selectedSubLocID
=
value
!
.
id
;
_selectedSubLocValue
=
value
.
subLocality
!
;
_selectedSubLocID
=
value
?
.
id
;
_selectedSubLocValue
=
value
?
.
subLocality
;
localityError
=
null
;
notifyListeners
();
}
...
...
@@ -192,6 +210,8 @@ class Accountslistprovider extends ChangeNotifier {
notifyListeners
();
}
// ---------- API / data loading ----------
Future
<
void
>
addCommonAccountViewAPI
(
context
)
async
{
try
{
var
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
...
...
@@ -205,12 +225,15 @@ class Accountslistprovider extends ChangeNotifier {
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
ChechkDropdownValues
();
_accountTypes
=
data
.
accountTypes
!
;
_states
=
data
.
states
!
;
_accountTypes
=
data
.
accountTypes
??
[]
;
_states
=
data
.
states
??
[]
;
notifyListeners
();
}
}
}
catch
(
e
)
{}
}
catch
(
e
)
{
// keep quiet but log in debug
if
(
kDebugMode
)
debugPrint
(
'addCommonAccountViewAPI error:
$e
'
);
}
}
Future
<
void
>
getDistrictAPI
(
context
,
stateID
)
async
{
...
...
@@ -225,11 +248,13 @@ class Accountslistprovider extends ChangeNotifier {
);
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
_districts
=
data
.
districts
!
;
_districts
=
data
.
districts
??
[]
;
notifyListeners
();
}
}
}
catch
(
e
)
{}
}
catch
(
e
)
{
if
(
kDebugMode
)
debugPrint
(
'getDistrictAPI error:
$e
'
);
}
}
Future
<
void
>
getSubLocationAPI
(
context
,
districtID
)
async
{
...
...
@@ -244,11 +269,13 @@ class Accountslistprovider extends ChangeNotifier {
);
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
_subLocations
=
data
.
subLocations
!
;
_subLocations
=
data
.
subLocations
??
[]
;
notifyListeners
();
}
}
}
catch
(
e
)
{}
}
catch
(
e
)
{
if
(
kDebugMode
)
debugPrint
(
'getSubLocationAPI error:
$e
'
);
}
}
Future
<
void
>
checkInputsAPI
(
context
,
type
,
value
)
async
{
...
...
@@ -260,6 +287,7 @@ class Accountslistprovider extends ChangeNotifier {
type
,
value
,
);
commonResponse
=
data
;
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
nameError
=
null
;
...
...
@@ -272,12 +300,310 @@ class Accountslistprovider extends ChangeNotifier {
mobileError
=
data
.
message
??
""
;
}
notifyListeners
();
// toast(context, data.message);
}
}
}
catch
(
e
)
{}
}
catch
(
e
)
{
if
(
kDebugMode
)
debugPrint
(
'checkInputsAPI error:
$e
'
);
}
}
/// Validate GST Number
/// Returns true if validated successfully (and sets gstResponse). Caller can await.
Future
<
bool
>
validateGstNumber
(
String
empId
,
String
sessionId
,
String
gstNumber
)
async
{
// if empty — don't call API; clear any previous errors/responses
if
(
gstNumber
.
trim
().
isEmpty
)
{
gstResponse
=
null
;
gstNumberError
=
null
;
notifyListeners
();
return
false
;
}
try
{
isLoading
=
true
;
errorMessage
=
null
;
// call API
final
response
=
await
ApiCalling
.
validateGstNumberApi
(
empId
,
sessionId
,
gstNumber
,
);
// assign
gstResponse
=
response
;
if
(
response
==
null
)
{
gstNumberError
=
"Failed to validate GST number"
;
notifyListeners
();
return
false
;
}
// Response object expected to contain `error` and `address` and `legal_name_of_business`
if
(
response
.
error
==
"0"
)
{
gstNumberError
=
null
;
// Optionally update address or other fields in UI (UI will read gstResponse)
notifyListeners
();
return
true
;
}
else
{
// API returned invalid GST
gstNumberError
=
response
.
message
??
"Invalid GST number"
;
notifyListeners
();
return
false
;
}
}
catch
(
e
)
{
gstNumberError
=
"Error validating GST:
${e.toString()}
"
;
if
(
kDebugMode
)
debugPrint
(
'validateGstNumber error:
$e
'
);
notifyListeners
();
return
false
;
}
finally
{
isLoading
=
false
;
notifyListeners
();
}
}
/// Validate Bank Account Details
/// Returns true if validated successfully (and sets bankResponse). Caller can await.
Future
<
bool
>
validateBankDetails
(
String
empId
,
String
sessionId
,
String
accountNumber
)
async
{
// require accountNumber and IFSC to be present
final
ifsc
=
bankIfscCotroller
.
text
.
trim
();
if
(
accountNumber
.
trim
().
isEmpty
||
ifsc
.
isEmpty
)
{
// clear previous bankResponse if user cleared input
bankResponse
=
null
;
bankAcNumberError
=
null
;
bankIFSCError
=
null
;
notifyListeners
();
return
false
;
}
// basic IFSC format check (caller/UI also checks) — we trust UI but double-check
final
reg
=
RegExp
(
r'^[A-Za-z]{4}0[A-Za-z0-9]{6}$'
);
if
(!
reg
.
hasMatch
(
ifsc
))
{
bankIFSCError
=
"Invalid IFSC format"
;
notifyListeners
();
return
false
;
}
try
{
isLoading
=
true
;
errorMessage
=
null
;
// call API - pass account number and IFSC from controller (some APIs require both)
final
response
=
await
ApiCalling
.
validateBankAccountDetailsApi
(
empId
,
sessionId
,
accountNumber
,
ifsc
,
);
bankResponse
=
response
;
if
(
response
==
null
)
{
bankAcNumberError
=
"Failed to validate bank account"
;
notifyListeners
();
return
false
;
}
if
(
response
.
error
==
"0"
)
{
// success — populate fields in UI from the provider.bankResponse (UI will take the values)
bankAcNumberError
=
null
;
bankIFSCError
=
null
;
banknameError
=
null
;
bankBranchError
=
null
;
bankHolderNameError
=
null
;
notifyListeners
();
return
true
;
}
else
{
// error returned
bankAcNumberError
=
response
.
message
??
"Invalid account details"
;
notifyListeners
();
return
false
;
}
}
catch
(
e
)
{
bankAcNumberError
=
"Error validating account:
${e.toString()}
"
;
if
(
kDebugMode
)
debugPrint
(
'validateBankDetails error:
$e
'
);
notifyListeners
();
return
false
;
}
finally
{
isLoading
=
false
;
notifyListeners
();
}
}
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
;
...
...
@@ -292,7 +618,6 @@ class Accountslistprovider extends ChangeNotifier {
Future
<
void
>
submitCommonAccountsAPI
(
context
,
from
)
async
{
try
{
if
(!
validatereceiptForm
(
context
))
{
// _submitClicked = false;
return
;
}
_submitClicked
=
true
;
...
...
@@ -327,14 +652,12 @@ class Accountslistprovider extends ChangeNotifier {
if
(
from
==
"Requesition"
)
{
Navigator
.
pop
(
context
,
res
);
}
else
if
(
from
==
"Dashboard"
)
{
print
(
"here"
);
Navigator
.
pushAndRemoveUntil
(
context
,
MaterialPageRoute
(
builder:
(
context
)
=>
Accountslistdetails
(
accountID:
data
.
id
),
),
(
Route
<
dynamic
>
route
)
{
(
Route
<
dynamic
>
route
)
{
return
route
.
settings
.
arguments
==
'Financedashboard'
;
},
);
...
...
@@ -360,7 +683,7 @@ class Accountslistprovider extends ChangeNotifier {
}
}
bool
validateStep1
()
{
bool
validateStep1
(
BuildContext
context
)
{
accountError
=
null
;
nameError
=
null
;
mobileError
=
null
;
...
...
@@ -374,11 +697,53 @@ class Accountslistprovider extends ChangeNotifier {
nameError
=
"Please Enter a Name"
;
isValid
=
false
;
}
if
(
mobileController
.
text
.
trim
().
isNotEmpty
&&
mobileController
.
text
.
length
<
10
)
{
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
;
...
...
@@ -392,109 +757,67 @@ class Accountslistprovider extends ChangeNotifier {
return
isValid
;
}
bool
validateStep2
()
{
stateError
=
null
;
districtError
=
null
;
localityError
=
null
;
addressError
=
null
;
bool
isValid
=
true
;
// if (_selectedState == null || _selectedStateID!.isEmpty) {
// stateError = "Please select a State";
// isValid = false;
// }
// if (_selectedDistricts == null || _selectedDistrictID!.isEmpty) {
// districtError = "Please select a District";
// isValid = false;
// }
// if (_selectedSubLocations == null || _selectedSubLocID!.isEmpty) {
// localityError = "Please select a Locality";
// isValid = false;
// }
// if (addressController.text.trim().isEmpty) {
// addressError = "Please Enter an Address";
// isValid = false;
// }
// optional step — you commented it optional. Keep commented validations deactivated.
_submitClicked
=
false
;
notifyListeners
();
return
isValid
;
}
bool
validateStep3
()
{
bool
validateStep3
(
BuildContext
context
)
{
banknameError
=
null
;
bankBranchError
=
null
;
bankIFSCError
=
null
;
bankHolderNameError
=
null
;
bankAcNumberError
=
null
;
upiError
=
null
;
gstNumberError
=
null
;
bool
isValid
=
true
;
// if (bankNameController.text
// .trim()
// .isEmpty) {
// banknameError = "Please Enter a Bank Name";
// isValid = false;
// }
//
// if (branchNameController.text
// .trim()
// .isEmpty) {
// bankBranchError = "Please Enter Branch Name";
// isValid = false;
// }
// if (bankIfscCotroller.text
// .trim()
// .isEmpty) {
// bankIFSCError = "Please Enter Bank IFSC";
// isValid = false;
// }
// if (bankHolderNameController.text
// .trim()
// .isEmpty) {
// bankHolderNameError = "Please Enter Account Holder Name";
// isValid = false;
// }
// if (bankAcNumberController.text
// .trim()
// .isEmpty) {
// bankAcNumberError = "Please Enter Bank Account Number";
// isValid = false;
// }
// if (bankUpiController.text
// .trim()
// .isEmpty) {
// upiError = "Please Enter UPI ID";
// isValid = false;
// }
_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
;
}
bool
validateStep4
()
{
bool
isValid
=
true
;
// if (contectPersonDesignationController.text
// .trim()
// .isEmpty) {
// desigantionError = "Please Enter Designation";
// isValid = false;
// }
// if (contectPersonAltMobController.text
// .trim()
// .isEmpty) {
// altMobError = "Please Enter Mobile Number";
// isValid = false;
// }
//
// }
// if (contectPersonTeleController.text.trim().isEmpty) {
// teleError= "Please Enter Telephone"; isValid = false;
// }
// if (contectPersonMailController.text.trim().isEmpty) {
// teleError= "Please Enter"; isValid = false;
// }
_submitClicked
=
false
;
notifyListeners
();
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
;
}
...
...
@@ -507,6 +830,7 @@ class Accountslistprovider extends ChangeNotifier {
localityError
=
null
;
addressError
=
null
;
banknameError
=
null
;
gstNumberError
=
null
;
bankBranchError
=
null
;
bankIFSCError
=
null
;
bankHolderNameError
=
null
;
...
...
@@ -535,94 +859,32 @@ class Accountslistprovider extends ChangeNotifier {
contactPersonError
=
"Please Enter Contact Person Name"
;
isValid
=
false
;
}
//
//
// if (!_isVisible && !hasFilledAdditionalDetails) {
// addMoreDetailsError = "Please Add More Details to Continue";
// isValid = false;
// }
// if(_isVisible) {
//
// if (_selectedState == null || _selectedStateID!.isEmpty) {
// stateError = "Please select a State";
// isValid = false;
// }
// if (_selectedDistricts == null || _selectedDistrictID!.isEmpty) {
// districtError = "Please select a District";
// isValid = false;
// }
// if (_selectedSubLocations == null || _selectedSubLocID!.isEmpty) {
// localityError = "Please select a Locality";
// isValid = false;
// }
// if (addressController.text.trim().isEmpty) {
// addressError = "Please Enter an Address";
// isValid = false;
// }
// if (bankNameController.text
// .trim()
// .isEmpty) {
// banknameError = "Please Enter a Bank Name";
// isValid = false;
// }
//
// if (branchNameController.text
// .trim()
// .isEmpty) {
// bankBranchError = "Please Enter Branch Name";
// isValid = false;
// }
// if (bankIfscCotroller.text
// .trim()
// .isEmpty) {
// bankIFSCError = "Please Enter Bank IFSC";
// isValid = false;
// }
// if (bankHolderNameController.text
// .trim()
// .isEmpty) {
// bankHolderNameError = "Please Enter Account Holder Name";
// isValid = false;
// }
// if (bankAcNumberController.text
// .trim()
// .isEmpty) {
// bankAcNumberError = "Please Enter Bank Account Number";
// isValid = false;
// }
// if (bankUpiController.text
// .trim()
// .isEmpty) {
// upiError = "Please Enter UPI ID";
// isValid = false;
// }
// if (contactPersonController.text
// .trim()
// .isEmpty) {
// contactPersonError = "Please Enter Contact Person Name";
// isValid = false;
// }
// if (contectPersonDesignationController.text
// .trim()
// .isEmpty) {
// desigantionError = "Please Enter Designation";
// isValid = false;
// }
// if (contectPersonAltMobController.text
// .trim()
// .isEmpty) {
// altMobError = "Please Enter Mobile Number";
// isValid = false;
// }
//
// }
// if (contectPersonTeleController.text.trim().isEmpty) {
// teleError= "Please Enter Telephone"; isValid = false;
// }
// if (contectPersonMailController.text.trim().isEmpty) {
// teleError= "Please Enter"; 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
;
...
...
@@ -645,67 +907,64 @@ class Accountslistprovider extends ChangeNotifier {
void
updateBankName
(
String
value
)
{
banknameError
=
null
;
notifyListeners
();
}
/// simplified update - kept for compatibility if UI uses it
void
updateGSTNumber
(
String
value
)
{
// just clear the error when user edits GST
gstNumberError
=
null
;
notifyListeners
();
}
void
updateBankBranch
(
String
value
)
{
bankBranchError
=
null
;
notifyListeners
();
}
void
updateIFSC
(
String
value
)
{
bankIFSCError
=
null
;
notifyListeners
();
}
void
updateHolder
(
String
value
)
{
bankHolderNameError
=
null
;
notifyListeners
();
}
void
updateNumber
(
String
value
)
{
bankAcNumberError
=
null
;
notifyListeners
();
}
void
updateUPI
(
String
value
)
{
upiError
=
null
;
notifyListeners
();
}
void
updateContactPerson
(
String
value
)
{
contactPersonError
=
null
;
notifyListeners
();
}
void
updateDesignation
(
String
value
)
{
desigantionError
=
null
;
notifyListeners
();
}
void
updateAltMobile
(
String
value
)
{
altMobError
=
null
;
notifyListeners
();
}
void
updateTeleMobile
(
String
value
)
{
teleError
=
null
;
notifyListeners
();
}
void
updateMail
(
String
value
)
{
mailError
=
null
;
notifyListeners
();
}
...
...
@@ -717,14 +976,11 @@ class Accountslistprovider extends ChangeNotifier {
notifyListeners
();
}
String
?
_errorMessage
;
String
?
get
errorMessage
=>
_errorMessage
;
// Common Account list provider
Future
<
void
>
commonAccountListAPIFunction
(
BuildContext
context
,
{
bool
append
=
false
,
})
async
{
BuildContext
context
,
{
bool
append
=
false
,
})
async
{
try
{
var
prov
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
...
...
@@ -747,19 +1003,13 @@ class Accountslistprovider extends ChangeNotifier {
companyNameController
.
text
,
mobileNumberController
.
text
,
);
debugPrint
(
'empId:
${prov.empId}
, session:
${prov.session}
, pageNumber:
$_pageNum
'
,
);
debugPrint
(
'empId:
${prov.empId}
, session:
${prov.session}
, pageNumber:
$_pageNum
'
);
if
(
data
!=
null
&&
data
.
error
==
"0"
)
{
if
(
data
.
accountList
!=
null
)
{
if
(
append
)
{
// Append with deduplication
final
existingIds
=
_accountsList
.
map
((
e
)
=>
e
.
id
).
toSet
();
final
newItems
=
data
.
accountList
!
.
where
((
item
)
=>
!
existingIds
.
contains
(
item
.
id
))
.
toList
();
final
newItems
=
data
.
accountList
!.
where
((
item
)
=>
!
existingIds
.
contains
(
item
.
id
)).
toList
();
_accountsList
.
addAll
(
newItems
);
}
else
{
_accountsList
=
data
.
accountList
!;
...
...
@@ -779,7 +1029,7 @@ class Accountslistprovider extends ChangeNotifier {
}
resetValues
()
{
p
rint
(
"rv"
);
if
(
kDebugMode
)
debugP
rint
(
"rv"
);
_selectedAccountType
=
null
;
_selectedState
=
null
;
_selectedDistricts
=
null
;
...
...
@@ -791,6 +1041,10 @@ class Accountslistprovider extends ChangeNotifier {
_selectedSubLocID
=
null
;
_selectedSubLocValue
=
null
;
gstResponse
=
null
;
bankResponse
=
null
;
errorMessage
=
null
;
_isVisible
=
false
;
stateSearchController
.
clear
();
districtSearchController
.
clear
();
...
...
@@ -819,6 +1073,7 @@ class Accountslistprovider extends ChangeNotifier {
localityError
=
null
;
addressError
=
null
;
banknameError
=
null
;
gstNumberError
=
null
;
bankBranchError
=
null
;
bankIFSCError
=
null
;
bankHolderNameError
=
null
;
...
...
@@ -836,21 +1091,18 @@ class Accountslistprovider extends ChangeNotifier {
}
void
ChechkDropdownValues
()
{
if
(!
_accountTypes
.
contains
(
_selectedAccountType
)
&&
_selectedAccountType
!=
null
)
{
if
(!
_accountTypes
.
contains
(
_selectedAccountType
)
&&
_selectedAccountType
!=
null
)
{
_selectedAccountType
=
null
;
}
if
(!
_states
.
contains
(
_selectedState
)
&&
_selectedState
!=
null
)
{
_selectedStateID
=
null
;
_selectedStateValue
=
null
;
}
if
(!
_districts
.
contains
(
_selectedDistricts
)
&&
_selectedDistricts
!=
null
)
{
if
(!
_districts
.
contains
(
_selectedDistricts
)
&&
_selectedDistricts
!=
null
)
{
_selectedDistrictID
=
null
;
_selectedDistrictValue
=
null
;
}
if
(!
_subLocations
.
contains
(
_selectedSubLocations
)
&&
_selectedSubLocations
!=
null
)
{
if
(!
_subLocations
.
contains
(
_selectedSubLocations
)
&&
_selectedSubLocations
!=
null
)
{
_selectedSubLocID
=
null
;
_selectedSubLocValue
=
null
;
}
...
...
lib/Notifiers/commonProvider/editCommonAccountProvider.dart
0 → 100644
View file @
b35acfea
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:generp/Notifiers/HomeScreenNotifier.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'package:generp/Utils/commonServices.dart'
;
import
'package:provider/provider.dart'
;
import
'../../Models/commonModels/DistrictsResponse.dart'
;
import
'../../Models/commonModels/EditCommonAccFormDetailsResponse.dart'
;
import
'../../Models/commonModels/SubLocationsResponse.dart'
;
import
'../../Models/financeModels/ValidateBankAccountDetailsResponse.dart'
;
import
'../../Models/financeModels/ValidateGstNumResponse.dart'
;
import
'../../Models/commonModels/commonAddAccountsViewResponse.dart'
;
class
EditCommonAccountProvider
extends
ChangeNotifier
{
// --- Text controllers used by edit form (only required ones) ---
final
TextEditingController
nameController
=
TextEditingController
();
final
TextEditingController
mobileController
=
TextEditingController
();
final
TextEditingController
addressController
=
TextEditingController
();
final
TextEditingController
bankNameController
=
TextEditingController
();
final
TextEditingController
branchNameController
=
TextEditingController
();
final
TextEditingController
bankIfscCotroller
=
TextEditingController
();
final
TextEditingController
bankHolderNameController
=
TextEditingController
();
final
TextEditingController
gstNumberController
=
TextEditingController
();
final
TextEditingController
bankAcNumberController
=
TextEditingController
();
final
TextEditingController
bankUpiController
=
TextEditingController
();
// contact person details (kept because your form uses them)
final
TextEditingController
contactPersonController
=
TextEditingController
();
// final TextEditingController contectPersonDesignationController = TextEditingController();
// final TextEditingController contectPersonAltMobController = TextEditingController();
// final TextEditingController contectPersonTeleController = TextEditingController();
final
TextEditingController
contectPersonMailController
=
TextEditingController
();
// small search controllers for dropdown search widgets
final
TextEditingController
stateSearchController
=
TextEditingController
();
final
TextEditingController
districtSearchController
=
TextEditingController
();
final
TextEditingController
subLocSearchController
=
TextEditingController
();
// --- simple error strings for UI ---
String
?
accountError
;
String
?
nameError
;
String
?
mobileError
;
String
?
stateError
;
String
?
districtError
;
String
?
localityError
;
String
?
addressError
;
String
?
gstNumberError
;
String
?
banknameError
;
String
?
bankBranchError
;
String
?
bankIFSCError
;
String
?
bankHolderNameError
;
String
?
bankAcNumberError
;
String
?
upiError
;
String
?
contactPersonError
;
String
?
desigantionError
;
String
?
altMobError
;
String
?
teleError
;
String
?
mailError
;
String
?
addMoreDetailsError
;
// --- dropdown lists (populated from addCommonAccountView API) ---
List
<
String
>
_accountTypes
=
[];
List
<
States
>
_states
=
[];
List
<
Districts
>
_districts
=
[];
List
<
SubLocations
>
_subLocations
=
[];
// selection holders
String
?
_selectedAccountType
;
States
?
_selectedState
;
Districts
?
_selectedDistricts
;
SubLocations
?
_selectedSubLocations
;
// IDs / values (strings) used when sending API
String
?
_selectedStateID
;
String
?
_selectedDistrictID
;
String
?
_selectedSubLocID
;
// responses from validation APIs
ValidateGstNumResponse
?
gstResponse
;
ValidateBankAccountDetailsResponse
?
bankResponse
;
commonAddAccountsViewResponse
?
commonResponse
;
// loading & submit state
bool
_isLoading
=
false
;
bool
_isSubmitting
=
false
;
String
?
updateErrorMessage
;
// getters
bool
get
isLoading
=>
_isLoading
;
bool
get
isSubmitting
=>
_isSubmitting
;
List
<
States
>
get
states
=>
_states
;
List
<
Districts
>
get
districts
=>
_districts
;
List
<
SubLocations
>
get
subLocations
=>
_subLocations
;
String
?
get
selectedAccountType
=>
_selectedAccountType
;
States
?
get
selectedState
=>
_selectedState
;
Districts
?
get
selectedDistricts
=>
_selectedDistricts
;
SubLocations
?
get
selectedSubLocations
=>
_selectedSubLocations
;
String
?
get
selectedStateID
=>
_selectedStateID
;
String
?
get
selectedDistrictId
=>
_selectedDistrictID
;
String
?
get
selectedSubLocID
=>
_selectedSubLocID
;
bool
_submitClicked
=
false
;
bool
get
submitClickced
=>
_submitClicked
;
set
submitClickced
(
bool
value
)
{
_submitClicked
=
value
;
notifyListeners
();
}
// --- setters that clear corresponding errors and notify ---
set
selectedAccountType
(
String
?
v
)
{
_selectedAccountType
=
v
;
accountError
=
null
;
notifyListeners
();
}
set
selectedState
(
States
?
v
)
{
_selectedState
=
v
;
_selectedStateID
=
v
?.
id
;
stateError
=
null
;
// clear dependent district/subLocation when state changes
_districts
.
clear
();
_selectedDistricts
=
null
;
_selectedDistrictID
=
null
;
_subLocations
.
clear
();
_selectedSubLocations
=
null
;
_selectedSubLocID
=
null
;
notifyListeners
();
}
set
selectedDistricts
(
Districts
?
v
)
{
_selectedDistricts
=
v
;
_selectedDistrictID
=
v
?.
id
;
districtError
=
null
;
_subLocations
.
clear
();
_selectedSubLocations
=
null
;
_selectedSubLocID
=
null
;
notifyListeners
();
}
set
selectedSubLocations
(
SubLocations
?
v
)
{
_selectedSubLocations
=
v
;
_selectedSubLocID
=
v
?.
id
;
localityError
=
null
;
notifyListeners
();
}
set
isLoading
(
bool
v
)
{
_isLoading
=
v
;
notifyListeners
();
}
EditCommonAccFormDetailsResponse
?
detailsListResponse
;
// LOAD ACCOUNT DETAILS + PREFILL ALL FIELDS
// ==========================================================
Future
<
bool
>
loadAccountDetailsForEdit
(
BuildContext
context
,
String
accountId
,
)
async
{
try
{
isLoading
=
true
;
notifyListeners
();
final
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
commonAccountDetailsListAPI
(
homeProv
.
empId
,
homeProv
.
session
,
accountId
,
);
detailsListResponse
=
data
;
if
(
data
==
null
||
data
.
error
!=
"0"
)
{
updateErrorMessage
=
data
?.
message
??
"Failed to load account details"
;
isLoading
=
false
;
notifyListeners
();
return
false
;
}
// Expecting at least one account in the list; take the first.
if
(
data
.
accountList
==
null
||
data
.
accountList
!.
isEmpty
)
{
updateErrorMessage
=
"No account data returned"
;
isLoading
=
false
;
notifyListeners
();
return
false
;
}
final
acc
=
data
.
accountList
!.
first
;
// 1) PREFILL TEXT CONTROLLERS
// ---------------------------
nameController
.
text
=
acc
.
name
??
""
;
mobileController
.
text
=
acc
.
mob1
??
""
;
addressController
.
text
=
acc
.
address
??
""
;
bankNameController
.
text
=
acc
.
bankName
??
""
;
branchNameController
.
text
=
acc
.
bankBranchName
??
""
;
bankIfscCotroller
.
text
=
acc
.
bankIfscCode
??
""
;
bankHolderNameController
.
text
=
acc
.
bankAccountHolderName
??
""
;
bankAcNumberController
.
text
=
acc
.
bankAccountNumber
??
""
;
bankUpiController
.
text
=
acc
.
bankUpiId
??
""
;
gstNumberController
.
text
=
acc
.
gstNumber
??
""
;
// contact person (if API has contact_name)
contactPersonController
.
text
=
acc
.
contactName
??
""
;
// Other contact fields in API aren't present — keep empty or preserve existing
contectPersonMailController
.
text
=
acc
.
email
??
""
;
// ---------------------------
// 2) PREFILL ACCOUNT TYPE
// ---------------------------
selectedAccountType
=
acc
.
type
;
// ---------------------------
// 3) LOAD DROPDOWNS (account types, states)
// ---------------------------
await
addCommonAccountViewAPI
(
context
);
// ---------------------------
// 4) SELECT STATE (by name)
// ---------------------------
if
(
acc
.
state
!=
null
&&
acc
.
state
!.
trim
().
isNotEmpty
)
{
final
matchState
=
_states
.
firstWhere
(
(
s
)
=>
(
s
.
name
??
""
).
toLowerCase
()
==
acc
.
state
!.
trim
().
toLowerCase
(),
orElse:
()
=>
States
(
id:
null
,
name:
null
),
);
if
(
matchState
.
id
!=
null
)
{
// use setter so it clears errors and resets dependent lists
selectedState
=
matchState
;
_selectedStateID
=
matchState
.
id
;
// load districts for this state
await
getDistrictAPI
(
context
,
matchState
.
id
);
}
}
// ---------------------------
// 5) SELECT DISTRICT (by name)
// ---------------------------
if
(
acc
.
district
!=
null
&&
acc
.
district
!.
trim
().
isNotEmpty
&&
_districts
.
isNotEmpty
)
{
final
matchDist
=
_districts
.
firstWhere
(
(
d
)
=>
(
d
.
district
??
""
).
toLowerCase
()
==
acc
.
district
!.
trim
().
toLowerCase
(),
orElse:
()
=>
Districts
(
id:
null
,
district:
null
),
);
if
(
matchDist
.
id
!=
null
)
{
selectedDistricts
=
matchDist
;
_selectedDistrictID
=
matchDist
.
id
;
// load sub-localities for this district
await
getSubLocationAPI
(
context
,
matchDist
.
id
);
}
}
// ---------------------------
// 6) SELECT SUB-LOCALITY (by name)
// ---------------------------
if
(
acc
.
subLocality
!=
null
&&
acc
.
subLocality
!.
trim
().
isNotEmpty
&&
_subLocations
.
isNotEmpty
)
{
final
matchSub
=
_subLocations
.
firstWhere
(
(
s
)
=>
(
s
.
subLocality
??
""
).
toLowerCase
()
==
acc
.
subLocality
!.
trim
().
toLowerCase
(),
orElse:
()
=>
SubLocations
(
id:
null
,
subLocality:
null
),
);
if
(
matchSub
.
id
!=
null
)
{
selectedSubLocations
=
matchSub
;
_selectedSubLocID
=
matchSub
.
id
;
}
}
// everything loaded
isLoading
=
false
;
notifyListeners
();
return
true
;
}
catch
(
e
,
s
)
{
if
(
kDebugMode
)
debugPrint
(
"loadAccountDetailsForEdit ERROR =>
$e
\n
$s
"
);
updateErrorMessage
=
e
.
toString
();
isLoading
=
false
;
notifyListeners
();
return
false
;
}
}
Future
<
void
>
getDistrictAPI
(
context
,
stateID
)
async
{
try
{
var
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
_districts
.
clear
();
notifyListeners
();
final
data
=
await
ApiCalling
.
commonAddAccountViewDistrictAPI
(
homeProv
.
empId
,
homeProv
.
session
,
stateID
,
);
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
_districts
=
data
.
districts
??
[];
notifyListeners
();
}
}
}
catch
(
e
)
{
if
(
kDebugMode
)
debugPrint
(
'getDistrictAPI error:
$e
'
);
}
}
Future
<
void
>
getSubLocationAPI
(
context
,
districtID
)
async
{
try
{
var
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
_subLocations
.
clear
();
notifyListeners
();
final
data
=
await
ApiCalling
.
commonAddAccountViewSubLocationAPI
(
homeProv
.
empId
,
homeProv
.
session
,
districtID
,
);
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
_subLocations
=
data
.
subLocations
??
[];
notifyListeners
();
}
}
}
catch
(
e
)
{
if
(
kDebugMode
)
debugPrint
(
'getSubLocationAPI error:
$e
'
);
}
}
// --- API: load data needed to populate dropdowns (account types, states) ---
Future
<
void
>
addCommonAccountViewAPI
(
BuildContext
context
)
async
{
try
{
isLoading
=
true
;
var
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
commonAddAccountViewAPI
(
homeProv
.
empId
,
homeProv
.
session
);
_accountTypes
.
clear
();
_states
.
clear
();
if
(
data
!=
null
&&
data
.
error
==
"0"
)
{
_accountTypes
=
data
.
accountTypes
??
[];
_states
=
data
.
states
??
[];
commonResponse
=
data
;
}
}
catch
(
e
)
{
if
(
kDebugMode
)
debugPrint
(
'addCommonAccountViewAPI error:
$e
'
);
}
finally
{
isLoading
=
false
;
notifyListeners
();
}
}
// --- GST validation: calls API and sets gstResponse; returns true if valid ---
Future
<
bool
>
validateGstNumber
(
String
empId
,
String
sessionId
,
String
gstNumber
)
async
{
if
(
gstNumber
.
trim
().
isEmpty
)
{
gstResponse
=
null
;
gstNumberError
=
null
;
notifyListeners
();
return
false
;
}
try
{
isLoading
=
true
;
final
response
=
await
ApiCalling
.
validateGstNumberApi
(
empId
,
sessionId
,
gstNumber
.
trim
());
gstResponse
=
response
;
if
(
response
==
null
)
{
gstNumberError
=
"Failed to validate GST number"
;
notifyListeners
();
return
false
;
}
if
(
response
.
error
==
"0"
)
{
gstNumberError
=
null
;
notifyListeners
();
return
true
;
}
else
{
gstNumberError
=
response
.
message
??
"Invalid GST number"
;
notifyListeners
();
return
false
;
}
}
catch
(
e
)
{
gstNumberError
=
"Error validating GST:
${e.toString()}
"
;
if
(
kDebugMode
)
debugPrint
(
'validateGstNumber error:
$e
'
);
notifyListeners
();
return
false
;
}
finally
{
isLoading
=
false
;
notifyListeners
();
}
}
// --- Bank validation: requires both account number and IFSC ---
Future
<
bool
>
validateBankDetails
(
String
empId
,
String
sessionId
,
String
accountNumber
)
async
{
final
ifsc
=
bankIfscCotroller
.
text
.
trim
();
final
accList
=
detailsListResponse
?.
accountList
!.
first
;
if
(
accountNumber
.
trim
().
isEmpty
||
ifsc
.
isEmpty
)
{
bankResponse
=
null
;
bankAcNumberError
=
null
;
bankIFSCError
=
null
;
bankNameController
.
text
=
""
;
branchNameController
.
text
=
""
;
bankHolderNameController
.
text
=
""
;
bankNameController
.
text
=
accList
?.
bankName
??
""
;
branchNameController
.
text
=
accList
?.
bankBranchName
??
""
;
bankHolderNameController
.
text
=
accList
?.
bankAccountHolderName
??
""
;
notifyListeners
();
return
false
;
}
if
(
bankAcNumberController
.
text
.
isEmpty
||
bankIfscCotroller
.
text
.
isEmpty
)
{
bankNameController
.
text
=
""
;
branchNameController
.
text
=
""
;
bankHolderNameController
.
text
=
""
;
bankNameController
.
text
=
accList
?.
bankName
??
""
;
branchNameController
.
text
=
accList
?.
bankBranchName
??
""
;
bankHolderNameController
.
text
=
accList
?.
bankAccountHolderName
??
""
;
notifyListeners
();
return
false
;
}
final
reg
=
RegExp
(
r'^[A-Za-z]{4}0[A-Za-z0-9]{6}$'
);
if
(!
reg
.
hasMatch
(
ifsc
))
{
bankIFSCError
=
"Invalid IFSC format"
;
notifyListeners
();
return
false
;
}
try
{
isLoading
=
true
;
final
response
=
await
ApiCalling
.
validateBankAccountDetailsApi
(
empId
,
sessionId
,
accountNumber
.
trim
(),
ifsc
);
bankResponse
=
response
;
if
(
response
==
null
)
{
bankAcNumberError
=
"Failed to validate bank account"
;
notifyListeners
();
return
false
;
}
if
(
response
.
error
==
"0"
)
{
bankAcNumberError
=
null
;
bankIFSCError
=
null
;
notifyListeners
();
return
true
;
}
else
{
bankAcNumberError
=
response
.
message
??
"Invalid account details"
;
notifyListeners
();
return
false
;
}
}
catch
(
e
)
{
bankAcNumberError
=
"Error validating account:
${e.toString()}
"
;
if
(
kDebugMode
)
debugPrint
(
'validateBankDetails error:
$e
'
);
notifyListeners
();
return
false
;
}
finally
{
isLoading
=
false
;
notifyListeners
();
}
}
// --- Combines validation and applies response (autofill) for GST ---
Future
<
void
>
checkAndApplyGst
(
BuildContext
context
,
String
gstNumber
)
async
{
gstNumberError
=
null
;
notifyListeners
();
final
trimmed
=
gstNumber
.
trim
();
if
(
trimmed
.
isEmpty
)
{
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"
)
{
// autofill address if available
final
apiAddress
=
(
resp
.
address
??
""
).
trim
();
final
apiName
=
(
resp
.
legalNameOfBusiness
??
""
).
trim
();
if
(
apiAddress
.
isNotEmpty
)
{
addressController
.
text
=
apiAddress
;
}
// compare company name and set error if mismatch
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
nameError
=
"Name Does not match with GST Legal Name : ('
$apiName
')."
;
}
else
{
nameError
=
null
;
}
}
gstNumberError
=
null
;
notifyListeners
();
return
;
}
else
{
_submitClicked
=
false
;
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
();
}
}
// --- Combines validation and applies response (autofill) for Bank ---
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
)
{
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
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"
)
{
// autofill bank fields from response
bankNameController
.
text
=
resp
.
bankName
??
bankNameController
.
text
;
branchNameController
.
text
=
resp
.
branch
??
branchNameController
.
text
;
bankHolderNameController
.
text
=
resp
.
nameAtBank
??
bankHolderNameController
.
text
;
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
();
}
}
}
// --- Re-compare company name with GST (UI calls this on name change) ---
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
=
"Name Does not match with GST Legal Name : ('
$apiName
')."
;
}
else
{
nameError
=
null
;
}
}
notifyListeners
();
}
Future
<
void
>
checkInputsAPI
(
context
,
type
,
value
)
async
{
try
{
var
homeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
commonAddAccountCheckInputsAPI
(
homeProv
.
empId
,
homeProv
.
session
,
type
,
value
,
);
commonResponse
=
data
;
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
nameError
=
null
;
mobileError
=
null
;
notifyListeners
();
}
else
if
(
data
.
error
==
"1"
)
{
if
(
data
.
message
?.
contains
(
"name already exists"
)
??
false
)
{
nameError
=
data
.
message
??
""
;
}
else
{
mobileError
=
data
.
message
??
""
;
}
notifyListeners
();
}
}
}
catch
(
e
)
{
if
(
kDebugMode
)
debugPrint
(
'checkInputsAPI error:
$e
'
);
}
}
// --- Submit (update) API function (calls your existing commonUpdateAccountDetailsAPI) ---
Future
<
bool
>
updateAccountDetailsAPIFunction
(
BuildContext
context
,
{
required
String
accId
,
required
String
name
,
required
String
mob1
,
String
?
mob2
,
String
?
tel
,
String
?
email
,
String
?
designation
,
String
?
address
,
String
?
state
,
String
?
district
,
String
?
subLocality
,
String
?
bankName
,
String
?
branchName
,
String
?
bankIfscCode
,
String
?
accHolderName
,
String
?
bankAccNumber
,
String
?
bankUpiId
,
})
async
{
try
{
_isSubmitting
=
true
;
updateErrorMessage
=
null
;
notifyListeners
();
var
prov
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
commonUpdateAccountDetailsAPI
(
prov
.
empId
,
prov
.
session
,
accId
,
name
,
mob1
,
mob2
??
''
,
tel
??
''
,
email
??
''
,
designation
??
''
,
address
??
''
,
state
??
''
,
district
??
''
,
subLocality
??
''
,
bankName
??
''
,
branchName
??
''
,
bankIfscCode
??
''
,
accHolderName
??
''
,
bankAccNumber
??
''
,
bankUpiId
??
''
,
);
if
(
data
==
null
)
{
updateErrorMessage
=
"No response from server"
;
_isSubmitting
=
false
;
notifyListeners
();
return
false
;
}
if
(
data
.
error
==
"0"
||
data
.
error
==
0
)
{
toast
(
context
,
data
.
message
??
"Updated successfully"
);
_isSubmitting
=
false
;
notifyListeners
();
return
true
;
}
else
{
updateErrorMessage
=
data
.
message
??
"Failed to update account"
;
_isSubmitting
=
false
;
notifyListeners
();
return
false
;
}
}
catch
(
e
,
s
)
{
if
(
kDebugMode
)
debugPrint
(
"updateAccountDetailsAPIFunction error:
$e
\n
$s
"
);
updateErrorMessage
=
e
.
toString
();
_isSubmitting
=
false
;
notifyListeners
();
return
false
;
}
}
bool
_isGstValidFormat
(
String
gst
)
{
gst
=
gst
.
trim
().
toUpperCase
();
final
reg
=
RegExp
(
r'^[0-3][0-9][A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$'
);
return
reg
.
hasMatch
(
gst
);
}
// --- Simple validation (keeps same logic as your UI expects) ---
bool
validateStep1
(
BuildContext
context
)
{
accountError
=
null
;
nameError
=
null
;
mobileError
=
null
;
gstNumberError
=
null
;
contactPersonError
=
null
;
bool
isValid
=
true
;
if
(
_selectedAccountType
==
null
||
_selectedAccountType
!.
isEmpty
)
{
accountError
=
"Please select an Account"
;
isValid
=
false
;
}
if
(
nameController
.
text
.
trim
().
isEmpty
)
{
nameError
=
"Please Enter a Name"
;
isValid
=
false
;
}
if
(
gstNumberController
.
text
.
trim
().
isNotEmpty
){
final
gst
=
gstNumberController
.
text
.
trim
();
if
(!
_isGstValidFormat
(
gst
))
{
gstNumberError
=
"Invalid GST format"
;
notifyListeners
();
isValid
=
false
;
}
}
if
(
gstNumberController
.
text
.
isEmpty
){
final
accList
=
detailsListResponse
?.
accountList
!.
first
;
final
gst
=
gstNumberController
.
text
.
trim
();
addressController
.
text
=
accList
?.
address
??
""
;
}
if
(
nameError
!=
null
&&
nameError
!.
isNotEmpty
)
{
isValid
=
false
;
}
if
(
mobileController
.
text
.
trim
().
isNotEmpty
&&
mobileController
.
text
.
length
<
10
)
{
mobileError
=
"Mobile Number should be 10 digits"
;
isValid
=
false
;
}
if
(
mobileController
.
text
.
trim
().
isEmpty
)
{
mobileError
=
"Please Enter Mobile Number"
;
isValid
=
false
;
}
if
(
contactPersonController
.
text
.
trim
().
isEmpty
)
{
contactPersonError
=
"Please Enter Contact Person Name"
;
isValid
=
false
;
}
// GST vs name check if gstResponse present
if
(
gstResponse
!=
null
)
{
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
')"
;
isValid
=
false
;
}
else
{
nameError
=
null
;
}
}
}
notifyListeners
();
return
isValid
;
}
bool
validateStep
()
{
final
accList
=
detailsListResponse
?.
accountList
!.
first
;
if
(
gstNumberController
.
text
.
isEmpty
)
{
final
gst
=
gstNumberController
.
text
.
trim
();
addressController
.
text
=
accList
?.
address
??
""
;
}
notifyListeners
();
return
false
;
}
bool
validateStep3
()
{
final
accList
=
detailsListResponse
?.
accountList
!.
first
;
if
(
bankAcNumberController
.
text
.
isEmpty
||
bankIfscCotroller
.
text
.
isEmpty
)
{
bankNameController
.
text
=
""
;
branchNameController
.
text
=
""
;
bankHolderNameController
.
text
=
""
;
bankNameController
.
text
=
accList
?.
bankName
??
""
;
branchNameController
.
text
=
accList
?.
bankBranchName
??
""
;
bankHolderNameController
.
text
=
accList
?.
bankAccountHolderName
??
""
;
notifyListeners
();
return
false
;
}
bool
isValid
=
true
;
// optional step — you commented it optional. Keep commented validations deactivated.
_submitClicked
=
false
;
notifyListeners
();
return
isValid
;
}
// Full form final validation before submit
bool
validatereceiptForm
(
BuildContext
context
)
{
// reset error holders
accountError
=
null
;
nameError
=
null
;
mobileError
=
null
;
stateError
=
null
;
districtError
=
null
;
localityError
=
null
;
addressError
=
null
;
banknameError
=
null
;
gstNumberError
=
null
;
bankBranchError
=
null
;
bankIFSCError
=
null
;
bankHolderNameError
=
null
;
bankAcNumberError
=
null
;
upiError
=
null
;
contactPersonError
=
null
;
desigantionError
=
null
;
altMobError
=
null
;
teleError
=
null
;
mailError
=
null
;
bool
isValid
=
true
;
if
(
_selectedAccountType
==
null
||
_selectedAccountType
!.
isEmpty
)
{
accountError
=
"Please select an Account"
;
isValid
=
false
;
}
if
(
nameController
.
text
.
trim
().
isEmpty
)
{
nameError
=
"Please Enter a Name"
;
isValid
=
false
;
}
if
(
mobileController
.
text
.
trim
().
isEmpty
)
{
mobileError
=
"Please Enter Mobile Number"
;
isValid
=
false
;
}
if
(
contactPersonController
.
text
.
trim
().
isEmpty
)
{
contactPersonError
=
"Please Enter Contact Person Name"
;
isValid
=
false
;
}
// GST check
final
apiName
=
(
gstResponse
?.
legalNameOfBusiness
??
""
).
trim
();
final
enteredName
=
nameController
.
text
.
trim
();
if
(
apiName
.
isNotEmpty
&&
enteredName
.
isNotEmpty
)
{
if
(
apiName
.
toLowerCase
()
!=
enteredName
.
toLowerCase
())
{
isValid
=
false
;
nameError
=
"Company name does not match GST record ('
$apiName
')"
;
}
}
notifyListeners
();
return
isValid
;
}
// --- update helper setters to clear errors on edit ---
void
updateName
(
String
value
)
{
nameError
=
null
;
notifyListeners
();
}
void
updateMobile
(
String
value
)
{
mobileError
=
null
;
notifyListeners
();
}
void
updateAddress
(
String
value
)
{
addressError
=
null
;
notifyListeners
();
}
void
updateBankName
(
String
value
)
{
banknameError
=
null
;
notifyListeners
();
}
void
updateGSTNumber
(
String
value
)
{
gstNumberError
=
null
;
notifyListeners
();
}
void
updateBankBranch
(
String
value
)
{
bankBranchError
=
null
;
notifyListeners
();
}
void
updateIFSC
(
String
value
)
{
bankIFSCError
=
null
;
notifyListeners
();
}
void
updateHolder
(
String
value
)
{
bankHolderNameError
=
null
;
notifyListeners
();
}
void
updateNumber
(
String
value
)
{
bankAcNumberError
=
null
;
notifyListeners
();
}
void
updateUPI
(
String
value
)
{
upiError
=
null
;
notifyListeners
();
}
void
updateContactPerson
(
String
value
)
{
contactPersonError
=
null
;
notifyListeners
();
}
void
updateDesignation
(
String
value
)
{
desigantionError
=
null
;
notifyListeners
();
}
void
updateAltMobile
(
String
value
)
{
altMobError
=
null
;
notifyListeners
();
}
void
updateTeleMobile
(
String
value
)
{
teleError
=
null
;
notifyListeners
();
}
void
updateMail
(
String
value
)
{
mailError
=
null
;
notifyListeners
();
}
// --- Reset values used by Edit form (clears controllers + errors + selections) ---
void
resetValues
()
{
_selectedAccountType
=
null
;
_selectedState
=
null
;
_selectedDistricts
=
null
;
_selectedSubLocations
=
null
;
_selectedStateID
=
null
;
_selectedDistrictID
=
null
;
_selectedSubLocID
=
null
;
gstResponse
=
null
;
bankResponse
=
null
;
commonResponse
=
null
;
updateErrorMessage
=
null
;
_isLoading
=
false
;
_isSubmitting
=
false
;
stateSearchController
.
clear
();
districtSearchController
.
clear
();
subLocSearchController
.
clear
();
nameController
.
clear
();
mobileController
.
clear
();
addressController
.
clear
();
bankNameController
.
clear
();
branchNameController
.
clear
();
bankIfscCotroller
.
clear
();
bankHolderNameController
.
clear
();
bankAcNumberController
.
clear
();
bankUpiController
.
clear
();
contactPersonController
.
clear
();
contectPersonMailController
.
clear
();
accountError
=
null
;
nameError
=
null
;
mobileError
=
null
;
stateError
=
null
;
districtError
=
null
;
localityError
=
null
;
addressError
=
null
;
banknameError
=
null
;
gstNumberError
=
null
;
bankBranchError
=
null
;
bankIFSCError
=
null
;
bankHolderNameError
=
null
;
bankAcNumberError
=
null
;
upiError
=
null
;
contactPersonError
=
null
;
desigantionError
=
null
;
altMobError
=
null
;
teleError
=
null
;
mailError
=
null
;
addMoreDetailsError
=
null
;
notifyListeners
();
}
// dispose controllers when provider is disposed (optional)
@override
void
dispose
()
{
nameController
.
dispose
();
mobileController
.
dispose
();
addressController
.
dispose
();
bankNameController
.
dispose
();
branchNameController
.
dispose
();
bankIfscCotroller
.
dispose
();
bankHolderNameController
.
dispose
();
gstNumberController
.
dispose
();
bankAcNumberController
.
dispose
();
bankUpiController
.
dispose
();
contactPersonController
.
dispose
();
contectPersonMailController
.
dispose
();
stateSearchController
.
dispose
();
districtSearchController
.
dispose
();
subLocSearchController
.
dispose
();
super
.
dispose
();
}
}
lib/Notifiers/crmProvider/CrmNearByGeneratorsProvider.dart
0 → 100644
View file @
b35acfea
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"
;
}
}
Prev
1
2
3
4
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