Pd and Rd list added

This commit is contained in:
kratikpal 2024-08-14 14:37:47 +05:30
parent 7e86e93c8e
commit de188372d9
6 changed files with 383 additions and 134 deletions

View File

@ -1,6 +1,7 @@
import 'dart:developer';
import 'dart:io';
import 'package:cheminova/provider/collect_kyc_provider.dart';
import 'package:cheminova/provider/pd_rd_provider.dart';
import 'package:cheminova/provider/product_provider.dart';
import 'package:cheminova/provider/user_provider.dart';
import 'package:cheminova/screens/splash_screen.dart';
@ -98,6 +99,7 @@ Future<void> main() async {
ChangeNotifierProvider(create: (context) => CollectKycProvider()),
ChangeNotifierProvider(create: (_) => UserProvider()),
ChangeNotifierProvider(create: (_) => ProductProvider()),
ChangeNotifierProvider(create: (_) => PdRdProvider()),
],
child: const MyApp(),
),

View File

@ -0,0 +1,156 @@
class PdRdResponseModel {
String id;
String name;
String tradeName;
String address;
String state;
String city;
String district;
String pincode;
String mobileNumber;
String principalDistributer;
String panNumber;
ImageModel panImg;
String aadharNumber;
ImageModel aadharImg;
String gstNumber;
ImageModel gstImg;
ImageModel pesticideLicenseImg;
ImageModel selfieEntranceImg;
String status;
String addedBy;
String? userType;
List<Note> notes;
DateTime createdAt;
DateTime updatedAt;
int v;
PdRdResponseModel({
required this.id,
required this.name,
required this.tradeName,
required this.address,
required this.state,
required this.city,
required this.district,
required this.pincode,
required this.mobileNumber,
required this.principalDistributer,
required this.panNumber,
required this.panImg,
required this.aadharNumber,
required this.aadharImg,
required this.gstNumber,
required this.gstImg,
required this.pesticideLicenseImg,
required this.selfieEntranceImg,
required this.status,
required this.addedBy,
this.userType,
required this.notes,
required this.createdAt,
required this.updatedAt,
required this.v,
});
factory PdRdResponseModel.fromJson(Map<String, dynamic> json) =>
PdRdResponseModel(
id: json["_id"],
name: json["name"],
tradeName: json["trade_name"],
address: json["address"],
state: json["state"],
city: json["city"],
district: json["district"],
pincode: json["pincode"],
mobileNumber: json["mobile_number"],
principalDistributer: json["principal_distributer"],
panNumber: json["pan_number"],
panImg: ImageModel.fromJson(json["pan_img"]),
aadharNumber: json["aadhar_number"],
aadharImg: ImageModel.fromJson(json["aadhar_img"]),
gstNumber: json["gst_number"],
gstImg: ImageModel.fromJson(json["gst_img"]),
pesticideLicenseImg: ImageModel.fromJson(json["pesticide_license_img"]),
selfieEntranceImg: ImageModel.fromJson(json["selfie_entrance_img"]),
status: json["status"],
addedBy: json["addedBy"],
userType: json["userType"],
notes: List<Note>.from(json["notes"].map((x) => Note.fromJson(x))),
createdAt: DateTime.parse(json["createdAt"]),
updatedAt: DateTime.parse(json["updatedAt"]),
v: json["__v"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"name": name,
"trade_name": tradeName,
"address": address,
"state": state,
"city": city,
"district": district,
"pincode": pincode,
"mobile_number": mobileNumber,
"principal_distributer": principalDistributer,
"pan_number": panNumber,
"pan_img": panImg.toJson(),
"aadhar_number": aadharNumber,
"aadhar_img": aadharImg.toJson(),
"gst_number": gstNumber,
"gst_img": gstImg.toJson(),
"pesticide_license_img": pesticideLicenseImg.toJson(),
"selfie_entrance_img": selfieEntranceImg.toJson(),
"status": status,
"addedBy": addedBy,
"userType": userType,
"notes": List<dynamic>.from(notes.map((x) => x.toJson())),
"createdAt": createdAt.toIso8601String(),
"updatedAt": updatedAt.toIso8601String(),
"__v": v,
};
}
class ImageModel {
String publicId;
String url;
ImageModel({
required this.publicId,
required this.url,
});
factory ImageModel.fromJson(Map<String, dynamic> json) => ImageModel(
publicId: json["public_id"],
url: json["url"],
);
Map<String, dynamic> toJson() => {
"public_id": publicId,
"url": url,
};
}
class Note {
String message;
DateTime replyDate;
String id;
Note({
required this.message,
required this.replyDate,
required this.id,
});
factory Note.fromJson(Map<String, dynamic> json) => Note(
message: json["message"],
replyDate: DateTime.parse(json["replyDate"]),
id: json["_id"],
);
Map<String, dynamic> toJson() => {
"message": message,
"replyDate": replyDate.toIso8601String(),
"_id": id,
};
}

View File

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:cheminova/models/pd_rd_response_model.dart';
import 'package:cheminova/services/api_client.dart';
import 'package:cheminova/services/api_urls.dart';
class PdRdProvider extends ChangeNotifier {
bool _isLoading = false;
bool get isLoading => _isLoading;
List<PdRdResponseModel> _pdRdList = [];
List<PdRdResponseModel> get pdRdList => _pdRdList;
final _apiClient = ApiClient();
void setLoading(bool loading) {
_isLoading = loading;
notifyListeners();
}
Future<void> getPdRd() async {
setLoading(true);
try {
Response response = await _apiClient.get(ApiUrls.getPdRdUrl);
if (response.statusCode == 200) {
// Assuming the response data is a list of PdRdResponseModel objects
List<PdRdResponseModel> data = (response.data as List)
.map((json) => PdRdResponseModel.fromJson(json))
.toList();
_pdRdList = data;
} else {
print("Failed to load data: ${response.statusCode}");
}
} catch (e) {
print("Error occurred: $e");
} finally {
setLoading(false);
}
}
}

View File

@ -19,12 +19,20 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
List<Product> selectedProducts = [];
List<Product> filteredProducts = [];
final searchController = TextEditingController();
late ProductProvider provider;
@override
void initState() {
super.initState();
loadProducts();
}
Future<void> loadProducts() async {
final provider = Provider.of<ProductProvider>(context, listen: false);
await provider.getProducts();
setState(() {
filteredProducts = provider.productList;
});
}
void filterProducts(String query) {
@ -56,12 +64,15 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
padding: const EdgeInsets.only(right: 20),
),
],
title: const Text('Add Products',
title: const Text(
'Add Products',
style: TextStyle(
fontSize: 20,
color: Colors.black,
fontWeight: FontWeight.w400,
fontFamily: 'Anek')),
fontFamily: 'Anek',
),
),
backgroundColor: Colors.transparent,
elevation: 0,
),
@ -100,14 +111,21 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
FloatingActionButton.extended(
onPressed: () {
showModalBottomSheet(
isScrollControlled: true,
constraints: BoxConstraints(
maxHeight:
MediaQuery.of(context).size.height * 0.9,
),
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
return Consumer<ProductProvider>(
builder: (context, value, child) =>
StatefulBuilder(
builder: (context, setState) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
padding: const EdgeInsets.all(18.0),
child: TextField(
controller: searchController,
decoration: const InputDecoration(
@ -124,11 +142,13 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
),
Expanded(
child: ListView.builder(
itemCount: filteredProducts.length,
itemCount:
filteredProducts.length,
itemBuilder: (context, index) {
bool isAlreadySelected =
selectedProducts.contains(
filteredProducts[index]);
filteredProducts[
index]);
return Card(
child: ListTile(
title: Text(
@ -141,7 +161,8 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
),
),
subtitle: Text(
filteredProducts[index].SKU,
filteredProducts[index]
.SKU,
style: TextStyle(
color: isAlreadySelected
? Colors.grey
@ -167,6 +188,7 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
],
);
},
),
);
},
).whenComplete(() {

View File

@ -1,9 +1,11 @@
import 'package:cheminova/screens/Add_products_screen.dart';
import 'package:flutter/material.dart';
import 'package:cheminova/provider/pd_rd_provider.dart';
import 'package:cheminova/screens/add_products_screen.dart';
import 'package:cheminova/widgets/common_background.dart';
import 'package:cheminova/widgets/common_app_bar.dart';
import 'package:cheminova/widgets/common_drawer.dart';
import 'package:cheminova/widgets/common_elevated_button.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class UpdateInventoryScreen extends StatefulWidget {
const UpdateInventoryScreen({super.key});
@ -13,14 +15,17 @@ class UpdateInventoryScreen extends StatefulWidget {
}
class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
final List<String> principalDistributors = ['vaibhav', 'sonu', 'monu'];
final List<String> retailerDistributors = ['shivam', 'vivek'];
String? selectedDistributorType;
String? selectedDistributor;
@override
void initState() {
super.initState();
// Fetch the PdRd data when the screen is initialized
WidgetsBinding.instance.addPostFrameCallback((_) {
final provider = Provider.of<PdRdProvider>(context, listen: false);
provider.getPdRd();
});
}
@override
@ -66,7 +71,27 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
},
),
),
body: Stack(
body: Consumer<PdRdProvider>(
builder: (context, provider, child) {
if (provider.isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (provider.pdRdList.isEmpty) {
return const Center(child: Text('No distributors available.'));
}
List<String> principalDistributors = provider.pdRdList
.where((item) => item.userType == 'SalesCoOrdinator')
.map((item) => item.name)
.toList();
List<String> retailerDistributors = provider.pdRdList
.where((item) => item.userType != 'SalesCoOrdinator')
.map((item) => item.name)
.toList();
return Stack(
children: [
Column(
children: [
@ -110,7 +135,8 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
border: OutlineInputBorder(),
),
value: selectedDistributor,
items: (selectedDistributorType == 'Principal Distributor'
items:
(selectedDistributorType == 'Principal Distributor'
? principalDistributors
: retailerDistributors)
.map((String distributor) {
@ -124,7 +150,6 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
selectedDistributor = value;
});
},
// Disable the dropdown if no distributor type is selected
isExpanded: true,
isDense: true,
iconSize: 24,
@ -135,6 +160,8 @@ class _UpdateInventoryScreenState extends State<UpdateInventoryScreen> {
],
),
],
);
},
),
),
);

View File

@ -12,4 +12,6 @@ class ApiUrls {
static const String notificationUrl = '$baseUrl/get-notification-tm';
static const String fcmUrl = '${baseUrl}kyc/save-fcm-tm';
static const String getProducts = '${baseUrl}product/getAll/user/';
static const String getPdRdUrl =
'inventory/distributors-TM/RetailDistributor';
}