order_management UI and API Done

This commit is contained in:
Vaibhav 2024-10-07 13:16:43 +05:30
parent 7fc5702a9c
commit 6792c73cde
10 changed files with 450 additions and 351 deletions

View File

@ -1,17 +1,22 @@
import 'dart:developer';
import 'package:cheminova/controller/get_single_placed_order_service.dart';
import 'package:cheminova/controller/place_order_controller.dart';
import 'package:cheminova/models/place_order_list_model.dart';
import 'package:cheminova/services/api_service.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../models/oder_place_model.dart';
import '../models/product_model1.dart';
import '../utils/log_service.dart';
import 'get_place_order_service.dart';
class GetPlacedOrderController extends GetxController {
final ApiService _apiService = ApiService();
final GetOrderPlacedService _getOrderPlacedService = GetOrderPlacedService();
final OrderPlacedController _orderPlacedController = Get.put(OrderPlacedController());
final GetSingleOrderPlacedService _getSingleOrderPlacedService = GetSingleOrderPlacedService();
final OrderPlacedController _orderPlacedController =
Get.put(OrderPlacedController());
final GetSingleOrderPlacedService _getSingleOrderPlacedService =
GetSingleOrderPlacedService();
var placedOrders = <PlacedOrderList>[].obs;
var products = <Product>[].obs;
@ -23,24 +28,47 @@ class GetPlacedOrderController extends GetxController {
getOrders(); // Fetch the orders immediately on initialization
}
RxInt currentPage = 1.obs;
RxBool hasMoreOrders = true.obs;
Future<void> getOrders() async {
if (isLoading.value || !hasMoreOrders.value) return;
final fetchedOrders = await _getOrderPlacedService.getPlacedOrders();
isLoading.value = true;
if (fetchedOrders != null && fetchedOrders.isNotEmpty) {
placedOrders.addAll(fetchedOrders);
//logger.w("Fetched orders: $fetchedOrders");
try {
final response = await _apiService
.get('/api/rd-place-order?page=${currentPage.value}');
log('response ---- $response');
PlacedOrderResponse data = PlacedOrderResponse.fromJson(response.data);
if (response.statusCode == 200) {
placedOrders.addAll(data.placedOrders ?? []);
debugPrint('allOrders.length: ${placedOrders.toJson()}');
currentPage++;
hasMoreOrders.value = placedOrders.length < data.totalOrders!.toInt();
} else {
//logger.w("No orders fetched");
throw Exception('Failed to load orders');
}
} catch (e) {
debugPrint('Error fetching orders: $e');
} finally {
isLoading.value = false;
}
}
void resetPagination() {
placedOrders.clear();
currentPage.value = 1;
hasMoreOrders.value = true;
}
Future<void> searchOrder() async {
try {
isLoading.value = true;
final order = await _getSingleOrderPlacedService.getSinglePlacedOrder(placedOrders[0].id);
final order = await _getSingleOrderPlacedService
.getSinglePlacedOrder(placedOrders[0].sId ?? '');
if (order != null) {
placedOrders.clear(); // Clear existing orders if needed
placedOrders.add(order);
@ -54,10 +82,10 @@ class GetPlacedOrderController extends GetxController {
}
}
// Optional: Reset the pagination if needed
void resetPagination() {
_getOrderPlacedService.resetPagination();
placedOrders.clear(); // Clear existing data
getOrders(); // Fetch fresh data
}
// // Optional: Reset the pagination if needed
// void resetPagination() {
// _getOrderPlacedService.resetPagination();
// placedOrders.clear(); // Clear existing data
// getOrders(); // Fetch fresh data
// }
}

View File

@ -13,7 +13,7 @@ class GetOrderPlacedService {
try {
while (_hasMoreOrders) {
// Construct the API URL with pagination parameters
String url = "api/rd-place-order?page=$_currentPage";
String url = "/api/rd-place-order?page=$_currentPage";
final response = await commonApiService<List<PlacedOrderList>>(
method: "GET",

View File

@ -1,136 +1,188 @@
class PlacedOrderResponse {
List<PlacedOrderList>? placedOrders;
dynamic? totalOrders;
PlacedOrderResponse({this.placedOrders, this.totalOrders});
PlacedOrderResponse.fromJson(Map<dynamic, dynamic> json) {
if (json['placedOrders'] != null) {
placedOrders = <PlacedOrderList>[];
json['placedOrders'].forEach((v) {
placedOrders!.add(PlacedOrderList.fromJson(v));
});
}
totalOrders = json['totalOrders'];
}
Map<dynamic, dynamic> toJson() {
final Map<dynamic, dynamic> data = <dynamic, dynamic>{};
if (placedOrders != null) {
data['placedOrders'] = placedOrders!.map((v) => v.toJson()).toList();
}
data['totalOrders'] = totalOrders;
return data;
}
}
class PlacedOrderList {
final String id;
final String paymentMode;
final String shipTo;
final String billTo;
final List<OrderItem1> orderItem;
final double subtotal;
final double gstTotal;
final double grandTotal;
final String status;
final String addedBy;
final bool isCancelled;
final bool isDelivered;
final String deliveredDate;
final String uniqueId;
final DateTime createdAt;
final DateTime updatedAt;
dynamic? sId;
dynamic? paymentMode;
dynamic? shipTo;
dynamic? billTo;
List<OrderItem>? orderItem;
dynamic? subtotal;
dynamic? gstTotal;
dynamic? grandTotal;
dynamic? status;
List<dynamic>? invoices;
dynamic? addedBy;
dynamic? pd;
bool? iscancelled;
bool? isDelivered;
dynamic? deliveredDate;
dynamic? statusUpdatedAt;
dynamic? uniqueId;
dynamic? createdAt;
dynamic? updatedAt;
dynamic? iV;
PlacedOrderList({
required this.id,
required this.paymentMode,
required this.shipTo,
required this.billTo,
required this.orderItem,
required this.subtotal,
required this.gstTotal,
required this.grandTotal,
required this.status,
required this.addedBy,
required this.isCancelled,
required this.isDelivered,
required this.deliveredDate,
required this.uniqueId,
required this.createdAt,
required this.updatedAt,
PlacedOrderList(
{this.sId,
this.paymentMode,
this.shipTo,
this.billTo,
this.orderItem,
this.subtotal,
this.gstTotal,
this.grandTotal,
this.status,
this.invoices,
this.addedBy,
this.pd,
this.iscancelled,
this.isDelivered,
this.deliveredDate,
this.statusUpdatedAt,
this.uniqueId,
this.createdAt,
this.updatedAt,
this.iV});
PlacedOrderList.fromJson(Map<dynamic, dynamic> json) {
sId = json['_id'];
paymentMode = json['paymentMode'];
shipTo = json['shipTo'];
billTo = json['billTo'];
if (json['orderItem'] != null) {
orderItem = <OrderItem>[];
json['orderItem'].forEach((v) {
orderItem!.add(OrderItem.fromJson(v));
});
factory PlacedOrderList.fromJson(Map<String, dynamic> json) {
return PlacedOrderList(
id: json['_id'],
paymentMode: json['paymentMode'],
shipTo: json['shipTo'],
billTo: json['billTo'],
orderItem: (json['orderItem'] as List)
.map((item) => OrderItem1.fromJson(item))
.toList(),
subtotal: json['subtotal'].toDouble(),
gstTotal: json['gstTotal'].toDouble(),
grandTotal: json['grandTotal'].toDouble(),
status: json['status'],
addedBy: json['addedBy'],
isCancelled: json['iscancelled'],
isDelivered: json['isDelivered'],
deliveredDate: json['DeliveredDate'],
uniqueId: json['uniqueId'],
createdAt: DateTime.parse(json['createdAt']),
updatedAt: DateTime.parse(json['updatedAt']),
);
}
subtotal = json['subtotal'];
gstTotal = json['gstTotal'];
grandTotal = json['grandTotal'];
status = json['status'];
invoices = json['invoices'].cast<dynamic>();
addedBy = json['addedBy'];
pd = json['pd'];
iscancelled = json['iscancelled'];
isDelivered = json['isDelivered'];
deliveredDate = json['DeliveredDate'];
statusUpdatedAt = json['statusUpdatedAt'];
uniqueId = json['uniqueId'];
createdAt = json['createdAt'];
updatedAt = json['updatedAt'];
iV = json['__v'];
}
Map<String, dynamic> toJson() {
return {
'_id': id,
'paymentMode': paymentMode,
'shipTo': shipTo,
'billTo': billTo,
'orderItem': orderItem.map((item) => item.toJson()).toList(),
'subtotal': subtotal,
'gstTotal': gstTotal,
'grandTotal': grandTotal,
'status': status,
'addedBy': addedBy,
'iscancelled': isCancelled,
'isDelivered': isDelivered,
'DeliveredDate': deliveredDate,
'uniqueId': uniqueId,
'createdAt': createdAt.toIso8601String(),
'updatedAt': updatedAt.toIso8601String(),
};
Map<dynamic, dynamic> toJson() {
final Map<dynamic, dynamic> data = <dynamic, dynamic>{};
data['_id'] = sId;
data['paymentMode'] = paymentMode;
data['shipTo'] = shipTo;
data['billTo'] = billTo;
if (orderItem != null) {
data['orderItem'] = orderItem!.map((v) => v.toJson()).toList();
}
@override
String toString() {
return 'PlacedOrderList(id: $id, paymentMode: $paymentMode, shipTo: $shipTo, billTo: $billTo, '
'orderItem: $orderItem, subtotal: $subtotal, gstTotal: $gstTotal, grandTotal: $grandTotal, '
'status: $status, addedBy: $addedBy, isCancelled: $isCancelled, isDelivered: $isDelivered, '
'deliveredDate: $deliveredDate, uniqueId: $uniqueId, createdAt: $createdAt, updatedAt: $updatedAt)';
data['subtotal'] = subtotal;
data['gstTotal'] = gstTotal;
data['grandTotal'] = grandTotal;
data['status'] = status;
data['invoices'] = invoices;
data['addedBy'] = addedBy;
data['pd'] = pd;
data['iscancelled'] = iscancelled;
data['isDelivered'] = isDelivered;
data['DeliveredDate'] = deliveredDate;
data['statusUpdatedAt'] = statusUpdatedAt;
data['uniqueId'] = uniqueId;
data['createdAt'] = createdAt;
data['updatedAt'] = updatedAt;
data['__v'] = iV;
return data;
}
}
class OrderItem1 {
final String sku;
final String name;
final String categoryName;
final String brandName;
final double price;
final int quantity;
class OrderItem {
dynamic? productId;
dynamic? sKU;
dynamic? name;
dynamic? categoryName;
dynamic? brandName;
dynamic? price;
dynamic? gST;
dynamic? hSNCode;
dynamic? description;
List<Null>? image;
dynamic? quantity;
dynamic? remainingQuantity;
dynamic? sId;
OrderItem1({
required this.sku,
required this.name,
required this.categoryName,
required this.brandName,
required this.price,
required this.quantity,
});
OrderItem(
{this.productId,
this.sKU,
this.name,
this.categoryName,
this.brandName,
this.price,
this.gST,
this.hSNCode,
this.description,
this.image,
this.quantity,
this.remainingQuantity,
this.sId});
factory OrderItem1.fromJson(Map<String, dynamic> json) {
return OrderItem1(
sku: json['SKU'],
name: json['name'],
categoryName: json['categoryName'],
brandName: json['brandName'],
price: json['price'].toDouble(),
quantity: json['quantity'],
);
OrderItem.fromJson(Map<dynamic, dynamic> json) {
productId = json['productId'];
sKU = json['SKU'];
name = json['name'];
categoryName = json['categoryName'];
brandName = json['brandName'];
price = json['price'];
gST = json['GST'];
hSNCode = json['HSN_Code'];
description = json['description'];
quantity = json['quantity'];
remainingQuantity = json['remainingQuantity'];
sId = json['_id'];
}
Map<String, dynamic> toJson() {
return {
'SKU': sku,
'name': name,
'categoryName': categoryName,
'brandName': brandName,
'price': price,
'quantity': quantity,
};
}
@override
String toString() {
return 'OrderItem(sku: $sku, name: $name, categoryName: $categoryName, '
'brandName: $brandName, price: $price, quantity: $quantity)';
Map<dynamic, dynamic> toJson() {
final Map<dynamic, dynamic> data = <dynamic, dynamic>{};
data['productId'] = productId;
data['SKU'] = sKU;
data['name'] = name;
data['categoryName'] = categoryName;
data['brandName'] = brandName;
data['price'] = price;
data['GST'] = gST;
data['HSN_Code'] = hSNCode;
data['description'] = description;
data['quantity'] = quantity;
data['remainingQuantity'] = remainingQuantity;
data['_id'] = sId;
return data;
}
}

View File

@ -196,7 +196,7 @@ class _LoginScreenState extends State<LoginScreen> {
),
),
),
const SizedBox(height: 30),
const SizedBox(height: 18),
// Login button with loading state
Obx(
() => CustomButton(

View File

@ -48,20 +48,20 @@ Future<void> adduni()async {
final List<PlacedOrderList> uniqueOrders = [];
for (var order in _getPlacedOrderController.placedOrders) {
if (uniqueOrderIds.add(order.uniqueId)) {
if (uniqueOrderIds.add(order.uniqueId??'')) {
uniqueOrders.add(order);
}
}
final order = uniqueOrders[0];
// Combine product names into a single string
final productNames = order.orderItem
final productNames = order.orderItem!
.map((item) => (item.name))
.join(', ');
final categotyName = order.orderItem
final categotyName = order.orderItem!
.map((item) => (item.categoryName))
.join(', ');
final quantity = order.orderItem
final quantity = order.orderItem!
.map((item) => (item.quantity))
.join(', ');
}
@ -157,7 +157,7 @@ Future<void> adduni()async {
fontWeight: FontWeight.bold,
),
),
Text(widget.placedOrderList!.uniqueId),
Text(widget.placedOrderList!.uniqueId??''),
],
),
),
@ -212,9 +212,9 @@ Future<void> adduni()async {
padding: EdgeInsets.all(Get.width * 0.02),
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: widget.placedOrderList?.orderItem.length ?? 0,
itemCount: widget.placedOrderList?.orderItem?.length ?? 0,
itemBuilder: (context, index) {
final orderItem = widget.placedOrderList!.orderItem[index];
final orderItem = widget.placedOrderList!.orderItem![index];
return orderItem != null
? Card(
margin: const EdgeInsets.symmetric(vertical: 5.0),
@ -237,7 +237,7 @@ Future<void> adduni()async {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
capitalizeFirstLetter(orderItem.name),
capitalizeFirstLetter(orderItem.name??''),
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.bold,

View File

@ -59,7 +59,9 @@ class _OrderManagementScreenState extends State<OrderManagementScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
return Stack(
children: [
Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
centerTitle: true,
@ -148,7 +150,7 @@ class _OrderManagementScreenState extends State<OrderManagementScreen> {
final List<PlacedOrderList> uniqueOrders = [];
for (var order in _getPlacedOrderController.placedOrders) {
if (uniqueOrderIds.add(order.id)) {
if (uniqueOrderIds.add(order.sId??'')) {
uniqueOrders.add(order);
}
}
@ -161,8 +163,8 @@ class _OrderManagementScreenState extends State<OrderManagementScreen> {
final order = uniqueOrders[index];
// Combine product names into a single string
final productNames = order.orderItem
.map((item) => capitalizeFirstLetter(item.name))
final productNames = order.orderItem!
.map((item) => capitalizeFirstLetter(item.name??''))
.join(', ');
return Padding(
@ -271,6 +273,19 @@ class _OrderManagementScreenState extends State<OrderManagementScreen> {
),
],
),
),
Obx(() {
if (_getPlacedOrderController.isLoading.value) {
return Container(
color: Colors.black.withOpacity(0.5),
child: const Center(
child: CircularProgressIndicator(strokeWidth: 1),
),
);
}
return const SizedBox.shrink();
},)
],
);
}
}

View File

@ -25,8 +25,7 @@ class ApiService {
return Response(
requestOptions: RequestOptions(path: ''),
statusCode: 500,
data: {'message': 'An unexpected error occurred'},
);
data: {'message': 'An unexpected error occurred'});
}
}
}

View File

@ -1,4 +1,5 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class AuthInterceptor extends Interceptor {
@ -9,6 +10,7 @@ class AuthInterceptor extends Interceptor {
final token = prefs.getString('token');
if (token != null) {
debugPrint('token-->\n $token\n');
options.headers['Authorization'] = 'Bearer $token';
}

View File

@ -17,19 +17,22 @@ class CustomButton extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
padding: EdgeInsets.symmetric(vertical:isLoading?0: 16, horizontal: 8),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: const Color(0xFF004791),
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
padding: EdgeInsets.symmetric(horizontal: 32, vertical:isLoading?0: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
),
onPressed: onPressed,
child: isLoading
? const CircularProgressIndicator()
? const CircularProgressIndicator(
strokeWidth: 1,color: Colors.white,
valueColor: AlwaysStoppedAnimation<Color>(Colors.blueGrey),
)
: Text(
text,
style: GoogleFonts.getFont(

View File

@ -32,7 +32,7 @@ class _MyDrawerState extends State<MyDrawer> {
return Center(child: Text(_homeController.error.value));
} else {
final user = _homeController.userProfile.value;
return DrawerHeader(
return user == null ?const SizedBox(): DrawerHeader(
decoration: const BoxDecoration(
color: Colors.black87,
),