Commit b38d986d authored by Sai Srinivas's avatar Sai Srinivas
Browse files

23-07-2025 By Sai Srinivas

CRM Lead Details, Generate Quotation & Followup and Prospect List.
parent c0252747
...@@ -328,6 +328,7 @@ class LeadProducts { ...@@ -328,6 +328,7 @@ class LeadProducts {
String? productId; String? productId;
String? qty; String? qty;
String? price; String? price;
String? prodTotalPrice;
String? date; String? date;
String? isDel; String? isDel;
String? isExists; String? isExists;
...@@ -341,6 +342,7 @@ class LeadProducts { ...@@ -341,6 +342,7 @@ class LeadProducts {
this.productId, this.productId,
this.qty, this.qty,
this.price, this.price,
this.prodTotalPrice,
this.date, this.date,
this.isDel, this.isDel,
this.isExists, this.isExists,
...@@ -354,6 +356,7 @@ class LeadProducts { ...@@ -354,6 +356,7 @@ class LeadProducts {
productId = json['product_id']; productId = json['product_id'];
qty = json['qty']; qty = json['qty'];
price = json['price']; price = json['price'];
prodTotalPrice = json['prod_total_price'];
date = json['date']; date = json['date'];
isDel = json['is_del']; isDel = json['is_del'];
isExists = json['is_exists']; isExists = json['is_exists'];
...@@ -369,6 +372,7 @@ class LeadProducts { ...@@ -369,6 +372,7 @@ class LeadProducts {
data['product_id'] = this.productId; data['product_id'] = this.productId;
data['qty'] = this.qty; data['qty'] = this.qty;
data['price'] = this.price; data['price'] = this.price;
data['prod_total_price'] = this.prodTotalPrice;
data['date'] = this.date; data['date'] = this.date;
data['is_del'] = this.isDel; data['is_del'] = this.isDel;
data['is_exists'] = this.isExists; data['is_exists'] = this.isExists;
......
class crmAddFollowUpResponse {
String? redirectTo;
String? error;
String? message;
int? sessionExists;
crmAddFollowUpResponse(
{this.redirectTo, this.error, this.message, this.sessionExists});
crmAddFollowUpResponse.fromJson(Map<String, dynamic> json) {
redirectTo = json['redirect_to'];
error = json['error'];
message = json['message'];
sessionExists = json['session_exists'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['redirect_to'] = this.redirectTo;
data['error'] = this.error;
data['message'] = this.message;
data['session_exists'] = this.sessionExists;
return data;
}
}
class crmDashboardResponse { class crmDashboardResponse {
Hotleads? hotleads; Hotleads? hotleads;
Hotleads? pendingTasks;
Hotleads? coldleads; Hotleads? coldleads;
Hotleads? warmleads; Hotleads? warmleads;
Hotleads? totalleads; Hotleads? totalleads;
Hotleads? openleads;
Hotleads? visits;
Hotleads? calls;
Hotleads? quote;
Hotleads? orderlost; Hotleads? orderlost;
Hotleads? norequirement; Hotleads? norequirement;
Hotleads? openEnquiries; Hotleads? openEnquiries;
List<NearbyLeads>? nearbyLeads;
String? error; String? error;
String? message; String? message;
int? sessionExists;
crmDashboardResponse( crmDashboardResponse(
{this.hotleads, {this.hotleads,
this.pendingTasks,
this.coldleads, this.coldleads,
this.warmleads, this.warmleads,
this.totalleads, this.totalleads,
this.openleads,
this.visits,
this.calls,
this.quote,
this.orderlost, this.orderlost,
this.norequirement, this.norequirement,
this.openEnquiries, this.openEnquiries,
this.nearbyLeads,
this.error, this.error,
this.message}); this.message,
this.sessionExists});
crmDashboardResponse.fromJson(Map<String, dynamic> json) { crmDashboardResponse.fromJson(Map<String, dynamic> json) {
hotleads = json['hotleads'] != null hotleads = json['hotleads'] != null
? new Hotleads.fromJson(json['hotleads']) ? new Hotleads.fromJson(json['hotleads'])
: null; : null;
pendingTasks = json['pending_tasks'] != null
? new Hotleads.fromJson(json['pending_tasks'])
: null;
coldleads = json['coldleads'] != null coldleads = json['coldleads'] != null
? new Hotleads.fromJson(json['coldleads']) ? new Hotleads.fromJson(json['coldleads'])
: null; : null;
...@@ -33,6 +50,13 @@ class crmDashboardResponse { ...@@ -33,6 +50,13 @@ class crmDashboardResponse {
totalleads = json['totalleads'] != null totalleads = json['totalleads'] != null
? new Hotleads.fromJson(json['totalleads']) ? new Hotleads.fromJson(json['totalleads'])
: null; : null;
openleads = json['openleads'] != null
? new Hotleads.fromJson(json['openleads'])
: null;
visits =
json['visits'] != null ? new Hotleads.fromJson(json['visits']) : null;
calls = json['calls'] != null ? new Hotleads.fromJson(json['calls']) : null;
quote = json['quote'] != null ? new Hotleads.fromJson(json['quote']) : null;
orderlost = json['orderlost'] != null orderlost = json['orderlost'] != null
? new Hotleads.fromJson(json['orderlost']) ? new Hotleads.fromJson(json['orderlost'])
: null; : null;
...@@ -42,8 +66,15 @@ class crmDashboardResponse { ...@@ -42,8 +66,15 @@ class crmDashboardResponse {
openEnquiries = json['open_enquiries'] != null openEnquiries = json['open_enquiries'] != null
? new Hotleads.fromJson(json['open_enquiries']) ? new Hotleads.fromJson(json['open_enquiries'])
: null; : null;
if (json['nearby_leads'] != null) {
nearbyLeads = <NearbyLeads>[];
json['nearby_leads'].forEach((v) {
nearbyLeads!.add(new NearbyLeads.fromJson(v));
});
}
error = json['error']; error = json['error'];
message = json['message']; message = json['message'];
sessionExists = json['session_exists'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
...@@ -51,6 +82,9 @@ class crmDashboardResponse { ...@@ -51,6 +82,9 @@ class crmDashboardResponse {
if (this.hotleads != null) { if (this.hotleads != null) {
data['hotleads'] = this.hotleads!.toJson(); data['hotleads'] = this.hotleads!.toJson();
} }
if (this.pendingTasks != null) {
data['pending_tasks'] = this.pendingTasks!.toJson();
}
if (this.coldleads != null) { if (this.coldleads != null) {
data['coldleads'] = this.coldleads!.toJson(); data['coldleads'] = this.coldleads!.toJson();
} }
...@@ -60,6 +94,18 @@ class crmDashboardResponse { ...@@ -60,6 +94,18 @@ class crmDashboardResponse {
if (this.totalleads != null) { if (this.totalleads != null) {
data['totalleads'] = this.totalleads!.toJson(); data['totalleads'] = this.totalleads!.toJson();
} }
if (this.openleads != null) {
data['openleads'] = this.openleads!.toJson();
}
if (this.visits != null) {
data['visits'] = this.visits!.toJson();
}
if (this.calls != null) {
data['calls'] = this.calls!.toJson();
}
if (this.quote != null) {
data['quote'] = this.quote!.toJson();
}
if (this.orderlost != null) { if (this.orderlost != null) {
data['orderlost'] = this.orderlost!.toJson(); data['orderlost'] = this.orderlost!.toJson();
} }
...@@ -69,8 +115,12 @@ class crmDashboardResponse { ...@@ -69,8 +115,12 @@ class crmDashboardResponse {
if (this.openEnquiries != null) { if (this.openEnquiries != null) {
data['open_enquiries'] = this.openEnquiries!.toJson(); data['open_enquiries'] = this.openEnquiries!.toJson();
} }
if (this.nearbyLeads != null) {
data['nearby_leads'] = this.nearbyLeads!.map((v) => v.toJson()).toList();
}
data['error'] = this.error; data['error'] = this.error;
data['message'] = this.message; data['message'] = this.message;
data['session_exists'] = this.sessionExists;
return data; return data;
} }
} }
...@@ -124,3 +174,116 @@ class Filter { ...@@ -124,3 +174,116 @@ class Filter {
return data; return data;
} }
} }
class NearbyLeads {
String? id;
String? ownerId;
String? accId;
String? accManagerId;
String? status;
String? openStatus;
String? date;
String? closeDate;
String? closereason;
String? competitor;
String? orderGainId;
String? loc;
String? isExists;
String? createdDatetime;
String? updatedDatetime;
String? followupFunction;
String? name;
String? product;
String? contName;
String? address;
String? mob1;
String? mob2;
String? tel;
String? email;
String? distance;
NearbyLeads(
{this.id,
this.ownerId,
this.accId,
this.accManagerId,
this.status,
this.openStatus,
this.date,
this.closeDate,
this.closereason,
this.competitor,
this.orderGainId,
this.loc,
this.isExists,
this.createdDatetime,
this.updatedDatetime,
this.followupFunction,
this.name,
this.product,
this.contName,
this.address,
this.mob1,
this.mob2,
this.tel,
this.email,
this.distance});
NearbyLeads.fromJson(Map<String, dynamic> json) {
id = json['id'];
ownerId = json['owner_id'];
accId = json['acc_id'];
accManagerId = json['acc_manager_id'];
status = json['status'];
openStatus = json['open_status'];
date = json['date'];
closeDate = json['close_date'];
closereason = json['closereason'];
competitor = json['competitor'];
orderGainId = json['order_gain_id'];
loc = json['loc'];
isExists = json['is_exists'];
createdDatetime = json['created_datetime'];
updatedDatetime = json['updated_datetime'];
followupFunction = json['followup_function'];
name = json['name'];
product = json['product'];
contName = json['cont_name'];
address = json['address'];
mob1 = json['mob1'];
mob2 = json['mob2'];
tel = json['tel'];
email = json['email'];
distance = json['distance'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['owner_id'] = this.ownerId;
data['acc_id'] = this.accId;
data['acc_manager_id'] = this.accManagerId;
data['status'] = this.status;
data['open_status'] = this.openStatus;
data['date'] = this.date;
data['close_date'] = this.closeDate;
data['closereason'] = this.closereason;
data['competitor'] = this.competitor;
data['order_gain_id'] = this.orderGainId;
data['loc'] = this.loc;
data['is_exists'] = this.isExists;
data['created_datetime'] = this.createdDatetime;
data['updated_datetime'] = this.updatedDatetime;
data['followup_function'] = this.followupFunction;
data['name'] = this.name;
data['product'] = this.product;
data['cont_name'] = this.contName;
data['address'] = this.address;
data['mob1'] = this.mob1;
data['mob2'] = this.mob2;
data['tel'] = this.tel;
data['email'] = this.email;
data['distance'] = this.distance;
return data;
}
}
...@@ -3,9 +3,10 @@ class crmLeadDetailsGenerateQuotationViewResponse { ...@@ -3,9 +3,10 @@ class crmLeadDetailsGenerateQuotationViewResponse {
List<LeadProducts>? leadProducts; List<LeadProducts>? leadProducts;
String? error; String? error;
String? message; String? message;
int? sessionExists;
crmLeadDetailsGenerateQuotationViewResponse( crmLeadDetailsGenerateQuotationViewResponse(
{this.quoteDetails, this.leadProducts, this.error, this.message}); {this.quoteDetails, this.leadProducts, this.error, this.message,this.sessionExists});
crmLeadDetailsGenerateQuotationViewResponse.fromJson( crmLeadDetailsGenerateQuotationViewResponse.fromJson(
Map<String, dynamic> json) { Map<String, dynamic> json) {
...@@ -20,6 +21,7 @@ class crmLeadDetailsGenerateQuotationViewResponse { ...@@ -20,6 +21,7 @@ class crmLeadDetailsGenerateQuotationViewResponse {
} }
error = json['error']; error = json['error'];
message = json['message']; message = json['message'];
sessionExists = json['session_exists'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
...@@ -33,6 +35,7 @@ class crmLeadDetailsGenerateQuotationViewResponse { ...@@ -33,6 +35,7 @@ class crmLeadDetailsGenerateQuotationViewResponse {
} }
data['error'] = this.error; data['error'] = this.error;
data['message'] = this.message; data['message'] = this.message;
data['session_exists'] = this.sessionExists;
return data; return data;
} }
} }
...@@ -84,6 +87,7 @@ class LeadProducts { ...@@ -84,6 +87,7 @@ class LeadProducts {
String? productId; String? productId;
String? qty; String? qty;
String? price; String? price;
String? prodTotalPrice;
String? date; String? date;
String? isDel; String? isDel;
String? isExists; String? isExists;
...@@ -97,6 +101,7 @@ class LeadProducts { ...@@ -97,6 +101,7 @@ class LeadProducts {
this.productId, this.productId,
this.qty, this.qty,
this.price, this.price,
this.prodTotalPrice,
this.date, this.date,
this.isDel, this.isDel,
this.isExists, this.isExists,
...@@ -110,6 +115,7 @@ class LeadProducts { ...@@ -110,6 +115,7 @@ class LeadProducts {
productId = json['product_id']; productId = json['product_id'];
qty = json['qty']; qty = json['qty'];
price = json['price']; price = json['price'];
prodTotalPrice = json['prod_total_price'];
date = json['date']; date = json['date'];
isDel = json['is_del']; isDel = json['is_del'];
isExists = json['is_exists']; isExists = json['is_exists'];
...@@ -125,6 +131,7 @@ class LeadProducts { ...@@ -125,6 +131,7 @@ class LeadProducts {
data['product_id'] = this.productId; data['product_id'] = this.productId;
data['qty'] = this.qty; data['qty'] = this.qty;
data['price'] = this.price; data['price'] = this.price;
data['prod_total_price'] = this.prodTotalPrice;
data['date'] = this.date; data['date'] = this.date;
data['is_del'] = this.isDel; data['is_del'] = this.isDel;
data['is_exists'] = this.isExists; data['is_exists'] = this.isExists;
......
...@@ -3,6 +3,9 @@ import 'package:flutter/foundation.dart'; ...@@ -3,6 +3,9 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:generp/Models/crmModels/crmDashboardResponse.dart'; import 'package:generp/Models/crmModels/crmDashboardResponse.dart';
import 'package:generp/Utils/app_colors.dart'; import 'package:generp/Utils/app_colors.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geolocator/geolocator.dart' as geo_location;
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
...@@ -13,37 +16,20 @@ import '../../services/api_calling.dart'; ...@@ -13,37 +16,20 @@ import '../../services/api_calling.dart';
import '../HomeScreenNotifier.dart'; import '../HomeScreenNotifier.dart';
class Crmdashboardprovider extends ChangeNotifier { class Crmdashboardprovider extends ChangeNotifier {
TextEditingController nextAppointmentDateController = TextEditingController(); String _googleApikey = "AIzaSyBGzvgMMKwPBAANTwaoRsAnrCpiWCj8wVs";
TextEditingController searchController = TextEditingController(); TextEditingController searchController = TextEditingController();
List<PagesAccessible> _accessPages = []; List<PagesAccessible> _accessPages = [];
List<PagesAccessible> get accessPages => _accessPages; List<PagesAccessible> get accessPages => _accessPages;
List<PendingTasks> _pendingTasks = []; List<PendingTasks> _pendingTasksList = [];
List<PendingTasks> get pendingTasksLists => _pendingTasks; List<PendingTasks> get pendingTasksLists => _pendingTasksList;
List<Accounts> _accountsList = []; List<Accounts> _accountsList = [];
List<Leads> _leadsList = []; List<Leads> _leadsList = [];
List<Enquires> _enquiresList = []; List<Enquires> _enquiresList = [];
TimeOfDay _selectedTime = TimeOfDay.now();
String _formattedTime = "";
String? _selectedFollowupType; LatLng? currentLocationLatLng;
String? _selectedLeadStatus; String latlongs = "";
String? _nextAppointmentStatus;
String? _selectNextAppointmentType;
DateTime? _date;
String? _formattedDate;
String? _dateError;
TimeOfDay get selectedTime => _selectedTime;
String get formattedTime => _formattedTime;
String? get selectedFollowupType => _selectedFollowupType;
String? get selectedLeadStatus => _selectedLeadStatus;
String? get nextAppointmentStatus => _nextAppointmentStatus;
String? get selectNextAppointmentType => _selectNextAppointmentType;
List<Accounts> get accountsList => _accountsList; List<Accounts> get accountsList => _accountsList;
...@@ -51,24 +37,54 @@ class Crmdashboardprovider extends ChangeNotifier { ...@@ -51,24 +37,54 @@ class Crmdashboardprovider extends ChangeNotifier {
List<Enquires> get enquiresList => _enquiresList; List<Enquires> get enquiresList => _enquiresList;
List<NearbyLeads> _nearByLeads = [];
List<NearbyLeads> get nearByLeads => _nearByLeads;
Hotleads _hotleads = Hotleads(); Hotleads _hotleads = Hotleads();
Hotleads get hotleads => _hotleads; Hotleads get hotleads => _hotleads;
Hotleads _pendingTasks = Hotleads();
Hotleads get pendingTasks => _pendingTasks;
Hotleads _coldleads = Hotleads(); Hotleads _coldleads = Hotleads();
Hotleads get coldleads => _coldleads; Hotleads get coldleads => _coldleads;
Hotleads _warmleads = Hotleads(); Hotleads _warmleads = Hotleads();
Hotleads get warmleads => _warmleads; Hotleads get warmleads => _warmleads;
Hotleads _totalleads = Hotleads(); Hotleads _totalleads = Hotleads();
Hotleads get totalleads => _totalleads; Hotleads get totalleads => _totalleads;
Hotleads _openleads = Hotleads();
Hotleads get openleads => _openleads;
Hotleads _visits = Hotleads();
Hotleads get visits => _visits;
Hotleads _calls = Hotleads();
Hotleads get calls => _calls;
Hotleads _quote = Hotleads();
Hotleads get quote => _quote;
Hotleads _orderlost = Hotleads(); Hotleads _orderlost = Hotleads();
Hotleads get orderlost => _orderlost; Hotleads get orderlost => _orderlost;
Hotleads _norequirement = Hotleads(); Hotleads _norequirement = Hotleads();
Hotleads get norequirement => _norequirement; Hotleads get norequirement => _norequirement;
Hotleads _openEnquiries = Hotleads(); Hotleads _openEnquiries = Hotleads();
Hotleads get openEnquiries => _openEnquiries; Hotleads get openEnquiries => _openEnquiries;
...@@ -77,25 +93,7 @@ class Crmdashboardprovider extends ChangeNotifier { ...@@ -77,25 +93,7 @@ class Crmdashboardprovider extends ChangeNotifier {
List<Hotleads> get allLeads => _allLeads; List<Hotleads> get allLeads => _allLeads;
set selectedFollowupType(String? value){
_selectedFollowupType = value;
notifyListeners();
}
set selectedLeadStatus(String? value){
_selectedLeadStatus = value;
notifyListeners();
}
set nextAppointmentStatus(String? value){
_nextAppointmentStatus = value;
notifyListeners();
}
set selectNextAppointmentType(String? value){
_selectNextAppointmentType = value;
notifyListeners();
}
Future<void> accessPagesAPIFunction(context) async { Future<void> accessPagesAPIFunction(context) async {
try { try {
...@@ -116,47 +114,82 @@ class Crmdashboardprovider extends ChangeNotifier { ...@@ -116,47 +114,82 @@ class Crmdashboardprovider extends ChangeNotifier {
} catch (e, s) {} } catch (e, s) {}
} }
Future<void> crmDashboardAPIFunction( Future<void> getCurrentLocation(context) async {
context, try {
mode, Position position = await Geolocator.getCurrentPosition(
from, desiredAccuracy: geo_location.LocationAccuracy.high,
to, );
teamemployee, currentLocationLatLng = LatLng(position.latitude, position.longitude);
) async { print("Current Loc: ${currentLocationLatLng}");
latlongs = '${position.latitude},${position.longitude}';
print("latlongs : ${latlongs}");
notifyListeners();
crmDashboardAPIFunction(context);
} catch (e) {
print("Error getting current location: $e");
}
}
Future<void> crmDashboardAPIFunction(context) async {
try { try {
var HomeProv = Provider.of<HomescreenNotifier>(context, listen: false); var HomeProv = Provider.of<HomescreenNotifier>(context, listen: false);
final data = await ApiCalling.crmDashboardAPI( final data = await ApiCalling.crmDashboardAPI(
HomeProv.empId, HomeProv.empId,
HomeProv.session, HomeProv.session,
mode, latlongs,
from,
to,
teamemployee,
); );
if (data != null) { if (data != null) {
if (data.error == "0") { if (data.error == "0") {
_hotleads = data.hotleads!; _hotleads = data.hotleads!;
_pendingTasks = data.pendingTasks!;
_coldleads = data.coldleads!; _coldleads = data.coldleads!;
_warmleads = data.warmleads!; _warmleads = data.warmleads!;
_totalleads = data.totalleads!; _totalleads = data.totalleads!;
_openleads = data.openleads!;
_visits = data.visits!;
_calls = data.calls!;
_quote = data.quote!;
_orderlost = data.orderlost!; _orderlost = data.orderlost!;
_norequirement = data.norequirement!; _norequirement = data.norequirement!;
_openEnquiries = data.openEnquiries!; _openEnquiries = data.openEnquiries!;
_allLeads = [ _allLeads = [
_openleads,
_quote,
_pendingTasks,
_visits,
_calls,
_hotleads, _hotleads,
_coldleads, _coldleads,
_warmleads, _warmleads,
_totalleads,
_orderlost,
_norequirement,
_openEnquiries,
]; ];
_nearByLeads = data.nearbyLeads!;
notifyListeners(); notifyListeners();
} }
} }
} catch (e, s) {} } catch (e, s) {}
} }
String getStaticMapUrl(double lat, double lng) {
const apiKey = 'YOUR_GOOGLE_MAPS_API_KEY';
const zoom = 15;
const size = '400x400';
return 'https://maps.googleapis.com/maps/api/staticmap?center=$lat,$lng&zoom=$zoom&size=$size&key=$_googleApikey';
}
String getSimpleOSMImage(double lat, double lng) {
final zoom = 15;
//https://maps.googleapis.com/maps/api/staticmap?center=15.4919328,80.0492584&zoom=15&size=400x400
return 'https://static-maps.yandex.ru/1.x/?ll=$lng,$lat&z=$zoom&size=400,400&l=map&pt=$lng,$lat,pm2rdm';
}
({double lat, double lng}) parseLocation(String loc) {
final parts = loc.split(',');
return (
lat: double.parse(parts[0].trim()),
lng: double.parse(parts[1].trim()),
);
}
Future<void> crmPendingTasksAPIFunction(context) async { Future<void> crmPendingTasksAPIFunction(context) async {
try { try {
var HomeProv = Provider.of<HomescreenNotifier>(context, listen: false); var HomeProv = Provider.of<HomescreenNotifier>(context, listen: false);
...@@ -166,7 +199,7 @@ class Crmdashboardprovider extends ChangeNotifier { ...@@ -166,7 +199,7 @@ class Crmdashboardprovider extends ChangeNotifier {
); );
if (data != null) { if (data != null) {
if (data.error == "0") { if (data.error == "0") {
_pendingTasks = data.pendingTasks!; _pendingTasksList = data.pendingTasks!;
notifyListeners(); notifyListeners();
} }
} }
...@@ -192,117 +225,4 @@ class Crmdashboardprovider extends ChangeNotifier { ...@@ -192,117 +225,4 @@ class Crmdashboardprovider extends ChangeNotifier {
} catch (e, s) {} } catch (e, s) {}
} }
set formattedDate(String? value) {
_formattedDate = value;
nextAppointmentDateController.text = _formattedDate!;
_dateError = null;
notifyListeners();
}
set dateError(value){
_dateError = value;
notifyListeners();
}
void setDate(DateTime newDate) {
_date = newDate;
_formattedDate = DateFormat('yyyy-MM-dd').format(newDate);
nextAppointmentDateController.text = _formattedDate!;
_dateError = null;
notifyListeners();
}
Future<void> selectTime(BuildContext context) async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: _selectedTime,
);
if (picked != null && picked != _selectedTime) _selectedTime = picked;
_formattedTime =
_selectedTime.hour.toString() + ":" + _selectedTime.minute.toString();
notifyListeners();
}
String formatTime(int hour, int minute) {
String period = (hour >= 12) ? 'pm' : 'am';
if (hour == 0) {
hour = 12;
} else if (hour > 12) {
hour -= 12;
}
String formattedHour = (hour < 10) ? '0$hour' : '$hour';
String formattedMinute = (minute < 10) ? '0$minute' : '$minute';
print("formattedTime: $formattedHour:$formattedMinute $period");
return '$formattedHour:$formattedMinute $period';
}
void showDatePickerDialog(BuildContext context) {
showCupertinoModalPopup<void>(
context: context,
builder:
(BuildContext context) => Container(
height: 216,
padding: const EdgeInsets.only(top: 6.0),
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
color: CupertinoColors.systemBackground.resolveFrom(context),
child: SafeArea(
top: false,
child: Column(
children: [
Expanded(
flex: 1,
child: SizedBox(
height: 40,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CupertinoButton(
child: Text(
'Cancel',
style: TextStyle(fontFamily: "JakartaMedium",color: AppColors.app_blue),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
'Done',
style: TextStyle(fontFamily: "JakartaMedium",color: AppColors.app_blue),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
),
Expanded(
flex: 3,
child: CupertinoDatePicker(
dateOrder: DatePickerDateOrder.dmy,
initialDateTime: _date ?? DateTime.now(),
mode: CupertinoDatePickerMode.date,
use24hFormat: true,
showDayOfWeek: true,
onDateTimeChanged: (DateTime newDate) {
setDate(newDate);
},
),
),
],
),
),
),
);
}
} }
...@@ -6,6 +6,7 @@ import 'package:flutter/services.dart'; ...@@ -6,6 +6,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_download_manager/flutter_download_manager.dart'; import 'package:flutter_download_manager/flutter_download_manager.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:generp/Models/crmModels/crmLeadDetailsGenerateQuotationViewResponse.dart'; import 'package:generp/Models/crmModels/crmLeadDetailsGenerateQuotationViewResponse.dart';
import 'package:generp/screens/LoginScreen.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
...@@ -18,11 +19,15 @@ import '../HomeScreenNotifier.dart'; ...@@ -18,11 +19,15 @@ import '../HomeScreenNotifier.dart';
class Crmgeneratequotationprovider extends ChangeNotifier { class Crmgeneratequotationprovider extends ChangeNotifier {
final FlutterLocalNotificationsPlugin _notificationsPlugin = final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin(); FlutterLocalNotificationsPlugin();
static const platform = MethodChannel('in.webgrid.generp/download'); static const platform = MethodChannel('in.webgrid.generp/download');
final GlobalKey webViewKey = GlobalKey(); final GlobalKey webViewKey = GlobalKey();
var dl = DownloadManager(); var dl = DownloadManager();
TextEditingController addEditProductPriceController = TextEditingController();
TextEditingController addEditQuantityController = TextEditingController();
TextEditingController addEditTotalAmountController = TextEditingController();
TextEditingController mailIdController = TextEditingController(); TextEditingController mailIdController = TextEditingController();
TextEditingController mobileController = TextEditingController(); TextEditingController mobileController = TextEditingController();
TextEditingController subjectsController = TextEditingController(); TextEditingController subjectsController = TextEditingController();
...@@ -30,7 +35,14 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -30,7 +35,14 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
TextEditingController SpecialNoteController = TextEditingController(); TextEditingController SpecialNoteController = TextEditingController();
TextEditingController forController = TextEditingController(); TextEditingController forController = TextEditingController();
TextEditingController paymentTermsController = TextEditingController(); TextEditingController paymentTermsController = TextEditingController();
List<Map<String, dynamic>> _productRows = []; // For backend
List<Map<String, dynamic>> get productRows => _productRows;
set productRows(value) {
_productRows = value;
notifyListeners();
}
String? mailIdError = ""; String? mailIdError = "";
String? mobileError = ""; String? mobileError = "";
...@@ -45,6 +57,9 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -45,6 +57,9 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
bool _isLoading = true; bool _isLoading = true;
String? _quotationFilePath; String? _quotationFilePath;
LeadProducts? _selectedLeadProducts; LeadProducts? _selectedLeadProducts;
String? _selectedAddEditLeadProductId;
String? _selectedAddEditLeadProductName;
List<TextEditingController> editProductPriceControllers = []; List<TextEditingController> editProductPriceControllers = [];
List<TextEditingController> editQuantityControllers = []; List<TextEditingController> editQuantityControllers = [];
List<TextEditingController> editTotalAmountControllers = []; List<TextEditingController> editTotalAmountControllers = [];
...@@ -58,21 +73,88 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -58,21 +73,88 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
QuoteDetails get quoteDetails => _quoteDetails; QuoteDetails get quoteDetails => _quoteDetails;
List<LeadProducts> get leadProductsList => _leadProductsList; List<LeadProducts> get leadProductsList => _leadProductsList;
set leadProductsList(List<LeadProducts> value) {
_leadProductsList = value;
notifyListeners();
}
LeadProducts? get selectedLeadProducts => _selectedLeadProducts; LeadProducts? get selectedLeadProducts => _selectedLeadProducts;
bool get isLoading => _isLoading; bool get isLoading => _isLoading;
List<String?> get selectedProductIds => _selectedProductIds; List<String?> get selectedProductIds => _selectedProductIds;
String? get selectedAddEditLeadProductId => _selectedAddEditLeadProductId;
String? get selectedAddEditLeadProductName => _selectedAddEditLeadProductName;
List<String?> get selectedValues => _selectedValues; List<String?> get selectedValues => _selectedValues;
bool get submitLoading => _submitLoading; bool get submitLoading => _submitLoading;
set selectedLeadProducts(LeadProducts? value) { set selectedLeadProducts(LeadProducts? value) {
_selectedLeadProducts = value; _selectedLeadProducts = value;
_selectedAddEditLeadProductId = value?.productId!;
_selectedAddEditLeadProductName = value?.productName;
notifyListeners(); notifyListeners();
} }
set selectedAddEditLeadProductId(String? value) {
_selectedAddEditLeadProductId = value;
notifyListeners();
}
set selectedAddEditLeadProductName(String? value) {
_selectedAddEditLeadProductName = value;
notifyListeners();
}
set submitLoading(bool value) {
_submitLoading = value;
notifyListeners();
}
void addEditUpdateTotalAmount(value) {
final price = double.tryParse(addEditProductPriceController.text) ?? 0;
final qty = int.tryParse(addEditQuantityController.text) ?? 0;
addEditTotalAmountController.text = (price * qty).toString();
notifyListeners();
}
void editProduct(int index, LeadProducts updatedProduct) {
if (index >= 0 && index < leadProductsList.length) {
leadProductsList[index] = updatedProduct;
_productRows[index] = {
"product_id": updatedProduct.productId!,
"price": updatedProduct.price,
"qty": updatedProduct.qty,
"net_price": updatedProduct.prodTotalPrice,
};
notifyListeners();
}
}
void addEditInitializeForm(BuildContext context) {
addEditProductPriceController.clear();
addEditQuantityController.clear();
addEditTotalAmountController.clear();
selectedLeadProducts = null;
selectedAddEditLeadProductId = null;
selectedAddEditLeadProductName = null;
notifyListeners();
}
void preFillFormForEdit(LeadProducts product) {
selectedLeadProducts = product;
selectedAddEditLeadProductId = product.id;
selectedAddEditLeadProductName = product.productName;
addEditProductPriceController.text = product.price?.toString() ?? '';
addEditQuantityController.text = product.qty?.toString() ?? '';
addEditTotalAmountController.text =
product.prodTotalPrice?.toString() ?? '';
notifyListeners();
}
void initializeForm(BuildContext context) { void initializeForm(BuildContext context) {
// Clear existing controllers // Clear existing controllers
...@@ -155,7 +237,7 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -155,7 +237,7 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
"product_id": _selectedProductIds[i]!, "product_id": _selectedProductIds[i]!,
"price": editProductPriceControllers[i].text, "price": editProductPriceControllers[i].text,
"qty": editQuantityControllers[i].text, "qty": editQuantityControllers[i].text,
"net_price":editTotalAmountControllers[i].text "net_price": editTotalAmountControllers[i].text,
}; };
insertData.add(rowData); insertData.add(rowData);
} }
...@@ -175,31 +257,53 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -175,31 +257,53 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
leadID, leadID,
); );
if (data != null) { if (data != null) {
if (data.error == "0") { if (data.sessionExists == 1) {
_isLoading = false; if (data.error == "0") {
_leadProductsList = data.leadProducts ?? []; _isLoading = false;
_quoteDetails = _leadProductsList = data.leadProducts ?? [];
data.quoteDetails ??
QuoteDetails( _quoteDetails =
accountId: "", data.quoteDetails ??
email: "", QuoteDetails(
forText: "", accountId: "",
mobile: "", email: "",
name: "", forText: "",
paymentTerms: "", mobile: "",
subject: "", name: "",
); paymentTerms: "",
mailIdController.text = data.quoteDetails!.email??"-"; subject: "",
mobileController.text = data.quoteDetails!.mobile??"-"; );
subjectsController.text = data.quoteDetails!.subject??"-"; mailIdController.text = data.quoteDetails!.email ?? "-";
// taxesController.text = data.quoteDetails!1; mobileController.text = data.quoteDetails!.mobile ?? "-";
// SpecialNoteController.text = data.quoteDetails; subjectsController.text = data.quoteDetails!.subject ?? "-";
forController.text = data.quoteDetails!.forText??"-"; // taxesController.text = data.quoteDetails!1;
paymentTermsController.text = data.quoteDetails!.paymentTerms??"-"; // SpecialNoteController.text = data.quoteDetails;
notifyListeners(); forController.text = data.quoteDetails!.forText ?? "-";
paymentTermsController.text =
data.quoteDetails!.paymentTerms ?? "-";
for (var product in data.leadProducts!) {
_productRows.add({
"product_id": product.productId!,
"price": product.price,
"qty": product.qty,
"net_price": product.prodTotalPrice,
});
}
print("_productRows : ${_productRows}");
notifyListeners();
} else {
_isLoading = false;
notifyListeners();
}
} else { } else {
_isLoading = false; Navigator.push(
notifyListeners(); context,
MaterialPageRoute(
builder: (context) => LoginScreen(),
settings: RouteSettings(name: 'LoginScreen'),
),
);
} }
} else { } else {
_isLoading = false; _isLoading = false;
...@@ -235,16 +339,22 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -235,16 +339,22 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
if (data != null) { if (data != null) {
if (data.error == "0") { if (data.error == "0") {
_quotationFilePath = data.quoteFilepath!; _quotationFilePath = data.quoteFilepath!;
if(quotation_type=="genquotedown"){ if (quotation_type == "genquotedown") {
String suggestedFilename = getUniqueFilename('quotation', 'pdf'); String suggestedFilename = getUniqueFilename('quotation', 'pdf');
String contentDisposition = 'attachment; filename="$suggestedFilename"'; String contentDisposition =
'attachment; filename="$suggestedFilename"';
// openWhatsApp(data.quoteFilepath!); // openWhatsApp(data.quoteFilepath!);
_handleDownload(context,data.quoteFilepath!,contentDisposition,'application/octet-stream',''); _handleDownload(
} context,
else if(quotation_type=="genquotewhatsappbymynum"){ data.quoteFilepath!,
contentDisposition,
'application/octet-stream',
'',
);
} else if (quotation_type == "genquotewhatsappbymynum") {
openWhatsApp(data.quoteFilepath!); openWhatsApp(data.quoteFilepath!);
} }
Navigator.pop(context,true); Navigator.pop(context, true);
toast(context, data.message); toast(context, data.message);
resetForm(); resetForm();
notifyListeners(); notifyListeners();
...@@ -260,6 +370,7 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -260,6 +370,7 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
final formattedDate = DateFormat('yyyyMMdd_HHmmss').format(now); final formattedDate = DateFormat('yyyyMMdd_HHmmss').format(now);
return '${baseName}_$formattedDate.$ext'; return '${baseName}_$formattedDate.$ext';
} }
void openWhatsApp(String path) async { void openWhatsApp(String path) async {
final Uri url = Uri.parse(path); // Example: 919876543210 final Uri url = Uri.parse(path); // Example: 919876543210
if (await canLaunchUrl(url)) { if (await canLaunchUrl(url)) {
...@@ -268,16 +379,17 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -268,16 +379,17 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
throw 'Could not launch $url'; throw 'Could not launch $url';
} }
} }
Future<void> _handleDownload( Future<void> _handleDownload(
context, context,
String url, String url,
String contentDisposition, String contentDisposition,
String mimeType, String mimeType,
String suggestedFilename, String suggestedFilename,
) async { ) async {
// Request notification permission for Android 13+ // Request notification permission for Android 13+
if (Platform.isIOS) { if (Platform.isIOS) {
_handleIOSDownload(context,url, suggestedFilename); _handleIOSDownload(context, url, suggestedFilename);
} else if (Platform.isAndroid) { } else if (Platform.isAndroid) {
if (await Permission.notification.request().isGranted) { if (await Permission.notification.request().isGranted) {
try { try {
...@@ -293,10 +405,12 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -293,10 +405,12 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
'mimeType': mimeType, 'mimeType': mimeType,
'suggestedFilename': suggestedFilename, 'suggestedFilename': suggestedFilename,
}); });
await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication); await launchUrl(
Uri.parse(url),
mode: LaunchMode.externalApplication,
);
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
_handleIOSDownload(context,url, suggestedFilename); _handleIOSDownload(context, url, suggestedFilename);
} }
} catch (e) { } catch (e) {
print("Download Error $e"); print("Download Error $e");
...@@ -307,7 +421,11 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -307,7 +421,11 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
} }
} }
Future<void> _handleIOSDownload(context,String url, String suggestedFilename) async { Future<void> _handleIOSDownload(
context,
String url,
String suggestedFilename,
) async {
try { try {
// Show initial download notification // Show initial download notification
await _showDownloadNotification(0, suggestedFilename, isComplete: false); await _showDownloadNotification(0, suggestedFilename, isComplete: false);
...@@ -315,9 +433,9 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -315,9 +433,9 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
// Get the temporary directory for iOS // Get the temporary directory for iOS
final tempDir = await getTemporaryDirectory(); final tempDir = await getTemporaryDirectory();
final fileName = final fileName =
suggestedFilename.isNotEmpty suggestedFilename.isNotEmpty
? suggestedFilename ? suggestedFilename
: url.split('/').last; : url.split('/').last;
final filePath = '${tempDir.path}/$fileName'; final filePath = '${tempDir.path}/$fileName';
// Download the file using http // Download the file using http
...@@ -348,11 +466,11 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -348,11 +466,11 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
} }
Future<void> _showDownloadNotification( Future<void> _showDownloadNotification(
int progress, int progress,
String fileName, { String fileName, {
bool isComplete = false, bool isComplete = false,
bool isError = false, bool isError = false,
}) async { }) async {
final androidDetails = AndroidNotificationDetails( final androidDetails = AndroidNotificationDetails(
'download_channel', 'download_channel',
'Downloads', 'Downloads',
...@@ -378,11 +496,11 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -378,11 +496,11 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
presentBadge: true, presentBadge: true,
presentSound: isComplete || isError, presentSound: isComplete || isError,
subtitle: subtitle:
isError isError
? 'Download failed' ? 'Download failed'
: isComplete : isComplete
? 'Download complete' ? 'Download complete'
: 'Downloading...', : 'Downloading...',
threadIdentifier: 'download_thread', threadIdentifier: 'download_thread',
); );
...@@ -407,39 +525,66 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -407,39 +525,66 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
); );
} }
onChangemailId(value){ onChangemailId(value) {
mailIdError = ""; mailIdError = "";
notifyListeners(); notifyListeners();
} }
onChangemobile(value){
onChangemobile(value) {
mobileError = ""; mobileError = "";
notifyListeners(); notifyListeners();
} }
onChangesubjects(value){
onChangesubjects(value) {
subjectsError = ""; subjectsError = "";
notifyListeners(); notifyListeners();
} }
onChangetaxes(value){
onChangetaxes(value) {
taxesError = ""; taxesError = "";
notifyListeners(); notifyListeners();
} }
onChangeSpecialNote(value){
onChangeSpecialNote(value) {
SpecialNoteError = ""; SpecialNoteError = "";
notifyListeners(); notifyListeners();
} }
onChangefor(value){
onChangefor(value) {
forError = ""; forError = "";
notifyListeners(); notifyListeners();
} }
onChangepaymentTerms(value){
onChangepaymentTerms(value) {
paymentTermsError = ""; paymentTermsError = "";
notifyListeners(); notifyListeners();
} }
void resetForm() {
checkDropdownReset();
_productRows.clear();
addEditProductPriceController.clear();
addEditQuantityController.clear();
addEditTotalAmountController.clear();
editProductPriceControllers.clear();
editQuantityControllers.clear();
editTotalAmountControllers.clear();
_selectedLeadProducts = null;
_selectedAddEditLeadProductId = null;
_selectedAddEditLeadProductName = null;
notifyListeners();
}
void checkDropdownReset() {
if (!_leadProductsList.contains(_selectedLeadProducts) &&
_selectedLeadProducts != null) {
_selectedAddEditLeadProductId = null;
_selectedAddEditLeadProductName = null;
}
notifyListeners();
}
resetForm2() {
resetForm(){
mailIdController.clear(); mailIdController.clear();
mobileController.clear(); mobileController.clear();
subjectsController.clear(); subjectsController.clear();
...@@ -460,6 +605,5 @@ class Crmgeneratequotationprovider extends ChangeNotifier { ...@@ -460,6 +605,5 @@ class Crmgeneratequotationprovider extends ChangeNotifier {
SpecialNoteError = ""; SpecialNoteError = "";
forError = ""; forError = "";
paymentTermsError = ""; paymentTermsError = "";
} }
} }
...@@ -196,14 +196,12 @@ class crmNearbyOpenLeadsProvider extends ChangeNotifier { ...@@ -196,14 +196,12 @@ class crmNearbyOpenLeadsProvider extends ChangeNotifier {
List<Marker> markers = []; List<Marker> markers = [];
// print("Hello Nutsby!"); // print("Hello Nutsby!");
ByteData data = await rootBundle.load("assets/images/dg_set.png"); ByteData data = await rootBundle.load("assets/images/leads_ic.png");
Uint8List bytes = data.buffer.asUint8List(); Uint8List bytes = data.buffer.asUint8List();
await Future.forEach(leadsList, (leads) async { await Future.forEach(leadsList, (leads) async {
ui.Codec codec = await ui.instantiateImageCodec( ui.Codec codec = await ui.instantiateImageCodec(
bytes, bytes,
targetWidth: 75,
targetHeight: 95,
); );
ui.FrameInfo fi = await codec.getNextFrame(); ui.FrameInfo fi = await codec.getNextFrame();
Uint8List resizedBytes = Uint8List resizedBytes =
...@@ -214,9 +212,11 @@ class crmNearbyOpenLeadsProvider extends ChangeNotifier { ...@@ -214,9 +212,11 @@ class crmNearbyOpenLeadsProvider extends ChangeNotifier {
markers.add( markers.add(
Marker( Marker(
markerId: MarkerId(leads.id.toString()), markerId: MarkerId(leads.id.toString()),
position: _parseLatLng(leads.loc), position: _parseLatLng(leads.loc),
icon: BitmapDescriptor.fromBytes(resizedBytes), icon: BitmapDescriptor.fromBytes(resizedBytes),
infoWindow: InfoWindow( infoWindow: InfoWindow(
onTap:() { onTap:() {
// onMarkerTap(context, leads.id); // onMarkerTap(context, leads.id);
Navigator.push( Navigator.push(
......
...@@ -126,11 +126,17 @@ import 'package:generp/Notifiers/HomeScreenNotifier.dart'; ...@@ -126,11 +126,17 @@ import 'package:generp/Notifiers/HomeScreenNotifier.dart';
import 'package:generp/services/api_calling.dart'; import 'package:generp/services/api_calling.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../Models/crmModels/crmLeadDetailsEditProductsViewResponse.dart'; import '../../Models/crmModels/crmLeadDetailsEditProductsViewResponse.dart';
import 'crmLeadDetailsProvider.dart';
class Editproductlistprovider extends ChangeNotifier { class Editproductlistprovider extends ChangeNotifier {
TextEditingController addEditProductPriceController = TextEditingController();
TextEditingController addEditQuantityController = TextEditingController();
TextEditingController addEditTotalAmountController = TextEditingController();
List<Products> _productsList = []; List<Products> _productsList = [];
List<LeadProducts> _leadProductsList = []; List<LeadProducts> _leadProductsList = [];
Products? _selectedProducts; Products? _selectedProducts;
String? _selectedAddEditProductId;
String? _selectedAddEditProductName;
List<TextEditingController> editProductPriceControllers = []; List<TextEditingController> editProductPriceControllers = [];
List<TextEditingController> editQuantityControllers = []; List<TextEditingController> editQuantityControllers = [];
List<TextEditingController> editTotalAmountControllers = []; List<TextEditingController> editTotalAmountControllers = [];
...@@ -139,14 +145,35 @@ class Editproductlistprovider extends ChangeNotifier { ...@@ -139,14 +145,35 @@ class Editproductlistprovider extends ChangeNotifier {
bool _submitLoading = false; bool _submitLoading = false;
List<Products> get productsList => _productsList; List<Products> get productsList => _productsList;
List<LeadProducts> get leadProductsList => _leadProductsList; List<LeadProducts> get leadProductsList => _leadProductsList;
Products? get selectedProducts => _selectedProducts; Products? get selectedProducts => _selectedProducts;
String? get selectedAddEditProductId => _selectedAddEditProductId;
String? get selectedAddEditProductName => _selectedAddEditProductName;
List<String?> get selectedProductIds => _selectedProductIds; List<String?> get selectedProductIds => _selectedProductIds;
List<String?> get selectedValues => _selectedValues; List<String?> get selectedValues => _selectedValues;
bool get submitLoading => _submitLoading; bool get submitLoading => _submitLoading;
set selectedProducts(Products? value) { set selectedProducts(Products? value) {
_selectedProducts = value; _selectedProducts = value;
_selectedAddEditProductId = value!.id!;
_selectedAddEditProductName = value.name;
notifyListeners();
}
set selectedAddEditProductId(String? value) {
_selectedAddEditProductId = value;
notifyListeners();
}
set selectedAddEditProductName(String? value) {
_selectedAddEditProductName = value;
notifyListeners(); notifyListeners();
} }
...@@ -165,10 +192,20 @@ class Editproductlistprovider extends ChangeNotifier { ...@@ -165,10 +192,20 @@ class Editproductlistprovider extends ChangeNotifier {
// Initialize controllers for each lead product // Initialize controllers for each lead product
for (var product in _leadProductsList) { for (var product in _leadProductsList) {
editProductPriceControllers.add(TextEditingController(text: product.price?.toString() ?? '')); editProductPriceControllers.add(
editQuantityControllers.add(TextEditingController(text: product.qty?.toString() ?? '')); TextEditingController(text: product.price?.toString() ?? ''),
editTotalAmountControllers.add(TextEditingController( );
text: (double.parse(product.price?.toString() ?? '0') * int.parse(product.qty?.toString() ?? '0')).toString())); editQuantityControllers.add(
TextEditingController(text: product.qty?.toString() ?? ''),
);
editTotalAmountControllers.add(
TextEditingController(
text:
(double.parse(product.price?.toString() ?? '0') *
int.parse(product.qty?.toString() ?? '0'))
.toString(),
),
);
_selectedProductIds.add(product.productId); _selectedProductIds.add(product.productId);
_selectedValues.add(product.productName); _selectedValues.add(product.productName);
} }
...@@ -215,6 +252,13 @@ class Editproductlistprovider extends ChangeNotifier { ...@@ -215,6 +252,13 @@ class Editproductlistprovider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void addEditUpdateTotalAmount() {
final price = double.tryParse(addEditProductPriceController.text) ?? 0;
final qty = int.tryParse(addEditQuantityController.text) ?? 0;
addEditTotalAmountController.text = (price * qty).toString();
notifyListeners();
}
List<Map<String, String>> getFormData() { List<Map<String, String>> getFormData() {
final List<Map<String, String>> insertData = []; final List<Map<String, String>> insertData = [];
for (int i = 0; i < editProductPriceControllers.length; i++) { for (int i = 0; i < editProductPriceControllers.length; i++) {
...@@ -230,10 +274,17 @@ class Editproductlistprovider extends ChangeNotifier { ...@@ -230,10 +274,17 @@ class Editproductlistprovider extends ChangeNotifier {
return insertData; return insertData;
} }
Future<void> crmLeadDetailsEditProductsViewAPIFunction(BuildContext context, String leadID) async { Future<void> crmLeadDetailsEditProductsViewAPIFunction(
BuildContext context,
String leadID,
) async {
try { try {
final prov = Provider.of<HomescreenNotifier>(context, listen: false); final prov = Provider.of<HomescreenNotifier>(context, listen: false);
final data = await ApiCalling.crmLeadDetailsEditProductsViewAPI(prov.empId, prov.session, leadID); final data = await ApiCalling.crmLeadDetailsEditProductsViewAPI(
prov.empId,
prov.session,
leadID,
);
if (data != null && data.error == "0") { if (data != null && data.error == "0") {
_leadProductsList = data.leadProducts ?? []; _leadProductsList = data.leadProducts ?? [];
_productsList = data.products ?? []; _productsList = data.products ?? [];
...@@ -244,13 +295,22 @@ class Editproductlistprovider extends ChangeNotifier { ...@@ -244,13 +295,22 @@ class Editproductlistprovider extends ChangeNotifier {
} }
} }
Future<void> crmLeadDetailsEditProductsSubmitAPIFunction(BuildContext context,products, String leadID) async { Future<void> crmLeadDetailsEditProductsSubmitAPIFunction(
BuildContext context,
products,
String leadID,
) async {
try { try {
final prov = Provider.of<HomescreenNotifier>(context, listen: false); final prov = Provider.of<HomescreenNotifier>(context, listen: false);
final data = await ApiCalling.crmLeadDetailsEditProductsSubmitAPI(prov.empId, prov.session,products, leadID); final data = await ApiCalling.crmLeadDetailsEditProductsSubmitAPI(
prov.empId,
prov.session,
products,
leadID,
);
if (data != null && data.error == "0") { if (data != null && data.error == "0") {
resetForm(); resetForm();
Navigator.pop(context,true); Navigator.pop(context, true);
notifyListeners(); notifyListeners();
} }
} catch (e, s) { } catch (e, s) {
...@@ -258,22 +318,78 @@ class Editproductlistprovider extends ChangeNotifier { ...@@ -258,22 +318,78 @@ class Editproductlistprovider extends ChangeNotifier {
} }
} }
void submitForm(BuildContext context,leadID) async { Future<void> crmLeadDetailsAddEditProductsSubmitAPIFunction(
BuildContext context,
mode,
String leadID,
type,
leadProductId,
productId,
) async {
try {
_submitLoading = true;
notifyListeners();
final prov = Provider.of<HomescreenNotifier>(context, listen: false);
final prov2 = Provider.of<crmLeadDetailsProvider>(context, listen: false);
final data = await ApiCalling.crmLeadDetailsAddEditProductsAPI(
prov.empId,
prov.session,
leadID,
type,
leadProductId,
productId,
addEditQuantityController.text,
addEditTotalAmountController.text,
);
if (data != null && data.error == "0") {
_submitLoading = false;
resetForm();
Navigator.pop(context, true);
prov2.crmLeadDetailsAPIFunction(context, leadID, mode);
notifyListeners();
}else{
_submitLoading = false;
notifyListeners();
}
} catch (e, s) {
_submitLoading = false;
notifyListeners();
print("Error: $e, Stack: $s");
}
}
void submitForm(BuildContext context, leadID) async {
submitLoading = true; submitLoading = true;
final insertedData = getFormData(); final insertedData = getFormData();
print("Form Data: $insertedData"); print("Form Data: $insertedData");
crmLeadDetailsEditProductsSubmitAPIFunction(context,insertedData,leadID); crmLeadDetailsEditProductsSubmitAPIFunction(context, insertedData, leadID);
submitLoading = false; submitLoading = false;
} }
void resetForm() { void resetForm() {
checkDropdownReset();
addEditProductPriceController.clear();
addEditQuantityController.clear();
addEditTotalAmountController.clear();
editProductPriceControllers.clear(); editProductPriceControllers.clear();
editQuantityControllers.clear(); editQuantityControllers.clear();
editTotalAmountControllers.clear(); editTotalAmountControllers.clear();
_selectedProductIds.clear(); _selectedProductIds.clear();
_selectedProducts = null;
_selectedAddEditProductId = null;
_selectedAddEditProductName = null;
_selectedValues.clear(); _selectedValues.clear();
_leadProductsList.clear(); _leadProductsList.clear();
notifyListeners(); notifyListeners();
} }
}
\ No newline at end of file void checkDropdownReset(){
if(!_productsList.contains(_selectedProducts)&&_selectedProducts!=null){
_selectedAddEditProductId = null;
_selectedAddEditProductName = null;
}
notifyListeners();
}
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:generp/Notifiers/HomeScreenNotifier.dart';
import 'package:generp/Utils/app_colors.dart';
import 'package:geolocator/geolocator.dart';
import 'package:geolocator/geolocator.dart' as geo_location;
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import '../../services/api_calling.dart';
import 'crmLeadDetailsProvider.dart';
class followUpUpdateProvider extends ChangeNotifier {
bool _submitLoading = false;
TextEditingController nextAppointmentDateController = TextEditingController();
TextEditingController followUpFeedbackController = TextEditingController();
TextEditingController noteController = TextEditingController();
TextEditingController reasonController = TextEditingController();
TimeOfDay _selectedTime = TimeOfDay.now();
String _formattedTime = "";
String? _selectedFollowupType;
String? _selectedLeadStatus;
String? _nextAppointmentStatus;
String? _selectNextAppointmentType;
String? _selectOrderStatus;
String? _selectedCompetitor;
LatLng? currentLocationLatLng;
String? latlongs;
DateTime? _date;
String? _formattedDate;
String? _dateError;
bool get submitLoading => _submitLoading;
TimeOfDay get selectedTime => _selectedTime;
String get formattedTime => _formattedTime;
String? get selectedFollowupType => _selectedFollowupType;
String? get selectedLeadStatus => _selectedLeadStatus;
String? get nextAppointmentStatus => _nextAppointmentStatus;
String? get selectNextAppointmentType => _selectNextAppointmentType;
String? get selectOrderStatus => _selectOrderStatus;
String? get selectedCompetitor => _selectedCompetitor;
set submitLoading(bool value){
_submitLoading = value;
notifyListeners();
}
set selectedFollowupType(String? value) {
_selectedFollowupType = value;
notifyListeners();
}
set selectedLeadStatus(String? value) {
_selectedLeadStatus = value;
notifyListeners();
}
set nextAppointmentStatus(String? value) {
_nextAppointmentStatus = value;
notifyListeners();
}
set selectNextAppointmentType(String? value) {
_selectNextAppointmentType = value;
notifyListeners();
}
set selectOrderStatus(String? value) {
_selectOrderStatus = value;
notifyListeners();
}
set selectedCompetitor(String? value) {
_selectedCompetitor = value;
notifyListeners();
}
bool _checked = false;
var _smsSent = "0";
bool get checked => _checked;
get smsSent => _smsSent;
set smsSent(value) {
_smsSent = value;
notifyListeners();
}
set checked(value) {
_checked = value;
notifyListeners();
}
set formattedDate(String? value) {
_formattedDate = value;
nextAppointmentDateController.text = _formattedDate!;
_dateError = null;
notifyListeners();
}
set dateError(value) {
_dateError = value;
notifyListeners();
}
Future<void> getCurrentLocation(context) async {
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: geo_location.LocationAccuracy.high,
);
currentLocationLatLng = LatLng(position.latitude, position.longitude);
print("Current Loc: ${currentLocationLatLng}");
latlongs = '${position.latitude},${position.longitude}';
print("latlongs : ${latlongs}");
notifyListeners();
} catch (e) {
print("Error getting current location: $e");
}
}
Future<void> crmAddFollowUpAPIFunction(
BuildContext context,
nextAppointmentStatus,
orderStatus,
leadID,
followupType,
competitor,
leadStatus,
appointmentType,
sms,
[mode]
) async {
try {
_submitLoading = true;
notifyListeners();
final prov = Provider.of<HomescreenNotifier>(context, listen: false);
final prov2 = Provider.of<crmLeadDetailsProvider>(context, listen: false);
final data = await ApiCalling.crmLeadDetailsAddFollowUpAPI(
prov.session,
prov.empId,
nextAppointmentStatus,
orderStatus,
leadID,
followUpFeedbackController.text,
followupType,
_selectedTime.hour.toString() + ":" + _selectedTime.minute.toString(),
latlongs,
competitor,
reasonController.text,
leadStatus,
nextAppointmentDateController.text,
appointmentType,
sms,
noteController.text,
);
if (data != null && data.error == "0") {
_submitLoading = false;
resetForm();
Navigator.pop(context);
if(mode.isNotEmpty){
prov2.crmLeadDetailsAPIFunction(context, leadID, mode);
}
notifyListeners();
} else {
_submitLoading = false;
notifyListeners();
}
} catch (e, s) {
_submitLoading = false;
notifyListeners();
print("Error: $e, Stack: $s");
}
}
void setDate(DateTime newDate) {
_date = newDate;
_formattedDate = DateFormat('yyyy-MM-dd').format(newDate);
nextAppointmentDateController.text = _formattedDate!;
_dateError = null;
notifyListeners();
}
Future<void> selectTime(BuildContext context) async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: _selectedTime,
);
if (picked != null && picked != _selectedTime) _selectedTime = picked;
_formattedTime =
_selectedTime.hour.toString() + ":" + _selectedTime.minute.toString();
notifyListeners();
}
String formatTime(int hour, int minute) {
String period = (hour >= 12) ? 'pm' : 'am';
if (hour == 0) {
hour = 12;
} else if (hour > 12) {
hour -= 12;
}
String formattedHour = (hour < 10) ? '0$hour' : '$hour';
String formattedMinute = (minute < 10) ? '0$minute' : '$minute';
print("formattedTime: $formattedHour:$formattedMinute $period");
return '$formattedHour:$formattedMinute $period';
}
void showDatePickerDialog(BuildContext context) {
showCupertinoModalPopup<void>(
context: context,
builder:
(BuildContext context) => Container(
height: 216,
padding: const EdgeInsets.only(top: 6.0),
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
color: CupertinoColors.systemBackground.resolveFrom(context),
child: SafeArea(
top: false,
child: Column(
children: [
Expanded(
flex: 1,
child: SizedBox(
height: 40,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CupertinoButton(
child: Text(
'Cancel',
style: TextStyle(
fontFamily: "JakartaMedium",
color: AppColors.app_blue,
),
),
onPressed: () {
Navigator.pop(context);
},
),
CupertinoButton(
child: Text(
'Done',
style: TextStyle(
fontFamily: "JakartaMedium",
color: AppColors.app_blue,
),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
),
Expanded(
flex: 3,
child: CupertinoDatePicker(
dateOrder: DatePickerDateOrder.dmy,
initialDateTime: _date ?? DateTime.now(),
mode: CupertinoDatePickerMode.date,
use24hFormat: true,
showDayOfWeek: true,
onDateTimeChanged: (DateTime newDate) {
setDate(newDate);
},
),
),
],
),
),
),
);
}
onFollowUpChanged(value) {}
onNoteChanged(value) {}
onReasonChanged(value) {}
void resetForm(){
nextAppointmentDateController.clear();
followUpFeedbackController.clear();
noteController.clear();
reasonController.clear();
_selectedFollowupType = null;
_selectedLeadStatus = null;
_nextAppointmentStatus = null;
_selectNextAppointmentType = null;
_selectOrderStatus = null;
_selectedCompetitor = null;
notifyListeners();
}
}
...@@ -414,7 +414,7 @@ class Requestionlistprovider extends ChangeNotifier { ...@@ -414,7 +414,7 @@ class Requestionlistprovider extends ChangeNotifier {
_accounts = data.accounts ?? []; _accounts = data.accounts ?? [];
if (mode != "self") { if (mode != "self") {
_accounts = [ _accounts = [
Accounts(id: "", name: "Select"), Accounts(id: "", name: "Select Account"),
...data.accounts ?? [], ...data.accounts ?? [],
]; ];
} }
......
...@@ -220,6 +220,7 @@ class MyApp extends StatelessWidget { ...@@ -220,6 +220,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => Addprospectleadsprovider()), ChangeNotifierProvider(create: (_) => Addprospectleadsprovider()),
ChangeNotifierProvider(create: (_) => Editorderprovider()), ChangeNotifierProvider(create: (_) => Editorderprovider()),
ChangeNotifierProvider(create: (_) => Dispatchorderprovider()), ChangeNotifierProvider(create: (_) => Dispatchorderprovider()),
ChangeNotifierProvider(create: (_) => followUpUpdateProvider()),
], ],
child: Builder( child: Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
......
This diff is collapsed.
...@@ -18,7 +18,9 @@ import '../../Notifiers/crmProvider/crmNearbyOpenLeadsProvider.dart'; ...@@ -18,7 +18,9 @@ import '../../Notifiers/crmProvider/crmNearbyOpenLeadsProvider.dart';
import '../../Utils/dropdownTheme.dart'; import '../../Utils/dropdownTheme.dart';
class NearbyOpenLeads extends StatefulWidget { class NearbyOpenLeads extends StatefulWidget {
const NearbyOpenLeads({super.key}); final latitude;
final longitude;
const NearbyOpenLeads({super.key, this.latitude, this.longitude});
@override @override
State<NearbyOpenLeads> createState() => _NearbyOpenLeadsState(); State<NearbyOpenLeads> createState() => _NearbyOpenLeadsState();
...@@ -121,6 +123,7 @@ class _NearbyOpenLeadsState extends State<NearbyOpenLeads> { ...@@ -121,6 +123,7 @@ class _NearbyOpenLeadsState extends State<NearbyOpenLeads> {
zoomGesturesEnabled: true, zoomGesturesEnabled: true,
zoomControlsEnabled: true, zoomControlsEnabled: true,
gestureRecognizers: { gestureRecognizers: {
Factory<OneSequenceGestureRecognizer>( Factory<OneSequenceGestureRecognizer>(
() => EagerGestureRecognizer(), () => EagerGestureRecognizer(),
), ),
...@@ -132,7 +135,9 @@ class _NearbyOpenLeadsState extends State<NearbyOpenLeads> { ...@@ -132,7 +135,9 @@ class _NearbyOpenLeadsState extends State<NearbyOpenLeads> {
), // Prioritize pinch-to-zoom ), // Prioritize pinch-to-zoom
}, },
initialCameraPosition: CameraPosition( initialCameraPosition: CameraPosition(
target: provider.startLocation, target: widget.latitude!=null||widget.longitude!=null?
LatLng(widget.latitude,widget.longitude):
provider.startLocation,
zoom: 14.0, zoom: 14.0,
), ),
markers: provider.markers.toSet(), markers: provider.markers.toSet(),
......
...@@ -198,7 +198,7 @@ class _ProspectListByModeState extends State<ProspectListByMode> { ...@@ -198,7 +198,7 @@ class _ProspectListByModeState extends State<ProspectListByMode> {
), ),
), ),
Text( Text(
crmLists[index].accman??"-", crmLists[index].mob1??"-",
maxLines: 1, maxLines: 1,
style: TextStyle( style: TextStyle(
fontFamily: "JakartaMedium", fontFamily: "JakartaMedium",
......
...@@ -5,7 +5,6 @@ import 'package:dotted_line/dotted_line.dart'; ...@@ -5,7 +5,6 @@ import 'package:dotted_line/dotted_line.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:generp/Models/crmModels/crmPendingTasksResponse.dart';
import 'package:generp/screens/crm/pendingTasksDetails.dart'; import 'package:generp/screens/crm/pendingTasksDetails.dart';
import 'package:generp/screens/crm/pendingTasksList.dart'; import 'package:generp/screens/crm/pendingTasksList.dart';
import 'package:generp/screens/crm/universalSearchScreen.dart'; import 'package:generp/screens/crm/universalSearchScreen.dart';
...@@ -38,8 +37,9 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> { ...@@ -38,8 +37,9 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
}); });
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
var prov = Provider.of<Crmdashboardprovider>(context, listen: false); var prov = Provider.of<Crmdashboardprovider>(context, listen: false);
prov.getCurrentLocation(context);
prov.accessPagesAPIFunction(context); prov.accessPagesAPIFunction(context);
prov.crmDashboardAPIFunction(context, "executive", "", "", ""); // prov.crmDashboardAPIFunction(context);
prov.crmPendingTasksAPIFunction(context); prov.crmPendingTasksAPIFunction(context);
}); });
} }
...@@ -208,8 +208,8 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> { ...@@ -208,8 +208,8 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
'Pending Tasks', 'Pending Tasks',
'Today Visits', 'Today Visits',
'Today Calls', 'Today Calls',
'Hot Leads' 'Hot Leads',
'Cold Leads', 'Cold Leads',
'Warm Leads', 'Warm Leads',
// 'Total Leads', // 'Total Leads',
// 'Order Lost', // 'Order Lost',
...@@ -322,6 +322,8 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> { ...@@ -322,6 +322,8 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
}, },
), ),
), ),
]else...[
SizedBox(height: 10,),
], ],
// ListView.builder( // ListView.builder(
...@@ -435,6 +437,7 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> { ...@@ -435,6 +437,7 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
// ); // );
// }, // },
// ), // ),
Container( Container(
height: MediaQuery.of(context).size.height * 0.2, height: MediaQuery.of(context).size.height * 0.2,
margin: EdgeInsets.symmetric(horizontal: 10), margin: EdgeInsets.symmetric(horizontal: 10),
...@@ -638,6 +641,207 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> { ...@@ -638,6 +641,207 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
), ),
), ),
if (provider.nearByLeads.isNotEmpty) ...[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: EdgeInsets.only(left: 15, top: 10, right: 15),
child: Row(
children: [
Text(
"NearBy Leads",
style: TextStyle(
fontSize: 16,
color: AppColors.grey_semi,
),
),
Spacer(),
InkResponse(
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NearbyOpenLeads(),
settings: RouteSettings(
name: "NearbyOpenLeads",
),
),
);
},
child: SizedBox(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"View All",
style: TextStyle(
fontFamily: "JakartaMedium",
fontSize: 14,
color: AppColors.app_blue,
),
),
SizedBox(width: 5),
SvgPicture.asset(
"assets/svg/next_button.svg",
),
],
),
),
),
],
),
),
),
SizedBox(
width: double.infinity,
height: 150,
child: ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
itemCount: provider.nearByLeads.length,
itemBuilder: (context, index) {
final lead = provider.nearByLeads[index];
final location = provider.parseLocation(lead.loc!);
final latitude = location.lat;
final longitude = location.lng;
return InkResponse(
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NearbyOpenLeads(
latitude:latitude,
longitude:longitude
),
settings: RouteSettings(
name: "NearbyOpenLeads",
),
),
);
},
child: Container(
alignment: Alignment.center,
height: 150,
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(14),
),
margin: EdgeInsets.symmetric(
horizontal: 5,
vertical: 5,
),
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 15,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment:CrossAxisAlignment.start,
children: [
Text(
provider.nearByLeads[index].name ?? "-",
maxLines: 1,
style: TextStyle(
fontSize: 14,
color: AppColors.semi_black,
fontFamily: "JakartaMedium"
),
),
Text(
provider.nearByLeads[index].product ??
"-",
maxLines: 2,
style: TextStyle(
fontSize: 14,
color: AppColors.grey_semi,
fontFamily: "JakartaMedium"
),
),
],
),
),
SizedBox(width: 10,),
Expanded(
child: ClipRRect(
borderRadius:BorderRadius.circular(16),
child: Image.network(
provider.getSimpleOSMImage(latitude, longitude),
width: 400,
height: 400,
fit: BoxFit.cover,
),
),
),
],
),
),
);
},
),
),
]else...[
SizedBox(height: 10,),
InkResponse(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NearbyOpenLeads(),
),
);
},
child: Container(
height: 60,
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Row(
children: [
Expanded(
flex: 1,
child: Container(
height: 35,
width: 35,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Color(0xFFEDF8FF),
shape: BoxShape.circle,
),
child: SvgPicture.asset(
"assets/svg/find_generator.svg",
),
),
),
Expanded(
flex: 4,
child: Text(
"Find Nearby Generators",
style: TextStyle(
fontSize: 14,
color: AppColors.app_blue,
),
),
),
],
),
),
),
],
if (provider.pendingTasksLists.length > 0) ...[ if (provider.pendingTasksLists.length > 0) ...[
Align( Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
...@@ -714,13 +918,15 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> { ...@@ -714,13 +918,15 @@ class _CrmdashboardScreenState extends State<CrmdashboardScreen> {
]; ];
return InkResponse( return InkResponse(
onTap: () async { onTap: () async {
await Navigator.push( await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: builder:
(context) => (context) =>
Pendingtasksdetails(detailIndex: index), Pendingtasksdetails(detailIndex: index),
settings: RouteSettings(name: 'Pendingtasksdetails') settings: RouteSettings(
name: 'Pendingtasksdetails',
),
), ),
); );
}, },
......
This diff is collapsed.
import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import '../../Models/crmModels/crmLeadDetailsGenerateQuotationViewResponse.dart';
import '../../Notifiers/crmProvider/crmGenerateQuotationProvider.dart';
import '../../Notifiers/crmProvider/crmLeadDetailsProvider.dart';
import '../../Utils/app_colors.dart';
import '../../Utils/commonServices.dart';
import '../../Utils/commonWidgets.dart';
import '../../Utils/dropdownTheme.dart';
class Generatequotationaddeditproduct extends StatefulWidget {
final leadId;
final type;
final product;
final index;
const Generatequotationaddeditproduct({
super.key,
required this.leadId,
this.type,
this.product,
this.index,
});
@override
State<Generatequotationaddeditproduct> createState() =>
_GeneratequotationaddeditproductState();
}
class _GeneratequotationaddeditproductState
extends State<Generatequotationaddeditproduct> {
Map _source = {ConnectivityResult.mobile: true};
final MyConnectivity _connectivity = MyConnectivity.instance;
Dropdowntheme ddtheme = Dropdowntheme();
@override
void initState() {
// TODO: implement initState
super.initState();
_connectivity.initialise();
_connectivity.myStream.listen((source) {
setState(() => _source = source);
});
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
final provider = Provider.of<Crmgeneratequotationprovider>(
context,
listen: false,
);
provider.crmLeadDetailsGenerateQuoteViewAPIFunction(
context,
widget.leadId,
);
// provider.resetForm();
if (widget.type == "add") {
// Initialize controllers and dropdowns after API call
provider.addEditInitializeForm(context);
} else {
provider.preFillFormForEdit(widget.product);
}
});
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_connectivity.disposeStream();
}
@override
Widget build(BuildContext context) {
switch (_source.keys.toList()[0]) {
case ConnectivityResult.mobile:
connection = 'Online';
break;
case ConnectivityResult.wifi:
connection = 'Online';
break;
case ConnectivityResult.none:
default:
connection = 'Offline';
}
return (connection == "Online")
? Platform.isAndroid
? WillPopScope(
onWillPop: () => onBackPressed(context),
child: SafeArea(
top: false,
bottom: true,
child: _scaffold(context),
),
)
: _scaffold(context)
: NoNetwork(context);
}
Widget _scaffold(BuildContext context) {
return Consumer<Crmgeneratequotationprovider>(
builder: (context, provider, child) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: appbarNew(context, "Generate Quotation", 0xFFFFFFFF),
backgroundColor: AppColors.scaffold_bg_color,
body: SingleChildScrollView(
child: Column(
children: [
Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
margin: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextWidget(context, "Product"),
DropdownButtonHideUnderline(
child: Row(
children: [
Expanded(
child: DropdownButton2<LeadProducts>(
isExpanded: true,
hint: const Text(
'Select Product',
style: TextStyle(fontSize: 14),
overflow: TextOverflow.ellipsis,
),
items:
provider.leadProductsList
.map(
(
ord,
) => DropdownMenuItem<LeadProducts>(
value: ord,
child: Text(
"(Product Name: ${ord.productName})",
style: const TextStyle(
fontSize: 14,
),
overflow: TextOverflow.ellipsis,
),
),
)
.toList(),
// provider.selectedOrderIds[index] != null?
// provider
// .orderList
// .firstWhere(
// (product) =>
// product
// .orderId ==
// provider
// .selectedOrderIds[index],
// )
value:
provider.selectedLeadProducts != null
? provider.leadProductsList.firstWhere(
(element) =>
element.id ==
provider
.selectedAddEditLeadProductId,
)
: null,
onChanged: (LeadProducts? value) {
if (value != null) {
provider.selectedLeadProducts = value;
provider.selectedAddEditLeadProductId =
value!.productId!;
provider.selectedAddEditLeadProductName =
value.productName;
}
},
buttonStyleData: ddtheme.buttonStyleData,
iconStyleData: ddtheme.iconStyleData,
menuItemStyleData: ddtheme.menuItemStyleData,
dropdownStyleData: ddtheme.dropdownStyleData,
),
),
],
),
),
const SizedBox(height: 10),
textControllerWidget(
context,
provider.addEditProductPriceController,
"Product Price",
"Enter Product Price",
provider.addEditUpdateTotalAmount,
TextInputType.number,
false,
FilteringTextInputFormatter.digitsOnly,
),
const SizedBox(height: 10),
textControllerWidget(
context,
provider.addEditQuantityController,
"Quantity",
"Enter Quantity",
provider.addEditUpdateTotalAmount,
TextInputType.number,
false,
FilteringTextInputFormatter.digitsOnly,
),
const SizedBox(height: 10),
Row(
children: [
Expanded(
flex: 2,
child: textControllerWidget(
context,
provider.addEditTotalAmountController,
"Amount",
"Total Amount",
(_) {},
TextInputType.number,
true,
FilteringTextInputFormatter.digitsOnly,
),
),
],
),
// IconButton(
// icon: const Icon(Icons.delete),
// onPressed: provider.editProductPriceControllers.length > 1
// ? () => provider.editRemoveRow(j)
// : null,
// ),
],
),
),
],
),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
floatingActionButton: InkWell(
onTap: () {
if (provider.selectedLeadProducts != null) {
var newProduct;
if (widget.type == "add") {
newProduct = LeadProducts(
id: provider.selectedAddEditLeadProductId,
productName: provider.selectedAddEditLeadProductName,
price: provider.addEditProductPriceController.text,
qty: provider.addEditQuantityController.text,
prodTotalPrice: provider.addEditTotalAmountController.text,
);
provider.leadProductsList.add(newProduct);
provider.productRows.add({
"product_id": provider.selectedAddEditLeadProductId!,
"price": provider.addEditProductPriceController.text,
"qty": provider.addEditQuantityController.text,
"net_price": provider.addEditTotalAmountController.text,
});
Navigator.pop(context, newProduct);
} else {
final updatedProduct = LeadProducts(
id: provider.selectedAddEditLeadProductId,
productName: provider.selectedAddEditLeadProductName,
price: provider.addEditProductPriceController.text,
qty: provider.addEditQuantityController.text,
prodTotalPrice: provider.addEditTotalAmountController.text,
);
provider.editProduct(widget.index!, updatedProduct);
Navigator.pop(context, updatedProduct);
}
// if (widget.index != null) {
// // Editing existing product
// provider.editProduct(widget.index!, newProduct);
// } else {
// // Adding new product
// provider.addProduct(newProduct);
// }
}
},
child: Container(
alignment: Alignment.center,
height: 45,
decoration: BoxDecoration(
color: AppColors.app_blue, //1487C9
borderRadius: BorderRadius.circular(14.0),
),
margin: EdgeInsets.symmetric(horizontal: 10),
child: Center(
child: Text(
"Submit",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
),
),
),
),
);
},
);
}
}
...@@ -37,7 +37,7 @@ class _PendingtasksdetailsState extends State<Pendingtasksdetails> { ...@@ -37,7 +37,7 @@ class _PendingtasksdetailsState extends State<Pendingtasksdetails> {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
var prov = Provider.of<Crmdashboardprovider>(context, listen: false); var prov = Provider.of<Crmdashboardprovider>(context, listen: false);
prov.accessPagesAPIFunction(context); prov.accessPagesAPIFunction(context);
prov.crmDashboardAPIFunction(context, "executive", "", "", ""); prov.crmDashboardAPIFunction(context);
prov.crmPendingTasksAPIFunction(context); prov.crmPendingTasksAPIFunction(context);
}); });
} }
...@@ -255,7 +255,9 @@ class _PendingtasksdetailsState extends State<Pendingtasksdetails> { ...@@ -255,7 +255,9 @@ class _PendingtasksdetailsState extends State<Pendingtasksdetails> {
onTap: () async { onTap: () async {
await Navigator.push( await Navigator.push(
context, context,
MaterialPageRoute(builder: (context) => Followupupdatescreen()), MaterialPageRoute(builder: (context) => Followupupdatescreen(
leadID: task.leadid,
)),
); );
}, },
child: Container( child: Container(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment