inventory update

This commit is contained in:
kratikpal 2024-08-14 16:56:38 +05:30
parent de188372d9
commit 5391d953a7
4 changed files with 82 additions and 27 deletions

View File

@ -47,6 +47,8 @@ class Product {
final DateTime createdAt;
final DateTime updatedAt;
final int v;
int? sale;
int? inventory;
Product({
required this.id,
@ -63,6 +65,8 @@ class Product {
required this.createdAt,
required this.updatedAt,
required this.v,
this.sale,
this.inventory,
});
factory Product.fromJson(Map<String, dynamic> json) {

View File

@ -12,11 +12,14 @@ class ProductProvider extends ChangeNotifier {
final _apiClient = ApiClient();
ProductResponse? productResponse;
List<Product> productList = [];
final List<Product> _selectedProducts = [];
bool _isLoading = false;
bool get isLoading => _isLoading;
List<Product> get selectedProducts => _selectedProducts;
void setLoading(bool loading) {
_isLoading = loading;
notifyListeners();
@ -37,4 +40,36 @@ class ProductProvider extends ChangeNotifier {
print("Error: $e");
}
}
Future<bool> submitSelectedProducts(
String addedFor, String addedForId) async {
setLoading(true);
try {
final data = {
"products": selectedProducts.map((product) {
return {
"SKU": product.SKU,
"ProductName": product.name,
"Sale": product.sale,
"Inventory": product.inventory,
};
}).toList(),
"addedFor": addedFor,
"addedForId": addedForId,
};
Response response =
await _apiClient.post(ApiUrls.submitProducts, data: data);
setLoading(false);
if (response.statusCode == 201) {
return true;
} else {
return false;
}
} catch (e) {
setLoading(false);
print("Error: $e");
return false;
}
}
}

View File

@ -16,7 +16,6 @@ class AddProductsScreen extends StatefulWidget {
}
class _AddProductsScreenState extends State<AddProductsScreen> {
List<Product> selectedProducts = [];
List<Product> filteredProducts = [];
final searchController = TextEditingController();
late ProductProvider provider;
@ -28,7 +27,7 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
}
Future<void> loadProducts() async {
final provider = Provider.of<ProductProvider>(context, listen: false);
provider = Provider.of<ProductProvider>(context, listen: false);
await provider.getProducts();
setState(() {
filteredProducts = provider.productList;
@ -87,20 +86,19 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
children: [
Column(
children: [
if (selectedProducts.isNotEmpty)
if (provider.selectedProducts.isNotEmpty)
Expanded(
child: ListView.builder(
itemCount: selectedProducts.length,
itemCount: provider.selectedProducts.length,
itemBuilder: (context, index) {
return ProductBlock(
product: selectedProducts[index]);
return ProductBlock(index: index);
},
),
),
],
),
Align(
alignment: selectedProducts.isEmpty
alignment: provider.selectedProducts.isEmpty
? Alignment.center
: Alignment.bottomCenter,
child: Padding(
@ -146,7 +144,8 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
filteredProducts.length,
itemBuilder: (context, index) {
bool isAlreadySelected =
selectedProducts.contains(
provider.selectedProducts
.contains(
filteredProducts[
index]);
return Card(
@ -173,8 +172,9 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
? null
: () {
setState(() {
selectedProducts.add(
filteredProducts[
provider
.selectedProducts
.add(filteredProducts[
index]);
});
Navigator.pop(
@ -202,7 +202,7 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
style: TextStyle(color: Colors.black),
),
),
if (selectedProducts.isNotEmpty) ...[
if (provider.selectedProducts.isNotEmpty) ...[
const SizedBox(height: 16.0),
CommonElevatedButton(
borderRadius: 30,
@ -211,6 +211,10 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
text: 'SUBMIT',
backgroundColor: const Color(0xff004791),
onPressed: () {
provider
.submitSelectedProducts("PrincipalDistributor", "66a0e19c981736b70ed4e34e")
.then((value) {
if (value) {
Navigator.push(
context,
MaterialPageRoute(
@ -218,6 +222,8 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
const DataSubmitSuccessfull(),
),
);
}
});
},
),
],
@ -235,9 +241,9 @@ class _AddProductsScreenState extends State<AddProductsScreen> {
}
class ProductBlock extends StatefulWidget {
final Product product;
final int index;
const ProductBlock({super.key, required this.product});
const ProductBlock({super.key, required this.index});
@override
_ProductBlockState createState() => _ProductBlockState();
@ -247,13 +253,15 @@ class _ProductBlockState extends State<ProductBlock> {
final saleController = TextEditingController();
final inventoryController = TextEditingController();
String? errorMessage;
late ProductProvider provider;
@override
void initState() {
super.initState();
provider = Provider.of<ProductProvider>(context, listen: false);
}
void validateInput() {
bool validateInput() {
setState(() {
if (saleController.text.isNotEmpty &&
inventoryController.text.isNotEmpty) {
@ -268,6 +276,7 @@ class _ProductBlockState extends State<ProductBlock> {
errorMessage = null;
}
});
return errorMessage == null;
}
@override
@ -281,9 +290,9 @@ class _ProductBlockState extends State<ProductBlock> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Product: ${widget.product.name}',
Text('Product: ${provider.selectedProducts[widget.index].name}',
style: const TextStyle(fontSize: 16)),
Text('SKU: ${widget.product.SKU}',
Text('SKU: ${provider.selectedProducts[widget.index].SKU}',
style: const TextStyle(fontSize: 15)),
const SizedBox(height: 8),
TextField(
@ -292,7 +301,10 @@ class _ProductBlockState extends State<ProductBlock> {
keyboardType: TextInputType.number,
// enabled: widget.product.isPurchased,
enabled: true,
onChanged: (_) => validateInput(),
onChanged: (_) => validateInput()
? provider.selectedProducts[widget.index].sale =
int.parse(saleController.text)
: null,
),
TextField(
controller: inventoryController,
@ -300,7 +312,10 @@ class _ProductBlockState extends State<ProductBlock> {
keyboardType: TextInputType.number,
// enabled: widget.product.isPurchased,
enabled: true,
onChanged: (_) => validateInput(),
onChanged: (_) => validateInput()
? provider.selectedProducts[widget.index].inventory =
int.parse(inventoryController.text)
: null,
),
if (errorMessage != null)
Padding(

View File

@ -14,4 +14,5 @@ class ApiUrls {
static const String getProducts = '${baseUrl}product/getAll/user/';
static const String getPdRdUrl =
'inventory/distributors-TM/RetailDistributor';
static const String submitProducts = 'inventory/add-TM';
}