1) Cancelled file changes done

This commit is contained in:
saritabirare 2024-10-22 15:45:48 +05:30
parent ff065bdc16
commit ef2799cbd4
12 changed files with 2100 additions and 811 deletions

View File

@ -1,72 +1,345 @@
// import 'package:cheminova/models/rd_order_item_model.dart';
//
// class SingleGetOrderModel {
// final String id;
// String? paymentMode;
// String? shipTo;
// String? billTo;
// List<RDOrderItem>? orderItem;
// double? subtotal;
// double? gstTotal;
// double? grandTotal;
// String? status;
// List<dynamic>? invoices;
// AddedBy? addedBy;
// String? pd;
// bool? isCancelled;
// bool? isDelivered;
// String? deliveredDate;
// DateTime? statusUpdatedAt;
// String? uniqueId;
// DateTime? createdAt;
// DateTime? updatedAt;
//
// SingleGetOrderModel({
// required this.id,
// 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,
// });
//
// factory SingleGetOrderModel.fromJson(Map<String, dynamic> json) {
// return SingleGetOrderModel(
// id: json['_id'] ?? '',
// paymentMode: json['paymentMode'] ?? '',
// shipTo: json['shipTo'] ?? '',
// billTo: json['billTo'] ?? '',
// orderItem: (json['orderItem'] as List<dynamic>?)
// ?.map((item) => RDOrderItem.fromJson(item))
// .toList() ??
// [],
// subtotal: (json['subtotal'] as num?)?.toDouble() ?? 0.0,
// gstTotal: (json['gstTotal'] as num?)?.toDouble() ?? 0.0,
// grandTotal: (json['grandTotal'] as num?)?.toDouble() ?? 0.0,
// status: json['status'] ?? '',
// invoices: json['invoices'] ?? [],
// addedBy: AddedBy.fromJson(json['addedBy'] ?? {}),
// pd: json['pd'] ?? '',
// isCancelled: json['iscancelled'] ?? false,
// isDelivered: json['isDelivered'] ?? false,
// deliveredDate: json['DeliveredDate'] ?? '',
// statusUpdatedAt: DateTime.parse(json['statusUpdatedAt'] ?? DateTime.now().toString()),
// uniqueId: json['uniqueId'] ?? '',
// createdAt: DateTime.parse(json['createdAt'] ?? DateTime.now().toString()),
// updatedAt: DateTime.parse(json['updatedAt'] ?? DateTime.now().toString()),
// );
// }
//
// 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,
// 'invoices': invoices,
// 'addedBy': addedBy?.toJson(),
// 'pd': pd,
// 'iscancelled': isCancelled,
// 'isDelivered': isDelivered,
// 'DeliveredDate': deliveredDate,
// 'statusUpdatedAt': statusUpdatedAt?.toIso8601String(),
// 'uniqueId': uniqueId,
// 'createdAt': createdAt?.toIso8601String(),
// 'updatedAt': updatedAt?.toIso8601String(),
// };
// }
//
// @override
// String toString() {
// return 'SingleGetOrderModel(id: $id, paymentMode: $paymentMode, shipTo: $shipTo, billTo: $billTo, '
// 'orderItem: $orderItem, subtotal: $subtotal, gstTotal: $gstTotal, grandTotal: $grandTotal, '
// 'status: $status, invoices: $invoices, addedBy: $addedBy, pd: $pd, '
// 'isCancelled: $isCancelled, isDelivered: $isDelivered, deliveredDate: $deliveredDate, '
// 'statusUpdatedAt: $statusUpdatedAt, uniqueId: $uniqueId, createdAt: $createdAt, updatedAt: $updatedAt)';
// }
// }
//
// class OrderItem {
// final String productId;
// final String sku;
// final String name;
// final String categoryName;
// final String brandName;
// final int price; // Use int for price
// final int gst; // Use int for GST
// final int hsnCode; // Use int for HSN Code
// final String description;
// final List<String> image; // Assuming images are stored as a list of strings
// final int quantity;
// final int remainingQuantity;
// int? processQuantity;
// final String id; // Use String for _id
//
// OrderItem({
// required this.productId,
// required this.sku,
// required this.name,
// required this.categoryName,
// required this.brandName,
// required this.price,
// required this.gst,
// required this.hsnCode,
// required this.description,
// required this.image,
// required this.quantity,
// required this.remainingQuantity,
// this.processQuantity = 1,
// required this.id,
// });
//
// factory OrderItem.fromJson(Map<String, dynamic> json) {
// return OrderItem(
// productId: json['productId'] ?? '',
// sku: json['SKU'] ?? '',
// name: json['name'] ?? '',
// categoryName: json['categoryName'] ?? '',
// brandName: json['brandName'] ?? '',
// price: (json['price'] as num?)?.toInt() ?? 0, // Handle as num
// gst: (json['GST'] as num?)?.toInt() ?? 0, // Handle as num
// hsnCode: (json['HSN_Code'] as num?)?.toInt() ?? 0, // Handle as num
// description: json['description'] ?? '',
// image: List<String>.from(json['image'] ?? []),
// quantity: (json['quantity'] as num?)?.toInt() ?? 0, // Handle as num
// remainingQuantity: (json['remainingQuantity'] as num?)?.toInt() ?? 0, // Handle as num
// processQuantity: (json['processQuantity']as num?)?.toInt()??0,
// id: json['_id'] ?? '',
// );
// }
//
// Map<String, dynamic> toJson() {
// return {
// 'productId': productId,
// 'SKU': sku,
// 'name': name,
// 'categoryName': categoryName,
// 'brandName': brandName,
// 'price': price,
// 'GST': gst,
// 'HSN_Code': hsnCode,
// 'description': description,
// 'image': image,
// 'quantity': quantity,
// 'remainingQuantity': remainingQuantity,
// '_id': id,
// };
// }
//
// @override
// String toString() {
// return 'OrderItem(productId: $productId, SKU: $sku, name: $name, categoryName: $categoryName, '
// 'brandName: $brandName, price: $price, GST: $gst, HSN_Code: $hsnCode, '
// 'description: $description, image: $image, quantity: $quantity, '
// 'remainingQuantity: $remainingQuantity, id: $id)';
// }
// }
//
// class AddedBy {
// final String id;
// final String designation;
// final String name;
// final String email;
// final String mobileNumber;
// final String principalDistributor;
// final String addedBy;
// final String userType;
// final String kyc;
// String? fcmToken;
// final DateTime createdAt;
// final DateTime updatedAt;
// final String mappedSC;
// final String uniqueId;
// final String mappedTM;
//
// AddedBy({
// required this.id,
// required this.designation,
// required this.name,
// required this.email,
// required this.mobileNumber,
// required this.principalDistributor,
// required this.addedBy,
// required this.userType,
// required this.kyc,
// this.fcmToken,
// required this.createdAt,
// required this.updatedAt,
// required this.mappedSC,
// required this.uniqueId,
// required this.mappedTM,
// });
//
// factory AddedBy.fromJson(Map<String, dynamic> json) {
// return AddedBy(
// id: json['_id'] ?? '',
// designation: json['designation'] ?? '',
// name: json['name'] ?? '',
// email: json['email'] ?? '',
// mobileNumber: json['mobile_number'] ?? '',
// principalDistributor: json['principal_distributer'] ?? '',
// addedBy: json['addedBy'] ?? '',
// userType: json['userType'] ?? '',
// kyc: json['kyc'] ?? '',
// fcmToken: json['fcm_token']?.toString(), // Handle null safely
// createdAt: DateTime.parse(json['createdAt'] ?? DateTime.now().toString()),
// updatedAt: DateTime.parse(json['updatedAt'] ?? DateTime.now().toString()),
// mappedSC: json['mappedSC'] ?? '',
// uniqueId: json['uniqueId'] ?? '',
// mappedTM: json['mappedTM'] ?? '',
// );
// }
//
// Map<String, dynamic> toJson() {
// return {
// '_id': id,
// 'designation': designation,
// 'name': name,
// 'email': email,
// 'mobile_number': mobileNumber,
// 'principal_distributer': principalDistributor,
// 'addedBy': addedBy,
// 'userType': userType,
// 'kyc': kyc,
// 'fcm_token': fcmToken,
// 'createdAt': createdAt.toIso8601String(),
// 'updatedAt': updatedAt.toIso8601String(),
// 'mappedSC': mappedSC,
// 'uniqueId': uniqueId,
// 'mappedTM': mappedTM,
// };
// }
//
// @override
// String toString() {
// return 'AddedBy(id: $id, designation: $designation, name: $name, email: $email, '
// 'mobileNumber: $mobileNumber, principalDistributor: $principalDistributor, '
// 'addedBy: $addedBy, userType: $userType, kyc: $kyc, '
// 'fcmToken: $fcmToken, createdAt: $createdAt, updatedAt: $updatedAt, '
// 'mappedSC: $mappedSC, uniqueId: $uniqueId, mappedTM: $mappedTM)';
// }
// }
import 'dart:convert';
import 'package:cheminova/models/rd_order_item_model.dart';
// Main model for the order
class SingleGetOrderModel {
final String id;
String? paymentMode;
String? shipTo;
String? billTo;
List<RDOrderItem>? orderItem;
double? subtotal;
double? gstTotal;
double? grandTotal;
String? status;
List<dynamic>? invoices;
AddedBy? addedBy;
String? pd;
bool? isCancelled;
bool? isDelivered;
String? deliveredDate;
DateTime? statusUpdatedAt;
String? uniqueId;
DateTime? createdAt;
DateTime? updatedAt;
String id;
String paymentMode;
String shipTo;
String billTo;
List<RDOrderItem> orderItem;
double subtotal;
double gstTotal;
double grandTotal;
String status;
List<Invoice> invoices;
AddedBy addedBy;
String pd;
bool isCancelled;
bool isDelivered;
String deliveredDate;
String statusUpdatedAt;
String uniqueId;
String createdAt;
String updatedAt;
SingleGetOrderModel({
required this.id,
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,
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.invoices,
required this.addedBy,
required this.pd,
required this.isCancelled,
required this.isDelivered,
required this.deliveredDate,
required this.statusUpdatedAt,
required this.uniqueId,
required this.createdAt,
required this.updatedAt,
});
factory SingleGetOrderModel.fromJson(Map<String, dynamic> json) {
return SingleGetOrderModel(
id: json['_id'] ?? '',
paymentMode: json['paymentMode'] ?? '',
shipTo: json['shipTo'] ?? '',
billTo: json['billTo'] ?? '',
orderItem: (json['orderItem'] as List<dynamic>?)
?.map((item) => RDOrderItem.fromJson(item))
.toList() ??
[],
subtotal: (json['subtotal'] as num?)?.toDouble() ?? 0.0,
gstTotal: (json['gstTotal'] as num?)?.toDouble() ?? 0.0,
grandTotal: (json['grandTotal'] as num?)?.toDouble() ?? 0.0,
status: json['status'] ?? '',
invoices: json['invoices'] ?? [],
addedBy: AddedBy.fromJson(json['addedBy'] ?? {}),
pd: json['pd'] ?? '',
isCancelled: json['iscancelled'] ?? false,
isDelivered: json['isDelivered'] ?? false,
deliveredDate: json['DeliveredDate'] ?? '',
statusUpdatedAt: DateTime.parse(json['statusUpdatedAt'] ?? DateTime.now().toString()),
uniqueId: json['uniqueId'] ?? '',
createdAt: DateTime.parse(json['createdAt'] ?? DateTime.now().toString()),
updatedAt: DateTime.parse(json['updatedAt'] ?? DateTime.now().toString()),
id: json['_id']??"1",
paymentMode: json['paymentMode']??"2343",
shipTo: json['shipTo']??"abc",
billTo: json['billTo']??"xyz",
orderItem: (json['orderItem'] as List)
.map((i) => RDOrderItem.fromJson(i))
.toList(),
subtotal: json['subtotal'].toDouble(),
gstTotal: json['gstTotal'].toDouble(),
grandTotal: json['grandTotal'].toDouble(),
status: json['status'],
invoices: (json['invoices'] as List)
.map((i) => Invoice.fromJson(i))
.toList(),
addedBy: AddedBy.fromJson(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']??"",
);
}
@ -76,51 +349,109 @@ class SingleGetOrderModel {
'paymentMode': paymentMode,
'shipTo': shipTo,
'billTo': billTo,
'orderItem': orderItem?.map((item) => item.toJson()).toList(),
'orderItem': orderItem.map((i) => i.toJson()).toList(),
'subtotal': subtotal,
'gstTotal': gstTotal,
'grandTotal': grandTotal,
'status': status,
'invoices': invoices,
'addedBy': addedBy?.toJson(),
'invoices': invoices.map((i) => i.toJson()).toList(),
'addedBy': addedBy.toJson(),
'pd': pd,
'iscancelled': isCancelled,
'isDelivered': isDelivered,
'DeliveredDate': deliveredDate,
'statusUpdatedAt': statusUpdatedAt?.toIso8601String(),
'statusUpdatedAt': statusUpdatedAt,
'uniqueId': uniqueId,
'createdAt': createdAt?.toIso8601String(),
'updatedAt': updatedAt?.toIso8601String(),
'createdAt': createdAt,
'updatedAt': updatedAt,
};
}
@override
String toString() {
return 'SingleGetOrderModel(id: $id, paymentMode: $paymentMode, shipTo: $shipTo, billTo: $billTo, '
'orderItem: $orderItem, subtotal: $subtotal, gstTotal: $gstTotal, grandTotal: $grandTotal, '
'status: $status, invoices: $invoices, addedBy: $addedBy, pd: $pd, '
'isCancelled: $isCancelled, isDelivered: $isDelivered, deliveredDate: $deliveredDate, '
'statusUpdatedAt: $statusUpdatedAt, uniqueId: $uniqueId, createdAt: $createdAt, updatedAt: $updatedAt)';
}
}
class OrderItem {
final String productId;
final String sku;
final String name;
final String categoryName;
final String brandName;
final int price; // Use int for price
final int gst; // Use int for GST
final int hsnCode; // Use int for HSN Code
final String description;
final List<String> image; // Assuming images are stored as a list of strings
final int quantity;
final int remainingQuantity;
int? processQuantity;
final String id; // Use String for _id
// Model for individual order items
OrderItem({
// Model for invoices
class Invoice {
Map<String, String> courierStatusTimeline;
String id;
String invoiceId;
String orderId;
List<InvoiceItem> items;
double subtotal;
double gstTotal;
double invoiceAmount;
String courierStatus;
int v;
String courierName;
String courierTrackingId;
Invoice({
required this.courierStatusTimeline,
required this.id,
required this.invoiceId,
required this.orderId,
required this.items,
required this.subtotal,
required this.gstTotal,
required this.invoiceAmount,
required this.courierStatus,
required this.v,
required this.courierName,
required this.courierTrackingId,
});
factory Invoice.fromJson(Map<String, dynamic> json) {
return Invoice(
courierStatusTimeline: Map<String, String>.from(json['courierstatus_timeline']??""),
id: json['_id']??"",
invoiceId: json['invoiceId']??"",
orderId: json['orderId']??"",
items: (json['items'] as List)
.map((i) => InvoiceItem.fromJson(i))
.toList(),
subtotal: json['subtotal'].toDouble(),
gstTotal: json['gstTotal'].toDouble(),
invoiceAmount: json['invoiceAmount'].toDouble(),
courierStatus: json['courierStatus'],
v: json['__v'],
courierName: json['courier_name']??"",
courierTrackingId: json['courier_tracking_id']??"",
);
}
Map<String, dynamic> toJson() {
return {
'courierstatus_timeline': courierStatusTimeline,
'_id': id,
'invoiceId': invoiceId,
'orderId': orderId,
'items': items.map((i) => i.toJson()).toList(),
'subtotal': subtotal,
'gstTotal': gstTotal,
'invoiceAmount': invoiceAmount,
'courierStatus': courierStatus,
'__v': v,
'courier_name': courierName,
'courier_tracking_id': courierTrackingId,
};
}
}
// Model for items in an invoice
class InvoiceItem {
String productId;
String sku;
String name;
String categoryName;
String brandName;
double price;
double gst;
int hsnCode;
int processQuantity;
String id;
InvoiceItem({
required this.productId,
required this.sku,
required this.name,
@ -129,30 +460,22 @@ class OrderItem {
required this.price,
required this.gst,
required this.hsnCode,
required this.description,
required this.image,
required this.quantity,
required this.remainingQuantity,
this.processQuantity = 1,
required this.processQuantity,
required this.id,
});
factory OrderItem.fromJson(Map<String, dynamic> json) {
return OrderItem(
productId: json['productId'] ?? '',
sku: json['SKU'] ?? '',
name: json['name'] ?? '',
categoryName: json['categoryName'] ?? '',
brandName: json['brandName'] ?? '',
price: (json['price'] as num?)?.toInt() ?? 0, // Handle as num
gst: (json['GST'] as num?)?.toInt() ?? 0, // Handle as num
hsnCode: (json['HSN_Code'] as num?)?.toInt() ?? 0, // Handle as num
description: json['description'] ?? '',
image: List<String>.from(json['image'] ?? []),
quantity: (json['quantity'] as num?)?.toInt() ?? 0, // Handle as num
remainingQuantity: (json['remainingQuantity'] as num?)?.toInt() ?? 0, // Handle as num
processQuantity: (json['processQuantity']as num?)?.toInt()??0,
id: json['_id'] ?? '',
factory InvoiceItem.fromJson(Map<String, dynamic> json) {
return InvoiceItem(
productId: json['productId']??"",
sku: json['SKU']??"",
name: json['name']??"",
categoryName: json['categoryName']??"",
brandName: json['brandName']??"",
price: json['price'].toDouble(),
gst: json['GST'].toDouble(),
hsnCode: json['HSN_Code']??"",
processQuantity: json['processquantity']??"",
id: json['_id']??"",
);
}
@ -166,23 +489,13 @@ class OrderItem {
'price': price,
'GST': gst,
'HSN_Code': hsnCode,
'description': description,
'image': image,
'quantity': quantity,
'remainingQuantity': remainingQuantity,
'processquantity': processQuantity,
'_id': id,
};
}
@override
String toString() {
return 'OrderItem(productId: $productId, SKU: $sku, name: $name, categoryName: $categoryName, '
'brandName: $brandName, price: $price, GST: $gst, HSN_Code: $hsnCode, '
'description: $description, image: $image, quantity: $quantity, '
'remainingQuantity: $remainingQuantity, id: $id)';
}
}
//Model for the user who added the order
class AddedBy {
final String id;
final String designation;
@ -229,7 +542,8 @@ class AddedBy {
addedBy: json['addedBy'] ?? '',
userType: json['userType'] ?? '',
kyc: json['kyc'] ?? '',
fcmToken: json['fcm_token']?.toString(), // Handle null safely
fcmToken: json['fcm_token']?.toString(),
// Handle null safely
createdAt: DateTime.parse(json['createdAt'] ?? DateTime.now().toString()),
updatedAt: DateTime.parse(json['updatedAt'] ?? DateTime.now().toString()),
mappedSC: json['mappedSC'] ?? '',
@ -267,3 +581,8 @@ class AddedBy {
'mappedSC: $mappedSC, uniqueId: $uniqueId, mappedTM: $mappedTM)';
}
}
// Function to parse the JSON string and create a SingleOrder object
SingleGetOrderModel parseSingleOrder(String jsonString) {
final jsonData = json.decode(jsonString);
return SingleGetOrderModel.fromJson(jsonData);
}

View File

@ -196,6 +196,27 @@ class _HomeScreenState extends State<HomeScreen> {
),
],
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
HomeCard(
title: 'Opening Inventory',
onTap: () => Get.to(
() => InventoryManagementScreen(),
),
),
// HomeCard(
// title: 'Announcement',
// onTap: () => Get.to(
// () => AnnouncementScreen(),
// ),
// ),
],
),
],

View File

@ -248,6 +248,19 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
_buildFilterDropdown(index),
),
),
SizedBox(
// height: Get.height * 0.1,
child:_products.isEmpty // Check if no products found
? Center(
child: Padding(
padding: const EdgeInsets.all(40.0),
child: Text(
"No products found!",
style: TextStyle(fontSize: 16),
),
),
) : SizedBox(),
),
SizedBox(
height: Get.height * 0.6,
child: ListView.builder(
@ -272,6 +285,7 @@ class _ProductCatalogScreenState extends State<ProductCatalogScreen> {
},
),
),
],
),
),

View File

@ -122,6 +122,11 @@ class _PartialPendingDialogScreenState extends State<PartialPendingDialogScreen>
@override
Widget build(BuildContext context) {
final order = widget.placedOrderList!.orderItem[0];
final subTotalProcesssItem = order.price! * order.remainingQuantity!.toInt();
final GstTotalAmounProcessItem = (order.price! * order.remainingQuantity!.toInt()) *(order.gst!/100 );
final grandTotalProcessItem = subTotalProcesssItem + GstTotalAmounProcessItem;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
@ -205,7 +210,7 @@ class _PartialPendingDialogScreenState extends State<PartialPendingDialogScreen>
fontWeight: FontWeight.bold,
),
),
Text("${widget.placedOrderList!.subtotal ?? 0}"),
Text("${subTotalProcesssItem}"),
],
),
Row(
@ -219,7 +224,7 @@ class _PartialPendingDialogScreenState extends State<PartialPendingDialogScreen>
fontWeight: FontWeight.bold,
),
),
Text("${widget.placedOrderList!.gstTotal ?? 0}"),
Text("${GstTotalAmounProcessItem}"),
],
),
Row(
@ -233,7 +238,7 @@ class _PartialPendingDialogScreenState extends State<PartialPendingDialogScreen>
fontWeight: FontWeight.bold,
),
),
Text("${widget.placedOrderList!.grandTotal ?? 0}"),
Text("${grandTotalProcessItem}"),
],
),
],

View File

@ -359,8 +359,6 @@ class _PartialProcessingDialogScreenState extends State<PartialProcessingDialogS
await controller.placeRDOrder();
showSnackbar("Partial order processed successfully.");
// Close the dialog before navigating to another screen
Navigator.of(context).pop();
// Navigate to the pending screen
Get.to(RdOrderPendingScreen());
@ -382,6 +380,10 @@ class _PartialProcessingDialogScreenState extends State<PartialProcessingDialogS
@override
Widget build(BuildContext context) {
final order = widget.placedOrderList!.orderItem[0];
final subTotalProcesssItem = order.price! * order.remainingQuantity!.toInt();
final GstTotalAmounProcessItem = (order.price! * order.remainingQuantity!.toInt()) *(order.gst!/100 );
final grandTotalProcessItem = subTotalProcesssItem + GstTotalAmounProcessItem;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
@ -470,7 +472,7 @@ class _PartialProcessingDialogScreenState extends State<PartialProcessingDialogS
fontWeight: FontWeight.bold,
),
),
Text("${widget.placedOrderList!.subtotal ?? 0}"),
Text("${subTotalProcesssItem}"),
],
),
Row(

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,16 @@
import 'package:cheminova/controller/get_rd_cancle_controller.dart';
import 'package:cheminova/controller/get_rd_pending_controller.dart';
import 'package:cheminova/controller/rd_get_order_controller.dart';
import 'package:cheminova/controller/rd_processing_invoice_controller.dart';
import 'package:cheminova/models/get_rd_cancelled_model.dart';
import 'package:cheminova/models/get_rd_pennding_model.dart';
import 'package:cheminova/models/rd_get_order_model.dart';
import 'package:cheminova/models/single_get_order_model.dart';
import 'package:cheminova/screens/rd%20orders/rd_cancelled_details_screen.dart';
import 'package:cheminova/screens/rd%20orders/rd_dispatched_details_screen.dart';
import 'package:cheminova/screens/rd%20orders/rd_order_details_screen.dart';
import 'package:cheminova/screens/rd%20orders/rd_order_details_update.dart';
import 'package:cheminova/screens/rd%20orders/rd_pending_deatils.dart';
import 'package:cheminova/screens/rd%20orders/rd_processing_details.dart';
import 'package:cheminova/widgets/input_field.dart';
import 'package:cheminova/widgets/my_drawer.dart';
import 'package:flutter/material.dart';
@ -15,12 +18,15 @@ import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../controller/get_rd_cancle_controller.dart';
import '../../controller/get_single_invoice_Service.dart';
import '../../controller/get_single_invoice_controller.dart';
import '../../controller/rd_get_single_service.dart';
import '../order_management/order_management_detail_screen.dart';
class RdCancelledScreen extends StatefulWidget {
final PlacedOrdersResponse? getrdProduct;
final GetRdCancelledModel? getrdProduct;
RdCancelledScreen({super.key, this.getrdProduct});
@ -37,7 +43,11 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
"cancelled",
"delivered",];
int _selectedIndex = 0;
final GetRDCancleController _getRdProductController = Get.put(GetRDCancleController());
final GetRDCancleController _getRDCancleController = Get.put(GetRDCancleController());
// final GetSingleInvoiceController _getSingleInvoiceController = Get.put(GetSingleInvoiceController());
// final GetRDProcessingInvoiceController _getRDProcessingInvoiceController = Get.put(GetRDProcessingInvoiceController());
// // final GetProductRDController _getRdProductController =
// // Get.put(GetProductRDController());
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
@override
@ -49,11 +59,12 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
Future<void> _onRefresh() async {
await getOrder1();
await Future.delayed(Duration(seconds: 1));
}
Future<void> getOrder1() async {
await _getRdProductController.getRDCancleProduct();
if (_getRdProductController.productRDList.isEmpty) {
await _getRDCancleController.getRDCancleProduct();
if (_getRDCancleController.productRDList.isEmpty) {
print("No orders found.");
} else {
print("Orders fetched successfully");
@ -70,11 +81,71 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
DateTime parsedDate = DateTime.parse(apiDate).toLocal(); // Convert to local time
// Format the date and time according to your specified format
String formattedDate = DateFormat('EEE MMM dd yyyy').format(parsedDate);
String formattedDate = DateFormat('EEE MMM dd yyyy hh:mm a').format(parsedDate);
return formattedDate; // Return the formatted date string
}
void onOrderTap(int index) async {
try {
// Fetch orders and ensure you wait for it to complete
await _getRDCancleController.getRDCancleProduct();
// Log the count of fetched orders
print('Fetched orders count: ${_getRDCancleController.productRDList.length}');
// Check if the productRDList is populated
if (_getRDCancleController.productRDList.isNotEmpty) {
// Ensure the index is valid
if (index >= 0 && index < _getRDCancleController.productRDList.length) {
// Get the order ID from the list based on the index
final orderId = _getRDCancleController.productRDList[index].id;
final invoiceId = _getRDCancleController.productRDList[index].invoices[0];
// Retrieve the token from SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token');
// Check if the token is not null
if (token != null) {
// Fetch the single order using the order ID
final SingleGetOrderModel? singleOrder = await GetSingleProductService().getSingleOrder(token, orderId);
// Check if the single order was fetched successfully
if (singleOrder != null) {
// Navigate to the details screen with the fetched order
Get.to(() => RdOrderCancelledScreenDetailScreen(
placedOrderList: singleOrder, // Pass the single order instance
orderId: orderId,
));
} else {
// Handle the case where the single order could not be fetched
Get.snackbar("Error", "Unable to fetch order details.");
}
} else {
// Handle the case where the token is null
Get.snackbar("Error", "User not authenticated.");
}
} else {
// Handle the case when the index is out of bounds
Get.snackbar("Error", "Invalid order selection.");
}
} else {
// Handle the case when the list is empty
Get.snackbar("Error", "No orders available to display.");
}
} catch (e) {
// Log any errors that occur during the process
print('Error in onOrderTap: $e');
Get.snackbar("Error", "An unexpected error occurred.");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -128,6 +199,7 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
controller: _searchController,
),
SizedBox(height: Get.height * 0.035),
SizedBox(height: Get.height * 0.035),
Card(
margin: const EdgeInsets.symmetric(horizontal: 18),
shape: RoundedRectangleBorder(
@ -140,63 +212,11 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
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: GestureDetector(
// onTap: () {
// setState(() {
// _selectedIndex = index; // Update selected index
// });
// // Navigate to different screens based on selected tab
// switch (_filterList[index]) {
// case "new":
// // Get.to(YourScreen1()); // Navigate to "new" orders screen
// break;
// case "pending":
// // Get.to(YourScreen2()); // Navigate to "pending" orders screen
// break;
// case "processing":
// // Get.to(YourScreen3()); // Navigate to "processing" orders screen
// break;
// // Add more cases for other statuses
// case "dispatched":
// // Get.to(YourScreen4()); // Navigate to dispatched orders
// break;
// case "cancelled":
// // Get.to(YourScreen5()); // Navigate to cancelled orders
// break;
// case "delivered":
// //Get.to(YourScreen6()); // Navigate to delivered orders
// break;
// default:
// // Get.to(YourScreen1()); // Default screen
// }
// },
// child: Chip(
// label: Text(capitalizeFirstLetter( _filterList[index])
// ,
// style: GoogleFonts.roboto(
// fontSize: 14,
// fontWeight: FontWeight.w500,
// color: _selectedIndex == index ? Colors.white : Colors.black, // Change color when selected
// ),
// ),
// backgroundColor: _selectedIndex == index ? Colors.blue : Colors.grey[300], // Change color when selected
// ),
// ),
// ),
// ),
// ),
SizedBox(
height: Get.height * 0.6,
child: Obx(() {
if (_getRdProductController.productRDList.isEmpty) {
if (_getRDCancleController.productRDList.isEmpty) {
return Center(
child: Text(
'No Orders Found',
@ -208,7 +228,7 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
final Set<String> uniqueOrderIds = {};
final List<GetRdCancelledModel> uniqueOrders = [];
for (var order in _getRdProductController.productRDList) {
for (var order in _getRDCancleController.productRDList) {
if (uniqueOrderIds.add(order.id)) {
uniqueOrders.add(order);
}
@ -282,7 +302,16 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 8, 8, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Order Value: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)),
Text("${order.grandTotal}")
],
),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 8, 8, 0),
@ -310,10 +339,12 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: ()=>
Get.to(() =>
RdCancelledDetailScreen(
placedOrderList: uniqueOrders[index])), // Navigate to detail screen
onPressed: (){
onOrderTap(index);
},
// Get.to(() =>
// RdOrderPendingScreenDetailScreen(
// placedOrderList: uniqueOrders[index])), // Navigate to detail screen
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: const Color(0xFF004791),
@ -348,3 +379,5 @@ class _RdCancelledScreenState extends State<RdCancelledScreen> {
}
}

View File

@ -33,14 +33,14 @@ import '../../utils/show_snackbar.dart';
class RdOrderPendingScreenDetailScreen extends StatefulWidget {
//final Product? productModel;
// PlacedOrderList and PlacedOrderModel are optional parameters passed to this screen
SingleGetOrderModel? placedOrderList;
GetRdPendingModel? productpendingModel;
final SingleGetOrderModel? placedOrderList;
// GetRdPendingModel? productpendingModel;
final String orderId;
GetInvoiceModel? placeInvoiceList;
// GetInvoiceModel? placeInvoiceList;
// PlacedOrderModel? placedOrderModel;
// Constructor for initializing the screen with placed order details
RdOrderPendingScreenDetailScreen({super.key,this.placedOrderList,required this.orderId,this.placeInvoiceList});
RdOrderPendingScreenDetailScreen({super.key,this.placedOrderList,required this.orderId});
@override
State<RdOrderPendingScreenDetailScreen> createState() =>
@ -324,7 +324,28 @@ class _RdOrderPendingScreenDetailScreenState
}
@override
Widget build(BuildContext context) {
// int remainingQuantity = (widget.placedOrderList!.orderItem![0].quantity)! -(widget.placedOrderList!.orderItem![0].remainingQuantity!.toInt());
if (widget.placedOrderList == null) {
return Center(child: Text('No order details available'));
}
// Safely get the order and invoice list
final order = widget.placedOrderList!;
final invoices = order.invoices;
// Check if the invoices list contains at least 4 items
List<String>? invoiceIds;
if (invoices.isNotEmpty) {
// Ensure there are at least 4 invoices
if (invoices.length >= 4) {
// Get the ID of the 4th invoice (index 3)
invoiceIds = [invoices[3].invoiceId!]; // Assuming invoiceId is a String
} else {
invoiceIds = []; // Fallback if not enough invoices
}
} else {
invoiceIds = []; // Fallback if no invoices available
}
//int remainingQuantity = (widget.placedOrderList!.orderItem![0].quantity)! -(widget.placedOrderList!.orderItem![0].remainingQuantity!.toInt());
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
@ -384,13 +405,13 @@ class _RdOrderPendingScreenDetailScreenState
children: [
Card(
child: Column(
child:
Column(
children: [
SizedBox(
width: Get.width,
child: Padding(
padding:
const EdgeInsets.fromLTRB(8, 8, 8, 0),
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Text(
"Invoices",
style: GoogleFonts.roboto(
@ -400,12 +421,18 @@ class _RdOrderPendingScreenDetailScreenState
),
),
),
SizedBox(
width: Get.width,
// Displaying each invoice in a separate card
if (widget.placedOrderList!.invoices.isNotEmpty)
...widget.placedOrderList!.invoices.map((invoice) {
return Card(
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
child: Padding(
padding:
const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Row(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Invoice ID
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
@ -415,20 +442,12 @@ class _RdOrderPendingScreenDetailScreenState
fontWeight: FontWeight.bold,
),
),
Text(widget.placeInvoiceList!.invoiceId.toString()),
// Text(widget.placedOrderList!.uniqueId),
Text(invoice.invoiceId.toString()),
],
),
),
),
SizedBox(
width: Get.width,
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10), // Add spacing
// Items for this invoice
Text(
"Items: ",
style: GoogleFonts.roboto(
@ -436,12 +455,13 @@ class _RdOrderPendingScreenDetailScreenState
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 10), // Add spacing between the title and the list of items
Column(
children: widget.placeInvoiceList!.items!.map((item) {
const SizedBox(height: 10), // Add spacing between title and items
// List of items in this invoice
Column(
children: invoice.items!.map((item) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0), // Add some spacing between items
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -451,7 +471,7 @@ class _RdOrderPendingScreenDetailScreenState
style: GoogleFonts.roboto(
fontSize: Get.width * 0.03,
),
overflow: TextOverflow.ellipsis, // Handle long text
overflow: TextOverflow.ellipsis,
),
),
Text("x ${item.processQuantity.toString()}"),
@ -460,111 +480,90 @@ class _RdOrderPendingScreenDetailScreenState
);
}).toList(),
),
],
),
),
),
SizedBox(
width: Get.width,
child: Padding(
padding:
const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Row(
const SizedBox(height: 10), // Add spacing between sections
// Sub Total
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Sub Total : ",
"Sub Total:",
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.bold,
),
),
Text("${widget.placeInvoiceList!.subtotal}"),
Text("${invoice.subtotal}"),
],
),
),
),
// GST
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"GST:",
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.bold,
),
),
Text("${invoice.gstTotal}"),
],
),
SizedBox(
width: Get.width,
child: Padding(
padding:
const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Row(
// Invoice Amount
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"GST : ",
"Invoice Amount:",
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.bold,
),
),
Text("${widget.placeInvoiceList!.gstTotal}"),
Text("${invoice.invoiceAmount}"),
],
),
),
),
SizedBox(
width: Get.width,
child: Padding(
padding:
const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Row(
// Courier Status
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Invoice Amount: ",
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.bold,
),
),
Text("${widget.placeInvoiceList!.invoiceAmount}"),
],
),
),
),
SizedBox(
width: Get.width,
child: Padding(
padding:
const EdgeInsets.fromLTRB(8, 8, 8, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Courier Status : ",
"Courier Status:",
style: GoogleFonts.roboto(
fontSize: Get.width * 0.04,
fontWeight: FontWeight.bold,
),
),
ElevatedButton(
onPressed: (){},
// Get.to(() =>
// RdOrderDetailScreen(
// placedOrderList: uniqueOrders[index])), // Navigate to detail screen
onPressed: () {},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor:_getCourierStatusColor(widget.placeInvoiceList!.courierStatus.toString()),
backgroundColor: _getCourierStatusColor(invoice.courierStatus.toString()),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
),
child: Text(capitalizeFirstLetter(widget.placeInvoiceList!.courierStatus.toString()),
// Text(widget.placedOrderList!.status.toString())
//Text(widget.placedOrderList!.status, style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)),
),
//Text("${widget.placedOrderList!.gstTotal}"),
)],
borderRadius: BorderRadius.circular(10),
),
),
child: Text(
capitalizeFirstLetter(invoice.courierStatus.toString()),
),
),
],
),
],
),
),
);
}).toList(),
],
),
),
const SizedBox(height: 8),
const SizedBox(height: 8),
@ -591,9 +590,9 @@ class _RdOrderPendingScreenDetailScreenState
Expanded(
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: widget.placedOrderList?.orderItem!.length ?? 0,
itemCount: order.orderItem!.length ?? 0,
itemBuilder: (context, index) {
final orderItem = widget.placedOrderList!.orderItem![index];
final orderItem =order.orderItem![index];
final subTotal = orderItem.price * orderItem.quantity!.toInt();
final GstTotalAmount = (orderItem.price * orderItem.quantity!.toInt()) *(orderItem.gst/100 );
final grandTotal = subTotal + GstTotalAmount;
@ -678,14 +677,14 @@ class _RdOrderPendingScreenDetailScreenState
Expanded(
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: widget.placedOrderList?.orderItem
itemCount: order.orderItem
?.where((item) => item.remainingQuantity! > 0)
.length ?? 0,
itemBuilder: (context, index) {
// Filter items with non-zero quantities
final filteredItems = widget.placedOrderList!.orderItem!
final filteredItems =order!.orderItem!
.where((item) => item.remainingQuantity! > 0)
.toList();
@ -775,7 +774,7 @@ class _RdOrderPendingScreenDetailScreenState
fontWeight: FontWeight.w500,
),
),
Text(capitalizeFirstLetter(widget.placeInvoiceList!.orderId!.paymentMode.toString())),
Text(capitalizeFirstLetter(widget.placedOrderList!.paymentMode.toString())),
// Text("${widget.placedOrderList!.paymentMode}",maxLines: 4,
// overflow:TextOverflow.ellipsis,)
],
@ -808,7 +807,7 @@ class _RdOrderPendingScreenDetailScreenState
),
SizedBox(width: Get.width*0.01,),
//Text(capitalizeFirstLetter(widget.placedOrderList!.status)),
Text(capitalizeFirstLetter(widget.placedOrderList!.status.toString()),maxLines: 4,
Text(capitalizeFirstLetter(order!.status.toString()),maxLines: 4,
overflow:TextOverflow.ellipsis,)
],
),
@ -1014,12 +1013,12 @@ class simple extends State<RdOrderPendingScreenDetailScreen> {
onPressed: () {},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.white,
backgroundColor: _getCourierStatusColor(widget.placeInvoiceList!.courierStatus.toString()), // Call the method here
backgroundColor: _getCourierStatusColor(widget.placedOrderList!.invoices[0]!.courierStatus.toString()), // Call the method here
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Text(widget.placeInvoiceList!.courierStatus.toString()),
child: Text(widget.placedOrderList!.invoices[0]!.courierStatus.toString()),
),
],
),

View File

@ -4,6 +4,7 @@ import 'package:cheminova/controller/rd_get_order_controller.dart';
import 'package:cheminova/controller/rd_processing_invoice_controller.dart';
import 'package:cheminova/models/get_rd_pennding_model.dart';
import 'package:cheminova/models/rd_get_order_model.dart';
import 'package:cheminova/models/single_get_order_model.dart';
import 'package:cheminova/screens/rd%20orders/rd_order_details_screen.dart';
import 'package:cheminova/screens/rd%20orders/rd_order_details_update.dart';
import 'package:cheminova/screens/rd%20orders/rd_pending_deatils.dart';
@ -88,9 +89,6 @@ class _RdOrderPendingScreenState extends State<RdOrderPendingScreen> {
// Fetch orders and ensure you wait for it to complete
await _getRdPendingController.getRDPendingProduct();
// await _getRDProcessingInvoiceController.getRDProcessingInvoiceProduct();
// await _getSingleInvoiceController.fetchInvoice(_getRDProcessingInvoiceController.productProcessingRDList[0].id);
// Log the count of fetched orders
print('Fetched orders count: ${_getRdPendingController.productRDList.length}');
@ -101,22 +99,22 @@ class _RdOrderPendingScreenState extends State<RdOrderPendingScreen> {
// Get the order ID from the list based on the index
final orderId = _getRdPendingController.productRDList[index].id;
final invoiceId = _getRdPendingController.productRDList[index].invoices[0];
// Retrieve the token from SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token');
// Check if the token is not null
if (token != null) {
// Fetch the single order using the order ID, and avoid caching issues
final singleOrder = await GetSingleProductService().getSingleOrder(token, orderId);
final singleInvoice = await GetSingleInvoiceService().fetchInvoice(token, invoiceId.toString());
// Fetch the single order using the order ID
final SingleGetOrderModel? singleOrder = await GetSingleProductService().getSingleOrder(token, orderId);
// Check if the single order was fetched successfully
if (singleOrder != null) {
// Navigate to the details screen with the fetched order
Get.to(() => RdOrderPendingScreenDetailScreen(
placedOrderList: singleOrder,
placedOrderList: singleOrder, // Pass the single order instance
orderId: orderId,
placeInvoiceList: singleInvoice,
));
} else {
@ -144,6 +142,7 @@ class _RdOrderPendingScreenState extends State<RdOrderPendingScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(

View File

@ -80,6 +80,14 @@ class ApiUrls {
//============================== Annaouncement Details ==============================//
static const String AnnaouncementUrl = '/api/announcement/PDs';
//============================== Annaouncement Details ==============================//
//============================== shipto Billto Details ==============================//
static const String ShiptoandBilltoAddressUrl = '/api/shipping/address/user/address';
//============================== Product stock Details ==============================//
static const String ProductStockUrl = '/api/pd/stock';
//============================== Product Update stock Details ==============================//
static const String ProductUpdateStockUrl = '/api/pd/stock-update';
}

View File

@ -37,14 +37,14 @@ class _MyDrawerState extends State<MyDrawer> {
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
user!.name ?? "username",
user?.name ?? "username",
style: const TextStyle(
color: Colors.white,
fontSize: 18,
),
),
Text(
user!.uniqueId ?? 'Employee ID',
user?.uniqueId ?? 'Employee ID',
style: const TextStyle(
color: Colors.white,
fontSize: 20,

View File

@ -94,7 +94,7 @@ class _ProductCard1State extends State<ProductCard1> {
),
),
Text(
" ${widget.productModel.quantity}",
" ${widget.productModel.remainingQuantity}",
style: GoogleFonts.roboto(
fontSize: 15,
),