dev #1

Merged
aefril merged 128 commits from dev into main 2025-08-13 17:19:48 +00:00
25 changed files with 1422 additions and 333 deletions
Showing only changes of commit 051b64e3a6 - Show all commits

View File

@ -3,4 +3,5 @@ class Variables {
static const String apiVersion = 'v1'; static const String apiVersion = 'v1';
// static const String baseUrl = 'http://192.168.1.202:8000'; // static const String baseUrl = 'http://192.168.1.202:8000';
static const String baseUrl = 'https://enaklo-pos-be.altru.id'; static const String baseUrl = 'https://enaklo-pos-be.altru.id';
static const int defaultLimit = 10;
} }

View File

@ -5,7 +5,7 @@ import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:enaklo_pos/core/utils/helper_pdf_service.dart'; import 'package:enaklo_pos/core/utils/helper_pdf_service.dart';
import 'package:enaklo_pos/data/models/response/order_remote_datasource.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:pdf/widgets.dart'; import 'package:pdf/widgets.dart';
import 'package:pdf/pdf.dart'; import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw; import 'package:pdf/widgets.dart' as pw;
@ -13,7 +13,7 @@ import 'package:pdf/widgets.dart' as pw;
class TransactionSalesInvoice { class TransactionSalesInvoice {
static late Font ttf; static late Font ttf;
static Future<File> generate( static Future<File> generate(
List<ItemOrder> itemOrders, String searchDateFormatted) async { List<Order> itemOrders, String searchDateFormatted) async {
final pdf = Document(); final pdf = Document();
// var data = await rootBundle.load("assets/fonts/noto-sans.ttf"); // var data = await rootBundle.load("assets/fonts/noto-sans.ttf");
// ttf = Font.ttf(data); // ttf = Font.ttf(data);
@ -70,7 +70,7 @@ class TransactionSalesInvoice {
), ),
]); ]);
static Widget buildInvoice(List<ItemOrder> itemOrders) { static Widget buildInvoice(List<Order> itemOrders) {
final headers = [ final headers = [
'Total', 'Total',
'Sub Total', 'Sub Total',
@ -81,12 +81,13 @@ class TransactionSalesInvoice {
]; ];
final data = itemOrders.map((item) { final data = itemOrders.map((item) {
return [ return [
item.total!.currencyFormatRp, item.totalAmount!.currencyFormatRp,
item.subTotal!.currencyFormatRp, item.subtotal!.currencyFormatRp,
item.tax!.currencyFormatRp, item.taxAmount!.currencyFormatRp,
int.parse(item.discountAmount!.replaceAll('.00', '')).currencyFormatRp, int.parse(item.discountAmount!.toString().replaceAll('.00', ''))
item.serviceCharge!.currencyFormatRp, .currencyFormatRp,
item.transactionTime!.toFormattedDate2(), 0,
item.createdAt!.toFormattedDate2(),
]; ];
}).toList(); }).toList();

View File

@ -6,7 +6,7 @@ import 'package:dio/dio.dart';
import 'package:enaklo_pos/core/constants/variables.dart'; import 'package:enaklo_pos/core/constants/variables.dart';
import 'package:enaklo_pos/core/network/dio_client.dart'; import 'package:enaklo_pos/core/network/dio_client.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart'; import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/data/models/response/order_remote_datasource.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:enaklo_pos/data/models/response/payment_method_response_model.dart'; import 'package:enaklo_pos/data/models/response/payment_method_response_model.dart';
import 'package:enaklo_pos/data/models/response/summary_response_model.dart'; import 'package:enaklo_pos/data/models/response/summary_response_model.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/presentation/home/models/order_model.dart';
@ -223,4 +223,48 @@ class OrderRemoteDatasource {
return const Left('Terjadi kesalahan tak terduga'); return const Left('Terjadi kesalahan tak terduga');
} }
} }
Future<Either<String, OrderResponseModel>> getOrder(
{int page = 1,
int limit = Variables.defaultLimit,
String status = 'completed'}) async {
try {
final authData = await AuthLocalDataSource().getAuthData();
final response = await dio.get(
'${Variables.baseUrl}/api/v1/orders',
queryParameters: {
'page': page,
'limit': limit,
'status': status,
'outlet_id': authData.user?.outletId,
},
options: Options(
headers: {
'Authorization': 'Bearer ${authData.token}',
'Accept': 'application/json',
'Content-Type': 'application/json',
},
),
);
log("📥 HTTP Status Code: ${response.statusCode}");
log("📥 Response Body: ${response.data}");
if (response.statusCode == 200) {
log("âś… getOrderByRangeDate API call successful");
return Right(OrderResponseModel.fromMap(response.data));
} else {
log("❌ getOrderByRangeDate API call failed - Status: ${response.statusCode}");
return const Left("Failed Load Data");
}
} on DioException catch (e) {
final errorMessage = 'Something went wrong';
log("đź’Ą Dio error: ${e.message}");
log("đź’Ą Dio response: ${e.response?.data}");
return Left(errorMessage);
} catch (e) {
log("đź’Ą Unexpected error: $e");
return Left("Unexpected Error: $e");
}
}
} }

View File

@ -1,113 +0,0 @@
import 'dart:convert';
class OrderResponseModel {
String? status;
List<ItemOrder>? data;
OrderResponseModel({
this.status,
this.data,
});
factory OrderResponseModel.fromJson(String str) =>
OrderResponseModel.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory OrderResponseModel.fromMap(Map<String, dynamic> json) =>
OrderResponseModel(
status: json["status"],
data: json["data"] == null
? []
: List<ItemOrder>.from(
json["data"]!.map((x) => ItemOrder.fromMap(x))),
);
Map<String, dynamic> toMap() => {
"status": status,
"data":
data == null ? [] : List<dynamic>.from(data!.map((x) => x.toMap())),
};
}
class ItemOrder {
int? id;
int? paymentAmount;
int? subTotal;
int? tax;
int? discount;
String? discountAmount;
int? serviceCharge;
int? total;
String? paymentMethod;
int? totalItem;
int? idKasir;
String? namaKasir;
DateTime? transactionTime;
DateTime? createdAt;
DateTime? updatedAt;
ItemOrder({
this.id,
this.paymentAmount,
this.subTotal,
this.tax,
this.discount,
this.discountAmount,
this.serviceCharge,
this.total,
this.paymentMethod,
this.totalItem,
this.idKasir,
this.namaKasir,
this.transactionTime,
this.createdAt,
this.updatedAt,
});
factory ItemOrder.fromJson(String str) => ItemOrder.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory ItemOrder.fromMap(Map<String, dynamic> json) => ItemOrder(
id: json["id"],
paymentAmount: json["payment_amount"],
subTotal: json["sub_total"],
tax: json["tax"],
discount: json["discount"],
discountAmount: json["discount_amount"],
serviceCharge: json["service_charge"],
total: json["total"],
paymentMethod: json["payment_method"]!,
totalItem: json["total_item"],
idKasir: json["id_kasir"],
namaKasir: json["nama_kasir"],
transactionTime: json["transaction_time"] == null
? null
: DateTime.parse(json["transaction_time"]),
createdAt: json["created_at"] == null
? null
: DateTime.parse(json["created_at"]),
updatedAt: json["updated_at"] == null
? null
: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toMap() => {
"id": id,
"payment_amount": paymentAmount,
"sub_total": subTotal,
"tax": tax,
"discount": discount,
"discount_amount": discountAmount,
"service_charge": serviceCharge,
"total": total,
"payment_method": paymentMethod,
"total_item": totalItem,
"id_kasir": idKasir,
"nama_kasir": namaKasir,
"transaction_time": transactionTime?.toIso8601String(),
"created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(),
};
}

View File

@ -0,0 +1,220 @@
import 'dart:convert';
class OrderResponseModel {
final bool? success;
final OrderData? data;
final dynamic errors;
OrderResponseModel({
this.success,
this.data,
this.errors,
});
factory OrderResponseModel.fromJson(String str) =>
OrderResponseModel.fromMap(json.decode(str));
String toJson() => json.encode(toMap());
factory OrderResponseModel.fromMap(Map<String, dynamic> json) =>
OrderResponseModel(
success: json["success"],
data: json["data"] == null ? null : OrderData.fromMap(json["data"]),
errors: json["errors"],
);
Map<String, dynamic> toMap() => {
"success": success,
"data": data?.toMap(),
"errors": errors,
};
}
class OrderData {
final List<Order>? orders;
final int? totalCount;
final int? page;
final int? limit;
final int? totalPages;
OrderData({
this.orders,
this.totalCount,
this.page,
this.limit,
this.totalPages,
});
factory OrderData.fromMap(Map<String, dynamic> json) => OrderData(
orders: json["orders"] == null
? []
: List<Order>.from(json["orders"].map((x) => Order.fromMap(x))),
totalCount: json["total_count"],
page: json["page"],
limit: json["limit"],
totalPages: json["total_pages"],
);
Map<String, dynamic> toMap() => {
"orders": orders == null
? []
: List<dynamic>.from(orders!.map((x) => x.toMap())),
"total_count": totalCount,
"page": page,
"limit": limit,
"total_pages": totalPages,
};
}
class Order {
final String? id;
final String? orderNumber;
final String? outletId;
final String? userId;
final String? tableNumber;
final String? orderType;
final String? status;
final int? subtotal;
final int? taxAmount;
final int? discountAmount;
final int? totalAmount;
final String? notes;
final Map<String, dynamic>? metadata;
final DateTime? createdAt;
final DateTime? updatedAt;
final List<OrderItem>? orderItems;
Order({
this.id,
this.orderNumber,
this.outletId,
this.userId,
this.tableNumber,
this.orderType,
this.status,
this.subtotal,
this.taxAmount,
this.discountAmount,
this.totalAmount,
this.notes,
this.metadata,
this.createdAt,
this.updatedAt,
this.orderItems,
});
factory Order.fromMap(Map<String, dynamic> json) => Order(
id: json["id"],
orderNumber: json["order_number"],
outletId: json["outlet_id"],
userId: json["user_id"],
tableNumber: json["table_number"],
orderType: json["order_type"],
status: json["status"],
subtotal: json["subtotal"],
taxAmount: json["tax_amount"],
discountAmount: json["discount_amount"],
totalAmount: json["total_amount"],
notes: json["notes"],
metadata: json["metadata"] ?? {},
createdAt: json["created_at"] == null
? null
: DateTime.parse(json["created_at"]),
updatedAt: json["updated_at"] == null
? null
: DateTime.parse(json["updated_at"]),
orderItems: json["order_items"] == null
? []
: List<OrderItem>.from(
json["order_items"].map((x) => OrderItem.fromMap(x))),
);
Map<String, dynamic> toMap() => {
"id": id,
"order_number": orderNumber,
"outlet_id": outletId,
"user_id": userId,
"table_number": tableNumber,
"order_type": orderType,
"status": status,
"subtotal": subtotal,
"tax_amount": taxAmount,
"discount_amount": discountAmount,
"total_amount": totalAmount,
"notes": notes,
"metadata": metadata,
"created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(),
"order_items": orderItems == null
? []
: List<dynamic>.from(orderItems!.map((x) => x.toMap())),
};
}
class OrderItem {
final String? id;
final String? orderId;
final String? productId;
final String? productName;
final String? productVariantId;
final int? quantity;
final int? unitPrice;
final int? totalPrice;
final List<dynamic>? modifiers;
final String? notes;
final String? status;
final DateTime? createdAt;
final DateTime? updatedAt;
OrderItem({
this.id,
this.orderId,
this.productId,
this.productName,
this.productVariantId,
this.quantity,
this.unitPrice,
this.totalPrice,
this.modifiers,
this.notes,
this.status,
this.createdAt,
this.updatedAt,
});
factory OrderItem.fromMap(Map<String, dynamic> json) => OrderItem(
id: json["id"],
orderId: json["order_id"],
productId: json["product_id"],
productName: json["product_name"],
productVariantId: json["product_variant_id"],
quantity: json["quantity"],
unitPrice: json["unit_price"],
totalPrice: json["total_price"],
modifiers: json["modifiers"] ?? [],
notes: json["notes"],
status: json["status"],
createdAt: json["created_at"] == null
? null
: DateTime.parse(json["created_at"]),
updatedAt: json["updated_at"] == null
? null
: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toMap() => {
"id": id,
"order_id": orderId,
"product_id": productId,
"product_name": productName,
"product_variant_id": productVariantId,
"quantity": quantity,
"unit_price": unitPrice,
"total_price": totalPrice,
"modifiers": modifiers,
"notes": notes,
"status": status,
"created_at": createdAt?.toIso8601String(),
"updated_at": updatedAt?.toIso8601String(),
};
}

View File

@ -4,6 +4,7 @@ import 'package:enaklo_pos/data/datasources/outlet_remote_data_source.dart';
import 'package:enaklo_pos/presentation/home/bloc/order_form/order_form_bloc.dart'; import 'package:enaklo_pos/presentation/home/bloc/order_form/order_form_bloc.dart';
import 'package:enaklo_pos/presentation/home/bloc/outlet_loader/outlet_loader_bloc.dart'; import 'package:enaklo_pos/presentation/home/bloc/outlet_loader/outlet_loader_bloc.dart';
import 'package:enaklo_pos/presentation/home/bloc/product_loader/product_loader_bloc.dart'; import 'package:enaklo_pos/presentation/home/bloc/product_loader/product_loader_bloc.dart';
import 'package:enaklo_pos/presentation/sales/blocs/order_loader/order_loader_bloc.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart'; import 'package:enaklo_pos/data/datasources/auth_local_datasource.dart';
import 'package:enaklo_pos/data/datasources/auth_remote_datasource.dart'; import 'package:enaklo_pos/data/datasources/auth_remote_datasource.dart';
@ -227,6 +228,9 @@ class _MyAppState extends State<MyApp> {
BlocProvider( BlocProvider(
create: (context) => OrderFormBloc(OrderRemoteDatasource()), create: (context) => OrderFormBloc(OrderRemoteDatasource()),
), ),
BlocProvider(
create: (context) => OrderLoaderBloc(OrderRemoteDatasource()),
),
BlocProvider( BlocProvider(
create: (context) => OutletLoaderBloc(OutletRemoteDataSource()), create: (context) => OutletLoaderBloc(OutletRemoteDataSource()),
), ),

View File

@ -46,6 +46,8 @@ class _DashboardPageState extends State<DashboardPage> {
setState(() {}); setState(() {});
} }
late StreamSubscription<List<ConnectivityResult>> _connectivitySubscription;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -63,24 +65,19 @@ class _DashboardPageState extends State<DashboardPage> {
const SettingsPage(), const SettingsPage(),
]; ];
// ignore: unused_local_variable // ignore: unused_local_variable
StreamSubscription<List<ConnectivityResult>> subscription = Connectivity() _connectivitySubscription = Connectivity()
.onConnectivityChanged .onConnectivityChanged
.listen((List<ConnectivityResult> connectivityResult) { .listen((List<ConnectivityResult> connectivityResult) {
// Received changes in available connectivity types! if (!mounted) return; // <-- Tambahkan ini!
if (connectivityResult.contains(ConnectivityResult.mobile)) { if (connectivityResult.contains(ConnectivityResult.mobile)) {
// Mobile network available.
context context
.read<OnlineCheckerBloc>() .read<OnlineCheckerBloc>()
.add(const OnlineCheckerEvent.check(true)); .add(const OnlineCheckerEvent.check(true));
} else if (connectivityResult.contains(ConnectivityResult.wifi)) { } else if (connectivityResult.contains(ConnectivityResult.wifi)) {
// Wi-fi is available.
context context
.read<OnlineCheckerBloc>() .read<OnlineCheckerBloc>()
.add(const OnlineCheckerEvent.check(true)); .add(const OnlineCheckerEvent.check(true));
// Note for Android:
// When both mobile and Wi-Fi are turned on system will return Wi-Fi only as active network type
} else { } else {
// Neither mobile network nor Wi-fi available.
context context
.read<OnlineCheckerBloc>() .read<OnlineCheckerBloc>()
.add(const OnlineCheckerEvent.check(false)); .add(const OnlineCheckerEvent.check(false));
@ -88,6 +85,12 @@ class _DashboardPageState extends State<DashboardPage> {
}); });
} }
@override
void dispose() {
_connectivitySubscription.cancel(); // <-- Cancel subscription di dispose
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SafeArea( return SafeArea(

View File

@ -37,7 +37,9 @@ class HomeRightTitle extends StatelessWidget {
width: 180.0, width: 180.0,
height: 40, height: 40,
elevation: 0, elevation: 0,
onPressed: () => context.push(SalesPage()), onPressed: () => context.push(SalesPage(
status: 'pending',
)),
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
icon: Icon( icon: Icon(

View File

@ -1,7 +1,6 @@
import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:enaklo_pos/data/datasources/order_remote_datasource.dart'; import 'package:enaklo_pos/data/datasources/order_remote_datasource.dart';
import 'package:enaklo_pos/data/models/response/order_remote_datasource.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
part 'transaction_report_event.dart'; part 'transaction_report_event.dart';
@ -19,7 +18,8 @@ class TransactionReportBloc
event.endDate, event.endDate,
); );
result.fold((l) => emit(_Error(l)), (r) => emit(_Loaded(r.data!))); result.fold(
(l) => emit(_Error(l)), (r) => emit(_Loaded(r.data!.orders!)));
}); });
} }
} }

View File

@ -342,7 +342,7 @@ mixin _$TransactionReportState {
required TResult Function() initial, required TResult Function() initial,
required TResult Function() loading, required TResult Function() loading,
required TResult Function(String message) error, required TResult Function(String message) error,
required TResult Function(List<ItemOrder> transactionReport) loaded, required TResult Function(List<Order> transactionReport) loaded,
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
@ -350,7 +350,7 @@ mixin _$TransactionReportState {
TResult? Function()? initial, TResult? Function()? initial,
TResult? Function()? loading, TResult? Function()? loading,
TResult? Function(String message)? error, TResult? Function(String message)? error,
TResult? Function(List<ItemOrder> transactionReport)? loaded, TResult? Function(List<Order> transactionReport)? loaded,
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@optionalTypeArgs @optionalTypeArgs
@ -358,7 +358,7 @@ mixin _$TransactionReportState {
TResult Function()? initial, TResult Function()? initial,
TResult Function()? loading, TResult Function()? loading,
TResult Function(String message)? error, TResult Function(String message)? error,
TResult Function(List<ItemOrder> transactionReport)? loaded, TResult Function(List<Order> transactionReport)? loaded,
required TResult orElse(), required TResult orElse(),
}) => }) =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
@ -455,7 +455,7 @@ class _$InitialImpl implements _Initial {
required TResult Function() initial, required TResult Function() initial,
required TResult Function() loading, required TResult Function() loading,
required TResult Function(String message) error, required TResult Function(String message) error,
required TResult Function(List<ItemOrder> transactionReport) loaded, required TResult Function(List<Order> transactionReport) loaded,
}) { }) {
return initial(); return initial();
} }
@ -466,7 +466,7 @@ class _$InitialImpl implements _Initial {
TResult? Function()? initial, TResult? Function()? initial,
TResult? Function()? loading, TResult? Function()? loading,
TResult? Function(String message)? error, TResult? Function(String message)? error,
TResult? Function(List<ItemOrder> transactionReport)? loaded, TResult? Function(List<Order> transactionReport)? loaded,
}) { }) {
return initial?.call(); return initial?.call();
} }
@ -477,7 +477,7 @@ class _$InitialImpl implements _Initial {
TResult Function()? initial, TResult Function()? initial,
TResult Function()? loading, TResult Function()? loading,
TResult Function(String message)? error, TResult Function(String message)? error,
TResult Function(List<ItemOrder> transactionReport)? loaded, TResult Function(List<Order> transactionReport)? loaded,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (initial != null) { if (initial != null) {
@ -572,7 +572,7 @@ class _$LoadingImpl implements _Loading {
required TResult Function() initial, required TResult Function() initial,
required TResult Function() loading, required TResult Function() loading,
required TResult Function(String message) error, required TResult Function(String message) error,
required TResult Function(List<ItemOrder> transactionReport) loaded, required TResult Function(List<Order> transactionReport) loaded,
}) { }) {
return loading(); return loading();
} }
@ -583,7 +583,7 @@ class _$LoadingImpl implements _Loading {
TResult? Function()? initial, TResult? Function()? initial,
TResult? Function()? loading, TResult? Function()? loading,
TResult? Function(String message)? error, TResult? Function(String message)? error,
TResult? Function(List<ItemOrder> transactionReport)? loaded, TResult? Function(List<Order> transactionReport)? loaded,
}) { }) {
return loading?.call(); return loading?.call();
} }
@ -594,7 +594,7 @@ class _$LoadingImpl implements _Loading {
TResult Function()? initial, TResult Function()? initial,
TResult Function()? loading, TResult Function()? loading,
TResult Function(String message)? error, TResult Function(String message)? error,
TResult Function(List<ItemOrder> transactionReport)? loaded, TResult Function(List<Order> transactionReport)? loaded,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (loading != null) { if (loading != null) {
@ -716,7 +716,7 @@ class _$ErrorImpl implements _Error {
required TResult Function() initial, required TResult Function() initial,
required TResult Function() loading, required TResult Function() loading,
required TResult Function(String message) error, required TResult Function(String message) error,
required TResult Function(List<ItemOrder> transactionReport) loaded, required TResult Function(List<Order> transactionReport) loaded,
}) { }) {
return error(message); return error(message);
} }
@ -727,7 +727,7 @@ class _$ErrorImpl implements _Error {
TResult? Function()? initial, TResult? Function()? initial,
TResult? Function()? loading, TResult? Function()? loading,
TResult? Function(String message)? error, TResult? Function(String message)? error,
TResult? Function(List<ItemOrder> transactionReport)? loaded, TResult? Function(List<Order> transactionReport)? loaded,
}) { }) {
return error?.call(message); return error?.call(message);
} }
@ -738,7 +738,7 @@ class _$ErrorImpl implements _Error {
TResult Function()? initial, TResult Function()? initial,
TResult Function()? loading, TResult Function()? loading,
TResult Function(String message)? error, TResult Function(String message)? error,
TResult Function(List<ItemOrder> transactionReport)? loaded, TResult Function(List<Order> transactionReport)? loaded,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (error != null) { if (error != null) {
@ -803,7 +803,7 @@ abstract class _$$LoadedImplCopyWith<$Res> {
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) = _$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
__$$LoadedImplCopyWithImpl<$Res>; __$$LoadedImplCopyWithImpl<$Res>;
@useResult @useResult
$Res call({List<ItemOrder> transactionReport}); $Res call({List<Order> transactionReport});
} }
/// @nodoc /// @nodoc
@ -825,7 +825,7 @@ class __$$LoadedImplCopyWithImpl<$Res>
null == transactionReport null == transactionReport
? _value._transactionReport ? _value._transactionReport
: transactionReport // ignore: cast_nullable_to_non_nullable : transactionReport // ignore: cast_nullable_to_non_nullable
as List<ItemOrder>, as List<Order>,
)); ));
} }
} }
@ -833,12 +833,12 @@ class __$$LoadedImplCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$LoadedImpl implements _Loaded { class _$LoadedImpl implements _Loaded {
const _$LoadedImpl(final List<ItemOrder> transactionReport) const _$LoadedImpl(final List<Order> transactionReport)
: _transactionReport = transactionReport; : _transactionReport = transactionReport;
final List<ItemOrder> _transactionReport; final List<Order> _transactionReport;
@override @override
List<ItemOrder> get transactionReport { List<Order> get transactionReport {
if (_transactionReport is EqualUnmodifiableListView) if (_transactionReport is EqualUnmodifiableListView)
return _transactionReport; return _transactionReport;
// ignore: implicit_dynamic_type // ignore: implicit_dynamic_type
@ -877,7 +877,7 @@ class _$LoadedImpl implements _Loaded {
required TResult Function() initial, required TResult Function() initial,
required TResult Function() loading, required TResult Function() loading,
required TResult Function(String message) error, required TResult Function(String message) error,
required TResult Function(List<ItemOrder> transactionReport) loaded, required TResult Function(List<Order> transactionReport) loaded,
}) { }) {
return loaded(transactionReport); return loaded(transactionReport);
} }
@ -888,7 +888,7 @@ class _$LoadedImpl implements _Loaded {
TResult? Function()? initial, TResult? Function()? initial,
TResult? Function()? loading, TResult? Function()? loading,
TResult? Function(String message)? error, TResult? Function(String message)? error,
TResult? Function(List<ItemOrder> transactionReport)? loaded, TResult? Function(List<Order> transactionReport)? loaded,
}) { }) {
return loaded?.call(transactionReport); return loaded?.call(transactionReport);
} }
@ -899,7 +899,7 @@ class _$LoadedImpl implements _Loaded {
TResult Function()? initial, TResult Function()? initial,
TResult Function()? loading, TResult Function()? loading,
TResult Function(String message)? error, TResult Function(String message)? error,
TResult Function(List<ItemOrder> transactionReport)? loaded, TResult Function(List<Order> transactionReport)? loaded,
required TResult orElse(), required TResult orElse(),
}) { }) {
if (loaded != null) { if (loaded != null) {
@ -947,9 +947,9 @@ class _$LoadedImpl implements _Loaded {
} }
abstract class _Loaded implements TransactionReportState { abstract class _Loaded implements TransactionReportState {
const factory _Loaded(final List<ItemOrder> transactionReport) = _$LoadedImpl; const factory _Loaded(final List<Order> transactionReport) = _$LoadedImpl;
List<ItemOrder> get transactionReport; List<Order> get transactionReport;
/// Create a copy of TransactionReportState /// Create a copy of TransactionReportState
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.

View File

@ -5,6 +5,6 @@ class TransactionReportState with _$TransactionReportState {
const factory TransactionReportState.initial() = _Initial; const factory TransactionReportState.initial() = _Initial;
const factory TransactionReportState.loading() = _Loading; const factory TransactionReportState.loading() = _Loading;
const factory TransactionReportState.error(String message) = _Error; const factory TransactionReportState.error(String message) = _Error;
const factory TransactionReportState.loaded( const factory TransactionReportState.loaded(List<Order> transactionReport) =
List<ItemOrder> transactionReport) = _Loaded; _Loaded;
} }

View File

@ -2,20 +2,19 @@ import 'dart:developer';
import 'package:enaklo_pos/core/components/spaces.dart'; import 'package:enaklo_pos/core/components/spaces.dart';
import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/date_time_ext.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart'; import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/core/utils/helper_pdf_service.dart'; import 'package:enaklo_pos/core/utils/helper_pdf_service.dart';
import 'package:enaklo_pos/presentation/report/widgets/report_page_title.dart'; import 'package:enaklo_pos/presentation/report/widgets/report_page_title.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:enaklo_pos/core/utils/permession_handler.dart'; import 'package:enaklo_pos/core/utils/permession_handler.dart';
import 'package:enaklo_pos/core/utils/transaction_sales_invoice.dart'; import 'package:enaklo_pos/core/utils/transaction_sales_invoice.dart';
import 'package:enaklo_pos/data/models/response/order_remote_datasource.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:horizontal_data_table/horizontal_data_table.dart'; import 'package:horizontal_data_table/horizontal_data_table.dart';
class TransactionReportWidget extends StatelessWidget { class TransactionReportWidget extends StatelessWidget {
final String title; final String title;
final String searchDateFormatted; final String searchDateFormatted;
final List<ItemOrder> transactionReport; final List<Order> transactionReport;
final List<Widget>? headerWidgets; final List<Widget>? headerWidgets;
const TransactionReportWidget({ const TransactionReportWidget({
super.key, super.key,
@ -91,86 +90,88 @@ class TransactionReportWidget extends StatelessWidget {
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Center( child: Center(
child: Text( child: Text(
transactionReport[index].total!.currencyFormatRp, transactionReport[index]
.totalAmount!
.currencyFormatRp,
)), )),
), ),
Container( // Container(
width: 120, // width: 120,
height: 52, // height: 52,
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0), // padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Center( // child: Center(
child: Text( // child: Text(
transactionReport[index].subTotal!.currencyFormatRp, // transactionReport[index].subTotal!.currencyFormatRp,
)), // )),
), // ),
Container( // Container(
width: 100, // width: 100,
height: 52, // height: 52,
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0), // padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Center( // child: Center(
child: Text( // child: Text(
transactionReport[index].tax!.currencyFormatRp, // transactionReport[index].tax!.currencyFormatRp,
)), // )),
), // ),
Container( // Container(
width: 100, // width: 100,
height: 52, // height: 52,
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0), // padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Center( // child: Center(
child: Text( // child: Text(
int.parse(transactionReport[index] // int.parse(transactionReport[index]
.discountAmount! // .discountAmount!
.replaceAll('.00', '')) // .replaceAll('.00', ''))
.currencyFormatRp, // .currencyFormatRp,
), // ),
), // ),
), // ),
Container( // Container(
width: 100, // width: 100,
height: 52, // height: 52,
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0), // padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Center( // child: Center(
child: Text( // child: Text(
transactionReport[index] // transactionReport[index]
.serviceCharge! // .serviceCharge!
.currencyFormatRp, // .currencyFormatRp,
), // ),
), // ),
), // ),
Container( // Container(
width: 100, // width: 100,
height: 52, // height: 52,
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0), // padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Center( // child: Center(
child: Text( // child: Text(
transactionReport[index].totalItem.toString()), // transactionReport[index].totalItem.toString()),
), // ),
), // ),
Container( // Container(
width: 150, // width: 150,
height: 52, // height: 52,
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0), // padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Center( // child: Center(
child: Text(transactionReport[index].namaKasir!), // child: Text(transactionReport[index].namaKasir!),
), // ),
), // ),
Container( // Container(
width: 230, // width: 230,
height: 52, // height: 52,
padding: const EdgeInsets.fromLTRB(5, 0, 0, 0), // padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
alignment: Alignment.centerLeft, // alignment: Alignment.centerLeft,
child: Center( // child: Center(
child: Text(transactionReport[index] // child: Text(transactionReport[index]
.transactionTime! // .transactionTime!
.toFormattedDate()), // .toFormattedDate()),
), // ),
), // ),
], ],
); );
}, },

View File

@ -0,0 +1,27 @@
import 'package:bloc/bloc.dart';
import 'package:enaklo_pos/data/datasources/order_remote_datasource.dart';
import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'order_loader_event.dart';
part 'order_loader_state.dart';
part 'order_loader_bloc.freezed.dart';
class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
final OrderRemoteDatasource _orderRemoteDatasource;
OrderLoaderBloc(this._orderRemoteDatasource)
: super(OrderLoaderState.initial()) {
on<_GetByStatus>((event, emit) async {
emit(const _Loading());
final result =
await _orderRemoteDatasource.getOrder(status: event.status);
result.fold(
(l) => emit(_Error(l)),
(r) => emit(_Loaded(
r.data?.orders ?? [],
r.data?.totalCount ?? 0,
)),
);
});
}
}

View File

@ -0,0 +1,863 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'order_loader_bloc.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
/// @nodoc
mixin _$OrderLoaderEvent {
String get status => throw _privateConstructorUsedError;
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String status) getByStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String status)? getByStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String status)? getByStatus,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_GetByStatus value) getByStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_GetByStatus value)? getByStatus,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_GetByStatus value)? getByStatus,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$OrderLoaderEventCopyWith<OrderLoaderEvent> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OrderLoaderEventCopyWith<$Res> {
factory $OrderLoaderEventCopyWith(
OrderLoaderEvent value, $Res Function(OrderLoaderEvent) then) =
_$OrderLoaderEventCopyWithImpl<$Res, OrderLoaderEvent>;
@useResult
$Res call({String status});
}
/// @nodoc
class _$OrderLoaderEventCopyWithImpl<$Res, $Val extends OrderLoaderEvent>
implements $OrderLoaderEventCopyWith<$Res> {
_$OrderLoaderEventCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? status = null,
}) {
return _then(_value.copyWith(
status: null == status
? _value.status
: status // ignore: cast_nullable_to_non_nullable
as String,
) as $Val);
}
}
/// @nodoc
abstract class _$$GetByStatusImplCopyWith<$Res>
implements $OrderLoaderEventCopyWith<$Res> {
factory _$$GetByStatusImplCopyWith(
_$GetByStatusImpl value, $Res Function(_$GetByStatusImpl) then) =
__$$GetByStatusImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({String status});
}
/// @nodoc
class __$$GetByStatusImplCopyWithImpl<$Res>
extends _$OrderLoaderEventCopyWithImpl<$Res, _$GetByStatusImpl>
implements _$$GetByStatusImplCopyWith<$Res> {
__$$GetByStatusImplCopyWithImpl(
_$GetByStatusImpl _value, $Res Function(_$GetByStatusImpl) _then)
: super(_value, _then);
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? status = null,
}) {
return _then(_$GetByStatusImpl(
null == status
? _value.status
: status // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$GetByStatusImpl implements _GetByStatus {
const _$GetByStatusImpl(this.status);
@override
final String status;
@override
String toString() {
return 'OrderLoaderEvent.getByStatus(status: $status)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$GetByStatusImpl &&
(identical(other.status, status) || other.status == status));
}
@override
int get hashCode => Object.hash(runtimeType, status);
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$GetByStatusImplCopyWith<_$GetByStatusImpl> get copyWith =>
__$$GetByStatusImplCopyWithImpl<_$GetByStatusImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function(String status) getByStatus,
}) {
return getByStatus(status);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function(String status)? getByStatus,
}) {
return getByStatus?.call(status);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function(String status)? getByStatus,
required TResult orElse(),
}) {
if (getByStatus != null) {
return getByStatus(status);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_GetByStatus value) getByStatus,
}) {
return getByStatus(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_GetByStatus value)? getByStatus,
}) {
return getByStatus?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_GetByStatus value)? getByStatus,
required TResult orElse(),
}) {
if (getByStatus != null) {
return getByStatus(this);
}
return orElse();
}
}
abstract class _GetByStatus implements OrderLoaderEvent {
const factory _GetByStatus(final String status) = _$GetByStatusImpl;
@override
String get status;
/// Create a copy of OrderLoaderEvent
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$GetByStatusImplCopyWith<_$GetByStatusImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$OrderLoaderState {
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Order> orders, int totalOrder) loaded,
required TResult Function(String message) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Order> orders, int totalOrder)? loaded,
TResult? Function(String message)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Order> orders, int totalOrder)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) =>
throw _privateConstructorUsedError;
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $OrderLoaderStateCopyWith<$Res> {
factory $OrderLoaderStateCopyWith(
OrderLoaderState value, $Res Function(OrderLoaderState) then) =
_$OrderLoaderStateCopyWithImpl<$Res, OrderLoaderState>;
}
/// @nodoc
class _$OrderLoaderStateCopyWithImpl<$Res, $Val extends OrderLoaderState>
implements $OrderLoaderStateCopyWith<$Res> {
_$OrderLoaderStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$InitialImplCopyWith<$Res> {
factory _$$InitialImplCopyWith(
_$InitialImpl value, $Res Function(_$InitialImpl) then) =
__$$InitialImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$InitialImplCopyWithImpl<$Res>
extends _$OrderLoaderStateCopyWithImpl<$Res, _$InitialImpl>
implements _$$InitialImplCopyWith<$Res> {
__$$InitialImplCopyWithImpl(
_$InitialImpl _value, $Res Function(_$InitialImpl) _then)
: super(_value, _then);
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$InitialImpl implements _Initial {
const _$InitialImpl();
@override
String toString() {
return 'OrderLoaderState.initial()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$InitialImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Order> orders, int totalOrder) loaded,
required TResult Function(String message) error,
}) {
return initial();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Order> orders, int totalOrder)? loaded,
TResult? Function(String message)? error,
}) {
return initial?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Order> orders, int totalOrder)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return initial(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return initial?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (initial != null) {
return initial(this);
}
return orElse();
}
}
abstract class _Initial implements OrderLoaderState {
const factory _Initial() = _$InitialImpl;
}
/// @nodoc
abstract class _$$LoadingImplCopyWith<$Res> {
factory _$$LoadingImplCopyWith(
_$LoadingImpl value, $Res Function(_$LoadingImpl) then) =
__$$LoadingImplCopyWithImpl<$Res>;
}
/// @nodoc
class __$$LoadingImplCopyWithImpl<$Res>
extends _$OrderLoaderStateCopyWithImpl<$Res, _$LoadingImpl>
implements _$$LoadingImplCopyWith<$Res> {
__$$LoadingImplCopyWithImpl(
_$LoadingImpl _value, $Res Function(_$LoadingImpl) _then)
: super(_value, _then);
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
class _$LoadingImpl implements _Loading {
const _$LoadingImpl();
@override
String toString() {
return 'OrderLoaderState.loading()';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType && other is _$LoadingImpl);
}
@override
int get hashCode => runtimeType.hashCode;
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Order> orders, int totalOrder) loaded,
required TResult Function(String message) error,
}) {
return loading();
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Order> orders, int totalOrder)? loaded,
TResult? Function(String message)? error,
}) {
return loading?.call();
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Order> orders, int totalOrder)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading();
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return loading(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return loading?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (loading != null) {
return loading(this);
}
return orElse();
}
}
abstract class _Loading implements OrderLoaderState {
const factory _Loading() = _$LoadingImpl;
}
/// @nodoc
abstract class _$$LoadedImplCopyWith<$Res> {
factory _$$LoadedImplCopyWith(
_$LoadedImpl value, $Res Function(_$LoadedImpl) then) =
__$$LoadedImplCopyWithImpl<$Res>;
@useResult
$Res call({List<Order> orders, int totalOrder});
}
/// @nodoc
class __$$LoadedImplCopyWithImpl<$Res>
extends _$OrderLoaderStateCopyWithImpl<$Res, _$LoadedImpl>
implements _$$LoadedImplCopyWith<$Res> {
__$$LoadedImplCopyWithImpl(
_$LoadedImpl _value, $Res Function(_$LoadedImpl) _then)
: super(_value, _then);
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? orders = null,
Object? totalOrder = null,
}) {
return _then(_$LoadedImpl(
null == orders
? _value._orders
: orders // ignore: cast_nullable_to_non_nullable
as List<Order>,
null == totalOrder
? _value.totalOrder
: totalOrder // ignore: cast_nullable_to_non_nullable
as int,
));
}
}
/// @nodoc
class _$LoadedImpl implements _Loaded {
const _$LoadedImpl(final List<Order> orders, this.totalOrder)
: _orders = orders;
final List<Order> _orders;
@override
List<Order> get orders {
if (_orders is EqualUnmodifiableListView) return _orders;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_orders);
}
@override
final int totalOrder;
@override
String toString() {
return 'OrderLoaderState.loaded(orders: $orders, totalOrder: $totalOrder)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$LoadedImpl &&
const DeepCollectionEquality().equals(other._orders, _orders) &&
(identical(other.totalOrder, totalOrder) ||
other.totalOrder == totalOrder));
}
@override
int get hashCode => Object.hash(
runtimeType, const DeepCollectionEquality().hash(_orders), totalOrder);
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$LoadedImplCopyWith<_$LoadedImpl> get copyWith =>
__$$LoadedImplCopyWithImpl<_$LoadedImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Order> orders, int totalOrder) loaded,
required TResult Function(String message) error,
}) {
return loaded(orders, totalOrder);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Order> orders, int totalOrder)? loaded,
TResult? Function(String message)? error,
}) {
return loaded?.call(orders, totalOrder);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Order> orders, int totalOrder)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(orders, totalOrder);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return loaded(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return loaded?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (loaded != null) {
return loaded(this);
}
return orElse();
}
}
abstract class _Loaded implements OrderLoaderState {
const factory _Loaded(final List<Order> orders, final int totalOrder) =
_$LoadedImpl;
List<Order> get orders;
int get totalOrder;
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$LoadedImplCopyWith<_$LoadedImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$ErrorImplCopyWith<$Res> {
factory _$$ErrorImplCopyWith(
_$ErrorImpl value, $Res Function(_$ErrorImpl) then) =
__$$ErrorImplCopyWithImpl<$Res>;
@useResult
$Res call({String message});
}
/// @nodoc
class __$$ErrorImplCopyWithImpl<$Res>
extends _$OrderLoaderStateCopyWithImpl<$Res, _$ErrorImpl>
implements _$$ErrorImplCopyWith<$Res> {
__$$ErrorImplCopyWithImpl(
_$ErrorImpl _value, $Res Function(_$ErrorImpl) _then)
: super(_value, _then);
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? message = null,
}) {
return _then(_$ErrorImpl(
null == message
? _value.message
: message // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$ErrorImpl implements _Error {
const _$ErrorImpl(this.message);
@override
final String message;
@override
String toString() {
return 'OrderLoaderState.error(message: $message)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ErrorImpl &&
(identical(other.message, message) || other.message == message));
}
@override
int get hashCode => Object.hash(runtimeType, message);
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
__$$ErrorImplCopyWithImpl<_$ErrorImpl>(this, _$identity);
@override
@optionalTypeArgs
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() loading,
required TResult Function(List<Order> orders, int totalOrder) loaded,
required TResult Function(String message) error,
}) {
return error(message);
}
@override
@optionalTypeArgs
TResult? whenOrNull<TResult extends Object?>({
TResult? Function()? initial,
TResult? Function()? loading,
TResult? Function(List<Order> orders, int totalOrder)? loaded,
TResult? Function(String message)? error,
}) {
return error?.call(message);
}
@override
@optionalTypeArgs
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? loading,
TResult Function(List<Order> orders, int totalOrder)? loaded,
TResult Function(String message)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(message);
}
return orElse();
}
@override
@optionalTypeArgs
TResult map<TResult extends Object?>({
required TResult Function(_Initial value) initial,
required TResult Function(_Loading value) loading,
required TResult Function(_Loaded value) loaded,
required TResult Function(_Error value) error,
}) {
return error(this);
}
@override
@optionalTypeArgs
TResult? mapOrNull<TResult extends Object?>({
TResult? Function(_Initial value)? initial,
TResult? Function(_Loading value)? loading,
TResult? Function(_Loaded value)? loaded,
TResult? Function(_Error value)? error,
}) {
return error?.call(this);
}
@override
@optionalTypeArgs
TResult maybeMap<TResult extends Object?>({
TResult Function(_Initial value)? initial,
TResult Function(_Loading value)? loading,
TResult Function(_Loaded value)? loaded,
TResult Function(_Error value)? error,
required TResult orElse(),
}) {
if (error != null) {
return error(this);
}
return orElse();
}
}
abstract class _Error implements OrderLoaderState {
const factory _Error(final String message) = _$ErrorImpl;
String get message;
/// Create a copy of OrderLoaderState
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ErrorImplCopyWith<_$ErrorImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,6 @@
part of 'order_loader_bloc.dart';
@freezed
class OrderLoaderEvent with _$OrderLoaderEvent {
const factory OrderLoaderEvent.getByStatus(String status) = _GetByStatus;
}

View File

@ -0,0 +1,10 @@
part of 'order_loader_bloc.dart';
@freezed
class OrderLoaderState with _$OrderLoaderState {
const factory OrderLoaderState.initial() = _Initial;
const factory OrderLoaderState.loading() = _Loading;
const factory OrderLoaderState.loaded(List<Order> orders, int totalOrder) =
_Loaded;
const factory OrderLoaderState.error(String message) = _Error;
}

View File

@ -1,7 +1,9 @@
import 'package:enaklo_pos/core/components/buttons.dart'; import 'package:enaklo_pos/core/components/buttons.dart';
import 'package:enaklo_pos/core/components/spaces.dart'; import 'package:enaklo_pos/core/components/spaces.dart';
import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/presentation/home/models/order_model.dart';
import 'package:enaklo_pos/presentation/sales/blocs/day_sales/day_sales_bloc.dart'; import 'package:enaklo_pos/presentation/sales/blocs/day_sales/day_sales_bloc.dart';
import 'package:enaklo_pos/presentation/sales/blocs/order_loader/order_loader_bloc.dart';
import 'package:enaklo_pos/presentation/sales/widgets/sales_detail.dart'; import 'package:enaklo_pos/presentation/sales/widgets/sales_detail.dart';
import 'package:enaklo_pos/presentation/sales/widgets/sales_list_order.dart'; import 'package:enaklo_pos/presentation/sales/widgets/sales_list_order.dart';
import 'package:enaklo_pos/presentation/sales/widgets/sales_order_information.dart'; import 'package:enaklo_pos/presentation/sales/widgets/sales_order_information.dart';
@ -15,7 +17,8 @@ import '../widgets/sales_card.dart';
import '../widgets/sales_title.dart'; import '../widgets/sales_title.dart';
class SalesPage extends StatefulWidget { class SalesPage extends StatefulWidget {
const SalesPage({super.key}); final String status;
const SalesPage({super.key, required this.status});
@override @override
State<SalesPage> createState() => _SalesPageState(); State<SalesPage> createState() => _SalesPageState();
@ -24,7 +27,7 @@ class SalesPage extends StatefulWidget {
class _SalesPageState extends State<SalesPage> { class _SalesPageState extends State<SalesPage> {
DateTime startDate = DateTime.now(); DateTime startDate = DateTime.now();
DateTime endDate = DateTime.now(); DateTime endDate = DateTime.now();
OrderModel? orderDetail; Order? orderDetail;
int _total = 0; int _total = 0;
String searchQuery = ''; String searchQuery = '';
@ -32,18 +35,18 @@ class _SalesPageState extends State<SalesPage> {
@override @override
void initState() { void initState() {
context context
.read<DaySalesBloc>() .read<OrderLoaderBloc>()
.add(DaySalesEvent.getRangeDateSales(startDate, endDate)); .add(OrderLoaderEvent.getByStatus(widget.status));
super.initState(); super.initState();
} }
List<OrderModel> _filterOrders(List<OrderModel> orders) { List<Order> _filterOrders(List<Order> orders) {
if (searchQuery.isEmpty) { if (searchQuery.isEmpty) {
return orders; return orders;
} }
return orders.where((order) { return orders.where((order) {
final customerName = order.customerName.toLowerCase(); final customerName = order.orderNumber?.toLowerCase() ?? "";
final queryLower = searchQuery.toLowerCase(); final queryLower = searchQuery.toLowerCase();
return customerName.contains(queryLower); return customerName.contains(queryLower);
}).toList(); }).toList();
@ -63,6 +66,9 @@ class _SalesPageState extends State<SalesPage> {
child: Column( child: Column(
children: [ children: [
SalesTitle( SalesTitle(
title: widget.status == 'pending'
? "Pending Pesanan"
: "Daftar Pesanan",
startDate: startDate, startDate: startDate,
endDate: endDate, endDate: endDate,
total: _total, total: _total,
@ -83,13 +89,26 @@ class _SalesPageState extends State<SalesPage> {
}, },
), ),
Expanded( Expanded(
child: BlocBuilder<DaySalesBloc, DaySalesState>( child: BlocBuilder<OrderLoaderBloc, OrderLoaderState>(
builder: (context, state) { builder: (context, state) {
return state.maybeWhen( return state.maybeWhen(
orElse: () => const Center( orElse: () => const Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
loaded: (orders) { loading: () => const Center(
child: CircularProgressIndicator(),
),
error: (message) => Center(
child: Text(
message,
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
),
loaded: (orders, totalOrder) {
_total = totalOrder;
final filtered = _filterOrders(orders); final filtered = _filterOrders(orders);
if (filtered.isEmpty) { if (filtered.isEmpty) {
return Center( return Center(
@ -102,13 +121,6 @@ class _SalesPageState extends State<SalesPage> {
), ),
); );
} else { } else {
WidgetsBinding.instance
.addPostFrameCallback((_) {
setState(() {
_total = filtered.length;
});
});
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
children: List.generate( children: List.generate(
@ -162,32 +174,35 @@ class _SalesPageState extends State<SalesPage> {
), ),
], ],
), ),
Padding( Expanded(
padding: const EdgeInsets.all(16.0), child: SingleChildScrollView(
child: Column( padding: const EdgeInsets.all(16.0),
children: [ child: Column(
Row( children: [
children: [ Row(
Expanded( crossAxisAlignment: CrossAxisAlignment.start,
child: SalesOrderInformation( children: [
order: orderDetail, Expanded(
child: SalesOrderInformation(
order: orderDetail,
),
), ),
), SpaceWidth(16),
SpaceWidth(16), Expanded(
Expanded( child: SalesDetail(
child: SalesDetail( order: orderDetail,
order: orderDetail, ),
), ),
), ],
], ),
), SalesListOrder(
SalesListOrder( order: orderDetail,
order: orderDetail, ),
), SalesPayment(
SalesPayment( order: orderDetail,
order: orderDetail, ),
), ],
], ),
), ),
) )
], ],

View File

@ -1,11 +1,11 @@
import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/date_time_ext.dart'; import 'package:enaklo_pos/core/extensions/date_time_ext.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart'; import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SalesCard extends StatelessWidget { class SalesCard extends StatelessWidget {
final OrderModel order; final Order order;
final bool isActive; final bool isActive;
const SalesCard({ const SalesCard({
@ -29,6 +29,17 @@ class SalesCard extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Align(
alignment: Alignment.centerRight,
child: Text(
'${order.orderNumber}',
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
),
const SizedBox(height: 12),
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -44,9 +55,9 @@ class SalesCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
order.customerName == "" order.metadata?['customer_name'] == ""
? "Anonim" ? "Anonim"
: order.customerName, : order.metadata?['customer_name'],
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -74,7 +85,7 @@ class SalesCard extends StatelessWidget {
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Text( child: Text(
order.status.toUpperCase(), (order.status ?? "").toUpperCase(),
style: TextStyle( style: TextStyle(
color: Colors.green, color: Colors.green,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -90,7 +101,7 @@ class SalesCard extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
order.total.currencyFormatRpV2, (order.totalAmount ?? 0).currencyFormatRpV2,
style: TextStyle( style: TextStyle(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -98,7 +109,7 @@ class SalesCard extends StatelessWidget {
), ),
), ),
Text( Text(
DateTime.parse(order.transactionTime).toFormattedDate2(), (order.createdAt ?? DateTime.now()).toFormattedDate3(),
style: TextStyle( style: TextStyle(
color: AppColors.black, color: AppColors.black,
), ),

View File

@ -1,10 +1,10 @@
import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/date_time_ext.dart'; import 'package:enaklo_pos/core/extensions/date_time_ext.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SalesDetail extends StatelessWidget { class SalesDetail extends StatelessWidget {
final OrderModel? order; final Order? order;
const SalesDetail({super.key, this.order}); const SalesDetail({super.key, this.order});
@override @override
@ -28,20 +28,15 @@ class SalesDetail extends StatelessWidget {
), ),
_item( _item(
title: 'Pelanggan', title: 'Pelanggan',
value: order?.customerName ?? "-", value: order?.metadata?['customer_name'] ?? "-",
), ),
_item( _item(
title: 'Waktu', title: 'Waktu',
value: value: (order?.createdAt ?? DateTime.now()).toFormattedDate3(),
DateTime.parse(order?.transactionTime ?? "").toFormattedDate3(),
), ),
_item( _item(
title: 'Status', title: 'Status',
value: order?.paymentStatus ?? "-", value: order?.status ?? "-",
),
_item(
title: 'Jenis Order',
value: order?.paymentMethod ?? "-",
), ),
], ],
), ),

View File

@ -1,10 +1,9 @@
import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:enaklo_pos/presentation/home/models/product_quantity.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SalesListOrder extends StatelessWidget { class SalesListOrder extends StatelessWidget {
final OrderModel? order; final Order? order;
const SalesListOrder({super.key, this.order}); const SalesListOrder({super.key, this.order});
@override @override
@ -37,8 +36,8 @@ class SalesListOrder extends StatelessWidget {
), ),
Column( Column(
children: List.generate( children: List.generate(
order?.orderItems.length ?? 0, order?.orderItems?.length ?? 0,
(index) => _item(order!.orderItems[index]), (index) => _item(order!.orderItems![index]),
).toList(), ).toList(),
), ),
], ],
@ -46,7 +45,7 @@ class SalesListOrder extends StatelessWidget {
); );
} }
Padding _item(ProductQuantity product) { Padding _item(OrderItem product) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16) padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16)
.copyWith(bottom: 0), .copyWith(bottom: 0),
@ -56,13 +55,13 @@ class SalesListOrder extends StatelessWidget {
Column( Column(
children: [ children: [
Text( Text(
product.product.name ?? '', product.productName ?? '',
style: const TextStyle( style: const TextStyle(
fontSize: 14, fontSize: 14,
), ),
), ),
Text( Text(
(product.product.price ?? 0) as String, (product.unitPrice ?? 0).toString(),
style: const TextStyle( style: const TextStyle(
fontSize: 14, fontSize: 14,
), ),
@ -76,7 +75,7 @@ class SalesListOrder extends StatelessWidget {
), ),
), ),
Text( Text(
(product.product.price ?? 0) as String, (product.totalPrice ?? 0).toString(),
style: const TextStyle( style: const TextStyle(
fontSize: 14, fontSize: 14,
), ),

View File

@ -1,10 +1,10 @@
import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/date_time_ext.dart'; import 'package:enaklo_pos/core/extensions/date_time_ext.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SalesOrderInformation extends StatelessWidget { class SalesOrderInformation extends StatelessWidget {
final OrderModel? order; final Order? order;
const SalesOrderInformation({super.key, this.order}); const SalesOrderInformation({super.key, this.order});
@override @override
@ -28,20 +28,19 @@ class SalesOrderInformation extends StatelessWidget {
), ),
_item( _item(
title: 'No. Order', title: 'No. Order',
value: "${order?.id}", value: "${order?.orderNumber}",
), ),
_item( _item(
title: 'Tanggal', title: 'Tanggal',
value: value: (order?.createdAt ?? DateTime.now()).toFormattedDate2(),
DateTime.parse(order?.transactionTime ?? "").toFormattedDate3(),
), ),
_item( _item(
title: 'Kasir', title: 'No. Meja',
value: order?.namaKasir ?? "-", value: order?.tableNumber ?? "-",
), ),
_item( _item(
title: 'Jenis Order', title: 'Jenis Order',
value: order?.orderType.value ?? "-", value: order?.orderType ?? "-",
), ),
], ],
), ),

View File

@ -2,11 +2,11 @@ import 'package:enaklo_pos/core/components/dashed_divider.dart';
import 'package:enaklo_pos/core/components/spaces.dart'; import 'package:enaklo_pos/core/components/spaces.dart';
import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/int_ext.dart'; import 'package:enaklo_pos/core/extensions/int_ext.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SalesPayment extends StatelessWidget { class SalesPayment extends StatelessWidget {
final OrderModel? order; final Order? order;
const SalesPayment({super.key, this.order}); const SalesPayment({super.key, this.order});
@override @override
@ -34,14 +34,14 @@ class SalesPayment extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'Subtotal ${order?.totalItem} Produk', 'Subtotal ${order?.orderItems?.length} Produk',
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
), ),
), ),
Text( Text(
(order?.subTotal)?.currencyFormatRp ?? "0", (order?.subtotal)?.currencyFormatRp ?? "0",
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -54,13 +54,13 @@ class SalesPayment extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
'Pajak (11%)', 'Pajak',
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
), ),
), ),
Text( Text(
(order?.tax)?.currencyFormatRp ?? "0", (order?.taxAmount)?.currencyFormatRp ?? "0",
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
), ),
@ -83,7 +83,7 @@ class SalesPayment extends StatelessWidget {
), ),
), ),
Text( Text(
(order?.total)?.currencyFormatRp ?? "0", (order?.totalAmount)?.currencyFormatRp ?? "0",
style: const TextStyle( style: const TextStyle(
color: AppColors.primary, color: AppColors.primary,
fontSize: 18, fontSize: 18,

View File

@ -1,10 +1,10 @@
import 'package:enaklo_pos/core/constants/colors.dart'; import 'package:enaklo_pos/core/constants/colors.dart';
import 'package:enaklo_pos/core/extensions/build_context_ext.dart'; import 'package:enaklo_pos/core/extensions/build_context_ext.dart';
import 'package:enaklo_pos/presentation/home/models/order_model.dart'; import 'package:enaklo_pos/data/models/response/order_response_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SalesRightTitle extends StatelessWidget { class SalesRightTitle extends StatelessWidget {
final OrderModel? order; final Order? order;
final List<Widget>? actionWidget; final List<Widget>? actionWidget;
const SalesRightTitle({super.key, this.order, this.actionWidget}); const SalesRightTitle({super.key, this.order, this.actionWidget});
@ -27,7 +27,7 @@ class SalesRightTitle extends StatelessWidget {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
"Detail Pesanan #${order?.id}", "Detail Pesanan #${order?.orderNumber}",
style: TextStyle( style: TextStyle(
color: AppColors.black, color: AppColors.black,
fontSize: 20, fontSize: 20,

View File

@ -6,6 +6,7 @@ import 'package:enaklo_pos/presentation/sales/dialog/filter_dialog.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SalesTitle extends StatelessWidget { class SalesTitle extends StatelessWidget {
final String title;
final DateTime startDate; final DateTime startDate;
final DateTime endDate; final DateTime endDate;
final int total; final int total;
@ -18,7 +19,8 @@ class SalesTitle extends StatelessWidget {
required this.endDate, required this.endDate,
required this.onChanged, required this.onChanged,
required this.total, required this.total,
required this.onDateRangeChanged}); required this.onDateRangeChanged,
required this.title});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -39,18 +41,14 @@ class SalesTitle extends StatelessWidget {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
GestureDetector( IconButton(
onTap: () => context.pop(), onPressed: () => context.pop(),
child: Icon( icon: Icon(Icons.arrow_back, color: AppColors.black),
Icons.arrow_back,
color: AppColors.primary,
size: 24,
),
), ),
SpaceWidth(16), SpaceWidth(16),
Expanded( Expanded(
child: Text( child: Text(
"Daftar Pesanan", title,
style: TextStyle( style: TextStyle(
color: AppColors.black, color: AppColors.black,
fontSize: 20, fontSize: 20,

View File

@ -122,7 +122,8 @@ class _SettingsPageState extends State<SettingsPage> {
title: 'Riwayat Transaksi', title: 'Riwayat Transaksi',
subtitle: 'Lihat riwayat transaksi', subtitle: 'Lihat riwayat transaksi',
icon: Icons.receipt_long_outlined, icon: Icons.receipt_long_outlined,
onTap: () => indexValue(2), onTap: () =>
context.push(SalesPage(status: 'completed')),
), ),
SettingTile( SettingTile(
index: 3, index: 3,
@ -168,7 +169,9 @@ class _SettingsPageState extends State<SettingsPage> {
children: [ children: [
role != null && role! != 'admin' ? SizedBox() : ProductPage(), role != null && role! != 'admin' ? SizedBox() : ProductPage(),
DiscountPage(), DiscountPage(),
SalesPage(), SalesPage(
status: 'completed',
),
TaxPage(), TaxPage(),
SyncDataPage(), SyncDataPage(),
ProductPage(), ProductPage(),