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
d2939607
Commit
d2939607
authored
Nov 21, 2025
by
Sai Srinivas
Browse files
Correction and changes
parent
a5ccb211
Changes
42
Expand all
Show whitespace changes
Inline
Side-by-side
lib/Models/financeModels/ValidateBankAccountDetailsResponse.dart
0 → 100644
View file @
d2939607
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 @
d2939607
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 @
d2939607
class
CommonResponse
{
class
CommonResponse
{
String
?
error
;
String
?
error
;
String
?
message
;
String
?
message
;
String
?
qrCode
;
String
?
qrId
;
int
?
sessionExists
;
int
?
sessionExists
;
CommonResponse
({
this
.
error
,
this
.
message
,
this
.
sessionExists
});
CommonResponse
({
this
.
error
,
this
.
message
,
this
.
sessionExists
});
CommonResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
CommonResponse
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
{
error
=
json
[
'error'
];
error
=
json
[
'error'
];
qrCode
=
json
[
'qr_code'
];
qrId
=
json
[
'razorpay_order_id'
];
message
=
json
[
'message'
];
message
=
json
[
'message'
];
sessionExists
=
json
[
'session_exists'
];
sessionExists
=
json
[
'session_exists'
];
}
}
...
@@ -15,6 +18,8 @@ class CommonResponse {
...
@@ -15,6 +18,8 @@ class CommonResponse {
Map
<
String
,
dynamic
>
toJson
()
{
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
data
=
<
String
,
dynamic
>{};
final
Map
<
String
,
dynamic
>
data
=
<
String
,
dynamic
>{};
data
[
'error'
]
=
error
;
data
[
'error'
]
=
error
;
data
[
'qr_code'
]
=
qrCode
;
data
[
'razorpay_order_id'
]
=
qrId
;
data
[
'message'
]
=
message
;
data
[
'message'
]
=
message
;
data
[
'session_exists'
]
=
sessionExists
;
data
[
'session_exists'
]
=
sessionExists
;
return
data
;
return
data
;
...
...
lib/Notifiers/PaymentDetailsProvider.dart
View file @
d2939607
...
@@ -208,6 +208,7 @@ class Paymentdetailsprovider extends ChangeNotifier {
...
@@ -208,6 +208,7 @@ class Paymentdetailsprovider extends ChangeNotifier {
_imageName
=
null
;
_imageName
=
null
;
_image_picked
=
0
;
_image_picked
=
0
;
resetErrors
();
notifyListeners
();
notifyListeners
();
}
else
{}
}
else
{}
}
else
{
}
else
{
...
@@ -775,6 +776,22 @@ class Paymentdetailsprovider extends ChangeNotifier {
...
@@ -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
()
{
resetAddContect
()
{
Amountcontroller
.
clear
();
Amountcontroller
.
clear
();
Referencecontroller
.
clear
();
Referencecontroller
.
clear
();
...
...
lib/Notifiers/QrProvider.dart
0 → 100644
View file @
d2939607
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
;
/// Fetch Razorpay QR API
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
();
}
}
/// Start 2-minute countdown
void
_startTimer
()
{
_secondsLeft
=
120
;
_timer
?.
cancel
();
_timer
=
Timer
.
periodic
(
const
Duration
(
seconds:
1
),
(
timer
)
{
if
(
_secondsLeft
>
0
)
{
_secondsLeft
--;
notifyListeners
();
}
else
{
timer
.
cancel
();
}
});
}
/// Dispose timer properly
@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
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
{
CustomSnackBar
.
showWarning
(
context:
context
,
message:
"⚠️ Payment not yet completed or failed"
);
debugPrint
(
"⚠️ Payment not yet completed or failed"
);
}
}
else
{
debugPrint
(
"❌ Null response from Razorpay QR Status API"
);
}
return
response
;
// return here
}
catch
(
e
)
{
debugPrint
(
"❌ fetchRazorpayUpiQrStatus error:
$e
"
);
return
null
;
}
finally
{
isPaymentUpdating
=
false
;
}
}
}
lib/Notifiers/commonProvider/ValidationProvider.dart
0 → 100644
View file @
d2939607
import
'package:flutter/material.dart'
;
import
'package:generp/services/api_calling.dart'
;
import
'../../Models/financeModels/ValidateBankAccountDetailsResponse.dart'
;
import
'../../Models/financeModels/ValidateGstNumResponse.dart'
;
class
ValidationProvider
extends
ChangeNotifier
{
bool
isLoading
=
false
;
ValidateGstNumResponse
?
gstResponse
;
ValidateBankAccountDetailsResponse
?
bankResponse
;
String
?
errorMessage
;
/// Validate GST Number
/// -----------------------------
Future
<
void
>
validateGstNumber
(
String
empId
,
String
sessionId
,
String
gstNumber
)
async
{
try
{
isLoading
=
true
;
errorMessage
=
null
;
notifyListeners
();
gstResponse
=
await
ApiCalling
.
validateGstNumberApi
(
empId
,
sessionId
,
gstNumber
,
);
if
(
gstResponse
==
null
)
{
errorMessage
=
"Failed to validate GST number"
;
}
}
catch
(
e
)
{
errorMessage
=
e
.
toString
();
}
isLoading
=
false
;
notifyListeners
();
}
/// Validate Bank Account Details
/// -----------------------------
Future
<
void
>
validateBankDetails
(
String
empId
,
String
sessionId
,
String
accountNumber
)
async
{
try
{
isLoading
=
true
;
errorMessage
=
null
;
notifyListeners
();
bankResponse
=
await
ApiCalling
.
validateBankAccountDetailsApi
(
empId
,
sessionId
,
accountNumber
,
""
);
if
(
bankResponse
==
null
)
{
errorMessage
=
"Failed to validate bank account"
;
}
}
catch
(
e
)
{
errorMessage
=
e
.
toString
();
}
isLoading
=
false
;
notifyListeners
();
}
/// Reset before calling again
void
clear
()
{
gstResponse
=
null
;
bankResponse
=
null
;
errorMessage
=
null
;
notifyListeners
();
}
}
lib/Notifiers/commonProvider/accountsListProvider.dart
View file @
d2939607
This diff is collapsed.
Click to expand it.
lib/Notifiers/crmProvider/LeadListProvider.dart
View file @
d2939607
This diff is collapsed.
Click to expand it.
lib/Notifiers/crmProvider/addNewLeadsandProspectsProvider.dart
View file @
d2939607
...
@@ -757,14 +757,17 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
...
@@ -757,14 +757,17 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
notifyListeners
();
notifyListeners
();
}
}
onChangeCompanyName
(
value
)
{
// onChangeCompanyName(value) {
companynameError
=
""
;
// companynameError = "";
// notifyListeners();
// }
onChangeContactPersonName
(
value
)
{
nameError
=
""
;
notifyListeners
();
notifyListeners
();
}
}
onChangeAlternatemobile
(
value
)
{
onChangeAlternatemobile
(
value
)
{
AlternatemobileError
=
""
;
AlternatemobileError
=
""
;
notifyListeners
();
notifyListeners
();
...
@@ -775,22 +778,22 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
...
@@ -775,22 +778,22 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
notifyListeners
();
notifyListeners
();
}
}
Future
<
void
>
onChangeCo
ntactPerson
Name
(
BuildContext
context
,
String
value
)
async
{
Future
<
void
>
onChangeCo
mpany
Name
(
BuildContext
context
,
String
value
)
async
{
nameError
=
""
;
company
nameError
=
""
;
if
(
value
.
isEmpty
)
{
if
(
value
.
isEmpty
)
{
nameError
=
"Name cannot be empty"
;
company
nameError
=
"
Company
Name cannot be empty"
;
}
else
if
(
value
.
length
<
3
)
{
}
else
if
(
value
.
length
<
3
)
{
nameError
=
"Name must be at least 3 characters"
;
company
nameError
=
"
Company
Name must be at least 3 characters"
;
}
else
{
}
else
{
final
exists
=
await
checkAccountFieldExistence
(
final
exists
=
await
checkAccountFieldExistence
(
context
,
context
,
type:
"
name
"
,
type:
"
company
"
,
typeValue:
value
,
typeValue:
value
,
);
);
if
(!
exists
)
{
if
(!
exists
)
{
nameError
=
"Name already exists"
;
company
nameError
=
"
Company
Name already exists"
;
}
else
{
}
else
{
nameError
=
null
;
company
nameError
=
null
;
}
}
}
}
notifyListeners
();
notifyListeners
();
...
@@ -997,7 +1000,7 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
...
@@ -997,7 +1000,7 @@ class Addnewleadsandprospectsprovider extends ChangeNotifier {
isValid
=
false
;
isValid
=
false
;
}
}
if
(
nameError
==
"Name already exists"
){
if
(
company
nameError
==
"
Company
Name already exists"
){
isValid
=
false
;
isValid
=
false
;
}
}
...
...
lib/Notifiers/crmProvider/editCrmAccountDetailsProvider.dart
View file @
d2939607
...
@@ -34,16 +34,26 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -34,16 +34,26 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
List
<
Teams
>
get
teamsList
=>
_teamsList
;
List
<
Teams
>
get
teamsList
=>
_teamsList
;
List
<
Segments
>
get
segmentsList
=>
_segmentsList
;
List
<
Segments
>
get
segmentsList
=>
_segmentsList
;
Teams
?
get
selectedTeams
=>
_selectedTeams
;
Segments
?
get
selectedSegments
=>
_selectedSegments
;
// IMPORTANT: Return null if the selected object is not present in the current list.
// This prevents DropdownButton2 from receiving a value that is not part of items.
Teams
?
get
selectedTeams
{
if
(
_selectedTeams
==
null
)
return
null
;
if
(!
_teamsList
.
contains
(
_selectedTeams
))
return
null
;
return
_selectedTeams
;
}
Segments
?
get
selectedSegments
{
if
(
_selectedSegments
==
null
)
return
null
;
if
(!
_segmentsList
.
contains
(
_selectedSegments
))
return
null
;
return
_selectedSegments
;
}
AccountDetails
get
accountsDetails
=>
_accountDetails
;
AccountDetails
get
accountsDetails
=>
_accountDetails
;
String
?
get
selectedTeamId
=>
_selectedTeamId
;
String
?
get
selectedTeamId
=>
_selectedTeamId
;
String
?
get
selectedTeamValue
=>
_selectedTeamValue
;
String
?
get
selectedTeamValue
=>
_selectedTeamValue
;
String
?
get
selectedSegmentId
=>
_selectedSegmentId
;
String
?
get
selectedSegmentId
=>
_selectedSegmentId
;
String
?
get
selectedSegmentValue
=>
_selectedSegmentValue
;
String
?
get
selectedSegmentValue
=>
_selectedSegmentValue
;
set
isLoading
(
bool
value
)
{
set
isLoading
(
bool
value
)
{
...
@@ -68,15 +78,25 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -68,15 +78,25 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
set
selectedTeams
(
Teams
?
value
)
{
set
selectedTeams
(
Teams
?
value
)
{
_selectedTeams
=
value
;
_selectedTeams
=
value
;
_selectedTeamId
=
value
!.
id
!;
if
(
value
!=
null
)
{
_selectedTeamId
=
value
.
id
;
_selectedTeamValue
=
value
.
name
;
_selectedTeamValue
=
value
.
name
;
}
else
{
_selectedTeamId
=
null
;
_selectedTeamValue
=
null
;
}
notifyListeners
();
notifyListeners
();
}
}
set
selectedSegments
(
Segments
?
value
)
{
set
selectedSegments
(
Segments
?
value
)
{
_selectedSegments
=
value
;
_selectedSegments
=
value
;
_selectedSegmentId
=
value
!.
id
!;
if
(
value
!=
null
)
{
_selectedSegmentId
=
value
.
id
;
_selectedSegmentValue
=
value
.
name
;
_selectedSegmentValue
=
value
.
name
;
}
else
{
_selectedSegmentId
=
null
;
_selectedSegmentValue
=
null
;
}
notifyListeners
();
notifyListeners
();
}
}
...
@@ -117,8 +137,21 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -117,8 +137,21 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
notifyListeners
();
notifyListeners
();
if
(
data
!=
null
)
{
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
if
(
data
.
error
==
"0"
)
{
_teamsList
=
data
.
teams
!;
_teamsList
=
data
.
teams
??
[];
_accountDetails
=
data
.
accountDetails
!;
_accountDetails
=
data
.
accountDetails
??
AccountDetails
();
// If current selected team/segment are not in the new lists, clear them
if
(
_selectedTeams
!=
null
&&
!
_teamsList
.
contains
(
_selectedTeams
))
{
_selectedTeams
=
null
;
_selectedTeamId
=
null
;
_selectedTeamValue
=
null
;
}
if
(
_selectedSegments
!=
null
&&
!
_segmentsList
.
contains
(
_selectedSegments
))
{
_selectedSegments
=
null
;
_selectedSegmentId
=
null
;
_selectedSegmentValue
=
null
;
}
_isLoading
=
false
;
_isLoading
=
false
;
notifyListeners
();
notifyListeners
();
}
else
{
}
else
{
...
@@ -149,13 +182,29 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -149,13 +182,29 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
);
);
if
(
data
!=
null
)
{
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
if
(
data
.
error
==
"0"
)
{
_segmentsList
=
data
.
segments
!;
_segmentsList
=
data
.
segments
??
[];
// clear selectedSegments if it's not part of new list
if
(
_selectedSegments
!=
null
&&
!
_segmentsList
.
contains
(
_selectedSegments
))
{
_selectedSegments
=
null
;
_selectedSegmentId
=
null
;
_selectedSegmentValue
=
null
;
}
notifyListeners
();
notifyListeners
();
}
}
}
}
}
catch
(
e
)
{}
}
catch
(
e
)
{}
}
}
// Fixed: check string emptiness properly (IDs are strings in your model)
bool
get
isFormValid
{
final
nameOk
=
editCompanyNameController
.
text
.
trim
().
isNotEmpty
;
final
teamOk
=
_selectedTeamId
!=
null
&&
_selectedTeamId
!.
isNotEmpty
;
final
segmentOk
=
_selectedSegmentId
!=
null
&&
_selectedSegmentId
!.
isNotEmpty
;
return
nameOk
&&
teamOk
&&
segmentOk
;
}
Future
<
void
>
crmLeadDetailsEditAccountSubmitAPIFunction
(
Future
<
void
>
crmLeadDetailsEditAccountSubmitAPIFunction
(
context
,
context
,
accountId
,
accountId
,
...
@@ -166,6 +215,10 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -166,6 +215,10 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
if
(!
validateForm
(
context
))
{
if
(!
validateForm
(
context
))
{
return
;
return
;
}
}
_isLoading
=
true
;
notifyListeners
();
var
HomeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
var
HomeProv
=
Provider
.
of
<
HomescreenNotifier
>(
context
,
listen:
false
);
final
data
=
await
ApiCalling
.
crmLeadDetailsEditAccountSubmitAPI
(
final
data
=
await
ApiCalling
.
crmLeadDetailsEditAccountSubmitAPI
(
HomeProv
.
empId
,
HomeProv
.
empId
,
...
@@ -175,8 +228,7 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -175,8 +228,7 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
teamId
,
teamId
,
editCompanyNameController
.
text
,
editCompanyNameController
.
text
,
);
);
_isLoading
=
true
;
notifyListeners
();
if
(
data
!=
null
)
{
if
(
data
!=
null
)
{
if
(
data
.
error
==
"0"
)
{
if
(
data
.
error
==
"0"
)
{
Navigator
.
pop
(
context
,
true
);
Navigator
.
pop
(
context
,
true
);
...
@@ -200,19 +252,24 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -200,19 +252,24 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
bool
validateForm
(
BuildContext
context
)
{
bool
validateForm
(
BuildContext
context
)
{
// Reset all errors
// Reset all errors
_companyNameError
=
null
;
_companyNameError
=
null
;
_selectedTeamError
=
null
;
_selectedSegmentError
=
null
;
bool
isValid
=
true
;
bool
isValid
=
true
;
if
(
_selectedTeams
==
null
||
_selectedTeamId
!.
isEmpty
)
{
// Team checks
_selectedTeamError
=
"Please select an account"
;
if
(
_selectedTeams
==
null
||
_selectedTeamId
==
null
||
_selectedTeamId
!.
isEmpty
)
{
_selectedTeamError
=
"Please select a team"
;
isValid
=
false
;
isValid
=
false
;
}
}
if
(
_selectedSegments
==
null
||
_selectedSegmentId
!.
isEmpty
)
{
// Segment checks
_selectedSegmentError
=
"Please select an account"
;
if
(
_selectedSegments
==
null
||
_selectedSegmentId
==
null
||
_selectedSegmentId
!.
isEmpty
)
{
_selectedSegmentError
=
"Please select a segment"
;
isValid
=
false
;
isValid
=
false
;
}
}
// Company name check
if
(
editCompanyNameController
.
text
.
trim
().
isEmpty
)
{
if
(
editCompanyNameController
.
text
.
trim
().
isEmpty
)
{
_companyNameError
=
"Please enter Company name"
;
_companyNameError
=
"Please enter Company name"
;
isValid
=
false
;
isValid
=
false
;
...
@@ -223,7 +280,12 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -223,7 +280,12 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
}
}
onChangedCompanyName
(
value
)
{
onChangedCompanyName
(
value
)
{
_companyNameError
=
""
;
// Clear the company name error when user types
if
(
value
!=
null
&&
value
.
toString
().
trim
().
isNotEmpty
)
{
_companyNameError
=
null
;
}
else
{
_companyNameError
=
"Name is required"
;
}
notifyListeners
();
notifyListeners
();
}
}
...
@@ -236,11 +298,13 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
...
@@ -236,11 +298,13 @@ class Editcrmaccountdetailsprovider extends ChangeNotifier {
_selectedSegmentId
=
null
;
_selectedSegmentId
=
null
;
_selectedTeamValue
=
null
;
_selectedTeamValue
=
null
;
_selectedSegmentValue
=
null
;
_selectedSegmentValue
=
null
;
_selectedTeamError
=
null
;
_selectedSegmentError
=
null
;
_companyNameError
=
null
;
}
}
void
checkDropDownValues
()
{
void
checkDropDownValues
()
{
if
(!
_segmentsList
.
contains
(
_selectedSegments
)
&&
if
(!
_segmentsList
.
contains
(
_selectedSegments
)
&&
_selectedSegments
!=
null
)
{
_selectedSegments
!=
null
)
{
_selectedTeamId
=
null
;
_selectedTeamId
=
null
;
_selectedTeamValue
=
null
;
_selectedTeamValue
=
null
;
}
}
...
...
lib/main.dart
View file @
d2939607
...
@@ -10,6 +10,7 @@ import 'package:flutter/services.dart';
...
@@ -10,6 +10,7 @@ import 'package:flutter/services.dart';
import
'package:flutter_local_notifications/flutter_local_notifications.dart'
;
import
'package:flutter_local_notifications/flutter_local_notifications.dart'
;
import
'package:flutter_ringtone_player/flutter_ringtone_player.dart'
;
import
'package:flutter_ringtone_player/flutter_ringtone_player.dart'
;
import
'package:generp/Models/hrmModels/leaveApplicationLIstResponse.dart'
;
import
'package:generp/Models/hrmModels/leaveApplicationLIstResponse.dart'
;
import
'package:generp/Notifiers/QrProvider.dart'
;
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/Utils/app_colors.dart'
;
import
'package:generp/screens/AttendanceScreen.dart'
;
import
'package:generp/screens/AttendanceScreen.dart'
;
import
'package:generp/screens/HomeScreen.dart'
;
import
'package:generp/screens/HomeScreen.dart'
;
...
@@ -426,6 +427,7 @@ class MyApp extends StatelessWidget {
...
@@ -426,6 +427,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider
(
create:
(
_
)
=>
AdvanceListProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
AdvanceListProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
CasualLeaveHistoryProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
CasualLeaveHistoryProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
ContactProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
ContactProvider
()),
ChangeNotifierProvider
(
create:
(
_
)
=>
QrProvider
()),
],
],
child:
Builder
(
child:
Builder
(
...
...
lib/screens/commom/addCommonPayment.dart
View file @
d2939607
This diff is collapsed.
Click to expand it.
lib/screens/commom/transactionDetails.dart
View file @
d2939607
...
@@ -103,7 +103,7 @@ class _TransactiondetailsState extends State<Transactiondetails> {
...
@@ -103,7 +103,7 @@ class _TransactiondetailsState extends State<Transactiondetails> {
),
),
),
),
),
),
SizedBox
(
width:
10
),
SizedBox
(
width:
8
),
Expanded
(
Expanded
(
flex:
3
,
flex:
3
,
child:
Container
(
child:
Container
(
...
@@ -117,15 +117,15 @@ class _TransactiondetailsState extends State<Transactiondetails> {
...
@@ -117,15 +117,15 @@ class _TransactiondetailsState extends State<Transactiondetails> {
),
),
child:
Center
(
child:
Center
(
child:
Text
(
child:
Text
(
"₹
${details.amount ?? "-"}
"
,
"
₹
${details.amount ?? "-"}
"
,
maxLines:
2
,
maxLines:
2
,
overflow:
TextOverflow
.
ellipsis
,
overflow:
TextOverflow
.
ellipsis
,
style:
TextStyle
(
style:
TextStyle
(
fontFamily:
"JakartaRegular"
,
fontFamily:
"JakartaRegular"
,
fontSize:
1
4
,
fontSize:
1
2.8
,
color:
color:
widget
.
type
==
"Credit
ed
"
widget
.
type
==
"Credit"
?
Color
(
0xFFEF3739
)
?
Color
(
0xFFEF3739
)
:
Color
(
0xFF0D9C00
),
:
Color
(
0xFF0D9C00
),
),
),
...
@@ -359,6 +359,7 @@ class _TransactiondetailsState extends State<Transactiondetails> {
...
@@ -359,6 +359,7 @@ class _TransactiondetailsState extends State<Transactiondetails> {
details
details
.
attachmentDirFilePath
??
.
attachmentDirFilePath
??
""
,
""
,
downloadEnable:
false
,
),
),
),
),
);
);
...
...
lib/screens/crm/LeadListByMode.dart
View file @
d2939607
...
@@ -151,6 +151,11 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
...
@@ -151,6 +151,11 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
InkResponse
(
InkResponse
(
onTap:
()
async
{
onTap:
()
async
{
HapticFeedback
.
selectionClick
();
HapticFeedback
.
selectionClick
();
final
provider
=
Provider
.
of
<
Leadlistprovider
>(
context
,
listen:
false
);
// If lists are empty, fetch required data first (this will populate sources, teams, states, employees)
if
(
provider
.
sourcesList
.
isEmpty
||
provider
.
teamsList
.
isEmpty
||
provider
.
employeesList
.
isEmpty
)
{
await
provider
.
crmLeadListViewAPIFunction
(
context
,
widget
.
mode
);
}
_showFilterSheetNew
(
context
);
_showFilterSheetNew
(
context
);
},
},
child:
SvgPicture
.
asset
(
child:
SvgPicture
.
asset
(
...
@@ -158,6 +163,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
...
@@ -158,6 +163,7 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
height:
25
,
height:
25
,
),
),
),
),
],
],
),
),
0xFFFFFFFF
,
0xFFFFFFFF
,
...
@@ -206,7 +212,36 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
...
@@ -206,7 +212,36 @@ class _LeadlistbymodeState extends State<Leadlistbymode> {
provider
.
crmLeadList
[
index
].
leadid
,
provider
.
crmLeadList
[
index
].
leadid
,
),
),
),
),
).
then
((
_
)
async
{
final
provider
=
Provider
.
of
<
Leadlistprovider
>(
context
,
listen:
false
);
provider
.
resetPagination
();
if
(
widget
.
filter
!=
null
)
{
provider
.
crmLeadListAPIFunction
(
context
,
widget
.
mode
,
widget
.
filter
!.
status
,
widget
.
filter
!.
openStatus
,
""
,
""
,
""
,
""
,
""
,
);
);
}
else
{
provider
.
crmLeadListAPIFunction
(
context
,
widget
.
mode
,
""
,
""
,
""
,
""
,
""
,
""
,
""
,
);
}
});
},
},
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
padding:
EdgeInsets
.
symmetric
(
...
...
lib/screens/crm/addLeadsProspectsScreen.dart
View file @
d2939607
...
@@ -291,7 +291,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
...
@@ -291,7 +291,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
provider
.
companyNameController
,
provider
.
companyNameController
,
"Company Name"
,
"Company Name"
,
"Enter Company Name"
,
"Enter Company Name"
,
provider
.
onChangeCompanyName
,
(
value
)
=>
provider
.
onChangeCompanyName
(
context
,
value
)
,
TextInputType
.
name
,
TextInputType
.
name
,
false
,
false
,
null
,
null
,
...
@@ -301,20 +301,33 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
...
@@ -301,20 +301,33 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
),
),
errorWidget
(
context
,
provider
.
companynameError
),
errorWidget
(
context
,
provider
.
companynameError
),
// textControllerWidget(
// context,
// provider.contactPersonNameController,
// "Contact Person Name",
// "Enter Name",
//
// TextInputType.name,
// false,
// null,
// focusNodes[1],
// focusNodes[2],
// TextInputAction.next,
// ),
textControllerWidget
(
textControllerWidget
(
context
,
context
,
provider
.
contactPersonNameController
,
provider
.
contactPersonNameController
,
"Contact Person Name"
,
"Contact Person Name"
,
"Enter Name"
,
"Enter Name"
,
(
value
)
=>
provider
.
onChangeContactPersonName
(
context
,
value
)
,
provider
.
onChangeContactPersonName
,
TextInputType
.
name
,
TextInputType
.
name
,
false
,
false
,
null
,
null
,
focusNodes
[
1
],
focusNodes
[
1
],
focusNodes
[
2
],
focusNodes
[
2
],
TextInputAction
.
next
,
TextInputAction
.
next
),
),
errorWidget
(
context
,
provider
.
nameError
),
errorWidget
(
context
,
provider
.
nameError
),
textControllerWidget
(
textControllerWidget
(
...
@@ -980,7 +993,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
...
@@ -980,7 +993,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
),
),
padding:
EdgeInsets
.
symmetric
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
horizontal:
10
,
vertical:
8
,
vertical:
6
,
),
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
color:
Color
(
0xFFE6F6FF
),
color:
Color
(
0xFFE6F6FF
),
...
@@ -1040,7 +1053,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
...
@@ -1040,7 +1053,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
color:
AppColors
.
grey_semi
,
color:
AppColors
.
grey_semi
,
),
),
),
),
SizedBox
(
height:
5
),
SizedBox
(
height:
2
),
DottedLine
(
DottedLine
(
dashGapLength:
4
,
dashGapLength:
4
,
dashGapColor:
Colors
.
white
,
dashGapColor:
Colors
.
white
,
...
@@ -1048,7 +1061,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
...
@@ -1048,7 +1061,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
dashLength:
2
,
dashLength:
2
,
lineThickness:
0.5
,
lineThickness:
0.5
,
),
),
SizedBox
(
height:
5
),
SizedBox
(
height:
2
),
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
...
@@ -1062,7 +1075,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
...
@@ -1062,7 +1075,7 @@ class _AddleadsprospectsscreenState extends State<Addleadsprospectsscreen> {
),
),
],
],
),
),
SizedBox
(
height:
5
),
SizedBox
(
height:
2
),
Row
(
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
children:
[
children:
[
...
...
lib/screens/crm/crmDashboard.dart
View file @
d2939607
...
@@ -16,6 +16,7 @@ import 'package:generp/screens/crm/universalSearchScreen.dart';
...
@@ -16,6 +16,7 @@ import 'package:generp/screens/crm/universalSearchScreen.dart';
import
'package:provider/provider.dart'
;
import
'package:provider/provider.dart'
;
import
'package:generp/screens/screensExports.dart'
;
import
'package:generp/screens/screensExports.dart'
;
import
'../../Notifiers/crmProvider/LeadListProvider.dart'
;
import
'../../Notifiers/crmProvider/crmDashboardProvider.dart'
;
import
'../../Notifiers/crmProvider/crmDashboardProvider.dart'
;
import
'../../Utils/app_colors.dart'
;
import
'../../Utils/app_colors.dart'
;
import
'../../Utils/commonServices.dart'
;
import
'../../Utils/commonServices.dart'
;
...
@@ -272,20 +273,49 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
...
@@ -272,20 +273,49 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
await
Navigator
.
push
(
await
Navigator
.
push
(
context
,
context
,
MaterialPageRoute
(
MaterialPageRoute
(
builder:
builder:
(
context
)
=>
Leadlistbymode
(
(
context
)
=>
Leadlistbymode
(
pageTitleName:
leadTitles
[
jndex
],
pageTitleName:
leadTitles
[
jndex
],
mode:
mode:
provider
.
allLeads
[
jndex
].
filter
!.
mode
,
provider
filter:
provider
.
allLeads
[
jndex
].
filter
!,
.
allLeads
[
jndex
]
.
filter
!
.
mode
,
filter:
provider
.
allLeads
[
jndex
].
filter
!,
),
),
),
),
).
then
((
_
)
async
{
// get the Leadlistprovider and reset filters + reload list
final
leadProv
=
Provider
.
of
<
Leadlistprovider
>(
context
,
listen:
false
);
// Clear selected filters
leadProv
.
resetForm
();
// Reset pagination and reload the list (same as your existing pattern)
leadProv
.
resetPagination
();
if
(
provider
.
allLeads
[
jndex
].
filter
!=
null
)
{
leadProv
.
crmLeadListAPIFunction
(
context
,
provider
.
allLeads
[
jndex
].
filter
!.
mode
,
provider
.
allLeads
[
jndex
].
filter
!.
status
,
provider
.
allLeads
[
jndex
].
filter
!.
openStatus
,
""
,
""
,
""
,
""
,
""
,
);
}
else
{
leadProv
.
crmLeadListAPIFunction
(
context
,
provider
.
allLeads
[
jndex
].
filter
!.
mode
,
""
,
""
,
""
,
""
,
""
,
""
,
""
,
);
);
}
}
});
}
}
}
if
(
leadTitles
[
jndex
]
==
"Pending Tasks"
)
{
if
(
leadTitles
[
jndex
]
==
"Pending Tasks"
)
{
await
Navigator
.
push
(
await
Navigator
.
push
(
...
...
lib/screens/crm/editAccountDetails.dart
View file @
d2939607
...
@@ -179,49 +179,45 @@ class _EditAccountDetailsState extends State<EditAccountDetails> {
...
@@ -179,49 +179,45 @@ class _EditAccountDetailsState extends State<EditAccountDetails> {
),
),
),
),
SizedBox
(
height:
25
),
SizedBox
(
height:
25
),
InkWell
(
// Use ElevatedButton so we can easily disable it when invalid or loading
onTap:
SizedBox
(
provider
.
isLoading
width:
double
.
infinity
,
child:
ElevatedButton
(
onPressed:
(
provider
.
isLoading
||
!
provider
.
isFormValid
)
?
null
?
null
:
()
{
:
()
{
provider
.
isLoading
=
true
;
// DO NOT set provider.isLoading here — provider will manage it.
provider
provider
.
crmLeadDetailsEditAccountSubmitAPIFunction
(
.
crmLeadDetailsEditAccountSubmitAPIFunction
(
context
,
context
,
widget
.
accountID
,
widget
.
accountID
,
provider
.
selectedSegmentId
,
provider
.
selectedSegmentId
,
provider
.
selectedTeamId
,
provider
.
selectedTeamId
,
);
);
},
},
child:
Container
(
style:
ElevatedButton
.
styleFrom
(
alignment:
Alignment
.
center
,
padding:
EdgeInsets
.
symmetric
(
vertical:
12.0
),
height:
45
,
shape:
RoundedRectangleBorder
(
margin:
EdgeInsets
.
only
(
left:
5.0
,
right:
5.0
,
top:
5.0
,
bottom:
5.0
,
),
decoration:
BoxDecoration
(
color:
AppColors
.
app_blue
,
//1487C9
borderRadius:
BorderRadius
.
circular
(
14.0
),
borderRadius:
BorderRadius
.
circular
(
14.0
),
),
),
child:
Center
(
backgroundColor:
AppColors
.
app_blue
,
child:
disabledBackgroundColor:
AppColors
.
app_blue
.
withOpacity
(
0.5
),
provider
.
isLoading
),
?
CircularProgressIndicator
.
adaptive
(
child:
provider
.
isLoading
valueColor:
AlwaysStoppedAnimation
(
?
SizedBox
(
AppColors
.
white
,
height:
20
,
width:
20
,
child:
CircularProgressIndicator
.
adaptive
(
valueColor:
AlwaysStoppedAnimation
(
Colors
.
white
),
strokeWidth:
2
,
),
),
)
)
:
Text
(
:
Text
(
"Submit"
,
"Submit"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
color:
Colors
.
white
),
style:
TextStyle
(
color:
Colors
.
white
),
),
),
),
),
),
),
),
],
],
),
),
),
),
...
...
lib/screens/finance/FileViewer.dart
View file @
d2939607
import
'dart:async'
;
import
'dart:async'
;
import
'dart:io'
;
import
'package:cached_network_image/cached_network_image.dart'
;
import
'package:cached_network_image/cached_network_image.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:open_filex/open_filex.dart'
;
import
'package:flutter_inappwebview/flutter_inappwebview.dart'
;
import
'package:flutter_inappwebview/flutter_inappwebview.dart'
;
import
'package:flutter_svg/svg.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:generp/Utils/commonWidgets.dart'
;
import
'package:path_provider/path_provider.dart'
;
import
'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'
;
import
'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'
;
import
'package:url_launcher/url_launcher.dart'
;
import
'package:url_launcher/url_launcher.dart'
;
import
'package:flutter_pdfview/flutter_pdfview.dart'
;
import
'package:flutter_pdfview/flutter_pdfview.dart'
;
...
@@ -17,7 +21,8 @@ import '../../Utils/app_colors.dart';
...
@@ -17,7 +21,8 @@ import '../../Utils/app_colors.dart';
class
Fileviewer
extends
StatefulWidget
{
class
Fileviewer
extends
StatefulWidget
{
final
String
fileName
;
final
String
fileName
;
final
String
fileUrl
;
final
String
fileUrl
;
const
Fileviewer
({
super
.
key
,
required
this
.
fileName
,
required
this
.
fileUrl
});
final
bool
downloadEnable
;
// use this to show download button or not at
const
Fileviewer
({
super
.
key
,
required
this
.
fileName
,
required
this
.
fileUrl
,
required
this
.
downloadEnable
});
@override
@override
State
<
Fileviewer
>
createState
()
=>
_FileviewerState
();
State
<
Fileviewer
>
createState
()
=>
_FileviewerState
();
...
@@ -60,36 +65,70 @@ class _FileviewerState extends State<Fileviewer> {
...
@@ -60,36 +65,70 @@ class _FileviewerState extends State<Fileviewer> {
@override
@override
void
initState
()
{
void
initState
()
{
pullToRefreshController
=
super
.
initState
();
kIsWeb
?
null
// Create pullToRefreshController only for non-web platforms
:
PullToRefreshController
(
if
(!
kIsWeb
)
{
pullToRefreshController
=
PullToRefreshController
(
settings:
pullToRefreshSettings
,
settings:
pullToRefreshSettings
,
onRefresh:
()
async
{
onRefresh:
()
async
{
// Guard: don't run if widget disposed
if
(!
mounted
)
return
;
try
{
if
(
defaultTargetPlatform
==
TargetPlatform
.
android
)
{
if
(
defaultTargetPlatform
==
TargetPlatform
.
android
)
{
webViewController
?.
reload
();
await
webViewController
?.
reload
();
}
else
if
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
)
{
}
else
if
(
defaultTargetPlatform
==
TargetPlatform
.
iOS
)
{
webViewController
?.
load
Url
(
final
currentUrl
=
await
webViewController
?.
get
Url
(
);
urlRequest:
URLRequest
(
if
(
currentUrl
!=
null
)
{
url:
await
webViewController
?.
get
Url
(
),
await
webViewController
?.
load
Url
(
),
urlRequest:
URLRequest
(
url:
currentUrl
),
);
);
}
}
}
}
catch
(
e
)
{
// ignore errors during refresh
}
finally
{
// ensure refresh animation stops even if reload fails
safeEndRefreshing
();
}
},
},
);
);
}
else
{
pullToRefreshController
=
null
;
}
// Initialize photo view controllers
// Initialize photo view controllers
_photoViewController
=
PhotoViewController
();
_photoViewController
=
PhotoViewController
();
_scaleStateController
=
PhotoViewScaleStateController
();
_scaleStateController
=
PhotoViewScaleStateController
();
}
super
.
initState
();
/// Safe helper to end pull-to-refresh only when mounted and controller exists.
void
safeEndRefreshing
()
{
if
(!
mounted
)
return
;
final
ctrl
=
pullToRefreshController
;
if
(
ctrl
!=
null
)
{
try
{
ctrl
.
endRefreshing
();
}
catch
(
e
)
{
// In some rare cases controller may already be disposed — ignore.
}
}
}
}
@override
@override
void
dispose
()
{
void
dispose
()
{
// Dispose photo controllers first
_photoViewController
.
dispose
();
_photoViewController
.
dispose
();
_scaleStateController
.
dispose
();
_scaleStateController
.
dispose
();
// Dispose pullToRefreshController and null it to avoid later use
try
{
pullToRefreshController
?.
dispose
();
pullToRefreshController
?.
dispose
();
}
catch
(
e
)
{
// ignore dispose errors
}
pullToRefreshController
=
null
;
webViewController
=
null
;
super
.
dispose
();
super
.
dispose
();
}
}
...
@@ -97,7 +136,50 @@ class _FileviewerState extends State<Fileviewer> {
...
@@ -97,7 +136,50 @@ class _FileviewerState extends State<Fileviewer> {
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
return
Scaffold
(
resizeToAvoidBottomInset:
true
,
resizeToAvoidBottomInset:
true
,
appBar:
appbarNew
(
context
,
"File Viewer"
,
0xFFFFFFFF
),
appBar:
AppBar
(
backgroundColor:
Color
(
0xFFFFFFFF
),
automaticallyImplyLeading:
false
,
title:
SizedBox
(
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
start
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
children:
[
InkResponse
(
onTap:
()
=>
Navigator
.
pop
(
context
,
true
),
child:
SvgPicture
.
asset
(
"assets/svg/appbar_back_button.svg"
,
height:
25
,
),
),
SizedBox
(
width:
10
),
InkResponse
(
onTap:
()
=>
Navigator
.
pop
(
context
,
true
),
child:
Text
(
"File Viewer"
,
style:
TextStyle
(
fontSize:
16
,
height:
1.1
,
fontFamily:
"JakartaSemiBold"
,
color:
AppColors
.
semi_black
,
),
),
),
Spacer
(),
/// DOWNLOAD BUTTON (NEW)
/// -----------------------------
if
(
widget
.
downloadEnable
)
IconButton
(
icon:
Icon
(
Icons
.
download_rounded
,
color:
AppColors
.
app_blue
),
onPressed:
()
async
{
await
_downloadFile
(
widget
.
fileUrl
,
widget
.
fileName
);
},
),
],
),
),
),
body:
SafeArea
(
body:
SafeArea
(
child:
Center
(
child:
Center
(
child:
fileWidget
(
context
)
child:
fileWidget
(
context
)
...
@@ -106,6 +188,190 @@ class _FileviewerState extends State<Fileviewer> {
...
@@ -106,6 +188,190 @@ class _FileviewerState extends State<Fileviewer> {
);
);
}
}
Future
<
void
>
_downloadFile
(
String
url
,
String
fileName
)
async
{
try
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"Downloading..."
)),
);
final
http
.
Response
response
=
await
http
.
get
(
Uri
.
parse
(
url
));
if
(
response
.
statusCode
==
200
)
{
final
bytes
=
response
.
bodyBytes
;
// Get storage directory
final
directory
=
await
getApplicationDocumentsDirectory
();
final
filePath
=
"
${directory.path}
/
$fileName
"
;
final
file
=
File
(
filePath
);
await
file
.
writeAsBytes
(
bytes
);
// Download success
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"File downloaded successfully
\n
At this:
${directory.path}
"
)),
);
// ASK USER TO OPEN THE DOWNLOADED FILE
// -------------------------------------
showDialog
(
context:
context
,
builder:
(
context
)
{
return
Dialog
(
backgroundColor:
Colors
.
white
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
20
),
),
elevation:
0
,
child:
Container
(
padding:
const
EdgeInsets
.
all
(
24
),
decoration:
BoxDecoration
(
color:
Colors
.
white
,
borderRadius:
BorderRadius
.
circular
(
20
),
boxShadow:
[
BoxShadow
(
color:
Colors
.
black
.
withOpacity
(
0.1
),
blurRadius:
20
,
offset:
const
Offset
(
0
,
4
),
),
],
),
child:
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
// Success Icon
Container
(
width:
60
,
height:
60
,
decoration:
BoxDecoration
(
color:
Colors
.
green
.
withOpacity
(
0.1
),
shape:
BoxShape
.
circle
,
),
child:
const
Icon
(
Icons
.
check_circle_rounded
,
color:
Colors
.
green
,
size:
36
,
),
),
const
SizedBox
(
height:
16
),
// Title
const
Text
(
"Download Complete"
,
style:
TextStyle
(
fontSize:
18
,
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w700
,
color:
Colors
.
black87
,
),
),
const
SizedBox
(
height:
8
),
// Description
Text
(
"Do you want to open the file?"
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
fontSize:
14
,
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w400
,
color:
Colors
.
grey
[
600
],
height:
1.4
,
),
),
const
SizedBox
(
height:
24
),
// Buttons Row
Row
(
children:
[
// Cancel Button
Expanded
(
child:
OutlinedButton
(
onPressed:
()
=>
Navigator
.
pop
(
context
),
style:
OutlinedButton
.
styleFrom
(
backgroundColor:
Colors
.
transparent
,
foregroundColor:
Colors
.
grey
[
600
],
side:
BorderSide
(
color:
Colors
.
grey
[
300
]!,
width:
1.5
,
),
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
12
),
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
elevation:
0
,
),
child:
Text
(
"Cancel"
,
style:
TextStyle
(
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w600
,
fontSize:
14
,
color:
Colors
.
grey
[
700
],
),
),
),
),
const
SizedBox
(
width:
12
),
// Open Button
Expanded
(
child:
ElevatedButton
(
onPressed:
()
{
Navigator
.
pop
(
context
);
OpenFilex
.
open
(
filePath
);
},
style:
ElevatedButton
.
styleFrom
(
backgroundColor:
const
Color
(
0xFF008CDE
),
foregroundColor:
Colors
.
white
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
12
),
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
14
),
elevation:
0
,
shadowColor:
Colors
.
transparent
,
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
const
Icon
(
Icons
.
open_in_new
,
size:
18
),
const
SizedBox
(
width:
6
),
Text
(
"Open"
,
style:
TextStyle
(
fontFamily:
"Plus Jakarta Sans"
,
fontWeight:
FontWeight
.
w600
,
fontSize:
14
,
color:
Colors
.
white
,
),
),
],
),
),
),
],
),
],
),
),
);
},
);
}
else
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"Failed to download file"
)),
);
}
}
catch
(
e
)
{
ScaffoldMessenger
.
of
(
context
).
showSnackBar
(
SnackBar
(
content:
Text
(
"Error:
$e
"
)),
);
}
}
Widget
fileWidget
(
BuildContext
context
)
{
Widget
fileWidget
(
BuildContext
context
)
{
final
extension
=
getFileExtension
(
widget
.
fileName
);
final
extension
=
getFileExtension
(
widget
.
fileName
);
switch
(
extension
)
{
switch
(
extension
)
{
...
...
lib/screens/finance/PaymentRequestionListDetails.dart
View file @
d2939607
...
@@ -350,6 +350,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -350,6 +350,7 @@ class _PaymentrequestionlistdetailsState
reqDet
reqDet
.
attachmentDirFilePath
??
.
attachmentDirFilePath
??
""
,
""
,
downloadEnable:
true
,
),
),
),
),
);
);
...
@@ -920,7 +921,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -920,7 +921,7 @@ class _PaymentrequestionlistdetailsState
textAlign:
TextAlign
.
center
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
style:
TextStyle
(
fontFamily:
"JakartaMedium"
,
fontFamily:
"JakartaMedium"
,
fontSize:
1
4
,
fontSize:
1
3
,
color:
getTextColor
(
reqDet
.
status
),
color:
getTextColor
(
reqDet
.
status
),
),
),
),
),
...
@@ -1011,6 +1012,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -1011,6 +1012,7 @@ class _PaymentrequestionlistdetailsState
reqDet
reqDet
.
attachmentDirFilePath
??
.
attachmentDirFilePath
??
""
,
""
,
downloadEnable:
true
,
),
),
),
),
);
);
...
@@ -1092,11 +1094,11 @@ class _PaymentrequestionlistdetailsState
...
@@ -1092,11 +1094,11 @@ class _PaymentrequestionlistdetailsState
decoration:
BoxDecoration
(
color:
Colors
.
white
),
decoration:
BoxDecoration
(
color:
Colors
.
white
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
10
),
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
10
),
alignment:
Alignment
.
bottomCenter
,
alignment:
Alignment
.
bottomCenter
,
height:
8
0
,
height:
7
8
,
child:
Container
(
child:
Container
(
margin:
EdgeInsets
.
only
(
bottom:
10
),
margin:
EdgeInsets
.
only
(
bottom:
10
),
alignment:
Alignment
.
center
,
alignment:
Alignment
.
center
,
height:
4
5
,
height:
4
2
,
child:
Row
(
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
children:
[
...
@@ -1131,7 +1133,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -1131,7 +1133,7 @@ class _PaymentrequestionlistdetailsState
"Reject"
,
"Reject"
,
style:
TextStyle
(
style:
TextStyle
(
color:
AppColors
.
semi_black
,
color:
AppColors
.
semi_black
,
fontSize:
1
4
,
fontSize:
1
2
,
),
),
),
),
),
),
...
@@ -1140,7 +1142,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -1140,7 +1142,7 @@ class _PaymentrequestionlistdetailsState
),
),
),
),
),
),
SizedBox
(
width:
6
),
SizedBox
(
width:
4
),
if
([
if
([
"apr_lvl1"
,
"apr_lvl1"
,
...
@@ -1150,7 +1152,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -1150,7 +1152,7 @@ class _PaymentrequestionlistdetailsState
SvgPicture
.
asset
(
SvgPicture
.
asset
(
"assets/svg/crm/vertical_line_ic.svg"
,
"assets/svg/crm/vertical_line_ic.svg"
,
),
),
SizedBox
(
width:
6
),
SizedBox
(
width:
4
),
Expanded
(
Expanded
(
child:
InkResponse
(
child:
InkResponse
(
onTap:
()
{
onTap:
()
{
...
@@ -1186,7 +1188,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -1186,7 +1188,7 @@ class _PaymentrequestionlistdetailsState
"Approve"
,
"Approve"
,
style:
TextStyle
(
style:
TextStyle
(
color:
AppColors
.
semi_black
,
color:
AppColors
.
semi_black
,
fontSize:
1
4
,
fontSize:
1
2
,
),
),
),
),
),
),
...
@@ -1195,12 +1197,12 @@ class _PaymentrequestionlistdetailsState
...
@@ -1195,12 +1197,12 @@ class _PaymentrequestionlistdetailsState
),
),
),
),
),
),
SizedBox
(
width:
6
),
SizedBox
(
width:
4
),
]
else
if
(
widget
.
mode
==
"process"
)
...[
]
else
if
(
widget
.
mode
==
"process"
)
...[
SvgPicture
.
asset
(
SvgPicture
.
asset
(
"assets/svg/crm/vertical_line_ic.svg"
,
"assets/svg/crm/vertical_line_ic.svg"
,
),
),
SizedBox
(
width:
6
),
SizedBox
(
width:
5
),
Expanded
(
Expanded
(
child:
InkResponse
(
child:
InkResponse
(
onTap:
()
{
onTap:
()
{
...
@@ -1231,13 +1233,13 @@ class _PaymentrequestionlistdetailsState
...
@@ -1231,13 +1233,13 @@ class _PaymentrequestionlistdetailsState
SvgPicture
.
asset
(
SvgPicture
.
asset
(
"assets/svg/finance/level_add_payment_ic.svg"
,
"assets/svg/finance/level_add_payment_ic.svg"
,
),
),
SizedBox
(
width:
5
),
SizedBox
(
width:
2
),
Center
(
Center
(
child:
Text
(
child:
Text
(
"Add Payment"
,
"Add Payment"
,
style:
TextStyle
(
style:
TextStyle
(
color:
AppColors
.
semi_black
,
color:
AppColors
.
semi_black
,
fontSize:
1
4
,
fontSize:
1
2
,
),
),
),
),
),
),
...
@@ -1280,7 +1282,7 @@ class _PaymentrequestionlistdetailsState
...
@@ -1280,7 +1282,7 @@ class _PaymentrequestionlistdetailsState
"Edit Amount"
,
"Edit Amount"
,
style:
TextStyle
(
style:
TextStyle
(
color:
AppColors
.
semi_black
,
color:
AppColors
.
semi_black
,
fontSize:
1
4
,
fontSize:
1
2
,
),
),
),
),
),
),
...
...
lib/screens/finance/financeDashboard.dart
View file @
d2939607
...
@@ -487,11 +487,11 @@ class _FinancedashboardState extends State<Financedashboard> {
...
@@ -487,11 +487,11 @@ class _FinancedashboardState extends State<Financedashboard> {
},
},
child:
Container
(
child:
Container
(
padding:
EdgeInsets
.
symmetric
(
padding:
EdgeInsets
.
symmetric
(
vertical:
5
,
vertical:
4.6
,
horizontal:
15
,
horizontal:
15
,
),
),
margin:
EdgeInsets
.
symmetric
(
margin:
EdgeInsets
.
symmetric
(
vertical:
7
,
vertical:
5
,
horizontal:
5
,
horizontal:
5
,
),
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
...
...
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment