diff --git a/lib/domain/analytic/analytic.freezed.dart b/lib/domain/analytic/analytic.freezed.dart index 400d8c5..e763773 100644 --- a/lib/domain/analytic/analytic.freezed.dart +++ b/lib/domain/analytic/analytic.freezed.dart @@ -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 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 diff --git a/lib/domain/analytic/entities/profit_sharing_entity.dart b/lib/domain/analytic/entities/profit_sharing_entity.dart index 78c0c29..8026a4c 100644 --- a/lib/domain/analytic/entities/profit_sharing_entity.dart +++ b/lib/domain/analytic/entities/profit_sharing_entity.dart @@ -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; } diff --git a/lib/infrastructure/analytic/analytic_dtos.freezed.dart b/lib/infrastructure/analytic/analytic_dtos.freezed.dart index a963583..2d56cfc 100644 --- a/lib/infrastructure/analytic/analytic_dtos.freezed.dart +++ b/lib/infrastructure/analytic/analytic_dtos.freezed.dart @@ -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 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 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 + 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 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 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 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 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 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 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; diff --git a/lib/infrastructure/analytic/analytic_dtos.g.dart b/lib/infrastructure/analytic/analytic_dtos.g.dart index 2b35022..c061949 100644 --- a/lib/infrastructure/analytic/analytic_dtos.g.dart +++ b/lib/infrastructure/analytic/analytic_dtos.g.dart @@ -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, + ), totalRevenue: json['total_revenue'] as num?, totalQuantity: json['total_quantity'] as num?, categoryCount: json['category_count'] as num?, @@ -1174,6 +1181,9 @@ Map _$$ProfitSharingCategoryDtoImplToJson( ) => { '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 _$$ProfitSharingCategoryDtoImplToJson( 'total_moving_average_hpp': instance.totalMovingAverageHpp, }; +_$ProfitSharingTopProductDtoImpl _$$ProfitSharingTopProductDtoImplFromJson( + Map 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 _$$ProfitSharingTopProductDtoImplToJson( + _$ProfitSharingTopProductDtoImpl instance, +) => { + 'product_id': instance.productId, + 'product_name': instance.productName, + 'quantity_sold': instance.quantitySold, + 'revenue': instance.revenue, +}; + _$ProfitSharingBudgetDtoImpl _$$ProfitSharingBudgetDtoImplFromJson( Map 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 _$$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 _$$ProfitSharingDetailDtoImplToJson( _$ProfitSharingSummaryDtoImpl _$$ProfitSharingSummaryDtoImplFromJson( Map 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 _$$ProfitSharingSummaryDtoImplToJson( _$ProfitSharingSummaryDtoImpl instance, ) => { + 'owner_fee_percent': instance.ownerFeePercent, + 'sdl': instance.sdl, 'total_revenue': instance.totalRevenue, 'total_quantity': instance.totalQuantity, 'category_count': instance.categoryCount, diff --git a/lib/infrastructure/analytic/dto/profit_sharing_dto.dart b/lib/infrastructure/analytic/dto/profit_sharing_dto.dart index d414cf1..2a98eb7 100644 --- a/lib/infrastructure/analytic/dto/profit_sharing_dto.dart +++ b/lib/infrastructure/analytic/dto/profit_sharing_dto.dart @@ -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 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, ); } diff --git a/lib/injection.config.dart b/lib/injection.config.dart index fcd6e86..1c0881c 100644 --- a/lib/injection.config.dart +++ b/lib/injection.config.dart @@ -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>()), ); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index e40f1e0..320e57a 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -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", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 02d7327..9f0bca9 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -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", diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 43191fb..27cd9cd 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -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: diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 220a9c1..6fdd488 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -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'; diff --git a/lib/l10n/app_localizations_id.dart b/lib/l10n/app_localizations_id.dart index 1cb9fd4..ae07cd7 100644 --- a/lib/l10n/app_localizations_id.dart +++ b/lib/l10n/app_localizations_id.dart @@ -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'; diff --git a/lib/presentation/pages/profit_sharing/profit_sharing_detail_page.dart b/lib/presentation/pages/profit_sharing/profit_sharing_detail_page.dart index 4d83483..473d435 100644 --- a/lib/presentation/pages/profit_sharing/profit_sharing_detail_page.dart +++ b/lib/presentation/pages/profit_sharing/profit_sharing_detail_page.dart @@ -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, ), ), ], diff --git a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_allocation.dart b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_allocation.dart index 9f7fb17..58376e8 100644 --- a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_allocation.dart +++ b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_allocation.dart @@ -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; diff --git a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_categories.dart b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_categories.dart index c39383e..a5f36a8 100644 --- a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_categories.dart +++ b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_categories.dart @@ -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 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( - 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( + 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( - 0, - (sum, e) => sum + e.totalStandardHpp, - ); - final totalFifoHpp = categories.fold( - 0, - (sum, e) => sum + e.totalFifoHpp, - ); - - double percentOf(int hpp) => - totalRevenue == 0 ? 0 : (hpp / totalRevenue) * 100; + final totalSdl = categories.fold(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), ], ), ], diff --git a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_detail_header.dart b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_detail_header.dart index 955e317..4c9709b 100644 --- a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_detail_header.dart +++ b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_detail_header.dart @@ -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, diff --git a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_header.dart b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_header.dart index 2446728..c5ee3af 100644 --- a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_header.dart +++ b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_header.dart @@ -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, diff --git a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_periods.dart b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_periods.dart index 30d6106..04b00a2 100644 --- a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_periods.dart +++ b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_periods.dart @@ -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, diff --git a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_status.dart b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_status.dart index 80257f0..6a74fae 100644 --- a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_status.dart +++ b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_status.dart @@ -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; diff --git a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_subcategories.dart b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_subcategories.dart index 7a67528..f894a4d 100644 --- a/lib/presentation/pages/profit_sharing/widgets/profit_sharing_subcategories.dart +++ b/lib/presentation/pages/profit_sharing/widgets/profit_sharing_subcategories.dart @@ -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, + ), ), ], ), diff --git a/pubspec.lock b/pubspec.lock index dffae66..842e294 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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: diff --git a/pubspec.yaml b/pubspec.yaml index 02623bd..6b0b21a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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