feat: update parent category analytic
Build & Deploy iOS to TestFlight / build-and-deploy (push) Canceled after 0s

This commit is contained in:
efrilm
2026-10-03 00:38:32 +07:00
parent 36bc9e0f9e
commit 288d0d75a0
21 changed files with 1366 additions and 344 deletions
+325 -21
View File
@@ -12394,6 +12394,9 @@ mixin _$ProfitSharingCategory {
int get totalStandardHpp => throw _privateConstructorUsedError;
int get totalFifoHpp => throw _privateConstructorUsedError;
int get totalMovingAverageHpp => throw _privateConstructorUsedError;
double get ownerFeePercent => throw _privateConstructorUsedError;
int get sdl => throw _privateConstructorUsedError;
ProfitSharingTopProduct get topProduct => throw _privateConstructorUsedError;
/// Create a copy of ProfitSharingCategory
/// with the given fields replaced by the non-null parameter values.
@@ -12420,7 +12423,12 @@ abstract class $ProfitSharingCategoryCopyWith<$Res> {
int totalStandardHpp,
int totalFifoHpp,
int totalMovingAverageHpp,
double ownerFeePercent,
int sdl,
ProfitSharingTopProduct topProduct,
});
$ProfitSharingTopProductCopyWith<$Res> get topProduct;
}
/// @nodoc
@@ -12451,6 +12459,9 @@ class _$ProfitSharingCategoryCopyWithImpl<
Object? totalStandardHpp = null,
Object? totalFifoHpp = null,
Object? totalMovingAverageHpp = null,
Object? ownerFeePercent = null,
Object? sdl = null,
Object? topProduct = null,
}) {
return _then(
_value.copyWith(
@@ -12494,10 +12505,32 @@ class _$ProfitSharingCategoryCopyWithImpl<
? _value.totalMovingAverageHpp
: totalMovingAverageHpp // ignore: cast_nullable_to_non_nullable
as int,
ownerFeePercent: null == ownerFeePercent
? _value.ownerFeePercent
: ownerFeePercent // ignore: cast_nullable_to_non_nullable
as double,
sdl: null == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as int,
topProduct: null == topProduct
? _value.topProduct
: topProduct // ignore: cast_nullable_to_non_nullable
as ProfitSharingTopProduct,
)
as $Val,
);
}
/// Create a copy of ProfitSharingCategory
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ProfitSharingTopProductCopyWith<$Res> get topProduct {
return $ProfitSharingTopProductCopyWith<$Res>(_value.topProduct, (value) {
return _then(_value.copyWith(topProduct: value) as $Val);
});
}
}
/// @nodoc
@@ -12520,7 +12553,13 @@ abstract class _$$ProfitSharingCategoryImplCopyWith<$Res>
int totalStandardHpp,
int totalFifoHpp,
int totalMovingAverageHpp,
double ownerFeePercent,
int sdl,
ProfitSharingTopProduct topProduct,
});
@override
$ProfitSharingTopProductCopyWith<$Res> get topProduct;
}
/// @nodoc
@@ -12548,6 +12587,9 @@ class __$$ProfitSharingCategoryImplCopyWithImpl<$Res>
Object? totalStandardHpp = null,
Object? totalFifoHpp = null,
Object? totalMovingAverageHpp = null,
Object? ownerFeePercent = null,
Object? sdl = null,
Object? topProduct = null,
}) {
return _then(
_$ProfitSharingCategoryImpl(
@@ -12591,6 +12633,18 @@ class __$$ProfitSharingCategoryImplCopyWithImpl<$Res>
? _value.totalMovingAverageHpp
: totalMovingAverageHpp // ignore: cast_nullable_to_non_nullable
as int,
ownerFeePercent: null == ownerFeePercent
? _value.ownerFeePercent
: ownerFeePercent // ignore: cast_nullable_to_non_nullable
as double,
sdl: null == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as int,
topProduct: null == topProduct
? _value.topProduct
: topProduct // ignore: cast_nullable_to_non_nullable
as ProfitSharingTopProduct,
),
);
}
@@ -12610,6 +12664,9 @@ class _$ProfitSharingCategoryImpl extends _ProfitSharingCategory {
required this.totalStandardHpp,
required this.totalFifoHpp,
required this.totalMovingAverageHpp,
this.ownerFeePercent = 0,
this.sdl = 0,
this.topProduct = const ProfitSharingTopProduct(),
}) : super._();
@override
@@ -12632,10 +12689,19 @@ class _$ProfitSharingCategoryImpl extends _ProfitSharingCategory {
final int totalFifoHpp;
@override
final int totalMovingAverageHpp;
@override
@JsonKey()
final double ownerFeePercent;
@override
@JsonKey()
final int sdl;
@override
@JsonKey()
final ProfitSharingTopProduct topProduct;
@override
String toString() {
return 'ProfitSharingCategory(parentCategoryId: $parentCategoryId, parentCategoryName: $parentCategoryName, totalRevenue: $totalRevenue, totalQuantity: $totalQuantity, categoryCount: $categoryCount, productCount: $productCount, orderCount: $orderCount, totalStandardHpp: $totalStandardHpp, totalFifoHpp: $totalFifoHpp, totalMovingAverageHpp: $totalMovingAverageHpp)';
return 'ProfitSharingCategory(parentCategoryId: $parentCategoryId, parentCategoryName: $parentCategoryName, totalRevenue: $totalRevenue, totalQuantity: $totalQuantity, categoryCount: $categoryCount, productCount: $productCount, orderCount: $orderCount, totalStandardHpp: $totalStandardHpp, totalFifoHpp: $totalFifoHpp, totalMovingAverageHpp: $totalMovingAverageHpp, ownerFeePercent: $ownerFeePercent, sdl: $sdl, topProduct: $topProduct)';
}
@override
@@ -12662,7 +12728,12 @@ class _$ProfitSharingCategoryImpl extends _ProfitSharingCategory {
(identical(other.totalFifoHpp, totalFifoHpp) ||
other.totalFifoHpp == totalFifoHpp) &&
(identical(other.totalMovingAverageHpp, totalMovingAverageHpp) ||
other.totalMovingAverageHpp == totalMovingAverageHpp));
other.totalMovingAverageHpp == totalMovingAverageHpp) &&
(identical(other.ownerFeePercent, ownerFeePercent) ||
other.ownerFeePercent == ownerFeePercent) &&
(identical(other.sdl, sdl) || other.sdl == sdl) &&
(identical(other.topProduct, topProduct) ||
other.topProduct == topProduct));
}
@override
@@ -12678,6 +12749,9 @@ class _$ProfitSharingCategoryImpl extends _ProfitSharingCategory {
totalStandardHpp,
totalFifoHpp,
totalMovingAverageHpp,
ownerFeePercent,
sdl,
topProduct,
);
/// Create a copy of ProfitSharingCategory
@@ -12705,6 +12779,9 @@ abstract class _ProfitSharingCategory extends ProfitSharingCategory {
required final int totalStandardHpp,
required final int totalFifoHpp,
required final int totalMovingAverageHpp,
final double ownerFeePercent,
final int sdl,
final ProfitSharingTopProduct topProduct,
}) = _$ProfitSharingCategoryImpl;
const _ProfitSharingCategory._() : super._();
@@ -12728,6 +12805,12 @@ abstract class _ProfitSharingCategory extends ProfitSharingCategory {
int get totalFifoHpp;
@override
int get totalMovingAverageHpp;
@override
double get ownerFeePercent;
@override
int get sdl;
@override
ProfitSharingTopProduct get topProduct;
/// Create a copy of ProfitSharingCategory
/// with the given fields replaced by the non-null parameter values.
@@ -12737,6 +12820,228 @@ abstract class _ProfitSharingCategory extends ProfitSharingCategory {
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$ProfitSharingTopProduct {
String get productId => throw _privateConstructorUsedError;
String get productName => throw _privateConstructorUsedError;
int get quantitySold => throw _privateConstructorUsedError;
int get revenue => throw _privateConstructorUsedError;
/// Create a copy of ProfitSharingTopProduct
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProfitSharingTopProductCopyWith<ProfitSharingTopProduct> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProfitSharingTopProductCopyWith<$Res> {
factory $ProfitSharingTopProductCopyWith(
ProfitSharingTopProduct value,
$Res Function(ProfitSharingTopProduct) then,
) = _$ProfitSharingTopProductCopyWithImpl<$Res, ProfitSharingTopProduct>;
@useResult
$Res call({
String productId,
String productName,
int quantitySold,
int revenue,
});
}
/// @nodoc
class _$ProfitSharingTopProductCopyWithImpl<
$Res,
$Val extends ProfitSharingTopProduct
>
implements $ProfitSharingTopProductCopyWith<$Res> {
_$ProfitSharingTopProductCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProfitSharingTopProduct
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = null,
Object? productName = null,
Object? quantitySold = null,
Object? revenue = null,
}) {
return _then(
_value.copyWith(
productId: null == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String,
productName: null == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String,
quantitySold: null == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as int,
revenue: null == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as int,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProfitSharingTopProductImplCopyWith<$Res>
implements $ProfitSharingTopProductCopyWith<$Res> {
factory _$$ProfitSharingTopProductImplCopyWith(
_$ProfitSharingTopProductImpl value,
$Res Function(_$ProfitSharingTopProductImpl) then,
) = __$$ProfitSharingTopProductImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
String productId,
String productName,
int quantitySold,
int revenue,
});
}
/// @nodoc
class __$$ProfitSharingTopProductImplCopyWithImpl<$Res>
extends
_$ProfitSharingTopProductCopyWithImpl<
$Res,
_$ProfitSharingTopProductImpl
>
implements _$$ProfitSharingTopProductImplCopyWith<$Res> {
__$$ProfitSharingTopProductImplCopyWithImpl(
_$ProfitSharingTopProductImpl _value,
$Res Function(_$ProfitSharingTopProductImpl) _then,
) : super(_value, _then);
/// Create a copy of ProfitSharingTopProduct
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = null,
Object? productName = null,
Object? quantitySold = null,
Object? revenue = null,
}) {
return _then(
_$ProfitSharingTopProductImpl(
productId: null == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String,
productName: null == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String,
quantitySold: null == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as int,
revenue: null == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as int,
),
);
}
}
/// @nodoc
class _$ProfitSharingTopProductImpl implements _ProfitSharingTopProduct {
const _$ProfitSharingTopProductImpl({
this.productId = '',
this.productName = '',
this.quantitySold = 0,
this.revenue = 0,
});
@override
@JsonKey()
final String productId;
@override
@JsonKey()
final String productName;
@override
@JsonKey()
final int quantitySold;
@override
@JsonKey()
final int revenue;
@override
String toString() {
return 'ProfitSharingTopProduct(productId: $productId, productName: $productName, quantitySold: $quantitySold, revenue: $revenue)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProfitSharingTopProductImpl &&
(identical(other.productId, productId) ||
other.productId == productId) &&
(identical(other.productName, productName) ||
other.productName == productName) &&
(identical(other.quantitySold, quantitySold) ||
other.quantitySold == quantitySold) &&
(identical(other.revenue, revenue) || other.revenue == revenue));
}
@override
int get hashCode =>
Object.hash(runtimeType, productId, productName, quantitySold, revenue);
/// Create a copy of ProfitSharingTopProduct
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProfitSharingTopProductImplCopyWith<_$ProfitSharingTopProductImpl>
get copyWith =>
__$$ProfitSharingTopProductImplCopyWithImpl<
_$ProfitSharingTopProductImpl
>(this, _$identity);
}
abstract class _ProfitSharingTopProduct implements ProfitSharingTopProduct {
const factory _ProfitSharingTopProduct({
final String productId,
final String productName,
final int quantitySold,
final int revenue,
}) = _$ProfitSharingTopProductImpl;
@override
String get productId;
@override
String get productName;
@override
int get quantitySold;
@override
int get revenue;
/// Create a copy of ProfitSharingTopProduct
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProfitSharingTopProductImplCopyWith<_$ProfitSharingTopProductImpl>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$ProfitSharingBudget {
ProfitSharingPercentage get percentages => throw _privateConstructorUsedError;
@@ -13229,7 +13534,7 @@ mixin _$ProfitSharingPeriod {
int get revenue => throw _privateConstructorUsedError;
int get orderCount => throw _privateConstructorUsedError;
int get limitPurchase => throw _privateConstructorUsedError;
int get limitOwner => throw _privateConstructorUsedError;
int get sdl => throw _privateConstructorUsedError;
int get limitTeam => throw _privateConstructorUsedError;
String get month => throw _privateConstructorUsedError;
int get weekCount => throw _privateConstructorUsedError;
@@ -13254,7 +13559,7 @@ abstract class $ProfitSharingPeriodCopyWith<$Res> {
int revenue,
int orderCount,
int limitPurchase,
int limitOwner,
int sdl,
int limitTeam,
String month,
int weekCount,
@@ -13281,7 +13586,7 @@ class _$ProfitSharingPeriodCopyWithImpl<$Res, $Val extends ProfitSharingPeriod>
Object? revenue = null,
Object? orderCount = null,
Object? limitPurchase = null,
Object? limitOwner = null,
Object? sdl = null,
Object? limitTeam = null,
Object? month = null,
Object? weekCount = null,
@@ -13308,9 +13613,9 @@ class _$ProfitSharingPeriodCopyWithImpl<$Res, $Val extends ProfitSharingPeriod>
? _value.limitPurchase
: limitPurchase // ignore: cast_nullable_to_non_nullable
as int,
limitOwner: null == limitOwner
? _value.limitOwner
: limitOwner // ignore: cast_nullable_to_non_nullable
sdl: null == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as int,
limitTeam: null == limitTeam
? _value.limitTeam
@@ -13345,7 +13650,7 @@ abstract class _$$ProfitSharingPeriodImplCopyWith<$Res>
int revenue,
int orderCount,
int limitPurchase,
int limitOwner,
int sdl,
int limitTeam,
String month,
int weekCount,
@@ -13371,7 +13676,7 @@ class __$$ProfitSharingPeriodImplCopyWithImpl<$Res>
Object? revenue = null,
Object? orderCount = null,
Object? limitPurchase = null,
Object? limitOwner = null,
Object? sdl = null,
Object? limitTeam = null,
Object? month = null,
Object? weekCount = null,
@@ -13398,9 +13703,9 @@ class __$$ProfitSharingPeriodImplCopyWithImpl<$Res>
? _value.limitPurchase
: limitPurchase // ignore: cast_nullable_to_non_nullable
as int,
limitOwner: null == limitOwner
? _value.limitOwner
: limitOwner // ignore: cast_nullable_to_non_nullable
sdl: null == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as int,
limitTeam: null == limitTeam
? _value.limitTeam
@@ -13428,7 +13733,7 @@ class _$ProfitSharingPeriodImpl extends _ProfitSharingPeriod {
required this.revenue,
required this.orderCount,
required this.limitPurchase,
required this.limitOwner,
required this.sdl,
required this.limitTeam,
this.month = '',
this.weekCount = 0,
@@ -13445,7 +13750,7 @@ class _$ProfitSharingPeriodImpl extends _ProfitSharingPeriod {
@override
final int limitPurchase;
@override
final int limitOwner;
final int sdl;
@override
final int limitTeam;
@override
@@ -13457,7 +13762,7 @@ class _$ProfitSharingPeriodImpl extends _ProfitSharingPeriod {
@override
String toString() {
return 'ProfitSharingPeriod(periodStart: $periodStart, periodEnd: $periodEnd, revenue: $revenue, orderCount: $orderCount, limitPurchase: $limitPurchase, limitOwner: $limitOwner, limitTeam: $limitTeam, month: $month, weekCount: $weekCount)';
return 'ProfitSharingPeriod(periodStart: $periodStart, periodEnd: $periodEnd, revenue: $revenue, orderCount: $orderCount, limitPurchase: $limitPurchase, sdl: $sdl, limitTeam: $limitTeam, month: $month, weekCount: $weekCount)';
}
@override
@@ -13474,8 +13779,7 @@ class _$ProfitSharingPeriodImpl extends _ProfitSharingPeriod {
other.orderCount == orderCount) &&
(identical(other.limitPurchase, limitPurchase) ||
other.limitPurchase == limitPurchase) &&
(identical(other.limitOwner, limitOwner) ||
other.limitOwner == limitOwner) &&
(identical(other.sdl, sdl) || other.sdl == sdl) &&
(identical(other.limitTeam, limitTeam) ||
other.limitTeam == limitTeam) &&
(identical(other.month, month) || other.month == month) &&
@@ -13491,7 +13795,7 @@ class _$ProfitSharingPeriodImpl extends _ProfitSharingPeriod {
revenue,
orderCount,
limitPurchase,
limitOwner,
sdl,
limitTeam,
month,
weekCount,
@@ -13516,7 +13820,7 @@ abstract class _ProfitSharingPeriod extends ProfitSharingPeriod {
required final int revenue,
required final int orderCount,
required final int limitPurchase,
required final int limitOwner,
required final int sdl,
required final int limitTeam,
final String month,
final int weekCount,
@@ -13534,7 +13838,7 @@ abstract class _ProfitSharingPeriod extends ProfitSharingPeriod {
@override
int get limitPurchase;
@override
int get limitOwner;
int get sdl;
@override
int get limitTeam;
@override
@@ -39,6 +39,9 @@ class ProfitSharingCategory with _$ProfitSharingCategory {
required int totalStandardHpp,
required int totalFifoHpp,
required int totalMovingAverageHpp,
@Default(0) double ownerFeePercent,
@Default(0) int sdl,
@Default(ProfitSharingTopProduct()) ProfitSharingTopProduct topProduct,
}) = _ProfitSharingCategory;
factory ProfitSharingCategory.empty() => const ProfitSharingCategory(
@@ -54,6 +57,8 @@ class ProfitSharingCategory with _$ProfitSharingCategory {
totalMovingAverageHpp: 0,
);
bool get hasTopProduct => topProduct.productId.isNotEmpty;
/// Laba kotor memakai HPP standar (acuan yang dipakai di laporan laba rugi).
int get grossProfit => totalRevenue - totalStandardHpp;
@@ -69,6 +74,17 @@ class ProfitSharingCategory with _$ProfitSharingCategory {
totalRevenue == 0 ? 0 : (totalFifoHpp / totalRevenue) * 100;
}
/// Produk dengan omzet tertinggi di satu kategori induk.
@freezed
class ProfitSharingTopProduct with _$ProfitSharingTopProduct {
const factory ProfitSharingTopProduct({
@Default('') String productId,
@Default('') String productName,
@Default(0) int quantitySold,
@Default(0) int revenue,
}) = _ProfitSharingTopProduct;
}
@freezed
class ProfitSharingBudget with _$ProfitSharingBudget {
const factory ProfitSharingBudget({
@@ -114,7 +130,7 @@ class ProfitSharingPeriod with _$ProfitSharingPeriod {
required int revenue,
required int orderCount,
required int limitPurchase,
required int limitOwner,
required int sdl,
required int limitTeam,
@Default('') String month,
@Default(0) int weekCount,
@@ -126,12 +142,16 @@ class ProfitSharingPeriod with _$ProfitSharingPeriod {
revenue: 0,
orderCount: 0,
limitPurchase: 0,
limitOwner: 0,
sdl: 0,
limitTeam: 0,
);
bool get hasRevenue => revenue > 0;
/// % SDL (bagian owner) terhadap omzet. Fee owner berbeda tiap kategori
/// induk, jadi porsinya dihitung dari nominal, bukan dari persentase tetap.
double get sdlPercentage => revenue == 0 ? 0 : (sdl / revenue) * 100;
int get averageOrderValue => orderCount == 0 ? 0 : revenue ~/ orderCount;
}
@@ -14538,6 +14538,13 @@ mixin _$ProfitSharingCategoryDto {
String? get parentCategoryId => throw _privateConstructorUsedError;
@JsonKey(name: 'parent_category_name')
String? get parentCategoryName => throw _privateConstructorUsedError;
@JsonKey(name: 'owner_fee_percent')
num? get ownerFeePercent => throw _privateConstructorUsedError;
@JsonKey(name: 'sdl')
num? get sdl => throw _privateConstructorUsedError;
@JsonKey(name: 'top_product')
ProfitSharingTopProductDto? get topProduct =>
throw _privateConstructorUsedError;
@JsonKey(name: 'total_revenue')
num? get totalRevenue => throw _privateConstructorUsedError;
@JsonKey(name: 'total_quantity')
@@ -14575,6 +14582,9 @@ abstract class $ProfitSharingCategoryDtoCopyWith<$Res> {
$Res call({
@JsonKey(name: 'parent_category_id') String? parentCategoryId,
@JsonKey(name: 'parent_category_name') String? parentCategoryName,
@JsonKey(name: 'owner_fee_percent') num? ownerFeePercent,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'top_product') ProfitSharingTopProductDto? topProduct,
@JsonKey(name: 'total_revenue') num? totalRevenue,
@JsonKey(name: 'total_quantity') num? totalQuantity,
@JsonKey(name: 'category_count') num? categoryCount,
@@ -14584,6 +14594,8 @@ abstract class $ProfitSharingCategoryDtoCopyWith<$Res> {
@JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
@JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
});
$ProfitSharingTopProductDtoCopyWith<$Res>? get topProduct;
}
/// @nodoc
@@ -14606,6 +14618,9 @@ class _$ProfitSharingCategoryDtoCopyWithImpl<
$Res call({
Object? parentCategoryId = freezed,
Object? parentCategoryName = freezed,
Object? ownerFeePercent = freezed,
Object? sdl = freezed,
Object? topProduct = freezed,
Object? totalRevenue = freezed,
Object? totalQuantity = freezed,
Object? categoryCount = freezed,
@@ -14625,6 +14640,18 @@ class _$ProfitSharingCategoryDtoCopyWithImpl<
? _value.parentCategoryName
: parentCategoryName // ignore: cast_nullable_to_non_nullable
as String?,
ownerFeePercent: freezed == ownerFeePercent
? _value.ownerFeePercent
: ownerFeePercent // ignore: cast_nullable_to_non_nullable
as num?,
sdl: freezed == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as num?,
topProduct: freezed == topProduct
? _value.topProduct
: topProduct // ignore: cast_nullable_to_non_nullable
as ProfitSharingTopProductDto?,
totalRevenue: freezed == totalRevenue
? _value.totalRevenue
: totalRevenue // ignore: cast_nullable_to_non_nullable
@@ -14661,6 +14688,22 @@ class _$ProfitSharingCategoryDtoCopyWithImpl<
as $Val,
);
}
/// Create a copy of ProfitSharingCategoryDto
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$ProfitSharingTopProductDtoCopyWith<$Res>? get topProduct {
if (_value.topProduct == null) {
return null;
}
return $ProfitSharingTopProductDtoCopyWith<$Res>(_value.topProduct!, (
value,
) {
return _then(_value.copyWith(topProduct: value) as $Val);
});
}
}
/// @nodoc
@@ -14675,6 +14718,9 @@ abstract class _$$ProfitSharingCategoryDtoImplCopyWith<$Res>
$Res call({
@JsonKey(name: 'parent_category_id') String? parentCategoryId,
@JsonKey(name: 'parent_category_name') String? parentCategoryName,
@JsonKey(name: 'owner_fee_percent') num? ownerFeePercent,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'top_product') ProfitSharingTopProductDto? topProduct,
@JsonKey(name: 'total_revenue') num? totalRevenue,
@JsonKey(name: 'total_quantity') num? totalQuantity,
@JsonKey(name: 'category_count') num? categoryCount,
@@ -14684,6 +14730,9 @@ abstract class _$$ProfitSharingCategoryDtoImplCopyWith<$Res>
@JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
@JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
});
@override
$ProfitSharingTopProductDtoCopyWith<$Res>? get topProduct;
}
/// @nodoc
@@ -14706,6 +14755,9 @@ class __$$ProfitSharingCategoryDtoImplCopyWithImpl<$Res>
$Res call({
Object? parentCategoryId = freezed,
Object? parentCategoryName = freezed,
Object? ownerFeePercent = freezed,
Object? sdl = freezed,
Object? topProduct = freezed,
Object? totalRevenue = freezed,
Object? totalQuantity = freezed,
Object? categoryCount = freezed,
@@ -14725,6 +14777,18 @@ class __$$ProfitSharingCategoryDtoImplCopyWithImpl<$Res>
? _value.parentCategoryName
: parentCategoryName // ignore: cast_nullable_to_non_nullable
as String?,
ownerFeePercent: freezed == ownerFeePercent
? _value.ownerFeePercent
: ownerFeePercent // ignore: cast_nullable_to_non_nullable
as num?,
sdl: freezed == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as num?,
topProduct: freezed == topProduct
? _value.topProduct
: topProduct // ignore: cast_nullable_to_non_nullable
as ProfitSharingTopProductDto?,
totalRevenue: freezed == totalRevenue
? _value.totalRevenue
: totalRevenue // ignore: cast_nullable_to_non_nullable
@@ -14768,6 +14832,9 @@ class _$ProfitSharingCategoryDtoImpl extends _ProfitSharingCategoryDto {
const _$ProfitSharingCategoryDtoImpl({
@JsonKey(name: 'parent_category_id') this.parentCategoryId,
@JsonKey(name: 'parent_category_name') this.parentCategoryName,
@JsonKey(name: 'owner_fee_percent') this.ownerFeePercent,
@JsonKey(name: 'sdl') this.sdl,
@JsonKey(name: 'top_product') this.topProduct,
@JsonKey(name: 'total_revenue') this.totalRevenue,
@JsonKey(name: 'total_quantity') this.totalQuantity,
@JsonKey(name: 'category_count') this.categoryCount,
@@ -14788,6 +14855,15 @@ class _$ProfitSharingCategoryDtoImpl extends _ProfitSharingCategoryDto {
@JsonKey(name: 'parent_category_name')
final String? parentCategoryName;
@override
@JsonKey(name: 'owner_fee_percent')
final num? ownerFeePercent;
@override
@JsonKey(name: 'sdl')
final num? sdl;
@override
@JsonKey(name: 'top_product')
final ProfitSharingTopProductDto? topProduct;
@override
@JsonKey(name: 'total_revenue')
final num? totalRevenue;
@override
@@ -14814,7 +14890,7 @@ class _$ProfitSharingCategoryDtoImpl extends _ProfitSharingCategoryDto {
@override
String toString() {
return 'ProfitSharingCategoryDto(parentCategoryId: $parentCategoryId, parentCategoryName: $parentCategoryName, totalRevenue: $totalRevenue, totalQuantity: $totalQuantity, categoryCount: $categoryCount, productCount: $productCount, orderCount: $orderCount, totalStandardHpp: $totalStandardHpp, totalFifoHpp: $totalFifoHpp, totalMovingAverageHpp: $totalMovingAverageHpp)';
return 'ProfitSharingCategoryDto(parentCategoryId: $parentCategoryId, parentCategoryName: $parentCategoryName, ownerFeePercent: $ownerFeePercent, sdl: $sdl, topProduct: $topProduct, totalRevenue: $totalRevenue, totalQuantity: $totalQuantity, categoryCount: $categoryCount, productCount: $productCount, orderCount: $orderCount, totalStandardHpp: $totalStandardHpp, totalFifoHpp: $totalFifoHpp, totalMovingAverageHpp: $totalMovingAverageHpp)';
}
@override
@@ -14826,6 +14902,11 @@ class _$ProfitSharingCategoryDtoImpl extends _ProfitSharingCategoryDto {
other.parentCategoryId == parentCategoryId) &&
(identical(other.parentCategoryName, parentCategoryName) ||
other.parentCategoryName == parentCategoryName) &&
(identical(other.ownerFeePercent, ownerFeePercent) ||
other.ownerFeePercent == ownerFeePercent) &&
(identical(other.sdl, sdl) || other.sdl == sdl) &&
(identical(other.topProduct, topProduct) ||
other.topProduct == topProduct) &&
(identical(other.totalRevenue, totalRevenue) ||
other.totalRevenue == totalRevenue) &&
(identical(other.totalQuantity, totalQuantity) ||
@@ -14850,6 +14931,9 @@ class _$ProfitSharingCategoryDtoImpl extends _ProfitSharingCategoryDto {
runtimeType,
parentCategoryId,
parentCategoryName,
ownerFeePercent,
sdl,
topProduct,
totalRevenue,
totalQuantity,
categoryCount,
@@ -14881,6 +14965,9 @@ abstract class _ProfitSharingCategoryDto extends ProfitSharingCategoryDto {
const factory _ProfitSharingCategoryDto({
@JsonKey(name: 'parent_category_id') final String? parentCategoryId,
@JsonKey(name: 'parent_category_name') final String? parentCategoryName,
@JsonKey(name: 'owner_fee_percent') final num? ownerFeePercent,
@JsonKey(name: 'sdl') final num? sdl,
@JsonKey(name: 'top_product') final ProfitSharingTopProductDto? topProduct,
@JsonKey(name: 'total_revenue') final num? totalRevenue,
@JsonKey(name: 'total_quantity') final num? totalQuantity,
@JsonKey(name: 'category_count') final num? categoryCount,
@@ -14902,6 +14989,15 @@ abstract class _ProfitSharingCategoryDto extends ProfitSharingCategoryDto {
@JsonKey(name: 'parent_category_name')
String? get parentCategoryName;
@override
@JsonKey(name: 'owner_fee_percent')
num? get ownerFeePercent;
@override
@JsonKey(name: 'sdl')
num? get sdl;
@override
@JsonKey(name: 'top_product')
ProfitSharingTopProductDto? get topProduct;
@override
@JsonKey(name: 'total_revenue')
num? get totalRevenue;
@override
@@ -14934,6 +15030,263 @@ abstract class _ProfitSharingCategoryDto extends ProfitSharingCategoryDto {
get copyWith => throw _privateConstructorUsedError;
}
ProfitSharingTopProductDto _$ProfitSharingTopProductDtoFromJson(
Map<String, dynamic> json,
) {
return _ProfitSharingTopProductDto.fromJson(json);
}
/// @nodoc
mixin _$ProfitSharingTopProductDto {
@JsonKey(name: 'product_id')
String? get productId => throw _privateConstructorUsedError;
@JsonKey(name: 'product_name')
String? get productName => throw _privateConstructorUsedError;
@JsonKey(name: 'quantity_sold')
num? get quantitySold => throw _privateConstructorUsedError;
@JsonKey(name: 'revenue')
num? get revenue => throw _privateConstructorUsedError;
/// Serializes this ProfitSharingTopProductDto to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of ProfitSharingTopProductDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$ProfitSharingTopProductDtoCopyWith<ProfitSharingTopProductDto>
get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ProfitSharingTopProductDtoCopyWith<$Res> {
factory $ProfitSharingTopProductDtoCopyWith(
ProfitSharingTopProductDto value,
$Res Function(ProfitSharingTopProductDto) then,
) =
_$ProfitSharingTopProductDtoCopyWithImpl<
$Res,
ProfitSharingTopProductDto
>;
@useResult
$Res call({
@JsonKey(name: 'product_id') String? productId,
@JsonKey(name: 'product_name') String? productName,
@JsonKey(name: 'quantity_sold') num? quantitySold,
@JsonKey(name: 'revenue') num? revenue,
});
}
/// @nodoc
class _$ProfitSharingTopProductDtoCopyWithImpl<
$Res,
$Val extends ProfitSharingTopProductDto
>
implements $ProfitSharingTopProductDtoCopyWith<$Res> {
_$ProfitSharingTopProductDtoCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ProfitSharingTopProductDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = freezed,
Object? productName = freezed,
Object? quantitySold = freezed,
Object? revenue = freezed,
}) {
return _then(
_value.copyWith(
productId: freezed == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String?,
productName: freezed == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String?,
quantitySold: freezed == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as num?,
revenue: freezed == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as num?,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$ProfitSharingTopProductDtoImplCopyWith<$Res>
implements $ProfitSharingTopProductDtoCopyWith<$Res> {
factory _$$ProfitSharingTopProductDtoImplCopyWith(
_$ProfitSharingTopProductDtoImpl value,
$Res Function(_$ProfitSharingTopProductDtoImpl) then,
) = __$$ProfitSharingTopProductDtoImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
@JsonKey(name: 'product_id') String? productId,
@JsonKey(name: 'product_name') String? productName,
@JsonKey(name: 'quantity_sold') num? quantitySold,
@JsonKey(name: 'revenue') num? revenue,
});
}
/// @nodoc
class __$$ProfitSharingTopProductDtoImplCopyWithImpl<$Res>
extends
_$ProfitSharingTopProductDtoCopyWithImpl<
$Res,
_$ProfitSharingTopProductDtoImpl
>
implements _$$ProfitSharingTopProductDtoImplCopyWith<$Res> {
__$$ProfitSharingTopProductDtoImplCopyWithImpl(
_$ProfitSharingTopProductDtoImpl _value,
$Res Function(_$ProfitSharingTopProductDtoImpl) _then,
) : super(_value, _then);
/// Create a copy of ProfitSharingTopProductDto
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? productId = freezed,
Object? productName = freezed,
Object? quantitySold = freezed,
Object? revenue = freezed,
}) {
return _then(
_$ProfitSharingTopProductDtoImpl(
productId: freezed == productId
? _value.productId
: productId // ignore: cast_nullable_to_non_nullable
as String?,
productName: freezed == productName
? _value.productName
: productName // ignore: cast_nullable_to_non_nullable
as String?,
quantitySold: freezed == quantitySold
? _value.quantitySold
: quantitySold // ignore: cast_nullable_to_non_nullable
as num?,
revenue: freezed == revenue
? _value.revenue
: revenue // ignore: cast_nullable_to_non_nullable
as num?,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$ProfitSharingTopProductDtoImpl extends _ProfitSharingTopProductDto {
const _$ProfitSharingTopProductDtoImpl({
@JsonKey(name: 'product_id') this.productId,
@JsonKey(name: 'product_name') this.productName,
@JsonKey(name: 'quantity_sold') this.quantitySold,
@JsonKey(name: 'revenue') this.revenue,
}) : super._();
factory _$ProfitSharingTopProductDtoImpl.fromJson(
Map<String, dynamic> json,
) => _$$ProfitSharingTopProductDtoImplFromJson(json);
@override
@JsonKey(name: 'product_id')
final String? productId;
@override
@JsonKey(name: 'product_name')
final String? productName;
@override
@JsonKey(name: 'quantity_sold')
final num? quantitySold;
@override
@JsonKey(name: 'revenue')
final num? revenue;
@override
String toString() {
return 'ProfitSharingTopProductDto(productId: $productId, productName: $productName, quantitySold: $quantitySold, revenue: $revenue)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProfitSharingTopProductDtoImpl &&
(identical(other.productId, productId) ||
other.productId == productId) &&
(identical(other.productName, productName) ||
other.productName == productName) &&
(identical(other.quantitySold, quantitySold) ||
other.quantitySold == quantitySold) &&
(identical(other.revenue, revenue) || other.revenue == revenue));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode =>
Object.hash(runtimeType, productId, productName, quantitySold, revenue);
/// Create a copy of ProfitSharingTopProductDto
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ProfitSharingTopProductDtoImplCopyWith<_$ProfitSharingTopProductDtoImpl>
get copyWith =>
__$$ProfitSharingTopProductDtoImplCopyWithImpl<
_$ProfitSharingTopProductDtoImpl
>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$ProfitSharingTopProductDtoImplToJson(this);
}
}
abstract class _ProfitSharingTopProductDto extends ProfitSharingTopProductDto {
const factory _ProfitSharingTopProductDto({
@JsonKey(name: 'product_id') final String? productId,
@JsonKey(name: 'product_name') final String? productName,
@JsonKey(name: 'quantity_sold') final num? quantitySold,
@JsonKey(name: 'revenue') final num? revenue,
}) = _$ProfitSharingTopProductDtoImpl;
const _ProfitSharingTopProductDto._() : super._();
factory _ProfitSharingTopProductDto.fromJson(Map<String, dynamic> json) =
_$ProfitSharingTopProductDtoImpl.fromJson;
@override
@JsonKey(name: 'product_id')
String? get productId;
@override
@JsonKey(name: 'product_name')
String? get productName;
@override
@JsonKey(name: 'quantity_sold')
num? get quantitySold;
@override
@JsonKey(name: 'revenue')
num? get revenue;
/// Create a copy of ProfitSharingTopProductDto
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ProfitSharingTopProductDtoImplCopyWith<_$ProfitSharingTopProductDtoImpl>
get copyWith => throw _privateConstructorUsedError;
}
ProfitSharingBudgetDto _$ProfitSharingBudgetDtoFromJson(
Map<String, dynamic> json,
) {
@@ -15544,8 +15897,8 @@ mixin _$ProfitSharingPeriodDto {
num? get orderCount => throw _privateConstructorUsedError;
@JsonKey(name: 'limit_purchase')
num? get limitPurchase => throw _privateConstructorUsedError;
@JsonKey(name: 'limit_owner')
num? get limitOwner => throw _privateConstructorUsedError;
@JsonKey(name: 'sdl')
num? get sdl => throw _privateConstructorUsedError;
@JsonKey(name: 'limit_team')
num? get limitTeam => throw _privateConstructorUsedError;
@JsonKey(name: 'month')
@@ -15576,7 +15929,7 @@ abstract class $ProfitSharingPeriodDtoCopyWith<$Res> {
@JsonKey(name: 'revenue') num? revenue,
@JsonKey(name: 'order_count') num? orderCount,
@JsonKey(name: 'limit_purchase') num? limitPurchase,
@JsonKey(name: 'limit_owner') num? limitOwner,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'limit_team') num? limitTeam,
@JsonKey(name: 'month') String? month,
@JsonKey(name: 'week_count') num? weekCount,
@@ -15606,7 +15959,7 @@ class _$ProfitSharingPeriodDtoCopyWithImpl<
Object? revenue = freezed,
Object? orderCount = freezed,
Object? limitPurchase = freezed,
Object? limitOwner = freezed,
Object? sdl = freezed,
Object? limitTeam = freezed,
Object? month = freezed,
Object? weekCount = freezed,
@@ -15633,9 +15986,9 @@ class _$ProfitSharingPeriodDtoCopyWithImpl<
? _value.limitPurchase
: limitPurchase // ignore: cast_nullable_to_non_nullable
as num?,
limitOwner: freezed == limitOwner
? _value.limitOwner
: limitOwner // ignore: cast_nullable_to_non_nullable
sdl: freezed == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as num?,
limitTeam: freezed == limitTeam
? _value.limitTeam
@@ -15670,7 +16023,7 @@ abstract class _$$ProfitSharingPeriodDtoImplCopyWith<$Res>
@JsonKey(name: 'revenue') num? revenue,
@JsonKey(name: 'order_count') num? orderCount,
@JsonKey(name: 'limit_purchase') num? limitPurchase,
@JsonKey(name: 'limit_owner') num? limitOwner,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'limit_team') num? limitTeam,
@JsonKey(name: 'month') String? month,
@JsonKey(name: 'week_count') num? weekCount,
@@ -15697,7 +16050,7 @@ class __$$ProfitSharingPeriodDtoImplCopyWithImpl<$Res>
Object? revenue = freezed,
Object? orderCount = freezed,
Object? limitPurchase = freezed,
Object? limitOwner = freezed,
Object? sdl = freezed,
Object? limitTeam = freezed,
Object? month = freezed,
Object? weekCount = freezed,
@@ -15724,9 +16077,9 @@ class __$$ProfitSharingPeriodDtoImplCopyWithImpl<$Res>
? _value.limitPurchase
: limitPurchase // ignore: cast_nullable_to_non_nullable
as num?,
limitOwner: freezed == limitOwner
? _value.limitOwner
: limitOwner // ignore: cast_nullable_to_non_nullable
sdl: freezed == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as num?,
limitTeam: freezed == limitTeam
? _value.limitTeam
@@ -15754,7 +16107,7 @@ class _$ProfitSharingPeriodDtoImpl extends _ProfitSharingPeriodDto {
@JsonKey(name: 'revenue') this.revenue,
@JsonKey(name: 'order_count') this.orderCount,
@JsonKey(name: 'limit_purchase') this.limitPurchase,
@JsonKey(name: 'limit_owner') this.limitOwner,
@JsonKey(name: 'sdl') this.sdl,
@JsonKey(name: 'limit_team') this.limitTeam,
@JsonKey(name: 'month') this.month,
@JsonKey(name: 'week_count') this.weekCount,
@@ -15779,8 +16132,8 @@ class _$ProfitSharingPeriodDtoImpl extends _ProfitSharingPeriodDto {
@JsonKey(name: 'limit_purchase')
final num? limitPurchase;
@override
@JsonKey(name: 'limit_owner')
final num? limitOwner;
@JsonKey(name: 'sdl')
final num? sdl;
@override
@JsonKey(name: 'limit_team')
final num? limitTeam;
@@ -15793,7 +16146,7 @@ class _$ProfitSharingPeriodDtoImpl extends _ProfitSharingPeriodDto {
@override
String toString() {
return 'ProfitSharingPeriodDto(periodStart: $periodStart, periodEnd: $periodEnd, revenue: $revenue, orderCount: $orderCount, limitPurchase: $limitPurchase, limitOwner: $limitOwner, limitTeam: $limitTeam, month: $month, weekCount: $weekCount)';
return 'ProfitSharingPeriodDto(periodStart: $periodStart, periodEnd: $periodEnd, revenue: $revenue, orderCount: $orderCount, limitPurchase: $limitPurchase, sdl: $sdl, limitTeam: $limitTeam, month: $month, weekCount: $weekCount)';
}
@override
@@ -15810,8 +16163,7 @@ class _$ProfitSharingPeriodDtoImpl extends _ProfitSharingPeriodDto {
other.orderCount == orderCount) &&
(identical(other.limitPurchase, limitPurchase) ||
other.limitPurchase == limitPurchase) &&
(identical(other.limitOwner, limitOwner) ||
other.limitOwner == limitOwner) &&
(identical(other.sdl, sdl) || other.sdl == sdl) &&
(identical(other.limitTeam, limitTeam) ||
other.limitTeam == limitTeam) &&
(identical(other.month, month) || other.month == month) &&
@@ -15828,7 +16180,7 @@ class _$ProfitSharingPeriodDtoImpl extends _ProfitSharingPeriodDto {
revenue,
orderCount,
limitPurchase,
limitOwner,
sdl,
limitTeam,
month,
weekCount,
@@ -15859,7 +16211,7 @@ abstract class _ProfitSharingPeriodDto extends ProfitSharingPeriodDto {
@JsonKey(name: 'revenue') final num? revenue,
@JsonKey(name: 'order_count') final num? orderCount,
@JsonKey(name: 'limit_purchase') final num? limitPurchase,
@JsonKey(name: 'limit_owner') final num? limitOwner,
@JsonKey(name: 'sdl') final num? sdl,
@JsonKey(name: 'limit_team') final num? limitTeam,
@JsonKey(name: 'month') final String? month,
@JsonKey(name: 'week_count') final num? weekCount,
@@ -15885,8 +16237,8 @@ abstract class _ProfitSharingPeriodDto extends ProfitSharingPeriodDto {
@JsonKey(name: 'limit_purchase')
num? get limitPurchase;
@override
@JsonKey(name: 'limit_owner')
num? get limitOwner;
@JsonKey(name: 'sdl')
num? get sdl;
@override
@JsonKey(name: 'limit_team')
num? get limitTeam;
@@ -16366,6 +16718,10 @@ ProfitSharingSummaryDto _$ProfitSharingSummaryDtoFromJson(
/// @nodoc
mixin _$ProfitSharingSummaryDto {
@JsonKey(name: 'owner_fee_percent')
num? get ownerFeePercent => throw _privateConstructorUsedError;
@JsonKey(name: 'sdl')
num? get sdl => throw _privateConstructorUsedError;
@JsonKey(name: 'total_revenue')
num? get totalRevenue => throw _privateConstructorUsedError;
@JsonKey(name: 'total_quantity')
@@ -16401,6 +16757,8 @@ abstract class $ProfitSharingSummaryDtoCopyWith<$Res> {
) = _$ProfitSharingSummaryDtoCopyWithImpl<$Res, ProfitSharingSummaryDto>;
@useResult
$Res call({
@JsonKey(name: 'owner_fee_percent') num? ownerFeePercent,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'total_revenue') num? totalRevenue,
@JsonKey(name: 'total_quantity') num? totalQuantity,
@JsonKey(name: 'category_count') num? categoryCount,
@@ -16430,6 +16788,8 @@ class _$ProfitSharingSummaryDtoCopyWithImpl<
@pragma('vm:prefer-inline')
@override
$Res call({
Object? ownerFeePercent = freezed,
Object? sdl = freezed,
Object? totalRevenue = freezed,
Object? totalQuantity = freezed,
Object? categoryCount = freezed,
@@ -16441,6 +16801,14 @@ class _$ProfitSharingSummaryDtoCopyWithImpl<
}) {
return _then(
_value.copyWith(
ownerFeePercent: freezed == ownerFeePercent
? _value.ownerFeePercent
: ownerFeePercent // ignore: cast_nullable_to_non_nullable
as num?,
sdl: freezed == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as num?,
totalRevenue: freezed == totalRevenue
? _value.totalRevenue
: totalRevenue // ignore: cast_nullable_to_non_nullable
@@ -16489,6 +16857,8 @@ abstract class _$$ProfitSharingSummaryDtoImplCopyWith<$Res>
@override
@useResult
$Res call({
@JsonKey(name: 'owner_fee_percent') num? ownerFeePercent,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'total_revenue') num? totalRevenue,
@JsonKey(name: 'total_quantity') num? totalQuantity,
@JsonKey(name: 'category_count') num? categoryCount,
@@ -16518,6 +16888,8 @@ class __$$ProfitSharingSummaryDtoImplCopyWithImpl<$Res>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? ownerFeePercent = freezed,
Object? sdl = freezed,
Object? totalRevenue = freezed,
Object? totalQuantity = freezed,
Object? categoryCount = freezed,
@@ -16529,6 +16901,14 @@ class __$$ProfitSharingSummaryDtoImplCopyWithImpl<$Res>
}) {
return _then(
_$ProfitSharingSummaryDtoImpl(
ownerFeePercent: freezed == ownerFeePercent
? _value.ownerFeePercent
: ownerFeePercent // ignore: cast_nullable_to_non_nullable
as num?,
sdl: freezed == sdl
? _value.sdl
: sdl // ignore: cast_nullable_to_non_nullable
as num?,
totalRevenue: freezed == totalRevenue
? _value.totalRevenue
: totalRevenue // ignore: cast_nullable_to_non_nullable
@@ -16570,6 +16950,8 @@ class __$$ProfitSharingSummaryDtoImplCopyWithImpl<$Res>
@JsonSerializable()
class _$ProfitSharingSummaryDtoImpl extends _ProfitSharingSummaryDto {
const _$ProfitSharingSummaryDtoImpl({
@JsonKey(name: 'owner_fee_percent') this.ownerFeePercent,
@JsonKey(name: 'sdl') this.sdl,
@JsonKey(name: 'total_revenue') this.totalRevenue,
@JsonKey(name: 'total_quantity') this.totalQuantity,
@JsonKey(name: 'category_count') this.categoryCount,
@@ -16583,6 +16965,12 @@ class _$ProfitSharingSummaryDtoImpl extends _ProfitSharingSummaryDto {
factory _$ProfitSharingSummaryDtoImpl.fromJson(Map<String, dynamic> json) =>
_$$ProfitSharingSummaryDtoImplFromJson(json);
@override
@JsonKey(name: 'owner_fee_percent')
final num? ownerFeePercent;
@override
@JsonKey(name: 'sdl')
final num? sdl;
@override
@JsonKey(name: 'total_revenue')
final num? totalRevenue;
@@ -16610,7 +16998,7 @@ class _$ProfitSharingSummaryDtoImpl extends _ProfitSharingSummaryDto {
@override
String toString() {
return 'ProfitSharingSummaryDto(totalRevenue: $totalRevenue, totalQuantity: $totalQuantity, categoryCount: $categoryCount, productCount: $productCount, orderCount: $orderCount, totalStandardHpp: $totalStandardHpp, totalFifoHpp: $totalFifoHpp, totalMovingAverageHpp: $totalMovingAverageHpp)';
return 'ProfitSharingSummaryDto(ownerFeePercent: $ownerFeePercent, sdl: $sdl, totalRevenue: $totalRevenue, totalQuantity: $totalQuantity, categoryCount: $categoryCount, productCount: $productCount, orderCount: $orderCount, totalStandardHpp: $totalStandardHpp, totalFifoHpp: $totalFifoHpp, totalMovingAverageHpp: $totalMovingAverageHpp)';
}
@override
@@ -16618,6 +17006,9 @@ class _$ProfitSharingSummaryDtoImpl extends _ProfitSharingSummaryDto {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ProfitSharingSummaryDtoImpl &&
(identical(other.ownerFeePercent, ownerFeePercent) ||
other.ownerFeePercent == ownerFeePercent) &&
(identical(other.sdl, sdl) || other.sdl == sdl) &&
(identical(other.totalRevenue, totalRevenue) ||
other.totalRevenue == totalRevenue) &&
(identical(other.totalQuantity, totalQuantity) ||
@@ -16640,6 +17031,8 @@ class _$ProfitSharingSummaryDtoImpl extends _ProfitSharingSummaryDto {
@override
int get hashCode => Object.hash(
runtimeType,
ownerFeePercent,
sdl,
totalRevenue,
totalQuantity,
categoryCount,
@@ -16669,6 +17062,8 @@ class _$ProfitSharingSummaryDtoImpl extends _ProfitSharingSummaryDto {
abstract class _ProfitSharingSummaryDto extends ProfitSharingSummaryDto {
const factory _ProfitSharingSummaryDto({
@JsonKey(name: 'owner_fee_percent') final num? ownerFeePercent,
@JsonKey(name: 'sdl') final num? sdl,
@JsonKey(name: 'total_revenue') final num? totalRevenue,
@JsonKey(name: 'total_quantity') final num? totalQuantity,
@JsonKey(name: 'category_count') final num? categoryCount,
@@ -16683,6 +17078,12 @@ abstract class _ProfitSharingSummaryDto extends ProfitSharingSummaryDto {
factory _ProfitSharingSummaryDto.fromJson(Map<String, dynamic> json) =
_$ProfitSharingSummaryDtoImpl.fromJson;
@override
@JsonKey(name: 'owner_fee_percent')
num? get ownerFeePercent;
@override
@JsonKey(name: 'sdl')
num? get sdl;
@override
@JsonKey(name: 'total_revenue')
num? get totalRevenue;
@@ -1159,6 +1159,13 @@ _$ProfitSharingCategoryDtoImpl _$$ProfitSharingCategoryDtoImplFromJson(
) => _$ProfitSharingCategoryDtoImpl(
parentCategoryId: json['parent_category_id'] as String?,
parentCategoryName: json['parent_category_name'] as String?,
ownerFeePercent: json['owner_fee_percent'] as num?,
sdl: json['sdl'] as num?,
topProduct: json['top_product'] == null
? null
: ProfitSharingTopProductDto.fromJson(
json['top_product'] as Map<String, dynamic>,
),
totalRevenue: json['total_revenue'] as num?,
totalQuantity: json['total_quantity'] as num?,
categoryCount: json['category_count'] as num?,
@@ -1174,6 +1181,9 @@ Map<String, dynamic> _$$ProfitSharingCategoryDtoImplToJson(
) => <String, dynamic>{
'parent_category_id': instance.parentCategoryId,
'parent_category_name': instance.parentCategoryName,
'owner_fee_percent': instance.ownerFeePercent,
'sdl': instance.sdl,
'top_product': instance.topProduct,
'total_revenue': instance.totalRevenue,
'total_quantity': instance.totalQuantity,
'category_count': instance.categoryCount,
@@ -1184,6 +1194,24 @@ Map<String, dynamic> _$$ProfitSharingCategoryDtoImplToJson(
'total_moving_average_hpp': instance.totalMovingAverageHpp,
};
_$ProfitSharingTopProductDtoImpl _$$ProfitSharingTopProductDtoImplFromJson(
Map<String, dynamic> json,
) => _$ProfitSharingTopProductDtoImpl(
productId: json['product_id'] as String?,
productName: json['product_name'] as String?,
quantitySold: json['quantity_sold'] as num?,
revenue: json['revenue'] as num?,
);
Map<String, dynamic> _$$ProfitSharingTopProductDtoImplToJson(
_$ProfitSharingTopProductDtoImpl instance,
) => <String, dynamic>{
'product_id': instance.productId,
'product_name': instance.productName,
'quantity_sold': instance.quantitySold,
'revenue': instance.revenue,
};
_$ProfitSharingBudgetDtoImpl _$$ProfitSharingBudgetDtoImplFromJson(
Map<String, dynamic> json,
) => _$ProfitSharingBudgetDtoImpl(
@@ -1248,7 +1276,7 @@ _$ProfitSharingPeriodDtoImpl _$$ProfitSharingPeriodDtoImplFromJson(
revenue: json['revenue'] as num?,
orderCount: json['order_count'] as num?,
limitPurchase: json['limit_purchase'] as num?,
limitOwner: json['limit_owner'] as num?,
sdl: json['sdl'] as num?,
limitTeam: json['limit_team'] as num?,
month: json['month'] as String?,
weekCount: json['week_count'] as num?,
@@ -1262,7 +1290,7 @@ Map<String, dynamic> _$$ProfitSharingPeriodDtoImplToJson(
'revenue': instance.revenue,
'order_count': instance.orderCount,
'limit_purchase': instance.limitPurchase,
'limit_owner': instance.limitOwner,
'sdl': instance.sdl,
'limit_team': instance.limitTeam,
'month': instance.month,
'week_count': instance.weekCount,
@@ -1315,6 +1343,8 @@ Map<String, dynamic> _$$ProfitSharingDetailDtoImplToJson(
_$ProfitSharingSummaryDtoImpl _$$ProfitSharingSummaryDtoImplFromJson(
Map<String, dynamic> json,
) => _$ProfitSharingSummaryDtoImpl(
ownerFeePercent: json['owner_fee_percent'] as num?,
sdl: json['sdl'] as num?,
totalRevenue: json['total_revenue'] as num?,
totalQuantity: json['total_quantity'] as num?,
categoryCount: json['category_count'] as num?,
@@ -1328,6 +1358,8 @@ _$ProfitSharingSummaryDtoImpl _$$ProfitSharingSummaryDtoImplFromJson(
Map<String, dynamic> _$$ProfitSharingSummaryDtoImplToJson(
_$ProfitSharingSummaryDtoImpl instance,
) => <String, dynamic>{
'owner_fee_percent': instance.ownerFeePercent,
'sdl': instance.sdl,
'total_revenue': instance.totalRevenue,
'total_quantity': instance.totalQuantity,
'category_count': instance.categoryCount,
@@ -35,6 +35,9 @@ class ProfitSharingCategoryDto with _$ProfitSharingCategoryDto {
const factory ProfitSharingCategoryDto({
@JsonKey(name: 'parent_category_id') String? parentCategoryId,
@JsonKey(name: 'parent_category_name') String? parentCategoryName,
@JsonKey(name: 'owner_fee_percent') num? ownerFeePercent,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'top_product') ProfitSharingTopProductDto? topProduct,
@JsonKey(name: 'total_revenue') num? totalRevenue,
@JsonKey(name: 'total_quantity') num? totalQuantity,
@JsonKey(name: 'category_count') num? categoryCount,
@@ -59,6 +62,31 @@ class ProfitSharingCategoryDto with _$ProfitSharingCategoryDto {
totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
ownerFeePercent: ownerFeePercent?.toDouble() ?? 0,
sdl: sdl?.toInt() ?? 0,
topProduct: topProduct?.toDomain() ?? const ProfitSharingTopProduct(),
);
}
@freezed
class ProfitSharingTopProductDto with _$ProfitSharingTopProductDto {
const ProfitSharingTopProductDto._();
const factory ProfitSharingTopProductDto({
@JsonKey(name: 'product_id') String? productId,
@JsonKey(name: 'product_name') String? productName,
@JsonKey(name: 'quantity_sold') num? quantitySold,
@JsonKey(name: 'revenue') num? revenue,
}) = _ProfitSharingTopProductDto;
factory ProfitSharingTopProductDto.fromJson(Map<String, dynamic> json) =>
_$ProfitSharingTopProductDtoFromJson(json);
ProfitSharingTopProduct toDomain() => ProfitSharingTopProduct(
productId: productId ?? '',
productName: productName ?? '',
quantitySold: quantitySold?.toInt() ?? 0,
revenue: revenue?.toInt() ?? 0,
);
}
@@ -118,7 +146,7 @@ class ProfitSharingPeriodDto with _$ProfitSharingPeriodDto {
@JsonKey(name: 'revenue') num? revenue,
@JsonKey(name: 'order_count') num? orderCount,
@JsonKey(name: 'limit_purchase') num? limitPurchase,
@JsonKey(name: 'limit_owner') num? limitOwner,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'limit_team') num? limitTeam,
@JsonKey(name: 'month') String? month,
@JsonKey(name: 'week_count') num? weekCount,
@@ -134,7 +162,7 @@ class ProfitSharingPeriodDto with _$ProfitSharingPeriodDto {
revenue: revenue?.toInt() ?? 0,
orderCount: orderCount?.toInt() ?? 0,
limitPurchase: limitPurchase?.toInt() ?? 0,
limitOwner: limitOwner?.toInt() ?? 0,
sdl: sdl?.toInt() ?? 0,
limitTeam: limitTeam?.toInt() ?? 0,
month: month ?? '',
weekCount: weekCount?.toInt() ?? 0,
@@ -187,6 +215,8 @@ class ProfitSharingSummaryDto with _$ProfitSharingSummaryDto {
const ProfitSharingSummaryDto._();
const factory ProfitSharingSummaryDto({
@JsonKey(name: 'owner_fee_percent') num? ownerFeePercent,
@JsonKey(name: 'sdl') num? sdl,
@JsonKey(name: 'total_revenue') num? totalRevenue,
@JsonKey(name: 'total_quantity') num? totalQuantity,
@JsonKey(name: 'category_count') num? categoryCount,
@@ -214,6 +244,8 @@ class ProfitSharingSummaryDto with _$ProfitSharingSummaryDto {
totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
ownerFeePercent: ownerFeePercent?.toDouble() ?? 0,
sdl: sdl?.toInt() ?? 0,
);
}
+3 -3
View File
@@ -294,13 +294,13 @@ extension GetItInjectableX on _i174.GetIt {
gh.factory<_i11.ProfitLossLoaderBloc>(
() => _i11.ProfitLossLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i631.ProfitSharingLoaderBloc>(
() => _i631.ProfitSharingLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i400.ProfitSharingDetailLoaderBloc>(
() =>
_i400.ProfitSharingDetailLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i631.ProfitSharingLoaderBloc>(
() => _i631.ProfitSharingLoaderBloc(gh<_i477.IAnalyticRepository>()),
);
gh.factory<_i945.AuthBloc>(
() => _i945.AuthBloc(gh<_i49.IAuthRepository>()),
);
+4
View File
@@ -551,6 +551,10 @@
"@share_owner": {},
"share_team": "Team",
"@share_team": {},
"sdl": "SDL",
"@sdl": {},
"top_product": "Top Product",
"@top_product": {},
"weekly": "Weekly",
"@weekly": {},
"monthly": "Monthly",
+4
View File
@@ -551,6 +551,10 @@
"@share_owner": {},
"share_team": "Tim",
"@share_team": {},
"sdl": "SDL",
"@sdl": {},
"top_product": "Produk Terlaris",
"@top_product": {},
"weekly": "Mingguan",
"@weekly": {},
"monthly": "Bulanan",
+12
View File
@@ -1601,6 +1601,18 @@ abstract class AppLocalizations {
/// **'Team'**
String get share_team;
/// No description provided for @sdl.
///
/// In en, this message translates to:
/// **'SDL'**
String get sdl;
/// No description provided for @top_product.
///
/// In en, this message translates to:
/// **'Top Product'**
String get top_product;
/// No description provided for @weekly.
///
/// In en, this message translates to:
+6
View File
@@ -775,6 +775,12 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get share_team => 'Team';
@override
String get sdl => 'SDL';
@override
String get top_product => 'Top Product';
@override
String get weekly => 'Weekly';
+6
View File
@@ -775,6 +775,12 @@ class AppLocalizationsId extends AppLocalizations {
@override
String get share_team => 'Tim';
@override
String get sdl => 'SDL';
@override
String get top_product => 'Produk Terlaris';
@override
String get weekly => 'Mingguan';
@@ -183,50 +183,55 @@ class _SummaryCard extends StatelessWidget {
Row(
children: [
Expanded(
child: ProfitSharingMetric(
child: ProfitSharingStatTile(
icon: Icons.category_rounded,
label: context.lang.sub_category,
value: '${summary.categoryCount}',
),
),
const SpaceWidth(10),
Expanded(
child: ProfitSharingMetric(
child: ProfitSharingStatTile(
icon: Icons.inventory_2_rounded,
label: context.lang.products,
value: '${summary.productCount}',
color: AppColor.info,
),
),
const SpaceWidth(10),
Expanded(
child: ProfitSharingMetric(
child: ProfitSharingStatTile(
icon: Icons.receipt_long_rounded,
label: context.lang.orders,
value: summary.orderCount.thousandFormat,
color: AppColor.warning,
),
),
],
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 12),
child: Divider(height: 1, color: AppColor.borderLight),
const SpaceHeight(12),
ProfitSharingSdlStrip(
amount: summary.sdl,
feePercent: summary.ownerFeePercent,
),
const SpaceHeight(12),
Row(
children: [
Expanded(
child: ProfitSharingMetric(
label: context.lang.std_hpp,
value: formatPercent(summary.standardHppPercentage),
child: Text(
context.lang.gross_profit,
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
),
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.real_hpp,
value: formatPercent(summary.realHppPercentage),
valueColor: statusColor(summary.realHppPercentage),
),
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.gross_profit,
value: summary.grossProfit.currencyFormatRp,
Text(
summary.grossProfit.currencyFormatRp,
style: AppStyle.md.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w800,
),
),
],
@@ -21,6 +21,11 @@ class ProfitSharingAllocation extends StatelessWidget {
Widget build(BuildContext context) {
final total = budget.total;
final percentages = budget.percentages;
// Fee owner berbeda tiap kategori induk, jadi porsi SDL dihitung dari
// nominalnya; persentase bawaan hanya dipakai saat belum ada omzet.
final sdlPercentage = total.hasRevenue
? total.sdlPercentage
: percentages.owner;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
@@ -52,7 +57,7 @@ class ProfitSharingAllocation extends StatelessWidget {
ProfitSharingBar(
purchase: percentages.purchase,
owner: percentages.owner,
owner: sdlPercentage,
team: percentages.team,
),
@@ -69,9 +74,9 @@ class ProfitSharingAllocation extends StatelessWidget {
_row(
context: context,
color: ProfitSharingColor.owner,
label: context.lang.share_owner,
percentage: percentages.owner,
amount: total.limitOwner,
label: context.lang.sdl,
percentage: sdlPercentage,
amount: total.sdl,
),
const Divider(height: 24, color: AppColor.borderLight),
_row(
@@ -140,7 +145,7 @@ class ProfitSharingAllocation extends StatelessWidget {
}
}
/// Bar proporsi belanja / owner / tim.
/// Bar proporsi belanja / SDL (owner) / tim.
class ProfitSharingBar extends StatelessWidget {
final double purchase;
final double owner;
@@ -6,7 +6,7 @@ import '../../../../domain/analytic/analytic.dart';
import '../../../components/spacer/spacer.dart';
import 'profit_sharing_status.dart';
/// Ringkasan omzet & HPP per kategori induk (parent category).
/// Ringkasan omzet & SDL per kategori induk (parent category).
/// Tiap kartu bisa diketuk untuk melihat rincian sub kategori & produknya.
class ProfitSharingCategories extends StatelessWidget {
final List<ProfitSharingCategory> categories;
@@ -69,18 +69,18 @@ class ProfitSharingCategories extends StatelessWidget {
),
)
else ...[
...sorted.map(
(category) => Padding(
for (var i = 0; i < sorted.length; i++)
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: _CategoryCard(
category: category,
rank: i + 1,
category: sorted[i],
share: totalRevenue == 0
? 0
: category.totalRevenue / totalRevenue,
onTap: () => onCategoryTap(category),
: sorted[i].totalRevenue / totalRevenue,
onTap: () => onCategoryTap(sorted[i]),
),
),
),
_TotalCard(categories: sorted),
],
],
@@ -90,11 +90,13 @@ class ProfitSharingCategories extends StatelessWidget {
}
class _CategoryCard extends StatelessWidget {
final int rank;
final ProfitSharingCategory category;
final double share;
final VoidCallback onTap;
const _CategoryCard({
required this.rank,
required this.category,
required this.share,
required this.onTap,
@@ -102,132 +104,216 @@ class _CategoryCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(12),
child: Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: AppColor.background,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.borderLight),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
category.parentCategoryName,
style: AppStyle.md.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w700,
final isTop = rank == 1;
return Material(
color: AppColor.background,
borderRadius: BorderRadius.circular(14),
child: InkWell(
onTap: onTap,
borderRadius: BorderRadius.circular(14),
child: Container(
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(14),
border: Border.all(color: AppColor.borderLight),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Container(
width: 36,
height: 36,
alignment: Alignment.center,
decoration: BoxDecoration(
color: isTop
? AppColor.primary
: AppColor.primary.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
const SpaceWidth(8),
ProfitSharingStatusBadge(
realHppPercentage: category.realHppPercentage,
),
const Icon(
Icons.chevron_right_rounded,
color: AppColor.textSecondary,
size: 20,
),
],
),
const SpaceHeight(8),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
category.totalRevenue.currencyFormatRp,
style: AppStyle.lg.copyWith(
color: AppColor.primary,
fontWeight: FontWeight.w800,
child: Text(
'$rank',
style: AppStyle.md.copyWith(
color: isTop ? AppColor.textWhite : AppColor.primary,
fontWeight: FontWeight.w800,
),
),
),
),
Text(
formatPercent(share * 100),
style: AppStyle.xs.copyWith(
const SpaceWidth(10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
category.parentCategoryName,
style: AppStyle.md.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w700,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 2),
Text(
'${category.categoryCount} ${context.lang.sub_category}'
' · ${category.productCount} ${context.lang.products}'
' · ${context.lang.qty} ${category.totalQuantity.thousandFormat}',
style: AppStyle.xs.copyWith(
color: AppColor.textSecondary,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
const SpaceWidth(8),
ProfitSharingStatusBadge(
realHppPercentage: category.realHppPercentage,
),
const Icon(
Icons.chevron_right_rounded,
color: AppColor.textSecondary,
fontWeight: FontWeight.w600,
size: 20,
),
),
],
),
],
),
const SpaceHeight(8),
const SpaceHeight(14),
ClipRRect(
borderRadius: BorderRadius.circular(6),
child: LinearProgressIndicator(
value: share.clamp(0.0, 1.0),
minHeight: 6,
backgroundColor: AppColor.borderLight,
valueColor: const AlwaysStoppedAnimation<Color>(
AppColor.primary,
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: Text(
category.totalRevenue.currencyFormatRp,
style: AppStyle.xl.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w800,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
const SpaceWidth(8),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 3,
),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.08),
borderRadius: BorderRadius.circular(20),
),
child: Text(
formatPercent(share * 100),
style: AppStyle.xs.copyWith(
color: AppColor.primary,
fontWeight: FontWeight.w700,
),
),
),
],
),
const SpaceHeight(8),
ClipRRect(
borderRadius: BorderRadius.circular(6),
child: LinearProgressIndicator(
value: share.clamp(0.0, 1.0),
minHeight: 6,
backgroundColor: AppColor.border.withOpacity(0.6),
valueColor: const AlwaysStoppedAnimation<Color>(
AppColor.primary,
),
),
),
),
const SpaceHeight(12),
const SpaceHeight(12),
Row(
children: [
Expanded(
child: ProfitSharingMetric(
label: context.lang.qty,
value: category.totalQuantity.thousandFormat,
),
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.products,
value: '${category.productCount}',
),
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.sub_category,
value: '${category.categoryCount}',
),
),
ProfitSharingSdlStrip(
amount: category.sdl,
feePercent: category.ownerFeePercent,
),
if (category.hasTopProduct) ...[
const SpaceHeight(10),
_TopProduct(product: category.topProduct),
],
),
],
),
),
),
);
}
}
const Padding(
padding: EdgeInsets.symmetric(vertical: 10),
child: Divider(height: 1, color: AppColor.border),
),
class _TopProduct extends StatelessWidget {
final ProfitSharingTopProduct product;
Row(
children: [
Expanded(
child: ProfitSharingMetric(
label: context.lang.std_hpp,
value: formatPercent(category.standardHppPercentage),
),
const _TopProduct({required this.product});
@override
Widget build(BuildContext context) {
return Row(
children: [
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: AppColor.warning.withOpacity(0.12),
borderRadius: BorderRadius.circular(8),
),
child: const Icon(
Icons.emoji_events_rounded,
color: AppColor.warning,
size: 16,
),
),
const SpaceWidth(10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
context.lang.top_product,
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
),
const SizedBox(height: 2),
Text(
product.productName,
style: AppStyle.sm.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w600,
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.real_hpp,
value: formatPercent(category.realHppPercentage),
valueColor: statusColor(category.realHppPercentage),
),
),
],
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
const SpaceWidth(8),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'${product.quantitySold.thousandFormat}x ${context.lang.sold.toLowerCase()}',
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
),
const SizedBox(height: 2),
Text(
product.revenue.currencyFormatRp,
style: AppStyle.sm.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
);
}
}
@@ -247,74 +333,44 @@ class _TotalCard extends StatelessWidget {
0,
(sum, e) => sum + e.totalRevenue,
);
final totalStandardHpp = categories.fold<int>(
0,
(sum, e) => sum + e.totalStandardHpp,
);
final totalFifoHpp = categories.fold<int>(
0,
(sum, e) => sum + e.totalFifoHpp,
);
double percentOf(int hpp) =>
totalRevenue == 0 ? 0 : (hpp / totalRevenue) * 100;
final totalSdl = categories.fold<int>(0, (sum, e) => sum + e.sdl);
return Container(
padding: const EdgeInsets.all(14),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: AppColor.primary.withOpacity(0.06),
borderRadius: BorderRadius.circular(12),
gradient: const LinearGradient(
colors: AppColor.primaryGradient,
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(14),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
context.lang.grand_total,
style: AppStyle.md.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w800,
),
),
),
Text(
totalRevenue.currencyFormatRp,
style: AppStyle.lg.copyWith(
color: AppColor.primary,
fontWeight: FontWeight.w900,
),
),
],
Text(
context.lang.grand_total,
style: AppStyle.xs.copyWith(
color: AppColor.textWhite.withOpacity(0.8),
fontWeight: FontWeight.w700,
letterSpacing: 1,
),
),
const SizedBox(height: 4),
Text(
totalRevenue.currencyFormatRp,
style: AppStyle.xl.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.w900,
),
),
const SpaceHeight(12),
Row(
children: [
Expanded(
child: ProfitSharingMetric(
label: context.lang.qty,
value: totalQuantity.thousandFormat,
isBold: true,
),
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.std_hpp,
value: formatPercent(percentOf(totalStandardHpp)),
isBold: true,
),
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.real_hpp,
value: formatPercent(percentOf(totalFifoHpp)),
isBold: true,
valueColor: statusColor(percentOf(totalFifoHpp)),
),
),
ProfitSharingHeaderStats(
stats: [
(context.lang.qty, totalQuantity.thousandFormat),
(context.lang.sdl, totalSdl.currencyFormatRp),
],
),
],
@@ -130,22 +130,13 @@ class ProfitSharingDetailHeader extends StatelessWidget {
const SpaceHeight(16),
if (state.isFetching)
Row(
children: [
_shimmerBox(width: 120, height: 32, radius: 20),
const SpaceWidth(8),
_shimmerBox(width: 120, height: 32, radius: 20),
],
)
_shimmerBox(width: double.infinity, height: 62, radius: 14)
else
Wrap(
spacing: 8,
runSpacing: 8,
children: [
_chip(
'${context.lang.qty} ${summary.totalQuantity.thousandFormat}',
),
_chip(context.lang.order_count_label(summary.orderCount)),
ProfitSharingHeaderStats(
stats: [
(context.lang.qty, summary.totalQuantity.thousandFormat),
(context.lang.orders, summary.orderCount.thousandFormat),
(context.lang.sdl, summary.sdl.currencyFormatRp),
],
),
],
@@ -155,25 +146,6 @@ class ProfitSharingDetailHeader extends StatelessWidget {
);
}
Widget _chip(String label) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
decoration: BoxDecoration(
color: AppColor.textWhite.withOpacity(0.15),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: AppColor.textWhite.withOpacity(0.25)),
),
child: Text(
label,
style: AppStyle.sm.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.w600,
fontSize: 12,
),
),
);
}
Widget _shimmerBox({
required double width,
required double height,
@@ -6,6 +6,7 @@ import '../../../../application/analytic/profit_sharing_loader/profit_sharing_lo
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/spacer/spacer.dart';
import 'profit_sharing_status.dart';
class ProfitSharingHeader extends StatelessWidget {
final ProfitSharingLoaderState state;
@@ -112,9 +113,15 @@ class ProfitSharingHeader extends StatelessWidget {
const SpaceHeight(16),
state.isFetching
? _shimmerBox(width: 140, height: 32, radius: 20)
: _chip(
context.lang.order_count_label(budget.total.orderCount),
? _shimmerBox(width: double.infinity, height: 62, radius: 14)
: ProfitSharingHeaderStats(
stats: [
(
context.lang.orders,
budget.total.orderCount.thousandFormat,
),
(context.lang.sdl, budget.total.sdl.currencyFormatRp),
],
),
],
),
@@ -123,25 +130,6 @@ class ProfitSharingHeader extends StatelessWidget {
);
}
Widget _chip(String label) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
decoration: BoxDecoration(
color: AppColor.textWhite.withOpacity(0.15),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: AppColor.textWhite.withOpacity(0.25)),
),
child: Text(
label,
style: AppStyle.sm.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.w600,
fontSize: 12,
),
),
);
}
Widget _shimmerBox({
required double width,
required double height,
@@ -200,7 +200,7 @@ class _PeriodCard extends StatelessWidget {
ProfitSharingBar(
purchase: percentages.purchase,
owner: percentages.owner,
owner: period.hasRevenue ? period.sdlPercentage : percentages.owner,
team: percentages.team,
height: 6,
),
@@ -214,11 +214,7 @@ class _PeriodCard extends StatelessWidget {
period.limitPurchase,
ProfitSharingColor.purchase,
),
_share(
context.lang.share_owner,
period.limitOwner,
ProfitSharingColor.owner,
),
_share(context.lang.sdl, period.sdl, ProfitSharingColor.owner),
_share(
context.lang.share_team,
period.limitTeam,
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import '../../../../common/extension/extension.dart';
import '../../../../common/theme/theme.dart';
import '../../../components/spacer/spacer.dart';
import 'profit_sharing_allocation.dart';
/// Ambang kesehatan berdasarkan % HPP riil terhadap omzet.
/// Ubah di sini kalau target margin bisnis berubah.
@@ -12,6 +14,10 @@ class HppThreshold {
String formatPercent(double value) => '${value.toStringAsFixed(1)}%';
/// Persen fee tanpa desimal kalau nilainya bulat (20% / 22.5%).
String formatFeePercent(double value) =>
'${value.toStringAsFixed(value % 1 == 0 ? 0 : 1)}%';
Color statusColor(double realHppPercentage) {
if (realHppPercentage <= HppThreshold.healthy) return AppColor.success;
if (realHppPercentage <= HppThreshold.watch) return AppColor.warning;
@@ -63,6 +69,201 @@ class ProfitSharingStatusBadge extends StatelessWidget {
}
}
/// Strip sorotan SDL: label + persen fee owner di kiri, nominal di kanan.
class ProfitSharingSdlStrip extends StatelessWidget {
final int amount;
final double? feePercent;
const ProfitSharingSdlStrip({
super.key,
required this.amount,
this.feePercent,
});
@override
Widget build(BuildContext context) {
const color = ProfitSharingColor.owner;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
decoration: BoxDecoration(
color: color.withOpacity(0.08),
borderRadius: BorderRadius.circular(10),
border: Border.all(color: color.withOpacity(0.2)),
),
child: Row(
children: [
const Icon(
Icons.account_balance_wallet_rounded,
color: color,
size: 18,
),
const SpaceWidth(8),
Text(
context.lang.sdl,
style: AppStyle.sm.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w600,
),
),
if (feePercent != null) ...[
const SpaceWidth(6),
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(6),
),
child: Text(
formatFeePercent(feePercent!),
style: AppStyle.xs.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.w700,
),
),
),
],
const SpaceWidth(8),
Expanded(
child: Text(
amount.currencyFormatRp,
textAlign: TextAlign.right,
style: AppStyle.md.copyWith(
color: AppColor.secondaryDark,
fontWeight: FontWeight.w800,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
}
/// Deretan angka ringkas di header (latar gelap), dipisah garis tipis.
class ProfitSharingHeaderStats extends StatelessWidget {
final List<(String label, String value)> stats;
const ProfitSharingHeaderStats({super.key, required this.stats});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
color: AppColor.textWhite.withOpacity(0.14),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: AppColor.textWhite.withOpacity(0.22)),
),
child: IntrinsicHeight(
child: Row(
children: [
for (var i = 0; i < stats.length; i++) ...[
if (i > 0)
VerticalDivider(
width: 1,
thickness: 1,
color: AppColor.textWhite.withOpacity(0.22),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
stats[i].$1,
style: AppStyle.xs.copyWith(
color: AppColor.textWhite.withOpacity(0.75),
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 4),
FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Text(
stats[i].$2,
style: AppStyle.md.copyWith(
color: AppColor.textWhite,
fontWeight: FontWeight.w800,
),
),
),
],
),
),
),
],
],
),
),
);
}
}
/// Kotak statistik kecil: ikon, nilai, lalu label.
class ProfitSharingStatTile extends StatelessWidget {
final IconData icon;
final String label;
final String value;
final Color color;
const ProfitSharingStatTile({
super.key,
required this.icon,
required this.label,
required this.value,
this.color = AppColor.primary,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: AppColor.background,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColor.borderLight),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
),
child: Icon(icon, color: color, size: 16),
),
const SpaceHeight(10),
Text(
value,
style: AppStyle.lg.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w800,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
const SizedBox(height: 2),
Text(
label,
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
);
}
}
/// Label kecil dua baris: judul di atas, nilai di bawah.
class ProfitSharingMetric extends StatelessWidget {
final String label;
@@ -178,13 +178,6 @@ class _SubCategoryCard extends StatelessWidget {
value: '${category.productCount}',
),
),
Expanded(
child: ProfitSharingMetric(
label: context.lang.real_hpp,
value: formatPercent(category.realHppPercentage),
valueColor: statusColor(category.realHppPercentage),
),
),
],
),
],
@@ -237,8 +230,6 @@ class _ProductRow extends StatelessWidget {
@override
Widget build(BuildContext context) {
final color = statusColor(product.realHppPercentage);
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: Row(
@@ -284,25 +275,12 @@ class _ProductRow extends StatelessWidget {
),
),
const SpaceWidth(8),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
product.revenue.currencyFormatRp,
style: AppStyle.sm.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 2),
Text(
'${context.lang.real_hpp} ${formatPercent(product.realHppPercentage)}',
style: AppStyle.xs.copyWith(
color: color,
fontWeight: FontWeight.w600,
),
),
],
Text(
product.revenue.currencyFormatRp,
style: AppStyle.sm.copyWith(
color: AppColor.textPrimary,
fontWeight: FontWeight.w700,
),
),
],
),
+2 -2
View File
@@ -1662,10 +1662,10 @@ packages:
dependency: transitive
description:
name: vector_math
sha256: f36f9f3be64c6198714492bb455c11056e33e2f85d9a0b676a48301e44fdcf47
sha256: "92b9910f66ed1057fd4da7b040ae7c74cafacf885bdc81be496928d5049b032d"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.4.3"
vm_service:
dependency: transitive
description:
+1 -1
View File
@@ -3,7 +3,7 @@ description: "A new Flutter project."
publish_to: "none"
version: 1.0.4+12
version: 1.0.4+13
environment:
sdk: ^3.8.1