This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
part of '../analytic.dart';
|
||||
|
||||
/// Bagi hasil (profit sharing) berdasarkan omzet per parent category.
|
||||
@freezed
|
||||
class ProfitSharing with _$ProfitSharing {
|
||||
const factory ProfitSharing({
|
||||
required String organizationId,
|
||||
required String outletId,
|
||||
required String outletName,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
required List<ProfitSharingCategory> categories,
|
||||
required ProfitSharingBudget budget,
|
||||
}) = _ProfitSharing;
|
||||
|
||||
factory ProfitSharing.empty() => ProfitSharing(
|
||||
organizationId: '',
|
||||
outletId: '',
|
||||
outletName: '',
|
||||
dateFrom: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
dateTo: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
categories: [],
|
||||
budget: ProfitSharingBudget.empty(),
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingCategory with _$ProfitSharingCategory {
|
||||
const ProfitSharingCategory._();
|
||||
|
||||
const factory ProfitSharingCategory({
|
||||
required String parentCategoryId,
|
||||
required String parentCategoryName,
|
||||
required int totalRevenue,
|
||||
required int totalQuantity,
|
||||
required int categoryCount,
|
||||
required int productCount,
|
||||
required int orderCount,
|
||||
required int totalStandardHpp,
|
||||
required int totalFifoHpp,
|
||||
required int totalMovingAverageHpp,
|
||||
}) = _ProfitSharingCategory;
|
||||
|
||||
factory ProfitSharingCategory.empty() => const ProfitSharingCategory(
|
||||
parentCategoryId: '',
|
||||
parentCategoryName: '',
|
||||
totalRevenue: 0,
|
||||
totalQuantity: 0,
|
||||
categoryCount: 0,
|
||||
productCount: 0,
|
||||
orderCount: 0,
|
||||
totalStandardHpp: 0,
|
||||
totalFifoHpp: 0,
|
||||
totalMovingAverageHpp: 0,
|
||||
);
|
||||
|
||||
/// Laba kotor memakai HPP standar (acuan yang dipakai di laporan laba rugi).
|
||||
int get grossProfit => totalRevenue - totalStandardHpp;
|
||||
|
||||
double get grossMargin =>
|
||||
totalRevenue == 0 ? 0 : (grossProfit / totalRevenue) * 100;
|
||||
|
||||
/// % HPP standar terhadap omzet.
|
||||
double get standardHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalStandardHpp / totalRevenue) * 100;
|
||||
|
||||
/// % HPP riil (FIFO) terhadap omzet — dipakai untuk status kesehatan margin.
|
||||
double get realHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalFifoHpp / totalRevenue) * 100;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingBudget with _$ProfitSharingBudget {
|
||||
const factory ProfitSharingBudget({
|
||||
required ProfitSharingPercentage percentages,
|
||||
required DateTime cutOffFrom,
|
||||
required DateTime cutOffTo,
|
||||
required ProfitSharingPeriod total,
|
||||
required List<ProfitSharingPeriod> weekly,
|
||||
required List<ProfitSharingPeriod> monthly,
|
||||
}) = _ProfitSharingBudget;
|
||||
|
||||
factory ProfitSharingBudget.empty() => ProfitSharingBudget(
|
||||
percentages: ProfitSharingPercentage.empty(),
|
||||
cutOffFrom: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
cutOffTo: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
total: ProfitSharingPeriod.empty(),
|
||||
weekly: [],
|
||||
monthly: [],
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingPercentage with _$ProfitSharingPercentage {
|
||||
const factory ProfitSharingPercentage({
|
||||
required double purchase,
|
||||
required double owner,
|
||||
required double team,
|
||||
}) = _ProfitSharingPercentage;
|
||||
|
||||
factory ProfitSharingPercentage.empty() =>
|
||||
const ProfitSharingPercentage(purchase: 0, owner: 0, team: 0);
|
||||
}
|
||||
|
||||
/// Satu baris periode bagi hasil. Dipakai untuk total, mingguan, dan bulanan.
|
||||
/// [month] dan [weekCount] hanya terisi untuk data bulanan.
|
||||
@freezed
|
||||
class ProfitSharingPeriod with _$ProfitSharingPeriod {
|
||||
const ProfitSharingPeriod._();
|
||||
|
||||
const factory ProfitSharingPeriod({
|
||||
required DateTime periodStart,
|
||||
required DateTime periodEnd,
|
||||
required int revenue,
|
||||
required int orderCount,
|
||||
required int limitPurchase,
|
||||
required int limitOwner,
|
||||
required int limitTeam,
|
||||
@Default('') String month,
|
||||
@Default(0) int weekCount,
|
||||
}) = _ProfitSharingPeriod;
|
||||
|
||||
factory ProfitSharingPeriod.empty() => ProfitSharingPeriod(
|
||||
periodStart: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
periodEnd: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
revenue: 0,
|
||||
orderCount: 0,
|
||||
limitPurchase: 0,
|
||||
limitOwner: 0,
|
||||
limitTeam: 0,
|
||||
);
|
||||
|
||||
bool get hasRevenue => revenue > 0;
|
||||
|
||||
int get averageOrderValue => orderCount == 0 ? 0 : revenue ~/ orderCount;
|
||||
}
|
||||
|
||||
/// Rincian satu kategori induk: ringkasan, sub kategori beserta produknya,
|
||||
/// dan bagi hasil khusus kategori tersebut.
|
||||
@freezed
|
||||
class ProfitSharingDetail with _$ProfitSharingDetail {
|
||||
const factory ProfitSharingDetail({
|
||||
required String organizationId,
|
||||
required String outletId,
|
||||
required String outletName,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
required String parentCategoryId,
|
||||
required String parentCategoryName,
|
||||
required ProfitSharingCategory summary,
|
||||
required List<ProfitSharingSubCategory> categories,
|
||||
required ProfitSharingBudget budget,
|
||||
}) = _ProfitSharingDetail;
|
||||
|
||||
factory ProfitSharingDetail.empty() => ProfitSharingDetail(
|
||||
organizationId: '',
|
||||
outletId: '',
|
||||
outletName: '',
|
||||
dateFrom: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
dateTo: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
parentCategoryId: '',
|
||||
parentCategoryName: '',
|
||||
summary: ProfitSharingCategory.empty(),
|
||||
categories: [],
|
||||
budget: ProfitSharingBudget.empty(),
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingSubCategory with _$ProfitSharingSubCategory {
|
||||
const ProfitSharingSubCategory._();
|
||||
|
||||
const factory ProfitSharingSubCategory({
|
||||
required String categoryId,
|
||||
required String categoryName,
|
||||
required int totalRevenue,
|
||||
required int totalQuantity,
|
||||
required int productCount,
|
||||
required int orderCount,
|
||||
required int totalStandardHpp,
|
||||
required int totalFifoHpp,
|
||||
required int totalMovingAverageHpp,
|
||||
required List<ProfitSharingProduct> products,
|
||||
}) = _ProfitSharingSubCategory;
|
||||
|
||||
double get standardHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalStandardHpp / totalRevenue) * 100;
|
||||
|
||||
double get realHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalFifoHpp / totalRevenue) * 100;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingProduct with _$ProfitSharingProduct {
|
||||
const ProfitSharingProduct._();
|
||||
|
||||
const factory ProfitSharingProduct({
|
||||
required String productId,
|
||||
required String productName,
|
||||
required String productSku,
|
||||
required int productPrice,
|
||||
required int quantitySold,
|
||||
required int revenue,
|
||||
required double averagePrice,
|
||||
required int orderCount,
|
||||
required double standardHppPerUnit,
|
||||
required int standardHppTotal,
|
||||
required double fifoHppPerUnit,
|
||||
required int fifoHppTotal,
|
||||
required double movingAverageHppPerUnit,
|
||||
required int movingAverageHppTotal,
|
||||
}) = _ProfitSharingProduct;
|
||||
|
||||
double get standardHppPercentage =>
|
||||
revenue == 0 ? 0 : (standardHppTotal / revenue) * 100;
|
||||
|
||||
double get realHppPercentage =>
|
||||
revenue == 0 ? 0 : (fifoHppTotal / revenue) * 100;
|
||||
}
|
||||
Reference in New Issue
Block a user