1)shipto and bill to Api integration done
2)Opening Inventory api integration done
This commit is contained in:
parent
09193d7423
commit
077aa1e5d5
56
lib/controller/product_stock_controller.dart
Normal file
56
lib/controller/product_stock_controller.dart
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import 'package:cheminova/controller/product_mannual_service.dart';
|
||||||
|
import 'package:cheminova/controller/product_stock_service.dart';
|
||||||
|
import 'package:cheminova/models/product_stock_model.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import '../models/product_mannual_model.dart'; // Your model import
|
||||||
|
// Your service import
|
||||||
|
|
||||||
|
class ProductStockController extends GetxController {
|
||||||
|
|
||||||
|
var productStockList = <ProductStockModel>[].obs;
|
||||||
|
|
||||||
|
// Service to fetch data
|
||||||
|
final ProductStockService productStockService = ProductStockService();
|
||||||
|
|
||||||
|
// Loading state
|
||||||
|
var isLoading = false.obs;
|
||||||
|
|
||||||
|
// Method to fetch product manuals from the service
|
||||||
|
Future<void>fetchProductStock() async {
|
||||||
|
try {
|
||||||
|
// Set loading to true
|
||||||
|
isLoading.value = true;
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String? token = prefs.getString('token');
|
||||||
|
var manuals = await productStockService.getProductStock(token!);
|
||||||
|
|
||||||
|
// If data is returned, update the list
|
||||||
|
if (manuals != null) {
|
||||||
|
productStockList.value = manuals;
|
||||||
|
} else {
|
||||||
|
productStockList.value = []; // If no data, set an empty list
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Handle error here, for example logging or showing an error message
|
||||||
|
print("Error fetching product stock: $e");
|
||||||
|
} finally {
|
||||||
|
// Set loading to false
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void updateProductInventory(int index, ProductStockModel newInventory) {
|
||||||
|
productStockList[index] = newInventory ;
|
||||||
|
productStockList.refresh(); // Refresh the list to reflect changes
|
||||||
|
}
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
// Fetch product manuals when the controller is initialized
|
||||||
|
fetchProductStock();
|
||||||
|
super.onInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
40
lib/controller/product_stock_service.dart
Normal file
40
lib/controller/product_stock_service.dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import 'package:cheminova/utils/api_urls.dart';
|
||||||
|
|
||||||
|
import '../models/product_mannual_model.dart';
|
||||||
|
import '../models/product_stock_model.dart';
|
||||||
|
import '../utils/common_api_service.dart'; // Replace with your actual common API service import
|
||||||
|
|
||||||
|
class ProductStockService {
|
||||||
|
// Method to fetch product manuals using an authorization token
|
||||||
|
Future<List<ProductStockModel>?> getProductStock(String token) async {
|
||||||
|
try {
|
||||||
|
String url = ApiUrls.ProductStockUrl; // Base URL to fetch product manuals
|
||||||
|
|
||||||
|
final response = await commonApiService<List<ProductStockModel>>(
|
||||||
|
method: "GET",
|
||||||
|
url: url,
|
||||||
|
additionalHeaders: { // Pass the token here
|
||||||
|
'Authorization': 'Bearer $token',
|
||||||
|
},
|
||||||
|
fromJson: (json) {
|
||||||
|
if (json['stocks'] != null) {
|
||||||
|
// If the productManuals key is present, map the response to a list of ProductManualModel objects
|
||||||
|
final List<ProductStockModel> productstock = (json['stocks'] as List)
|
||||||
|
.map((manualJson) => ProductStockModel.fromJson(manualJson as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
return productstock; // Return the list of product manuals
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
print(e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
lib/controller/shiptoandbillto_service.dart
Normal file
40
lib/controller/shiptoandbillto_service.dart
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
import '../models/shippingandBilling_address_model.dart';
|
||||||
|
import '../utils/api_urls.dart';
|
||||||
|
import '../utils/common_api_service.dart';
|
||||||
|
|
||||||
|
class ShiptoandbilltoService {
|
||||||
|
|
||||||
|
|
||||||
|
Future<List<UserShippingAddress>?> fetchshiptobillAddress(String token) async {
|
||||||
|
try {
|
||||||
|
String url = ApiUrls
|
||||||
|
.ShiptoandBilltoAddressUrl; // Base URL to fetch product manuals
|
||||||
|
|
||||||
|
final response = await commonApiService<List<UserShippingAddress>>(
|
||||||
|
method: "GET",
|
||||||
|
url: url,
|
||||||
|
additionalHeaders: { // Pass the token here
|
||||||
|
'Authorization': 'Bearer $token',
|
||||||
|
},
|
||||||
|
fromJson: (json) {
|
||||||
|
if (json['UserShippingAddress'] != null) {
|
||||||
|
// If the productManuals key is present, map the response to a list of ProductManualModel objects
|
||||||
|
final List<
|
||||||
|
UserShippingAddress> productManuals = (json['UserShippingAddress'] as List)
|
||||||
|
.map((manualJson) => UserShippingAddress.fromJson(manualJson))
|
||||||
|
.toList();
|
||||||
|
return productManuals; // Return the list of product manuals
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return response;
|
||||||
|
} catch (e) {
|
||||||
|
print("fkfgghgh ,${e.toString()}");
|
||||||
|
//print(e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
101
lib/controller/shiptobilltoController.dart
Normal file
101
lib/controller/shiptobilltoController.dart
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// import 'package:cheminova/controller/shiptoandbillto_service.dart';
|
||||||
|
// import 'package:cheminova/models/shiping_billing_address_model.dart';
|
||||||
|
// import 'package:get/get.dart';
|
||||||
|
// import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
//
|
||||||
|
// class AddressController extends GetxController {
|
||||||
|
// final ShiptoandbilltoService _productService = ShiptoandbilltoService();
|
||||||
|
//
|
||||||
|
// var addressList = <UserShippingAddress>[].obs; // Observable list of addresses
|
||||||
|
// var selectedShippingAddressId = ''.obs;
|
||||||
|
// var selectedBillingAddressId = ''.obs;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void onInit() {
|
||||||
|
// super.onInit();
|
||||||
|
// _loadAddresses();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _loadAddresses() async {
|
||||||
|
// try {
|
||||||
|
// SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
// String? token = prefs.getString('token');
|
||||||
|
// final response = await _productService.fetchshiptobillAddress(token!);
|
||||||
|
// addressList.assignAll(response as Iterable<UserShippingAddress>);
|
||||||
|
//
|
||||||
|
// // Load previously selected addresses
|
||||||
|
// selectedShippingAddressId.value = prefs.getString('selectedShippingAddress') ?? '';
|
||||||
|
// selectedBillingAddressId.value = prefs.getString('selectedBillingAddress') ?? '';
|
||||||
|
//
|
||||||
|
// // Set the default selection to the first address if available
|
||||||
|
// if (addressList.isNotEmpty) {
|
||||||
|
// if (selectedShippingAddressId.value.isEmpty) {
|
||||||
|
// selectedShippingAddressId.value = addressList.first.id;
|
||||||
|
// }
|
||||||
|
// if (selectedBillingAddressId.value.isEmpty) {
|
||||||
|
// selectedBillingAddressId.value = addressList.first.id;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Exception: $e");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _saveSelectedAddress() async {
|
||||||
|
// SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
// await prefs.setString('selectedShippingAddress', selectedShippingAddressId.value);
|
||||||
|
// await prefs.setString('selectedBillingAddress', selectedBillingAddressId.value);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void onShippingAddressChanged(String? value) {
|
||||||
|
// if (value != null) {
|
||||||
|
// selectedShippingAddressId.value = value;
|
||||||
|
// _saveSelectedAddress();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void onBillingAddressChanged(String? value) {
|
||||||
|
// if (value != null) {
|
||||||
|
// selectedBillingAddressId.value = value;
|
||||||
|
// _saveSelectedAddress();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
import 'package:cheminova/controller/shiptoandbillto_service.dart';
|
||||||
|
import 'package:get/get_rx/src/rx_types/rx_types.dart';
|
||||||
|
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
import '../models/shippingandBilling_address_model.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class AddressController extends GetxController {
|
||||||
|
RxList<UserShippingAddress> addressList = <UserShippingAddress>[].obs;
|
||||||
|
RxString selectedShippingAddressId = ''.obs;
|
||||||
|
RxString selectedBillingAddressId = ''.obs;
|
||||||
|
Rx<UserShippingAddress?> selectedShippingAddress = Rx<UserShippingAddress?>(null);
|
||||||
|
Rx<UserShippingAddress?> selectedBillingAddress = Rx<UserShippingAddress?>(null);
|
||||||
|
|
||||||
|
void fetchAddresses() async {
|
||||||
|
// Fetch the addresses from the API
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String? token = prefs.getString('token');
|
||||||
|
var response = await ShiptoandbilltoService().fetchshiptobillAddress(token!);
|
||||||
|
if (response!= null) {
|
||||||
|
addressList.value = response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onShippingAddressChanged(String? value) {
|
||||||
|
selectedShippingAddressId.value = value ?? '';
|
||||||
|
selectedShippingAddress.value = addressList.firstWhere((address) => address.id == value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onBillingAddressChanged(String? value) {
|
||||||
|
selectedBillingAddressId.value = value ?? '';
|
||||||
|
selectedBillingAddress.value = addressList.firstWhere((address) => address.id == value,);
|
||||||
|
}
|
||||||
|
}
|
33
lib/controller/update_stock_controller.dart
Normal file
33
lib/controller/update_stock_controller.dart
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import 'package:cheminova/controller/product_stock_service.dart';
|
||||||
|
import 'package:cheminova/controller/update_stock_service.dart';
|
||||||
|
import 'package:cheminova/models/product_stock_model.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class UpdateStockController extends GetxController{
|
||||||
|
|
||||||
|
|
||||||
|
Future<void> updateProductStock(List<ProductStockModel> reason) async {
|
||||||
|
try {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String? token = prefs.getString('token'); // Get the token
|
||||||
|
|
||||||
|
if (token == null || token.isEmpty) {
|
||||||
|
throw Exception("Token is missing. Please login again.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show loading indicator
|
||||||
|
|
||||||
|
// Call the service function and pass the token, orderId, and reason
|
||||||
|
await UpdateStockService().UpdateStockProduct(token, reason);
|
||||||
|
|
||||||
|
// Optionally refresh the data or show success message
|
||||||
|
print("UpdateStockService process complete.");
|
||||||
|
} catch (e) {
|
||||||
|
print("Error: $e");
|
||||||
|
} finally {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
46
lib/controller/update_stock_service.dart
Normal file
46
lib/controller/update_stock_service.dart
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:cheminova/models/product_stock_model.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
import '../utils/api_urls.dart';
|
||||||
|
import '../utils/common_api_service.dart';
|
||||||
|
import '../utils/show_snackbar.dart';
|
||||||
|
|
||||||
|
class UpdateStockService{
|
||||||
|
|
||||||
|
// Function to handle password change functionality
|
||||||
|
Future<void> UpdateStockProduct(String token, List<ProductStockModel> stock) async {
|
||||||
|
try {
|
||||||
|
// Correct API URL with orderId passed in the URL
|
||||||
|
final String url = ApiUrls.ProductUpdateStockUrl;
|
||||||
|
|
||||||
|
// Make the PUT request
|
||||||
|
final response = await Dio().put(
|
||||||
|
url, // Use the correct URL here
|
||||||
|
data: {
|
||||||
|
"products": stock, // Send the cancellation reason as JSON
|
||||||
|
},
|
||||||
|
options: Options(
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer $token', // Pass the token in the Authorization header
|
||||||
|
'Content-Type': 'application/json', // Set content-type to application/json
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check the response status
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
print(response.data);
|
||||||
|
print("Stock Update successfully");
|
||||||
|
} else {
|
||||||
|
throw Exception('Failed to Stock Update');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Handle error
|
||||||
|
print('Error Stock Update: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
41
lib/models/product_stock_model.dart
Normal file
41
lib/models/product_stock_model.dart
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
class ProductStockModel {
|
||||||
|
final String productid;
|
||||||
|
final String name;
|
||||||
|
final String sku;
|
||||||
|
final int stock;
|
||||||
|
final int openingInventory;
|
||||||
|
|
||||||
|
ProductStockModel({
|
||||||
|
required this.productid,
|
||||||
|
required this.name,
|
||||||
|
required this.sku,
|
||||||
|
required this.stock,
|
||||||
|
required this.openingInventory,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory ProductStockModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return ProductStockModel(
|
||||||
|
productid: json['productid']??"2323",
|
||||||
|
name: json['name']??"rert",
|
||||||
|
sku: json['SKU']??"",
|
||||||
|
stock: json['Stock']??"",
|
||||||
|
openingInventory: json['openingInventory']??""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a ProductStock instance to a JSON map
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'productid': productid,
|
||||||
|
'name': name,
|
||||||
|
'SKU': sku,
|
||||||
|
'Stock': stock,
|
||||||
|
'openingInventory':openingInventory
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ProductStock(productid: $productid, name: $name, sku: $sku, stock: $stock,openingInventory:$openingInventory)';
|
||||||
|
}
|
||||||
|
}
|
56
lib/models/shippingandBilling_address_model.dart
Normal file
56
lib/models/shippingandBilling_address_model.dart
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
class UserShippingAddress {
|
||||||
|
final String id;
|
||||||
|
final String name;
|
||||||
|
final String phoneNumber;
|
||||||
|
final String street;
|
||||||
|
final String district;
|
||||||
|
final String city;
|
||||||
|
final String state;
|
||||||
|
final String postalCode;
|
||||||
|
final String country;
|
||||||
|
final String tradeName;
|
||||||
|
final bool isDefault;
|
||||||
|
final String user;
|
||||||
|
DateTime? createdAt;
|
||||||
|
DateTime? updatedAt;
|
||||||
|
|
||||||
|
UserShippingAddress({
|
||||||
|
required this.id,
|
||||||
|
required this.name,
|
||||||
|
required this.phoneNumber,
|
||||||
|
required this.street,
|
||||||
|
required this.district,
|
||||||
|
required this.city,
|
||||||
|
required this.state,
|
||||||
|
required this.postalCode,
|
||||||
|
required this.country,
|
||||||
|
required this.tradeName,
|
||||||
|
required this.isDefault,
|
||||||
|
required this.user,
|
||||||
|
this.createdAt,
|
||||||
|
this.updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UserShippingAddress.fromJson(Map<String, dynamic> json) {
|
||||||
|
return UserShippingAddress(
|
||||||
|
id: json['_id'] ?? '',
|
||||||
|
name: json['Name'] ?? '',
|
||||||
|
phoneNumber: json['phoneNumber'] ?? '',
|
||||||
|
street: json['street'] ?? '',
|
||||||
|
district: json['district'] ?? '',
|
||||||
|
city: json['city'] ?? '',
|
||||||
|
state: json['state'] ?? '',
|
||||||
|
postalCode: json['postalCode'] ?? '',
|
||||||
|
country: json['country'] ?? '',
|
||||||
|
tradeName: json['tradeName'] ?? '',
|
||||||
|
isDefault: json['isDefault'] ?? false,
|
||||||
|
user: json['user'] ?? '',
|
||||||
|
createdAt: DateTime.parse(json['createdAt']),
|
||||||
|
updatedAt: DateTime.parse(json['updatedAt']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
String toStringFullAddress() {
|
||||||
|
return "$street, $city, $state, $postalCode, $country";
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:cheminova/controller/home_controller.dart';
|
import 'package:cheminova/controller/home_controller.dart';
|
||||||
import 'package:cheminova/screens/announment/announment_screen.dart';
|
import 'package:cheminova/screens/announment/announment_screen.dart';
|
||||||
import 'package:cheminova/screens/inventory/inventory_management_screen.dart';
|
import 'package:cheminova/screens/inventory/inventory_management_screen.dart';
|
||||||
|
import 'package:cheminova/screens/opening%20Inventory/inventory_management_screen.dart';
|
||||||
import 'package:cheminova/screens/order/order_tracking_screen.dart';
|
import 'package:cheminova/screens/order/order_tracking_screen.dart';
|
||||||
import 'package:cheminova/screens/order_management/order_management_screen.dart';
|
import 'package:cheminova/screens/order_management/order_management_screen.dart';
|
||||||
import 'package:cheminova/screens/product/product_catalog_screen.dart';
|
import 'package:cheminova/screens/product/product_catalog_screen.dart';
|
||||||
@ -139,6 +140,12 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||||||
() => AnnouncementScreen(), // Navigates to RetailDistributerOnBoardingScreen.
|
() => AnnouncementScreen(), // Navigates to RetailDistributerOnBoardingScreen.
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
HomeCard(
|
||||||
|
title: 'Opening Inventory',
|
||||||
|
onTap: () => Get.to(
|
||||||
|
() => OpeningInventoryManagementScreen(), // Navigates to RetailDistributerOnBoardingScreen.
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
290
lib/screens/opening Inventory/inventory_management_screen.dart
Normal file
290
lib/screens/opening Inventory/inventory_management_screen.dart
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:cheminova/controller/product_stock_controller.dart';
|
||||||
|
import 'package:cheminova/models/place_order_list_model.dart';
|
||||||
|
import 'package:cheminova/models/product_stock_model.dart';
|
||||||
|
import 'package:cheminova/screens/opening%20Inventory/update_stock_screen.dart';
|
||||||
|
import 'package:cheminova/screens/order_management/order_management_detail_screen.dart';
|
||||||
|
import 'package:cheminova/widgets/input_field.dart';
|
||||||
|
import 'package:cheminova/widgets/my_drawer.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import '../../controller/cart_controller.dart';
|
||||||
|
import '../../controller/get_order_placed_controller.dart';
|
||||||
|
import '../../models/product_model1.dart';
|
||||||
|
|
||||||
|
|
||||||
|
class OpeningInventoryManagementScreen extends StatefulWidget {
|
||||||
|
final ProductStockModel? productModel;
|
||||||
|
// PlacedOrderList? placeOrder;
|
||||||
|
OpeningInventoryManagementScreen({super.key, this.productModel,});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<OpeningInventoryManagementScreen> createState() => _OpeningInventoryManagementScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OpeningInventoryManagementScreenState extends State<OpeningInventoryManagementScreen> {
|
||||||
|
final _searchController = TextEditingController();
|
||||||
|
//final List<String> _filterList = ["Order Status", "Date Range"];
|
||||||
|
|
||||||
|
final ProductStockController _getProductStockController = Get.put(ProductStockController());
|
||||||
|
final CartController _cartController = Get.put(CartController());
|
||||||
|
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
|
||||||
|
GlobalKey<RefreshIndicatorState>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
getOrder1(); // Fetch orders when the screen initializes
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onRefresh() async {
|
||||||
|
await getOrder1();
|
||||||
|
await Future.delayed(Duration(seconds: 1));
|
||||||
|
}
|
||||||
|
// Fetches orders from the API
|
||||||
|
Future<void> getOrder1() async {
|
||||||
|
await _getProductStockController.fetchProductStock();
|
||||||
|
print("Opening order Inventory fetched successfully");
|
||||||
|
}
|
||||||
|
// Capitalizes the first letter of the string
|
||||||
|
String capitalizeFirstLetter(String text) {
|
||||||
|
if (text.isEmpty) return text;
|
||||||
|
return text[0].toUpperCase() + text.substring(1).toLowerCase();
|
||||||
|
}
|
||||||
|
// Formats the date received from the API
|
||||||
|
String formatDate(String apiDate) {
|
||||||
|
DateTime parsedDate = DateTime.parse(apiDate);
|
||||||
|
String formattedDate = DateFormat('dd-MMM-yyyy').format(parsedDate);
|
||||||
|
return formattedDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
extendBodyBehindAppBar: true,
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
elevation: 0,
|
||||||
|
leading: Builder(
|
||||||
|
builder: (context) {
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => Scaffold.of(context).openDrawer(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: SvgPicture.asset('assets/svg/menu.svg'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Get.back(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: SvgPicture.asset('assets/svg/back_arrow.svg'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
title: const Text("Opening Inventory "),
|
||||||
|
),
|
||||||
|
drawer: MyDrawer(),
|
||||||
|
body: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Image.asset('assets/images/image_1.png', fit: BoxFit.cover),
|
||||||
|
SafeArea(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||||
|
child: RefreshIndicator(
|
||||||
|
key: _refreshIndicatorKey,
|
||||||
|
onRefresh: _onRefresh,
|
||||||
|
color: Colors.black,
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
InputField(
|
||||||
|
hintText: "Search Order",
|
||||||
|
labelText: "Search Order",
|
||||||
|
|
||||||
|
controller: _searchController,
|
||||||
|
onChanged: (value) {
|
||||||
|
//searchOrder(value);// Call search function with input value
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: Get.height * 0.035),
|
||||||
|
Card(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 18),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(19),
|
||||||
|
side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||||
|
),
|
||||||
|
color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// SizedBox(
|
||||||
|
// height: Get.height * 0.05,
|
||||||
|
// child: ListView.builder(
|
||||||
|
// shrinkWrap: true,
|
||||||
|
// scrollDirection: Axis.horizontal,
|
||||||
|
// itemCount: _filterList.length,
|
||||||
|
// itemBuilder: (context, index) => Padding(
|
||||||
|
// padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
|
// child: Chip(
|
||||||
|
// label: Text(
|
||||||
|
// _filterList[index],
|
||||||
|
// style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w500),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
SizedBox(
|
||||||
|
height: Get.height * 0.6,
|
||||||
|
child: Obx(() {
|
||||||
|
// Use a set to keep track of unique order IDs
|
||||||
|
final Set<String> uniqueOrderIds = {};
|
||||||
|
final List<ProductStockModel> uniqueOrders = [];
|
||||||
|
// Loop through the fetched orders to filter unique orders
|
||||||
|
for (var order in _getProductStockController.productStockList) {
|
||||||
|
if (uniqueOrderIds.add(order.productid)) {
|
||||||
|
uniqueOrders.add(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Displaying unique orders in a ListView
|
||||||
|
return ListView.builder(
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemCount: uniqueOrders.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final order = uniqueOrders[index];
|
||||||
|
|
||||||
|
// Combine product names into a single string
|
||||||
|
// final productNames = order.name
|
||||||
|
// .map((item) => capitalizeFirstLetter(item.name))
|
||||||
|
// .join(', ');
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: Card(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 8, 8, 0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Product ID: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)),
|
||||||
|
Text("${order.productid}")
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 8, 8, 0),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, // Aligns the Column to the top of the Text
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Product Names: ",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, // Aligns text to the right within the Column
|
||||||
|
children: [
|
||||||
|
|
||||||
|
Text(
|
||||||
|
'${order.name}', // Adds index and trims whitespace
|
||||||
|
textAlign: TextAlign.left, // Aligns text to the right
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: 14,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 8, 8, 0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("SKU: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)),
|
||||||
|
Text("${order.sku}")
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 8, 8, 0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text("Opening Inventory: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)),
|
||||||
|
Text("${order.openingInventory}")
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width * 0.5,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: (){
|
||||||
|
Get.to(InventoryUpdateStockScreen(products: _getProductStockController.productStockList, selectedProductId: _getProductStockController.productStockList[index].productid,));
|
||||||
|
},
|
||||||
|
|
||||||
|
// Navigate to detail screen
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
backgroundColor: const Color(0xFF004791),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10)),
|
||||||
|
),
|
||||||
|
child: Text("Update Inventory", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,226 @@
|
|||||||
|
import 'package:cheminova/models/product_model.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
|
class OpeningInventoryProductDetailScreen extends StatefulWidget {
|
||||||
|
final ProductModel product;
|
||||||
|
|
||||||
|
const OpeningInventoryProductDetailScreen({
|
||||||
|
super.key,
|
||||||
|
required this.product,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<OpeningInventoryProductDetailScreen> createState() =>
|
||||||
|
_OpeningInventoryProductDetailScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _OpeningInventoryProductDetailScreenState
|
||||||
|
extends State<OpeningInventoryProductDetailScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
extendBodyBehindAppBar: true,
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
elevation: 0,
|
||||||
|
leading: GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
'assets/svg/menu.svg',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Get.back(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
'assets/svg/back_arrow.svg',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
title: const Text(
|
||||||
|
"Inventory Product Detail",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/image_1.png',
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
SafeArea(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: Get.height * 0.02,
|
||||||
|
),
|
||||||
|
Card(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(19),
|
||||||
|
side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||||
|
),
|
||||||
|
color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Container(
|
||||||
|
height: Get.height * 0.4,
|
||||||
|
width: Get.width * 0.7,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
width: 4,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
child: Image.asset(
|
||||||
|
widget.product.image,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Card(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
|
child: Text(
|
||||||
|
"Product Name: ${widget.product.name}",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.fromLTRB(8, 8, 8, 8),
|
||||||
|
child: Text(
|
||||||
|
"Descrition: ${widget.product.description}",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Card(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
|
child: Text(
|
||||||
|
"Stock Information",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
|
child: Text(
|
||||||
|
"Current Stock: ${widget.product.quantity}",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
|
child: Text(
|
||||||
|
"Minimum Stock Level: 20",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
|
child: Text(
|
||||||
|
"Last Restock Date: MM/DD/YYYY",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: Get.width,
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.fromLTRB(8, 8, 8, 8),
|
||||||
|
child: Text(
|
||||||
|
"Supplier: ABC Supplier",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
367
lib/screens/opening Inventory/update_stock_screen.dart
Normal file
367
lib/screens/opening Inventory/update_stock_screen.dart
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
//
|
||||||
|
// import 'package:flutter_svg/svg.dart';
|
||||||
|
// import 'package:get/get.dart';
|
||||||
|
// import 'package:get/get_core/src/get_main.dart';
|
||||||
|
// import 'package:google_fonts/google_fonts.dart';
|
||||||
|
//
|
||||||
|
// import '../../controller/update_stock_controller.dart';
|
||||||
|
// import '../../models/product_stock_model.dart';
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
//
|
||||||
|
// import '../../utils/show_snackbar.dart';
|
||||||
|
// import '../../widgets/input_field.dart';
|
||||||
|
// import 'inventory_management_screen.dart';
|
||||||
|
// class InventoryUpdateStockScreen extends StatefulWidget {
|
||||||
|
// final ProductStockModel product;
|
||||||
|
//
|
||||||
|
// const InventoryUpdateStockScreen({
|
||||||
|
// super.key,
|
||||||
|
// required this.product,
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// State<InventoryUpdateStockScreen> createState() => _InventoryUpdateStockScreenState();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// class _InventoryUpdateStockScreenState extends State<InventoryUpdateStockScreen> {
|
||||||
|
// final _textController = TextEditingController();
|
||||||
|
// final UpdateStockController _updateStockController = Get.put(UpdateStockController());
|
||||||
|
//
|
||||||
|
// // Map to store the updated stock quantities for each product
|
||||||
|
// final Map<String, int> _updatedStockMap = {};
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// super.initState();
|
||||||
|
// // Set the initial value of the text controller if there's an updated stock for the current product
|
||||||
|
// _textController.text = _updatedStockMap[widget.product.productid]?.toString() ?? widget.product.stock.toString();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _onUpdateStock() async {
|
||||||
|
// try {
|
||||||
|
// // Parse the new stock quantity from the text controller
|
||||||
|
// int? newStockQuantity = int.tryParse(_textController.text.trim());
|
||||||
|
//
|
||||||
|
// // Check if the parsed quantity is valid
|
||||||
|
// if (newStockQuantity == null || newStockQuantity < 0) {
|
||||||
|
// showSnackbar("Please enter a valid stock quantity.");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Update the map with the new stock quantity for the current product
|
||||||
|
// setState(() {
|
||||||
|
// _updatedStockMap[widget.product.productid] = newStockQuantity;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // Create a list of ProductStockModel instances with updated stock
|
||||||
|
// List<ProductStockModel> productStockList = [
|
||||||
|
// ProductStockModel(
|
||||||
|
// productid: widget.product.productid,
|
||||||
|
// name: widget.product.name,
|
||||||
|
// sku: widget.product.sku,
|
||||||
|
// stock: widget.product.stock,
|
||||||
|
// openingInventory: newStockQuantity, // Update stock with new quantity
|
||||||
|
// ),
|
||||||
|
// ];
|
||||||
|
//
|
||||||
|
// // Call the updateStock function
|
||||||
|
// final update = await _updateStockController.updateProductStock(productStockList);
|
||||||
|
//
|
||||||
|
// // Optionally, show a confirmation message or navigate to another screen
|
||||||
|
// showSnackbar("Opening Inventory updated successfully");
|
||||||
|
// Get.to(OpeningInventoryManagementScreen());
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Error updating stock: $e");
|
||||||
|
// showSnackbar("Error updating stock. Please try again.");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void didUpdateWidget(covariant InventoryUpdateStockScreen oldWidget) {
|
||||||
|
// super.didUpdateWidget(oldWidget);
|
||||||
|
// // Update the text controller with the new product's stock or the previously updated value
|
||||||
|
// _textController.text = _updatedStockMap[widget.product.productid]?.toString() ?? widget.product.stock.toString();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Scaffold(
|
||||||
|
// extendBodyBehindAppBar: true,
|
||||||
|
// appBar: AppBar(
|
||||||
|
// centerTitle: true,
|
||||||
|
// backgroundColor: Colors.transparent,
|
||||||
|
// elevation: 0,
|
||||||
|
// leading: GestureDetector(
|
||||||
|
// onTap: () {},
|
||||||
|
// child: Padding(
|
||||||
|
// padding: const EdgeInsets.all(16.0),
|
||||||
|
// child: SvgPicture.asset(
|
||||||
|
// 'assets/svg/menu.svg',
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// actions: [
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () => Get.back(),
|
||||||
|
// child: Padding(
|
||||||
|
// padding: const EdgeInsets.all(8.0),
|
||||||
|
// child: SvgPicture.asset(
|
||||||
|
// 'assets/svg/back_arrow.svg',
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// title: const Text(
|
||||||
|
// "Update Inventory",
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// body: Stack(
|
||||||
|
// fit: StackFit.expand,
|
||||||
|
// children: [
|
||||||
|
// Image.asset(
|
||||||
|
// 'assets/images/image_1.png',
|
||||||
|
// fit: BoxFit.cover,
|
||||||
|
// ),
|
||||||
|
// SafeArea(
|
||||||
|
// child: Column(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// SizedBox(
|
||||||
|
// height: Get.height * 0.02,
|
||||||
|
// ),
|
||||||
|
// Card(
|
||||||
|
// margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(19),
|
||||||
|
// side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||||
|
// ),
|
||||||
|
// color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||||
|
// child: Padding(
|
||||||
|
// padding: const EdgeInsets.all(12.0),
|
||||||
|
// child: Column(
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// Card(
|
||||||
|
// child: SizedBox(
|
||||||
|
// width: Get.width,
|
||||||
|
// child: Padding(
|
||||||
|
// padding: const EdgeInsets.all(12),
|
||||||
|
// child: Row(
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// "Product Name: ",
|
||||||
|
// style: GoogleFonts.roboto(
|
||||||
|
// fontSize: Get.width * 0.04,
|
||||||
|
// fontWeight: FontWeight.w700,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Text("${widget.product.name}"),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// InputField(
|
||||||
|
// hintText: "Enter New Opening Inventory Quantity:",
|
||||||
|
// labelText: "Enter New Opening Inventory Quantity:",
|
||||||
|
// controller: _textController,
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: Get.height * 0.04),
|
||||||
|
// SizedBox(
|
||||||
|
// width: Get.width * 0.9,
|
||||||
|
// height: Get.height * 0.06,
|
||||||
|
// child: ElevatedButton(
|
||||||
|
// onPressed: () {
|
||||||
|
// _onUpdateStock();
|
||||||
|
// },
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// foregroundColor: Colors.white,
|
||||||
|
// backgroundColor: const Color(0xFF00784C),
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(10),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: Text(
|
||||||
|
// "Update Inventory Quantity",
|
||||||
|
// style: GoogleFonts.roboto(
|
||||||
|
// fontSize: Get.width * 0.05,
|
||||||
|
// fontWeight: FontWeight.w600,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
|
import '../../controller/update_stock_controller.dart';
|
||||||
|
import '../../models/product_stock_model.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../utils/show_snackbar.dart';
|
||||||
|
import '../../widgets/input_field.dart';
|
||||||
|
import 'inventory_management_screen.dart';
|
||||||
|
|
||||||
|
class InventoryUpdateStockScreen extends StatefulWidget {
|
||||||
|
final List<ProductStockModel> products;
|
||||||
|
final String selectedProductId;
|
||||||
|
|
||||||
|
const InventoryUpdateStockScreen({
|
||||||
|
super.key,
|
||||||
|
required this.products,
|
||||||
|
required this.selectedProductId,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<InventoryUpdateStockScreen> createState() => _InventoryUpdateStockScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _InventoryUpdateStockScreenState extends State<InventoryUpdateStockScreen> {
|
||||||
|
late TextEditingController _textController;
|
||||||
|
final UpdateStockController _updateStockController = Get.put(UpdateStockController());
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// Initialize text controller with the stock of the selected product
|
||||||
|
final selectedProduct = widget.products.firstWhere((product) => product.productid == widget.selectedProductId);
|
||||||
|
_textController = TextEditingController(text: selectedProduct.stock.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onUpdateStock() async {
|
||||||
|
try {
|
||||||
|
int? newStockQuantity = int.tryParse(_textController.text.trim());
|
||||||
|
|
||||||
|
if (newStockQuantity == null || newStockQuantity < 0) {
|
||||||
|
showSnackbar("Please enter a valid stock quantity.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update only the stock for the selected product while keeping others the same
|
||||||
|
List<ProductStockModel> updatedProductStockList = widget.products.map((product) {
|
||||||
|
if (product.productid == widget.selectedProductId) {
|
||||||
|
return ProductStockModel(
|
||||||
|
productid: product.productid,
|
||||||
|
name: product.name,
|
||||||
|
sku: product.sku,
|
||||||
|
stock: newStockQuantity,
|
||||||
|
openingInventory: newStockQuantity,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
// Call the updateStock function with the updated list
|
||||||
|
final update = await _updateStockController.updateProductStock(updatedProductStockList);
|
||||||
|
|
||||||
|
showSnackbar("Opening Inventory for ${widget.selectedProductId} updated successfully");
|
||||||
|
Get.to(OpeningInventoryManagementScreen());
|
||||||
|
} catch (e) {
|
||||||
|
print("Error updating stock: $e");
|
||||||
|
showSnackbar("Error updating stock. Please try again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final selectedProduct = widget.products.firstWhere((product) => product.productid == widget.selectedProductId);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
extendBodyBehindAppBar: true,
|
||||||
|
appBar: AppBar(
|
||||||
|
centerTitle: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
elevation: 0,
|
||||||
|
leading: GestureDetector(
|
||||||
|
onTap: () {},
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
'assets/svg/menu.svg',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => Get.back(),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
'assets/svg/back_arrow.svg',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
title: const Text(
|
||||||
|
"Update Inventory",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
'assets/images/image_1.png',
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
|
SafeArea(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: Get.height * 0.02),
|
||||||
|
Text(
|
||||||
|
"Product Name: ${selectedProduct.name}",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InputField(
|
||||||
|
hintText: "Enter New Opening Inventory Quantity:",
|
||||||
|
labelText: "Enter New Opening Inventory Quantity:",
|
||||||
|
controller: _textController,
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: _onUpdateStock,
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
backgroundColor: const Color(0xFF00784C),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
"Update Inventory Quantity",
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.05,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,3 +1,434 @@
|
|||||||
|
// import 'dart:ffi';
|
||||||
|
// import 'package:cheminova/controller/get_order_placed_controller.dart';
|
||||||
|
// import 'package:cheminova/models/added_by_model.dart';
|
||||||
|
// import 'package:cheminova/models/category_model.dart';
|
||||||
|
// import 'package:cheminova/utils/show_snackbar.dart';
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
// import 'package:flutter_svg/svg.dart';
|
||||||
|
// import 'package:get/get.dart';
|
||||||
|
// import 'package:google_fonts/google_fonts.dart';
|
||||||
|
// import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
//
|
||||||
|
// import '../../controller/cart_controller.dart';
|
||||||
|
// import '../../controller/place_order_controller.dart';
|
||||||
|
// import '../../controller/place_order_service.dart';
|
||||||
|
// import '../../controller/product_controller.dart';
|
||||||
|
// import '../../controller/product_service.dart';
|
||||||
|
// import '../../models/brand_model.dart';
|
||||||
|
// import '../../models/oder_place_model.dart';
|
||||||
|
// import '../../models/product_model1.dart';
|
||||||
|
// import '../../widgets/my_drawer.dart';
|
||||||
|
// import '../../widgets/product_card.dart';
|
||||||
|
// import 'order_confermation_screen.dart';
|
||||||
|
//
|
||||||
|
// class CheckoutScreen extends StatefulWidget {
|
||||||
|
// final Product? productModel;
|
||||||
|
//
|
||||||
|
// PlacedOrderModel? placeOrder;
|
||||||
|
// List<Product>? selectedProducts;
|
||||||
|
// CheckoutScreen({super.key, this.productModel, this.placeOrder,this.selectedProducts});
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// State<CheckoutScreen> createState() => _CheckoutScreenState();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// class _CheckoutScreenState extends State<CheckoutScreen> {
|
||||||
|
// final CartController _cartController = Get.put(CartController());
|
||||||
|
// final ProductService _productService = ProductService();
|
||||||
|
// final ProductController _productController = Get.put(ProductController());
|
||||||
|
// final OrderPlacedController _orderPlacedController =
|
||||||
|
// Get.put(OrderPlacedController());
|
||||||
|
// final GetPlacedOrderController _getPlacedOrderController = Get.put(GetPlacedOrderController());
|
||||||
|
//
|
||||||
|
// int currentPage = 1;
|
||||||
|
// String _groupValue = "cheque";
|
||||||
|
//
|
||||||
|
// final List<String> _addressList = [
|
||||||
|
// 'Home - 123 Street, City',
|
||||||
|
// 'Office - 456 Avenue, City',
|
||||||
|
// 'Warehouse - 789 Blvd, City',
|
||||||
|
// ];
|
||||||
|
//
|
||||||
|
// String? _selectedShippingAddress;
|
||||||
|
// String? _selectedBillingAddress;
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// super.initState();
|
||||||
|
// // _getOrder();
|
||||||
|
// _loadSelectedAddress();
|
||||||
|
// _loadSelectedPaymentMode();
|
||||||
|
//
|
||||||
|
// if (_addressList.isNotEmpty) {
|
||||||
|
// _selectedShippingAddress = _addressList.first;
|
||||||
|
// _selectedBillingAddress = _addressList.first;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _saveSelectedAddress() async {
|
||||||
|
// SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
// await prefs.setString('selectedShippingAddress', _selectedShippingAddress!);
|
||||||
|
// await prefs.setString('selectedBillingAddress', _selectedBillingAddress!);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _onShippingAddressChanged(String? value) {
|
||||||
|
// setState(() {
|
||||||
|
// _selectedShippingAddress = value;
|
||||||
|
// });
|
||||||
|
// _saveSelectedAddress();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _onBillingAddressChanged(String? value) {
|
||||||
|
// setState(() {
|
||||||
|
// _selectedBillingAddress = value;
|
||||||
|
// });
|
||||||
|
// _saveSelectedAddress();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _loadSelectedAddress() async {
|
||||||
|
// SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
// setState(() {
|
||||||
|
// _selectedShippingAddress =
|
||||||
|
// prefs.getString('selectedShippingAddress') ?? _addressList.first;
|
||||||
|
// _selectedBillingAddress =
|
||||||
|
// prefs.getString('selectedBillingAddress') ?? _addressList.first;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _onPaymentModeChanged(String? value) {
|
||||||
|
// setState(() {
|
||||||
|
// _groupValue = value!;
|
||||||
|
// });
|
||||||
|
// _saveSelectedPaymentMode();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _saveSelectedPaymentMode() async {
|
||||||
|
// SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
// await prefs.setString('selectedPaymentMode', _groupValue);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _loadSelectedPaymentMode() async {
|
||||||
|
// SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
// setState(() {
|
||||||
|
// _groupValue = prefs.getString('selectedPaymentMode') ?? 'cheque';
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // void _getOrder(){
|
||||||
|
// // final details = _getPlacedOrderController.getOrder(widget.productModel!.id);
|
||||||
|
// // print("dffgfg,$details");
|
||||||
|
// // }
|
||||||
|
// void _onPlaceOrder() async {
|
||||||
|
// try {
|
||||||
|
// // Map the cart items (Product) to OrderItem objects
|
||||||
|
// List<OrderItem> orderItems = _cartController.selectedProducts.map<OrderItem>((product) {
|
||||||
|
// return OrderItem(
|
||||||
|
// id: product.id,
|
||||||
|
// name: product.name,
|
||||||
|
// price: product.price.toDouble(),
|
||||||
|
// sku: product.sku,
|
||||||
|
// gst: product.gst.toDouble(),
|
||||||
|
// hsnCode: product.hsnCode,
|
||||||
|
// description: product.description,
|
||||||
|
// productStatus: product.productStatus,
|
||||||
|
// image: [],
|
||||||
|
// createdAt: product.createdAt,
|
||||||
|
// updatedAt: product.createdAt,
|
||||||
|
// count: product.quantity,
|
||||||
|
//
|
||||||
|
// //category:product.category,
|
||||||
|
// category:Category(id: product.category.id, categoryName: product.category.categoryName),
|
||||||
|
// // brand:product.brand,
|
||||||
|
// brand:Brand(id: product.brand.id, brandName: product.brand.brandName),
|
||||||
|
// v: 0, addedBy: product.addedBy,
|
||||||
|
// );
|
||||||
|
// }).toList();
|
||||||
|
//
|
||||||
|
// // Update the placedOrder1 value
|
||||||
|
// _orderPlacedController.placedOrder1.value= PlacedOrderModel(
|
||||||
|
// paymentMode: _groupValue,
|
||||||
|
// shipTo: _selectedShippingAddress!,
|
||||||
|
// billTo: _selectedBillingAddress!,
|
||||||
|
// orderItems: orderItems,
|
||||||
|
// gstTotal: _cartController.gstTotal.value,
|
||||||
|
// grandTotal: _cartController.grandTotal.value,
|
||||||
|
// subtotal: _cartController.subtotal.value,
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// await _orderPlacedController.placeOrder();
|
||||||
|
//
|
||||||
|
// if (_orderPlacedController.isLoading.value) {
|
||||||
|
// showSnackbar("Order Placed Successfully");
|
||||||
|
// Get.to(() => OrderConfermationScreen(
|
||||||
|
// placedOrder: _orderPlacedController.placedOrder1.value,
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print("PlaceOrderScreen error: $e");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Scaffold(
|
||||||
|
// extendBodyBehindAppBar: true,
|
||||||
|
// appBar: AppBar(
|
||||||
|
// backgroundColor: Colors.transparent,
|
||||||
|
// elevation: 0,
|
||||||
|
// leading: Builder(
|
||||||
|
// builder: (context) {
|
||||||
|
// return GestureDetector(
|
||||||
|
// onTap: () => Scaffold.of(context).openDrawer(),
|
||||||
|
// child: Padding(
|
||||||
|
// padding: const EdgeInsets.all(16.0),
|
||||||
|
// child: SvgPicture.asset(
|
||||||
|
// 'assets/svg/menu.svg',
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// actions: [
|
||||||
|
// GestureDetector(
|
||||||
|
// onTap: () => Get.back(),
|
||||||
|
// child: Padding(
|
||||||
|
// padding: EdgeInsets.all(Get.width * 0.02),
|
||||||
|
// child: SvgPicture.asset(
|
||||||
|
// 'assets/svg/back_arrow.svg',
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// title: const Text("Checkout"),
|
||||||
|
// ),
|
||||||
|
// drawer: const MyDrawer(),
|
||||||
|
// body: Stack(
|
||||||
|
// fit: StackFit.expand,
|
||||||
|
// children: [
|
||||||
|
// Image.asset(
|
||||||
|
// 'assets/images/image_1.png',
|
||||||
|
// fit: BoxFit.cover,
|
||||||
|
// ),
|
||||||
|
// SafeArea(
|
||||||
|
// child: Column(
|
||||||
|
// children: [
|
||||||
|
// SizedBox(height: Get.height * 0.02),
|
||||||
|
// Card(
|
||||||
|
// margin: EdgeInsets.symmetric(horizontal: Get.width * 0.05),
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(19),
|
||||||
|
// side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||||
|
// ),
|
||||||
|
// color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||||
|
// child: Padding(
|
||||||
|
// padding: EdgeInsets.all(Get.width * 0.04),
|
||||||
|
// child: Column(
|
||||||
|
// mainAxisSize: MainAxisSize.min,
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// Padding(
|
||||||
|
// padding: EdgeInsets.symmetric(
|
||||||
|
// horizontal: Get.width * 0.04),
|
||||||
|
// child: Text(
|
||||||
|
// 'Shipping Information',
|
||||||
|
// style: GoogleFonts.roboto(
|
||||||
|
// fontSize: Get.width * 0.04,
|
||||||
|
// fontWeight: FontWeight.w500,
|
||||||
|
// color: Colors.black,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: 5,),
|
||||||
|
// DropdownButtonFormField<String>(
|
||||||
|
// decoration: InputDecoration(
|
||||||
|
// labelText: 'Shipping Address:',
|
||||||
|
// hintText: 'Select Shipping Address',
|
||||||
|
// border: OutlineInputBorder(),
|
||||||
|
// ),
|
||||||
|
// value: _selectedShippingAddress,
|
||||||
|
// items: _addressList.map((String address) {
|
||||||
|
// return DropdownMenuItem<String>(
|
||||||
|
// value: address,
|
||||||
|
// child: Text(address),
|
||||||
|
// );
|
||||||
|
// }).toList(),
|
||||||
|
// onChanged: _onShippingAddressChanged,
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: Get.height * 0.02),
|
||||||
|
// DropdownButtonFormField<String>(
|
||||||
|
// decoration: InputDecoration(
|
||||||
|
// labelText: 'Billing Address:',
|
||||||
|
// hintText: 'Select Billing Address',
|
||||||
|
// border: OutlineInputBorder(),
|
||||||
|
// ),
|
||||||
|
// value: _selectedBillingAddress,
|
||||||
|
// items: _addressList.map((String address) {
|
||||||
|
// return DropdownMenuItem<String>(
|
||||||
|
// value: address,
|
||||||
|
// child: Text(address),
|
||||||
|
// );
|
||||||
|
// }).toList(),
|
||||||
|
// onChanged: _onBillingAddressChanged,
|
||||||
|
// ),
|
||||||
|
// Padding(
|
||||||
|
// padding: EdgeInsets.symmetric(
|
||||||
|
// horizontal: Get.width * 0.04),
|
||||||
|
// child: Text(
|
||||||
|
// 'Payment Information',
|
||||||
|
// style: GoogleFonts.roboto(
|
||||||
|
// fontSize: Get.width * 0.04,
|
||||||
|
// fontWeight: FontWeight.w500,
|
||||||
|
// color: Colors.black,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Card(
|
||||||
|
// child: ListView(
|
||||||
|
// padding: EdgeInsets.zero,
|
||||||
|
// shrinkWrap: true,
|
||||||
|
// children: [
|
||||||
|
// SizedBox(
|
||||||
|
// height: Get.height * 0.035,
|
||||||
|
// child: RadioListTile(
|
||||||
|
// title: const Text("Cheque"),
|
||||||
|
// contentPadding: EdgeInsets.zero,
|
||||||
|
// value: "cheque",
|
||||||
|
// groupValue: _groupValue,
|
||||||
|
// onChanged: _onPaymentModeChanged,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(
|
||||||
|
// height: Get.height * 0.035,
|
||||||
|
// child: RadioListTile(
|
||||||
|
// title: const Text("Online transfer"),
|
||||||
|
// contentPadding: EdgeInsets.zero,
|
||||||
|
// value: "online-transfer",
|
||||||
|
// groupValue: _groupValue,
|
||||||
|
// onChanged: _onPaymentModeChanged,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(
|
||||||
|
// child: RadioListTile(
|
||||||
|
// title: const Text("Credit"),
|
||||||
|
// contentPadding: EdgeInsets.zero,
|
||||||
|
// value: "credit",
|
||||||
|
// groupValue: _groupValue,
|
||||||
|
// onChanged: _onPaymentModeChanged,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Padding(
|
||||||
|
// padding: EdgeInsets.symmetric(
|
||||||
|
// horizontal: Get.width * 0.04),
|
||||||
|
// child: Text(
|
||||||
|
// 'Order Summary',
|
||||||
|
// style: GoogleFonts.roboto(
|
||||||
|
// fontSize: Get.width * 0.04,
|
||||||
|
// fontWeight: FontWeight.w500,
|
||||||
|
// color: Colors.black,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Card(
|
||||||
|
// child: Column(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// SizedBox(
|
||||||
|
// height: Get.height * 0.22,
|
||||||
|
// child: Padding(
|
||||||
|
// padding: EdgeInsets.all(Get.width * 0.02),
|
||||||
|
// child: ListView.builder(
|
||||||
|
// itemCount: _cartController.selectedProducts.length,
|
||||||
|
// itemBuilder: (context, index) {
|
||||||
|
// final cartItem =
|
||||||
|
// _cartController.cartList[index];
|
||||||
|
// return ProductCard(
|
||||||
|
// productModel:_cartController.selectedProducts[index] ,
|
||||||
|
// isCheckout: true,
|
||||||
|
// quantity: _cartController.cartList[0].quantity,
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// // ListTile(
|
||||||
|
// // title: Text(cartItem.name ?? 'N/A'),
|
||||||
|
// // subtitle: Text(
|
||||||
|
// // 'Quantity: ${cartItem.quantity}'),
|
||||||
|
// // trailing: Text(
|
||||||
|
// // 'Price: \₹${cartItem.price.toStringAsFixed(2)}'),
|
||||||
|
// // );
|
||||||
|
// );},
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// Padding(
|
||||||
|
// padding: EdgeInsets.all(Get.width * 0.02),
|
||||||
|
// child: Column(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: [
|
||||||
|
// Text('Subtotal',style: TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
// Text('₹${_cartController.subtotal.value.toStringAsFixed(2)}'),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: [
|
||||||
|
// Text('GST',style: TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
// Text('₹${_cartController.gstTotal.value.toStringAsFixed(2)}'),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: [
|
||||||
|
// Text('Total Amount',style: TextStyle(fontWeight: FontWeight.bold)),
|
||||||
|
// Text('₹${_cartController.grandTotal.value.toStringAsFixed(2)}'),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
//
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: 10.0,),
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// ElevatedButton(
|
||||||
|
// onPressed: _onPlaceOrder,
|
||||||
|
// style: ElevatedButton.styleFrom(
|
||||||
|
// foregroundColor: Colors.white,
|
||||||
|
// backgroundColor: const Color(0xFF00784C),
|
||||||
|
// padding: EdgeInsets.symmetric(
|
||||||
|
// horizontal: Get.width * 0.20,
|
||||||
|
// vertical: Get.height * 0.02),
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.circular(10),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// child: const Text("Place Order"),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
import 'dart:ffi';
|
import 'dart:ffi';
|
||||||
import 'package:cheminova/controller/get_order_placed_controller.dart';
|
import 'package:cheminova/controller/get_order_placed_controller.dart';
|
||||||
import 'package:cheminova/models/added_by_model.dart';
|
import 'package:cheminova/models/added_by_model.dart';
|
||||||
@ -14,9 +445,12 @@ import '../../controller/place_order_controller.dart';
|
|||||||
import '../../controller/place_order_service.dart';
|
import '../../controller/place_order_service.dart';
|
||||||
import '../../controller/product_controller.dart';
|
import '../../controller/product_controller.dart';
|
||||||
import '../../controller/product_service.dart';
|
import '../../controller/product_service.dart';
|
||||||
|
import '../../controller/shiptobilltoController.dart';
|
||||||
import '../../models/brand_model.dart';
|
import '../../models/brand_model.dart';
|
||||||
import '../../models/oder_place_model.dart';
|
import '../../models/oder_place_model.dart';
|
||||||
import '../../models/product_model1.dart';
|
import '../../models/product_model1.dart';
|
||||||
|
|
||||||
|
import '../../models/shippingandBilling_address_model.dart';
|
||||||
import '../../widgets/my_drawer.dart';
|
import '../../widgets/my_drawer.dart';
|
||||||
import '../../widgets/product_card.dart';
|
import '../../widgets/product_card.dart';
|
||||||
import 'order_confermation_screen.dart';
|
import 'order_confermation_screen.dart';
|
||||||
@ -39,6 +473,7 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
final OrderPlacedController _orderPlacedController =
|
final OrderPlacedController _orderPlacedController =
|
||||||
Get.put(OrderPlacedController());
|
Get.put(OrderPlacedController());
|
||||||
final GetPlacedOrderController _getPlacedOrderController = Get.put(GetPlacedOrderController());
|
final GetPlacedOrderController _getPlacedOrderController = Get.put(GetPlacedOrderController());
|
||||||
|
final AddressController _addressController = Get.put(AddressController()); // Initialize AddressController
|
||||||
|
|
||||||
int currentPage = 1;
|
int currentPage = 1;
|
||||||
String _groupValue = "cheque";
|
String _groupValue = "cheque";
|
||||||
@ -52,17 +487,25 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
String? _selectedShippingAddress;
|
String? _selectedShippingAddress;
|
||||||
String? _selectedBillingAddress;
|
String? _selectedBillingAddress;
|
||||||
|
|
||||||
|
|
||||||
|
String capitalizeFirstLetter(String text) {
|
||||||
|
if (text.isEmpty) return text;
|
||||||
|
return text[0].toUpperCase() + text.substring(1).toLowerCase();
|
||||||
|
}
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
// _getOrder();
|
// _getOrder();
|
||||||
|
_addressController.fetchAddresses();
|
||||||
_loadSelectedAddress();
|
_loadSelectedAddress();
|
||||||
_loadSelectedPaymentMode();
|
_loadSelectedPaymentMode();
|
||||||
|
// _loadSelectedAddress();
|
||||||
if (_addressList.isNotEmpty) {
|
// _loadSelectedPaymentMode();
|
||||||
_selectedShippingAddress = _addressList.first;
|
//
|
||||||
_selectedBillingAddress = _addressList.first;
|
// if (_addressList.isNotEmpty) {
|
||||||
}
|
// _selectedShippingAddress = _addressList.first;
|
||||||
|
// _selectedBillingAddress = _addressList.first;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void _saveSelectedAddress() async {
|
void _saveSelectedAddress() async {
|
||||||
@ -114,10 +557,6 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// void _getOrder(){
|
|
||||||
// final details = _getPlacedOrderController.getOrder(widget.productModel!.id);
|
|
||||||
// print("dffgfg,$details");
|
|
||||||
// }
|
|
||||||
void _onPlaceOrder() async {
|
void _onPlaceOrder() async {
|
||||||
try {
|
try {
|
||||||
// Map the cart items (Product) to OrderItem objects
|
// Map the cart items (Product) to OrderItem objects
|
||||||
@ -144,11 +583,35 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
|
||||||
|
// Get the full address for shipping and billing
|
||||||
|
String? shippingAddress = _addressController.addressList.firstWhere(
|
||||||
|
(address) => address.id == _addressController.selectedShippingAddressId.value,
|
||||||
|
orElse: () => UserShippingAddress(
|
||||||
|
id: '',
|
||||||
|
street: '',
|
||||||
|
city: '',
|
||||||
|
state: '',
|
||||||
|
postalCode: '',
|
||||||
|
country: '', tradeName: '', name: '', phoneNumber: '', district: '', isDefault: false, user: '',
|
||||||
|
)).toStringFullAddress();
|
||||||
|
|
||||||
|
String? billingAddress = _addressController.addressList.firstWhere(
|
||||||
|
(address) => address.id == _addressController.selectedBillingAddressId.value,
|
||||||
|
orElse: () => UserShippingAddress(
|
||||||
|
id: '',
|
||||||
|
street: '',
|
||||||
|
city: '',
|
||||||
|
state: '',
|
||||||
|
postalCode: '',
|
||||||
|
country: '', tradeName: '', name: '', phoneNumber: '', district: '', isDefault: false, user: '', createdAt: null,
|
||||||
|
)).toStringFullAddress();
|
||||||
|
|
||||||
// Update the placedOrder1 value
|
// Update the placedOrder1 value
|
||||||
_orderPlacedController.placedOrder1.value= PlacedOrderModel(
|
_orderPlacedController.placedOrder1.value= PlacedOrderModel(
|
||||||
paymentMode: _groupValue,
|
paymentMode: _groupValue,
|
||||||
shipTo: _selectedShippingAddress!,
|
shipTo: shippingAddress, // Full shipping address
|
||||||
billTo: _selectedBillingAddress!,
|
billTo: billingAddress, // Full billing address
|
||||||
orderItems: orderItems,
|
orderItems: orderItems,
|
||||||
gstTotal: _cartController.gstTotal.value,
|
gstTotal: _cartController.gstTotal.value,
|
||||||
grandTotal: _cartController.grandTotal.value,
|
grandTotal: _cartController.grandTotal.value,
|
||||||
@ -161,11 +624,16 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
showSnackbar("Order Placed Successfully");
|
showSnackbar("Order Placed Successfully");
|
||||||
Get.to(() => OrderConfermationScreen(
|
Get.to(() => OrderConfermationScreen(
|
||||||
placedOrder: _orderPlacedController.placedOrder1.value,
|
placedOrder: _orderPlacedController.placedOrder1.value,
|
||||||
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("PlaceOrderScreen error: $e");
|
print("PlaceOrderScreen error: $e");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -204,7 +672,7 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
],
|
],
|
||||||
title: const Text("Checkout"),
|
title: const Text("Checkout"),
|
||||||
),
|
),
|
||||||
drawer: const MyDrawer(),
|
drawer: MyDrawer(),
|
||||||
body: Stack(
|
body: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
@ -223,15 +691,15 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
side: const BorderSide(color: Color(0xFFFDFDFD)),
|
side: const BorderSide(color: Color(0xFFFDFDFD)),
|
||||||
),
|
),
|
||||||
color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
color: const Color(0xFFB4D1E5).withOpacity(0.9),
|
||||||
child: Padding(
|
child:
|
||||||
|
Padding(
|
||||||
padding: EdgeInsets.all(Get.width * 0.04),
|
padding: EdgeInsets.all(Get.width * 0.04),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(horizontal: Get.width * 0.04),
|
||||||
horizontal: Get.width * 0.04),
|
|
||||||
child: Text(
|
child: Text(
|
||||||
'Shipping Information',
|
'Shipping Information',
|
||||||
style: GoogleFonts.roboto(
|
style: GoogleFonts.roboto(
|
||||||
@ -241,38 +709,58 @@ class _CheckoutScreenState extends State<CheckoutScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 5,),
|
SizedBox(height: 5),
|
||||||
DropdownButtonFormField<String>(
|
Obx(() => Container(
|
||||||
|
|
||||||
|
child: DropdownButtonFormField<String>(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Shipping Address:',
|
labelText: 'Shipping Address:',
|
||||||
hintText: 'Select Shipping Address',
|
hintText: 'Select Shipping Address',
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
value: _selectedShippingAddress,
|
value: _addressController.selectedShippingAddressId.value.isEmpty
|
||||||
items: _addressList.map((String address) {
|
? null // Show null if there's no selection yet
|
||||||
|
: _addressController.selectedShippingAddressId.value, // Set the selected ID
|
||||||
|
items: _addressController.addressList.map((UserShippingAddress address) {
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: address,
|
value: address.id, // Set the value as the address ID
|
||||||
child: Text(address),
|
child: Text("${address.street} ${address.city}\n ${address.state} \n ${address.postalCode} , ${address.country}",style: TextStyle(fontSize: 15),), // Display full address
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: _onShippingAddressChanged,
|
onChanged: (value) {
|
||||||
|
_addressController.onShippingAddressChanged(value); // Update the selected address
|
||||||
|
},
|
||||||
),
|
),
|
||||||
|
)),
|
||||||
SizedBox(height: Get.height * 0.02),
|
SizedBox(height: Get.height * 0.02),
|
||||||
DropdownButtonFormField<String>(
|
|
||||||
|
// Billing Address Dropdown
|
||||||
|
Obx(() => Container(
|
||||||
|
child: DropdownButtonFormField<String>(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Billing Address:',
|
labelText: 'Billing Address:',
|
||||||
hintText: 'Select Billing Address',
|
hintText: 'Select Billing Address',
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
),
|
),
|
||||||
value: _selectedBillingAddress,
|
value: _addressController.selectedBillingAddressId.value.isEmpty
|
||||||
items: _addressList.map((String address) {
|
? null
|
||||||
|
: _addressController.selectedBillingAddressId.value,
|
||||||
|
items: _addressController.addressList
|
||||||
|
.where((address) => address.isDefault == true) // Filter only default addresses
|
||||||
|
.map((UserShippingAddress address) {
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: address,
|
value: address.id,
|
||||||
child: Text(address),
|
child: Text(
|
||||||
|
"${address.street} ${address.city}${address.state}\n${address.postalCode}, ${address.country}",
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: _onBillingAddressChanged,
|
onChanged: (value) {
|
||||||
|
_addressController.onBillingAddressChanged(value);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
|
)),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
horizontal: Get.width * 0.04),
|
horizontal: Get.width * 0.04),
|
||||||
|
@ -282,11 +282,12 @@ Future<void> adduni()async {
|
|||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: Get.width,
|
width: Get.width,
|
||||||
height: Get.height*0.06,
|
height: Get.height * 0.10,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding:
|
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
child: Wrap( // Use Wrap to allow wrapping
|
||||||
child: Row(
|
crossAxisAlignment: WrapCrossAlignment.start,
|
||||||
|
direction: Axis.horizontal,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
"Address: ",
|
"Address: ",
|
||||||
@ -295,8 +296,17 @@ Future<void> adduni()async {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
AutoSizeText("${widget.placedOrderList!.shipTo}",maxLines: 4,
|
Text(
|
||||||
overflow:TextOverflow.ellipsis,)
|
"${widget.placedOrderList!.shipTo.toString()}",
|
||||||
|
// Text(
|
||||||
|
// "${widget.placedOrderList!.shipTo}",
|
||||||
|
maxLines: 4,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: GoogleFonts.roboto(
|
||||||
|
fontSize: Get.width * 0.04,
|
||||||
|
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -16,4 +16,14 @@ class ApiUrls {
|
|||||||
static const String inventoryManangementOrdersStock ='${baseUrl}/api/stock';
|
static const String inventoryManangementOrdersStock ='${baseUrl}/api/stock';
|
||||||
static const String announcementUrl ='${baseUrl}/api/announcement/RDs?page%3D1=rowsPerPage=5';
|
static const String announcementUrl ='${baseUrl}/api/announcement/RDs?page%3D1=rowsPerPage=5';
|
||||||
|
|
||||||
|
|
||||||
|
//============================== Product stock Details ==============================//
|
||||||
|
static const String ProductStockUrl = '/api/rd/stock';
|
||||||
|
|
||||||
|
//============================== Product Update stock Details ==============================//
|
||||||
|
static const String ProductUpdateStockUrl = '${baseUrl}/api/rd/stock-update';
|
||||||
|
|
||||||
|
|
||||||
|
//============================== shipto Billto Details ==============================//
|
||||||
|
static const String ShiptoandBilltoAddressUrl = '/api/rd/shipping/address';
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ class InputField extends StatefulWidget {
|
|||||||
final TextEditingController controller;
|
final TextEditingController controller;
|
||||||
final bool obscureText;
|
final bool obscureText;
|
||||||
final TextInputType? keyboardType;
|
final TextInputType? keyboardType;
|
||||||
|
final void Function(String)? onChanged;
|
||||||
final String? Function(String?)? validator;// Add this line for validation
|
final String? Function(String?)? validator;// Add this line for validation
|
||||||
|
|
||||||
InputField({
|
InputField({
|
||||||
@ -15,6 +16,7 @@ class InputField extends StatefulWidget {
|
|||||||
required this.labelText,
|
required this.labelText,
|
||||||
required this.controller,
|
required this.controller,
|
||||||
this.obscureText = false,
|
this.obscureText = false,
|
||||||
|
this.onChanged,
|
||||||
this.keyboardType = TextInputType.text,
|
this.keyboardType = TextInputType.text,
|
||||||
this.validator, // Add this
|
this.validator, // Add this
|
||||||
});
|
});
|
||||||
|
24
pubspec.lock
24
pubspec.lock
@ -500,18 +500,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
|
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.5"
|
version: "10.0.4"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker_flutter_testing
|
name: leak_tracker_flutter_testing
|
||||||
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
|
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.5"
|
version: "3.0.3"
|
||||||
leak_tracker_testing:
|
leak_tracker_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -548,18 +548,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.1"
|
version: "0.8.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
|
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
version: "1.12.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -849,10 +849,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
|
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.2"
|
version: "0.7.0"
|
||||||
timezone:
|
timezone:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -977,10 +977,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc
|
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.2.4"
|
version: "14.2.1"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
Loading…
Reference in New Issue
Block a user