This commit is contained in:
@@ -12,7 +12,7 @@ A POS (Point of Sale) application for business owners, built with Flutter. The p
|
||||
- Architecture Overview
|
||||
- Project Structure
|
||||
- Key Dependencies & Purpose
|
||||
- Code Generation
|
||||
- Code Generation (see docs/codegen.md)
|
||||
- Internationalization (i18n)
|
||||
- Theming & Assets
|
||||
- Environment Configuration (`env.dart`)
|
||||
@@ -40,6 +40,7 @@ A POS (Point of Sale) application for business owners, built with Flutter. The p
|
||||
|
||||
- Flutter SDK installed as per the official guide (`https://flutter.dev/docs/get-started/install`)
|
||||
- Dart version per constraint: ^3.8.1
|
||||
- For code generation only: FVM + Flutter 3.41.9 (`dart pub global activate fvm && fvm install 3.41.9`) — see [docs/codegen.md](docs/codegen.md)
|
||||
|
||||
### Installation
|
||||
|
||||
@@ -51,8 +52,16 @@ flutter pub get
|
||||
|
||||
### Code generation (required after clone or when annotations change)
|
||||
|
||||
```bash
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
> **Do not run codegen with Flutter 3.47 / Dart 3.13** — every builder crashes with
|
||||
> `Missing implementation of visitDotShorthandPropertyAccess`. Codegen must run on Flutter 3.41.9
|
||||
> (Dart 3.11.5) via FVM. Full setup, commands, and troubleshooting: **[docs/codegen.md](docs/codegen.md)**.
|
||||
|
||||
```powershell
|
||||
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"
|
||||
|
||||
& "$FVM\flutter.bat" pub get
|
||||
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
flutter pub get # restore lockfile resolution for the global SDK
|
||||
```
|
||||
|
||||
> Re-run whenever you change files using `@RoutePage()`, `@injectable`, `@freezed`, or `@JsonSerializable`.
|
||||
@@ -179,14 +188,27 @@ Refer to `pubspec.yaml` for full version constraints.
|
||||
|
||||
## Code Generation
|
||||
|
||||
**Full guide: [docs/codegen.md](docs/codegen.md)** — read it before your first codegen run.
|
||||
|
||||
Codegen runs on a pinned SDK (Flutter 3.41.9 / Dart 3.11.5 via FVM), not on the global Flutter 3.47:
|
||||
`freezed 2.5.8` caps `analyzer` below 8.0.0, and analyzer 7.7.1 crashes on the dot-shorthand syntax
|
||||
used by Dart 3.13 sources. The app itself still runs and builds with the global SDK.
|
||||
|
||||
Common commands:
|
||||
|
||||
```bash
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
```powershell
|
||||
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"
|
||||
|
||||
& "$FVM\flutter.bat" pub get
|
||||
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
# or watch
|
||||
flutter pub run build_runner watch --delete-conflicting-outputs
|
||||
& "$FVM\dart.bat" run build_runner watch --delete-conflicting-outputs
|
||||
flutter pub get # restore lockfile resolution for the global SDK
|
||||
```
|
||||
|
||||
> `--delete-conflicting-outputs` wipes every generated file first. If you cancel the build midway,
|
||||
> restore them with `git checkout` — see the troubleshooting table in [docs/codegen.md](docs/codegen.md).
|
||||
|
||||
### Asset generation (flutter_gen_runner)
|
||||
|
||||
`flutter_gen_runner` is integrated with `build_runner`. Running the commands above will also generate typed accessors for assets based on the `flutter_gen` section in `pubspec.yaml`:
|
||||
@@ -255,15 +277,20 @@ flutter pub get
|
||||
flutter format .
|
||||
flutter analyze
|
||||
|
||||
# Code generation (single run / watch)
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
flutter pub run build_runner watch --delete-conflicting-outputs
|
||||
# Localization (safe on the global SDK)
|
||||
flutter gen-l10n
|
||||
|
||||
# Run by device
|
||||
flutter devices
|
||||
flutter run -d <device-id>
|
||||
```
|
||||
|
||||
Code generation uses the pinned FVM SDK — see [docs/codegen.md](docs/codegen.md):
|
||||
|
||||
```powershell
|
||||
& "$env:USERPROFILE\fvm\versions\3.41.9\bin\dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Additional Notes
|
||||
@@ -316,7 +343,7 @@ Aplikasi Point of Sale (POS) untuk pemilik usaha, dibangun dengan Flutter. Proye
|
||||
- Arsitektur & Alur
|
||||
- Struktur Proyek
|
||||
- Dependensi Utama & Fungsinya
|
||||
- Code Generation
|
||||
- Code Generation (lihat docs/codegen.md)
|
||||
- Internationalization (i18n)
|
||||
- Theming & Assets
|
||||
- Konfigurasi Lingkungan (`env.dart`)
|
||||
@@ -344,6 +371,7 @@ Aplikasi Point of Sale (POS) untuk pemilik usaha, dibangun dengan Flutter. Proye
|
||||
|
||||
- Flutter SDK terpasang sesuai panduan resmi (`https://flutter.dev/docs/get-started/install`)
|
||||
- Versi Dart sesuai constraint: ^3.8.1
|
||||
- Khusus untuk code generation: FVM + Flutter 3.41.9 (`dart pub global activate fvm && fvm install 3.41.9`) — lihat [docs/codegen.md](docs/codegen.md)
|
||||
|
||||
### Instalasi
|
||||
|
||||
@@ -355,8 +383,16 @@ flutter pub get
|
||||
|
||||
### Generate kode (wajib setelah clone atau mengubah anotasi)
|
||||
|
||||
```bash
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
> **Jangan jalankan codegen dengan Flutter 3.47 / Dart 3.13** — semua builder crash dengan
|
||||
> `Missing implementation of visitDotShorthandPropertyAccess`. Codegen harus memakai Flutter 3.41.9
|
||||
> (Dart 3.11.5) via FVM. Setup, perintah, dan troubleshooting lengkap: **[docs/codegen.md](docs/codegen.md)**.
|
||||
|
||||
```powershell
|
||||
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"
|
||||
|
||||
& "$FVM\flutter.bat" pub get
|
||||
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
flutter pub get # kembalikan resolusi lockfile ke SDK global
|
||||
```
|
||||
|
||||
> Jalankan ulang perintah di atas setiap kali Anda mengubah file yang menggunakan anotasi `@RoutePage()`, `@injectable`, `@freezed`, atau `@JsonSerializable`.
|
||||
@@ -472,14 +508,27 @@ Catatan versi lengkap tersedia di `pubspec.yaml`.
|
||||
|
||||
## Code Generation
|
||||
|
||||
**Panduan lengkap: [docs/codegen.md](docs/codegen.md)** — baca dulu sebelum codegen pertama kali.
|
||||
|
||||
Codegen dijalankan dengan SDK terpisah (Flutter 3.41.9 / Dart 3.11.5 via FVM), bukan Flutter global 3.47:
|
||||
`freezed 2.5.8` mengunci `analyzer` di bawah 8.0.0, dan analyzer 7.7.1 crash pada sintaks *dot-shorthand*
|
||||
milik Dart 3.13. Aplikasinya sendiri tetap di-`run`/`build` dengan SDK global.
|
||||
|
||||
Perintah umum:
|
||||
|
||||
```bash
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
```powershell
|
||||
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"
|
||||
|
||||
& "$FVM\flutter.bat" pub get
|
||||
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
# atau untuk watch
|
||||
flutter pub run build_runner watch --delete-conflicting-outputs
|
||||
& "$FVM\dart.bat" run build_runner watch --delete-conflicting-outputs
|
||||
flutter pub get # kembalikan resolusi lockfile ke SDK global
|
||||
```
|
||||
|
||||
> `--delete-conflicting-outputs` menghapus semua file generated lebih dulu. Kalau build dibatalkan di
|
||||
> tengah jalan, pulihkan dengan `git checkout` — lihat tabel troubleshooting di [docs/codegen.md](docs/codegen.md).
|
||||
|
||||
Generator yang digunakan:
|
||||
|
||||
- AutoRoute: menghasilkan deklarasi router & route.
|
||||
@@ -533,15 +582,20 @@ flutter pub get
|
||||
flutter format .
|
||||
flutter analyze
|
||||
|
||||
# Code generation (sekali jalan / watch)
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
flutter pub run build_runner watch --delete-conflicting-outputs
|
||||
# Localization (aman dengan SDK global)
|
||||
flutter gen-l10n
|
||||
|
||||
# Run by device
|
||||
flutter devices
|
||||
flutter run -d <device-id>
|
||||
```
|
||||
|
||||
Code generation memakai SDK FVM yang di-pin — lihat [docs/codegen.md](docs/codegen.md):
|
||||
|
||||
```powershell
|
||||
& "$env:USERPROFILE\fvm\versions\3.41.9\bin\dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Catatan Tambahan
|
||||
|
||||
@@ -19,3 +19,10 @@ analyzer:
|
||||
- test/generated/**
|
||||
- "**/**.g.dart"
|
||||
- "**/**.freezed.dart"
|
||||
- build/**
|
||||
- android/**
|
||||
- ios/**
|
||||
- web/**
|
||||
- windows/**
|
||||
- macos/**
|
||||
- linux/**
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
|
||||
|
||||
@@ -18,8 +18,8 @@ pluginManagement {
|
||||
|
||||
plugins {
|
||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||
id("com.android.application") version "8.7.3" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
|
||||
id("com.android.application") version "8.11.1" apply false
|
||||
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
|
||||
id("com.google.gms.google-services") version "4.4.2" apply false
|
||||
}
|
||||
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
# Code Generation (build_runner)
|
||||
|
||||
> **PENTING:** `build_runner` di proyek ini **tidak bisa** dijalankan dengan Flutter 3.47 / Dart 3.13.
|
||||
> Gunakan SDK Flutter 3.41.9 (Dart 3.11.5) lewat FVM. Aplikasinya sendiri tetap di-`run`/`build`
|
||||
> dengan Flutter versi global (3.47).
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
PowerShell (Windows):
|
||||
|
||||
```powershell
|
||||
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"
|
||||
|
||||
& "$FVM\flutter.bat" pub get # 1. resolve paket dgn Dart 3.11.5
|
||||
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs # 2. generate
|
||||
flutter pub get # 3. balik ke SDK global 3.47
|
||||
```
|
||||
|
||||
Git Bash:
|
||||
|
||||
```bash
|
||||
FVM=~/fvm/versions/3.41.9/bin
|
||||
|
||||
"$FVM/flutter.bat" pub get
|
||||
"$FVM/dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
Durasi normal: **±90–120 detik** untuk full build (146 output).
|
||||
|
||||
Setelah itu jalankan `flutter analyze` untuk memastikan hasil generate bersih.
|
||||
|
||||
---
|
||||
|
||||
## Kenapa harus SDK terpisah?
|
||||
|
||||
Kalau codegen dijalankan dengan Flutter global (3.47 / Dart 3.13), semua builder gagal dengan:
|
||||
|
||||
```
|
||||
W SDK language version 3.13.0 is newer than `analyzer` language version 3.9.0.
|
||||
E freezed on lib/application/.../category_analytic_loader_bloc.dart:
|
||||
Exception: Missing implementation of visitDotShorthandPropertyAccess
|
||||
```
|
||||
|
||||
Rantai penyebabnya:
|
||||
|
||||
1. `freezed 2.5.8` membatasi `analyzer <8.0.0`, jadi pub me-resolve ke **analyzer 7.7.1** (language version 3.9).
|
||||
2. Dart 3.13 memakai sintaks *dot-shorthand* (`.value`) di sumber SDK/framework.
|
||||
3. Analyzer 7.7.1 bisa mem-*parse*-nya tapi belum bisa menuliskannya ke summary → crash saat resolve.
|
||||
4. Semua generator (`freezed`, `json_serializable`, `injectable_generator`, `auto_route_generator`) berbagi analyzer yang sama, jadi semuanya ikut mati — termasuk saat men-generate file lama yang tidak diubah.
|
||||
|
||||
Dart 3.11.5 (Flutter 3.41.9) adalah versi tertinggi yang **masih cocok dengan analyzer 7.7.1** sekaligus memenuhi batas `pubspec.lock` (`dart >=3.11.0-0`).
|
||||
|
||||
---
|
||||
|
||||
## Setup sekali di mesin baru
|
||||
|
||||
```powershell
|
||||
dart pub global activate fvm
|
||||
```
|
||||
|
||||
Tambahkan folder binari pub ke PATH agar perintah `fvm` dikenali:
|
||||
`%LOCALAPPDATA%\Pub\Cache\bin`
|
||||
|
||||
Lalu unduh SDK-nya (±1 GB, sekali saja):
|
||||
|
||||
```powershell
|
||||
fvm install 3.41.9
|
||||
fvm list # verifikasi
|
||||
```
|
||||
|
||||
SDK tersimpan di `%USERPROFILE%\fvm\versions\3.41.9` dan **tidak** mengubah Flutter global.
|
||||
|
||||
> Kita sengaja **tidak** menjalankan `fvm use`, supaya repo tidak punya `.fvmrc`/`.fvm/`
|
||||
> dan IDE tetap memakai Flutter 3.47 untuk menjalankan aplikasi.
|
||||
> Kalau lebih suka pin per-project, jalankan `fvm use 3.41.9` lalu pakai `fvm dart run build_runner ...`,
|
||||
> dan tambahkan `.fvm/` ke `.gitignore`.
|
||||
|
||||
---
|
||||
|
||||
## Perintah harian
|
||||
|
||||
Semua contoh memakai variabel `$FVM` dari bagian TL;DR.
|
||||
|
||||
```powershell
|
||||
# build sekali (paling sering dipakai)
|
||||
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
|
||||
|
||||
# mode watch saat banyak mengubah anotasi
|
||||
& "$FVM\dart.bat" run build_runner watch --delete-conflicting-outputs
|
||||
|
||||
# hanya membersihkan output generated
|
||||
& "$FVM\dart.bat" run build_runner clean
|
||||
```
|
||||
|
||||
Wajib generate ulang setiap kali mengubah/menambah file dengan anotasi:
|
||||
|
||||
| Anotasi | Generator | Output |
|
||||
| --- | --- | --- |
|
||||
| `@freezed` | freezed | `*.freezed.dart` |
|
||||
| `@JsonSerializable` / `fromJson` di DTO | json_serializable | `*.g.dart` |
|
||||
| `@injectable`, `@LazySingleton` | injectable_generator | `lib/injection.config.dart` |
|
||||
| `@RoutePage()` | auto_route_generator | `lib/presentation/router/app_router.gr.dart` |
|
||||
| asset baru di `assets/` | flutter_gen_runner | `lib/presentation/components/assets/assets.gen.dart` |
|
||||
|
||||
### Localization (i18n) — tidak lewat build_runner
|
||||
|
||||
`flutter gen-l10n` memakai tooling Flutter, bukan analyzer, jadi **aman dijalankan dengan Flutter 3.47**:
|
||||
|
||||
```powershell
|
||||
flutter gen-l10n
|
||||
```
|
||||
|
||||
Jalankan setiap kali `lib/l10n/app_id.arb` / `app_en.arb` berubah. Hasilnya: `lib/l10n/app_localizations*.dart`.
|
||||
|
||||
---
|
||||
|
||||
## Aturan penting soal `--delete-conflicting-outputs`
|
||||
|
||||
Flag ini **menghapus dulu** semua file generated (±55 file `*.freezed.dart` / `*.g.dart`) sebelum membuat ulang.
|
||||
Kalau proses dibatalkan di tengah jalan, project akan penuh error karena file-nya sudah hilang.
|
||||
|
||||
Pemulihan (semua file generated ikut ter-commit di git):
|
||||
|
||||
```bash
|
||||
git status --porcelain | grep -E "^ D" | sed 's/^ D //' | while read -r f; do git checkout -- "$f"; done
|
||||
```
|
||||
|
||||
Tips: jangan pipe output build ke `tail`/`head` — outputnya jadi ter-buffer sampai proses selesai,
|
||||
sehingga terlihat seperti *hang* padahal sedang jalan.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Gejala | Penyebab | Solusi |
|
||||
| --- | --- | --- |
|
||||
| `Missing implementation of visitDotShorthandPropertyAccess` | codegen dijalankan dengan Flutter global 3.47 | pakai SDK FVM 3.41.9 |
|
||||
| `Failed to update packages` + dump stack VM | `flutter pub run build_runner` / `fvm spawn ... pub run` | pakai `dart.bat run build_runner`, jangan `flutter pub run` |
|
||||
| Ratusan error “isn't defined” di IDE, file `*.freezed.dart` hilang | build dibatalkan setelah `--delete-conflicting-outputs` | restore lewat `git checkout` (lihat di atas) |
|
||||
| `pub get` gagal / versi paket bergeser | `pubspec.lock` di-resolve oleh SDK berbeda | jalankan `flutter pub get` dengan SDK global setelah codegen selesai |
|
||||
| Build terasa lama di run pertama | asset graph baru dibuat dari nol | wajar, ±90–120 detik; run berikutnya inkremental |
|
||||
|
||||
---
|
||||
|
||||
## Rencana jangka panjang
|
||||
|
||||
Perbaikan permanen = upgrade toolchain codegen supaya jalan native di Dart 3.13:
|
||||
|
||||
- `freezed` 2.5.8 → 3.x, `freezed_annotation` 2.4.x → 3.x
|
||||
- `injectable` 2.x → 3.x, `injectable_generator` 2.7 → 3.x
|
||||
- `auto_route` 9.x → 11.x, `auto_route_generator` 9.x → 10.x
|
||||
- `build_runner` → 2.16.x, `json_serializable` → 6.14.x (analyzer ikut naik ke 13.x)
|
||||
|
||||
Konsekuensinya breaking dan cukup besar, jadi perlu dijadwalkan sendiri:
|
||||
|
||||
- freezed 3 **menghapus** `.map()` / `.when()` / `.maybeWhen()` / `.maybeMap()` → ±49 pemakaian (mayoritas di handler event BLoC) harus diganti pattern matching Dart 3 (`switch`).
|
||||
- ±98 file dengan `@freezed` harus dideklarasikan `abstract class` atau `sealed class`.
|
||||
- Migrasi konfigurasi router (auto_route 11) dan DI (injectable 3).
|
||||
|
||||
Selama migrasi itu belum dikerjakan, gunakan alur FVM di dokumen ini.
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
|
||||
import '../../../domain/analytic/analytic.dart';
|
||||
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
|
||||
|
||||
part 'profit_sharing_detail_loader_event.dart';
|
||||
part 'profit_sharing_detail_loader_state.dart';
|
||||
part 'profit_sharing_detail_loader_bloc.freezed.dart';
|
||||
|
||||
@injectable
|
||||
class ProfitSharingDetailLoaderBloc
|
||||
extends
|
||||
Bloc<ProfitSharingDetailLoaderEvent, ProfitSharingDetailLoaderState> {
|
||||
final IAnalyticRepository _repository;
|
||||
|
||||
ProfitSharingDetailLoaderBloc(this._repository)
|
||||
: super(ProfitSharingDetailLoaderState.initial()) {
|
||||
on<ProfitSharingDetailLoaderEvent>(_onProfitSharingDetailLoaderEvent);
|
||||
}
|
||||
|
||||
Future<void> _onProfitSharingDetailLoaderEvent(
|
||||
ProfitSharingDetailLoaderEvent event,
|
||||
Emitter<ProfitSharingDetailLoaderState> emit,
|
||||
) {
|
||||
return event.map(
|
||||
expandedCategoryChanged: (e) async {
|
||||
final isSame = state.expandedCategoryId == e.categoryId;
|
||||
emit(state.copyWith(expandedCategoryId: isSame ? '' : e.categoryId));
|
||||
},
|
||||
fetched: (e) async {
|
||||
emit(
|
||||
state.copyWith(
|
||||
isFetching: true,
|
||||
failureOption: none(),
|
||||
parentCategoryId: e.parentCategoryId,
|
||||
dateFrom: e.dateFrom,
|
||||
dateTo: e.dateTo,
|
||||
),
|
||||
);
|
||||
|
||||
final result = await _repository.getProfitSharingDetail(
|
||||
parentCategoryId: e.parentCategoryId,
|
||||
dateFrom: e.dateFrom,
|
||||
dateTo: e.dateTo,
|
||||
);
|
||||
|
||||
final newState = result.fold(
|
||||
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||
(detail) => state.copyWith(
|
||||
detail: detail,
|
||||
// Sub kategori pertama langsung terbuka supaya produknya kelihatan.
|
||||
expandedCategoryId: detail.categories.isEmpty
|
||||
? ''
|
||||
: detail.categories.first.categoryId,
|
||||
),
|
||||
);
|
||||
|
||||
emit(newState.copyWith(isFetching: false));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
+772
@@ -0,0 +1,772 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'profit_sharing_detail_loader_bloc.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
|
||||
);
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ProfitSharingDetailLoaderEvent {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)
|
||||
fetched,
|
||||
required TResult Function(String categoryId) expandedCategoryChanged,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)?
|
||||
fetched,
|
||||
TResult? Function(String categoryId)? expandedCategoryChanged,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)?
|
||||
fetched,
|
||||
TResult Function(String categoryId)? expandedCategoryChanged,
|
||||
required TResult orElse(),
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
required TResult Function(_ExpandedCategoryChanged value)
|
||||
expandedCategoryChanged,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
TResult? Function(_ExpandedCategoryChanged value)? expandedCategoryChanged,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
TResult Function(_ExpandedCategoryChanged value)? expandedCategoryChanged,
|
||||
required TResult orElse(),
|
||||
}) => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ProfitSharingDetailLoaderEventCopyWith<$Res> {
|
||||
factory $ProfitSharingDetailLoaderEventCopyWith(
|
||||
ProfitSharingDetailLoaderEvent value,
|
||||
$Res Function(ProfitSharingDetailLoaderEvent) then,
|
||||
) =
|
||||
_$ProfitSharingDetailLoaderEventCopyWithImpl<
|
||||
$Res,
|
||||
ProfitSharingDetailLoaderEvent
|
||||
>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ProfitSharingDetailLoaderEventCopyWithImpl<
|
||||
$Res,
|
||||
$Val extends ProfitSharingDetailLoaderEvent
|
||||
>
|
||||
implements $ProfitSharingDetailLoaderEventCopyWith<$Res> {
|
||||
_$ProfitSharingDetailLoaderEventCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$FetchedImplCopyWith<$Res> {
|
||||
factory _$$FetchedImplCopyWith(
|
||||
_$FetchedImpl value,
|
||||
$Res Function(_$FetchedImpl) then,
|
||||
) = __$$FetchedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({String parentCategoryId, DateTime dateFrom, DateTime dateTo});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$FetchedImplCopyWithImpl<$Res>
|
||||
extends _$ProfitSharingDetailLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
||||
implements _$$FetchedImplCopyWith<$Res> {
|
||||
__$$FetchedImplCopyWithImpl(
|
||||
_$FetchedImpl _value,
|
||||
$Res Function(_$FetchedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? parentCategoryId = null,
|
||||
Object? dateFrom = null,
|
||||
Object? dateTo = null,
|
||||
}) {
|
||||
return _then(
|
||||
_$FetchedImpl(
|
||||
parentCategoryId: null == parentCategoryId
|
||||
? _value.parentCategoryId
|
||||
: parentCategoryId // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
dateFrom: null == dateFrom
|
||||
? _value.dateFrom
|
||||
: dateFrom // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
dateTo: null == dateTo
|
||||
? _value.dateTo
|
||||
: dateTo // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$FetchedImpl implements _Fetched {
|
||||
const _$FetchedImpl({
|
||||
required this.parentCategoryId,
|
||||
required this.dateFrom,
|
||||
required this.dateTo,
|
||||
});
|
||||
|
||||
@override
|
||||
final String parentCategoryId;
|
||||
@override
|
||||
final DateTime dateFrom;
|
||||
@override
|
||||
final DateTime dateTo;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingDetailLoaderEvent.fetched(parentCategoryId: $parentCategoryId, dateFrom: $dateFrom, dateTo: $dateTo)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$FetchedImpl &&
|
||||
(identical(other.parentCategoryId, parentCategoryId) ||
|
||||
other.parentCategoryId == parentCategoryId) &&
|
||||
(identical(other.dateFrom, dateFrom) ||
|
||||
other.dateFrom == dateFrom) &&
|
||||
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
Object.hash(runtimeType, parentCategoryId, dateFrom, dateTo);
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$FetchedImplCopyWith<_$FetchedImpl> get copyWith =>
|
||||
__$$FetchedImplCopyWithImpl<_$FetchedImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)
|
||||
fetched,
|
||||
required TResult Function(String categoryId) expandedCategoryChanged,
|
||||
}) {
|
||||
return fetched(parentCategoryId, dateFrom, dateTo);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)?
|
||||
fetched,
|
||||
TResult? Function(String categoryId)? expandedCategoryChanged,
|
||||
}) {
|
||||
return fetched?.call(parentCategoryId, dateFrom, dateTo);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)?
|
||||
fetched,
|
||||
TResult Function(String categoryId)? expandedCategoryChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (fetched != null) {
|
||||
return fetched(parentCategoryId, dateFrom, dateTo);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
required TResult Function(_ExpandedCategoryChanged value)
|
||||
expandedCategoryChanged,
|
||||
}) {
|
||||
return fetched(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
TResult? Function(_ExpandedCategoryChanged value)? expandedCategoryChanged,
|
||||
}) {
|
||||
return fetched?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
TResult Function(_ExpandedCategoryChanged value)? expandedCategoryChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (fetched != null) {
|
||||
return fetched(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _Fetched implements ProfitSharingDetailLoaderEvent {
|
||||
const factory _Fetched({
|
||||
required final String parentCategoryId,
|
||||
required final DateTime dateFrom,
|
||||
required final DateTime dateTo,
|
||||
}) = _$FetchedImpl;
|
||||
|
||||
String get parentCategoryId;
|
||||
DateTime get dateFrom;
|
||||
DateTime get dateTo;
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$FetchedImplCopyWith<_$FetchedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ExpandedCategoryChangedImplCopyWith<$Res> {
|
||||
factory _$$ExpandedCategoryChangedImplCopyWith(
|
||||
_$ExpandedCategoryChangedImpl value,
|
||||
$Res Function(_$ExpandedCategoryChangedImpl) then,
|
||||
) = __$$ExpandedCategoryChangedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({String categoryId});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ExpandedCategoryChangedImplCopyWithImpl<$Res>
|
||||
extends
|
||||
_$ProfitSharingDetailLoaderEventCopyWithImpl<
|
||||
$Res,
|
||||
_$ExpandedCategoryChangedImpl
|
||||
>
|
||||
implements _$$ExpandedCategoryChangedImplCopyWith<$Res> {
|
||||
__$$ExpandedCategoryChangedImplCopyWithImpl(
|
||||
_$ExpandedCategoryChangedImpl _value,
|
||||
$Res Function(_$ExpandedCategoryChangedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({Object? categoryId = null}) {
|
||||
return _then(
|
||||
_$ExpandedCategoryChangedImpl(
|
||||
null == categoryId
|
||||
? _value.categoryId
|
||||
: categoryId // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$ExpandedCategoryChangedImpl implements _ExpandedCategoryChanged {
|
||||
const _$ExpandedCategoryChangedImpl(this.categoryId);
|
||||
|
||||
@override
|
||||
final String categoryId;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingDetailLoaderEvent.expandedCategoryChanged(categoryId: $categoryId)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ExpandedCategoryChangedImpl &&
|
||||
(identical(other.categoryId, categoryId) ||
|
||||
other.categoryId == categoryId));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, categoryId);
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ExpandedCategoryChangedImplCopyWith<_$ExpandedCategoryChangedImpl>
|
||||
get copyWith =>
|
||||
__$$ExpandedCategoryChangedImplCopyWithImpl<
|
||||
_$ExpandedCategoryChangedImpl
|
||||
>(this, _$identity);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)
|
||||
fetched,
|
||||
required TResult Function(String categoryId) expandedCategoryChanged,
|
||||
}) {
|
||||
return expandedCategoryChanged(categoryId);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)?
|
||||
fetched,
|
||||
TResult? Function(String categoryId)? expandedCategoryChanged,
|
||||
}) {
|
||||
return expandedCategoryChanged?.call(categoryId);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(
|
||||
String parentCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
)?
|
||||
fetched,
|
||||
TResult Function(String categoryId)? expandedCategoryChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (expandedCategoryChanged != null) {
|
||||
return expandedCategoryChanged(categoryId);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
required TResult Function(_ExpandedCategoryChanged value)
|
||||
expandedCategoryChanged,
|
||||
}) {
|
||||
return expandedCategoryChanged(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
TResult? Function(_ExpandedCategoryChanged value)? expandedCategoryChanged,
|
||||
}) {
|
||||
return expandedCategoryChanged?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
TResult Function(_ExpandedCategoryChanged value)? expandedCategoryChanged,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (expandedCategoryChanged != null) {
|
||||
return expandedCategoryChanged(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _ExpandedCategoryChanged
|
||||
implements ProfitSharingDetailLoaderEvent {
|
||||
const factory _ExpandedCategoryChanged(final String categoryId) =
|
||||
_$ExpandedCategoryChangedImpl;
|
||||
|
||||
String get categoryId;
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ExpandedCategoryChangedImplCopyWith<_$ExpandedCategoryChangedImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ProfitSharingDetailLoaderState {
|
||||
ProfitSharingDetail get detail => throw _privateConstructorUsedError;
|
||||
Option<AnalyticFailure> get failureOption =>
|
||||
throw _privateConstructorUsedError;
|
||||
bool get isFetching => throw _privateConstructorUsedError;
|
||||
String get parentCategoryId => throw _privateConstructorUsedError;
|
||||
String get expandedCategoryId => throw _privateConstructorUsedError;
|
||||
DateTime get dateFrom => throw _privateConstructorUsedError;
|
||||
DateTime get dateTo => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$ProfitSharingDetailLoaderStateCopyWith<ProfitSharingDetailLoaderState>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ProfitSharingDetailLoaderStateCopyWith<$Res> {
|
||||
factory $ProfitSharingDetailLoaderStateCopyWith(
|
||||
ProfitSharingDetailLoaderState value,
|
||||
$Res Function(ProfitSharingDetailLoaderState) then,
|
||||
) =
|
||||
_$ProfitSharingDetailLoaderStateCopyWithImpl<
|
||||
$Res,
|
||||
ProfitSharingDetailLoaderState
|
||||
>;
|
||||
@useResult
|
||||
$Res call({
|
||||
ProfitSharingDetail detail,
|
||||
Option<AnalyticFailure> failureOption,
|
||||
bool isFetching,
|
||||
String parentCategoryId,
|
||||
String expandedCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
});
|
||||
|
||||
$ProfitSharingDetailCopyWith<$Res> get detail;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ProfitSharingDetailLoaderStateCopyWithImpl<
|
||||
$Res,
|
||||
$Val extends ProfitSharingDetailLoaderState
|
||||
>
|
||||
implements $ProfitSharingDetailLoaderStateCopyWith<$Res> {
|
||||
_$ProfitSharingDetailLoaderStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? detail = null,
|
||||
Object? failureOption = null,
|
||||
Object? isFetching = null,
|
||||
Object? parentCategoryId = null,
|
||||
Object? expandedCategoryId = null,
|
||||
Object? dateFrom = null,
|
||||
Object? dateTo = null,
|
||||
}) {
|
||||
return _then(
|
||||
_value.copyWith(
|
||||
detail: null == detail
|
||||
? _value.detail
|
||||
: detail // ignore: cast_nullable_to_non_nullable
|
||||
as ProfitSharingDetail,
|
||||
failureOption: null == failureOption
|
||||
? _value.failureOption
|
||||
: failureOption // ignore: cast_nullable_to_non_nullable
|
||||
as Option<AnalyticFailure>,
|
||||
isFetching: null == isFetching
|
||||
? _value.isFetching
|
||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
parentCategoryId: null == parentCategoryId
|
||||
? _value.parentCategoryId
|
||||
: parentCategoryId // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
expandedCategoryId: null == expandedCategoryId
|
||||
? _value.expandedCategoryId
|
||||
: expandedCategoryId // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
dateFrom: null == dateFrom
|
||||
? _value.dateFrom
|
||||
: dateFrom // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
dateTo: null == dateTo
|
||||
? _value.dateTo
|
||||
: dateTo // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
)
|
||||
as $Val,
|
||||
);
|
||||
}
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ProfitSharingDetailCopyWith<$Res> get detail {
|
||||
return $ProfitSharingDetailCopyWith<$Res>(_value.detail, (value) {
|
||||
return _then(_value.copyWith(detail: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ProfitSharingDetailLoaderStateImplCopyWith<$Res>
|
||||
implements $ProfitSharingDetailLoaderStateCopyWith<$Res> {
|
||||
factory _$$ProfitSharingDetailLoaderStateImplCopyWith(
|
||||
_$ProfitSharingDetailLoaderStateImpl value,
|
||||
$Res Function(_$ProfitSharingDetailLoaderStateImpl) then,
|
||||
) = __$$ProfitSharingDetailLoaderStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({
|
||||
ProfitSharingDetail detail,
|
||||
Option<AnalyticFailure> failureOption,
|
||||
bool isFetching,
|
||||
String parentCategoryId,
|
||||
String expandedCategoryId,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
});
|
||||
|
||||
@override
|
||||
$ProfitSharingDetailCopyWith<$Res> get detail;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ProfitSharingDetailLoaderStateImplCopyWithImpl<$Res>
|
||||
extends
|
||||
_$ProfitSharingDetailLoaderStateCopyWithImpl<
|
||||
$Res,
|
||||
_$ProfitSharingDetailLoaderStateImpl
|
||||
>
|
||||
implements _$$ProfitSharingDetailLoaderStateImplCopyWith<$Res> {
|
||||
__$$ProfitSharingDetailLoaderStateImplCopyWithImpl(
|
||||
_$ProfitSharingDetailLoaderStateImpl _value,
|
||||
$Res Function(_$ProfitSharingDetailLoaderStateImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? detail = null,
|
||||
Object? failureOption = null,
|
||||
Object? isFetching = null,
|
||||
Object? parentCategoryId = null,
|
||||
Object? expandedCategoryId = null,
|
||||
Object? dateFrom = null,
|
||||
Object? dateTo = null,
|
||||
}) {
|
||||
return _then(
|
||||
_$ProfitSharingDetailLoaderStateImpl(
|
||||
detail: null == detail
|
||||
? _value.detail
|
||||
: detail // ignore: cast_nullable_to_non_nullable
|
||||
as ProfitSharingDetail,
|
||||
failureOption: null == failureOption
|
||||
? _value.failureOption
|
||||
: failureOption // ignore: cast_nullable_to_non_nullable
|
||||
as Option<AnalyticFailure>,
|
||||
isFetching: null == isFetching
|
||||
? _value.isFetching
|
||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
parentCategoryId: null == parentCategoryId
|
||||
? _value.parentCategoryId
|
||||
: parentCategoryId // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
expandedCategoryId: null == expandedCategoryId
|
||||
? _value.expandedCategoryId
|
||||
: expandedCategoryId // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
dateFrom: null == dateFrom
|
||||
? _value.dateFrom
|
||||
: dateFrom // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
dateTo: null == dateTo
|
||||
? _value.dateTo
|
||||
: dateTo // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$ProfitSharingDetailLoaderStateImpl
|
||||
extends _ProfitSharingDetailLoaderState {
|
||||
const _$ProfitSharingDetailLoaderStateImpl({
|
||||
required this.detail,
|
||||
required this.failureOption,
|
||||
this.isFetching = false,
|
||||
this.parentCategoryId = '',
|
||||
this.expandedCategoryId = '',
|
||||
required this.dateFrom,
|
||||
required this.dateTo,
|
||||
}) : super._();
|
||||
|
||||
@override
|
||||
final ProfitSharingDetail detail;
|
||||
@override
|
||||
final Option<AnalyticFailure> failureOption;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isFetching;
|
||||
@override
|
||||
@JsonKey()
|
||||
final String parentCategoryId;
|
||||
@override
|
||||
@JsonKey()
|
||||
final String expandedCategoryId;
|
||||
@override
|
||||
final DateTime dateFrom;
|
||||
@override
|
||||
final DateTime dateTo;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingDetailLoaderState(detail: $detail, failureOption: $failureOption, isFetching: $isFetching, parentCategoryId: $parentCategoryId, expandedCategoryId: $expandedCategoryId, dateFrom: $dateFrom, dateTo: $dateTo)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ProfitSharingDetailLoaderStateImpl &&
|
||||
(identical(other.detail, detail) || other.detail == detail) &&
|
||||
(identical(other.failureOption, failureOption) ||
|
||||
other.failureOption == failureOption) &&
|
||||
(identical(other.isFetching, isFetching) ||
|
||||
other.isFetching == isFetching) &&
|
||||
(identical(other.parentCategoryId, parentCategoryId) ||
|
||||
other.parentCategoryId == parentCategoryId) &&
|
||||
(identical(other.expandedCategoryId, expandedCategoryId) ||
|
||||
other.expandedCategoryId == expandedCategoryId) &&
|
||||
(identical(other.dateFrom, dateFrom) ||
|
||||
other.dateFrom == dateFrom) &&
|
||||
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
detail,
|
||||
failureOption,
|
||||
isFetching,
|
||||
parentCategoryId,
|
||||
expandedCategoryId,
|
||||
dateFrom,
|
||||
dateTo,
|
||||
);
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ProfitSharingDetailLoaderStateImplCopyWith<
|
||||
_$ProfitSharingDetailLoaderStateImpl
|
||||
>
|
||||
get copyWith =>
|
||||
__$$ProfitSharingDetailLoaderStateImplCopyWithImpl<
|
||||
_$ProfitSharingDetailLoaderStateImpl
|
||||
>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _ProfitSharingDetailLoaderState
|
||||
extends ProfitSharingDetailLoaderState {
|
||||
const factory _ProfitSharingDetailLoaderState({
|
||||
required final ProfitSharingDetail detail,
|
||||
required final Option<AnalyticFailure> failureOption,
|
||||
final bool isFetching,
|
||||
final String parentCategoryId,
|
||||
final String expandedCategoryId,
|
||||
required final DateTime dateFrom,
|
||||
required final DateTime dateTo,
|
||||
}) = _$ProfitSharingDetailLoaderStateImpl;
|
||||
const _ProfitSharingDetailLoaderState._() : super._();
|
||||
|
||||
@override
|
||||
ProfitSharingDetail get detail;
|
||||
@override
|
||||
Option<AnalyticFailure> get failureOption;
|
||||
@override
|
||||
bool get isFetching;
|
||||
@override
|
||||
String get parentCategoryId;
|
||||
@override
|
||||
String get expandedCategoryId;
|
||||
@override
|
||||
DateTime get dateFrom;
|
||||
@override
|
||||
DateTime get dateTo;
|
||||
|
||||
/// Create a copy of ProfitSharingDetailLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ProfitSharingDetailLoaderStateImplCopyWith<
|
||||
_$ProfitSharingDetailLoaderStateImpl
|
||||
>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
part of 'profit_sharing_detail_loader_bloc.dart';
|
||||
|
||||
@freezed
|
||||
class ProfitSharingDetailLoaderEvent with _$ProfitSharingDetailLoaderEvent {
|
||||
const factory ProfitSharingDetailLoaderEvent.fetched({
|
||||
required String parentCategoryId,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
}) = _Fetched;
|
||||
|
||||
/// Buka/tutup daftar produk pada satu sub kategori.
|
||||
const factory ProfitSharingDetailLoaderEvent.expandedCategoryChanged(
|
||||
String categoryId,
|
||||
) = _ExpandedCategoryChanged;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
part of 'profit_sharing_detail_loader_bloc.dart';
|
||||
|
||||
@freezed
|
||||
class ProfitSharingDetailLoaderState with _$ProfitSharingDetailLoaderState {
|
||||
const ProfitSharingDetailLoaderState._();
|
||||
|
||||
const factory ProfitSharingDetailLoaderState({
|
||||
required ProfitSharingDetail detail,
|
||||
required Option<AnalyticFailure> failureOption,
|
||||
@Default(false) bool isFetching,
|
||||
@Default('') String parentCategoryId,
|
||||
@Default('') String expandedCategoryId,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
}) = _ProfitSharingDetailLoaderState;
|
||||
|
||||
factory ProfitSharingDetailLoaderState.initial() {
|
||||
final now = DateTime.now();
|
||||
return ProfitSharingDetailLoaderState(
|
||||
detail: ProfitSharingDetail.empty(),
|
||||
failureOption: none(),
|
||||
dateFrom: DateTime(now.year, now.month, 1),
|
||||
dateTo: DateTime(now.year, now.month + 1, 0),
|
||||
);
|
||||
}
|
||||
|
||||
bool isExpanded(String categoryId) => expandedCategoryId == categoryId;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
|
||||
import '../../../domain/analytic/analytic.dart';
|
||||
import '../../../domain/analytic/repositories/i_analytic_repository.dart';
|
||||
|
||||
part 'profit_sharing_loader_event.dart';
|
||||
part 'profit_sharing_loader_state.dart';
|
||||
part 'profit_sharing_loader_bloc.freezed.dart';
|
||||
|
||||
@injectable
|
||||
class ProfitSharingLoaderBloc
|
||||
extends Bloc<ProfitSharingLoaderEvent, ProfitSharingLoaderState> {
|
||||
final IAnalyticRepository _repository;
|
||||
|
||||
ProfitSharingLoaderBloc(this._repository)
|
||||
: super(ProfitSharingLoaderState.initial()) {
|
||||
on<ProfitSharingLoaderEvent>(_onProfitSharingLoaderEvent);
|
||||
}
|
||||
|
||||
Future<void> _onProfitSharingLoaderEvent(
|
||||
ProfitSharingLoaderEvent event,
|
||||
Emitter<ProfitSharingLoaderState> emit,
|
||||
) {
|
||||
return event.map(
|
||||
rangeDateChanged: (e) async {
|
||||
emit(state.copyWith(dateFrom: e.dateFrom, dateTo: e.dateTo));
|
||||
},
|
||||
periodTypeChanged: (e) async {
|
||||
emit(state.copyWith(periodType: e.periodType));
|
||||
},
|
||||
fetched: (e) async {
|
||||
emit(state.copyWith(isFetching: true, failureOption: none()));
|
||||
|
||||
final result = await _repository.getProfitSharing(
|
||||
dateFrom: state.dateFrom,
|
||||
dateTo: state.dateTo,
|
||||
);
|
||||
|
||||
final newState = result.fold(
|
||||
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||
(profitSharing) => state.copyWith(profitSharing: profitSharing),
|
||||
);
|
||||
|
||||
emit(newState.copyWith(isFetching: false));
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
+807
@@ -0,0 +1,807 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'profit_sharing_loader_bloc.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
|
||||
);
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ProfitSharingLoaderEvent {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(DateTime dateFrom, DateTime dateTo)
|
||||
rangeDateChanged,
|
||||
required TResult Function(ProfitSharingPeriodType periodType)
|
||||
periodTypeChanged,
|
||||
required TResult Function() fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult? Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult? Function()? fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult Function()? fetched,
|
||||
required TResult orElse(),
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_RangeDateChanged value) rangeDateChanged,
|
||||
required TResult Function(_PeriodTypeChanged value) periodTypeChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult? Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) => throw _privateConstructorUsedError;
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
required TResult orElse(),
|
||||
}) => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ProfitSharingLoaderEventCopyWith<$Res> {
|
||||
factory $ProfitSharingLoaderEventCopyWith(
|
||||
ProfitSharingLoaderEvent value,
|
||||
$Res Function(ProfitSharingLoaderEvent) then,
|
||||
) = _$ProfitSharingLoaderEventCopyWithImpl<$Res, ProfitSharingLoaderEvent>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ProfitSharingLoaderEventCopyWithImpl<
|
||||
$Res,
|
||||
$Val extends ProfitSharingLoaderEvent
|
||||
>
|
||||
implements $ProfitSharingLoaderEventCopyWith<$Res> {
|
||||
_$ProfitSharingLoaderEventCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$RangeDateChangedImplCopyWith<$Res> {
|
||||
factory _$$RangeDateChangedImplCopyWith(
|
||||
_$RangeDateChangedImpl value,
|
||||
$Res Function(_$RangeDateChangedImpl) then,
|
||||
) = __$$RangeDateChangedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({DateTime dateFrom, DateTime dateTo});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$RangeDateChangedImplCopyWithImpl<$Res>
|
||||
extends _$ProfitSharingLoaderEventCopyWithImpl<$Res, _$RangeDateChangedImpl>
|
||||
implements _$$RangeDateChangedImplCopyWith<$Res> {
|
||||
__$$RangeDateChangedImplCopyWithImpl(
|
||||
_$RangeDateChangedImpl _value,
|
||||
$Res Function(_$RangeDateChangedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({Object? dateFrom = null, Object? dateTo = null}) {
|
||||
return _then(
|
||||
_$RangeDateChangedImpl(
|
||||
null == dateFrom
|
||||
? _value.dateFrom
|
||||
: dateFrom // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
null == dateTo
|
||||
? _value.dateTo
|
||||
: dateTo // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$RangeDateChangedImpl implements _RangeDateChanged {
|
||||
const _$RangeDateChangedImpl(this.dateFrom, this.dateTo);
|
||||
|
||||
@override
|
||||
final DateTime dateFrom;
|
||||
@override
|
||||
final DateTime dateTo;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingLoaderEvent.rangeDateChanged(dateFrom: $dateFrom, dateTo: $dateTo)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$RangeDateChangedImpl &&
|
||||
(identical(other.dateFrom, dateFrom) ||
|
||||
other.dateFrom == dateFrom) &&
|
||||
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, dateFrom, dateTo);
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$RangeDateChangedImplCopyWith<_$RangeDateChangedImpl> get copyWith =>
|
||||
__$$RangeDateChangedImplCopyWithImpl<_$RangeDateChangedImpl>(
|
||||
this,
|
||||
_$identity,
|
||||
);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(DateTime dateFrom, DateTime dateTo)
|
||||
rangeDateChanged,
|
||||
required TResult Function(ProfitSharingPeriodType periodType)
|
||||
periodTypeChanged,
|
||||
required TResult Function() fetched,
|
||||
}) {
|
||||
return rangeDateChanged(dateFrom, dateTo);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult? Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult? Function()? fetched,
|
||||
}) {
|
||||
return rangeDateChanged?.call(dateFrom, dateTo);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult Function()? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (rangeDateChanged != null) {
|
||||
return rangeDateChanged(dateFrom, dateTo);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_RangeDateChanged value) rangeDateChanged,
|
||||
required TResult Function(_PeriodTypeChanged value) periodTypeChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) {
|
||||
return rangeDateChanged(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult? Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) {
|
||||
return rangeDateChanged?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (rangeDateChanged != null) {
|
||||
return rangeDateChanged(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _RangeDateChanged implements ProfitSharingLoaderEvent {
|
||||
const factory _RangeDateChanged(
|
||||
final DateTime dateFrom,
|
||||
final DateTime dateTo,
|
||||
) = _$RangeDateChangedImpl;
|
||||
|
||||
DateTime get dateFrom;
|
||||
DateTime get dateTo;
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$RangeDateChangedImplCopyWith<_$RangeDateChangedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$PeriodTypeChangedImplCopyWith<$Res> {
|
||||
factory _$$PeriodTypeChangedImplCopyWith(
|
||||
_$PeriodTypeChangedImpl value,
|
||||
$Res Function(_$PeriodTypeChangedImpl) then,
|
||||
) = __$$PeriodTypeChangedImplCopyWithImpl<$Res>;
|
||||
@useResult
|
||||
$Res call({ProfitSharingPeriodType periodType});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$PeriodTypeChangedImplCopyWithImpl<$Res>
|
||||
extends
|
||||
_$ProfitSharingLoaderEventCopyWithImpl<$Res, _$PeriodTypeChangedImpl>
|
||||
implements _$$PeriodTypeChangedImplCopyWith<$Res> {
|
||||
__$$PeriodTypeChangedImplCopyWithImpl(
|
||||
_$PeriodTypeChangedImpl _value,
|
||||
$Res Function(_$PeriodTypeChangedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({Object? periodType = null}) {
|
||||
return _then(
|
||||
_$PeriodTypeChangedImpl(
|
||||
null == periodType
|
||||
? _value.periodType
|
||||
: periodType // ignore: cast_nullable_to_non_nullable
|
||||
as ProfitSharingPeriodType,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$PeriodTypeChangedImpl implements _PeriodTypeChanged {
|
||||
const _$PeriodTypeChangedImpl(this.periodType);
|
||||
|
||||
@override
|
||||
final ProfitSharingPeriodType periodType;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingLoaderEvent.periodTypeChanged(periodType: $periodType)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$PeriodTypeChangedImpl &&
|
||||
(identical(other.periodType, periodType) ||
|
||||
other.periodType == periodType));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, periodType);
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$PeriodTypeChangedImplCopyWith<_$PeriodTypeChangedImpl> get copyWith =>
|
||||
__$$PeriodTypeChangedImplCopyWithImpl<_$PeriodTypeChangedImpl>(
|
||||
this,
|
||||
_$identity,
|
||||
);
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(DateTime dateFrom, DateTime dateTo)
|
||||
rangeDateChanged,
|
||||
required TResult Function(ProfitSharingPeriodType periodType)
|
||||
periodTypeChanged,
|
||||
required TResult Function() fetched,
|
||||
}) {
|
||||
return periodTypeChanged(periodType);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult? Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult? Function()? fetched,
|
||||
}) {
|
||||
return periodTypeChanged?.call(periodType);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult Function()? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (periodTypeChanged != null) {
|
||||
return periodTypeChanged(periodType);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_RangeDateChanged value) rangeDateChanged,
|
||||
required TResult Function(_PeriodTypeChanged value) periodTypeChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) {
|
||||
return periodTypeChanged(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult? Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) {
|
||||
return periodTypeChanged?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (periodTypeChanged != null) {
|
||||
return periodTypeChanged(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _PeriodTypeChanged implements ProfitSharingLoaderEvent {
|
||||
const factory _PeriodTypeChanged(final ProfitSharingPeriodType periodType) =
|
||||
_$PeriodTypeChangedImpl;
|
||||
|
||||
ProfitSharingPeriodType get periodType;
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$PeriodTypeChangedImplCopyWith<_$PeriodTypeChangedImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$FetchedImplCopyWith<$Res> {
|
||||
factory _$$FetchedImplCopyWith(
|
||||
_$FetchedImpl value,
|
||||
$Res Function(_$FetchedImpl) then,
|
||||
) = __$$FetchedImplCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$FetchedImplCopyWithImpl<$Res>
|
||||
extends _$ProfitSharingLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
||||
implements _$$FetchedImplCopyWith<$Res> {
|
||||
__$$FetchedImplCopyWithImpl(
|
||||
_$FetchedImpl _value,
|
||||
$Res Function(_$FetchedImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderEvent
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$FetchedImpl implements _Fetched {
|
||||
const _$FetchedImpl();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingLoaderEvent.fetched()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType && other is _$FetchedImpl);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object?>({
|
||||
required TResult Function(DateTime dateFrom, DateTime dateTo)
|
||||
rangeDateChanged,
|
||||
required TResult Function(ProfitSharingPeriodType periodType)
|
||||
periodTypeChanged,
|
||||
required TResult Function() fetched,
|
||||
}) {
|
||||
return fetched();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? whenOrNull<TResult extends Object?>({
|
||||
TResult? Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult? Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult? Function()? fetched,
|
||||
}) {
|
||||
return fetched?.call();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object?>({
|
||||
TResult Function(DateTime dateFrom, DateTime dateTo)? rangeDateChanged,
|
||||
TResult Function(ProfitSharingPeriodType periodType)? periodTypeChanged,
|
||||
TResult Function()? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (fetched != null) {
|
||||
return fetched();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object?>({
|
||||
required TResult Function(_RangeDateChanged value) rangeDateChanged,
|
||||
required TResult Function(_PeriodTypeChanged value) periodTypeChanged,
|
||||
required TResult Function(_Fetched value) fetched,
|
||||
}) {
|
||||
return fetched(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult? mapOrNull<TResult extends Object?>({
|
||||
TResult? Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult? Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult? Function(_Fetched value)? fetched,
|
||||
}) {
|
||||
return fetched?.call(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object?>({
|
||||
TResult Function(_RangeDateChanged value)? rangeDateChanged,
|
||||
TResult Function(_PeriodTypeChanged value)? periodTypeChanged,
|
||||
TResult Function(_Fetched value)? fetched,
|
||||
required TResult orElse(),
|
||||
}) {
|
||||
if (fetched != null) {
|
||||
return fetched(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _Fetched implements ProfitSharingLoaderEvent {
|
||||
const factory _Fetched() = _$FetchedImpl;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ProfitSharingLoaderState {
|
||||
ProfitSharing get profitSharing => throw _privateConstructorUsedError;
|
||||
Option<AnalyticFailure> get failureOption =>
|
||||
throw _privateConstructorUsedError;
|
||||
bool get isFetching => throw _privateConstructorUsedError;
|
||||
ProfitSharingPeriodType get periodType => throw _privateConstructorUsedError;
|
||||
DateTime get dateFrom => throw _privateConstructorUsedError;
|
||||
DateTime get dateTo => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$ProfitSharingLoaderStateCopyWith<ProfitSharingLoaderState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ProfitSharingLoaderStateCopyWith<$Res> {
|
||||
factory $ProfitSharingLoaderStateCopyWith(
|
||||
ProfitSharingLoaderState value,
|
||||
$Res Function(ProfitSharingLoaderState) then,
|
||||
) = _$ProfitSharingLoaderStateCopyWithImpl<$Res, ProfitSharingLoaderState>;
|
||||
@useResult
|
||||
$Res call({
|
||||
ProfitSharing profitSharing,
|
||||
Option<AnalyticFailure> failureOption,
|
||||
bool isFetching,
|
||||
ProfitSharingPeriodType periodType,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
});
|
||||
|
||||
$ProfitSharingCopyWith<$Res> get profitSharing;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ProfitSharingLoaderStateCopyWithImpl<
|
||||
$Res,
|
||||
$Val extends ProfitSharingLoaderState
|
||||
>
|
||||
implements $ProfitSharingLoaderStateCopyWith<$Res> {
|
||||
_$ProfitSharingLoaderStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? profitSharing = null,
|
||||
Object? failureOption = null,
|
||||
Object? isFetching = null,
|
||||
Object? periodType = null,
|
||||
Object? dateFrom = null,
|
||||
Object? dateTo = null,
|
||||
}) {
|
||||
return _then(
|
||||
_value.copyWith(
|
||||
profitSharing: null == profitSharing
|
||||
? _value.profitSharing
|
||||
: profitSharing // ignore: cast_nullable_to_non_nullable
|
||||
as ProfitSharing,
|
||||
failureOption: null == failureOption
|
||||
? _value.failureOption
|
||||
: failureOption // ignore: cast_nullable_to_non_nullable
|
||||
as Option<AnalyticFailure>,
|
||||
isFetching: null == isFetching
|
||||
? _value.isFetching
|
||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
periodType: null == periodType
|
||||
? _value.periodType
|
||||
: periodType // ignore: cast_nullable_to_non_nullable
|
||||
as ProfitSharingPeriodType,
|
||||
dateFrom: null == dateFrom
|
||||
? _value.dateFrom
|
||||
: dateFrom // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
dateTo: null == dateTo
|
||||
? _value.dateTo
|
||||
: dateTo // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
)
|
||||
as $Val,
|
||||
);
|
||||
}
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ProfitSharingCopyWith<$Res> get profitSharing {
|
||||
return $ProfitSharingCopyWith<$Res>(_value.profitSharing, (value) {
|
||||
return _then(_value.copyWith(profitSharing: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ProfitSharingLoaderStateImplCopyWith<$Res>
|
||||
implements $ProfitSharingLoaderStateCopyWith<$Res> {
|
||||
factory _$$ProfitSharingLoaderStateImplCopyWith(
|
||||
_$ProfitSharingLoaderStateImpl value,
|
||||
$Res Function(_$ProfitSharingLoaderStateImpl) then,
|
||||
) = __$$ProfitSharingLoaderStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({
|
||||
ProfitSharing profitSharing,
|
||||
Option<AnalyticFailure> failureOption,
|
||||
bool isFetching,
|
||||
ProfitSharingPeriodType periodType,
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
});
|
||||
|
||||
@override
|
||||
$ProfitSharingCopyWith<$Res> get profitSharing;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ProfitSharingLoaderStateImplCopyWithImpl<$Res>
|
||||
extends
|
||||
_$ProfitSharingLoaderStateCopyWithImpl<
|
||||
$Res,
|
||||
_$ProfitSharingLoaderStateImpl
|
||||
>
|
||||
implements _$$ProfitSharingLoaderStateImplCopyWith<$Res> {
|
||||
__$$ProfitSharingLoaderStateImplCopyWithImpl(
|
||||
_$ProfitSharingLoaderStateImpl _value,
|
||||
$Res Function(_$ProfitSharingLoaderStateImpl) _then,
|
||||
) : super(_value, _then);
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? profitSharing = null,
|
||||
Object? failureOption = null,
|
||||
Object? isFetching = null,
|
||||
Object? periodType = null,
|
||||
Object? dateFrom = null,
|
||||
Object? dateTo = null,
|
||||
}) {
|
||||
return _then(
|
||||
_$ProfitSharingLoaderStateImpl(
|
||||
profitSharing: null == profitSharing
|
||||
? _value.profitSharing
|
||||
: profitSharing // ignore: cast_nullable_to_non_nullable
|
||||
as ProfitSharing,
|
||||
failureOption: null == failureOption
|
||||
? _value.failureOption
|
||||
: failureOption // ignore: cast_nullable_to_non_nullable
|
||||
as Option<AnalyticFailure>,
|
||||
isFetching: null == isFetching
|
||||
? _value.isFetching
|
||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
periodType: null == periodType
|
||||
? _value.periodType
|
||||
: periodType // ignore: cast_nullable_to_non_nullable
|
||||
as ProfitSharingPeriodType,
|
||||
dateFrom: null == dateFrom
|
||||
? _value.dateFrom
|
||||
: dateFrom // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
dateTo: null == dateTo
|
||||
? _value.dateTo
|
||||
: dateTo // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$ProfitSharingLoaderStateImpl extends _ProfitSharingLoaderState {
|
||||
const _$ProfitSharingLoaderStateImpl({
|
||||
required this.profitSharing,
|
||||
required this.failureOption,
|
||||
this.isFetching = false,
|
||||
this.periodType = ProfitSharingPeriodType.weekly,
|
||||
required this.dateFrom,
|
||||
required this.dateTo,
|
||||
}) : super._();
|
||||
|
||||
@override
|
||||
final ProfitSharing profitSharing;
|
||||
@override
|
||||
final Option<AnalyticFailure> failureOption;
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isFetching;
|
||||
@override
|
||||
@JsonKey()
|
||||
final ProfitSharingPeriodType periodType;
|
||||
@override
|
||||
final DateTime dateFrom;
|
||||
@override
|
||||
final DateTime dateTo;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingLoaderState(profitSharing: $profitSharing, failureOption: $failureOption, isFetching: $isFetching, periodType: $periodType, dateFrom: $dateFrom, dateTo: $dateTo)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ProfitSharingLoaderStateImpl &&
|
||||
(identical(other.profitSharing, profitSharing) ||
|
||||
other.profitSharing == profitSharing) &&
|
||||
(identical(other.failureOption, failureOption) ||
|
||||
other.failureOption == failureOption) &&
|
||||
(identical(other.isFetching, isFetching) ||
|
||||
other.isFetching == isFetching) &&
|
||||
(identical(other.periodType, periodType) ||
|
||||
other.periodType == periodType) &&
|
||||
(identical(other.dateFrom, dateFrom) ||
|
||||
other.dateFrom == dateFrom) &&
|
||||
(identical(other.dateTo, dateTo) || other.dateTo == dateTo));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
profitSharing,
|
||||
failureOption,
|
||||
isFetching,
|
||||
periodType,
|
||||
dateFrom,
|
||||
dateTo,
|
||||
);
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ProfitSharingLoaderStateImplCopyWith<_$ProfitSharingLoaderStateImpl>
|
||||
get copyWith =>
|
||||
__$$ProfitSharingLoaderStateImplCopyWithImpl<
|
||||
_$ProfitSharingLoaderStateImpl
|
||||
>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _ProfitSharingLoaderState extends ProfitSharingLoaderState {
|
||||
const factory _ProfitSharingLoaderState({
|
||||
required final ProfitSharing profitSharing,
|
||||
required final Option<AnalyticFailure> failureOption,
|
||||
final bool isFetching,
|
||||
final ProfitSharingPeriodType periodType,
|
||||
required final DateTime dateFrom,
|
||||
required final DateTime dateTo,
|
||||
}) = _$ProfitSharingLoaderStateImpl;
|
||||
const _ProfitSharingLoaderState._() : super._();
|
||||
|
||||
@override
|
||||
ProfitSharing get profitSharing;
|
||||
@override
|
||||
Option<AnalyticFailure> get failureOption;
|
||||
@override
|
||||
bool get isFetching;
|
||||
@override
|
||||
ProfitSharingPeriodType get periodType;
|
||||
@override
|
||||
DateTime get dateFrom;
|
||||
@override
|
||||
DateTime get dateTo;
|
||||
|
||||
/// Create a copy of ProfitSharingLoaderState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$ProfitSharingLoaderStateImplCopyWith<_$ProfitSharingLoaderStateImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
part of 'profit_sharing_loader_bloc.dart';
|
||||
|
||||
@freezed
|
||||
class ProfitSharingLoaderEvent with _$ProfitSharingLoaderEvent {
|
||||
const factory ProfitSharingLoaderEvent.rangeDateChanged(
|
||||
DateTime dateFrom,
|
||||
DateTime dateTo,
|
||||
) = _RangeDateChanged;
|
||||
const factory ProfitSharingLoaderEvent.periodTypeChanged(
|
||||
ProfitSharingPeriodType periodType,
|
||||
) = _PeriodTypeChanged;
|
||||
const factory ProfitSharingLoaderEvent.fetched() = _Fetched;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
part of 'profit_sharing_loader_bloc.dart';
|
||||
|
||||
/// Tampilan rincian bagi hasil: per minggu atau per bulan.
|
||||
enum ProfitSharingPeriodType { weekly, monthly }
|
||||
|
||||
@freezed
|
||||
class ProfitSharingLoaderState with _$ProfitSharingLoaderState {
|
||||
const ProfitSharingLoaderState._();
|
||||
|
||||
const factory ProfitSharingLoaderState({
|
||||
required ProfitSharing profitSharing,
|
||||
required Option<AnalyticFailure> failureOption,
|
||||
@Default(false) bool isFetching,
|
||||
@Default(ProfitSharingPeriodType.weekly) ProfitSharingPeriodType periodType,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
}) = _ProfitSharingLoaderState;
|
||||
|
||||
factory ProfitSharingLoaderState.initial() {
|
||||
final now = DateTime.now();
|
||||
return ProfitSharingLoaderState(
|
||||
profitSharing: ProfitSharing.empty(),
|
||||
failureOption: none(),
|
||||
dateFrom: DateTime(now.year, now.month, 1),
|
||||
dateTo: DateTime(now.year, now.month + 1, 0),
|
||||
);
|
||||
}
|
||||
|
||||
/// Baris periode sesuai tab yang dipilih, periode kosong disembunyikan.
|
||||
List<ProfitSharingPeriod> get periods {
|
||||
final budget = profitSharing.budget;
|
||||
final list = periodType == ProfitSharingPeriodType.weekly
|
||||
? budget.weekly
|
||||
: budget.monthly;
|
||||
return list.where((e) => e.hasRevenue).toList();
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,7 @@ extension IntegerExt on int {
|
||||
symbol: 'Rp. ',
|
||||
decimalDigits: 0,
|
||||
).format(this);
|
||||
|
||||
/// Format ribuan tanpa simbol mata uang, contoh: 1.639
|
||||
String get thousandFormat => NumberFormat.decimalPattern('id').format(this);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ class ApiPath {
|
||||
static const String purchasingAnalytic = '/api/v1/analytics/purchasing';
|
||||
static const String exclusiveSummaryAnalytic =
|
||||
'/api/v1/analytics/exclusive-summary/period';
|
||||
static const String parentCategoryAnalytic =
|
||||
'/api/v1/analytics/parent-categories';
|
||||
|
||||
// Inventory
|
||||
static const String inventoryReportDetail =
|
||||
|
||||
@@ -13,4 +13,5 @@ part 'entities/product_analytic_entity.dart';
|
||||
part 'entities/payment_method_analytic_entity.dart';
|
||||
part 'entities/purchasing_analytic_entity.dart';
|
||||
part 'entities/exclusive_summary_entity.dart';
|
||||
part 'entities/profit_sharing_entity.dart';
|
||||
part 'failures/analytic_failure.dart';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,219 @@
|
||||
part of '../analytic.dart';
|
||||
|
||||
/// Bagi hasil (profit sharing) berdasarkan omzet per parent category.
|
||||
@freezed
|
||||
class ProfitSharing with _$ProfitSharing {
|
||||
const factory ProfitSharing({
|
||||
required String organizationId,
|
||||
required String outletId,
|
||||
required String outletName,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
required List<ProfitSharingCategory> categories,
|
||||
required ProfitSharingBudget budget,
|
||||
}) = _ProfitSharing;
|
||||
|
||||
factory ProfitSharing.empty() => ProfitSharing(
|
||||
organizationId: '',
|
||||
outletId: '',
|
||||
outletName: '',
|
||||
dateFrom: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
dateTo: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
categories: [],
|
||||
budget: ProfitSharingBudget.empty(),
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingCategory with _$ProfitSharingCategory {
|
||||
const ProfitSharingCategory._();
|
||||
|
||||
const factory ProfitSharingCategory({
|
||||
required String parentCategoryId,
|
||||
required String parentCategoryName,
|
||||
required int totalRevenue,
|
||||
required int totalQuantity,
|
||||
required int categoryCount,
|
||||
required int productCount,
|
||||
required int orderCount,
|
||||
required int totalStandardHpp,
|
||||
required int totalFifoHpp,
|
||||
required int totalMovingAverageHpp,
|
||||
}) = _ProfitSharingCategory;
|
||||
|
||||
factory ProfitSharingCategory.empty() => const ProfitSharingCategory(
|
||||
parentCategoryId: '',
|
||||
parentCategoryName: '',
|
||||
totalRevenue: 0,
|
||||
totalQuantity: 0,
|
||||
categoryCount: 0,
|
||||
productCount: 0,
|
||||
orderCount: 0,
|
||||
totalStandardHpp: 0,
|
||||
totalFifoHpp: 0,
|
||||
totalMovingAverageHpp: 0,
|
||||
);
|
||||
|
||||
/// Laba kotor memakai HPP standar (acuan yang dipakai di laporan laba rugi).
|
||||
int get grossProfit => totalRevenue - totalStandardHpp;
|
||||
|
||||
double get grossMargin =>
|
||||
totalRevenue == 0 ? 0 : (grossProfit / totalRevenue) * 100;
|
||||
|
||||
/// % HPP standar terhadap omzet.
|
||||
double get standardHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalStandardHpp / totalRevenue) * 100;
|
||||
|
||||
/// % HPP riil (FIFO) terhadap omzet — dipakai untuk status kesehatan margin.
|
||||
double get realHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalFifoHpp / totalRevenue) * 100;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingBudget with _$ProfitSharingBudget {
|
||||
const factory ProfitSharingBudget({
|
||||
required ProfitSharingPercentage percentages,
|
||||
required DateTime cutOffFrom,
|
||||
required DateTime cutOffTo,
|
||||
required ProfitSharingPeriod total,
|
||||
required List<ProfitSharingPeriod> weekly,
|
||||
required List<ProfitSharingPeriod> monthly,
|
||||
}) = _ProfitSharingBudget;
|
||||
|
||||
factory ProfitSharingBudget.empty() => ProfitSharingBudget(
|
||||
percentages: ProfitSharingPercentage.empty(),
|
||||
cutOffFrom: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
cutOffTo: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
total: ProfitSharingPeriod.empty(),
|
||||
weekly: [],
|
||||
monthly: [],
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingPercentage with _$ProfitSharingPercentage {
|
||||
const factory ProfitSharingPercentage({
|
||||
required double purchase,
|
||||
required double owner,
|
||||
required double team,
|
||||
}) = _ProfitSharingPercentage;
|
||||
|
||||
factory ProfitSharingPercentage.empty() =>
|
||||
const ProfitSharingPercentage(purchase: 0, owner: 0, team: 0);
|
||||
}
|
||||
|
||||
/// Satu baris periode bagi hasil. Dipakai untuk total, mingguan, dan bulanan.
|
||||
/// [month] dan [weekCount] hanya terisi untuk data bulanan.
|
||||
@freezed
|
||||
class ProfitSharingPeriod with _$ProfitSharingPeriod {
|
||||
const ProfitSharingPeriod._();
|
||||
|
||||
const factory ProfitSharingPeriod({
|
||||
required DateTime periodStart,
|
||||
required DateTime periodEnd,
|
||||
required int revenue,
|
||||
required int orderCount,
|
||||
required int limitPurchase,
|
||||
required int limitOwner,
|
||||
required int limitTeam,
|
||||
@Default('') String month,
|
||||
@Default(0) int weekCount,
|
||||
}) = _ProfitSharingPeriod;
|
||||
|
||||
factory ProfitSharingPeriod.empty() => ProfitSharingPeriod(
|
||||
periodStart: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
periodEnd: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
revenue: 0,
|
||||
orderCount: 0,
|
||||
limitPurchase: 0,
|
||||
limitOwner: 0,
|
||||
limitTeam: 0,
|
||||
);
|
||||
|
||||
bool get hasRevenue => revenue > 0;
|
||||
|
||||
int get averageOrderValue => orderCount == 0 ? 0 : revenue ~/ orderCount;
|
||||
}
|
||||
|
||||
/// Rincian satu kategori induk: ringkasan, sub kategori beserta produknya,
|
||||
/// dan bagi hasil khusus kategori tersebut.
|
||||
@freezed
|
||||
class ProfitSharingDetail with _$ProfitSharingDetail {
|
||||
const factory ProfitSharingDetail({
|
||||
required String organizationId,
|
||||
required String outletId,
|
||||
required String outletName,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
required String parentCategoryId,
|
||||
required String parentCategoryName,
|
||||
required ProfitSharingCategory summary,
|
||||
required List<ProfitSharingSubCategory> categories,
|
||||
required ProfitSharingBudget budget,
|
||||
}) = _ProfitSharingDetail;
|
||||
|
||||
factory ProfitSharingDetail.empty() => ProfitSharingDetail(
|
||||
organizationId: '',
|
||||
outletId: '',
|
||||
outletName: '',
|
||||
dateFrom: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
dateTo: DateTime.fromMillisecondsSinceEpoch(0),
|
||||
parentCategoryId: '',
|
||||
parentCategoryName: '',
|
||||
summary: ProfitSharingCategory.empty(),
|
||||
categories: [],
|
||||
budget: ProfitSharingBudget.empty(),
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingSubCategory with _$ProfitSharingSubCategory {
|
||||
const ProfitSharingSubCategory._();
|
||||
|
||||
const factory ProfitSharingSubCategory({
|
||||
required String categoryId,
|
||||
required String categoryName,
|
||||
required int totalRevenue,
|
||||
required int totalQuantity,
|
||||
required int productCount,
|
||||
required int orderCount,
|
||||
required int totalStandardHpp,
|
||||
required int totalFifoHpp,
|
||||
required int totalMovingAverageHpp,
|
||||
required List<ProfitSharingProduct> products,
|
||||
}) = _ProfitSharingSubCategory;
|
||||
|
||||
double get standardHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalStandardHpp / totalRevenue) * 100;
|
||||
|
||||
double get realHppPercentage =>
|
||||
totalRevenue == 0 ? 0 : (totalFifoHpp / totalRevenue) * 100;
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingProduct with _$ProfitSharingProduct {
|
||||
const ProfitSharingProduct._();
|
||||
|
||||
const factory ProfitSharingProduct({
|
||||
required String productId,
|
||||
required String productName,
|
||||
required String productSku,
|
||||
required int productPrice,
|
||||
required int quantitySold,
|
||||
required int revenue,
|
||||
required double averagePrice,
|
||||
required int orderCount,
|
||||
required double standardHppPerUnit,
|
||||
required int standardHppTotal,
|
||||
required double fifoHppPerUnit,
|
||||
required int fifoHppTotal,
|
||||
required double movingAverageHppPerUnit,
|
||||
required int movingAverageHppTotal,
|
||||
}) = _ProfitSharingProduct;
|
||||
|
||||
double get standardHppPercentage =>
|
||||
revenue == 0 ? 0 : (standardHppTotal / revenue) * 100;
|
||||
|
||||
double get realHppPercentage =>
|
||||
revenue == 0 ? 0 : (fifoHppTotal / revenue) * 100;
|
||||
}
|
||||
@@ -57,4 +57,18 @@ abstract class IAnalyticRepository {
|
||||
required DateTime dateTo,
|
||||
String? outletId,
|
||||
});
|
||||
|
||||
Future<Either<AnalyticFailure, ProfitSharing>> getProfitSharing({
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
String? outletId,
|
||||
String groupBy = 'day',
|
||||
});
|
||||
|
||||
Future<Either<AnalyticFailure, ProfitSharingDetail>> getProfitSharingDetail({
|
||||
required String parentCategoryId,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
String? outletId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,3 +14,4 @@ part 'dto/product_analytic_dto.dart';
|
||||
part 'dto/payment_method_analytic_dto.dart';
|
||||
part 'dto/purchasing_analytic_dto.dart';
|
||||
part 'dto/exclusive_summary_dto.dart';
|
||||
part 'dto/profit_sharing_dto.dart';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1121,3 +1121,289 @@ Map<String, dynamic> _$$ExclusiveSummaryTransactionDtoImplToJson(
|
||||
'amount': instance.amount,
|
||||
'source': instance.source,
|
||||
};
|
||||
|
||||
_$ProfitSharingDtoImpl _$$ProfitSharingDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingDtoImpl(
|
||||
organizationId: json['organization_id'] as String?,
|
||||
outletId: json['outlet_id'] as String?,
|
||||
outletName: json['outlet_name'] as String?,
|
||||
dateFrom: json['date_from'] == null
|
||||
? null
|
||||
: DateTime.parse(json['date_from'] as String),
|
||||
dateTo: json['date_to'] == null
|
||||
? null
|
||||
: DateTime.parse(json['date_to'] as String),
|
||||
data: (json['data'] as List<dynamic>?)
|
||||
?.map((e) => ProfitSharingCategoryDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
budget: json['budget'] == null
|
||||
? null
|
||||
: ProfitSharingBudgetDto.fromJson(json['budget'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingDtoImplToJson(
|
||||
_$ProfitSharingDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'organization_id': instance.organizationId,
|
||||
'outlet_id': instance.outletId,
|
||||
'outlet_name': instance.outletName,
|
||||
'date_from': instance.dateFrom?.toIso8601String(),
|
||||
'date_to': instance.dateTo?.toIso8601String(),
|
||||
'data': instance.data,
|
||||
'budget': instance.budget,
|
||||
};
|
||||
|
||||
_$ProfitSharingCategoryDtoImpl _$$ProfitSharingCategoryDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingCategoryDtoImpl(
|
||||
parentCategoryId: json['parent_category_id'] as String?,
|
||||
parentCategoryName: json['parent_category_name'] as String?,
|
||||
totalRevenue: json['total_revenue'] as num?,
|
||||
totalQuantity: json['total_quantity'] as num?,
|
||||
categoryCount: json['category_count'] as num?,
|
||||
productCount: json['product_count'] as num?,
|
||||
orderCount: json['order_count'] as num?,
|
||||
totalStandardHpp: json['total_standard_hpp'] as num?,
|
||||
totalFifoHpp: json['total_fifo_hpp'] as num?,
|
||||
totalMovingAverageHpp: json['total_moving_average_hpp'] as num?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingCategoryDtoImplToJson(
|
||||
_$ProfitSharingCategoryDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'parent_category_id': instance.parentCategoryId,
|
||||
'parent_category_name': instance.parentCategoryName,
|
||||
'total_revenue': instance.totalRevenue,
|
||||
'total_quantity': instance.totalQuantity,
|
||||
'category_count': instance.categoryCount,
|
||||
'product_count': instance.productCount,
|
||||
'order_count': instance.orderCount,
|
||||
'total_standard_hpp': instance.totalStandardHpp,
|
||||
'total_fifo_hpp': instance.totalFifoHpp,
|
||||
'total_moving_average_hpp': instance.totalMovingAverageHpp,
|
||||
};
|
||||
|
||||
_$ProfitSharingBudgetDtoImpl _$$ProfitSharingBudgetDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingBudgetDtoImpl(
|
||||
percentages: json['percentages'] == null
|
||||
? null
|
||||
: ProfitSharingPercentageDto.fromJson(
|
||||
json['percentages'] as Map<String, dynamic>,
|
||||
),
|
||||
cutOffFrom: json['cut_off_from'] == null
|
||||
? null
|
||||
: DateTime.parse(json['cut_off_from'] as String),
|
||||
cutOffTo: json['cut_off_to'] == null
|
||||
? null
|
||||
: DateTime.parse(json['cut_off_to'] as String),
|
||||
total: json['total'] == null
|
||||
? null
|
||||
: ProfitSharingPeriodDto.fromJson(json['total'] as Map<String, dynamic>),
|
||||
weekly: (json['weekly'] as List<dynamic>?)
|
||||
?.map((e) => ProfitSharingPeriodDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
monthly: (json['monthly'] as List<dynamic>?)
|
||||
?.map((e) => ProfitSharingPeriodDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingBudgetDtoImplToJson(
|
||||
_$ProfitSharingBudgetDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'percentages': instance.percentages,
|
||||
'cut_off_from': instance.cutOffFrom?.toIso8601String(),
|
||||
'cut_off_to': instance.cutOffTo?.toIso8601String(),
|
||||
'total': instance.total,
|
||||
'weekly': instance.weekly,
|
||||
'monthly': instance.monthly,
|
||||
};
|
||||
|
||||
_$ProfitSharingPercentageDtoImpl _$$ProfitSharingPercentageDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingPercentageDtoImpl(
|
||||
purchase: json['purchase'] as num?,
|
||||
owner: json['owner'] as num?,
|
||||
team: json['team'] as num?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingPercentageDtoImplToJson(
|
||||
_$ProfitSharingPercentageDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'purchase': instance.purchase,
|
||||
'owner': instance.owner,
|
||||
'team': instance.team,
|
||||
};
|
||||
|
||||
_$ProfitSharingPeriodDtoImpl _$$ProfitSharingPeriodDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingPeriodDtoImpl(
|
||||
periodStart: json['period_start'] == null
|
||||
? null
|
||||
: DateTime.parse(json['period_start'] as String),
|
||||
periodEnd: json['period_end'] == null
|
||||
? null
|
||||
: DateTime.parse(json['period_end'] as String),
|
||||
revenue: json['revenue'] as num?,
|
||||
orderCount: json['order_count'] as num?,
|
||||
limitPurchase: json['limit_purchase'] as num?,
|
||||
limitOwner: json['limit_owner'] as num?,
|
||||
limitTeam: json['limit_team'] as num?,
|
||||
month: json['month'] as String?,
|
||||
weekCount: json['week_count'] as num?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingPeriodDtoImplToJson(
|
||||
_$ProfitSharingPeriodDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'period_start': instance.periodStart?.toIso8601String(),
|
||||
'period_end': instance.periodEnd?.toIso8601String(),
|
||||
'revenue': instance.revenue,
|
||||
'order_count': instance.orderCount,
|
||||
'limit_purchase': instance.limitPurchase,
|
||||
'limit_owner': instance.limitOwner,
|
||||
'limit_team': instance.limitTeam,
|
||||
'month': instance.month,
|
||||
'week_count': instance.weekCount,
|
||||
};
|
||||
|
||||
_$ProfitSharingDetailDtoImpl _$$ProfitSharingDetailDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingDetailDtoImpl(
|
||||
organizationId: json['organization_id'] as String?,
|
||||
outletId: json['outlet_id'] as String?,
|
||||
outletName: json['outlet_name'] as String?,
|
||||
dateFrom: json['date_from'] == null
|
||||
? null
|
||||
: DateTime.parse(json['date_from'] as String),
|
||||
dateTo: json['date_to'] == null
|
||||
? null
|
||||
: DateTime.parse(json['date_to'] as String),
|
||||
parentCategoryId: json['parent_category_id'] as String?,
|
||||
parentCategoryName: json['parent_category_name'] as String?,
|
||||
summary: json['summary'] == null
|
||||
? null
|
||||
: ProfitSharingSummaryDto.fromJson(
|
||||
json['summary'] as Map<String, dynamic>,
|
||||
),
|
||||
categories: (json['categories'] as List<dynamic>?)
|
||||
?.map(
|
||||
(e) => ProfitSharingSubCategoryDto.fromJson(e as Map<String, dynamic>),
|
||||
)
|
||||
.toList(),
|
||||
budget: json['budget'] == null
|
||||
? null
|
||||
: ProfitSharingBudgetDto.fromJson(json['budget'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingDetailDtoImplToJson(
|
||||
_$ProfitSharingDetailDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'organization_id': instance.organizationId,
|
||||
'outlet_id': instance.outletId,
|
||||
'outlet_name': instance.outletName,
|
||||
'date_from': instance.dateFrom?.toIso8601String(),
|
||||
'date_to': instance.dateTo?.toIso8601String(),
|
||||
'parent_category_id': instance.parentCategoryId,
|
||||
'parent_category_name': instance.parentCategoryName,
|
||||
'summary': instance.summary,
|
||||
'categories': instance.categories,
|
||||
'budget': instance.budget,
|
||||
};
|
||||
|
||||
_$ProfitSharingSummaryDtoImpl _$$ProfitSharingSummaryDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingSummaryDtoImpl(
|
||||
totalRevenue: json['total_revenue'] as num?,
|
||||
totalQuantity: json['total_quantity'] as num?,
|
||||
categoryCount: json['category_count'] as num?,
|
||||
productCount: json['product_count'] as num?,
|
||||
orderCount: json['order_count'] as num?,
|
||||
totalStandardHpp: json['total_standard_hpp'] as num?,
|
||||
totalFifoHpp: json['total_fifo_hpp'] as num?,
|
||||
totalMovingAverageHpp: json['total_moving_average_hpp'] as num?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingSummaryDtoImplToJson(
|
||||
_$ProfitSharingSummaryDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'total_revenue': instance.totalRevenue,
|
||||
'total_quantity': instance.totalQuantity,
|
||||
'category_count': instance.categoryCount,
|
||||
'product_count': instance.productCount,
|
||||
'order_count': instance.orderCount,
|
||||
'total_standard_hpp': instance.totalStandardHpp,
|
||||
'total_fifo_hpp': instance.totalFifoHpp,
|
||||
'total_moving_average_hpp': instance.totalMovingAverageHpp,
|
||||
};
|
||||
|
||||
_$ProfitSharingSubCategoryDtoImpl _$$ProfitSharingSubCategoryDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingSubCategoryDtoImpl(
|
||||
categoryId: json['category_id'] as String?,
|
||||
categoryName: json['category_name'] as String?,
|
||||
totalRevenue: json['total_revenue'] as num?,
|
||||
totalQuantity: json['total_quantity'] as num?,
|
||||
productCount: json['product_count'] as num?,
|
||||
orderCount: json['order_count'] as num?,
|
||||
totalStandardHpp: json['total_standard_hpp'] as num?,
|
||||
totalFifoHpp: json['total_fifo_hpp'] as num?,
|
||||
totalMovingAverageHpp: json['total_moving_average_hpp'] as num?,
|
||||
products: (json['products'] as List<dynamic>?)
|
||||
?.map((e) => ProfitSharingProductDto.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingSubCategoryDtoImplToJson(
|
||||
_$ProfitSharingSubCategoryDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'category_id': instance.categoryId,
|
||||
'category_name': instance.categoryName,
|
||||
'total_revenue': instance.totalRevenue,
|
||||
'total_quantity': instance.totalQuantity,
|
||||
'product_count': instance.productCount,
|
||||
'order_count': instance.orderCount,
|
||||
'total_standard_hpp': instance.totalStandardHpp,
|
||||
'total_fifo_hpp': instance.totalFifoHpp,
|
||||
'total_moving_average_hpp': instance.totalMovingAverageHpp,
|
||||
'products': instance.products,
|
||||
};
|
||||
|
||||
_$ProfitSharingProductDtoImpl _$$ProfitSharingProductDtoImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$ProfitSharingProductDtoImpl(
|
||||
productId: json['product_id'] as String?,
|
||||
productName: json['product_name'] as String?,
|
||||
productSku: json['product_sku'] as String?,
|
||||
productPrice: json['product_price'] as num?,
|
||||
quantitySold: json['quantity_sold'] as num?,
|
||||
revenue: json['revenue'] as num?,
|
||||
averagePrice: json['average_price'] as num?,
|
||||
orderCount: json['order_count'] as num?,
|
||||
standardHppPerUnit: json['standard_hpp_per_unit'] as num?,
|
||||
standardHppTotal: json['standard_hpp_total'] as num?,
|
||||
fifoHppPerUnit: json['fifo_hpp_per_unit'] as num?,
|
||||
fifoHppTotal: json['fifo_hpp_total'] as num?,
|
||||
movingAverageHppPerUnit: json['moving_average_hpp_per_unit'] as num?,
|
||||
movingAverageHppTotal: json['moving_average_hpp_total'] as num?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$ProfitSharingProductDtoImplToJson(
|
||||
_$ProfitSharingProductDtoImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'product_id': instance.productId,
|
||||
'product_name': instance.productName,
|
||||
'product_sku': instance.productSku,
|
||||
'product_price': instance.productPrice,
|
||||
'quantity_sold': instance.quantitySold,
|
||||
'revenue': instance.revenue,
|
||||
'average_price': instance.averagePrice,
|
||||
'order_count': instance.orderCount,
|
||||
'standard_hpp_per_unit': instance.standardHppPerUnit,
|
||||
'standard_hpp_total': instance.standardHppTotal,
|
||||
'fifo_hpp_per_unit': instance.fifoHppPerUnit,
|
||||
'fifo_hpp_total': instance.fifoHppTotal,
|
||||
'moving_average_hpp_per_unit': instance.movingAverageHppPerUnit,
|
||||
'moving_average_hpp_total': instance.movingAverageHppTotal,
|
||||
};
|
||||
|
||||
@@ -295,4 +295,74 @@ class AnalyticRemoteDataProvider {
|
||||
return DC.error(AnalyticFailure.serverError(e));
|
||||
}
|
||||
}
|
||||
|
||||
Future<DC<AnalyticFailure, ProfitSharingDto>> fetchProfitSharing({
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
String? outletId,
|
||||
String groupBy = 'day',
|
||||
}) async {
|
||||
try {
|
||||
final Map<String, dynamic> params = {
|
||||
'date_from': dateFrom.toServerDate,
|
||||
'date_to': dateTo.toServerDate,
|
||||
'group_by': groupBy,
|
||||
};
|
||||
if (outletId != null) params['outlet_id'] = outletId;
|
||||
|
||||
final response = await _apiClient.get(
|
||||
ApiPath.parentCategoryAnalytic,
|
||||
params: params,
|
||||
headers: getAuthorizationHeader(),
|
||||
);
|
||||
|
||||
if (response.data['data'] == null) {
|
||||
return DC.error(AnalyticFailure.empty());
|
||||
}
|
||||
|
||||
final dto = ProfitSharingDto.fromJson(response.data['data']);
|
||||
|
||||
return DC.data(dto);
|
||||
} on ApiFailure catch (e, s) {
|
||||
log('fetchProfitSharingError', name: _logName, error: e, stackTrace: s);
|
||||
return DC.error(AnalyticFailure.serverError(e));
|
||||
}
|
||||
}
|
||||
|
||||
Future<DC<AnalyticFailure, ProfitSharingDetailDto>> fetchProfitSharingDetail({
|
||||
required String parentCategoryId,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
String? outletId,
|
||||
}) async {
|
||||
try {
|
||||
final Map<String, dynamic> params = {
|
||||
'date_from': dateFrom.toServerDate,
|
||||
'date_to': dateTo.toServerDate,
|
||||
};
|
||||
if (outletId != null) params['outlet_id'] = outletId;
|
||||
|
||||
final response = await _apiClient.get(
|
||||
'${ApiPath.parentCategoryAnalytic}/$parentCategoryId',
|
||||
params: params,
|
||||
headers: getAuthorizationHeader(),
|
||||
);
|
||||
|
||||
if (response.data['data'] == null) {
|
||||
return DC.error(AnalyticFailure.empty());
|
||||
}
|
||||
|
||||
final dto = ProfitSharingDetailDto.fromJson(response.data['data']);
|
||||
|
||||
return DC.data(dto);
|
||||
} on ApiFailure catch (e, s) {
|
||||
log(
|
||||
'fetchProfitSharingDetailError',
|
||||
name: _logName,
|
||||
error: e,
|
||||
stackTrace: s,
|
||||
);
|
||||
return DC.error(AnalyticFailure.serverError(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
part of '../analytic_dtos.dart';
|
||||
|
||||
@freezed
|
||||
class ProfitSharingDto with _$ProfitSharingDto {
|
||||
const ProfitSharingDto._();
|
||||
|
||||
const factory ProfitSharingDto({
|
||||
@JsonKey(name: 'organization_id') String? organizationId,
|
||||
@JsonKey(name: 'outlet_id') String? outletId,
|
||||
@JsonKey(name: 'outlet_name') String? outletName,
|
||||
@JsonKey(name: 'date_from') DateTime? dateFrom,
|
||||
@JsonKey(name: 'date_to') DateTime? dateTo,
|
||||
@JsonKey(name: 'data') List<ProfitSharingCategoryDto>? data,
|
||||
@JsonKey(name: 'budget') ProfitSharingBudgetDto? budget,
|
||||
}) = _ProfitSharingDto;
|
||||
|
||||
factory ProfitSharingDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingDtoFromJson(json);
|
||||
|
||||
ProfitSharing toDomain() => ProfitSharing(
|
||||
organizationId: organizationId ?? '',
|
||||
outletId: outletId ?? '',
|
||||
outletName: outletName ?? '',
|
||||
dateFrom: dateFrom?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
dateTo: dateTo?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
categories: data?.map((e) => e.toDomain()).toList() ?? [],
|
||||
budget: budget?.toDomain() ?? ProfitSharingBudget.empty(),
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingCategoryDto with _$ProfitSharingCategoryDto {
|
||||
const ProfitSharingCategoryDto._();
|
||||
|
||||
const factory ProfitSharingCategoryDto({
|
||||
@JsonKey(name: 'parent_category_id') String? parentCategoryId,
|
||||
@JsonKey(name: 'parent_category_name') String? parentCategoryName,
|
||||
@JsonKey(name: 'total_revenue') num? totalRevenue,
|
||||
@JsonKey(name: 'total_quantity') num? totalQuantity,
|
||||
@JsonKey(name: 'category_count') num? categoryCount,
|
||||
@JsonKey(name: 'product_count') num? productCount,
|
||||
@JsonKey(name: 'order_count') num? orderCount,
|
||||
@JsonKey(name: 'total_standard_hpp') num? totalStandardHpp,
|
||||
@JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
|
||||
@JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
|
||||
}) = _ProfitSharingCategoryDto;
|
||||
|
||||
factory ProfitSharingCategoryDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingCategoryDtoFromJson(json);
|
||||
|
||||
ProfitSharingCategory toDomain() => ProfitSharingCategory(
|
||||
parentCategoryId: parentCategoryId ?? '',
|
||||
parentCategoryName: parentCategoryName ?? '',
|
||||
totalRevenue: totalRevenue?.toInt() ?? 0,
|
||||
totalQuantity: totalQuantity?.toInt() ?? 0,
|
||||
categoryCount: categoryCount?.toInt() ?? 0,
|
||||
productCount: productCount?.toInt() ?? 0,
|
||||
orderCount: orderCount?.toInt() ?? 0,
|
||||
totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
|
||||
totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
|
||||
totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingBudgetDto with _$ProfitSharingBudgetDto {
|
||||
const ProfitSharingBudgetDto._();
|
||||
|
||||
const factory ProfitSharingBudgetDto({
|
||||
@JsonKey(name: 'percentages') ProfitSharingPercentageDto? percentages,
|
||||
@JsonKey(name: 'cut_off_from') DateTime? cutOffFrom,
|
||||
@JsonKey(name: 'cut_off_to') DateTime? cutOffTo,
|
||||
@JsonKey(name: 'total') ProfitSharingPeriodDto? total,
|
||||
@JsonKey(name: 'weekly') List<ProfitSharingPeriodDto>? weekly,
|
||||
@JsonKey(name: 'monthly') List<ProfitSharingPeriodDto>? monthly,
|
||||
}) = _ProfitSharingBudgetDto;
|
||||
|
||||
factory ProfitSharingBudgetDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingBudgetDtoFromJson(json);
|
||||
|
||||
ProfitSharingBudget toDomain() => ProfitSharingBudget(
|
||||
percentages: percentages?.toDomain() ?? ProfitSharingPercentage.empty(),
|
||||
cutOffFrom: cutOffFrom?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
cutOffTo: cutOffTo?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
total: total?.toDomain() ?? ProfitSharingPeriod.empty(),
|
||||
weekly: weekly?.map((e) => e.toDomain()).toList() ?? [],
|
||||
monthly: monthly?.map((e) => e.toDomain()).toList() ?? [],
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingPercentageDto with _$ProfitSharingPercentageDto {
|
||||
const ProfitSharingPercentageDto._();
|
||||
|
||||
const factory ProfitSharingPercentageDto({
|
||||
@JsonKey(name: 'purchase') num? purchase,
|
||||
@JsonKey(name: 'owner') num? owner,
|
||||
@JsonKey(name: 'team') num? team,
|
||||
}) = _ProfitSharingPercentageDto;
|
||||
|
||||
factory ProfitSharingPercentageDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingPercentageDtoFromJson(json);
|
||||
|
||||
ProfitSharingPercentage toDomain() => ProfitSharingPercentage(
|
||||
purchase: purchase?.toDouble() ?? 0,
|
||||
owner: owner?.toDouble() ?? 0,
|
||||
team: team?.toDouble() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingPeriodDto with _$ProfitSharingPeriodDto {
|
||||
const ProfitSharingPeriodDto._();
|
||||
|
||||
const factory ProfitSharingPeriodDto({
|
||||
@JsonKey(name: 'period_start') DateTime? periodStart,
|
||||
@JsonKey(name: 'period_end') DateTime? periodEnd,
|
||||
@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: 'limit_team') num? limitTeam,
|
||||
@JsonKey(name: 'month') String? month,
|
||||
@JsonKey(name: 'week_count') num? weekCount,
|
||||
}) = _ProfitSharingPeriodDto;
|
||||
|
||||
factory ProfitSharingPeriodDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingPeriodDtoFromJson(json);
|
||||
|
||||
ProfitSharingPeriod toDomain() => ProfitSharingPeriod(
|
||||
periodStart:
|
||||
periodStart?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
periodEnd: periodEnd?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
revenue: revenue?.toInt() ?? 0,
|
||||
orderCount: orderCount?.toInt() ?? 0,
|
||||
limitPurchase: limitPurchase?.toInt() ?? 0,
|
||||
limitOwner: limitOwner?.toInt() ?? 0,
|
||||
limitTeam: limitTeam?.toInt() ?? 0,
|
||||
month: month ?? '',
|
||||
weekCount: weekCount?.toInt() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingDetailDto with _$ProfitSharingDetailDto {
|
||||
const ProfitSharingDetailDto._();
|
||||
|
||||
const factory ProfitSharingDetailDto({
|
||||
@JsonKey(name: 'organization_id') String? organizationId,
|
||||
@JsonKey(name: 'outlet_id') String? outletId,
|
||||
@JsonKey(name: 'outlet_name') String? outletName,
|
||||
@JsonKey(name: 'date_from') DateTime? dateFrom,
|
||||
@JsonKey(name: 'date_to') DateTime? dateTo,
|
||||
@JsonKey(name: 'parent_category_id') String? parentCategoryId,
|
||||
@JsonKey(name: 'parent_category_name') String? parentCategoryName,
|
||||
@JsonKey(name: 'summary') ProfitSharingSummaryDto? summary,
|
||||
@JsonKey(name: 'categories') List<ProfitSharingSubCategoryDto>? categories,
|
||||
@JsonKey(name: 'budget') ProfitSharingBudgetDto? budget,
|
||||
}) = _ProfitSharingDetailDto;
|
||||
|
||||
factory ProfitSharingDetailDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingDetailDtoFromJson(json);
|
||||
|
||||
ProfitSharingDetail toDomain() => ProfitSharingDetail(
|
||||
organizationId: organizationId ?? '',
|
||||
outletId: outletId ?? '',
|
||||
outletName: outletName ?? '',
|
||||
dateFrom: dateFrom?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
dateTo: dateTo?.toLocal() ?? DateTime.fromMillisecondsSinceEpoch(0),
|
||||
parentCategoryId: parentCategoryId ?? '',
|
||||
parentCategoryName: parentCategoryName ?? '',
|
||||
summary:
|
||||
summary?.toDomain(
|
||||
parentCategoryId: parentCategoryId ?? '',
|
||||
parentCategoryName: parentCategoryName ?? '',
|
||||
) ??
|
||||
ProfitSharingCategory.empty(),
|
||||
categories: categories?.map((e) => e.toDomain()).toList() ?? [],
|
||||
budget: budget?.toDomain() ?? ProfitSharingBudget.empty(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Ringkasan kategori induk pada endpoint detail — bentuknya sama dengan item
|
||||
/// pada endpoint daftar, hanya saja id & nama kategori ada di level atas.
|
||||
@freezed
|
||||
class ProfitSharingSummaryDto with _$ProfitSharingSummaryDto {
|
||||
const ProfitSharingSummaryDto._();
|
||||
|
||||
const factory ProfitSharingSummaryDto({
|
||||
@JsonKey(name: 'total_revenue') num? totalRevenue,
|
||||
@JsonKey(name: 'total_quantity') num? totalQuantity,
|
||||
@JsonKey(name: 'category_count') num? categoryCount,
|
||||
@JsonKey(name: 'product_count') num? productCount,
|
||||
@JsonKey(name: 'order_count') num? orderCount,
|
||||
@JsonKey(name: 'total_standard_hpp') num? totalStandardHpp,
|
||||
@JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
|
||||
@JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
|
||||
}) = _ProfitSharingSummaryDto;
|
||||
|
||||
factory ProfitSharingSummaryDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingSummaryDtoFromJson(json);
|
||||
|
||||
ProfitSharingCategory toDomain({
|
||||
required String parentCategoryId,
|
||||
required String parentCategoryName,
|
||||
}) => ProfitSharingCategory(
|
||||
parentCategoryId: parentCategoryId,
|
||||
parentCategoryName: parentCategoryName,
|
||||
totalRevenue: totalRevenue?.toInt() ?? 0,
|
||||
totalQuantity: totalQuantity?.toInt() ?? 0,
|
||||
categoryCount: categoryCount?.toInt() ?? 0,
|
||||
productCount: productCount?.toInt() ?? 0,
|
||||
orderCount: orderCount?.toInt() ?? 0,
|
||||
totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
|
||||
totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
|
||||
totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingSubCategoryDto with _$ProfitSharingSubCategoryDto {
|
||||
const ProfitSharingSubCategoryDto._();
|
||||
|
||||
const factory ProfitSharingSubCategoryDto({
|
||||
@JsonKey(name: 'category_id') String? categoryId,
|
||||
@JsonKey(name: 'category_name') String? categoryName,
|
||||
@JsonKey(name: 'total_revenue') num? totalRevenue,
|
||||
@JsonKey(name: 'total_quantity') num? totalQuantity,
|
||||
@JsonKey(name: 'product_count') num? productCount,
|
||||
@JsonKey(name: 'order_count') num? orderCount,
|
||||
@JsonKey(name: 'total_standard_hpp') num? totalStandardHpp,
|
||||
@JsonKey(name: 'total_fifo_hpp') num? totalFifoHpp,
|
||||
@JsonKey(name: 'total_moving_average_hpp') num? totalMovingAverageHpp,
|
||||
@JsonKey(name: 'products') List<ProfitSharingProductDto>? products,
|
||||
}) = _ProfitSharingSubCategoryDto;
|
||||
|
||||
factory ProfitSharingSubCategoryDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingSubCategoryDtoFromJson(json);
|
||||
|
||||
ProfitSharingSubCategory toDomain() => ProfitSharingSubCategory(
|
||||
categoryId: categoryId ?? '',
|
||||
categoryName: categoryName ?? '',
|
||||
totalRevenue: totalRevenue?.toInt() ?? 0,
|
||||
totalQuantity: totalQuantity?.toInt() ?? 0,
|
||||
productCount: productCount?.toInt() ?? 0,
|
||||
orderCount: orderCount?.toInt() ?? 0,
|
||||
totalStandardHpp: totalStandardHpp?.toInt() ?? 0,
|
||||
totalFifoHpp: totalFifoHpp?.toInt() ?? 0,
|
||||
totalMovingAverageHpp: totalMovingAverageHpp?.toInt() ?? 0,
|
||||
products: products?.map((e) => e.toDomain()).toList() ?? [],
|
||||
);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class ProfitSharingProductDto with _$ProfitSharingProductDto {
|
||||
const ProfitSharingProductDto._();
|
||||
|
||||
const factory ProfitSharingProductDto({
|
||||
@JsonKey(name: 'product_id') String? productId,
|
||||
@JsonKey(name: 'product_name') String? productName,
|
||||
@JsonKey(name: 'product_sku') String? productSku,
|
||||
@JsonKey(name: 'product_price') num? productPrice,
|
||||
@JsonKey(name: 'quantity_sold') num? quantitySold,
|
||||
@JsonKey(name: 'revenue') num? revenue,
|
||||
@JsonKey(name: 'average_price') num? averagePrice,
|
||||
@JsonKey(name: 'order_count') num? orderCount,
|
||||
@JsonKey(name: 'standard_hpp_per_unit') num? standardHppPerUnit,
|
||||
@JsonKey(name: 'standard_hpp_total') num? standardHppTotal,
|
||||
@JsonKey(name: 'fifo_hpp_per_unit') num? fifoHppPerUnit,
|
||||
@JsonKey(name: 'fifo_hpp_total') num? fifoHppTotal,
|
||||
@JsonKey(name: 'moving_average_hpp_per_unit') num? movingAverageHppPerUnit,
|
||||
@JsonKey(name: 'moving_average_hpp_total') num? movingAverageHppTotal,
|
||||
}) = _ProfitSharingProductDto;
|
||||
|
||||
factory ProfitSharingProductDto.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProfitSharingProductDtoFromJson(json);
|
||||
|
||||
ProfitSharingProduct toDomain() => ProfitSharingProduct(
|
||||
productId: productId ?? '',
|
||||
productName: productName ?? '',
|
||||
productSku: productSku ?? '',
|
||||
productPrice: productPrice?.toInt() ?? 0,
|
||||
quantitySold: quantitySold?.toInt() ?? 0,
|
||||
revenue: revenue?.toInt() ?? 0,
|
||||
averagePrice: averagePrice?.toDouble() ?? 0,
|
||||
orderCount: orderCount?.toInt() ?? 0,
|
||||
standardHppPerUnit: standardHppPerUnit?.toDouble() ?? 0,
|
||||
standardHppTotal: standardHppTotal?.toInt() ?? 0,
|
||||
fifoHppPerUnit: fifoHppPerUnit?.toDouble() ?? 0,
|
||||
fifoHppTotal: fifoHppTotal?.toInt() ?? 0,
|
||||
movingAverageHppPerUnit: movingAverageHppPerUnit?.toDouble() ?? 0,
|
||||
movingAverageHppTotal: movingAverageHppTotal?.toInt() ?? 0,
|
||||
);
|
||||
}
|
||||
@@ -220,4 +220,50 @@ class AnalyticRepository implements IAnalyticRepository {
|
||||
return left(const AnalyticFailure.unexpectedError());
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<AnalyticFailure, ProfitSharing>> getProfitSharing({
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
String? outletId,
|
||||
String groupBy = 'day',
|
||||
}) async {
|
||||
try {
|
||||
final result = await _dataProvider.fetchProfitSharing(
|
||||
dateFrom: dateFrom,
|
||||
dateTo: dateTo,
|
||||
outletId: _resolveOutletId(outletId),
|
||||
groupBy: groupBy,
|
||||
);
|
||||
|
||||
if (result.hasError) return left(result.error!);
|
||||
return right(result.data!.toDomain());
|
||||
} catch (e, s) {
|
||||
log('getProfitSharingError', name: _logName, error: e, stackTrace: s);
|
||||
return left(const AnalyticFailure.unexpectedError());
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<AnalyticFailure, ProfitSharingDetail>> getProfitSharingDetail({
|
||||
required String parentCategoryId,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
String? outletId,
|
||||
}) async {
|
||||
try {
|
||||
final result = await _dataProvider.fetchProfitSharingDetail(
|
||||
parentCategoryId: parentCategoryId,
|
||||
dateFrom: dateFrom,
|
||||
dateTo: dateTo,
|
||||
outletId: _resolveOutletId(outletId),
|
||||
);
|
||||
|
||||
if (result.hasError) return left(result.error!);
|
||||
return right(result.data!.toDomain());
|
||||
} catch (e, s) {
|
||||
log('getProfitSharingDetailError', name: _logName, error: e, stackTrace: s);
|
||||
return left(const AnalyticFailure.unexpectedError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,10 @@ import 'package:apskel_owner_flutter/application/analytic/product_analytic_loade
|
||||
as _i221;
|
||||
import 'package:apskel_owner_flutter/application/analytic/profit_loss_loader/profit_loss_loader_bloc.dart'
|
||||
as _i11;
|
||||
import 'package:apskel_owner_flutter/application/analytic/profit_sharing_detail_loader/profit_sharing_detail_loader_bloc.dart'
|
||||
as _i400;
|
||||
import 'package:apskel_owner_flutter/application/analytic/profit_sharing_loader/profit_sharing_loader_bloc.dart'
|
||||
as _i631;
|
||||
import 'package:apskel_owner_flutter/application/analytic/purchasing_analytic_loader/purchasing_analytic_loader_bloc.dart'
|
||||
as _i755;
|
||||
import 'package:apskel_owner_flutter/application/analytic/sales_loader/sales_loader_bloc.dart'
|
||||
@@ -290,6 +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<_i945.AuthBloc>(
|
||||
() => _i945.AuthBloc(gh<_i49.IAuthRepository>()),
|
||||
);
|
||||
|
||||
+63
-1
@@ -538,5 +538,67 @@
|
||||
"no_data_yet": "No data yet",
|
||||
"@no_data_yet": {},
|
||||
"total_inventory_value": "Total Inventory Value",
|
||||
"@total_inventory_value": {}
|
||||
"@total_inventory_value": {},
|
||||
"profit_sharing": "Profit Sharing",
|
||||
"@profit_sharing": {},
|
||||
"profit_sharing_desc": "Revenue allocation for purchasing, owner, and team",
|
||||
"@profit_sharing_desc": {},
|
||||
"profit_sharing_allocation": "Profit Sharing Allocation",
|
||||
"@profit_sharing_allocation": {},
|
||||
"share_purchase": "Purchasing",
|
||||
"@share_purchase": {},
|
||||
"share_owner": "Owner",
|
||||
"@share_owner": {},
|
||||
"share_team": "Team",
|
||||
"@share_team": {},
|
||||
"weekly": "Weekly",
|
||||
"@weekly": {},
|
||||
"monthly": "Monthly",
|
||||
"@monthly": {},
|
||||
"period_breakdown": "Period Breakdown",
|
||||
"@period_breakdown": {},
|
||||
"revenue_by_brand": "Revenue by Brand",
|
||||
"@revenue_by_brand": {},
|
||||
"week_count": "{count} weeks",
|
||||
"@week_count": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int",
|
||||
"example": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"order_count_label": "{count} orders",
|
||||
"@order_count_label": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int",
|
||||
"example": "328"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gross_margin": "Gross Margin",
|
||||
"@gross_margin": {},
|
||||
"parent_category_summary": "Parent Category Summary",
|
||||
"@parent_category_summary": {},
|
||||
"sub_category": "Sub Category",
|
||||
"@sub_category": {},
|
||||
"qty": "Qty",
|
||||
"@qty": {},
|
||||
"std_hpp": "Std HPP",
|
||||
"@std_hpp": {},
|
||||
"real_hpp": "Real HPP",
|
||||
"@real_hpp": {},
|
||||
"status": "Status",
|
||||
"@status": {},
|
||||
"grand_total": "TOTAL",
|
||||
"@grand_total": {},
|
||||
"status_healthy": "Healthy",
|
||||
"@status_healthy": {},
|
||||
"status_watch": "Watch",
|
||||
"@status_watch": {},
|
||||
"status_critical": "Unhealthy",
|
||||
"@status_critical": {},
|
||||
"tap_row_for_detail": "Tap a card to see sub category and product details",
|
||||
"@tap_row_for_detail": {}
|
||||
}
|
||||
|
||||
+63
-1
@@ -538,5 +538,67 @@
|
||||
"no_data_yet": "Belum ada data",
|
||||
"@no_data_yet": {},
|
||||
"total_inventory_value": "Total Nilai Inventori",
|
||||
"@total_inventory_value": {}
|
||||
"@total_inventory_value": {},
|
||||
"profit_sharing": "Bagi Hasil",
|
||||
"@profit_sharing": {},
|
||||
"profit_sharing_desc": "Alokasi omzet untuk belanja, owner, dan tim",
|
||||
"@profit_sharing_desc": {},
|
||||
"profit_sharing_allocation": "Alokasi Bagi Hasil",
|
||||
"@profit_sharing_allocation": {},
|
||||
"share_purchase": "Belanja",
|
||||
"@share_purchase": {},
|
||||
"share_owner": "Owner",
|
||||
"@share_owner": {},
|
||||
"share_team": "Tim",
|
||||
"@share_team": {},
|
||||
"weekly": "Mingguan",
|
||||
"@weekly": {},
|
||||
"monthly": "Bulanan",
|
||||
"@monthly": {},
|
||||
"period_breakdown": "Rincian Periode",
|
||||
"@period_breakdown": {},
|
||||
"revenue_by_brand": "Omzet per Brand",
|
||||
"@revenue_by_brand": {},
|
||||
"week_count": "{count} minggu",
|
||||
"@week_count": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int",
|
||||
"example": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"order_count_label": "{count} pesanan",
|
||||
"@order_count_label": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int",
|
||||
"example": "328"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gross_margin": "Margin Kotor",
|
||||
"@gross_margin": {},
|
||||
"parent_category_summary": "Ringkasan Kategori Induk",
|
||||
"@parent_category_summary": {},
|
||||
"sub_category": "Sub Kategori",
|
||||
"@sub_category": {},
|
||||
"qty": "Qty",
|
||||
"@qty": {},
|
||||
"std_hpp": "Std HPP",
|
||||
"@std_hpp": {},
|
||||
"real_hpp": "Real HPP",
|
||||
"@real_hpp": {},
|
||||
"status": "Status",
|
||||
"@status": {},
|
||||
"grand_total": "TOTAL",
|
||||
"@grand_total": {},
|
||||
"status_healthy": "Sehat",
|
||||
"@status_healthy": {},
|
||||
"status_watch": "Waspada",
|
||||
"@status_watch": {},
|
||||
"status_critical": "Tidak Sehat",
|
||||
"@status_critical": {},
|
||||
"tap_row_for_detail": "Ketuk kartu untuk melihat rincian sub kategori dan produk",
|
||||
"@tap_row_for_detail": {}
|
||||
}
|
||||
|
||||
@@ -1564,6 +1564,150 @@ abstract class AppLocalizations {
|
||||
/// In en, this message translates to:
|
||||
/// **'Total Inventory Value'**
|
||||
String get total_inventory_value;
|
||||
|
||||
/// No description provided for @profit_sharing.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Profit Sharing'**
|
||||
String get profit_sharing;
|
||||
|
||||
/// No description provided for @profit_sharing_desc.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Revenue allocation for purchasing, owner, and team'**
|
||||
String get profit_sharing_desc;
|
||||
|
||||
/// No description provided for @profit_sharing_allocation.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Profit Sharing Allocation'**
|
||||
String get profit_sharing_allocation;
|
||||
|
||||
/// No description provided for @share_purchase.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Purchasing'**
|
||||
String get share_purchase;
|
||||
|
||||
/// No description provided for @share_owner.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Owner'**
|
||||
String get share_owner;
|
||||
|
||||
/// No description provided for @share_team.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Team'**
|
||||
String get share_team;
|
||||
|
||||
/// No description provided for @weekly.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Weekly'**
|
||||
String get weekly;
|
||||
|
||||
/// No description provided for @monthly.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Monthly'**
|
||||
String get monthly;
|
||||
|
||||
/// No description provided for @period_breakdown.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Period Breakdown'**
|
||||
String get period_breakdown;
|
||||
|
||||
/// No description provided for @revenue_by_brand.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Revenue by Brand'**
|
||||
String get revenue_by_brand;
|
||||
|
||||
/// No description provided for @week_count.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count} weeks'**
|
||||
String week_count(int count);
|
||||
|
||||
/// No description provided for @order_count_label.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'{count} orders'**
|
||||
String order_count_label(int count);
|
||||
|
||||
/// No description provided for @gross_margin.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Gross Margin'**
|
||||
String get gross_margin;
|
||||
|
||||
/// No description provided for @parent_category_summary.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Parent Category Summary'**
|
||||
String get parent_category_summary;
|
||||
|
||||
/// No description provided for @sub_category.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Sub Category'**
|
||||
String get sub_category;
|
||||
|
||||
/// No description provided for @qty.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Qty'**
|
||||
String get qty;
|
||||
|
||||
/// No description provided for @std_hpp.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Std HPP'**
|
||||
String get std_hpp;
|
||||
|
||||
/// No description provided for @real_hpp.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Real HPP'**
|
||||
String get real_hpp;
|
||||
|
||||
/// No description provided for @status.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Status'**
|
||||
String get status;
|
||||
|
||||
/// No description provided for @grand_total.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'TOTAL'**
|
||||
String get grand_total;
|
||||
|
||||
/// No description provided for @status_healthy.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Healthy'**
|
||||
String get status_healthy;
|
||||
|
||||
/// No description provided for @status_watch.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Watch'**
|
||||
String get status_watch;
|
||||
|
||||
/// No description provided for @status_critical.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Unhealthy'**
|
||||
String get status_critical;
|
||||
|
||||
/// No description provided for @tap_row_for_detail.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Tap a card to see sub category and product details'**
|
||||
String get tap_row_for_detail;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
|
||||
|
||||
@@ -756,4 +756,80 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get total_inventory_value => 'Total Inventory Value';
|
||||
|
||||
@override
|
||||
String get profit_sharing => 'Profit Sharing';
|
||||
|
||||
@override
|
||||
String get profit_sharing_desc => 'Revenue allocation for purchasing, owner, and team';
|
||||
|
||||
@override
|
||||
String get profit_sharing_allocation => 'Profit Sharing Allocation';
|
||||
|
||||
@override
|
||||
String get share_purchase => 'Purchasing';
|
||||
|
||||
@override
|
||||
String get share_owner => 'Owner';
|
||||
|
||||
@override
|
||||
String get share_team => 'Team';
|
||||
|
||||
@override
|
||||
String get weekly => 'Weekly';
|
||||
|
||||
@override
|
||||
String get monthly => 'Monthly';
|
||||
|
||||
@override
|
||||
String get period_breakdown => 'Period Breakdown';
|
||||
|
||||
@override
|
||||
String get revenue_by_brand => 'Revenue by Brand';
|
||||
|
||||
@override
|
||||
String week_count(int count) {
|
||||
return '$count weeks';
|
||||
}
|
||||
|
||||
@override
|
||||
String order_count_label(int count) {
|
||||
return '$count orders';
|
||||
}
|
||||
|
||||
@override
|
||||
String get gross_margin => 'Gross Margin';
|
||||
|
||||
@override
|
||||
String get parent_category_summary => 'Parent Category Summary';
|
||||
|
||||
@override
|
||||
String get sub_category => 'Sub Category';
|
||||
|
||||
@override
|
||||
String get qty => 'Qty';
|
||||
|
||||
@override
|
||||
String get std_hpp => 'Std HPP';
|
||||
|
||||
@override
|
||||
String get real_hpp => 'Real HPP';
|
||||
|
||||
@override
|
||||
String get status => 'Status';
|
||||
|
||||
@override
|
||||
String get grand_total => 'TOTAL';
|
||||
|
||||
@override
|
||||
String get status_healthy => 'Healthy';
|
||||
|
||||
@override
|
||||
String get status_watch => 'Watch';
|
||||
|
||||
@override
|
||||
String get status_critical => 'Unhealthy';
|
||||
|
||||
@override
|
||||
String get tap_row_for_detail => 'Tap a card to see sub category and product details';
|
||||
}
|
||||
|
||||
@@ -756,4 +756,80 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get total_inventory_value => 'Total Nilai Inventori';
|
||||
|
||||
@override
|
||||
String get profit_sharing => 'Bagi Hasil';
|
||||
|
||||
@override
|
||||
String get profit_sharing_desc => 'Alokasi omzet untuk belanja, owner, dan tim';
|
||||
|
||||
@override
|
||||
String get profit_sharing_allocation => 'Alokasi Bagi Hasil';
|
||||
|
||||
@override
|
||||
String get share_purchase => 'Belanja';
|
||||
|
||||
@override
|
||||
String get share_owner => 'Owner';
|
||||
|
||||
@override
|
||||
String get share_team => 'Tim';
|
||||
|
||||
@override
|
||||
String get weekly => 'Mingguan';
|
||||
|
||||
@override
|
||||
String get monthly => 'Bulanan';
|
||||
|
||||
@override
|
||||
String get period_breakdown => 'Rincian Periode';
|
||||
|
||||
@override
|
||||
String get revenue_by_brand => 'Omzet per Brand';
|
||||
|
||||
@override
|
||||
String week_count(int count) {
|
||||
return '$count minggu';
|
||||
}
|
||||
|
||||
@override
|
||||
String order_count_label(int count) {
|
||||
return '$count pesanan';
|
||||
}
|
||||
|
||||
@override
|
||||
String get gross_margin => 'Margin Kotor';
|
||||
|
||||
@override
|
||||
String get parent_category_summary => 'Ringkasan Kategori Induk';
|
||||
|
||||
@override
|
||||
String get sub_category => 'Sub Kategori';
|
||||
|
||||
@override
|
||||
String get qty => 'Qty';
|
||||
|
||||
@override
|
||||
String get std_hpp => 'Std HPP';
|
||||
|
||||
@override
|
||||
String get real_hpp => 'Real HPP';
|
||||
|
||||
@override
|
||||
String get status => 'Status';
|
||||
|
||||
@override
|
||||
String get grand_total => 'TOTAL';
|
||||
|
||||
@override
|
||||
String get status_healthy => 'Sehat';
|
||||
|
||||
@override
|
||||
String get status_watch => 'Waspada';
|
||||
|
||||
@override
|
||||
String get status_critical => 'Tidak Sehat';
|
||||
|
||||
@override
|
||||
String get tap_row_for_detail => 'Ketuk kartu untuk melihat rincian sub kategori dan produk';
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import 'widgets/feature.dart';
|
||||
import 'widgets/header.dart';
|
||||
import 'widgets/home_top_products.dart';
|
||||
import 'widgets/home_warnings.dart';
|
||||
import 'widgets/profit_sharing_banner.dart';
|
||||
import 'widgets/stats.dart';
|
||||
|
||||
@RoutePage()
|
||||
@@ -201,6 +202,7 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
HomeFeature(),
|
||||
HomeProfitSharingBanner(),
|
||||
HomeWarnings(),
|
||||
HomeStats(overview: state.dashboard.overview),
|
||||
HomeTopProducts(
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hugeicons/hugeicons.dart';
|
||||
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
import '../../../router/app_router.gr.dart';
|
||||
|
||||
/// Pintu masuk ke halaman bagi hasil dari beranda.
|
||||
class HomeProfitSharingBanner extends StatelessWidget {
|
||||
const HomeProfitSharingBanner({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
|
||||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(AppValue.radius),
|
||||
onTap: () => context.router.push(const ProfitSharingRoute()),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(
|
||||
colors: AppColor.primaryGradient,
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(AppValue.radius),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.primary.withOpacity(0.25),
|
||||
blurRadius: 12,
|
||||
offset: const Offset(0, 4),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 44,
|
||||
height: 44,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.textWhite.withOpacity(0.18),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const HugeIcon(
|
||||
icon: HugeIcons.strokeRoundedPieChart,
|
||||
color: AppColor.textWhite,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SpaceWidth(14),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.lang.profit_sharing,
|
||||
style: AppStyle.md.copyWith(
|
||||
color: AppColor.textWhite,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
context.lang.profit_sharing_desc,
|
||||
style: AppStyle.xs.copyWith(
|
||||
color: AppColor.textWhite.withOpacity(0.8),
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SpaceWidth(8),
|
||||
const Icon(
|
||||
Icons.chevron_right_rounded,
|
||||
color: AppColor.textWhite,
|
||||
size: 24,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
import '../../../application/analytic/profit_sharing_detail_loader/profit_sharing_detail_loader_bloc.dart';
|
||||
import '../../../common/extension/extension.dart';
|
||||
import '../../../common/theme/theme.dart';
|
||||
import '../../../domain/analytic/analytic.dart';
|
||||
import '../../../injection.dart';
|
||||
import '../../components/spacer/spacer.dart';
|
||||
import 'widgets/profit_sharing_allocation.dart';
|
||||
import 'widgets/profit_sharing_detail_header.dart';
|
||||
import 'widgets/profit_sharing_status.dart';
|
||||
import 'widgets/profit_sharing_subcategories.dart';
|
||||
|
||||
@RoutePage()
|
||||
class ProfitSharingDetailPage extends StatelessWidget
|
||||
implements AutoRouteWrapper {
|
||||
final String parentCategoryId;
|
||||
final String parentCategoryName;
|
||||
final DateTime dateFrom;
|
||||
final DateTime dateTo;
|
||||
|
||||
const ProfitSharingDetailPage({
|
||||
super.key,
|
||||
required this.parentCategoryId,
|
||||
required this.parentCategoryName,
|
||||
required this.dateFrom,
|
||||
required this.dateTo,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget wrappedRoute(BuildContext context) => BlocProvider(
|
||||
create: (_) => getIt<ProfitSharingDetailLoaderBloc>()..add(_fetchEvent()),
|
||||
child: this,
|
||||
);
|
||||
|
||||
ProfitSharingDetailLoaderEvent _fetchEvent() =>
|
||||
ProfitSharingDetailLoaderEvent.fetched(
|
||||
parentCategoryId: parentCategoryId,
|
||||
dateFrom: dateFrom,
|
||||
dateTo: dateTo,
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColor.background,
|
||||
body:
|
||||
BlocBuilder<
|
||||
ProfitSharingDetailLoaderBloc,
|
||||
ProfitSharingDetailLoaderState
|
||||
>(
|
||||
builder: (context, state) {
|
||||
return RefreshIndicator(
|
||||
backgroundColor: AppColor.white,
|
||||
color: AppColor.primary,
|
||||
onRefresh: () async {
|
||||
context.read<ProfitSharingDetailLoaderBloc>().add(
|
||||
_fetchEvent(),
|
||||
);
|
||||
await context
|
||||
.read<ProfitSharingDetailLoaderBloc>()
|
||||
.stream
|
||||
.firstWhere((s) => !s.isFetching);
|
||||
},
|
||||
child: CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: ProfitSharingDetailHeader(
|
||||
state: state,
|
||||
fallbackTitle: parentCategoryName,
|
||||
),
|
||||
),
|
||||
|
||||
const SliverToBoxAdapter(child: SpaceHeight(16)),
|
||||
|
||||
if (state.isFetching)
|
||||
SliverToBoxAdapter(child: _buildShimmer())
|
||||
else ...[
|
||||
SliverToBoxAdapter(
|
||||
child: _SummaryCard(summary: state.detail.summary),
|
||||
),
|
||||
|
||||
const SliverToBoxAdapter(child: SpaceHeight(16)),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: ProfitSharingAllocation(
|
||||
budget: state.detail.budget,
|
||||
),
|
||||
),
|
||||
|
||||
const SliverToBoxAdapter(child: SpaceHeight(16)),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: ProfitSharingSubCategories(
|
||||
categories: state.detail.categories,
|
||||
expandedCategoryId: state.expandedCategoryId,
|
||||
onToggle: (categoryId) =>
|
||||
context.read<ProfitSharingDetailLoaderBloc>().add(
|
||||
ProfitSharingDetailLoaderEvent.expandedCategoryChanged(
|
||||
categoryId,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 100)),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildShimmer() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
_shimmerBox(height: 160),
|
||||
const SpaceHeight(16),
|
||||
_shimmerBox(height: 240),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _shimmerBox({required double height}) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: Colors.grey[300]!,
|
||||
highlightColor: Colors.grey[100]!,
|
||||
child: Container(
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SummaryCard extends StatelessWidget {
|
||||
final ProfitSharingCategory summary;
|
||||
|
||||
const _SummaryCard({required this.summary});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.textLight.withOpacity(0.08),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.lang.summary,
|
||||
style: AppStyle.lg.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColor.textPrimary,
|
||||
),
|
||||
),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ProfitSharingMetric(
|
||||
label: context.lang.sub_category,
|
||||
value: '${summary.categoryCount}',
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ProfitSharingMetric(
|
||||
label: context.lang.products,
|
||||
value: '${summary.productCount}',
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ProfitSharingMetric(
|
||||
label: context.lang.orders,
|
||||
value: summary.orderCount.thousandFormat,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 12),
|
||||
child: Divider(height: 1, color: AppColor.borderLight),
|
||||
),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ProfitSharingMetric(
|
||||
label: context.lang.std_hpp,
|
||||
value: formatPercent(summary.standardHppPercentage),
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
import '../../../application/analytic/profit_sharing_loader/profit_sharing_loader_bloc.dart';
|
||||
import '../../../common/theme/theme.dart';
|
||||
import '../../../injection.dart';
|
||||
import '../../components/field/date_range_picker_field.dart';
|
||||
import '../../components/spacer/spacer.dart';
|
||||
import '../../router/app_router.gr.dart';
|
||||
import 'widgets/profit_sharing_allocation.dart';
|
||||
import 'widgets/profit_sharing_categories.dart';
|
||||
import 'widgets/profit_sharing_header.dart';
|
||||
import 'widgets/profit_sharing_periods.dart';
|
||||
|
||||
@RoutePage()
|
||||
class ProfitSharingPage extends StatefulWidget implements AutoRouteWrapper {
|
||||
const ProfitSharingPage({super.key});
|
||||
|
||||
@override
|
||||
State<ProfitSharingPage> createState() => _ProfitSharingPageState();
|
||||
|
||||
@override
|
||||
Widget wrappedRoute(BuildContext context) => BlocProvider(
|
||||
create: (_) =>
|
||||
getIt<ProfitSharingLoaderBloc>()
|
||||
..add(ProfitSharingLoaderEvent.fetched()),
|
||||
child: this,
|
||||
);
|
||||
}
|
||||
|
||||
class _ProfitSharingPageState extends State<ProfitSharingPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late AnimationController _fadeController;
|
||||
late Animation<double> _fadeAnimation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_fadeController = AnimationController(
|
||||
duration: const Duration(milliseconds: 1000),
|
||||
vsync: this,
|
||||
);
|
||||
|
||||
_fadeAnimation = Tween<double>(
|
||||
begin: 0.0,
|
||||
end: 1.0,
|
||||
).animate(CurvedAnimation(parent: _fadeController, curve: Curves.easeIn));
|
||||
|
||||
_fadeController.forward();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_fadeController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppColor.background,
|
||||
body: BlocListener<ProfitSharingLoaderBloc, ProfitSharingLoaderState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.dateFrom != current.dateFrom ||
|
||||
previous.dateTo != current.dateTo,
|
||||
listener: (context, state) {
|
||||
context.read<ProfitSharingLoaderBloc>().add(
|
||||
const ProfitSharingLoaderEvent.fetched(),
|
||||
);
|
||||
},
|
||||
child: BlocBuilder<ProfitSharingLoaderBloc, ProfitSharingLoaderState>(
|
||||
builder: (context, state) {
|
||||
return RefreshIndicator(
|
||||
backgroundColor: AppColor.white,
|
||||
color: AppColor.primary,
|
||||
onRefresh: () async {
|
||||
context.read<ProfitSharingLoaderBloc>().add(
|
||||
const ProfitSharingLoaderEvent.fetched(),
|
||||
);
|
||||
await context.read<ProfitSharingLoaderBloc>().stream.firstWhere(
|
||||
(s) => !s.isFetching,
|
||||
);
|
||||
},
|
||||
child: CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: ProfitSharingHeader(state: state),
|
||||
),
|
||||
),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: DateRangePickerField(
|
||||
startDate: state.dateFrom,
|
||||
endDate: state.dateTo,
|
||||
onChanged: (startDate, endDate) {
|
||||
if (startDate == null || endDate == null) return;
|
||||
context.read<ProfitSharingLoaderBloc>().add(
|
||||
ProfitSharingLoaderEvent.rangeDateChanged(
|
||||
startDate,
|
||||
endDate,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
if (state.isFetching)
|
||||
SliverToBoxAdapter(child: _buildShimmer())
|
||||
else ...[
|
||||
SliverToBoxAdapter(
|
||||
child: FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: ProfitSharingCategories(
|
||||
categories: state.profitSharing.categories,
|
||||
onCategoryTap: (category) => context.router.push(
|
||||
ProfitSharingDetailRoute(
|
||||
parentCategoryId: category.parentCategoryId,
|
||||
parentCategoryName: category.parentCategoryName,
|
||||
dateFrom: state.dateFrom,
|
||||
dateTo: state.dateTo,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SliverToBoxAdapter(child: SpaceHeight(16)),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: ProfitSharingAllocation(
|
||||
budget: state.profitSharing.budget,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SliverToBoxAdapter(child: SpaceHeight(16)),
|
||||
|
||||
SliverToBoxAdapter(
|
||||
child: FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: ProfitSharingPeriods(
|
||||
state: state,
|
||||
onPeriodTypeChanged: (type) {
|
||||
context.read<ProfitSharingLoaderBloc>().add(
|
||||
ProfitSharingLoaderEvent.periodTypeChanged(type),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 100)),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildShimmer() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
_shimmerBox(height: 240),
|
||||
const SpaceHeight(16),
|
||||
_shimmerBox(height: 300),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _shimmerBox({required double height}) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: Colors.grey[300]!,
|
||||
highlightColor: Colors.grey[100]!,
|
||||
child: Container(
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
/// Label rentang periode ringkas, contoh: "27 Jul - 2 Agu 2026".
|
||||
String formatPeriodLabel(DateTime from, DateTime to) {
|
||||
final dayMonth = DateFormat('d MMM', 'id_ID');
|
||||
final dayMonthYear = DateFormat('d MMM yyyy', 'id_ID');
|
||||
|
||||
if (from.year == to.year && from.month == to.month && from.day == to.day) {
|
||||
return dayMonthYear.format(from);
|
||||
}
|
||||
if (from.year == to.year) {
|
||||
return '${dayMonth.format(from)} - ${dayMonthYear.format(to)}';
|
||||
}
|
||||
return '${dayMonthYear.format(from)} - ${dayMonthYear.format(to)}';
|
||||
}
|
||||
|
||||
/// Label bulan dari format API "2026-08" menjadi "Agustus 2026".
|
||||
String formatMonthLabel(String month, DateTime fallback) {
|
||||
final parts = month.split('-');
|
||||
if (parts.length == 2) {
|
||||
final year = int.tryParse(parts[0]);
|
||||
final monthNumber = int.tryParse(parts[1]);
|
||||
if (year != null && monthNumber != null) {
|
||||
return DateFormat(
|
||||
'MMMM yyyy',
|
||||
'id_ID',
|
||||
).format(DateTime(year, monthNumber));
|
||||
}
|
||||
}
|
||||
return DateFormat('MMMM yyyy', 'id_ID').format(fallback);
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../domain/analytic/analytic.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
|
||||
/// Warna tetap untuk tiap pos bagi hasil supaya konsisten di semua bagian.
|
||||
class ProfitSharingColor {
|
||||
static const Color purchase = Color(0xFF2196F3);
|
||||
static const Color owner = Color(0xFF4CAF50);
|
||||
static const Color team = Color(0xFFFF9800);
|
||||
}
|
||||
|
||||
class ProfitSharingAllocation extends StatelessWidget {
|
||||
final ProfitSharingBudget budget;
|
||||
|
||||
const ProfitSharingAllocation({super.key, required this.budget});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final total = budget.total;
|
||||
final percentages = budget.percentages;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.textLight.withOpacity(0.08),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.lang.profit_sharing_allocation,
|
||||
style: AppStyle.lg.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColor.textPrimary,
|
||||
),
|
||||
),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
ProfitSharingBar(
|
||||
purchase: percentages.purchase,
|
||||
owner: percentages.owner,
|
||||
team: percentages.team,
|
||||
),
|
||||
|
||||
const SpaceHeight(20),
|
||||
|
||||
_row(
|
||||
context: context,
|
||||
color: ProfitSharingColor.purchase,
|
||||
label: context.lang.share_purchase,
|
||||
percentage: percentages.purchase,
|
||||
amount: total.limitPurchase,
|
||||
),
|
||||
const Divider(height: 24, color: AppColor.borderLight),
|
||||
_row(
|
||||
context: context,
|
||||
color: ProfitSharingColor.owner,
|
||||
label: context.lang.share_owner,
|
||||
percentage: percentages.owner,
|
||||
amount: total.limitOwner,
|
||||
),
|
||||
const Divider(height: 24, color: AppColor.borderLight),
|
||||
_row(
|
||||
context: context,
|
||||
color: ProfitSharingColor.team,
|
||||
label: context.lang.share_team,
|
||||
percentage: percentages.team,
|
||||
amount: total.limitTeam,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _row({
|
||||
required BuildContext context,
|
||||
required Color color,
|
||||
required String label,
|
||||
required double percentage,
|
||||
required int amount,
|
||||
}) {
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
||||
),
|
||||
const SpaceWidth(10),
|
||||
Text(
|
||||
label,
|
||||
style: AppStyle.md.copyWith(
|
||||
color: AppColor.textPrimary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SpaceWidth(8),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withOpacity(0.12),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
'${percentage.toStringAsFixed(percentage % 1 == 0 ? 0 : 1)}%',
|
||||
style: AppStyle.xs.copyWith(
|
||||
color: color,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Flexible(
|
||||
child: Text(
|
||||
amount.currencyFormatRp,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppStyle.md.copyWith(
|
||||
color: AppColor.textPrimary,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Bar proporsi belanja / owner / tim.
|
||||
class ProfitSharingBar extends StatelessWidget {
|
||||
final double purchase;
|
||||
final double owner;
|
||||
final double team;
|
||||
final double height;
|
||||
|
||||
const ProfitSharingBar({
|
||||
super.key,
|
||||
required this.purchase,
|
||||
required this.owner,
|
||||
required this.team,
|
||||
this.height = 12,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final total = purchase + owner + team;
|
||||
if (total <= 0) {
|
||||
return Container(
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.borderLight,
|
||||
borderRadius: BorderRadius.circular(height),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(height),
|
||||
child: SizedBox(
|
||||
height: height,
|
||||
child: Row(
|
||||
children: [
|
||||
_segment(purchase, ProfitSharingColor.purchase),
|
||||
_segment(owner, ProfitSharingColor.owner),
|
||||
_segment(team, ProfitSharingColor.team),
|
||||
].whereType<Widget>().toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Segmen dilewati saat porsinya 0 supaya Expanded tidak dipakai dengan flex 0.
|
||||
Widget? _segment(double value, Color color) {
|
||||
final flex = (value * 100).round();
|
||||
if (flex <= 0) return null;
|
||||
return Expanded(
|
||||
flex: flex,
|
||||
child: Container(color: color),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../domain/analytic/analytic.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
import 'profit_sharing_status.dart';
|
||||
|
||||
/// Ringkasan omzet & HPP per kategori induk (parent category).
|
||||
/// Tiap kartu bisa diketuk untuk melihat rincian sub kategori & produknya.
|
||||
class ProfitSharingCategories extends StatelessWidget {
|
||||
final List<ProfitSharingCategory> categories;
|
||||
final ValueChanged<ProfitSharingCategory> onCategoryTap;
|
||||
|
||||
const ProfitSharingCategories({
|
||||
super.key,
|
||||
required this.categories,
|
||||
required this.onCategoryTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sorted = [...categories]
|
||||
..sort((a, b) => b.totalRevenue.compareTo(a.totalRevenue));
|
||||
|
||||
final totalRevenue = sorted.fold<int>(0, (sum, e) => sum + e.totalRevenue);
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.textLight.withOpacity(0.08),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.lang.parent_category_summary,
|
||||
style: AppStyle.lg.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColor.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
context.lang.tap_row_for_detail,
|
||||
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
||||
),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
if (sorted.isEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 24),
|
||||
child: Center(
|
||||
child: Text(
|
||||
context.lang.no_data_yet,
|
||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
||||
),
|
||||
),
|
||||
)
|
||||
else ...[
|
||||
...sorted.map(
|
||||
(category) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: _CategoryCard(
|
||||
category: category,
|
||||
share: totalRevenue == 0
|
||||
? 0
|
||||
: category.totalRevenue / totalRevenue,
|
||||
onTap: () => onCategoryTap(category),
|
||||
),
|
||||
),
|
||||
),
|
||||
_TotalCard(categories: sorted),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _CategoryCard extends StatelessWidget {
|
||||
final ProfitSharingCategory category;
|
||||
final double share;
|
||||
final VoidCallback onTap;
|
||||
|
||||
const _CategoryCard({
|
||||
required this.category,
|
||||
required this.share,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
@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,
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
formatPercent(share * 100),
|
||||
style: AppStyle.xs.copyWith(
|
||||
color: AppColor.textSecondary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SpaceHeight(8),
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
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}',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 10),
|
||||
child: Divider(height: 1, color: AppColor.border),
|
||||
),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ProfitSharingMetric(
|
||||
label: context.lang.std_hpp,
|
||||
value: formatPercent(category.standardHppPercentage),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ProfitSharingMetric(
|
||||
label: context.lang.real_hpp,
|
||||
value: formatPercent(category.realHppPercentage),
|
||||
valueColor: statusColor(category.realHppPercentage),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TotalCard extends StatelessWidget {
|
||||
final List<ProfitSharingCategory> categories;
|
||||
|
||||
const _TotalCard({required this.categories});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final totalQuantity = categories.fold<int>(
|
||||
0,
|
||||
(sum, e) => sum + e.totalQuantity,
|
||||
);
|
||||
final totalRevenue = categories.fold<int>(
|
||||
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;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(14),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.primary.withOpacity(0.06),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
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)),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
import '../../../../application/analytic/profit_sharing_detail_loader/profit_sharing_detail_loader_bloc.dart';
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
import 'period_label.dart';
|
||||
import 'profit_sharing_status.dart';
|
||||
|
||||
class ProfitSharingDetailHeader extends StatelessWidget {
|
||||
final ProfitSharingDetailLoaderState state;
|
||||
final String fallbackTitle;
|
||||
|
||||
const ProfitSharingDetailHeader({
|
||||
super.key,
|
||||
required this.state,
|
||||
required this.fallbackTitle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final detail = state.detail;
|
||||
final summary = detail.summary;
|
||||
final title = detail.parentCategoryName.isNotEmpty
|
||||
? detail.parentCategoryName
|
||||
: fallbackTitle;
|
||||
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: AppColor.primaryGradient,
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24),
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => context.router.maybePop(),
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.textWhite.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.chevron_left_rounded,
|
||||
color: AppColor.textWhite,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SpaceWidth(12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: AppStyle.xl.copyWith(
|
||||
color: AppColor.textWhite,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 20,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
formatPeriodLabel(state.dateFrom, state.dateTo),
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: AppColor.textWhite.withOpacity(0.75),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SpaceHeight(24),
|
||||
|
||||
if (state.isFetching)
|
||||
_shimmerBox(width: 220, height: 36)
|
||||
else
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
summary.totalRevenue.currencyFormatRp,
|
||||
style: AppStyle.h1.copyWith(
|
||||
color: AppColor.textWhite,
|
||||
fontWeight: FontWeight.w900,
|
||||
fontSize: 30,
|
||||
),
|
||||
),
|
||||
),
|
||||
ProfitSharingStatusBadge(
|
||||
realHppPercentage: summary.realHppPercentage,
|
||||
onDarkBackground: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SpaceHeight(4),
|
||||
Text(
|
||||
context.lang.total_revenue,
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: AppColor.textWhite.withOpacity(0.75),
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
|
||||
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),
|
||||
],
|
||||
)
|
||||
else
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
_chip(
|
||||
'${context.lang.qty} ${summary.totalQuantity.thousandFormat}',
|
||||
),
|
||||
_chip(context.lang.order_count_label(summary.orderCount)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
double radius = 8,
|
||||
}) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: AppColor.textWhite.withOpacity(0.3),
|
||||
highlightColor: AppColor.textWhite.withOpacity(0.6),
|
||||
child: Container(
|
||||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.textWhite.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(radius),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shimmer/shimmer.dart';
|
||||
|
||||
import '../../../../application/analytic/profit_sharing_loader/profit_sharing_loader_bloc.dart';
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
|
||||
class ProfitSharingHeader extends StatelessWidget {
|
||||
final ProfitSharingLoaderState state;
|
||||
|
||||
const ProfitSharingHeader({super.key, required this.state});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final budget = state.profitSharing.budget;
|
||||
final outletLabel = state.profitSharing.outletName.isNotEmpty
|
||||
? state.profitSharing.outletName
|
||||
: context.lang.all_outlets;
|
||||
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: AppColor.primaryGradient,
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24),
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 12, 16, 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
if (context.router.canPop()) ...[
|
||||
GestureDetector(
|
||||
onTap: () => context.router.maybePop(),
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.textWhite.withOpacity(0.15),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.chevron_left_rounded,
|
||||
color: AppColor.textWhite,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SpaceWidth(12),
|
||||
],
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.lang.profit_sharing,
|
||||
style: AppStyle.xl.copyWith(
|
||||
color: AppColor.textWhite,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontSize: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
outletLabel,
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: AppColor.textWhite.withOpacity(0.75),
|
||||
fontSize: 12,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SpaceHeight(24),
|
||||
|
||||
state.isFetching
|
||||
? _shimmerBox(width: 220, height: 36)
|
||||
: Text(
|
||||
budget.total.revenue.currencyFormatRp,
|
||||
style: AppStyle.h1.copyWith(
|
||||
color: AppColor.textWhite,
|
||||
fontWeight: FontWeight.w900,
|
||||
fontSize: 32,
|
||||
),
|
||||
),
|
||||
|
||||
const SpaceHeight(4),
|
||||
Text(
|
||||
context.lang.total_revenue,
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: AppColor.textWhite.withOpacity(0.75),
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
state.isFetching
|
||||
? _shimmerBox(width: 140, height: 32, radius: 20)
|
||||
: _chip(
|
||||
context.lang.order_count_label(budget.total.orderCount),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
double radius = 8,
|
||||
}) {
|
||||
return Shimmer.fromColors(
|
||||
baseColor: AppColor.textWhite.withOpacity(0.3),
|
||||
highlightColor: AppColor.textWhite.withOpacity(0.6),
|
||||
child: Container(
|
||||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.textWhite.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(radius),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../application/analytic/profit_sharing_loader/profit_sharing_loader_bloc.dart';
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../domain/analytic/analytic.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
import 'period_label.dart';
|
||||
import 'profit_sharing_allocation.dart';
|
||||
|
||||
class ProfitSharingPeriods extends StatelessWidget {
|
||||
final ProfitSharingLoaderState state;
|
||||
final ValueChanged<ProfitSharingPeriodType> onPeriodTypeChanged;
|
||||
|
||||
const ProfitSharingPeriods({
|
||||
super.key,
|
||||
required this.state,
|
||||
required this.onPeriodTypeChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final periods = state.periods;
|
||||
final percentages = state.profitSharing.budget.percentages;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.textLight.withOpacity(0.08),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.lang.period_breakdown,
|
||||
style: AppStyle.lg.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColor.textPrimary,
|
||||
),
|
||||
),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
_tabs(context),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
if (periods.isEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 24),
|
||||
child: Center(
|
||||
child: Text(
|
||||
context.lang.no_data_yet,
|
||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
...periods.map(
|
||||
(period) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: _PeriodCard(period: period, percentages: percentages),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _tabs(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.background,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
_tab(
|
||||
context: context,
|
||||
label: context.lang.weekly,
|
||||
type: ProfitSharingPeriodType.weekly,
|
||||
),
|
||||
_tab(
|
||||
context: context,
|
||||
label: context.lang.monthly,
|
||||
type: ProfitSharingPeriodType.monthly,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _tab({
|
||||
required BuildContext context,
|
||||
required String label,
|
||||
required ProfitSharingPeriodType type,
|
||||
}) {
|
||||
final isSelected = state.periodType == type;
|
||||
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () => onPeriodTypeChanged(type),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? AppColor.primary : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: isSelected ? AppColor.textWhite : AppColor.textSecondary,
|
||||
fontWeight: isSelected ? FontWeight.w700 : FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PeriodCard extends StatelessWidget {
|
||||
final ProfitSharingPeriod period;
|
||||
final ProfitSharingPercentage percentages;
|
||||
|
||||
const _PeriodCard({required this.period, required this.percentages});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isMonthly = period.month.isNotEmpty;
|
||||
|
||||
final title = isMonthly
|
||||
? formatMonthLabel(period.month, period.periodStart)
|
||||
: formatPeriodLabel(period.periodStart, period.periodEnd);
|
||||
|
||||
final subtitle = isMonthly
|
||||
? '${formatPeriodLabel(period.periodStart, period.periodEnd)} - ${context.lang.week_count(period.weekCount)}'
|
||||
: context.lang.order_count_label(period.orderCount);
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.background,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColor.borderLight),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: AppStyle.md.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColor.textPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
subtitle,
|
||||
style: AppStyle.xs.copyWith(
|
||||
color: AppColor.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SpaceWidth(8),
|
||||
Text(
|
||||
period.revenue.currencyFormatRp,
|
||||
style: AppStyle.md.copyWith(
|
||||
fontWeight: FontWeight.w800,
|
||||
color: AppColor.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SpaceHeight(12),
|
||||
|
||||
ProfitSharingBar(
|
||||
purchase: percentages.purchase,
|
||||
owner: percentages.owner,
|
||||
team: percentages.team,
|
||||
height: 6,
|
||||
),
|
||||
|
||||
const SpaceHeight(12),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
_share(
|
||||
context.lang.share_purchase,
|
||||
period.limitPurchase,
|
||||
ProfitSharingColor.purchase,
|
||||
),
|
||||
_share(
|
||||
context.lang.share_owner,
|
||||
period.limitOwner,
|
||||
ProfitSharingColor.owner,
|
||||
),
|
||||
_share(
|
||||
context.lang.share_team,
|
||||
period.limitTeam,
|
||||
ProfitSharingColor.team,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _share(String label, int amount, Color color) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
||||
),
|
||||
const SpaceWidth(6),
|
||||
Flexible(
|
||||
child: Text(
|
||||
label,
|
||||
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
amount.currencyFormatRp,
|
||||
style: AppStyle.xs.copyWith(
|
||||
color: AppColor.textPrimary,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
|
||||
/// Ambang kesehatan berdasarkan % HPP riil terhadap omzet.
|
||||
/// Ubah di sini kalau target margin bisnis berubah.
|
||||
class HppThreshold {
|
||||
static const double healthy = 70;
|
||||
static const double watch = 80;
|
||||
}
|
||||
|
||||
String formatPercent(double value) => '${value.toStringAsFixed(1)}%';
|
||||
|
||||
Color statusColor(double realHppPercentage) {
|
||||
if (realHppPercentage <= HppThreshold.healthy) return AppColor.success;
|
||||
if (realHppPercentage <= HppThreshold.watch) return AppColor.warning;
|
||||
return AppColor.error;
|
||||
}
|
||||
|
||||
String statusLabel(BuildContext context, double realHppPercentage) {
|
||||
if (realHppPercentage <= HppThreshold.healthy) {
|
||||
return context.lang.status_healthy;
|
||||
}
|
||||
if (realHppPercentage <= HppThreshold.watch) return context.lang.status_watch;
|
||||
return context.lang.status_critical;
|
||||
}
|
||||
|
||||
/// Pill status margin (Sehat / Waspada / Tidak Sehat).
|
||||
class ProfitSharingStatusBadge extends StatelessWidget {
|
||||
final double realHppPercentage;
|
||||
final bool onDarkBackground;
|
||||
|
||||
const ProfitSharingStatusBadge({
|
||||
super.key,
|
||||
required this.realHppPercentage,
|
||||
this.onDarkBackground = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final color = statusColor(realHppPercentage);
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: onDarkBackground
|
||||
? AppColor.textWhite.withOpacity(0.18)
|
||||
: color.withOpacity(0.12),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: onDarkBackground
|
||||
? Border.all(color: AppColor.textWhite.withOpacity(0.3))
|
||||
: null,
|
||||
),
|
||||
child: Text(
|
||||
statusLabel(context, realHppPercentage),
|
||||
style: AppStyle.xs.copyWith(
|
||||
color: onDarkBackground ? AppColor.textWhite : color,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Label kecil dua baris: judul di atas, nilai di bawah.
|
||||
class ProfitSharingMetric extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
final Color? valueColor;
|
||||
final bool isBold;
|
||||
|
||||
const ProfitSharingMetric({
|
||||
super.key,
|
||||
required this.label,
|
||||
required this.value,
|
||||
this.valueColor,
|
||||
this.isBold = false,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
value,
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: valueColor ?? AppColor.textPrimary,
|
||||
fontWeight: isBold ? FontWeight.w800 : FontWeight.w600,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../common/extension/extension.dart';
|
||||
import '../../../../common/theme/theme.dart';
|
||||
import '../../../../domain/analytic/analytic.dart';
|
||||
import '../../../components/spacer/spacer.dart';
|
||||
import 'profit_sharing_status.dart';
|
||||
|
||||
/// Daftar sub kategori; tiap kartu bisa dibuka untuk melihat produknya.
|
||||
class ProfitSharingSubCategories extends StatelessWidget {
|
||||
final List<ProfitSharingSubCategory> categories;
|
||||
final String expandedCategoryId;
|
||||
final ValueChanged<String> onToggle;
|
||||
|
||||
const ProfitSharingSubCategories({
|
||||
super.key,
|
||||
required this.categories,
|
||||
required this.expandedCategoryId,
|
||||
required this.onToggle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sorted = [...categories]
|
||||
..sort((a, b) => b.totalRevenue.compareTo(a.totalRevenue));
|
||||
|
||||
final totalRevenue = sorted.fold<int>(0, (sum, e) => sum + e.totalRevenue);
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.all(20),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColor.textLight.withOpacity(0.08),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 10,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
context.lang.sub_category,
|
||||
style: AppStyle.lg.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColor.textPrimary,
|
||||
),
|
||||
),
|
||||
|
||||
const SpaceHeight(16),
|
||||
|
||||
if (sorted.isEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 24),
|
||||
child: Center(
|
||||
child: Text(
|
||||
context.lang.no_data_yet,
|
||||
style: AppStyle.sm.copyWith(color: AppColor.textSecondary),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
...sorted.map(
|
||||
(category) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: _SubCategoryCard(
|
||||
category: category,
|
||||
share: totalRevenue == 0
|
||||
? 0
|
||||
: category.totalRevenue / totalRevenue,
|
||||
isExpanded: expandedCategoryId == category.categoryId,
|
||||
onToggle: () => onToggle(category.categoryId),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SubCategoryCard extends StatelessWidget {
|
||||
final ProfitSharingSubCategory category;
|
||||
final double share;
|
||||
final bool isExpanded;
|
||||
final VoidCallback onToggle;
|
||||
|
||||
const _SubCategoryCard({
|
||||
required this.category,
|
||||
required this.share,
|
||||
required this.isExpanded,
|
||||
required this.onToggle,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.background,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: AppColor.borderLight),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
InkWell(
|
||||
onTap: onToggle,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
category.categoryName,
|
||||
style: AppStyle.md.copyWith(
|
||||
color: AppColor.textPrimary,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const SpaceWidth(8),
|
||||
Text(
|
||||
category.totalRevenue.currencyFormatRp,
|
||||
style: AppStyle.md.copyWith(
|
||||
color: AppColor.primary,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
AnimatedRotation(
|
||||
turns: isExpanded ? 0.5 : 0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: const Icon(
|
||||
Icons.keyboard_arrow_down_rounded,
|
||||
color: AppColor.textSecondary,
|
||||
size: 22,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SpaceHeight(8),
|
||||
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
child: LinearProgressIndicator(
|
||||
value: share.clamp(0.0, 1.0),
|
||||
minHeight: 5,
|
||||
backgroundColor: AppColor.borderLight,
|
||||
valueColor: const AlwaysStoppedAnimation<Color>(
|
||||
AppColor.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
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.real_hpp,
|
||||
value: formatPercent(category.realHppPercentage),
|
||||
valueColor: statusColor(category.realHppPercentage),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
AnimatedCrossFade(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
crossFadeState: isExpanded
|
||||
? CrossFadeState.showFirst
|
||||
: CrossFadeState.showSecond,
|
||||
firstChild: _ProductList(products: category.products),
|
||||
secondChild: const SizedBox(width: double.infinity),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProductList extends StatelessWidget {
|
||||
final List<ProfitSharingProduct> products;
|
||||
|
||||
const _ProductList({required this.products});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sorted = [...products]
|
||||
..sort((a, b) => b.revenue.compareTo(a.revenue));
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.fromLTRB(14, 0, 14, 14),
|
||||
child: Column(
|
||||
children: [
|
||||
const Divider(height: 1, color: AppColor.border),
|
||||
const SpaceHeight(10),
|
||||
...sorted.map((product) => _ProductRow(product: product)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProductRow extends StatelessWidget {
|
||||
final ProfitSharingProduct product;
|
||||
|
||||
const _ProductRow({required this.product});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final color = statusColor(product.realHppPercentage);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
margin: const EdgeInsets.only(top: 4),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.primary.withOpacity(0.08),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
'${product.quantitySold}x',
|
||||
style: AppStyle.xs.copyWith(
|
||||
color: AppColor.primary,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SpaceWidth(10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
product.productName,
|
||||
style: AppStyle.sm.copyWith(
|
||||
color: AppColor.textPrimary,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'${product.productSku} · @${product.averagePrice.round().currencyFormatRp}',
|
||||
style: AppStyle.xs.copyWith(color: AppColor.textSecondary),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,10 @@ class AppRouter extends RootStackRouter {
|
||||
// Finance page
|
||||
AutoRoute(page: FinanceRoute.page),
|
||||
|
||||
// Profit Sharing
|
||||
AutoRoute(page: ProfitSharingRoute.page),
|
||||
AutoRoute(page: ProfitSharingDetailRoute.page),
|
||||
|
||||
// Exclusive Summary
|
||||
AutoRoute(page: ExclusiveSummaryRoute.page),
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
// coverage:ignore-file
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'package:apskel_owner_flutter/domain/order/order.dart' as _i29;
|
||||
import 'package:apskel_owner_flutter/domain/user/user.dart' as _i30;
|
||||
import 'package:apskel_owner_flutter/domain/order/order.dart' as _i31;
|
||||
import 'package:apskel_owner_flutter/domain/user/user.dart' as _i32;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/about_app/about_app_page.dart'
|
||||
as _i1;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/auth/login/login_page.dart'
|
||||
@@ -53,28 +53,32 @@ import 'package:apskel_owner_flutter/presentation/pages/profile/pages/profile_ed
|
||||
as _i20;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/profile/profile_page.dart'
|
||||
as _i21;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/profit_sharing/profit_sharing_detail_page.dart'
|
||||
as _i22;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/profit_sharing/profit_sharing_page.dart'
|
||||
as _i23;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/purchase/purchase_page.dart'
|
||||
as _i24;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/report/report_page.dart'
|
||||
as _i25;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart'
|
||||
import 'package:apskel_owner_flutter/presentation/pages/sales/sales_page.dart'
|
||||
as _i26;
|
||||
import 'package:auto_route/auto_route.dart' as _i27;
|
||||
import 'package:flutter/material.dart' as _i28;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/schedule/schedule_page.dart'
|
||||
as _i27;
|
||||
import 'package:apskel_owner_flutter/presentation/pages/splash/splash_page.dart'
|
||||
as _i28;
|
||||
import 'package:auto_route/auto_route.dart' as _i29;
|
||||
import 'package:flutter/material.dart' as _i30;
|
||||
|
||||
/// generated route for
|
||||
/// [_i1.AboutAppPage]
|
||||
class AboutAppRoute extends _i27.PageRouteInfo<void> {
|
||||
const AboutAppRoute({List<_i27.PageRouteInfo>? children})
|
||||
class AboutAppRoute extends _i29.PageRouteInfo<void> {
|
||||
const AboutAppRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(AboutAppRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'AboutAppRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i1.AboutAppPage();
|
||||
@@ -84,13 +88,13 @@ class AboutAppRoute extends _i27.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i2.ComingSoonPage]
|
||||
class ComingSoonRoute extends _i27.PageRouteInfo<void> {
|
||||
const ComingSoonRoute({List<_i27.PageRouteInfo>? children})
|
||||
class ComingSoonRoute extends _i29.PageRouteInfo<void> {
|
||||
const ComingSoonRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ComingSoonRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ComingSoonRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i2.ComingSoonPage();
|
||||
@@ -100,29 +104,29 @@ class ComingSoonRoute extends _i27.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i3.CustomerPage]
|
||||
class CustomerRoute extends _i27.PageRouteInfo<void> {
|
||||
const CustomerRoute({List<_i27.PageRouteInfo>? children})
|
||||
class CustomerRoute extends _i29.PageRouteInfo<void> {
|
||||
const CustomerRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(CustomerRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'CustomerRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i3.CustomerPage());
|
||||
return _i29.WrappedRoute(child: const _i3.CustomerPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i4.DailyTasksFormPage]
|
||||
class DailyTasksFormRoute extends _i27.PageRouteInfo<void> {
|
||||
const DailyTasksFormRoute({List<_i27.PageRouteInfo>? children})
|
||||
class DailyTasksFormRoute extends _i29.PageRouteInfo<void> {
|
||||
const DailyTasksFormRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(DailyTasksFormRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'DailyTasksFormRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i4.DailyTasksFormPage();
|
||||
@@ -132,32 +136,32 @@ class DailyTasksFormRoute extends _i27.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i5.DownloadReportPage]
|
||||
class DownloadReportRoute extends _i27.PageRouteInfo<void> {
|
||||
const DownloadReportRoute({List<_i27.PageRouteInfo>? children})
|
||||
class DownloadReportRoute extends _i29.PageRouteInfo<void> {
|
||||
const DownloadReportRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(DownloadReportRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'DownloadReportRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i5.DownloadReportPage());
|
||||
return _i29.WrappedRoute(child: const _i5.DownloadReportPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i6.ErrorPage]
|
||||
class ErrorRoute extends _i27.PageRouteInfo<ErrorRouteArgs> {
|
||||
class ErrorRoute extends _i29.PageRouteInfo<ErrorRouteArgs> {
|
||||
ErrorRoute({
|
||||
_i28.Key? key,
|
||||
_i30.Key? key,
|
||||
String? title,
|
||||
String? message,
|
||||
_i28.VoidCallback? onRetry,
|
||||
_i28.VoidCallback? onBack,
|
||||
_i30.VoidCallback? onRetry,
|
||||
_i30.VoidCallback? onBack,
|
||||
String? errorCode,
|
||||
_i28.IconData? errorIcon,
|
||||
List<_i27.PageRouteInfo>? children,
|
||||
_i30.IconData? errorIcon,
|
||||
List<_i29.PageRouteInfo>? children,
|
||||
}) : super(
|
||||
ErrorRoute.name,
|
||||
args: ErrorRouteArgs(
|
||||
@@ -174,7 +178,7 @@ class ErrorRoute extends _i27.PageRouteInfo<ErrorRouteArgs> {
|
||||
|
||||
static const String name = 'ErrorRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
final args = data.argsAs<ErrorRouteArgs>(
|
||||
@@ -204,19 +208,19 @@ class ErrorRouteArgs {
|
||||
this.errorIcon,
|
||||
});
|
||||
|
||||
final _i28.Key? key;
|
||||
final _i30.Key? key;
|
||||
|
||||
final String? title;
|
||||
|
||||
final String? message;
|
||||
|
||||
final _i28.VoidCallback? onRetry;
|
||||
final _i30.VoidCallback? onRetry;
|
||||
|
||||
final _i28.VoidCallback? onBack;
|
||||
final _i30.VoidCallback? onBack;
|
||||
|
||||
final String? errorCode;
|
||||
|
||||
final _i28.IconData? errorIcon;
|
||||
final _i30.IconData? errorIcon;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -226,77 +230,77 @@ class ErrorRouteArgs {
|
||||
|
||||
/// generated route for
|
||||
/// [_i7.ExclusiveSummaryPage]
|
||||
class ExclusiveSummaryRoute extends _i27.PageRouteInfo<void> {
|
||||
const ExclusiveSummaryRoute({List<_i27.PageRouteInfo>? children})
|
||||
class ExclusiveSummaryRoute extends _i29.PageRouteInfo<void> {
|
||||
const ExclusiveSummaryRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ExclusiveSummaryRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ExclusiveSummaryRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i7.ExclusiveSummaryPage());
|
||||
return _i29.WrappedRoute(child: const _i7.ExclusiveSummaryPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i8.FinancePage]
|
||||
class FinanceRoute extends _i27.PageRouteInfo<void> {
|
||||
const FinanceRoute({List<_i27.PageRouteInfo>? children})
|
||||
class FinanceRoute extends _i29.PageRouteInfo<void> {
|
||||
const FinanceRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(FinanceRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'FinanceRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i8.FinancePage());
|
||||
return _i29.WrappedRoute(child: const _i8.FinancePage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i9.HomePage]
|
||||
class HomeRoute extends _i27.PageRouteInfo<void> {
|
||||
const HomeRoute({List<_i27.PageRouteInfo>? children})
|
||||
class HomeRoute extends _i29.PageRouteInfo<void> {
|
||||
const HomeRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(HomeRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'HomeRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i9.HomePage());
|
||||
return _i29.WrappedRoute(child: const _i9.HomePage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i10.InventoryPage]
|
||||
class InventoryRoute extends _i27.PageRouteInfo<void> {
|
||||
const InventoryRoute({List<_i27.PageRouteInfo>? children})
|
||||
class InventoryRoute extends _i29.PageRouteInfo<void> {
|
||||
const InventoryRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(InventoryRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'InventoryRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i10.InventoryPage());
|
||||
return _i29.WrappedRoute(child: const _i10.InventoryPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i11.LanguagePage]
|
||||
class LanguageRoute extends _i27.PageRouteInfo<void> {
|
||||
const LanguageRoute({List<_i27.PageRouteInfo>? children})
|
||||
class LanguageRoute extends _i29.PageRouteInfo<void> {
|
||||
const LanguageRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(LanguageRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'LanguageRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i11.LanguagePage();
|
||||
@@ -306,29 +310,29 @@ class LanguageRoute extends _i27.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i12.LoginPage]
|
||||
class LoginRoute extends _i27.PageRouteInfo<void> {
|
||||
const LoginRoute({List<_i27.PageRouteInfo>? children})
|
||||
class LoginRoute extends _i29.PageRouteInfo<void> {
|
||||
const LoginRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(LoginRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'LoginRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i12.LoginPage());
|
||||
return _i29.WrappedRoute(child: const _i12.LoginPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i13.MainPage]
|
||||
class MainRoute extends _i27.PageRouteInfo<void> {
|
||||
const MainRoute({List<_i27.PageRouteInfo>? children})
|
||||
class MainRoute extends _i29.PageRouteInfo<void> {
|
||||
const MainRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(MainRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'MainRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i13.MainPage();
|
||||
@@ -338,11 +342,11 @@ class MainRoute extends _i27.PageRouteInfo<void> {
|
||||
|
||||
/// generated route for
|
||||
/// [_i14.OrderDetailPage]
|
||||
class OrderDetailRoute extends _i27.PageRouteInfo<OrderDetailRouteArgs> {
|
||||
class OrderDetailRoute extends _i29.PageRouteInfo<OrderDetailRouteArgs> {
|
||||
OrderDetailRoute({
|
||||
_i28.Key? key,
|
||||
required _i29.Order order,
|
||||
List<_i27.PageRouteInfo>? children,
|
||||
_i30.Key? key,
|
||||
required _i31.Order order,
|
||||
List<_i29.PageRouteInfo>? children,
|
||||
}) : super(
|
||||
OrderDetailRoute.name,
|
||||
args: OrderDetailRouteArgs(key: key, order: order),
|
||||
@@ -351,7 +355,7 @@ class OrderDetailRoute extends _i27.PageRouteInfo<OrderDetailRouteArgs> {
|
||||
|
||||
static const String name = 'OrderDetailRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
final args = data.argsAs<OrderDetailRouteArgs>();
|
||||
@@ -363,9 +367,9 @@ class OrderDetailRoute extends _i27.PageRouteInfo<OrderDetailRouteArgs> {
|
||||
class OrderDetailRouteArgs {
|
||||
const OrderDetailRouteArgs({this.key, required this.order});
|
||||
|
||||
final _i28.Key? key;
|
||||
final _i30.Key? key;
|
||||
|
||||
final _i29.Order order;
|
||||
final _i31.Order order;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -375,91 +379,91 @@ class OrderDetailRouteArgs {
|
||||
|
||||
/// generated route for
|
||||
/// [_i15.OrderPage]
|
||||
class OrderRoute extends _i27.PageRouteInfo<void> {
|
||||
const OrderRoute({List<_i27.PageRouteInfo>? children})
|
||||
class OrderRoute extends _i29.PageRouteInfo<void> {
|
||||
const OrderRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(OrderRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'OrderRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i15.OrderPage());
|
||||
return _i29.WrappedRoute(child: const _i15.OrderPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i16.OutletInformationPage]
|
||||
class OutletInformationRoute extends _i27.PageRouteInfo<void> {
|
||||
const OutletInformationRoute({List<_i27.PageRouteInfo>? children})
|
||||
class OutletInformationRoute extends _i29.PageRouteInfo<void> {
|
||||
const OutletInformationRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(OutletInformationRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'OutletInformationRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i16.OutletInformationPage());
|
||||
return _i29.WrappedRoute(child: const _i16.OutletInformationPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i17.ProductAnalyticPage]
|
||||
class ProductAnalyticRoute extends _i27.PageRouteInfo<void> {
|
||||
const ProductAnalyticRoute({List<_i27.PageRouteInfo>? children})
|
||||
class ProductAnalyticRoute extends _i29.PageRouteInfo<void> {
|
||||
const ProductAnalyticRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ProductAnalyticRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ProductAnalyticRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i17.ProductAnalyticPage());
|
||||
return _i29.WrappedRoute(child: const _i17.ProductAnalyticPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i18.ProductPage]
|
||||
class ProductRoute extends _i27.PageRouteInfo<void> {
|
||||
const ProductRoute({List<_i27.PageRouteInfo>? children})
|
||||
class ProductRoute extends _i29.PageRouteInfo<void> {
|
||||
const ProductRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ProductRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ProductRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i18.ProductPage());
|
||||
return _i29.WrappedRoute(child: const _i18.ProductPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i19.ProfileChangePasswordPage]
|
||||
class ProfileChangePasswordRoute extends _i27.PageRouteInfo<void> {
|
||||
const ProfileChangePasswordRoute({List<_i27.PageRouteInfo>? children})
|
||||
class ProfileChangePasswordRoute extends _i29.PageRouteInfo<void> {
|
||||
const ProfileChangePasswordRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ProfileChangePasswordRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ProfileChangePasswordRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i19.ProfileChangePasswordPage());
|
||||
return _i29.WrappedRoute(child: const _i19.ProfileChangePasswordPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i20.ProfileEditPage]
|
||||
class ProfileEditRoute extends _i27.PageRouteInfo<ProfileEditRouteArgs> {
|
||||
class ProfileEditRoute extends _i29.PageRouteInfo<ProfileEditRouteArgs> {
|
||||
ProfileEditRoute({
|
||||
_i28.Key? key,
|
||||
required _i30.User user,
|
||||
List<_i27.PageRouteInfo>? children,
|
||||
_i30.Key? key,
|
||||
required _i32.User user,
|
||||
List<_i29.PageRouteInfo>? children,
|
||||
}) : super(
|
||||
ProfileEditRoute.name,
|
||||
args: ProfileEditRouteArgs(key: key, user: user),
|
||||
@@ -468,11 +472,11 @@ class ProfileEditRoute extends _i27.PageRouteInfo<ProfileEditRouteArgs> {
|
||||
|
||||
static const String name = 'ProfileEditRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
final args = data.argsAs<ProfileEditRouteArgs>();
|
||||
return _i27.WrappedRoute(
|
||||
return _i29.WrappedRoute(
|
||||
child: _i20.ProfileEditPage(key: args.key, user: args.user),
|
||||
);
|
||||
},
|
||||
@@ -482,9 +486,9 @@ class ProfileEditRoute extends _i27.PageRouteInfo<ProfileEditRouteArgs> {
|
||||
class ProfileEditRouteArgs {
|
||||
const ProfileEditRouteArgs({this.key, required this.user});
|
||||
|
||||
final _i28.Key? key;
|
||||
final _i30.Key? key;
|
||||
|
||||
final _i30.User user;
|
||||
final _i32.User user;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@@ -494,96 +498,179 @@ class ProfileEditRouteArgs {
|
||||
|
||||
/// generated route for
|
||||
/// [_i21.ProfilePage]
|
||||
class ProfileRoute extends _i27.PageRouteInfo<void> {
|
||||
const ProfileRoute({List<_i27.PageRouteInfo>? children})
|
||||
class ProfileRoute extends _i29.PageRouteInfo<void> {
|
||||
const ProfileRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ProfileRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ProfileRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i21.ProfilePage());
|
||||
return _i29.WrappedRoute(child: const _i21.ProfilePage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i22.PurchasePage]
|
||||
class PurchaseRoute extends _i27.PageRouteInfo<void> {
|
||||
const PurchaseRoute({List<_i27.PageRouteInfo>? children})
|
||||
/// [_i22.ProfitSharingDetailPage]
|
||||
class ProfitSharingDetailRoute
|
||||
extends _i29.PageRouteInfo<ProfitSharingDetailRouteArgs> {
|
||||
ProfitSharingDetailRoute({
|
||||
_i30.Key? key,
|
||||
required String parentCategoryId,
|
||||
required String parentCategoryName,
|
||||
required DateTime dateFrom,
|
||||
required DateTime dateTo,
|
||||
List<_i29.PageRouteInfo>? children,
|
||||
}) : super(
|
||||
ProfitSharingDetailRoute.name,
|
||||
args: ProfitSharingDetailRouteArgs(
|
||||
key: key,
|
||||
parentCategoryId: parentCategoryId,
|
||||
parentCategoryName: parentCategoryName,
|
||||
dateFrom: dateFrom,
|
||||
dateTo: dateTo,
|
||||
),
|
||||
initialChildren: children,
|
||||
);
|
||||
|
||||
static const String name = 'ProfitSharingDetailRoute';
|
||||
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
final args = data.argsAs<ProfitSharingDetailRouteArgs>();
|
||||
return _i29.WrappedRoute(
|
||||
child: _i22.ProfitSharingDetailPage(
|
||||
key: args.key,
|
||||
parentCategoryId: args.parentCategoryId,
|
||||
parentCategoryName: args.parentCategoryName,
|
||||
dateFrom: args.dateFrom,
|
||||
dateTo: args.dateTo,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class ProfitSharingDetailRouteArgs {
|
||||
const ProfitSharingDetailRouteArgs({
|
||||
this.key,
|
||||
required this.parentCategoryId,
|
||||
required this.parentCategoryName,
|
||||
required this.dateFrom,
|
||||
required this.dateTo,
|
||||
});
|
||||
|
||||
final _i30.Key? key;
|
||||
|
||||
final String parentCategoryId;
|
||||
|
||||
final String parentCategoryName;
|
||||
|
||||
final DateTime dateFrom;
|
||||
|
||||
final DateTime dateTo;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ProfitSharingDetailRouteArgs{key: $key, parentCategoryId: $parentCategoryId, parentCategoryName: $parentCategoryName, dateFrom: $dateFrom, dateTo: $dateTo}';
|
||||
}
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i23.ProfitSharingPage]
|
||||
class ProfitSharingRoute extends _i29.PageRouteInfo<void> {
|
||||
const ProfitSharingRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ProfitSharingRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ProfitSharingRoute';
|
||||
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i29.WrappedRoute(child: const _i23.ProfitSharingPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i24.PurchasePage]
|
||||
class PurchaseRoute extends _i29.PageRouteInfo<void> {
|
||||
const PurchaseRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(PurchaseRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'PurchaseRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i22.PurchasePage());
|
||||
return _i29.WrappedRoute(child: const _i24.PurchasePage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i23.ReportPage]
|
||||
class ReportRoute extends _i27.PageRouteInfo<void> {
|
||||
const ReportRoute({List<_i27.PageRouteInfo>? children})
|
||||
/// [_i25.ReportPage]
|
||||
class ReportRoute extends _i29.PageRouteInfo<void> {
|
||||
const ReportRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ReportRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ReportRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i23.ReportPage());
|
||||
return _i29.WrappedRoute(child: const _i25.ReportPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i24.SalesPage]
|
||||
class SalesRoute extends _i27.PageRouteInfo<void> {
|
||||
const SalesRoute({List<_i27.PageRouteInfo>? children})
|
||||
/// [_i26.SalesPage]
|
||||
class SalesRoute extends _i29.PageRouteInfo<void> {
|
||||
const SalesRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(SalesRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'SalesRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return _i27.WrappedRoute(child: const _i24.SalesPage());
|
||||
return _i29.WrappedRoute(child: const _i26.SalesPage());
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i25.SchedulePage]
|
||||
class ScheduleRoute extends _i27.PageRouteInfo<void> {
|
||||
const ScheduleRoute({List<_i27.PageRouteInfo>? children})
|
||||
/// [_i27.SchedulePage]
|
||||
class ScheduleRoute extends _i29.PageRouteInfo<void> {
|
||||
const ScheduleRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(ScheduleRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'ScheduleRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i25.SchedulePage();
|
||||
return const _i27.SchedulePage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// generated route for
|
||||
/// [_i26.SplashPage]
|
||||
class SplashRoute extends _i27.PageRouteInfo<void> {
|
||||
const SplashRoute({List<_i27.PageRouteInfo>? children})
|
||||
/// [_i28.SplashPage]
|
||||
class SplashRoute extends _i29.PageRouteInfo<void> {
|
||||
const SplashRoute({List<_i29.PageRouteInfo>? children})
|
||||
: super(SplashRoute.name, initialChildren: children);
|
||||
|
||||
static const String name = 'SplashRoute';
|
||||
|
||||
static _i27.PageInfo page = _i27.PageInfo(
|
||||
static _i29.PageInfo page = _i29.PageInfo(
|
||||
name,
|
||||
builder: (data) {
|
||||
return const _i26.SplashPage();
|
||||
return const _i28.SplashPage();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
+11
-11
@@ -841,10 +841,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
||||
sha256: "1ca20c894b1717686a2319b8548763d812bc0aabdac580420a44c5178c57a867"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.20.2"
|
||||
version: "0.20.3"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -937,10 +937,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||
sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.19"
|
||||
version: "0.12.20"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -953,10 +953,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
|
||||
sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
version: "1.19.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1526,10 +1526,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
|
||||
sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.11"
|
||||
version: "0.7.12"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1662,10 +1662,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
sha256: f36f9f3be64c6198714492bb455c11056e33e2f85d9a0b676a48301e44fdcf47
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.4.2"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1747,5 +1747,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.10.0-0 <4.0.0"
|
||||
dart: ">=3.11.0-0 <4.0.0"
|
||||
flutter: ">=3.29.0"
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ description: "A new Flutter project."
|
||||
|
||||
publish_to: "none"
|
||||
|
||||
version: 1.0.4+10
|
||||
version: 1.0.4+11
|
||||
|
||||
environment:
|
||||
sdk: ^3.8.1
|
||||
|
||||
Reference in New Issue
Block a user