feat: warehouse_and_distribution in killhouse module
This commit is contained in:
@@ -27,9 +27,14 @@ import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_ar
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
abstract class ChickenRemoteDatasource {
|
||||
Future<List<InventoryModel>?> getInventory({required String token, CancelToken? cancelToken});
|
||||
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({required String token});
|
||||
Future<List<InventoryModel>?> getInventory({
|
||||
required String token,
|
||||
required String role,
|
||||
CancelToken? cancelToken,
|
||||
});
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({
|
||||
required String token,
|
||||
});
|
||||
|
||||
Future<BarInformation?> getGeneralBarInformation({
|
||||
required String token,
|
||||
@@ -41,7 +46,10 @@ abstract class ChickenRemoteDatasource {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> setSateForArrivals({required String token, required Map<String, dynamic> request});
|
||||
Future<void> setSateForArrivals({
|
||||
required String token,
|
||||
required Map<String, dynamic> request,
|
||||
});
|
||||
|
||||
Future<PaginationModel<ImportedLoadsModel>?> getImportedLoadsModel({
|
||||
required String token,
|
||||
@@ -53,9 +61,15 @@ abstract class ChickenRemoteDatasource {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> confirmAllocation({required String token, required Map<String, dynamic> allocation});
|
||||
Future<void> confirmAllocation({
|
||||
required String token,
|
||||
required Map<String, dynamic> allocation,
|
||||
});
|
||||
|
||||
Future<void> denyAllocation({required String token, required String allocationToken});
|
||||
Future<void> denyAllocation({
|
||||
required String token,
|
||||
required String allocationToken,
|
||||
});
|
||||
|
||||
Future<void> confirmAllAllocation({
|
||||
required String token,
|
||||
@@ -81,7 +95,10 @@ abstract class ChickenRemoteDatasource {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> updateStewardAllocation({required String token, required ConformAllocation request});
|
||||
Future<void> updateStewardAllocation({
|
||||
required String token,
|
||||
required ConformAllocation request,
|
||||
});
|
||||
|
||||
Future<StewardFreeBarDashboard?> getStewardDashboard({
|
||||
required String token,
|
||||
@@ -95,7 +112,8 @@ abstract class ChickenRemoteDatasource {
|
||||
required String endDate,
|
||||
});
|
||||
|
||||
Future<PaginationModel<StewardFreeBar>?> getStewardPurchasesOutSideOfTheProvince({
|
||||
Future<PaginationModel<StewardFreeBar>?>
|
||||
getStewardPurchasesOutSideOfTheProvince({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
@@ -115,8 +133,8 @@ abstract class ChickenRemoteDatasource {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
|
||||
Future<PaginationModel<OutProvinceCarcassesBuyer>?> getOutProvinceCarcassesBuyer({
|
||||
Future<PaginationModel<OutProvinceCarcassesBuyer>?>
|
||||
getOutProvinceCarcassesBuyer({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
@@ -145,29 +163,42 @@ abstract class ChickenRemoteDatasource {
|
||||
required StewardFreeSaleBarRequest body,
|
||||
});
|
||||
|
||||
|
||||
Future<void> deleteOutProvinceStewardFreeBar({
|
||||
required String token,
|
||||
required String key
|
||||
required String key,
|
||||
});
|
||||
|
||||
|
||||
Future<UserProfile?> getUserProfile({required String token});
|
||||
|
||||
Future<void> updateUserProfile({required String token, required UserProfile userProfile});
|
||||
Future<void> updateUserProfile({
|
||||
required String token,
|
||||
required UserProfile userProfile,
|
||||
});
|
||||
|
||||
Future<void> updatePassword({required String token, required ChangePasswordRequestModel model});
|
||||
Future<void> updatePassword({
|
||||
required String token,
|
||||
required ChangePasswordRequestModel model,
|
||||
});
|
||||
|
||||
Future<PaginationModel<SegmentationModel>?> getSegmentation({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> createSegmentation({required String token, required SegmentationModel model});
|
||||
Future<void> createSegmentation({
|
||||
required String token,
|
||||
required SegmentationModel model,
|
||||
});
|
||||
|
||||
Future<void> editSegmentation({required String token, required SegmentationModel model});
|
||||
Future<void> editSegmentation({
|
||||
required String token,
|
||||
required SegmentationModel model,
|
||||
});
|
||||
|
||||
Future<SegmentationModel?> deleteSegmentation({required String token, required String key});
|
||||
Future<SegmentationModel?> deleteSegmentation({
|
||||
required String token,
|
||||
required String key,
|
||||
});
|
||||
|
||||
Future<BroadcastPrice?> getBroadcastPrice({required String token});
|
||||
|
||||
|
||||
@@ -36,21 +36,25 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
@override
|
||||
Future<List<InventoryModel>?> getInventory({
|
||||
required String token,
|
||||
required String role,
|
||||
CancelToken? cancelToken,
|
||||
}) async {
|
||||
var res = await _httpClient.get(
|
||||
'/roles-products/?role=Steward',
|
||||
'/roles-products/?role=$role',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
|
||||
fromJsonList: (json) =>
|
||||
(json).map((item) => InventoryModel.fromJson(item as Map<String, dynamic>)).toList(),
|
||||
fromJsonList: (json) => (json)
|
||||
.map((item) => InventoryModel.fromJson(item as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
return res.data;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({required String token}) async {
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({
|
||||
required String token,
|
||||
}) async {
|
||||
var res = await _httpClient.get(
|
||||
'/kill-house-distribution-info/?role=Steward',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
@@ -150,7 +154,10 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> denyAllocation({required String token, required String allocationToken}) async {
|
||||
Future<void> denyAllocation({
|
||||
required String token,
|
||||
required String allocationToken,
|
||||
}) async {
|
||||
await _httpClient.delete(
|
||||
'/steward-allocation/0/?steward_allocation_key=$allocationToken',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
@@ -174,8 +181,9 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
var res = await _httpClient.get(
|
||||
'/roles-products/?role=Steward',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
fromJsonList: (json) =>
|
||||
json.map((item) => ProductModel.fromJson(item as Map<String, dynamic>)).toList(),
|
||||
fromJsonList: (json) => json
|
||||
.map((item) => ProductModel.fromJson(item as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
return res.data;
|
||||
}
|
||||
@@ -189,8 +197,9 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
'/guilds/',
|
||||
queryParameters: queryParameters,
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
fromJsonList: (json) =>
|
||||
json.map((item) => GuildModel.fromJson(item as Map<String, dynamic>)).toList(),
|
||||
fromJsonList: (json) => json
|
||||
.map((item) => GuildModel.fromJson(item as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
return res.data;
|
||||
}
|
||||
@@ -270,7 +279,8 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PaginationModel<StewardFreeBar>?> getStewardPurchasesOutSideOfTheProvince({
|
||||
Future<PaginationModel<StewardFreeBar>?>
|
||||
getStewardPurchasesOutSideOfTheProvince({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
}) async {
|
||||
@@ -287,22 +297,34 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<IranProvinceCityModel>?> getCity({required String provinceName}) async {
|
||||
Future<List<IranProvinceCityModel>?> getCity({
|
||||
required String provinceName,
|
||||
}) async {
|
||||
var res = await _httpClient.get(
|
||||
'/iran_city/',
|
||||
queryParameters: {'name': provinceName},
|
||||
fromJsonList: (json) =>
|
||||
json.map((item) => IranProvinceCityModel.fromJson(item as Map<String, dynamic>)).toList(),
|
||||
fromJsonList: (json) => json
|
||||
.map(
|
||||
(item) =>
|
||||
IranProvinceCityModel.fromJson(item as Map<String, dynamic>),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
return res.data;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<IranProvinceCityModel>?> getProvince({CancelToken? cancelToken}) async {
|
||||
Future<List<IranProvinceCityModel>?> getProvince({
|
||||
CancelToken? cancelToken,
|
||||
}) async {
|
||||
var res = await _httpClient.get(
|
||||
'/iran_province/',
|
||||
fromJsonList: (json) =>
|
||||
json.map((item) => IranProvinceCityModel.fromJson(item as Map<String, dynamic>)).toList(),
|
||||
fromJsonList: (json) => json
|
||||
.map(
|
||||
(item) =>
|
||||
IranProvinceCityModel.fromJson(item as Map<String, dynamic>),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
return res.data;
|
||||
}
|
||||
@@ -315,7 +337,7 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
await _httpClient.post(
|
||||
'/steward_free_bar/',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
data: body.toJson()..removeWhere((key, value) => value==null,),
|
||||
data: body.toJson()..removeWhere((key, value) => value == null),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -346,7 +368,8 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PaginationModel<OutProvinceCarcassesBuyer>?> getOutProvinceCarcassesBuyer({
|
||||
Future<PaginationModel<OutProvinceCarcassesBuyer>?>
|
||||
getOutProvinceCarcassesBuyer({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
}) async {
|
||||
@@ -356,7 +379,8 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
fromJson: (json) => PaginationModel<OutProvinceCarcassesBuyer>.fromJson(
|
||||
json,
|
||||
(json) => OutProvinceCarcassesBuyer.fromJson(json as Map<String, dynamic>),
|
||||
(json) =>
|
||||
OutProvinceCarcassesBuyer.fromJson(json as Map<String, dynamic>),
|
||||
),
|
||||
);
|
||||
return res.data;
|
||||
@@ -412,13 +436,19 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
'/steward_free_sale_bar/0/',
|
||||
data: body.toJson()
|
||||
..removeWhere((key, value) => value == null)
|
||||
..addAll({'carcassWeight': body.weightOfCarcasses, 'carcassCount': body.numberOfCarcasses}),
|
||||
..addAll({
|
||||
'carcassWeight': body.weightOfCarcasses,
|
||||
'carcassCount': body.numberOfCarcasses,
|
||||
}),
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteOutProvinceStewardFreeBar({required String token, required String key}) async {
|
||||
Future<void> deleteOutProvinceStewardFreeBar({
|
||||
required String token,
|
||||
required String key,
|
||||
}) async {
|
||||
await _httpClient.delete(
|
||||
'/steward_free_sale_bar/0/',
|
||||
queryParameters: {'key': key},
|
||||
@@ -438,7 +468,10 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateUserProfile({required String token, required UserProfile userProfile}) async {
|
||||
Future<void> updateUserProfile({
|
||||
required String token,
|
||||
required UserProfile userProfile,
|
||||
}) async {
|
||||
await _httpClient.put(
|
||||
'/system_user_profile/0/',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
@@ -476,7 +509,10 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createSegmentation({required String token, required SegmentationModel model}) async {
|
||||
Future<void> createSegmentation({
|
||||
required String token,
|
||||
required SegmentationModel model,
|
||||
}) async {
|
||||
await _httpClient.post(
|
||||
'/app-segmentation/',
|
||||
data: model.toJson()..removeWhere((key, value) => value == null),
|
||||
@@ -485,7 +521,10 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> editSegmentation({required String token, required SegmentationModel model}) async {
|
||||
Future<void> editSegmentation({
|
||||
required String token,
|
||||
required SegmentationModel model,
|
||||
}) async {
|
||||
await _httpClient.put(
|
||||
'/app-segmentation/0/',
|
||||
data: model.toJson()..removeWhere((key, value) => value == null),
|
||||
@@ -536,7 +575,9 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<StewardRemainWeight?> getStewardRemainWeight({required String token}) async {
|
||||
Future<StewardRemainWeight?> getStewardRemainWeight({
|
||||
required String token,
|
||||
}) async {
|
||||
var res = await _httpClient.get(
|
||||
'/steward-remain-weight/',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
@@ -545,4 +586,5 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource {
|
||||
|
||||
return res.data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,8 +2,12 @@ import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/response/kill_house/kill_house_response.dart';
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/response/kill_request_list/kill_request_list.dart'
|
||||
as listModel;
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/warehouse_and_distribution/response/kill_house_sales_info_dashboard.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
abstract class KillHouseRemoteDataSource {
|
||||
|
||||
//region requestKill
|
||||
Future<List<KillHouseResponse>?> getKillHouseList({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
@@ -22,4 +26,21 @@ abstract class KillHouseRemoteDataSource {
|
||||
});
|
||||
|
||||
Future<void> deleteKillRequest({required String token, required int requestId});
|
||||
//endregion
|
||||
|
||||
//region warehouseAndDistribution
|
||||
|
||||
Future<KillHouseSalesInfoDashboard?> getKillHouseSalesInfoDashboard({
|
||||
required String token,
|
||||
CancelToken? cancelToken,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/response/kill_house/kill_house_response.dart';
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/response/kill_request_list/kill_request_list.dart'
|
||||
as listModel;
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/warehouse_and_distribution/response/kill_house_sales_info_dashboard.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class KillHouseRemoteDataSourceImpl extends KillHouseRemoteDataSource {
|
||||
@@ -20,7 +21,9 @@ class KillHouseRemoteDataSourceImpl extends KillHouseRemoteDataSource {
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
fromJson: (json) {
|
||||
var data = json['results'] as List<dynamic>;
|
||||
return ChickenCommissionPrices.fromJson(data.first as Map<String, dynamic>);
|
||||
return ChickenCommissionPrices.fromJson(
|
||||
data.first as Map<String, dynamic>,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -35,8 +38,9 @@ class KillHouseRemoteDataSourceImpl extends KillHouseRemoteDataSource {
|
||||
var res = await _httpClient.get(
|
||||
'/kill_house/?kill_house',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
fromJsonList: (json) =>
|
||||
json.map((e) => KillHouseResponse.fromJson(e as Map<String, dynamic>)).toList(),
|
||||
fromJsonList: (json) => json
|
||||
.map((e) => KillHouseResponse.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
return res.data;
|
||||
@@ -63,18 +67,47 @@ class KillHouseRemoteDataSourceImpl extends KillHouseRemoteDataSource {
|
||||
'/kill_request/',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
queryParameters: queryParameters,
|
||||
fromJsonList: (json) =>
|
||||
json.map((e) => listModel.KillRequestList.fromJson(e as Map<String, dynamic>)).toList(),
|
||||
fromJsonList: (json) => json
|
||||
.map(
|
||||
(e) =>
|
||||
listModel.KillRequestList.fromJson(e as Map<String, dynamic>),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
|
||||
return res.data;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteKillRequest({required String token, required int requestId}) async {
|
||||
Future<void> deleteKillRequest({
|
||||
required String token,
|
||||
required int requestId,
|
||||
}) async {
|
||||
await _httpClient.delete(
|
||||
'/kill_request/$requestId/',
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
);
|
||||
}
|
||||
|
||||
//endregion
|
||||
//region warehouseAndDistribution
|
||||
@override
|
||||
Future<KillHouseSalesInfoDashboard?> getKillHouseSalesInfoDashboard({
|
||||
required String token,
|
||||
CancelToken? cancelToken,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
}) async {
|
||||
var res = await _httpClient.get(
|
||||
'/kill-house-sales-info-dashboard/?role=KillHouse',
|
||||
|
||||
cancelToken: cancelToken,
|
||||
headers: {'Authorization': 'Bearer $token'},
|
||||
queryParameters: queryParameters,
|
||||
fromJson: KillHouseSalesInfoDashboard.fromJson,
|
||||
);
|
||||
|
||||
return res.data;
|
||||
}
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'kill_house_sales_info_dashboard.freezed.dart';
|
||||
part 'kill_house_sales_info_dashboard.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class KillHouseSalesInfoDashboard with _$KillHouseSalesInfoDashboard {
|
||||
const factory KillHouseSalesInfoDashboard({
|
||||
double? totalGovernmentalInputWeight,
|
||||
double? totalFreeInputWeight,
|
||||
double? totalGovernmentalOutputWeight,
|
||||
double? totalFreeOutputWeight,
|
||||
double? totalGovernmentalRemainWeight,
|
||||
double? totalFreeRemainWeight,
|
||||
@JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight')
|
||||
double? totalKillHouseFreeSaleBarCarcassesWeight,
|
||||
double? totalKillHouseAllocationsWeight,
|
||||
double? segmentationsWeight,
|
||||
double? coldHouseAllocationsWeight,
|
||||
double? totalSellingInProvinceGovernmentalWeight,
|
||||
double? totalSellingInProvinceFreeWeight,
|
||||
double? totalCommitmentSellingInProvinceGovernmentalWeight,
|
||||
double? totalCommitmentSellingInProvinceGovernmentalRemainWeight,
|
||||
double? totalCommitmentSellingInProvinceFreeWeight,
|
||||
double? totalCommitmentSellingInProvinceFreeRemainWeight,
|
||||
double? posAllocatedWeight,
|
||||
double? posGovernmentalAllocatedWeight,
|
||||
double? posFreeAllocatedWeight,
|
||||
double? wareHouseArchiveGovernmentalWeight,
|
||||
double? wareHouseArchiveFreeWeight,
|
||||
}) = _KillHouseSalesInfoDashboard;
|
||||
|
||||
factory KillHouseSalesInfoDashboard.fromJson(Map<String, dynamic> json) =>
|
||||
_$KillHouseSalesInfoDashboardFromJson(json);
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// 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 'kill_house_sales_info_dashboard.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$KillHouseSalesInfoDashboard {
|
||||
|
||||
double? get totalGovernmentalInputWeight; double? get totalFreeInputWeight; double? get totalGovernmentalOutputWeight; double? get totalFreeOutputWeight; double? get totalGovernmentalRemainWeight; double? get totalFreeRemainWeight;@JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') double? get totalKillHouseFreeSaleBarCarcassesWeight; double? get totalKillHouseAllocationsWeight; double? get segmentationsWeight; double? get coldHouseAllocationsWeight; double? get totalSellingInProvinceGovernmentalWeight; double? get totalSellingInProvinceFreeWeight; double? get totalCommitmentSellingInProvinceGovernmentalWeight; double? get totalCommitmentSellingInProvinceGovernmentalRemainWeight; double? get totalCommitmentSellingInProvinceFreeWeight; double? get totalCommitmentSellingInProvinceFreeRemainWeight; double? get posAllocatedWeight; double? get posGovernmentalAllocatedWeight; double? get posFreeAllocatedWeight; double? get wareHouseArchiveGovernmentalWeight; double? get wareHouseArchiveFreeWeight;
|
||||
/// Create a copy of KillHouseSalesInfoDashboard
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$KillHouseSalesInfoDashboardCopyWith<KillHouseSalesInfoDashboard> get copyWith => _$KillHouseSalesInfoDashboardCopyWithImpl<KillHouseSalesInfoDashboard>(this as KillHouseSalesInfoDashboard, _$identity);
|
||||
|
||||
/// Serializes this KillHouseSalesInfoDashboard to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is KillHouseSalesInfoDashboard&&(identical(other.totalGovernmentalInputWeight, totalGovernmentalInputWeight) || other.totalGovernmentalInputWeight == totalGovernmentalInputWeight)&&(identical(other.totalFreeInputWeight, totalFreeInputWeight) || other.totalFreeInputWeight == totalFreeInputWeight)&&(identical(other.totalGovernmentalOutputWeight, totalGovernmentalOutputWeight) || other.totalGovernmentalOutputWeight == totalGovernmentalOutputWeight)&&(identical(other.totalFreeOutputWeight, totalFreeOutputWeight) || other.totalFreeOutputWeight == totalFreeOutputWeight)&&(identical(other.totalGovernmentalRemainWeight, totalGovernmentalRemainWeight) || other.totalGovernmentalRemainWeight == totalGovernmentalRemainWeight)&&(identical(other.totalFreeRemainWeight, totalFreeRemainWeight) || other.totalFreeRemainWeight == totalFreeRemainWeight)&&(identical(other.totalKillHouseFreeSaleBarCarcassesWeight, totalKillHouseFreeSaleBarCarcassesWeight) || other.totalKillHouseFreeSaleBarCarcassesWeight == totalKillHouseFreeSaleBarCarcassesWeight)&&(identical(other.totalKillHouseAllocationsWeight, totalKillHouseAllocationsWeight) || other.totalKillHouseAllocationsWeight == totalKillHouseAllocationsWeight)&&(identical(other.segmentationsWeight, segmentationsWeight) || other.segmentationsWeight == segmentationsWeight)&&(identical(other.coldHouseAllocationsWeight, coldHouseAllocationsWeight) || other.coldHouseAllocationsWeight == coldHouseAllocationsWeight)&&(identical(other.totalSellingInProvinceGovernmentalWeight, totalSellingInProvinceGovernmentalWeight) || other.totalSellingInProvinceGovernmentalWeight == totalSellingInProvinceGovernmentalWeight)&&(identical(other.totalSellingInProvinceFreeWeight, totalSellingInProvinceFreeWeight) || other.totalSellingInProvinceFreeWeight == totalSellingInProvinceFreeWeight)&&(identical(other.totalCommitmentSellingInProvinceGovernmentalWeight, totalCommitmentSellingInProvinceGovernmentalWeight) || other.totalCommitmentSellingInProvinceGovernmentalWeight == totalCommitmentSellingInProvinceGovernmentalWeight)&&(identical(other.totalCommitmentSellingInProvinceGovernmentalRemainWeight, totalCommitmentSellingInProvinceGovernmentalRemainWeight) || other.totalCommitmentSellingInProvinceGovernmentalRemainWeight == totalCommitmentSellingInProvinceGovernmentalRemainWeight)&&(identical(other.totalCommitmentSellingInProvinceFreeWeight, totalCommitmentSellingInProvinceFreeWeight) || other.totalCommitmentSellingInProvinceFreeWeight == totalCommitmentSellingInProvinceFreeWeight)&&(identical(other.totalCommitmentSellingInProvinceFreeRemainWeight, totalCommitmentSellingInProvinceFreeRemainWeight) || other.totalCommitmentSellingInProvinceFreeRemainWeight == totalCommitmentSellingInProvinceFreeRemainWeight)&&(identical(other.posAllocatedWeight, posAllocatedWeight) || other.posAllocatedWeight == posAllocatedWeight)&&(identical(other.posGovernmentalAllocatedWeight, posGovernmentalAllocatedWeight) || other.posGovernmentalAllocatedWeight == posGovernmentalAllocatedWeight)&&(identical(other.posFreeAllocatedWeight, posFreeAllocatedWeight) || other.posFreeAllocatedWeight == posFreeAllocatedWeight)&&(identical(other.wareHouseArchiveGovernmentalWeight, wareHouseArchiveGovernmentalWeight) || other.wareHouseArchiveGovernmentalWeight == wareHouseArchiveGovernmentalWeight)&&(identical(other.wareHouseArchiveFreeWeight, wareHouseArchiveFreeWeight) || other.wareHouseArchiveFreeWeight == wareHouseArchiveFreeWeight));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hashAll([runtimeType,totalGovernmentalInputWeight,totalFreeInputWeight,totalGovernmentalOutputWeight,totalFreeOutputWeight,totalGovernmentalRemainWeight,totalFreeRemainWeight,totalKillHouseFreeSaleBarCarcassesWeight,totalKillHouseAllocationsWeight,segmentationsWeight,coldHouseAllocationsWeight,totalSellingInProvinceGovernmentalWeight,totalSellingInProvinceFreeWeight,totalCommitmentSellingInProvinceGovernmentalWeight,totalCommitmentSellingInProvinceGovernmentalRemainWeight,totalCommitmentSellingInProvinceFreeWeight,totalCommitmentSellingInProvinceFreeRemainWeight,posAllocatedWeight,posGovernmentalAllocatedWeight,posFreeAllocatedWeight,wareHouseArchiveGovernmentalWeight,wareHouseArchiveFreeWeight]);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'KillHouseSalesInfoDashboard(totalGovernmentalInputWeight: $totalGovernmentalInputWeight, totalFreeInputWeight: $totalFreeInputWeight, totalGovernmentalOutputWeight: $totalGovernmentalOutputWeight, totalFreeOutputWeight: $totalFreeOutputWeight, totalGovernmentalRemainWeight: $totalGovernmentalRemainWeight, totalFreeRemainWeight: $totalFreeRemainWeight, totalKillHouseFreeSaleBarCarcassesWeight: $totalKillHouseFreeSaleBarCarcassesWeight, totalKillHouseAllocationsWeight: $totalKillHouseAllocationsWeight, segmentationsWeight: $segmentationsWeight, coldHouseAllocationsWeight: $coldHouseAllocationsWeight, totalSellingInProvinceGovernmentalWeight: $totalSellingInProvinceGovernmentalWeight, totalSellingInProvinceFreeWeight: $totalSellingInProvinceFreeWeight, totalCommitmentSellingInProvinceGovernmentalWeight: $totalCommitmentSellingInProvinceGovernmentalWeight, totalCommitmentSellingInProvinceGovernmentalRemainWeight: $totalCommitmentSellingInProvinceGovernmentalRemainWeight, totalCommitmentSellingInProvinceFreeWeight: $totalCommitmentSellingInProvinceFreeWeight, totalCommitmentSellingInProvinceFreeRemainWeight: $totalCommitmentSellingInProvinceFreeRemainWeight, posAllocatedWeight: $posAllocatedWeight, posGovernmentalAllocatedWeight: $posGovernmentalAllocatedWeight, posFreeAllocatedWeight: $posFreeAllocatedWeight, wareHouseArchiveGovernmentalWeight: $wareHouseArchiveGovernmentalWeight, wareHouseArchiveFreeWeight: $wareHouseArchiveFreeWeight)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $KillHouseSalesInfoDashboardCopyWith<$Res> {
|
||||
factory $KillHouseSalesInfoDashboardCopyWith(KillHouseSalesInfoDashboard value, $Res Function(KillHouseSalesInfoDashboard) _then) = _$KillHouseSalesInfoDashboardCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
double? totalGovernmentalInputWeight, double? totalFreeInputWeight, double? totalGovernmentalOutputWeight, double? totalFreeOutputWeight, double? totalGovernmentalRemainWeight, double? totalFreeRemainWeight,@JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') double? totalKillHouseFreeSaleBarCarcassesWeight, double? totalKillHouseAllocationsWeight, double? segmentationsWeight, double? coldHouseAllocationsWeight, double? totalSellingInProvinceGovernmentalWeight, double? totalSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceGovernmentalWeight, double? totalCommitmentSellingInProvinceGovernmentalRemainWeight, double? totalCommitmentSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceFreeRemainWeight, double? posAllocatedWeight, double? posGovernmentalAllocatedWeight, double? posFreeAllocatedWeight, double? wareHouseArchiveGovernmentalWeight, double? wareHouseArchiveFreeWeight
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$KillHouseSalesInfoDashboardCopyWithImpl<$Res>
|
||||
implements $KillHouseSalesInfoDashboardCopyWith<$Res> {
|
||||
_$KillHouseSalesInfoDashboardCopyWithImpl(this._self, this._then);
|
||||
|
||||
final KillHouseSalesInfoDashboard _self;
|
||||
final $Res Function(KillHouseSalesInfoDashboard) _then;
|
||||
|
||||
/// Create a copy of KillHouseSalesInfoDashboard
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? totalGovernmentalInputWeight = freezed,Object? totalFreeInputWeight = freezed,Object? totalGovernmentalOutputWeight = freezed,Object? totalFreeOutputWeight = freezed,Object? totalGovernmentalRemainWeight = freezed,Object? totalFreeRemainWeight = freezed,Object? totalKillHouseFreeSaleBarCarcassesWeight = freezed,Object? totalKillHouseAllocationsWeight = freezed,Object? segmentationsWeight = freezed,Object? coldHouseAllocationsWeight = freezed,Object? totalSellingInProvinceGovernmentalWeight = freezed,Object? totalSellingInProvinceFreeWeight = freezed,Object? totalCommitmentSellingInProvinceGovernmentalWeight = freezed,Object? totalCommitmentSellingInProvinceGovernmentalRemainWeight = freezed,Object? totalCommitmentSellingInProvinceFreeWeight = freezed,Object? totalCommitmentSellingInProvinceFreeRemainWeight = freezed,Object? posAllocatedWeight = freezed,Object? posGovernmentalAllocatedWeight = freezed,Object? posFreeAllocatedWeight = freezed,Object? wareHouseArchiveGovernmentalWeight = freezed,Object? wareHouseArchiveFreeWeight = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
totalGovernmentalInputWeight: freezed == totalGovernmentalInputWeight ? _self.totalGovernmentalInputWeight : totalGovernmentalInputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalFreeInputWeight: freezed == totalFreeInputWeight ? _self.totalFreeInputWeight : totalFreeInputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalGovernmentalOutputWeight: freezed == totalGovernmentalOutputWeight ? _self.totalGovernmentalOutputWeight : totalGovernmentalOutputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalFreeOutputWeight: freezed == totalFreeOutputWeight ? _self.totalFreeOutputWeight : totalFreeOutputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalGovernmentalRemainWeight: freezed == totalGovernmentalRemainWeight ? _self.totalGovernmentalRemainWeight : totalGovernmentalRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalFreeRemainWeight: freezed == totalFreeRemainWeight ? _self.totalFreeRemainWeight : totalFreeRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalKillHouseFreeSaleBarCarcassesWeight: freezed == totalKillHouseFreeSaleBarCarcassesWeight ? _self.totalKillHouseFreeSaleBarCarcassesWeight : totalKillHouseFreeSaleBarCarcassesWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalKillHouseAllocationsWeight: freezed == totalKillHouseAllocationsWeight ? _self.totalKillHouseAllocationsWeight : totalKillHouseAllocationsWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,segmentationsWeight: freezed == segmentationsWeight ? _self.segmentationsWeight : segmentationsWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,coldHouseAllocationsWeight: freezed == coldHouseAllocationsWeight ? _self.coldHouseAllocationsWeight : coldHouseAllocationsWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalSellingInProvinceGovernmentalWeight: freezed == totalSellingInProvinceGovernmentalWeight ? _self.totalSellingInProvinceGovernmentalWeight : totalSellingInProvinceGovernmentalWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalSellingInProvinceFreeWeight: freezed == totalSellingInProvinceFreeWeight ? _self.totalSellingInProvinceFreeWeight : totalSellingInProvinceFreeWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceGovernmentalWeight: freezed == totalCommitmentSellingInProvinceGovernmentalWeight ? _self.totalCommitmentSellingInProvinceGovernmentalWeight : totalCommitmentSellingInProvinceGovernmentalWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceGovernmentalRemainWeight: freezed == totalCommitmentSellingInProvinceGovernmentalRemainWeight ? _self.totalCommitmentSellingInProvinceGovernmentalRemainWeight : totalCommitmentSellingInProvinceGovernmentalRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceFreeWeight: freezed == totalCommitmentSellingInProvinceFreeWeight ? _self.totalCommitmentSellingInProvinceFreeWeight : totalCommitmentSellingInProvinceFreeWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceFreeRemainWeight: freezed == totalCommitmentSellingInProvinceFreeRemainWeight ? _self.totalCommitmentSellingInProvinceFreeRemainWeight : totalCommitmentSellingInProvinceFreeRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,posAllocatedWeight: freezed == posAllocatedWeight ? _self.posAllocatedWeight : posAllocatedWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,posGovernmentalAllocatedWeight: freezed == posGovernmentalAllocatedWeight ? _self.posGovernmentalAllocatedWeight : posGovernmentalAllocatedWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,posFreeAllocatedWeight: freezed == posFreeAllocatedWeight ? _self.posFreeAllocatedWeight : posFreeAllocatedWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,wareHouseArchiveGovernmentalWeight: freezed == wareHouseArchiveGovernmentalWeight ? _self.wareHouseArchiveGovernmentalWeight : wareHouseArchiveGovernmentalWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,wareHouseArchiveFreeWeight: freezed == wareHouseArchiveFreeWeight ? _self.wareHouseArchiveFreeWeight : wareHouseArchiveFreeWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [KillHouseSalesInfoDashboard].
|
||||
extension KillHouseSalesInfoDashboardPatterns on KillHouseSalesInfoDashboard {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _KillHouseSalesInfoDashboard value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _KillHouseSalesInfoDashboard() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _KillHouseSalesInfoDashboard value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _KillHouseSalesInfoDashboard():
|
||||
return $default(_that);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _KillHouseSalesInfoDashboard value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _KillHouseSalesInfoDashboard() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( double? totalGovernmentalInputWeight, double? totalFreeInputWeight, double? totalGovernmentalOutputWeight, double? totalFreeOutputWeight, double? totalGovernmentalRemainWeight, double? totalFreeRemainWeight, @JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') double? totalKillHouseFreeSaleBarCarcassesWeight, double? totalKillHouseAllocationsWeight, double? segmentationsWeight, double? coldHouseAllocationsWeight, double? totalSellingInProvinceGovernmentalWeight, double? totalSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceGovernmentalWeight, double? totalCommitmentSellingInProvinceGovernmentalRemainWeight, double? totalCommitmentSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceFreeRemainWeight, double? posAllocatedWeight, double? posGovernmentalAllocatedWeight, double? posFreeAllocatedWeight, double? wareHouseArchiveGovernmentalWeight, double? wareHouseArchiveFreeWeight)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _KillHouseSalesInfoDashboard() when $default != null:
|
||||
return $default(_that.totalGovernmentalInputWeight,_that.totalFreeInputWeight,_that.totalGovernmentalOutputWeight,_that.totalFreeOutputWeight,_that.totalGovernmentalRemainWeight,_that.totalFreeRemainWeight,_that.totalKillHouseFreeSaleBarCarcassesWeight,_that.totalKillHouseAllocationsWeight,_that.segmentationsWeight,_that.coldHouseAllocationsWeight,_that.totalSellingInProvinceGovernmentalWeight,_that.totalSellingInProvinceFreeWeight,_that.totalCommitmentSellingInProvinceGovernmentalWeight,_that.totalCommitmentSellingInProvinceGovernmentalRemainWeight,_that.totalCommitmentSellingInProvinceFreeWeight,_that.totalCommitmentSellingInProvinceFreeRemainWeight,_that.posAllocatedWeight,_that.posGovernmentalAllocatedWeight,_that.posFreeAllocatedWeight,_that.wareHouseArchiveGovernmentalWeight,_that.wareHouseArchiveFreeWeight);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( double? totalGovernmentalInputWeight, double? totalFreeInputWeight, double? totalGovernmentalOutputWeight, double? totalFreeOutputWeight, double? totalGovernmentalRemainWeight, double? totalFreeRemainWeight, @JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') double? totalKillHouseFreeSaleBarCarcassesWeight, double? totalKillHouseAllocationsWeight, double? segmentationsWeight, double? coldHouseAllocationsWeight, double? totalSellingInProvinceGovernmentalWeight, double? totalSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceGovernmentalWeight, double? totalCommitmentSellingInProvinceGovernmentalRemainWeight, double? totalCommitmentSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceFreeRemainWeight, double? posAllocatedWeight, double? posGovernmentalAllocatedWeight, double? posFreeAllocatedWeight, double? wareHouseArchiveGovernmentalWeight, double? wareHouseArchiveFreeWeight) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _KillHouseSalesInfoDashboard():
|
||||
return $default(_that.totalGovernmentalInputWeight,_that.totalFreeInputWeight,_that.totalGovernmentalOutputWeight,_that.totalFreeOutputWeight,_that.totalGovernmentalRemainWeight,_that.totalFreeRemainWeight,_that.totalKillHouseFreeSaleBarCarcassesWeight,_that.totalKillHouseAllocationsWeight,_that.segmentationsWeight,_that.coldHouseAllocationsWeight,_that.totalSellingInProvinceGovernmentalWeight,_that.totalSellingInProvinceFreeWeight,_that.totalCommitmentSellingInProvinceGovernmentalWeight,_that.totalCommitmentSellingInProvinceGovernmentalRemainWeight,_that.totalCommitmentSellingInProvinceFreeWeight,_that.totalCommitmentSellingInProvinceFreeRemainWeight,_that.posAllocatedWeight,_that.posGovernmentalAllocatedWeight,_that.posFreeAllocatedWeight,_that.wareHouseArchiveGovernmentalWeight,_that.wareHouseArchiveFreeWeight);case _:
|
||||
throw StateError('Unexpected subclass');
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( double? totalGovernmentalInputWeight, double? totalFreeInputWeight, double? totalGovernmentalOutputWeight, double? totalFreeOutputWeight, double? totalGovernmentalRemainWeight, double? totalFreeRemainWeight, @JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') double? totalKillHouseFreeSaleBarCarcassesWeight, double? totalKillHouseAllocationsWeight, double? segmentationsWeight, double? coldHouseAllocationsWeight, double? totalSellingInProvinceGovernmentalWeight, double? totalSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceGovernmentalWeight, double? totalCommitmentSellingInProvinceGovernmentalRemainWeight, double? totalCommitmentSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceFreeRemainWeight, double? posAllocatedWeight, double? posGovernmentalAllocatedWeight, double? posFreeAllocatedWeight, double? wareHouseArchiveGovernmentalWeight, double? wareHouseArchiveFreeWeight)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _KillHouseSalesInfoDashboard() when $default != null:
|
||||
return $default(_that.totalGovernmentalInputWeight,_that.totalFreeInputWeight,_that.totalGovernmentalOutputWeight,_that.totalFreeOutputWeight,_that.totalGovernmentalRemainWeight,_that.totalFreeRemainWeight,_that.totalKillHouseFreeSaleBarCarcassesWeight,_that.totalKillHouseAllocationsWeight,_that.segmentationsWeight,_that.coldHouseAllocationsWeight,_that.totalSellingInProvinceGovernmentalWeight,_that.totalSellingInProvinceFreeWeight,_that.totalCommitmentSellingInProvinceGovernmentalWeight,_that.totalCommitmentSellingInProvinceGovernmentalRemainWeight,_that.totalCommitmentSellingInProvinceFreeWeight,_that.totalCommitmentSellingInProvinceFreeRemainWeight,_that.posAllocatedWeight,_that.posGovernmentalAllocatedWeight,_that.posFreeAllocatedWeight,_that.wareHouseArchiveGovernmentalWeight,_that.wareHouseArchiveFreeWeight);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _KillHouseSalesInfoDashboard implements KillHouseSalesInfoDashboard {
|
||||
const _KillHouseSalesInfoDashboard({this.totalGovernmentalInputWeight, this.totalFreeInputWeight, this.totalGovernmentalOutputWeight, this.totalFreeOutputWeight, this.totalGovernmentalRemainWeight, this.totalFreeRemainWeight, @JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') this.totalKillHouseFreeSaleBarCarcassesWeight, this.totalKillHouseAllocationsWeight, this.segmentationsWeight, this.coldHouseAllocationsWeight, this.totalSellingInProvinceGovernmentalWeight, this.totalSellingInProvinceFreeWeight, this.totalCommitmentSellingInProvinceGovernmentalWeight, this.totalCommitmentSellingInProvinceGovernmentalRemainWeight, this.totalCommitmentSellingInProvinceFreeWeight, this.totalCommitmentSellingInProvinceFreeRemainWeight, this.posAllocatedWeight, this.posGovernmentalAllocatedWeight, this.posFreeAllocatedWeight, this.wareHouseArchiveGovernmentalWeight, this.wareHouseArchiveFreeWeight});
|
||||
factory _KillHouseSalesInfoDashboard.fromJson(Map<String, dynamic> json) => _$KillHouseSalesInfoDashboardFromJson(json);
|
||||
|
||||
@override final double? totalGovernmentalInputWeight;
|
||||
@override final double? totalFreeInputWeight;
|
||||
@override final double? totalGovernmentalOutputWeight;
|
||||
@override final double? totalFreeOutputWeight;
|
||||
@override final double? totalGovernmentalRemainWeight;
|
||||
@override final double? totalFreeRemainWeight;
|
||||
@override@JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') final double? totalKillHouseFreeSaleBarCarcassesWeight;
|
||||
@override final double? totalKillHouseAllocationsWeight;
|
||||
@override final double? segmentationsWeight;
|
||||
@override final double? coldHouseAllocationsWeight;
|
||||
@override final double? totalSellingInProvinceGovernmentalWeight;
|
||||
@override final double? totalSellingInProvinceFreeWeight;
|
||||
@override final double? totalCommitmentSellingInProvinceGovernmentalWeight;
|
||||
@override final double? totalCommitmentSellingInProvinceGovernmentalRemainWeight;
|
||||
@override final double? totalCommitmentSellingInProvinceFreeWeight;
|
||||
@override final double? totalCommitmentSellingInProvinceFreeRemainWeight;
|
||||
@override final double? posAllocatedWeight;
|
||||
@override final double? posGovernmentalAllocatedWeight;
|
||||
@override final double? posFreeAllocatedWeight;
|
||||
@override final double? wareHouseArchiveGovernmentalWeight;
|
||||
@override final double? wareHouseArchiveFreeWeight;
|
||||
|
||||
/// Create a copy of KillHouseSalesInfoDashboard
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$KillHouseSalesInfoDashboardCopyWith<_KillHouseSalesInfoDashboard> get copyWith => __$KillHouseSalesInfoDashboardCopyWithImpl<_KillHouseSalesInfoDashboard>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$KillHouseSalesInfoDashboardToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _KillHouseSalesInfoDashboard&&(identical(other.totalGovernmentalInputWeight, totalGovernmentalInputWeight) || other.totalGovernmentalInputWeight == totalGovernmentalInputWeight)&&(identical(other.totalFreeInputWeight, totalFreeInputWeight) || other.totalFreeInputWeight == totalFreeInputWeight)&&(identical(other.totalGovernmentalOutputWeight, totalGovernmentalOutputWeight) || other.totalGovernmentalOutputWeight == totalGovernmentalOutputWeight)&&(identical(other.totalFreeOutputWeight, totalFreeOutputWeight) || other.totalFreeOutputWeight == totalFreeOutputWeight)&&(identical(other.totalGovernmentalRemainWeight, totalGovernmentalRemainWeight) || other.totalGovernmentalRemainWeight == totalGovernmentalRemainWeight)&&(identical(other.totalFreeRemainWeight, totalFreeRemainWeight) || other.totalFreeRemainWeight == totalFreeRemainWeight)&&(identical(other.totalKillHouseFreeSaleBarCarcassesWeight, totalKillHouseFreeSaleBarCarcassesWeight) || other.totalKillHouseFreeSaleBarCarcassesWeight == totalKillHouseFreeSaleBarCarcassesWeight)&&(identical(other.totalKillHouseAllocationsWeight, totalKillHouseAllocationsWeight) || other.totalKillHouseAllocationsWeight == totalKillHouseAllocationsWeight)&&(identical(other.segmentationsWeight, segmentationsWeight) || other.segmentationsWeight == segmentationsWeight)&&(identical(other.coldHouseAllocationsWeight, coldHouseAllocationsWeight) || other.coldHouseAllocationsWeight == coldHouseAllocationsWeight)&&(identical(other.totalSellingInProvinceGovernmentalWeight, totalSellingInProvinceGovernmentalWeight) || other.totalSellingInProvinceGovernmentalWeight == totalSellingInProvinceGovernmentalWeight)&&(identical(other.totalSellingInProvinceFreeWeight, totalSellingInProvinceFreeWeight) || other.totalSellingInProvinceFreeWeight == totalSellingInProvinceFreeWeight)&&(identical(other.totalCommitmentSellingInProvinceGovernmentalWeight, totalCommitmentSellingInProvinceGovernmentalWeight) || other.totalCommitmentSellingInProvinceGovernmentalWeight == totalCommitmentSellingInProvinceGovernmentalWeight)&&(identical(other.totalCommitmentSellingInProvinceGovernmentalRemainWeight, totalCommitmentSellingInProvinceGovernmentalRemainWeight) || other.totalCommitmentSellingInProvinceGovernmentalRemainWeight == totalCommitmentSellingInProvinceGovernmentalRemainWeight)&&(identical(other.totalCommitmentSellingInProvinceFreeWeight, totalCommitmentSellingInProvinceFreeWeight) || other.totalCommitmentSellingInProvinceFreeWeight == totalCommitmentSellingInProvinceFreeWeight)&&(identical(other.totalCommitmentSellingInProvinceFreeRemainWeight, totalCommitmentSellingInProvinceFreeRemainWeight) || other.totalCommitmentSellingInProvinceFreeRemainWeight == totalCommitmentSellingInProvinceFreeRemainWeight)&&(identical(other.posAllocatedWeight, posAllocatedWeight) || other.posAllocatedWeight == posAllocatedWeight)&&(identical(other.posGovernmentalAllocatedWeight, posGovernmentalAllocatedWeight) || other.posGovernmentalAllocatedWeight == posGovernmentalAllocatedWeight)&&(identical(other.posFreeAllocatedWeight, posFreeAllocatedWeight) || other.posFreeAllocatedWeight == posFreeAllocatedWeight)&&(identical(other.wareHouseArchiveGovernmentalWeight, wareHouseArchiveGovernmentalWeight) || other.wareHouseArchiveGovernmentalWeight == wareHouseArchiveGovernmentalWeight)&&(identical(other.wareHouseArchiveFreeWeight, wareHouseArchiveFreeWeight) || other.wareHouseArchiveFreeWeight == wareHouseArchiveFreeWeight));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hashAll([runtimeType,totalGovernmentalInputWeight,totalFreeInputWeight,totalGovernmentalOutputWeight,totalFreeOutputWeight,totalGovernmentalRemainWeight,totalFreeRemainWeight,totalKillHouseFreeSaleBarCarcassesWeight,totalKillHouseAllocationsWeight,segmentationsWeight,coldHouseAllocationsWeight,totalSellingInProvinceGovernmentalWeight,totalSellingInProvinceFreeWeight,totalCommitmentSellingInProvinceGovernmentalWeight,totalCommitmentSellingInProvinceGovernmentalRemainWeight,totalCommitmentSellingInProvinceFreeWeight,totalCommitmentSellingInProvinceFreeRemainWeight,posAllocatedWeight,posGovernmentalAllocatedWeight,posFreeAllocatedWeight,wareHouseArchiveGovernmentalWeight,wareHouseArchiveFreeWeight]);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'KillHouseSalesInfoDashboard(totalGovernmentalInputWeight: $totalGovernmentalInputWeight, totalFreeInputWeight: $totalFreeInputWeight, totalGovernmentalOutputWeight: $totalGovernmentalOutputWeight, totalFreeOutputWeight: $totalFreeOutputWeight, totalGovernmentalRemainWeight: $totalGovernmentalRemainWeight, totalFreeRemainWeight: $totalFreeRemainWeight, totalKillHouseFreeSaleBarCarcassesWeight: $totalKillHouseFreeSaleBarCarcassesWeight, totalKillHouseAllocationsWeight: $totalKillHouseAllocationsWeight, segmentationsWeight: $segmentationsWeight, coldHouseAllocationsWeight: $coldHouseAllocationsWeight, totalSellingInProvinceGovernmentalWeight: $totalSellingInProvinceGovernmentalWeight, totalSellingInProvinceFreeWeight: $totalSellingInProvinceFreeWeight, totalCommitmentSellingInProvinceGovernmentalWeight: $totalCommitmentSellingInProvinceGovernmentalWeight, totalCommitmentSellingInProvinceGovernmentalRemainWeight: $totalCommitmentSellingInProvinceGovernmentalRemainWeight, totalCommitmentSellingInProvinceFreeWeight: $totalCommitmentSellingInProvinceFreeWeight, totalCommitmentSellingInProvinceFreeRemainWeight: $totalCommitmentSellingInProvinceFreeRemainWeight, posAllocatedWeight: $posAllocatedWeight, posGovernmentalAllocatedWeight: $posGovernmentalAllocatedWeight, posFreeAllocatedWeight: $posFreeAllocatedWeight, wareHouseArchiveGovernmentalWeight: $wareHouseArchiveGovernmentalWeight, wareHouseArchiveFreeWeight: $wareHouseArchiveFreeWeight)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$KillHouseSalesInfoDashboardCopyWith<$Res> implements $KillHouseSalesInfoDashboardCopyWith<$Res> {
|
||||
factory _$KillHouseSalesInfoDashboardCopyWith(_KillHouseSalesInfoDashboard value, $Res Function(_KillHouseSalesInfoDashboard) _then) = __$KillHouseSalesInfoDashboardCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
double? totalGovernmentalInputWeight, double? totalFreeInputWeight, double? totalGovernmentalOutputWeight, double? totalFreeOutputWeight, double? totalGovernmentalRemainWeight, double? totalFreeRemainWeight,@JsonKey(name: 'total_kill_house_free_sale__bar_carcasses_weight') double? totalKillHouseFreeSaleBarCarcassesWeight, double? totalKillHouseAllocationsWeight, double? segmentationsWeight, double? coldHouseAllocationsWeight, double? totalSellingInProvinceGovernmentalWeight, double? totalSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceGovernmentalWeight, double? totalCommitmentSellingInProvinceGovernmentalRemainWeight, double? totalCommitmentSellingInProvinceFreeWeight, double? totalCommitmentSellingInProvinceFreeRemainWeight, double? posAllocatedWeight, double? posGovernmentalAllocatedWeight, double? posFreeAllocatedWeight, double? wareHouseArchiveGovernmentalWeight, double? wareHouseArchiveFreeWeight
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$KillHouseSalesInfoDashboardCopyWithImpl<$Res>
|
||||
implements _$KillHouseSalesInfoDashboardCopyWith<$Res> {
|
||||
__$KillHouseSalesInfoDashboardCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _KillHouseSalesInfoDashboard _self;
|
||||
final $Res Function(_KillHouseSalesInfoDashboard) _then;
|
||||
|
||||
/// Create a copy of KillHouseSalesInfoDashboard
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? totalGovernmentalInputWeight = freezed,Object? totalFreeInputWeight = freezed,Object? totalGovernmentalOutputWeight = freezed,Object? totalFreeOutputWeight = freezed,Object? totalGovernmentalRemainWeight = freezed,Object? totalFreeRemainWeight = freezed,Object? totalKillHouseFreeSaleBarCarcassesWeight = freezed,Object? totalKillHouseAllocationsWeight = freezed,Object? segmentationsWeight = freezed,Object? coldHouseAllocationsWeight = freezed,Object? totalSellingInProvinceGovernmentalWeight = freezed,Object? totalSellingInProvinceFreeWeight = freezed,Object? totalCommitmentSellingInProvinceGovernmentalWeight = freezed,Object? totalCommitmentSellingInProvinceGovernmentalRemainWeight = freezed,Object? totalCommitmentSellingInProvinceFreeWeight = freezed,Object? totalCommitmentSellingInProvinceFreeRemainWeight = freezed,Object? posAllocatedWeight = freezed,Object? posGovernmentalAllocatedWeight = freezed,Object? posFreeAllocatedWeight = freezed,Object? wareHouseArchiveGovernmentalWeight = freezed,Object? wareHouseArchiveFreeWeight = freezed,}) {
|
||||
return _then(_KillHouseSalesInfoDashboard(
|
||||
totalGovernmentalInputWeight: freezed == totalGovernmentalInputWeight ? _self.totalGovernmentalInputWeight : totalGovernmentalInputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalFreeInputWeight: freezed == totalFreeInputWeight ? _self.totalFreeInputWeight : totalFreeInputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalGovernmentalOutputWeight: freezed == totalGovernmentalOutputWeight ? _self.totalGovernmentalOutputWeight : totalGovernmentalOutputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalFreeOutputWeight: freezed == totalFreeOutputWeight ? _self.totalFreeOutputWeight : totalFreeOutputWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalGovernmentalRemainWeight: freezed == totalGovernmentalRemainWeight ? _self.totalGovernmentalRemainWeight : totalGovernmentalRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalFreeRemainWeight: freezed == totalFreeRemainWeight ? _self.totalFreeRemainWeight : totalFreeRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalKillHouseFreeSaleBarCarcassesWeight: freezed == totalKillHouseFreeSaleBarCarcassesWeight ? _self.totalKillHouseFreeSaleBarCarcassesWeight : totalKillHouseFreeSaleBarCarcassesWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalKillHouseAllocationsWeight: freezed == totalKillHouseAllocationsWeight ? _self.totalKillHouseAllocationsWeight : totalKillHouseAllocationsWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,segmentationsWeight: freezed == segmentationsWeight ? _self.segmentationsWeight : segmentationsWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,coldHouseAllocationsWeight: freezed == coldHouseAllocationsWeight ? _self.coldHouseAllocationsWeight : coldHouseAllocationsWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalSellingInProvinceGovernmentalWeight: freezed == totalSellingInProvinceGovernmentalWeight ? _self.totalSellingInProvinceGovernmentalWeight : totalSellingInProvinceGovernmentalWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalSellingInProvinceFreeWeight: freezed == totalSellingInProvinceFreeWeight ? _self.totalSellingInProvinceFreeWeight : totalSellingInProvinceFreeWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceGovernmentalWeight: freezed == totalCommitmentSellingInProvinceGovernmentalWeight ? _self.totalCommitmentSellingInProvinceGovernmentalWeight : totalCommitmentSellingInProvinceGovernmentalWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceGovernmentalRemainWeight: freezed == totalCommitmentSellingInProvinceGovernmentalRemainWeight ? _self.totalCommitmentSellingInProvinceGovernmentalRemainWeight : totalCommitmentSellingInProvinceGovernmentalRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceFreeWeight: freezed == totalCommitmentSellingInProvinceFreeWeight ? _self.totalCommitmentSellingInProvinceFreeWeight : totalCommitmentSellingInProvinceFreeWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,totalCommitmentSellingInProvinceFreeRemainWeight: freezed == totalCommitmentSellingInProvinceFreeRemainWeight ? _self.totalCommitmentSellingInProvinceFreeRemainWeight : totalCommitmentSellingInProvinceFreeRemainWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,posAllocatedWeight: freezed == posAllocatedWeight ? _self.posAllocatedWeight : posAllocatedWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,posGovernmentalAllocatedWeight: freezed == posGovernmentalAllocatedWeight ? _self.posGovernmentalAllocatedWeight : posGovernmentalAllocatedWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,posFreeAllocatedWeight: freezed == posFreeAllocatedWeight ? _self.posFreeAllocatedWeight : posFreeAllocatedWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,wareHouseArchiveGovernmentalWeight: freezed == wareHouseArchiveGovernmentalWeight ? _self.wareHouseArchiveGovernmentalWeight : wareHouseArchiveGovernmentalWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,wareHouseArchiveFreeWeight: freezed == wareHouseArchiveFreeWeight ? _self.wareHouseArchiveFreeWeight : wareHouseArchiveFreeWeight // ignore: cast_nullable_to_non_nullable
|
||||
as double?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
@@ -0,0 +1,91 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'kill_house_sales_info_dashboard.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_KillHouseSalesInfoDashboard _$KillHouseSalesInfoDashboardFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _KillHouseSalesInfoDashboard(
|
||||
totalGovernmentalInputWeight:
|
||||
(json['total_governmental_input_weight'] as num?)?.toDouble(),
|
||||
totalFreeInputWeight: (json['total_free_input_weight'] as num?)?.toDouble(),
|
||||
totalGovernmentalOutputWeight:
|
||||
(json['total_governmental_output_weight'] as num?)?.toDouble(),
|
||||
totalFreeOutputWeight: (json['total_free_output_weight'] as num?)?.toDouble(),
|
||||
totalGovernmentalRemainWeight:
|
||||
(json['total_governmental_remain_weight'] as num?)?.toDouble(),
|
||||
totalFreeRemainWeight: (json['total_free_remain_weight'] as num?)?.toDouble(),
|
||||
totalKillHouseFreeSaleBarCarcassesWeight:
|
||||
(json['total_kill_house_free_sale__bar_carcasses_weight'] as num?)
|
||||
?.toDouble(),
|
||||
totalKillHouseAllocationsWeight:
|
||||
(json['total_kill_house_allocations_weight'] as num?)?.toDouble(),
|
||||
segmentationsWeight: (json['segmentations_weight'] as num?)?.toDouble(),
|
||||
coldHouseAllocationsWeight: (json['cold_house_allocations_weight'] as num?)
|
||||
?.toDouble(),
|
||||
totalSellingInProvinceGovernmentalWeight:
|
||||
(json['total_selling_in_province_governmental_weight'] as num?)
|
||||
?.toDouble(),
|
||||
totalSellingInProvinceFreeWeight:
|
||||
(json['total_selling_in_province_free_weight'] as num?)?.toDouble(),
|
||||
totalCommitmentSellingInProvinceGovernmentalWeight:
|
||||
(json['total_commitment_selling_in_province_governmental_weight'] as num?)
|
||||
?.toDouble(),
|
||||
totalCommitmentSellingInProvinceGovernmentalRemainWeight:
|
||||
(json['total_commitment_selling_in_province_governmental_remain_weight']
|
||||
as num?)
|
||||
?.toDouble(),
|
||||
totalCommitmentSellingInProvinceFreeWeight:
|
||||
(json['total_commitment_selling_in_province_free_weight'] as num?)
|
||||
?.toDouble(),
|
||||
totalCommitmentSellingInProvinceFreeRemainWeight:
|
||||
(json['total_commitment_selling_in_province_free_remain_weight'] as num?)
|
||||
?.toDouble(),
|
||||
posAllocatedWeight: (json['pos_allocated_weight'] as num?)?.toDouble(),
|
||||
posGovernmentalAllocatedWeight:
|
||||
(json['pos_governmental_allocated_weight'] as num?)?.toDouble(),
|
||||
posFreeAllocatedWeight: (json['pos_free_allocated_weight'] as num?)
|
||||
?.toDouble(),
|
||||
wareHouseArchiveGovernmentalWeight:
|
||||
(json['ware_house_archive_governmental_weight'] as num?)?.toDouble(),
|
||||
wareHouseArchiveFreeWeight: (json['ware_house_archive_free_weight'] as num?)
|
||||
?.toDouble(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$KillHouseSalesInfoDashboardToJson(
|
||||
_KillHouseSalesInfoDashboard instance,
|
||||
) => <String, dynamic>{
|
||||
'total_governmental_input_weight': instance.totalGovernmentalInputWeight,
|
||||
'total_free_input_weight': instance.totalFreeInputWeight,
|
||||
'total_governmental_output_weight': instance.totalGovernmentalOutputWeight,
|
||||
'total_free_output_weight': instance.totalFreeOutputWeight,
|
||||
'total_governmental_remain_weight': instance.totalGovernmentalRemainWeight,
|
||||
'total_free_remain_weight': instance.totalFreeRemainWeight,
|
||||
'total_kill_house_free_sale__bar_carcasses_weight':
|
||||
instance.totalKillHouseFreeSaleBarCarcassesWeight,
|
||||
'total_kill_house_allocations_weight':
|
||||
instance.totalKillHouseAllocationsWeight,
|
||||
'segmentations_weight': instance.segmentationsWeight,
|
||||
'cold_house_allocations_weight': instance.coldHouseAllocationsWeight,
|
||||
'total_selling_in_province_governmental_weight':
|
||||
instance.totalSellingInProvinceGovernmentalWeight,
|
||||
'total_selling_in_province_free_weight':
|
||||
instance.totalSellingInProvinceFreeWeight,
|
||||
'total_commitment_selling_in_province_governmental_weight':
|
||||
instance.totalCommitmentSellingInProvinceGovernmentalWeight,
|
||||
'total_commitment_selling_in_province_governmental_remain_weight':
|
||||
instance.totalCommitmentSellingInProvinceGovernmentalRemainWeight,
|
||||
'total_commitment_selling_in_province_free_weight':
|
||||
instance.totalCommitmentSellingInProvinceFreeWeight,
|
||||
'total_commitment_selling_in_province_free_remain_weight':
|
||||
instance.totalCommitmentSellingInProvinceFreeRemainWeight,
|
||||
'pos_allocated_weight': instance.posAllocatedWeight,
|
||||
'pos_governmental_allocated_weight': instance.posGovernmentalAllocatedWeight,
|
||||
'pos_free_allocated_weight': instance.posFreeAllocatedWeight,
|
||||
'ware_house_archive_governmental_weight':
|
||||
instance.wareHouseArchiveGovernmentalWeight,
|
||||
'ware_house_archive_free_weight': instance.wareHouseArchiveFreeWeight,
|
||||
};
|
||||
@@ -26,6 +26,8 @@ abstract class InventoryModel with _$InventoryModel {
|
||||
int? totalGovernmentalCarcassesWeight,
|
||||
int? totalFreeBarsCarcassesQuantity,
|
||||
int? totalFreeBarsCarcassesWeight,
|
||||
int? totalFreeRemainWeight,
|
||||
int? totalGovernmentalRemainWeight,
|
||||
double? weightAverage,
|
||||
int? totalCarcassesQuantity,
|
||||
int? totalCarcassesWeight,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -43,6 +43,9 @@ _InventoryModel _$InventoryModelFromJson(
|
||||
(json['total_free_bars_carcasses_quantity'] as num?)?.toInt(),
|
||||
totalFreeBarsCarcassesWeight:
|
||||
(json['total_free_bars_carcasses_weight'] as num?)?.toInt(),
|
||||
totalFreeRemainWeight: (json['total_free_remain_weight'] as num?)?.toInt(),
|
||||
totalGovernmentalRemainWeight:
|
||||
(json['total_governmental_remain_weight'] as num?)?.toInt(),
|
||||
weightAverage: (json['weight_average'] as num?)?.toDouble(),
|
||||
totalCarcassesQuantity: (json['total_carcasses_quantity'] as num?)?.toInt(),
|
||||
totalCarcassesWeight: (json['total_carcasses_weight'] as num?)?.toInt(),
|
||||
@@ -101,6 +104,8 @@ Map<String, dynamic> _$InventoryModelToJson(
|
||||
instance.totalGovernmentalCarcassesWeight,
|
||||
'total_free_bars_carcasses_quantity': instance.totalFreeBarsCarcassesQuantity,
|
||||
'total_free_bars_carcasses_weight': instance.totalFreeBarsCarcassesWeight,
|
||||
'total_free_remain_weight': instance.totalFreeRemainWeight,
|
||||
'total_governmental_remain_weight': instance.totalGovernmentalRemainWeight,
|
||||
'weight_average': instance.weightAverage,
|
||||
'total_carcasses_quantity': instance.totalCarcassesQuantity,
|
||||
'total_carcasses_weight': instance.totalCarcassesWeight,
|
||||
|
||||
@@ -32,9 +32,16 @@ abstract class ChickenRepository {
|
||||
//region Remote
|
||||
|
||||
//region Steward
|
||||
Future<List<InventoryModel>?> getInventory({required String token, CancelToken? cancelToken});
|
||||
Future<List<InventoryModel>?> getInventory({
|
||||
required String token,
|
||||
required String role,
|
||||
CancelToken? cancelToken,
|
||||
});
|
||||
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({required String token});
|
||||
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({
|
||||
required String token,
|
||||
});
|
||||
|
||||
Future<BarInformation?> getGeneralBarInformation({
|
||||
required String token,
|
||||
@@ -46,7 +53,10 @@ abstract class ChickenRepository {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> setSateForArrivals({required String token, required Map<String, dynamic> request});
|
||||
Future<void> setSateForArrivals({
|
||||
required String token,
|
||||
required Map<String, dynamic> request,
|
||||
});
|
||||
|
||||
Future<PaginationModel<ImportedLoadsModel>?> getImportedLoadsModel({
|
||||
required String token,
|
||||
@@ -58,9 +68,15 @@ abstract class ChickenRepository {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> confirmAllocation({required String token, required Map<String, dynamic> allocation});
|
||||
Future<void> confirmAllocation({
|
||||
required String token,
|
||||
required Map<String, dynamic> allocation,
|
||||
});
|
||||
|
||||
Future<void> denyAllocation({required String token, required String allocationToken});
|
||||
Future<void> denyAllocation({
|
||||
required String token,
|
||||
required String allocationToken,
|
||||
});
|
||||
|
||||
Future<void> confirmAllAllocation({
|
||||
required String token,
|
||||
@@ -86,7 +102,10 @@ abstract class ChickenRepository {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> updateStewardAllocation({required String token, required ConformAllocation request});
|
||||
Future<void> updateStewardAllocation({
|
||||
required String token,
|
||||
required ConformAllocation request,
|
||||
});
|
||||
|
||||
Future<StewardFreeBarDashboard?> getStewardDashboard({
|
||||
required String token,
|
||||
@@ -100,7 +119,8 @@ abstract class ChickenRepository {
|
||||
required String endDate,
|
||||
});
|
||||
|
||||
Future<PaginationModel<StewardFreeBar>?> getStewardPurchasesOutSideOfTheProvince({
|
||||
Future<PaginationModel<StewardFreeBar>?>
|
||||
getStewardPurchasesOutSideOfTheProvince({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
@@ -110,20 +130,18 @@ abstract class ChickenRepository {
|
||||
required CreateStewardFreeBar body,
|
||||
});
|
||||
|
||||
|
||||
Future<CreateStewardFreeBar?> editStewardPurchasesOutSideOfTheProvince({
|
||||
required String token,
|
||||
required CreateStewardFreeBar body,
|
||||
});
|
||||
|
||||
|
||||
|
||||
Future<void> deleteStewardPurchasesOutSideOfTheProvince({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<PaginationModel<OutProvinceCarcassesBuyer>?> getOutProvinceCarcassesBuyer({
|
||||
Future<PaginationModel<OutProvinceCarcassesBuyer>?>
|
||||
getOutProvinceCarcassesBuyer({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
@@ -154,27 +172,40 @@ abstract class ChickenRepository {
|
||||
|
||||
Future<void> deleteOutProvinceStewardFreeBar({
|
||||
required String token,
|
||||
required String key
|
||||
required String key,
|
||||
});
|
||||
|
||||
|
||||
|
||||
Future<UserProfile?> getUserProfile({required String token});
|
||||
|
||||
Future<void> updateUserProfile({required String token, required UserProfile userProfile});
|
||||
Future<void> updateUserProfile({
|
||||
required String token,
|
||||
required UserProfile userProfile,
|
||||
});
|
||||
|
||||
Future<void> updatePassword({required String token, required ChangePasswordRequestModel model});
|
||||
Future<void> updatePassword({
|
||||
required String token,
|
||||
required ChangePasswordRequestModel model,
|
||||
});
|
||||
|
||||
Future<PaginationModel<SegmentationModel>?> getSegmentation({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> createSegmentation({required String token, required SegmentationModel model});
|
||||
Future<void> createSegmentation({
|
||||
required String token,
|
||||
required SegmentationModel model,
|
||||
});
|
||||
|
||||
Future<void> editSegmentation({required String token, required SegmentationModel model});
|
||||
Future<void> editSegmentation({
|
||||
required String token,
|
||||
required SegmentationModel model,
|
||||
});
|
||||
|
||||
Future<SegmentationModel?> deleteSegmentation({required String token, required String key});
|
||||
Future<SegmentationModel?> deleteSegmentation({
|
||||
required String token,
|
||||
required String key,
|
||||
});
|
||||
|
||||
Future<BroadcastPrice?> getBroadcastPrice({required String token});
|
||||
|
||||
@@ -187,9 +218,6 @@ abstract class ChickenRepository {
|
||||
|
||||
//endregion
|
||||
|
||||
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
//region local
|
||||
|
||||
@@ -41,12 +41,14 @@ class ChickenRepositoryImp implements ChickenRepository {
|
||||
@override
|
||||
Future<List<InventoryModel>?> getInventory({
|
||||
required String token,
|
||||
required String role,
|
||||
CancelToken? cancelToken,
|
||||
}) async {
|
||||
var res = await remote.getInventory(token: token, cancelToken: cancelToken);
|
||||
var res = await remote.getInventory(token: token, role: role, cancelToken: cancelToken);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<KillHouseDistributionInfo?> getKillHouseDistributionInfo({
|
||||
required String token,
|
||||
|
||||
@@ -4,8 +4,11 @@ import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/response/kill_request_list/kill_request_list.dart'
|
||||
as listModel
|
||||
show KillRequestList;
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/warehouse_and_distribution/response/kill_house_sales_info_dashboard.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
abstract class KillHouseRepository {
|
||||
//region requestKill
|
||||
Future<List<KillHouseResponse>?> getKillHouseList({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
@@ -16,12 +19,29 @@ abstract class KillHouseRepository {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> submitKillHouseRequest({required String token, required KillRequestResponse data});
|
||||
Future<void> submitKillHouseRequest({
|
||||
required String token,
|
||||
required KillRequestResponse data,
|
||||
});
|
||||
|
||||
Future<List<listModel.KillRequestList>?> getListKillRequest({
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
Future<void> deleteKillRequest({required String token, required int requestId});
|
||||
Future<void> deleteKillRequest({
|
||||
required String token,
|
||||
required int requestId,
|
||||
});
|
||||
|
||||
//endregion
|
||||
|
||||
//region warehouseAndDistribution
|
||||
Future<KillHouseSalesInfoDashboard?> getKillHouseSalesInfoDashboard({
|
||||
required String token,
|
||||
CancelToken? cancelToken,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
});
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/response/kill_house/kill_house_response.dart';
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/register_request/response/kill_request_list/kill_request_list.dart'
|
||||
as listModel;
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/warehouse_and_distribution/response/kill_house_sales_info_dashboard.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'kill_house_repository.dart';
|
||||
|
||||
@@ -17,7 +19,10 @@ class KillHouseRepositoryImpl extends KillHouseRepository {
|
||||
required String token,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
}) async {
|
||||
return await remoteDataSource.getKillHouseList(token: token, queryParameters: queryParameters);
|
||||
return await remoteDataSource.getKillHouseList(
|
||||
token: token,
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -37,7 +42,10 @@ class KillHouseRepositoryImpl extends KillHouseRepository {
|
||||
required KillRequestResponse data,
|
||||
}) async {
|
||||
var jsonData = data.toJson();
|
||||
return await remoteDataSource.submitKillHouseRequest(token: token, data: jsonData);
|
||||
return await remoteDataSource.submitKillHouseRequest(
|
||||
token: token,
|
||||
data: jsonData,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -52,7 +60,31 @@ class KillHouseRepositoryImpl extends KillHouseRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteKillRequest({required String token, required int requestId}) async {
|
||||
await remoteDataSource.deleteKillRequest(token: token, requestId: requestId);
|
||||
Future<void> deleteKillRequest({
|
||||
required String token,
|
||||
required int requestId,
|
||||
}) async {
|
||||
await remoteDataSource.deleteKillRequest(
|
||||
token: token,
|
||||
requestId: requestId,
|
||||
);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
//region warehouseAndDistribution
|
||||
@override
|
||||
Future<KillHouseSalesInfoDashboard?> getKillHouseSalesInfoDashboard({
|
||||
required String token,
|
||||
CancelToken? cancelToken,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
}) async {
|
||||
return await remoteDataSource.getKillHouseSalesInfoDashboard(
|
||||
token: token,
|
||||
cancelToken: cancelToken,
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
}
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class KillHouseActionLogic extends GetxController {
|
||||
@@ -7,19 +8,28 @@ class KillHouseActionLogic extends GetxController {
|
||||
title: "ثبت درخواست",
|
||||
icon: Assets.vec.submitRequestSvg.path,
|
||||
route: ChickenRoutes.submitRequestKillHouse,
|
||||
navId: killHouseActionKey,
|
||||
),
|
||||
GlassMorphismCardItem(
|
||||
title: "انبار و توزیع",
|
||||
icon: Assets.vec.warehouseDistributionSvg.path,
|
||||
route: '',
|
||||
route: ChickenRoutes.initWarehouseAndDistribution,
|
||||
),
|
||||
GlassMorphismCardItem(
|
||||
title: "سفارشات دریافتی",
|
||||
icon: Assets.vec.ordersReceivedSvg.path,
|
||||
route: '',
|
||||
),
|
||||
GlassMorphismCardItem(title: "خرید مستقیم", icon: Assets.vec.directPurchaseSvg.path, route: ''),
|
||||
GlassMorphismCardItem(title: "تخصیص خودرو", icon: Assets.vec.carAllocationSvg.path, route: ''),
|
||||
GlassMorphismCardItem(
|
||||
title: "خرید مستقیم",
|
||||
icon: Assets.vec.directPurchaseSvg.path,
|
||||
route: '',
|
||||
),
|
||||
GlassMorphismCardItem(
|
||||
title: "تخصیص خودرو",
|
||||
icon: Assets.vec.carAllocationSvg.path,
|
||||
route: '',
|
||||
),
|
||||
GlassMorphismCardItem(
|
||||
title: "ورود اطلاعات بار",
|
||||
icon: Assets.vec.enterCargoInformationSvg.path,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
@@ -15,7 +14,7 @@ class KillHouseActionPage extends GetView<KillHouseActionLogic> {
|
||||
child: GlassMorphismGrid(
|
||||
items: controller.items,
|
||||
onTap: (item) {
|
||||
Get.toNamed(item.route, id: killHouseActionKey);
|
||||
Get.toNamed(item.route, id: item.navId);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyLogic extends GetxController {
|
||||
List<String> routesName = ['خرید'];
|
||||
DateTime? _lastBackPressed;
|
||||
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
fLog('BuyLogic onReady');
|
||||
super.onReady();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
void onPopScopTaped() async {
|
||||
final now = DateTime.now();
|
||||
if (_lastBackPressed == null || now.difference(_lastBackPressed!) > Duration(seconds: 2)) {
|
||||
_lastBackPressed = now;
|
||||
Get.snackbar(
|
||||
'خروج از برنامه',
|
||||
'برای خروج دوباره بازگشت را بزنید',
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: AppColor.warning,
|
||||
);
|
||||
} else {
|
||||
await SystemNavigator.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyPage
|
||||
extends GetView<WarehouseAndDistributionBuyLogic> {
|
||||
const WarehouseAndDistributionBuyPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChickenBasePage(
|
||||
routes: controller.routesName,
|
||||
isBase: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 21.w,
|
||||
children: [
|
||||
GlassMorphismCardIcon(
|
||||
title: 'خرید داخل استان',
|
||||
vecIcon: Assets.vec.map1Svg.path,
|
||||
gradient: LinearGradient(
|
||||
colors: [Color(0xFF00E096), Color(0xFF007D5E)],
|
||||
stops: [0.0, 0.95],
|
||||
begin: AlignmentGeometry.topLeft,
|
||||
end: AlignmentGeometry.bottomRight,
|
||||
),
|
||||
onTap: () {
|
||||
Get.toNamed(
|
||||
ChickenRoutes.buysInProvinceWarehouseAndDistribution,
|
||||
id: killHouseWarehouseAndDistributionBuyKey,
|
||||
);
|
||||
},
|
||||
),
|
||||
GlassMorphismCardIcon(
|
||||
title: 'خرید خارج استان',
|
||||
vecIcon: Assets.vec.buyOutProvinceSvg.path,
|
||||
gradient: LinearGradient(
|
||||
colors: [Color(0xFF00E096), Color(0xFF007D5E)],
|
||||
stops: [0.0, 0.95],
|
||||
begin: AlignmentGeometry.topLeft,
|
||||
end: AlignmentGeometry.bottomRight,
|
||||
),
|
||||
onTap: () {
|
||||
Get.toNamed(
|
||||
ChickenRoutes.buysOutOfProvinceWarehouseAndDistribution,
|
||||
id: killHouseWarehouseAndDistributionBuyKey,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/buy/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/buy_in_province_all/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/buy_in_province_waiting/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyInProvinceLogic extends GetxController {
|
||||
RxList<String> routesName = RxList();
|
||||
RxList<int> isExpandedList = <int>[].obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
WarehouseAndDistributionBuyLogic get buyLogic => Get.find<WarehouseAndDistributionBuyLogic>();
|
||||
RxInt selectedSegmentIndex = 0.obs;
|
||||
|
||||
WarehouseAndDistributionBuyInProvinceAllLogic buyAllLogic = Get.find<WarehouseAndDistributionBuyInProvinceAllLogic>();
|
||||
WarehouseAndDistributionBuyInProvinceWaitingLogic buyWaitingLogic = Get.find<WarehouseAndDistributionBuyInProvinceWaitingLogic>();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
routesName.value = [...buyLogic.routesName, 'داخل استان'].toList();
|
||||
routesName.add(selectedSegmentIndex.value == 0 ? 'در انتظار' : 'کل خریدها');
|
||||
ever(selectedSegmentIndex, (callback) {
|
||||
routesName.removeLast();
|
||||
routesName.add(callback == 0 ? 'در انتظار' : 'کل خریدها');
|
||||
});
|
||||
|
||||
ever(fromDateFilter, (callback) => _setFromDateFilter(callback));
|
||||
ever(toDateFilter, (callback) => _setToDateFilter(callback));
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
fLog('BuyInProvinceLogic onReady');
|
||||
super.onReady();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
void _setFromDateFilter(Jalali jalali) {
|
||||
final isWaiting = selectedSegmentIndex.value == 0;
|
||||
if (isWaiting) {
|
||||
buyWaitingLogic.fromDateFilter.value = fromDateFilter.value;
|
||||
} else {
|
||||
buyAllLogic.fromDateFilter.value = fromDateFilter.value;
|
||||
}
|
||||
}
|
||||
|
||||
void _setToDateFilter(Jalali jalali) {
|
||||
final isWaiting = selectedSegmentIndex.value == 0;
|
||||
if (isWaiting) {
|
||||
buyWaitingLogic.toDateFilter.value = fromDateFilter.value;
|
||||
} else {
|
||||
buyAllLogic.toDateFilter.value = fromDateFilter.value;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> submitFilter() async {
|
||||
final isWaiting = selectedSegmentIndex.value == 0;
|
||||
if (isWaiting) {
|
||||
buyWaitingLogic.getWaitingArrivals();
|
||||
} else {
|
||||
buyAllLogic.getAllArrivals();
|
||||
}
|
||||
}
|
||||
|
||||
void setSearchValue(String? data) {
|
||||
searchedValue.value = data?.trim();
|
||||
final isWaiting = selectedSegmentIndex.value == 0;
|
||||
if (isWaiting) {
|
||||
buyWaitingLogic.searchedValue.value = searchedValue.value;
|
||||
} else {
|
||||
buyAllLogic.searchedValue.value = searchedValue.value;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
await rootLogic.onRefresh();
|
||||
await Future.wait([buyWaitingLogic.getWaitingArrivals(), buyAllLogic.getAllArrivals()]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/buy_in_province_all/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/buy_in_province_waiting/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyInProvincePage
|
||||
extends GetView<WarehouseAndDistributionBuyInProvinceLogic> {
|
||||
const WarehouseAndDistributionBuyInProvincePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChickenBasePage(
|
||||
routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName),
|
||||
onSearchChanged: (data) => controller.setSearchValue(data),
|
||||
hasBack: true,
|
||||
backId: killHouseWarehouseAndDistributionBuyKey,
|
||||
|
||||
onFilterTap: () {
|
||||
Get.bottomSheet(filterBottomSheet());
|
||||
},
|
||||
onRefresh: controller.onRefresh,
|
||||
child: Column(
|
||||
spacing: 4.h,
|
||||
children: [
|
||||
ObxValue((data) {
|
||||
return InventoryWidget(inventoryModel: data.value);
|
||||
}, controller.rootLogic.inventoryModel),
|
||||
|
||||
segmentWidget(),
|
||||
ObxValue((index) {
|
||||
return Expanded(
|
||||
child: index.value == 0
|
||||
? WarehouseAndDistributionBuyInProvinceWaitingPage()
|
||||
: WarehouseAndDistributionBuyInProvinceAllPage(),
|
||||
);
|
||||
}, controller.selectedSegmentIndex),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Padding segmentWidget() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: RSegment(
|
||||
children: ['وارد شده به انبار', 'کل خریدها'],
|
||||
selectedIndex: 0,
|
||||
borderColor: const Color(0xFFB4B4B4),
|
||||
selectedBorderColor: AppColor.blueNormal,
|
||||
selectedBackgroundColor: AppColor.blueLight,
|
||||
onSegmentSelected: (index) =>
|
||||
controller.selectedSegmentIndex.value = index,
|
||||
backgroundColor: AppColor.whiteGreyNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget filterBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 200,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
'فیلترها',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: dateFilterWidget(
|
||||
date: controller.fromDateFilter,
|
||||
onChanged: (jalali) =>
|
||||
controller.fromDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: dateFilterWidget(
|
||||
isFrom: false,
|
||||
date: controller.toDateFilter,
|
||||
onChanged: (jalali) => controller.toDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
RElevated(
|
||||
text: 'اعمال فیلتر',
|
||||
|
||||
isFullWidth: true,
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
onPressed: () {
|
||||
controller.submitFilter();
|
||||
Get.back();
|
||||
},
|
||||
height: 40,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyInProvinceAllLogic extends GetxController {
|
||||
RxInt isExpandedListIndex = (-1).obs;
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
RxMap<String, bool> isLoadingConfirmMap = RxMap();
|
||||
final RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
RxInt currentPage = 1.obs;
|
||||
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
Rx<Resource<PaginationModel<WaitingArrivalModel>>> allProduct =
|
||||
Resource<PaginationModel<WaitingArrivalModel>>.loading().obs;
|
||||
|
||||
TextEditingController weightController = TextEditingController();
|
||||
TextEditingController countController = TextEditingController();
|
||||
TextEditingController lossController = TextEditingController();
|
||||
TextEditingController approvedWithOtpController = TextEditingController();
|
||||
|
||||
RxBool approvedWithOtpCode = false.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
getAllArrivals();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
debounce(searchedValue, (callback) => getAllArrivals(), time: Duration(milliseconds: 2000));
|
||||
super.onReady();
|
||||
ever(approvedWithOtpCode, (callback) {
|
||||
if (callback == false) {
|
||||
approvedWithOtpController.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
Future<void> getAllArrivals([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
allProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.loading();
|
||||
}
|
||||
|
||||
if (searchedValue.value != null &&
|
||||
searchedValue.value!.trim().isNotEmpty &&
|
||||
currentPage.value > 1) {
|
||||
currentPage.value = 1;
|
||||
}
|
||||
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getWaitingArrivals(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
queryParams: {'type': 'all'},
|
||||
pageSize: 20,
|
||||
page: currentPage.value,
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value,
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) async {
|
||||
await Future.delayed(Duration(milliseconds: 200));
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
allProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.empty();
|
||||
} else {
|
||||
allProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.success(
|
||||
PaginationModel<WaitingArrivalModel>(
|
||||
count: res?.count ?? 0,
|
||||
next: res?.next,
|
||||
previous: res?.previous,
|
||||
results: [...(allProduct.value.data?.results ?? []), ...(res?.results ?? [])],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> acceptEntries(WaitingArrivalModel model) async {
|
||||
var request = StewardAllocationRequest(
|
||||
allocationKey: model.key,
|
||||
checkAllocation: true,
|
||||
state: 'accepted',
|
||||
receiverRealNumberOfCarcasses: model.realNumberOfCarcasses ?? 0,
|
||||
receiverRealWeightOfCarcasses: model.realWeightOfCarcasses?.toInt() ?? 0,
|
||||
registrationCode: approvedWithOtpCode.value
|
||||
? int.parse(approvedWithOtpController.text)
|
||||
: null,
|
||||
weightLossOfCarcasses: model.weightLossOfCarcasses?.toInt() ?? 0,
|
||||
).toJson();
|
||||
request.removeWhere((key, value) => value == null);
|
||||
|
||||
safeCall(
|
||||
showError: true,
|
||||
call: () async => await rootLogic.chickenRepository.setSateForArrivals(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
request: request,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
getAllArrivals();
|
||||
rootLogic.onRefresh();
|
||||
clearApprovedController();
|
||||
toggleExpansion();
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> denyEntries(WaitingArrivalModel model) async {
|
||||
var request = StewardAllocationRequest(
|
||||
allocationKey: model.key,
|
||||
checkAllocation: true,
|
||||
state: 'rejected',
|
||||
).toJson();
|
||||
request.removeWhere((key, value) => value == null);
|
||||
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.setSateForArrivals(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
request: request,
|
||||
),
|
||||
onError: (error, stackTrace) {
|
||||
eLog(error);
|
||||
},
|
||||
onSuccess: (result) {
|
||||
getAllArrivals();
|
||||
rootLogic.onRefresh();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
String getVecPathItem(String? item) {
|
||||
switch (item) {
|
||||
case 'pending':
|
||||
return Assets.vec.timerSvg.path;
|
||||
case 'accepted':
|
||||
return Assets.vec.checkSquareSvg.path;
|
||||
case 'rejected':
|
||||
return Assets.vec.closeCircleSvg.path;
|
||||
default:
|
||||
return Assets.vec.timerSvg.path;
|
||||
}
|
||||
}
|
||||
|
||||
void clearApprovedController() {
|
||||
weightController.clear();
|
||||
countController.clear();
|
||||
lossController.clear();
|
||||
approvedWithOtpController.clear();
|
||||
approvedWithOtpCode.value = false;
|
||||
}
|
||||
|
||||
void toggleExpansion({int? index}) {
|
||||
if (isExpandedListIndex.value == index || index == null) {
|
||||
isExpandedListIndex.value = -1;
|
||||
} else {
|
||||
isExpandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
|
||||
Color getLabelColor(String? receiverState) {
|
||||
if (receiverState == 'pending') {
|
||||
return AppColor.yellowNormal2;
|
||||
}
|
||||
return AppColor.mediumGreyDarkHover;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyInProvinceAllPage extends GetView<WarehouseAndDistributionBuyInProvinceAllLogic> {
|
||||
const WarehouseAndDistributionBuyInProvinceAllPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
listType: ListType.separated,
|
||||
resource: data.value,
|
||||
hasMore: data.value.data?.next != null,
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
|
||||
itemBuilder: (context, index) {
|
||||
var item = data.value.data!.results![index];
|
||||
return ObxValue((val) {
|
||||
return ExpandableListItem2(
|
||||
selected: val.value == index,
|
||||
onTap: () => controller.toggleExpansion(index: index),
|
||||
index: index,
|
||||
child: itemListWidget(item),
|
||||
secondChild: itemListExpandedWidget(item),
|
||||
labelColor: getLabelColor(item.receiverState),
|
||||
labelIcon: controller.getVecPathItem(item.receiverState),
|
||||
labelIconColor: controller.getLabelColor(item.receiverState),
|
||||
);
|
||||
}, controller.isExpandedListIndex);
|
||||
},
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||
onLoadMore: () async => controller.getAllArrivals(true),
|
||||
);
|
||||
}, controller.allProduct),
|
||||
);
|
||||
}
|
||||
|
||||
Row itemListWidget(WaitingArrivalModel item) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
item.toSteward?.user?.fullname ?? 'N/A',
|
||||
textAlign: TextAlign.start,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Text(
|
||||
item.date?.formattedJalaliDate ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
spacing: 3,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
spacing: 6,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: item.product?.name?.contains('مرغ گرم') ?? false,
|
||||
child: Assets.vec.hotChickenSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
item.weightOfCarcasses?.separatedByCommaFa.addKg ?? 'N/A',
|
||||
textAlign: TextAlign.left,
|
||||
textDirection: TextDirection.ltr,
|
||||
style: AppFonts.yekan12Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Text(
|
||||
item.toSteward?.guildsName ?? 'N/Aaq',
|
||||
textAlign: TextAlign.start,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Assets.vec.scanSvg.svg(
|
||||
width: 32.w,
|
||||
height: 32.h,
|
||||
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container itemListExpandedWidget(WaitingArrivalModel item) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
item.toSteward?.user?.fullname ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
item.receiverState?.faItem ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan10.copyWith(color: AppColor.darkGreyDark),
|
||||
),
|
||||
SizedBox(width: 7),
|
||||
SvgGenImage.vec(controller.getVecPathItem(item.receiverState)).svg(
|
||||
width: 16.w,
|
||||
height: 16.h,
|
||||
colorFilter: ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: AppColor.blueLightHover),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
item.date?.toJalali.formatter.wN ?? 'N/A',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'N/A'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.y}',
|
||||
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'N/A'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
buildRow(title: 'مشخصات فروشنده', value: item.toSteward?.user?.fullname ?? 'N/A'),
|
||||
buildRow(
|
||||
title: 'تلفن فروشنده',
|
||||
value: item.toSteward?.user?.mobile ?? 'N/A',
|
||||
valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
buildRow(title: 'نوع تخصیص', value: item.allocationType?.faAllocationType ?? 'N/A'),
|
||||
buildRow(title: ' سهمیه', value: item.quota?.faTitle ?? 'N/A'),
|
||||
buildRow(title: 'محصول', value: item.product?.name ?? 'N/A'),
|
||||
buildRow(
|
||||
title: 'وزن خریداری شده',
|
||||
value: item.weightOfCarcasses?.separatedByCommaFa ?? 'N/A',
|
||||
valueLabel: 'کیلوگرم',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت هر کیلوگرم',
|
||||
titleLabel: (item.approvedPriceStatus ?? false) ? 'مصوب' : 'آزاد',
|
||||
titleLabelStyle: AppFonts.yekan14Bold.copyWith(color: AppColor.greenNormal),
|
||||
value: item.amount?.separatedByCommaFa ?? 'N/A',
|
||||
valueLabel: 'ریال',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت کل',
|
||||
value: item.totalAmount?.separatedByCommaFa ?? 'N/A',
|
||||
valueLabel: 'ریال',
|
||||
),
|
||||
|
||||
Visibility(
|
||||
visible: item.receiverState == 'pending',
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16.w,
|
||||
children: [
|
||||
ObxValue((data) {
|
||||
return RElevated(
|
||||
text: 'تایید',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
isLoading: data[item.key!] ?? false,
|
||||
onPressed: () async {
|
||||
await Get.bottomSheet(
|
||||
conformationBottomSheet(item),
|
||||
isScrollControlled: true,
|
||||
).then((value) {
|
||||
Get.back();
|
||||
controller.clearApprovedController();
|
||||
});
|
||||
},
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
);
|
||||
}, controller.isLoadingConfirmMap),
|
||||
ROutlinedElevated(
|
||||
text: 'رد',
|
||||
textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal),
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
buildWarningDialog(
|
||||
title: 'اخطار',
|
||||
middleText: 'آیا از رد شدن این مورد اطمینان دارید؟',
|
||||
onConfirm: () => controller.denyEntries(item),
|
||||
onRefresh: () => controller.getAllArrivals(),
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.redNormal,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Color getLabelColor(String? item) {
|
||||
switch (item) {
|
||||
case 'pending':
|
||||
return AppColor.blueLight;
|
||||
case 'accepted':
|
||||
return AppColor.greenLightHover;
|
||||
case 'rejected':
|
||||
return AppColor.redLightHover;
|
||||
default:
|
||||
return AppColor.blueLight;
|
||||
}
|
||||
}
|
||||
|
||||
Widget conformationBottomSheet(WaitingArrivalModel item) {
|
||||
controller.weightController.text = item.weightOfCarcasses.separatedByComma;
|
||||
return BaseBottomSheet(
|
||||
height: 430.h,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
RTextField(
|
||||
label: 'وزن(کیلوگرم)',
|
||||
controller: controller.weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
RTextField(
|
||||
label: 'حجم(قطعه)',
|
||||
controller: controller.countController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
RTextField(
|
||||
label: 'افت وزن(کیلوگرم)',
|
||||
controller: controller.lossController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
Text('تایید ', style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor)),
|
||||
ObxValue((data) {
|
||||
return Column(
|
||||
children: [
|
||||
RadioGroup(
|
||||
groupValue: data.value,
|
||||
onChanged: (value) {
|
||||
controller.approvedWithOtpCode.value = value ?? false;
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
radioRow(
|
||||
value: true,
|
||||
label: ' با کد احراز',
|
||||
onTap: () {
|
||||
controller.approvedWithOtpCode.value = true;
|
||||
},
|
||||
),
|
||||
radioRow(
|
||||
value: false,
|
||||
label: 'بدون کد احراز',
|
||||
onTap: () {
|
||||
controller.approvedWithOtpCode.value = false;
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
child: RTextField(
|
||||
controller: controller.approvedWithOtpController,
|
||||
label: 'کد احراز',
|
||||
keyboardType: TextInputType.number,
|
||||
),
|
||||
visible: data.value,
|
||||
),
|
||||
],
|
||||
);
|
||||
}, controller.approvedWithOtpCode),
|
||||
SizedBox(height: 30.h),
|
||||
ObxValue((data) {
|
||||
return RElevated(
|
||||
enabled: controller.approvedWithOtpCode.value
|
||||
? controller.approvedWithOtpController.text.isNotEmpty
|
||||
: true,
|
||||
text: 'تایید',
|
||||
onPressed: () async {
|
||||
await controller.acceptEntries(item);
|
||||
},
|
||||
isFullWidth: true,
|
||||
);
|
||||
}, controller.approvedWithOtpCode),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget radioRow({
|
||||
required bool value,
|
||||
required String label,
|
||||
TextStyle? textStyle,
|
||||
GestureTapCallback? onTap,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: value),
|
||||
Text(label, style: textStyle ?? AppFonts.yekan16.copyWith(color: AppColor.textColor)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyInProvinceWaitingLogic extends GetxController {
|
||||
RxInt isExpandedListIndex = (-1).obs;
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
RxMap<String, bool> isLoadingConfirmMap = RxMap();
|
||||
Rx<Color> bgConfirmAllColor = AppColor.blueNormal.obs;
|
||||
RxInt currentPage = 1.obs;
|
||||
final RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
RxBool isButtonConfirm = false.obs;
|
||||
|
||||
Rx<Resource<PaginationModel<WaitingArrivalModel>>> waitingProduct =
|
||||
Resource<PaginationModel<WaitingArrivalModel>>.loading().obs;
|
||||
|
||||
TextEditingController weightController = TextEditingController();
|
||||
TextEditingController countController = TextEditingController();
|
||||
TextEditingController lossController = TextEditingController();
|
||||
TextEditingController approvedWithOtpController = TextEditingController();
|
||||
|
||||
RxBool approvedWithOtpCode = false.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getWaitingArrivals(),
|
||||
time: Duration(milliseconds: timeDebounce),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
getWaitingArrivals();
|
||||
approvedWithOtpController.addListener(() {
|
||||
isButtonConfirm.value = approvedWithOtpController.text.trim().length > 4;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
void setSearchValue(String? data) {
|
||||
searchedValue.value = data?.trim();
|
||||
}
|
||||
|
||||
Future<void> getWaitingArrivals([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
waitingProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.loading();
|
||||
}
|
||||
|
||||
if (searchedValue.value != null &&
|
||||
searchedValue.value!.trim().isNotEmpty &&
|
||||
currentPage.value > 1) {
|
||||
currentPage.value = 1;
|
||||
}
|
||||
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getWaitingArrivals(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
queryParams: {'type': 'not_entered'},
|
||||
pageSize: 20,
|
||||
page: currentPage.value,
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value,
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) async {
|
||||
await Future.delayed(Duration(milliseconds: 200));
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
waitingProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.empty();
|
||||
} else {
|
||||
waitingProduct.value = Resource<PaginationModel<WaitingArrivalModel>>.success(
|
||||
PaginationModel<WaitingArrivalModel>(
|
||||
count: res?.count ?? 0,
|
||||
next: res?.next,
|
||||
previous: res?.previous,
|
||||
results: [...(waitingProduct.value.data?.results ?? []), ...(res?.results ?? [])],
|
||||
),
|
||||
);
|
||||
flashingFabBgColor();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> acceptEntries(WaitingArrivalModel model) async {
|
||||
var request = StewardAllocationRequest(
|
||||
allocationKey: model.key,
|
||||
checkAllocation: true,
|
||||
state: 'accepted',
|
||||
receiverRealNumberOfCarcasses: model.realNumberOfCarcasses ?? 0,
|
||||
receiverRealWeightOfCarcasses: model.realWeightOfCarcasses?.toInt() ?? 0,
|
||||
registrationCode: approvedWithOtpCode.value
|
||||
? int.parse(approvedWithOtpController.text.trim())
|
||||
: null,
|
||||
weightLossOfCarcasses: model.weightLossOfCarcasses?.toInt() ?? 0,
|
||||
stewardCheckAllocation: true,
|
||||
).toJson();
|
||||
request.removeWhere((key, value) => value == null);
|
||||
|
||||
safeCall(
|
||||
showError: true,
|
||||
showSuccess: true,
|
||||
call: () async => await rootLogic.chickenRepository.setSateForArrivals(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
request: request,
|
||||
),
|
||||
onError: (error, stackTrace) {
|
||||
eLog(error);
|
||||
},
|
||||
onSuccess: (result) {
|
||||
getWaitingArrivals();
|
||||
rootLogic.onRefresh();
|
||||
clearApprovedController();
|
||||
toggleExpansion();
|
||||
Future.delayed(Duration(seconds: 3), () {
|
||||
Get.back();
|
||||
Get.back();
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> denyEntries(WaitingArrivalModel model) async {
|
||||
var request = StewardAllocationRequest(
|
||||
allocationKey: model.key,
|
||||
checkAllocation: true,
|
||||
state: 'rejected',
|
||||
).toJson();
|
||||
request.removeWhere((key, value) => value == null);
|
||||
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.setSateForArrivals(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
request: request,
|
||||
),
|
||||
onError: (error, stackTrace) {
|
||||
eLog(error);
|
||||
},
|
||||
onSuccess: (result) {
|
||||
getWaitingArrivals();
|
||||
rootLogic.onRefresh();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void flashingFabBgColor() {
|
||||
Timer.periodic(Duration(seconds: 2), (timer) {
|
||||
if (bgConfirmAllColor.value == AppColor.blueNormal) {
|
||||
bgConfirmAllColor.value = AppColor.blueLightHover;
|
||||
} else {
|
||||
bgConfirmAllColor.value = AppColor.blueNormal;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void clearApprovedController() {
|
||||
weightController.clear();
|
||||
countController.clear();
|
||||
lossController.clear();
|
||||
approvedWithOtpController.clear();
|
||||
approvedWithOtpCode.value = false;
|
||||
}
|
||||
|
||||
void toggleExpansion({int? index}) {
|
||||
if (isExpandedListIndex.value == index || index == null) {
|
||||
isExpandedListIndex.value = -1;
|
||||
} else {
|
||||
isExpandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyInProvinceWaitingPage extends GetView<WarehouseAndDistributionBuyInProvinceWaitingLogic> {
|
||||
const WarehouseAndDistributionBuyInProvinceWaitingPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.transparent,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
listType: ListType.separated,
|
||||
resource: data.value,
|
||||
hasMore: data.value.data?.next != null,
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
|
||||
itemBuilder: (context, index) {
|
||||
var item = data.value.data!.results![index];
|
||||
return ObxValue((val) {
|
||||
return ExpandableListItem2(
|
||||
selected: controller.isExpandedListIndex.value == index,
|
||||
onTap: () => controller.toggleExpansion(index: index),
|
||||
index: index,
|
||||
child: itemListWidget(item),
|
||||
secondChild: itemListExpandedWidget(item),
|
||||
labelColor: AppColor.blueLight,
|
||||
labelIcon: Assets.vec.timerSvg.path,
|
||||
labelIconColor: AppColor.yellowNormal2,
|
||||
);
|
||||
}, controller.isExpandedListIndex);
|
||||
},
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||
onLoadMore: () async => controller.getWaitingArrivals(true),
|
||||
);
|
||||
}, controller.waitingProduct),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Row itemListWidget(WaitingArrivalModel item) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
'${controller.rootLogic.isKillHouse(item) ? 'کشتارگاه' : 'مباشر'} ${controller.rootLogic.isKillHouse(item) ? item.killHouse?.name : item.steward?.user?.fullname} ',
|
||||
textAlign: TextAlign.start,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Text(
|
||||
item.date?.formattedJalaliDate ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
spacing: 3,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
spacing: 6,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: item.product?.name?.contains('مرغ گرم') ?? false,
|
||||
child: Assets.vec.hotChickenSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
item.weightOfCarcasses?.separatedByCommaFa.addKg ?? 'ندارد',
|
||||
textAlign: TextAlign.left,
|
||||
textDirection: TextDirection.ltr,
|
||||
style: AppFonts.yekan12Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'${item.amount?.separatedByCommaFa} ریال',
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
(item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد',
|
||||
style: AppFonts.yekan12Bold.copyWith(
|
||||
color: (item.approvedPriceStatus ?? false)
|
||||
? AppColor.blueNormal
|
||||
: AppColor.greenNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container itemListExpandedWidget(WaitingArrivalModel item) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${controller.rootLogic.isKillHouse(item) ? item.killHouse?.name : item.steward?.user?.fullname} ',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
'در انتظار',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan10.copyWith(color: AppColor.darkGreyDark),
|
||||
),
|
||||
SizedBox(width: 7),
|
||||
Assets.vec.clockSvg.svg(width: 16.w, height: 16.h),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: AppColor.blueLightHover),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
item.date?.toJalali.formatter.wN ?? 'ندارد',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.y}',
|
||||
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'مشخصات فروشنده',
|
||||
value:
|
||||
'${controller.rootLogic.isKillHouse(item) ? item.killHouse?.killHouseOperator?.user?.fullname : item.steward?.user?.fullname} ',
|
||||
),
|
||||
buildRow(
|
||||
title: 'تلفن فروشنده',
|
||||
value:
|
||||
'${controller.rootLogic.isKillHouse(item) ? item.killHouse?.killHouseOperator?.user?.mobile : item.steward?.user?.mobile} ',
|
||||
valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
buildRow(title: 'نوع تخصیص', value: item.allocationType?.faAllocationType ?? 'ندارد'),
|
||||
buildRow(title: ' سهمیه', value: item.quota?.faTitle ?? 'ندارد'),
|
||||
buildRow(title: 'نوع فروش', value: item.saleType == "governmental" ? 'دولتی' : 'آزاد'),
|
||||
buildRow(title: 'محصول', value: item.product?.name ?? 'ندارد'),
|
||||
buildRow(
|
||||
title: 'تاریخ تولید گوشت',
|
||||
value: item.productionDate?.toJalali.toJalaliDateTime() ?? 'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'وزن خریداری شده',
|
||||
value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت هر کیلوگرم',
|
||||
titleLabel: (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد',
|
||||
titleLabelStyle: AppFonts.yekan14Bold.copyWith(color: AppColor.greenNormal),
|
||||
value: '${item.amount?.separatedByCommaFa} ریال',
|
||||
),
|
||||
|
||||
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByCommaFa} ریال'),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16.w,
|
||||
children: [
|
||||
ObxValue((data) {
|
||||
return RElevated(
|
||||
text: 'تایید',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
isLoading: data[item.key!] ?? false,
|
||||
onPressed: () async {
|
||||
await Get.bottomSheet(conformationBottomSheet(item), isScrollControlled: true);
|
||||
},
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
);
|
||||
}, controller.isLoadingConfirmMap),
|
||||
ROutlinedElevated(
|
||||
text: 'رد',
|
||||
textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal),
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
buildWarningDialog(
|
||||
title: 'اخطار',
|
||||
middleText: 'آیا از رد شدن این مورد اطمینان دارید؟',
|
||||
onConfirm: () => controller.denyEntries(item),
|
||||
onRefresh: () => controller.getWaitingArrivals(),
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.redNormal,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget conformationBottomSheet(WaitingArrivalModel item) {
|
||||
controller.weightController.text = item.weightOfCarcasses.separatedByComma;
|
||||
return BaseBottomSheet(
|
||||
height: 450.h,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(height: 10),
|
||||
RTextField(
|
||||
label: 'وزن(کیلوگرم)',
|
||||
controller: controller.weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
RTextField(
|
||||
label: 'حجم(قطعه)',
|
||||
controller: controller.countController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
RTextField(
|
||||
label: 'افت وزن(کیلوگرم)',
|
||||
controller: controller.lossController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
|
||||
Text('تایید ', style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor)),
|
||||
ObxValue((data) {
|
||||
return Column(
|
||||
children: [
|
||||
RadioGroup(
|
||||
groupValue: data.value,
|
||||
onChanged: (value) {
|
||||
controller.approvedWithOtpCode.value = value ?? false;
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
radioRow(
|
||||
value: true,
|
||||
label: ' با کد احراز',
|
||||
onTap: () {
|
||||
controller.approvedWithOtpCode.value = true;
|
||||
},
|
||||
),
|
||||
radioRow(
|
||||
value: false,
|
||||
label: 'بدون کد احراز',
|
||||
onTap: () {
|
||||
controller.approvedWithOtpCode.value = false;
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
child: RTextField(
|
||||
controller: controller.approvedWithOtpController,
|
||||
label: 'کد احراز',
|
||||
keyboardType: TextInputType.number,
|
||||
maxLength: 5,
|
||||
),
|
||||
visible: data.value,
|
||||
),
|
||||
],
|
||||
);
|
||||
}, controller.approvedWithOtpCode),
|
||||
SizedBox(height: 30.h),
|
||||
Obx(() {
|
||||
return RElevated(
|
||||
enabled: controller.approvedWithOtpCode.value
|
||||
? controller.isButtonConfirm.value
|
||||
: true,
|
||||
text: 'تایید',
|
||||
onPressed: () async {
|
||||
await controller.acceptEntries(item);
|
||||
},
|
||||
isFullWidth: true,
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget radioRow({
|
||||
required bool value,
|
||||
required String label,
|
||||
TextStyle? textStyle,
|
||||
GestureTapCallback? onTap,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: value),
|
||||
Text(label, style: textStyle ?? AppFonts.yekan16.copyWith(color: AppColor.textColor)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/buy/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sale/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyOutOfProvinceLogic extends GetxController {
|
||||
late List<String> routesName;
|
||||
RxBool isSubmitButtonEnabled = false.obs;
|
||||
RxInt expandedListIndex = (-1).obs;
|
||||
|
||||
final RxInt currentPage = 1.obs;
|
||||
final RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
final RxBool isOnLoadingSubmitOrEdit = false.obs;
|
||||
|
||||
//TODO add this to Di
|
||||
ImagePicker imagePicker = ImagePicker();
|
||||
|
||||
Rx<Resource<PaginationModel<StewardFreeBar>>> purchaseOutOfProvinceList =
|
||||
Resource<PaginationModel<StewardFreeBar>>.loading().obs;
|
||||
Rxn<ProductModel> selectedProduct = Rxn();
|
||||
|
||||
RxList<IranProvinceCityModel> cites = <IranProvinceCityModel>[].obs;
|
||||
Rxn<IranProvinceCityModel> selectedProvince = Rxn();
|
||||
Rxn<IranProvinceCityModel> selectedCity = Rxn();
|
||||
Rxn<XFile> selectedImage = Rxn<XFile>();
|
||||
final RxnString _base64Image = RxnString();
|
||||
RxnString editImageUrl = RxnString();
|
||||
RxnString editFreeBarKey = RxnString();
|
||||
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
WarehouseAndDistributionBuyLogic buyLogic = Get.find<WarehouseAndDistributionBuyLogic>();
|
||||
|
||||
WarehouseAndDistributionSaleLogic outOfTheProvinceLogic = Get.find<WarehouseAndDistributionSaleLogic>();
|
||||
|
||||
GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
TextEditingController sellerNameController = TextEditingController();
|
||||
TextEditingController sellerPhoneController = TextEditingController();
|
||||
TextEditingController carcassWeightController = TextEditingController();
|
||||
TextEditingController carcassCountController = TextEditingController();
|
||||
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
routesName = [...buyLogic.routesName, 'خارج استان'].toList();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
getStewardPurchaseOutOfProvince();
|
||||
selectedProvince.listen((p0) => getCites());
|
||||
|
||||
selectedProduct.value = rootLogic.rolesProductsModel.first;
|
||||
setupListeners();
|
||||
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getStewardPurchaseOutOfProvince(),
|
||||
time: Duration(milliseconds: timeDebounce),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
sellerNameController.dispose();
|
||||
sellerPhoneController.dispose();
|
||||
carcassWeightController.dispose();
|
||||
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
void setSearchValue(String? data) {
|
||||
searchedValue.value = data?.trim();
|
||||
}
|
||||
|
||||
Future<void> getStewardPurchaseOutOfProvince([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
purchaseOutOfProvinceList.value = Resource<PaginationModel<StewardFreeBar>>.loading();
|
||||
}
|
||||
|
||||
if (searchedValue.value != null &&
|
||||
searchedValue.value!.trim().isNotEmpty &&
|
||||
currentPage.value > 1) {
|
||||
currentPage.value = 1; // Reset to first page if search value is set
|
||||
}
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 20,
|
||||
page: currentPage.value,
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value,
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) async {
|
||||
await Future.delayed(Duration(milliseconds: 500));
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
purchaseOutOfProvinceList.value = Resource<PaginationModel<StewardFreeBar>>.empty();
|
||||
} else {
|
||||
purchaseOutOfProvinceList.value = Resource<PaginationModel<StewardFreeBar>>.success(
|
||||
PaginationModel<StewardFreeBar>(
|
||||
count: res?.count ?? 0,
|
||||
next: res?.next,
|
||||
previous: res?.previous,
|
||||
results: [
|
||||
...(purchaseOutOfProvinceList.value.data?.results ?? []),
|
||||
...(res?.results ?? []),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getCites() async {
|
||||
await safeCall(
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''),
|
||||
onSuccess: (result) {
|
||||
if (result != null && result.isNotEmpty) {
|
||||
cites.value = result;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void setupListeners() {
|
||||
sellerNameController.addListener(() {
|
||||
checkFormValid();
|
||||
if (!isSubmitButtonEnabled.value) {
|
||||
isSubmitButtonEnabled.value = !isSubmitButtonEnabled.value;
|
||||
}
|
||||
});
|
||||
sellerPhoneController.addListener(checkFormValid);
|
||||
carcassWeightController.addListener(checkFormValid);
|
||||
carcassCountController.addListener(checkFormValid);
|
||||
|
||||
ever(selectedProvince, (_) => checkFormValid());
|
||||
ever(selectedCity, (_) => checkFormValid());
|
||||
ever(selectedProduct, (_) => checkFormValid());
|
||||
ever(selectedImage, (data) async {
|
||||
checkFormValid();
|
||||
if (data?.path != null) {
|
||||
_base64Image.value = await convertImageToBase64(data!.path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void checkFormValid() {
|
||||
isSubmitButtonEnabled.value =
|
||||
sellerNameController.text.isNotEmpty &&
|
||||
sellerPhoneController.text.isNotEmpty &&
|
||||
carcassWeightController.text.isNotEmpty &&
|
||||
carcassCountController.text.isNotEmpty &&
|
||||
selectedProvince.value != null &&
|
||||
selectedCity.value != null &&
|
||||
selectedProduct.value != null &&
|
||||
(selectedImage.value != null || editImageUrl.value != null);
|
||||
|
||||
if (isSubmitButtonEnabled.value) {
|
||||
isOnLoadingSubmitOrEdit.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> createStewardPurchaseOutOfProvince() async {
|
||||
bool res = false;
|
||||
isOnLoadingSubmitOrEdit.value = true;
|
||||
if (!(formKey.currentState?.validate() ?? false)) {
|
||||
isOnLoadingSubmitOrEdit.value = false;
|
||||
return res;
|
||||
}
|
||||
await safeCall(
|
||||
showError: true,
|
||||
call: () async {
|
||||
CreateStewardFreeBar createStewardFreeBar = CreateStewardFreeBar(
|
||||
productKey: selectedProduct.value!.key,
|
||||
killHouseName: sellerNameController.text,
|
||||
killHouseMobile: sellerPhoneController.text,
|
||||
province: selectedProvince.value!.name,
|
||||
city: selectedCity.value!.name,
|
||||
weightOfCarcasses: int.parse(carcassWeightController.text.clearComma),
|
||||
numberOfCarcasses: int.parse(carcassCountController.text.clearComma),
|
||||
barImage: _base64Image.value,
|
||||
date: DateTime.now().formattedYHMS,
|
||||
);
|
||||
await rootLogic.chickenRepository.createStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: createStewardFreeBar,
|
||||
);
|
||||
},
|
||||
onSuccess: (result) {
|
||||
getStewardPurchaseOutOfProvince();
|
||||
resetSubmitForm();
|
||||
toggleExpansion();
|
||||
res = true;
|
||||
},
|
||||
);
|
||||
isOnLoadingSubmitOrEdit.value = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
void resetSubmitForm() {
|
||||
sellerNameController.clear();
|
||||
sellerPhoneController.clear();
|
||||
carcassWeightController.clear();
|
||||
carcassCountController.clear();
|
||||
selectedProvince.value = null;
|
||||
selectedCity.value = null;
|
||||
selectedImage.value = null;
|
||||
_base64Image.value = null;
|
||||
editImageUrl.value = null;
|
||||
|
||||
isSubmitButtonEnabled.value = false;
|
||||
}
|
||||
|
||||
void setEditData(StewardFreeBar item) async {
|
||||
editImageUrl.value = item.barImage;
|
||||
sellerNameController.text = item.killHouseName ?? '';
|
||||
sellerPhoneController.text = item.killHouseMobile ?? '';
|
||||
carcassWeightController.text = item.weightOfCarcasses.separatedByComma;
|
||||
carcassCountController.text = item.numberOfCarcasses.separatedByComma;
|
||||
editFreeBarKey.value = item.key;
|
||||
selectedProvince.value = IranProvinceCityModel(name: item.province);
|
||||
selectedCity.value = IranProvinceCityModel(name: item.city);
|
||||
selectedProduct.value = rootLogic.rolesProductsModel.firstWhere(
|
||||
(element) => element.key == item.product!.key,
|
||||
);
|
||||
|
||||
isSubmitButtonEnabled.value = true;
|
||||
}
|
||||
|
||||
Future<void> editStewardPurchaseOutOfProvince() async {
|
||||
CreateStewardFreeBar edit = CreateStewardFreeBar(
|
||||
productKey: selectedProduct.value!.key,
|
||||
key: editFreeBarKey.value,
|
||||
killHouseName: sellerNameController.text,
|
||||
killHouseMobile: sellerPhoneController.text,
|
||||
province: selectedProvince.value!.name,
|
||||
city: selectedCity.value!.name,
|
||||
weightOfCarcasses: int.parse(carcassWeightController.text.clearComma),
|
||||
numberOfCarcasses: int.parse(carcassCountController.text.clearComma),
|
||||
date: DateTime.now().formattedYHMS,
|
||||
);
|
||||
|
||||
if (_base64Image.value != null) {
|
||||
edit = edit.copyWith(barImage: _base64Image.value);
|
||||
}
|
||||
|
||||
await safeCall(
|
||||
showError: true,
|
||||
call: () => rootLogic.chickenRepository.editStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: edit,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
onRefresh();
|
||||
rootLogic.onRefresh();
|
||||
toggleExpansion();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> deleteStewardPurchaseOutOfProvince(String key) async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.deleteStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildRawQueryParams(queryParams: {'key': key}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
currentPage.value = 1;
|
||||
await rootLogic.onRefresh();
|
||||
await getStewardPurchaseOutOfProvince();
|
||||
}
|
||||
|
||||
void toggleExpansion({int? index}) {
|
||||
if (expandedListIndex.value == index || index == null) {
|
||||
expandedListIndex.value = -1;
|
||||
} else {
|
||||
expandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,698 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart' hide Image;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionBuyOutOfProvincePage
|
||||
extends GetView<WarehouseAndDistributionBuyOutOfProvinceLogic> {
|
||||
const WarehouseAndDistributionBuyOutOfProvincePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChickenBasePage(
|
||||
routes: controller.routesName,
|
||||
backId: killHouseWarehouseAndDistributionBuyKey,
|
||||
onRefresh: controller.onRefresh,
|
||||
onSearchChanged: (data) => controller.setSearchValue(data),
|
||||
onFilterTap: () {
|
||||
Get.bottomSheet(filterBottomSheet());
|
||||
},
|
||||
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Column(
|
||||
children: [
|
||||
//inventoryWidget(controller.rootLogic),
|
||||
ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
listType: ListType.separated,
|
||||
resource: data.value,
|
||||
hasMore: data.value.data?.next != null,
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
|
||||
itemBuilder: (context, index) {
|
||||
var item = data.value.data!.results![index];
|
||||
return ObxValue((val) {
|
||||
return ExpandableListItem2(
|
||||
selected: val.value == index,
|
||||
onTap: () => controller.toggleExpansion(index: index),
|
||||
index: index,
|
||||
child: itemListWidget(item),
|
||||
secondChild: itemListExpandedWidget(item),
|
||||
labelColor: AppColor.blueLight,
|
||||
labelIcon: Assets.vec.truckFastOutlinedSvg.path,
|
||||
);
|
||||
}, controller.expandedListIndex);
|
||||
},
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||
onLoadMore: () async =>
|
||||
controller.getStewardPurchaseOutOfProvince(true),
|
||||
);
|
||||
}, controller.purchaseOutOfProvinceList),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 5,
|
||||
bottom: 95,
|
||||
child: RFab.add(
|
||||
onPressed: () {
|
||||
Get.bottomSheet(
|
||||
addPurchasedInformationBottomSheet(),
|
||||
isScrollControlled: true,
|
||||
ignoreSafeArea: false,
|
||||
).whenComplete(() {
|
||||
controller.resetSubmitForm();
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container itemListExpandedWidget(StewardFreeBar item) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${item.province}-${item.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: AppColor.blueLightHover),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
item.date?.toJalali.formatter.wN ?? 'ندارد',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.textColor,
|
||||
),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.y}',
|
||||
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'مشخصات فروشنده',
|
||||
value: item.killHouseName ?? 'ندارد',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'تلفن فروشنده',
|
||||
value: item.killHouseMobile ?? 'ندارد',
|
||||
valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
buildRow(title: 'محصول', value: item.product?.name ?? 'ندارد'),
|
||||
buildRow(
|
||||
title: 'وزن خریداری شده',
|
||||
value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم',
|
||||
),
|
||||
buildRow(
|
||||
title: 'حجم خریداری شده',
|
||||
value: '${item.numberOfCarcasses?.separatedByCommaFa} قطعه',
|
||||
),
|
||||
buildRowOnTapped(
|
||||
title: 'مشاهده بارنامه',
|
||||
titleStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
valueWidget: Assets.vec.clipboardEyeSvg.svg(
|
||||
width: 20,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.blueNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
Get.bottomSheet(
|
||||
BaseBottomSheet(
|
||||
height: 400,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
'بارنامه',
|
||||
style: AppFonts.yekan16Bold.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
|
||||
Image.network(
|
||||
item.barImage ?? '',
|
||||
fit: BoxFit.cover,
|
||||
height: 300,
|
||||
errorBuilder: (context, error, stackTrace) {
|
||||
eLog(error.toString());
|
||||
return Center(child: Text('خطایی پیش آمده!'));
|
||||
},
|
||||
loadingBuilder: (context, child, loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return CupertinoActivityIndicator();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16.w,
|
||||
children: [
|
||||
RElevated(
|
||||
text: 'ویرایش',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
controller.setEditData(item);
|
||||
Get.bottomSheet(
|
||||
addPurchasedInformationBottomSheet(true),
|
||||
isScrollControlled: true,
|
||||
).whenComplete(() {
|
||||
controller.resetSubmitForm();
|
||||
});
|
||||
},
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
),
|
||||
ROutlinedElevated(
|
||||
text: 'حذف',
|
||||
textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal),
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
buildDeleteDialog(
|
||||
onConfirm: () => controller
|
||||
.deleteStewardPurchaseOutOfProvince(item.key!),
|
||||
onRefresh: () async {
|
||||
controller.rootLogic.onRefresh();
|
||||
controller.onRefresh();
|
||||
controller.toggleExpansion();
|
||||
},
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.redNormal,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Row itemListWidget(StewardFreeBar item) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
item.killHouseName ?? 'ندارد',
|
||||
textAlign: TextAlign.start,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Text(
|
||||
item.date?.formattedJalaliDate ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
spacing: 3,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: item.product?.name?.contains('مرغ گرم') ?? false,
|
||||
child: Assets.vec.hotChickenSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.blueNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${item.weightOfCarcasses?.separatedByCommaFa}kg',
|
||||
textAlign: TextAlign.left,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
'${item.numberOfCarcasses.separatedByComma} ${'قطعه'}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
'${item.province}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Text(
|
||||
'${item.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget addPurchasedInformationBottomSheet([bool isOnEdit = false]) {
|
||||
return BaseBottomSheet(
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
isOnEdit ? 'ویرایش اطلاعات خرید' : 'ثبت اطلاعات خرید',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
_productDropDown(),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [_provinceWidget(), _cityWidget()],
|
||||
),
|
||||
),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
RTextField(
|
||||
controller: controller.sellerNameController,
|
||||
label: 'نام فروشنده',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filled: true,
|
||||
filledColor: AppColor.bgLight,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.sellerPhoneController,
|
||||
label: 'تلفن فروشنده',
|
||||
keyboardType: TextInputType.phone,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
maxLength: 11,
|
||||
filled: true,
|
||||
filledColor: AppColor.bgLight,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'لطفاً شماره موبایل را وارد کنید';
|
||||
}
|
||||
String cleaned = value.replaceAll(',', '');
|
||||
if (cleaned.length != 11) {
|
||||
return 'شماره موبایل باید ۱۱ رقم باشد';
|
||||
}
|
||||
if (!cleaned.startsWith('09')) {
|
||||
return 'شماره موبایل باید با 09 شروع شود';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
|
||||
UnitTextField(
|
||||
controller: controller.carcassWeightController,
|
||||
hint: 'وزن',
|
||||
unit: 'کیلوگرم',
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
),
|
||||
|
||||
UnitTextField(
|
||||
controller: controller.carcassCountController,
|
||||
hint: 'حجم',
|
||||
unit: 'قطعه',
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_imageCarcasesWidget(isOnEdit),
|
||||
submitButtonWidget(isOnEdit),
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget submitButtonWidget(bool isOnEdit) {
|
||||
return Obx(() {
|
||||
return RElevated(
|
||||
text: isOnEdit ? 'ویرایش' : 'ثبت',
|
||||
width: Get.width,
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
isLoading: controller.isOnLoadingSubmitOrEdit.value,
|
||||
enabled: controller.isSubmitButtonEnabled.value,
|
||||
onPressed: isOnEdit
|
||||
? () async {
|
||||
await controller.editStewardPurchaseOutOfProvince();
|
||||
Get.back();
|
||||
}
|
||||
: () async {
|
||||
var res = await controller.createStewardPurchaseOutOfProvince();
|
||||
if (res) {
|
||||
Get.back();
|
||||
}
|
||||
},
|
||||
height: 40,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _productDropDown() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<ProductModel>(
|
||||
items: controller.rootLogic.rolesProductsModel,
|
||||
height: 56,
|
||||
hasDropIcon: false,
|
||||
background: Colors.white,
|
||||
onChanged: (value) {
|
||||
controller.selectedProduct.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedProduct.value,
|
||||
initialValue: controller.selectedProduct.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
(item?.name?.contains('مرغ گرم') ?? false)
|
||||
? Assets.images.chicken.image(width: 40, height: 40)
|
||||
: Assets.vec.placeHolderSvg.svg(width: 40, height: 40),
|
||||
|
||||
Text(item?.name ?? 'انتخاب محصول'),
|
||||
Spacer(),
|
||||
Text(
|
||||
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0}',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _provinceWidget() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: controller.rootLogic.provinces,
|
||||
onChanged: (value) {
|
||||
controller.selectedProvince.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedProvince.value,
|
||||
itemBuilder: (item) => Text(
|
||||
item.name ?? 'بدون نام',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.lightGreyDarker),
|
||||
),
|
||||
labelBuilder: (item) => item?.name != null
|
||||
? Text(
|
||||
item!.name!,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
)
|
||||
: Text(
|
||||
'انتخاب استان',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.textColorLight,
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _cityWidget() {
|
||||
return ObxValue((data) {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: data,
|
||||
onChanged: (value) {
|
||||
controller.selectedCity.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedCity.value,
|
||||
itemBuilder: (item) => Text(
|
||||
item.name ?? 'بدون نام',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.lightGreyDarker),
|
||||
),
|
||||
labelBuilder: (item) => item?.name != null
|
||||
? Text(
|
||||
item!.name!,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
)
|
||||
: Text(
|
||||
'انتخاب شهر',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.textColorLight,
|
||||
),
|
||||
),
|
||||
);
|
||||
}, controller.cites);
|
||||
}
|
||||
|
||||
SizedBox _imageCarcasesWidget(bool isOnEdit) {
|
||||
return SizedBox(
|
||||
width: Get.width,
|
||||
height: 370,
|
||||
child: Card(
|
||||
color: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
'بارنامه',
|
||||
style: AppFonts.yekan16Bold.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return Container(
|
||||
width: Get.width,
|
||||
height: 270,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.lightGreyNormal,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 1, color: AppColor.blackLight),
|
||||
),
|
||||
child: Center(
|
||||
child: isOnEdit
|
||||
? Image.network(controller.editImageUrl.value ?? '')
|
||||
: data.value == null
|
||||
? Padding(
|
||||
padding: const EdgeInsets.fromLTRB(
|
||||
30,
|
||||
10,
|
||||
10,
|
||||
30,
|
||||
),
|
||||
child: Assets.vec.placeHolderSvg.svg(
|
||||
width: 200.w,
|
||||
height: 150.h,
|
||||
),
|
||||
)
|
||||
: Image.file(
|
||||
File(data.value!.path),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
);
|
||||
}, controller.selectedImage),
|
||||
),
|
||||
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
RElevated(
|
||||
text: 'گالری',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
onPressed: () async {
|
||||
controller.selectedImage.value = await controller
|
||||
.imagePicker
|
||||
.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
imageQuality: 60,
|
||||
maxWidth: 1080,
|
||||
maxHeight: 720,
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
ROutlinedElevated(
|
||||
text: 'دوربین',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
textStyle: AppFonts.yekan20.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
onPressed: () async {
|
||||
controller.selectedImage.value = await controller
|
||||
.imagePicker
|
||||
.pickImage(
|
||||
source: ImageSource.camera,
|
||||
imageQuality: 60,
|
||||
maxWidth: 1080,
|
||||
maxHeight: 720,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget filterBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 200,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
'فیلترها',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: dateFilterWidget(
|
||||
date: controller.fromDateFilter,
|
||||
onChanged: (jalali) =>
|
||||
controller.fromDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: dateFilterWidget(
|
||||
isFrom: false,
|
||||
date: controller.toDateFilter,
|
||||
onChanged: (jalali) => controller.toDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
RElevated(
|
||||
text: 'اعمال فیلتر',
|
||||
isFullWidth: true,
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
onPressed: () {
|
||||
controller.getStewardPurchaseOutOfProvince();
|
||||
Get.back();
|
||||
},
|
||||
height: 40,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionHomeLogic extends GetxController {
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
RxnInt totalWeightTodayBars = RxnInt();
|
||||
Rxn<KillHouseDistributionInfo> killHouseDistributionInfo = Rxn<KillHouseDistributionInfo>();
|
||||
Rxn<BarInformation> barInformation = Rxn();
|
||||
|
||||
RxList<Map<String, String?>> inventoryItems = [
|
||||
{'خریدهای دولتی داخل استان': null},
|
||||
{'خریدهای آزاد داخل استان': null},
|
||||
{'وزن خریدهای خارج استان': null},
|
||||
{'کل ورودی به انبار': null},
|
||||
{'کل فروش': null},
|
||||
{'مانده انبار': null},
|
||||
].obs;
|
||||
|
||||
RxList<Map<String, String>> broadcastItems = [
|
||||
{'وزن دولتی': '2،225،256'},
|
||||
{'وزن آزاد': '2،225،256'},
|
||||
{'فروش دولتی': '2،225،256'},
|
||||
{'فروش آزاد': '2،225،256'},
|
||||
{'توزیع داخل استان': '2،225،256'},
|
||||
{'توزیع خارج استان': '2،225،256'},
|
||||
{'قطعه بندی': '2،225،256'},
|
||||
].obs;
|
||||
|
||||
RxBool isExpanded = false.obs;
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
refreshData();
|
||||
|
||||
}
|
||||
|
||||
Future<void> refreshData() async {
|
||||
await Future.wait([
|
||||
getGeneralBarsInformation(),
|
||||
getTodayBars(),
|
||||
getDistributionInformation(),
|
||||
rootLogic.getRolesProducts(),
|
||||
rootLogic.getKillHouseSalesInfoDashboard(),
|
||||
]);
|
||||
}
|
||||
|
||||
Future<void> getGeneralBarsInformation() async {
|
||||
await safeCall<BarInformation?>(
|
||||
call: () async => await rootLogic.chickenRepository.getGeneralBarInformation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(role: 'Steward'),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
barInformation.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getTodayBars() async {
|
||||
await safeCall<BarInformation?>(
|
||||
call: () async => await rootLogic.chickenRepository.getGeneralBarInformation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
fromDate: DateTime.now(),
|
||||
toDate: DateTime.now(),
|
||||
role: 'Steward',
|
||||
),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
totalWeightTodayBars.value = result.totalBarsWeight?.toInt();
|
||||
}
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getDistributionInformation() async {
|
||||
await safeCall<KillHouseDistributionInfo?>(
|
||||
call: () async => await rootLogic.chickenRepository.getKillHouseDistributionInfo(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
killHouseDistributionInfo.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,276 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:rasadyar_chicken/data/data_source/local/chicken_local.dart';
|
||||
import 'package:rasadyar_chicken/data/di/chicken_di.dart';
|
||||
import 'package:rasadyar_chicken/data/models/kill_house_module/warehouse_and_distribution/response/kill_house_sales_info_dashboard.dart';
|
||||
import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'
|
||||
hide ProductModel;
|
||||
import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/kill_house/kill_house_repository.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/common/profile/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/buy/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/home/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sale/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/segmentation/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
enum ErrorLocationType { serviceDisabled, permissionDenied, none }
|
||||
|
||||
class WarehouseAndDistributionRootLogic extends GetxController {
|
||||
DateTime? _lastBackPressed;
|
||||
RxInt currentPage = 2.obs;
|
||||
List<Widget> pages = [
|
||||
WarehouseAndDistributionBuyPage(),
|
||||
WarehouseAndDistributionSalePage(),
|
||||
WarehouseAndDistributionHomePage(),
|
||||
WarehouseAndDistributionSegmentationPage(),
|
||||
ProfilePage(),
|
||||
];
|
||||
|
||||
final defaultRoutes = <int, String>{
|
||||
0: ChickenRoutes.buyWarehouseAndDistribution,
|
||||
1: ChickenRoutes.saleWarehouseAndDistribution,
|
||||
};
|
||||
RxList<ProductModel> rolesProductsModel = RxList<ProductModel>();
|
||||
Rxn<WidelyUsedLocalModel> widelyUsedList = Rxn<WidelyUsedLocalModel>();
|
||||
Rxn<StewardSalesInfoDashboard> stewardSalesInfoDashboard =
|
||||
Rxn<StewardSalesInfoDashboard>();
|
||||
Rxn<StewardRemainWeight> stewardRemainWeight = Rxn<StewardRemainWeight>();
|
||||
|
||||
late DioRemote dioRemote;
|
||||
var tokenService = Get.find<TokenStorageService>();
|
||||
late ChickenRepository chickenRepository;
|
||||
|
||||
late KillHouseRepository killHouseRepository;
|
||||
late ChickenLocalDataSource localDatasource;
|
||||
|
||||
RxList<ErrorLocationType> errorLocationType = RxList();
|
||||
RxMap<int, dynamic> inventoryExpandedList = RxMap();
|
||||
Rxn<InventoryModel> inventoryModel = Rxn<InventoryModel>();
|
||||
Rxn<KillHouseSalesInfoDashboard> killHouseSalesInfoDashboard =
|
||||
Rxn<KillHouseSalesInfoDashboard>();
|
||||
RxList<IranProvinceCityModel> provinces = <IranProvinceCityModel>[].obs;
|
||||
|
||||
// Cancel tokens for API calls
|
||||
CancelToken? _inventoryCancelToken;
|
||||
CancelToken? _provincesCancelToken;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
localDatasource = diChicken.get<ChickenLocalDataSource>();
|
||||
chickenRepository = diChicken.get<ChickenRepository>();
|
||||
killHouseRepository = diChicken.get<KillHouseRepository>();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
|
||||
if (provinces.isEmpty) {
|
||||
getProvinces();
|
||||
}
|
||||
if (killHouseSalesInfoDashboard.value == null) {
|
||||
getKillHouseSalesInfoDashboard();
|
||||
}
|
||||
if (rolesProductsModel.isEmpty) {
|
||||
getRolesProducts();
|
||||
}
|
||||
getStewardSaleDashboard();
|
||||
getStewardRemainWeightData();
|
||||
|
||||
if (widelyUsedList.value?.hasInit != true) {
|
||||
//TODO
|
||||
localDatasource.initWidleyUsed().then(
|
||||
(value) => localDatasource.getAllWidely(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// Cancel any ongoing requests when controller is disposed
|
||||
_inventoryCancelToken?.cancel();
|
||||
_provincesCancelToken?.cancel();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
await Future.wait([
|
||||
getKillHouseSalesInfoDashboard(),
|
||||
getRolesProducts(),
|
||||
getStewardSaleDashboard(),
|
||||
getStewardRemainWeightData(),
|
||||
getProvinces(),
|
||||
getStewardRemainWeightData(),
|
||||
]);
|
||||
}
|
||||
|
||||
void toggleExpanded(int index) {
|
||||
if (inventoryExpandedList.keys.contains(index)) {
|
||||
inventoryExpandedList.remove(index);
|
||||
} else {
|
||||
inventoryExpandedList[index] = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getKillHouseSalesInfoDashboard() async {
|
||||
// Cancel previous request if still running
|
||||
_inventoryCancelToken?.cancel();
|
||||
_inventoryCancelToken = CancelToken();
|
||||
|
||||
await safeCall<KillHouseSalesInfoDashboard?>(
|
||||
call: () async =>
|
||||
await killHouseRepository.getKillHouseSalesInfoDashboard(
|
||||
token: tokenService.accessToken.value!,
|
||||
cancelToken: _inventoryCancelToken,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
killHouseSalesInfoDashboard.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stackTrace) {
|
||||
if (error is DioException && error.type == DioExceptionType.cancel) {
|
||||
// Request was cancelled, ignore the error
|
||||
return;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void rootErrorHandler(DioException error) {
|
||||
handleGeneric(error, () {
|
||||
tokenService.deleteModuleTokens(Module.chicken);
|
||||
});
|
||||
}
|
||||
|
||||
void changePage(int index) {
|
||||
currentPage.value = index;
|
||||
}
|
||||
|
||||
Future<void> getProvinces() async {
|
||||
// Cancel previous request if still running
|
||||
_provincesCancelToken?.cancel();
|
||||
_provincesCancelToken = CancelToken();
|
||||
|
||||
try {
|
||||
final res = await chickenRepository.getProvince(
|
||||
cancelToken: _provincesCancelToken,
|
||||
);
|
||||
if (res != null) {
|
||||
provinces.clear();
|
||||
provinces.value = res;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e is DioException && e.type == DioExceptionType.cancel) {
|
||||
// Request was cancelled, ignore the error
|
||||
return;
|
||||
}
|
||||
provinces.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getRolesProducts() async {
|
||||
safeCall(
|
||||
call: () async => await chickenRepository.getRolesProducts(
|
||||
token: tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
rolesProductsModel.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getStewardSaleDashboard() async {
|
||||
safeCall(
|
||||
call: () async => await chickenRepository.getStewardSalesInfoDashboard(
|
||||
token: tokenService.accessToken.value!,
|
||||
queryParameters: buildRawQueryParams(role: 'Steward'),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
stewardSalesInfoDashboard.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getStewardRemainWeightData() async {
|
||||
safeCall(
|
||||
call: () async => await chickenRepository.getStewardRemainWeight(
|
||||
token: tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
stewardRemainWeight.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
int getNestedKey() {
|
||||
switch (currentPage.value) {
|
||||
case 0:
|
||||
return stewardFirstKey;
|
||||
case 1:
|
||||
return stewardSecondKey;
|
||||
case 2:
|
||||
return stewardThirdKey;
|
||||
|
||||
case 3:
|
||||
return stewardFourthKey;
|
||||
|
||||
case 4:
|
||||
return stewardFourthKey;
|
||||
|
||||
default:
|
||||
return stewardThirdKey;
|
||||
}
|
||||
}
|
||||
|
||||
void onPopScopTaped() async {
|
||||
final nestedKeyId = getNestedKey();
|
||||
GlobalKey<NavigatorState>? currentNestedKey = Get.nestedKey(nestedKeyId);
|
||||
|
||||
if (currentNestedKey?.currentState?.canPop() == true) {
|
||||
iLog(currentNestedKey?.currentState?.canPop());
|
||||
iLog(currentNestedKey?.currentContext);
|
||||
currentNestedKey?.currentState?.popUntil((route) => route.isFirst);
|
||||
} else {
|
||||
final now = DateTime.now();
|
||||
if (_lastBackPressed == null ||
|
||||
now.difference(_lastBackPressed!) > Duration(seconds: 2)) {
|
||||
_lastBackPressed = now;
|
||||
Get.snackbar(
|
||||
'خروج از برنامه',
|
||||
'برای خروج دوباره بازگشت را بزنید',
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: AppColor.warning,
|
||||
);
|
||||
} else {
|
||||
await SystemNavigator.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isKillHouse(WaitingArrivalModel model) =>
|
||||
model.allocationType?.split("_")[0].toLowerCase() == "killhouse";
|
||||
}
|
||||
@@ -0,0 +1,695 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/chicken.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionRootPage
|
||||
extends GetView<WarehouseAndDistributionRootLogic> {
|
||||
WarehouseAndDistributionRootPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ObxValue((data) {
|
||||
return ChickenBasePage(
|
||||
isFullScreen: true,
|
||||
isBase: true,
|
||||
onPopScopTaped: controller.onPopScopTaped,
|
||||
child: Stack(
|
||||
children: [
|
||||
IndexedStack(
|
||||
children: [
|
||||
Navigator(
|
||||
key: Get.nestedKey(killHouseWarehouseAndDistributionBuyKey),
|
||||
onGenerateRoute: (settings) {
|
||||
final page = ChickenPages.pages.firstWhere(
|
||||
(e) => e.name == settings.name,
|
||||
orElse: () => ChickenPages.pages.firstWhere(
|
||||
(e) =>
|
||||
e.name == ChickenRoutes.buyWarehouseAndDistribution,
|
||||
),
|
||||
);
|
||||
|
||||
return buildRouteFromGetPage(page);
|
||||
},
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(killHouseWarehouseAndDistributionSaleKey),
|
||||
onGenerateRoute: (settings) {
|
||||
final page = ChickenPages.pages.firstWhere(
|
||||
(e) => e.name == settings.name,
|
||||
orElse: () => ChickenPages.pages.firstWhere(
|
||||
(e) =>
|
||||
e.name ==
|
||||
ChickenRoutes.saleWarehouseAndDistribution,
|
||||
),
|
||||
);
|
||||
|
||||
return buildRouteFromGetPage(page);
|
||||
},
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(stewardThirdKey),
|
||||
onGenerateRoute: (settings) =>
|
||||
GetPageRoute(page: () => controller.pages[2]),
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(stewardFourthKey),
|
||||
onGenerateRoute: (settings) =>
|
||||
GetPageRoute(page: () => controller.pages[3]),
|
||||
),
|
||||
Navigator(
|
||||
key: Get.nestedKey(stewardFifthKey),
|
||||
onGenerateRoute: (settings) =>
|
||||
GetPageRoute(page: () => controller.pages[4]),
|
||||
),
|
||||
],
|
||||
index: data.value,
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: RBottomNavigation(
|
||||
items: [
|
||||
RBottomNavigationItem(
|
||||
label: 'خرید',
|
||||
icon: Assets.vec.buySvg.path,
|
||||
isSelected: controller.currentPage.value == 0,
|
||||
onTap: () {
|
||||
Get.nestedKey(
|
||||
stewardFirstKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
Get.nestedKey(
|
||||
stewardSecondKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
|
||||
controller.changePage(0);
|
||||
},
|
||||
),
|
||||
RBottomNavigationItem(
|
||||
label: 'فروش',
|
||||
icon: Assets.vec.saleSvg.path,
|
||||
isSelected: controller.currentPage.value == 1,
|
||||
onTap: () {
|
||||
Get.nestedKey(
|
||||
stewardFirstKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
Get.nestedKey(
|
||||
stewardSecondKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
controller.changePage(1);
|
||||
},
|
||||
),
|
||||
RBottomNavigationItem(
|
||||
label: 'خانه',
|
||||
icon: Assets.vec.homeSvg.path,
|
||||
isSelected: controller.currentPage.value == 2,
|
||||
onTap: () {
|
||||
Get.nestedKey(
|
||||
stewardSecondKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
Get.nestedKey(
|
||||
stewardFirstKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
controller.changePage(2);
|
||||
},
|
||||
),
|
||||
RBottomNavigationItem(
|
||||
label: 'قطعه بندی',
|
||||
icon: Assets.vec.convertCubeSvg.path,
|
||||
isSelected: controller.currentPage.value == 3,
|
||||
onTap: () {
|
||||
Get.nestedKey(
|
||||
stewardSecondKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
Get.nestedKey(
|
||||
stewardFirstKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
controller.changePage(3);
|
||||
},
|
||||
),
|
||||
RBottomNavigationItem(
|
||||
label: 'پروفایل',
|
||||
icon: Assets.vec.profileCircleSvg.path,
|
||||
isSelected: controller.currentPage.value == 4,
|
||||
onTap: () {
|
||||
Get.nestedKey(
|
||||
stewardSecondKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
Get.nestedKey(
|
||||
stewardFirstKey,
|
||||
)?.currentState?.popUntil((route) => route.isFirst);
|
||||
|
||||
controller.changePage(4);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}, controller.currentPage);
|
||||
}
|
||||
|
||||
Container _todayShipmentWidget() {
|
||||
return Container(
|
||||
height: 70,
|
||||
width: Get.width / 2,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [const Color(0xFFEAEFFF), Colors.white],
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Assets.icons.cubeScan.svg(width: 30.w, height: 30),
|
||||
Text(
|
||||
'بارهای امروز',
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
'2،225،256',
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
Text(
|
||||
'کیلوگرم',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container _informationLabelCard({
|
||||
required String title,
|
||||
required String description,
|
||||
String unit = 'کیلوگرم',
|
||||
required String iconPath,
|
||||
required Color iconColor,
|
||||
required Color bgDescriptionColor,
|
||||
required Color bgLabelColor,
|
||||
}) {
|
||||
return Container(
|
||||
height: 82,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Row(
|
||||
children: [
|
||||
// Left side with icon and title
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 82,
|
||||
decoration: BoxDecoration(
|
||||
color: bgLabelColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(8),
|
||||
bottomRight: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
SvgGenImage.vec(iconPath).svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn),
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.mediumGreyDarkActive,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// Right side with description and unit
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: bgDescriptionColor,
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(8),
|
||||
bottomLeft: Radius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
description,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: AppColor.mediumGreyDarkActive,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
unit,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: AppColor.mediumGreyDarkActive,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container _informationIconCard({
|
||||
required String title,
|
||||
required String description,
|
||||
String unit = 'کیلوگرم',
|
||||
required String iconPath,
|
||||
required Color iconColor,
|
||||
required Color bgDescriptionColor,
|
||||
required Color bgLabelColor,
|
||||
}) {
|
||||
return Container(
|
||||
height: 110,
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Stack(
|
||||
alignment: Alignment.topCenter,
|
||||
children: [
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
left: 0,
|
||||
child: Container(
|
||||
height: 91,
|
||||
decoration: BoxDecoration(
|
||||
color: bgDescriptionColor,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 0.25, color: const Color(0xFFB4B4B4)),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.mediumGreyDarkActive,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
description,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: AppColor.mediumGreyDarkActive,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
unit,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: AppColor.mediumGreyDarkActive,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
child: Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: ShapeDecoration(
|
||||
color: bgLabelColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
side: BorderSide(width: 0.25, color: const Color(0xFFD5D5D5)),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgGenImage.vec(iconPath).svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget widelyUsed({
|
||||
required String title,
|
||||
required String iconPath,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
padding: EdgeInsets.all(4),
|
||||
decoration: ShapeDecoration(
|
||||
color: const Color(0xFFBECDFF),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueNormal,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: SvgGenImage.vec(iconPath).svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
style: AppFonts.yekan10.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget addWidelyUsed({required VoidCallback onTap}) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
padding: EdgeInsets.all(4),
|
||||
decoration: ShapeDecoration(
|
||||
color: const Color(0xFFD9F7F0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Assets.vec.messageAddSvg.svg(
|
||||
width: 40,
|
||||
height: 40,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.greenNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'افزودن',
|
||||
style: AppFonts.yekan10.copyWith(color: AppColor.greenDarkHover),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/*Column oldPage() {
|
||||
return Column(
|
||||
children: [
|
||||
inventoryWidget(),
|
||||
ObxValue((data) => broadcastInformationWidget(data.value), controller.killHouseDistributionInfo),
|
||||
SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
cardWidget(
|
||||
title: 'ورود به انبار',
|
||||
iconPath: Assets.icons.whareHouse.path,
|
||||
onTap: () {
|
||||
Get.toNamed(ChickenRoutes.enteringTheWarehouse);
|
||||
},
|
||||
),
|
||||
cardWidget(
|
||||
title: 'فروش داخل استان',
|
||||
iconPath: Assets.icons.inside.path,
|
||||
onTap: () {
|
||||
Get.toNamed(ChickenRoutes.salesInProvince);
|
||||
},
|
||||
),
|
||||
cardWidget(
|
||||
title: 'فروش خارج استان',
|
||||
iconPath: Assets.icons.outside.path,
|
||||
onTap: () {
|
||||
Get.toNamed(ChickenRoutes.salesOutOfProvince);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget inventoryWidget() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text('موجودی انبار', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
ObxValue(
|
||||
(data) =>
|
||||
data.isEmpty
|
||||
? Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 2),
|
||||
height: 80,
|
||||
padding: EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.blueNormal, width: 1),
|
||||
),
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
)
|
||||
: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemCount: controller.inventoryList.length,
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 8),
|
||||
itemBuilder: (context, index) {
|
||||
return ObxValue((expand) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
controller.toggleExpanded(index);
|
||||
},
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: AnimatedContainer(
|
||||
onEnd: () {
|
||||
controller.inventoryExpandedList[index] = !controller.inventoryExpandedList[index]!;
|
||||
},
|
||||
margin: const EdgeInsets.symmetric(vertical: 2),
|
||||
padding: EdgeInsets.all(6),
|
||||
curve: Curves.easeInOut,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.blueNormal, width: 1),
|
||||
),
|
||||
duration: const Duration(seconds: 1),
|
||||
height: expand.keys.contains(index) ? 250 : 80,
|
||||
child: inventoryItem(
|
||||
isExpanded: expand.keys.contains(index) && expand[index]!,
|
||||
index: index,
|
||||
model: controller.inventoryList[index],
|
||||
),
|
||||
),
|
||||
);
|
||||
}, controller.inventoryExpandedList);
|
||||
},
|
||||
),
|
||||
controller.inventoryList,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget inventoryItem({required bool isExpanded, required int index, required InventoryModel model}) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 8,
|
||||
children: [
|
||||
buildRow('نام محصول', model.name ?? ''),
|
||||
Visibility(
|
||||
visible: isExpanded,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
buildRow('وزن خریدهای دولتی داخل استان (کیلوگرم)', '0326598653'),
|
||||
buildRow('وزن خریدهای آزاد داخل استان (کیلوگرم)', model.receiveFreeCarcassesWeight.toString()),
|
||||
buildRow('وزن خریدهای خارج استان (کیلوگرم)', model.freeBuyingCarcassesWeight.toString()),
|
||||
buildRow('کل ورودی به انبار (کیلوگرم)', model.totalFreeBarsCarcassesWeight.toString()),
|
||||
buildRow('کل فروش (کیلوگرم)', model.realAllocatedWeight.toString()),
|
||||
buildRow('مانده انبار (کیلوگرم)', model.totalRemainWeight.toString()),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}*/
|
||||
|
||||
Widget buildRow(String title, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.darkGreyDarkHover,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Text(
|
||||
value,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.darkGreyDarkHover,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget broadcastInformationWidget(KillHouseDistributionInfo? model) {
|
||||
return Container(
|
||||
height: 140,
|
||||
margin: const EdgeInsets.all(8),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.blueNormal, width: 1),
|
||||
),
|
||||
child: model != null
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 10,
|
||||
children: [
|
||||
Text(
|
||||
'اطلاعات ارسالی',
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16Bold.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
buildRow(
|
||||
'فروش و توزیع داخل استان (کیلوگرم)',
|
||||
model.stewardAllocationsWeight!.toInt().toString(),
|
||||
),
|
||||
buildRow(
|
||||
'فروش و توزیع خارج استان (کیلوگرم)',
|
||||
model.freeSalesWeight!.toInt().toString(),
|
||||
),
|
||||
],
|
||||
)
|
||||
: const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
|
||||
Widget cardWidget({
|
||||
required String title,
|
||||
required String iconPath,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return Container(
|
||||
width: Get.width / 4,
|
||||
height: 130,
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Card(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(width: 1, color: AppColor.blueNormal),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SvgGenImage(iconPath).svg(width: 50, height: 50),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionSaleLogic extends GetxController {
|
||||
Rxn<List<AllocatedMadeModel>?> allocatedMadeModel = Rxn<List<AllocatedMadeModel>?>();
|
||||
|
||||
RxList<GuildModel> guildsModel = <GuildModel>[].obs;
|
||||
|
||||
Rxn<StewardFreeBarDashboard> stewardFreeDashboard = Rxn<StewardFreeBarDashboard>();
|
||||
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
List<String> routesName = ['فروش'];
|
||||
DateTime? _lastBackPressed;
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
getStewardDashBord();
|
||||
|
||||
}
|
||||
|
||||
Future<void> getAllocatedMade() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getAllocatedMade(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(page: 1, pageSize: 20, search: 'filter', role: 'Steward'),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
allocatedMadeModel.value = result.results;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
void checkVerfication() {}
|
||||
|
||||
void confirmAllocation(ConformAllocation allocation) {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.confirmAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
allocation: allocation.toJson(),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
getAllocatedMade();
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
void denyAllocation(String token) {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.denyAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
allocationToken: token,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
getAllocatedMade();
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> confirmAllAllocations() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.confirmAllAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
allocationTokens: allocatedMadeModel.value?.map((e) => e.key!).toList() ?? [],
|
||||
),
|
||||
onSuccess: (result) {
|
||||
getAllocatedMade();
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Future<void> getGuilds() async {}
|
||||
|
||||
Future<void> addSale() async {}
|
||||
|
||||
void setSelectedGuild(GuildModel value) {}
|
||||
|
||||
void setSelectedProduct(ProductModel value) {}
|
||||
|
||||
Future<void> getStewardDashBord() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getStewardDashboard(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
stratDate: DateTime.now().formattedDashedGregorian,
|
||||
endDate: DateTime.now().formattedDashedGregorian,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
stewardFreeDashboard.value = result;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> submitAllocation() async {}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
rootLogic.inventoryExpandedList.clear();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
void onPopScopTaped() async {
|
||||
|
||||
final now = DateTime.now();
|
||||
if (_lastBackPressed == null || now.difference(_lastBackPressed!) > Duration(seconds: 2)) {
|
||||
_lastBackPressed = now;
|
||||
Get.snackbar(
|
||||
'خروج از برنامه',
|
||||
'برای خروج دوباره بازگشت را بزنید',
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: Duration(seconds: 2),
|
||||
backgroundColor: AppColor.warning,
|
||||
);
|
||||
} else {
|
||||
await SystemNavigator.pop();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/chicken.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionSalePage extends GetView<WarehouseAndDistributionSaleLogic> {
|
||||
WarehouseAndDistributionSalePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChickenBasePage(
|
||||
routes: controller.routesName,
|
||||
isBase: true,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 21,
|
||||
children: [
|
||||
GlassMorphismCardIcon(
|
||||
title: 'فروش داخل استان',
|
||||
vecIcon: Assets.vec.map2Svg.path,
|
||||
onTap: () {
|
||||
Get.toNamed(ChickenRoutes.salesInProvinceSteward, id: stewardSecondKey);
|
||||
},
|
||||
),
|
||||
GlassMorphismCardIcon(
|
||||
title: 'فروش خارج استان',
|
||||
vecIcon: Assets.vec.saleOutProvinceSvg.path,
|
||||
onTap: () {
|
||||
Get.toNamed(ChickenRoutes.salesOutOfProvinceSteward, id: stewardSecondKey);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget addSaleOutOfTheProvinceBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'ثبت فروش خارج استان',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
RElevated(text: 'ثبت توزیع/ فروش', onPressed: () {}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _typeOuterInfoCard({
|
||||
required String title,
|
||||
required String iconPath,
|
||||
required Color foregroundColor,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
height: 180,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 1, color: foregroundColor),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Positioned(
|
||||
top: -41,
|
||||
child: SvgGenImage.vec(iconPath).svg(
|
||||
width: 45,
|
||||
height: 45,
|
||||
colorFilter: ColorFilter.mode(foregroundColor, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
|
||||
Assets.vec.shoppingBasketSvg.svg(
|
||||
width: 55,
|
||||
height: 60,
|
||||
colorFilter: ColorFilter.mode(foregroundColor, BlendMode.srcIn),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16Bold.copyWith(color: foregroundColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget summaryOfInformation(StewardFreeBarDashboard? model) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'خلاصه اطلاعات',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 140,
|
||||
margin: const EdgeInsets.all(8),
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.blueNormal, width: 1),
|
||||
),
|
||||
child: model == null
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 10,
|
||||
children: [
|
||||
const SizedBox(height: 12),
|
||||
buildRow('تعداد کل بارها', model.totalQuantity?.toString() ?? '0'),
|
||||
buildRow('تعداد کل', model.totalBars?.toString() ?? '0'),
|
||||
buildRow('وزن کل (کیلوگرم)', model.totalWeight?.toString() ?? '0'),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildRow(String title, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
value,
|
||||
textAlign: TextAlign.left,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,505 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sale/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionSalesInProvinceLogic extends GetxController {
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
WarehouseAndDistributionSaleLogic saleLogic = Get.find<WarehouseAndDistributionSaleLogic>();
|
||||
RxnString searchedValue = RxnString();
|
||||
RxInt expandedListIndex = (-1).obs;
|
||||
RxList<String> routesName = RxList();
|
||||
Rx<Color> bgConfirmAllColor = AppColor.blueNormal.obs;
|
||||
final RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
Timer? _flashingTimer;
|
||||
|
||||
Rx<Resource<PaginationModel<AllocatedMadeModel>>> allocatedList =
|
||||
Resource<PaginationModel<AllocatedMadeModel>>.loading().obs;
|
||||
|
||||
RxList<ProductModel> rolesProductsModel = RxList<ProductModel>();
|
||||
|
||||
RxList<GuildModel> guildsModel = <GuildModel>[].obs;
|
||||
|
||||
GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
Rxn<ProductModel> selectedProductModel = Rxn<ProductModel>();
|
||||
Rxn<GuildModel> selectedGuildModel = Rxn<GuildModel>();
|
||||
Rxn<GuildProfile> guildProfile = Rxn<GuildProfile>();
|
||||
RxInt saleType = 1.obs;
|
||||
RxInt priceType = 2.obs;
|
||||
RxInt quotaType = 1.obs;
|
||||
RxInt weight = 0.obs;
|
||||
RxInt pricePerKilo = 0.obs;
|
||||
RxInt totalCost = 0.obs;
|
||||
RxBool isValid = false.obs;
|
||||
final weightController = TextEditingController();
|
||||
final pricePerKiloController = TextEditingController();
|
||||
final totalCostController = TextEditingController();
|
||||
|
||||
final ScrollController scrollControllerAllocationsMade = ScrollController();
|
||||
final RxInt currentPage = 1.obs;
|
||||
final RxBool addPageAllocationsMade = false.obs;
|
||||
final RxBool hasMoreDataAllocationsMade = true.obs;
|
||||
|
||||
Rxn<BroadcastPrice> broadcastPrice = Rxn<BroadcastPrice>();
|
||||
Rxn<AllocatedMadeModel> selectedAllocationModelForUpdate = Rxn<AllocatedMadeModel>();
|
||||
SubmitStewardAllocation? tmpStewardAllocation;
|
||||
|
||||
Rxn<Jalali> productionDate = Rxn(null);
|
||||
Rxn<int> remainingStock = Rxn(null);
|
||||
Map<String, DayData> freeProductionDateData = {};
|
||||
Map<String, DayData> governmentalProductionDateData = {};
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
routesName.value = [...saleLogic.routesName, 'داخل استان'].toList();
|
||||
getAllocatedMade();
|
||||
getRolesProducts();
|
||||
getGuilds();
|
||||
getGuildProfile();
|
||||
getBroadcastPrice();
|
||||
ever(saleType, (callback) {
|
||||
getGuilds();
|
||||
});
|
||||
|
||||
ever(quotaType, (_) {
|
||||
remainingStock.value = null;
|
||||
productionDate.value = null;
|
||||
});
|
||||
|
||||
debounce(weight, time: Duration(milliseconds: 110), (callback) {
|
||||
totalCost.value = callback * pricePerKilo.value;
|
||||
});
|
||||
|
||||
debounce(pricePerKilo, time: Duration(milliseconds: 100), (callback) {
|
||||
totalCost.value = callback * weight.value;
|
||||
});
|
||||
|
||||
totalCost.listen((data) {
|
||||
totalCostController.text = data.toString().separatedByComma;
|
||||
|
||||
isValid.value =
|
||||
weight.value > 0 &&
|
||||
pricePerKilo.value > 0 &&
|
||||
totalCost.value > 0 &&
|
||||
selectedProductModel.value != null &&
|
||||
selectedGuildModel.value != null;
|
||||
});
|
||||
everAll([
|
||||
totalCost,
|
||||
weight,
|
||||
pricePerKilo,
|
||||
totalCost,
|
||||
selectedProductModel,
|
||||
selectedGuildModel,
|
||||
productionDate,
|
||||
], (callback) => checkVerification());
|
||||
|
||||
scrollControllerAllocationsMade.addListener(() {
|
||||
if (scrollControllerAllocationsMade.position.pixels >=
|
||||
scrollControllerAllocationsMade.position.maxScrollExtent - 100) {
|
||||
addPageAllocationsMade.value = true;
|
||||
getAllocatedMade();
|
||||
}
|
||||
});
|
||||
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getAllocatedMade(),
|
||||
time: Duration(milliseconds: timeDebounce),
|
||||
);
|
||||
|
||||
_updateGovernmentalProductionDateData();
|
||||
_updateFreeProductionDateData();
|
||||
ever(rootLogic.stewardRemainWeight, (callback) {
|
||||
_updateGovernmentalProductionDateData();
|
||||
_updateFreeProductionDateData();
|
||||
});
|
||||
}
|
||||
|
||||
void _updateGovernmentalProductionDateData() {
|
||||
List<RemainWeightDay> dates = rootLogic.stewardRemainWeight.value?.governmental ?? [];
|
||||
governmentalProductionDateData = {
|
||||
for (var element in dates)
|
||||
element.day.toString().toJalali.formatCompactDate(): DayData(
|
||||
value: element.amount?.toInt(),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
void _updateFreeProductionDateData() {
|
||||
var dates = rootLogic.stewardRemainWeight.value?.free ?? [];
|
||||
freeProductionDateData = {
|
||||
for (var element in dates)
|
||||
element.day.toString().toJalali.formatCompactDate(): DayData(
|
||||
value: element.amount?.toInt(),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> getAllocatedMade([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
allocatedList.value = Resource<PaginationModel<AllocatedMadeModel>>.loading();
|
||||
}
|
||||
|
||||
if (searchedValue.value != null &&
|
||||
searchedValue.value!.trim().isNotEmpty &&
|
||||
currentPage.value > 1) {
|
||||
currentPage.value = 1; // Reset to first page if search value is set
|
||||
}
|
||||
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getAllocatedMade(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
page: currentPage.value,
|
||||
pageSize: 20,
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value,
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) async {
|
||||
await Future.delayed(Duration(milliseconds: 200));
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
allocatedList.value = Resource<PaginationModel<AllocatedMadeModel>>.empty();
|
||||
} else {
|
||||
allocatedList.value = Resource<PaginationModel<AllocatedMadeModel>>.success(
|
||||
PaginationModel<AllocatedMadeModel>(
|
||||
count: res?.count ?? 0,
|
||||
next: res?.next,
|
||||
previous: res?.previous,
|
||||
results: isLoadingMore
|
||||
? [...(allocatedList.value.data?.results ?? []), ...(res?.results ?? [])]
|
||||
: res?.results ?? [],
|
||||
),
|
||||
);
|
||||
isLoadingMoreAllocationsMade.value = false;
|
||||
if ((allocatedList.value.data?.results?.length ?? 0) > 1) {
|
||||
flashingFabBgColor();
|
||||
}
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {
|
||||
isLoadingMoreAllocationsMade.value = false;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void checkVerification() {
|
||||
var hasWeight = quotaType.value == 1
|
||||
? weight.value <=
|
||||
(governmentalProductionDateData[productionDate.value?.formatCompactDate()]?.value ??
|
||||
0)
|
||||
: weight.value <=
|
||||
(freeProductionDateData[productionDate.value?.formatCompactDate()]?.value ?? 0);
|
||||
|
||||
isValid.value =
|
||||
weight.value > 0 &&
|
||||
pricePerKilo.value > 0 &&
|
||||
totalCost.value > 0 &&
|
||||
hasWeight &&
|
||||
selectedProductModel.value != null &&
|
||||
selectedGuildModel.value != null;
|
||||
}
|
||||
|
||||
void confirmAllocation(ConformAllocation allocation) {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.confirmAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
allocation: allocation.toJson(),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
getAllocatedMade();
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
void denyAllocation(String token) {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.denyAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
allocationToken: token,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
getAllocatedMade();
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> confirmAllAllocations() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.confirmAllAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
allocationTokens: allocatedList.value.data?.results?.map((e) => e.key!).toList() ?? [],
|
||||
),
|
||||
onSuccess: (result) {
|
||||
getAllocatedMade();
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getRolesProducts() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getRolesProducts(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
rolesProductsModel.value = result;
|
||||
selectedProductModel.value = result.first;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getGuilds() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getGuilds(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
//queryParams: {'free': saleType.value == 2 ? true : false},
|
||||
queryParams: {'all': true},
|
||||
role: 'Steward',
|
||||
),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
guildsModel.clear();
|
||||
guildsModel.addAll(result);
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> addSale() async {}
|
||||
|
||||
void setSelectedGuild(GuildModel value) {
|
||||
selectedGuildModel.value = value;
|
||||
update();
|
||||
}
|
||||
|
||||
void setSelectedProduct(ProductModel value) {
|
||||
selectedProductModel.value = value;
|
||||
update();
|
||||
}
|
||||
|
||||
Future<void> getGuildProfile() async {
|
||||
await safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getProfile(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
),
|
||||
onError: (error, stackTrace) {},
|
||||
onSuccess: (result) {
|
||||
guildProfile.value = result;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void setSubmitData() {
|
||||
tmpStewardAllocation = SubmitStewardAllocation(
|
||||
approvedPriceStatus: priceType.value == 1,
|
||||
allocationType:
|
||||
'${guildProfile.value?.steward == true ? "steward" : "guild"}_${selectedGuildModel.value?.steward == true ? "steward" : "guild"}',
|
||||
sellerType: guildProfile.value?.steward == true ? "Steward" : "Guild",
|
||||
buyerType: selectedGuildModel.value?.steward == true ? "Steward" : "Guild",
|
||||
amount: pricePerKilo.value,
|
||||
totalAmount: totalCost.value,
|
||||
weightOfCarcasses: weight.value,
|
||||
sellType: saleType.value == 2 ? "free" : 'exclusive',
|
||||
numberOfCarcasses: 0,
|
||||
productionDate: productionDate.value?.toDateTime().formattedDashedGregorian,
|
||||
quota: quotaType.value == 1 ? 'governmental' : 'free',
|
||||
guildKey: selectedGuildModel.value?.key,
|
||||
productKey: selectedProductModel.value?.key,
|
||||
date: DateTime.now().formattedDashedGregorian,
|
||||
type: "manual",
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> submitAllocation() async {
|
||||
setSubmitData();
|
||||
|
||||
safeCall(
|
||||
showError: true,
|
||||
call: () async => await rootLogic.chickenRepository.postSubmitStewardAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
request: tmpStewardAllocation!,
|
||||
),
|
||||
|
||||
onSuccess: (result) {
|
||||
clearForm();
|
||||
onRefresh();
|
||||
rootLogic.onRefresh();
|
||||
Future.delayed(Duration(seconds: 1), () => defaultShowSuccessMessage("ثبت موفق بود"));
|
||||
Get.back();
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> deleteAllocation(AllocatedMadeModel model) async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.deleteStewardAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: {'steward_allocation_key': model.key},
|
||||
),
|
||||
|
||||
onSuccess: (result) {
|
||||
getAllocatedMade();
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
rootLogic.inventoryExpandedList.clear();
|
||||
stopFlashing();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void setEditData(AllocatedMadeModel item) {
|
||||
selectedAllocationModelForUpdate.value = item;
|
||||
selectedProductModel.value = rolesProductsModel.first;
|
||||
selectedGuildModel.value = GuildModel(guildsName: 'tst');
|
||||
weight.value = item.weightOfCarcasses ?? 0;
|
||||
pricePerKilo.value = item.amount ?? 0;
|
||||
totalCost.value = item.totalAmount ?? 0;
|
||||
weightController.text = weight.value.toString().separatedByComma;
|
||||
pricePerKiloController.text = pricePerKilo.value.toString().separatedByComma;
|
||||
totalCostController.text = totalCost.value.toString().separatedByComma;
|
||||
isValid.value = true;
|
||||
productionDate.value = item.productionDate.toJalali;
|
||||
}
|
||||
|
||||
void clearForm() {
|
||||
selectedGuildModel.value = null;
|
||||
weight.value = 0;
|
||||
totalCost.value = 0;
|
||||
weightController.clear();
|
||||
if (broadcastPrice.value?.active == false) {
|
||||
pricePerKilo.value = 0;
|
||||
pricePerKiloController.clear();
|
||||
}
|
||||
totalCostController.clear();
|
||||
isValid.value = false;
|
||||
productionDate.value = null;
|
||||
quotaType.value = 1;
|
||||
priceType.value = 2;
|
||||
saleType.value = 2;
|
||||
}
|
||||
|
||||
Future<void> updateAllocation() async {
|
||||
ConformAllocation updatedAllocationModel = ConformAllocation(
|
||||
allocation_key: selectedAllocationModelForUpdate.value?.key,
|
||||
amount: pricePerKilo.value,
|
||||
total_amount: totalCost.value,
|
||||
number_of_carcasses: 0,
|
||||
weight_of_carcasses: weight.value,
|
||||
);
|
||||
|
||||
safeCall(
|
||||
showError: true,
|
||||
call: () async => await rootLogic.chickenRepository.updateStewardAllocation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
request: updatedAllocationModel,
|
||||
),
|
||||
|
||||
onSuccess: (result) {
|
||||
clearForm();
|
||||
onRefresh();
|
||||
rootLogic.onRefresh();
|
||||
Future.delayed(Duration(seconds: 1), () => defaultShowSuccessMessage("ویرایش موفق بود"));
|
||||
Get.back();
|
||||
},
|
||||
onError: (error, stackTrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
void setSearchValue(String? data) {
|
||||
searchedValue.value = data?.trim();
|
||||
}
|
||||
|
||||
void flashingFabBgColor() {
|
||||
_flashingTimer?.cancel();
|
||||
|
||||
_flashingTimer = Timer.periodic(Duration(seconds: 2), (timer) {
|
||||
if (bgConfirmAllColor.value == AppColor.blueNormal) {
|
||||
bgConfirmAllColor.value = AppColor.blueLightHover;
|
||||
} else {
|
||||
bgConfirmAllColor.value = AppColor.blueNormal;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void stopFlashing() {
|
||||
_flashingTimer?.cancel();
|
||||
_flashingTimer = null;
|
||||
bgConfirmAllColor.value = AppColor.blueNormal; // بازگرداندن به رنگ پیشفرض
|
||||
}
|
||||
|
||||
Steward? getBuyerInformation(AllocatedMadeModel model) {
|
||||
if (model.allocationType?.buyerIsGuild ?? false) {
|
||||
return model.toGuilds;
|
||||
} else {
|
||||
return model.steward;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getBroadcastPrice() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getBroadcastPrice(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
broadcastPrice.value = result;
|
||||
if (broadcastPrice.value?.active == true) {
|
||||
pricePerKilo.value = broadcastPrice.value?.stewardPrice ?? 0;
|
||||
pricePerKiloController.text = pricePerKilo.value.toString().separatedByComma;
|
||||
priceType.value = 2;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
toggleExpansion();
|
||||
currentPage.value = 1;
|
||||
hasMoreDataAllocationsMade.value = true;
|
||||
await Future.wait([getAllocatedMade(), getRolesProducts(), rootLogic.onRefresh()]);
|
||||
}
|
||||
|
||||
void toggleExpansion({int? index}) {
|
||||
if (expandedListIndex.value == index || index == null) {
|
||||
expandedListIndex.value = -1;
|
||||
} else {
|
||||
expandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,543 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sales_in_province/widgets/cu_sale_in_provience.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart';
|
||||
import 'package:rasadyar_core/core.dart' hide modalDatePicker;
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionSalesInProvincePage
|
||||
extends GetView<WarehouseAndDistributionSalesInProvinceLogic> {
|
||||
const WarehouseAndDistributionSalesInProvincePage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChickenBasePage(
|
||||
routes: controller.routesName,
|
||||
backId: stewardSecondKey,
|
||||
onSearchChanged: (data) => controller.setSearchValue(data),
|
||||
onRefresh: controller.onRefresh,
|
||||
onFilterTap: () {
|
||||
Get.bottomSheet(filterBottomSheet());
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Column(
|
||||
children: [
|
||||
// inventoryWidget(controller.rootLogic),
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
listType: ListType.separated,
|
||||
resource: data.value,
|
||||
hasMore: data.value.data?.next != null,
|
||||
isPaginating:
|
||||
controller.isLoadingMoreAllocationsMade.value,
|
||||
onLoadMore: () async {
|
||||
controller.currentPage.value++;
|
||||
await controller.getAllocatedMade(true);
|
||||
},
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
|
||||
itemBuilder: (context, index) {
|
||||
var item = data.value.data!.results![index];
|
||||
return ObxValue((val) {
|
||||
return ExpandableListItem2(
|
||||
selected: val.value == index,
|
||||
onTap: () =>
|
||||
controller.toggleExpansion(index: index),
|
||||
index: index,
|
||||
child: itemListWidget(item),
|
||||
secondChild: itemListExpandedWidget(item, index),
|
||||
labelColor: AppColor.blueLight,
|
||||
labelIcon: Assets.vec.timerSvg.path,
|
||||
labelIconColor: item.registrationCode == null
|
||||
? AppColor.darkGreyDark
|
||||
: AppColor.error,
|
||||
);
|
||||
}, controller.expandedListIndex);
|
||||
},
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) =>
|
||||
SizedBox(height: 8.h),
|
||||
);
|
||||
}, controller.allocatedList),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: 5,
|
||||
bottom: 95,
|
||||
child: SizedBox(
|
||||
width: Get.width - 30,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
RFab.add(
|
||||
onPressed: () {
|
||||
/* Get.bottomSheet(
|
||||
addOrEditBottomSheet(controller),
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
).whenComplete(() {
|
||||
controller.clearForm();
|
||||
}); */
|
||||
},
|
||||
),
|
||||
|
||||
ObxValue((data) {
|
||||
return Visibility(
|
||||
visible: (data.value.data?.results?.length ?? 0) > 1,
|
||||
child: AnimatedFab(
|
||||
onPressed: () async {
|
||||
Get.defaultDialog(
|
||||
title: 'تایید یکجا',
|
||||
middleText:
|
||||
'آیا از تایید تمامی تخصیص ها اطمینان دارید؟',
|
||||
confirm: ElevatedButton(
|
||||
onPressed: () async {
|
||||
await controller.confirmAllAllocations();
|
||||
controller.getAllocatedMade();
|
||||
controller.rootLogic.getKillHouseSalesInfoDashboard();
|
||||
Get.back();
|
||||
},
|
||||
child: Text('تایید'),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColor.blueNormal,
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
cancel: OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: AppColor.error,
|
||||
enableFeedback: true,
|
||||
side: BorderSide(
|
||||
color: AppColor.error,
|
||||
width: 1,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: Text('لغو'),
|
||||
),
|
||||
);
|
||||
},
|
||||
message: 'تایید یکجا',
|
||||
icon: Assets.vec.clipboardTaskSvg.svg(
|
||||
width: 40.w,
|
||||
height: 40.h,
|
||||
),
|
||||
backgroundColor: controller.bgConfirmAllColor.value,
|
||||
),
|
||||
);
|
||||
}, controller.allocatedList),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Row itemListWidget(AllocatedMadeModel item) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
controller.getBuyerInformation(item)?.user?.fullname ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
item.createDate?.formattedJalaliDate ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
spacing: 6,
|
||||
children: [
|
||||
Visibility(
|
||||
visible: item.product?.name?.contains('مرغ گرم') ?? false,
|
||||
child: Assets.vec.hotChickenSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.blueNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
item.weightOfCarcasses!.separatedByCommaFa.addKg,
|
||||
textAlign: TextAlign.left,
|
||||
textDirection: TextDirection.ltr,
|
||||
style: AppFonts.yekan12Bold.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
item.amount.separatedByCommaFa.addReal,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(width: 8),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
spacing: 3,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
item.approvedPriceStatus == true
|
||||
? 'دولتی'
|
||||
: item.approvedPriceStatus == false
|
||||
? 'آزاد'
|
||||
: '-',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: item.approvedPriceStatus == true
|
||||
? AppColor.blueNormal
|
||||
: AppColor.greenNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(width: 8),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container itemListExpandedWidget(AllocatedMadeModel item, int index) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
controller.getBuyerInformation(item)?.user?.fullname ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
|
||||
),
|
||||
Spacer(),
|
||||
Text(
|
||||
item.registrationCode == null
|
||||
? 'در انتظار'
|
||||
: 'در انتظار تایید خریدار',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan10.copyWith(
|
||||
color: item.registrationCode == null
|
||||
? AppColor.darkGreyDark
|
||||
: AppColor.error,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 7),
|
||||
Assets.vec.clockSvg.svg(
|
||||
width: 16.w,
|
||||
height: 16.h,
|
||||
colorFilter: ColorFilter.mode(
|
||||
item.registrationCode == null
|
||||
? AppColor.darkGreyDark
|
||||
: AppColor.error,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: AppColor.blueLightHover),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
item.date?.toJalali.formatter.wN ?? 'ندارد',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.textColor,
|
||||
),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.y}',
|
||||
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
buildRow(
|
||||
title: 'تلفن خریدار',
|
||||
value:
|
||||
controller.getBuyerInformation(item)?.user?.mobile ?? 'ندارد',
|
||||
valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
buildRow(title: 'محصول', value: item.product?.name ?? 'ندارد'),
|
||||
|
||||
buildRow(
|
||||
title: 'تاریخ تولید گوشت',
|
||||
value: item.productionDate?.toJalali.formatCompactDate() ?? 'ندارد',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'نوع تخصیص',
|
||||
value: item.allocationType?.faAllocationType ?? 'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'نوع فروش',
|
||||
value: (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'نوع انبار',
|
||||
value: (item.quota == 'governmental') ? 'دولتی' : 'آزاد',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'وزن خریداری شده',
|
||||
value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم',
|
||||
),
|
||||
buildRow(
|
||||
title: 'افت وزن(کیلوگرم)',
|
||||
value: item.weightLossOfCarcasses?.toInt().toString() ?? 'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت هر کیلوگرم',
|
||||
titleLabel: (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد',
|
||||
titleLabelStyle: AppFonts.yekan14Bold.copyWith(
|
||||
color: (item.approvedPriceStatus ?? false)
|
||||
? AppColor.blueNormal
|
||||
: AppColor.greenNormal,
|
||||
),
|
||||
value: '${item.amount?.separatedByCommaFa} ریال',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت کل',
|
||||
value: '${item.totalAmount?.separatedByCommaFa} ریال',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'کداحراز',
|
||||
value: item.registrationCode?.toString() ?? 'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'وضعیت کد احراز',
|
||||
value: item.systemRegistrationCode == true
|
||||
? "ارسال شده"
|
||||
: "ارسال نشده",
|
||||
),
|
||||
|
||||
Visibility(
|
||||
visible: item.registrationCode == null,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16.w,
|
||||
children: [
|
||||
RElevated(
|
||||
text: 'ویرایش',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
controller.setEditData(item);
|
||||
/* Get.bottomSheet(
|
||||
addOrEditBottomSheet(controller, isEditMode: true),
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
).whenComplete(() {
|
||||
controller.clearForm();
|
||||
}); */
|
||||
},
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
),
|
||||
ROutlinedElevated(
|
||||
text: 'حذف',
|
||||
textStyle: AppFonts.yekan20.copyWith(
|
||||
color: AppColor.redNormal,
|
||||
),
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
buildDeleteDialog(
|
||||
onConfirm: () async {
|
||||
controller.toggleExpansion(index: index);
|
||||
|
||||
await controller.deleteAllocation(item);
|
||||
},
|
||||
onRefresh: controller.onRefresh,
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.redNormal,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget filterBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 200,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
'فیلترها',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
controller: controller,
|
||||
date: controller.fromDateFilter,
|
||||
onChanged: (jalali) =>
|
||||
controller.fromDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
controller: controller,
|
||||
isFrom: false,
|
||||
date: controller.toDateFilter,
|
||||
onChanged: (jalali) => controller.toDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
RElevated(
|
||||
text: 'اعمال فیلتر',
|
||||
isFullWidth: true,
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
onPressed: () {
|
||||
controller.getAllocatedMade();
|
||||
Get.back();
|
||||
},
|
||||
height: 40,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
GestureDetector timeFilterWidget({
|
||||
required WarehouseAndDistributionSalesInProvinceLogic controller,
|
||||
isFrom = true,
|
||||
required Rx<Jalali> date,
|
||||
required Function(Jalali jalali) onChanged,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.bottomSheet(modalDatePicker((value) => onChanged(value)));
|
||||
},
|
||||
child: Container(
|
||||
height: 35,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 1, color: AppColor.blueNormal),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 11, vertical: 4),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Assets.vec.calendarSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: const ColorFilter.mode(
|
||||
AppColor.blueNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
isFrom ? 'از' : 'تا',
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return Text(
|
||||
date.value.formatCompactDate(),
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: AppColor.lightGreyNormalActive,
|
||||
),
|
||||
);
|
||||
}, date),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,515 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sales_in_province/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
Widget addOrEditBottomSheet(WarehouseAndDistributionSalesInProvinceLogic controller, {bool isEditMode = false}) {
|
||||
return BaseBottomSheet(
|
||||
height: Get.height * (isEditMode ? 0.60 : 0.75),
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'${isEditMode ? 'ویرایش' : 'ثبت'} توزیع/ فروش',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
productDropDown(controller),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
ObxValue((data) {
|
||||
return RTextField(
|
||||
controller: TextEditingController(),
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
label: 'تاریخ',
|
||||
onTap: () {
|
||||
Get.bottomSheet(
|
||||
modalDatePicker((value) {
|
||||
controller.fromDateFilter.value = value;
|
||||
controller.fromDateFilter.refresh();
|
||||
}),
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
initText: (data.value).formatCompactDate(),
|
||||
);
|
||||
}, controller.fromDateFilter),
|
||||
Visibility(
|
||||
visible: isEditMode == false,
|
||||
child: Container(
|
||||
height: 50.h,
|
||||
clipBehavior: Clip.none,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
alignment: Alignment.center,
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Positioned(
|
||||
child: Container(color: Colors.white, child: Text("انبار")),
|
||||
top: -10,
|
||||
right: 8,
|
||||
),
|
||||
Obx(() {
|
||||
return RadioGroup(
|
||||
groupValue: controller.quotaType.value,
|
||||
onChanged: (value) {
|
||||
controller.quotaType.value = value ?? 0;
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.quotaType.value = 1;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: 1),
|
||||
Text('دولتی', style: AppFonts.yekan14),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.quotaType.value = 2;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: 2),
|
||||
Text('آزاد', style: AppFonts.yekan14),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Obx(() {
|
||||
return MonthlyDataCalendar(
|
||||
label: 'تاریخ تولید گوشت',
|
||||
selectedDate: controller.productionDate.value?.formatCompactDate(),
|
||||
onDateSelect: (value) {
|
||||
controller.productionDate.value = value.date;
|
||||
controller.remainingStock.value = value.remainingStock;
|
||||
},
|
||||
dayData: controller.quotaType.value == 1
|
||||
? controller.governmentalProductionDateData
|
||||
: controller.freeProductionDateData,
|
||||
);
|
||||
}),
|
||||
|
||||
Visibility(visible: isEditMode == false, child: guildsDropDown(controller)),
|
||||
|
||||
RTextField(
|
||||
controller: controller.weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
autoValidateMode: AutovalidateMode.onUserInteraction,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
validator: (value) {
|
||||
if ((int.tryParse(value?.clearComma ?? '0') ?? 0) >
|
||||
(controller.remainingStock.value ?? 0)) {
|
||||
return 'وزن تخصیصی بیشتر از موجودی انبار است';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onChanged: (p0) {
|
||||
controller.weight.value = int.tryParse(p0.clearComma) ?? 0;
|
||||
},
|
||||
label: 'وزن لاشه (کیلوگرم)',
|
||||
),
|
||||
|
||||
Visibility(
|
||||
visible: isEditMode == false,
|
||||
child: Container(
|
||||
height: 58.h,
|
||||
clipBehavior: Clip.none,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
alignment: Alignment.center,
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Positioned(
|
||||
child: Container(color: Colors.white, child: Text("فروش")),
|
||||
top: -10,
|
||||
right: 8,
|
||||
),
|
||||
Obx(() {
|
||||
return RadioGroup(
|
||||
groupValue: controller.priceType.value,
|
||||
onChanged: (value) {
|
||||
controller.priceType.value = value!;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: (controller.broadcastPrice.value?.active ?? false)
|
||||
? () {
|
||||
controller.priceType.value = 1;
|
||||
}
|
||||
: null,
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(
|
||||
value: 1,
|
||||
enabled: controller.broadcastPrice.value?.active ?? false,
|
||||
),
|
||||
Text(
|
||||
'قیمت مصوب',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color:
|
||||
(controller.broadcastPrice.value?.active ?? false)
|
||||
? AppColor.textColor
|
||||
: AppColor.labelTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.priceType.value = 2;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: 2),
|
||||
Text('قیمت آزاد', style: AppFonts.yekan14),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
ObxValue((data) {
|
||||
return RTextField(
|
||||
variant: RTextFieldVariant.noBorder,
|
||||
controller: controller.pricePerKiloController,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
readonly: data.value == 1,
|
||||
onChanged: (p0) {
|
||||
controller.pricePerKilo.value = int.tryParse(p0.clearComma) ?? 0;
|
||||
},
|
||||
keyboardType: TextInputType.number,
|
||||
label: 'قیمت هر کیلو (ريال)',
|
||||
);
|
||||
}, controller.priceType),
|
||||
|
||||
RTextField(
|
||||
variant: RTextFieldVariant.noBorder,
|
||||
enabled: false,
|
||||
keyboardType: TextInputType.number,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
controller: controller.totalCostController,
|
||||
label: 'هزینه کل (ريال)',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 12.h),
|
||||
ObxValue((data) {
|
||||
return RElevated(
|
||||
text: isEditMode ? 'ویرایش' : 'ثبت',
|
||||
isFullWidth: true,
|
||||
textStyle: AppFonts.yekan16.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
height: 40,
|
||||
enabled: data.value,
|
||||
onPressed: isEditMode
|
||||
? () async {
|
||||
await controller.updateAllocation();
|
||||
Get.back();
|
||||
}
|
||||
: () async {
|
||||
await controller.submitAllocation();
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
}, controller.isValid),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget guildsDropDown(WarehouseAndDistributionSalesInProvinceLogic controller) {
|
||||
return Obx(() {
|
||||
final item = controller.selectedGuildModel.value;
|
||||
|
||||
return SearchableDropdown(
|
||||
onChanged: (value) {
|
||||
controller.selectedGuildModel.value = value;
|
||||
},
|
||||
selectedItem: [?item],
|
||||
singleSelect: false,
|
||||
items: controller.guildsModel,
|
||||
hintText: 'انتخاب مباشر/صنف',
|
||||
itemBuilder: (item) => Text(
|
||||
item.user != null
|
||||
? '${item.steward == true ? 'مباشر' : 'صنف'} ${item.user!.fullname} (${item.user!.mobile})'
|
||||
: 'بدون نام',
|
||||
),
|
||||
multiLabelBuilder: (item) => Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.bgLight,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight),
|
||||
),
|
||||
padding: EdgeInsets.all(4),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
item?.user != null
|
||||
? '${item?.steward == true ? 'مباشر' : 'صنف'} ${item?.user!.fullname}'
|
||||
: 'بدون نام',
|
||||
style: AppFonts.yekan14,
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
Icon(Icons.close, size: 16, color: AppColor.labelTextColor),
|
||||
],
|
||||
),
|
||||
),
|
||||
onSearch: (query) async {
|
||||
return Future.microtask(() {
|
||||
return RxList(
|
||||
controller.guildsModel
|
||||
.where((element) => element.user?.fullname?.contains(query) ?? false)
|
||||
.toList(),
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget productDropDown(WarehouseAndDistributionSalesInProvinceLogic controller) {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<ProductModel>(
|
||||
items: controller.rolesProductsModel,
|
||||
height: 56,
|
||||
hasDropIcon: false,
|
||||
background: Colors.white,
|
||||
onChanged: (value) {
|
||||
controller.selectedProductModel.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedProductModel.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
(item?.name?.contains('مرغ گرم') ?? false)
|
||||
? Assets.images.chicken.image(width: 40, height: 40)
|
||||
: Assets.vec.placeHolderSvg.svg(width: 40, height: 40),
|
||||
|
||||
Text(item?.name ?? 'انتخاب محصول'),
|
||||
|
||||
Spacer(),
|
||||
|
||||
ObxValue((data) {
|
||||
return Visibility(visible: data.value != null, child: Text('موجودی: $data'));
|
||||
}, controller.remainingStock),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Container modalDatePicker(ValueChanged<Jalali> onDateSelected) {
|
||||
Jalali? tempPickedDate;
|
||||
return Container(
|
||||
height: 250,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'تایید',
|
||||
),
|
||||
Spacer(),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
backgroundColor: AppColor.error,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'لغو',
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 0, thickness: 1),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: PersianCupertinoDatePicker(
|
||||
initialDateTime: Jalali.now(),
|
||||
minimumDate: Jalali.now().add(days: -1),
|
||||
maximumDate: Jalali.now(),
|
||||
mode: PersianCupertinoDatePickerMode.date,
|
||||
onDateTimeChanged: (dateTime) {
|
||||
tempPickedDate = dateTime;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget show2StepAddBottomSheet(WarehouseAndDistributionSalesInProvinceLogic controller) {
|
||||
return BaseBottomSheet(
|
||||
height: Get.height * .39,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
buildRow(
|
||||
title: 'تاریخ ثبت',
|
||||
value: controller.tmpStewardAllocation?.date?.formattedJalaliDate ?? 'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'نام و نام خانوادگی خریدار',
|
||||
value:
|
||||
controller.guildsModel
|
||||
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
|
||||
.user
|
||||
?.fullname ??
|
||||
'ندارد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'شماره خریدار',
|
||||
value:
|
||||
controller.guildsModel
|
||||
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
|
||||
.user
|
||||
?.mobile ??
|
||||
'ندارد',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'قیمت هر کیلو',
|
||||
value: '${controller.tmpStewardAllocation?.amount.separatedByCommaFa ?? 0} ریال ',
|
||||
),
|
||||
buildRow(
|
||||
title: 'وزن تخصیصی',
|
||||
value:
|
||||
'${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByCommaFa ?? 0} کیلوگرم',
|
||||
),
|
||||
buildRow(
|
||||
title: 'قیمت کل',
|
||||
value: '${controller.tmpStewardAllocation?.totalAmount.separatedByCommaFa ?? 0} ریال',
|
||||
),
|
||||
|
||||
Row(
|
||||
spacing: 10,
|
||||
children: [
|
||||
Expanded(
|
||||
child: RElevated(
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
height: 40,
|
||||
text: 'ثبت',
|
||||
textStyle: AppFonts.yekan18.copyWith(color: Colors.white),
|
||||
onPressed: () async {
|
||||
await controller.submitAllocation();
|
||||
Get
|
||||
..back()
|
||||
..back();
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ROutlinedElevated(
|
||||
height: 40,
|
||||
borderColor: AppColor.error,
|
||||
text: ' بازگشت',
|
||||
textStyle: AppFonts.yekan18.copyWith(color: AppColor.error),
|
||||
onPressed: () {
|
||||
Get
|
||||
..back()
|
||||
..back();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sale/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sales_out_of_province_buyers/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sales_out_of_province_sales_list/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionSalesOutOfProvinceLogic extends GetxController {
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
WarehouseAndDistributionSaleLogic saleLogic = Get.find<WarehouseAndDistributionSaleLogic>();
|
||||
|
||||
WarehouseAndDistributionSalesOutOfProvinceSalesListLogic saleListLogic = Get.find<WarehouseAndDistributionSalesOutOfProvinceSalesListLogic>();
|
||||
|
||||
WarehouseAndDistributionSalesOutOfProvinceBuyersLogic buyerLogic = Get.find<WarehouseAndDistributionSalesOutOfProvinceBuyersLogic>();
|
||||
|
||||
RxBool isExpanded = false.obs;
|
||||
RxInt currentPage = 1.obs;
|
||||
RxBool isSaleSubmitButtonEnabled = false.obs;
|
||||
RxInt expandedListIndex = (-1).obs;
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
RxList<String> routesName = RxList();
|
||||
RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
Rxn<IranProvinceCityModel> selectedCity = Rxn();
|
||||
Rxn<BroadcastPrice> broadcastPrice = Rxn<BroadcastPrice>();
|
||||
GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
TextEditingController quarantineCodeController = TextEditingController();
|
||||
TextEditingController saleWeightController = TextEditingController();
|
||||
TextEditingController saleCountController = TextEditingController();
|
||||
TextEditingController pricePerKiloController = TextEditingController();
|
||||
TextEditingController totalCostController = TextEditingController();
|
||||
TextEditingController otpCodeSell = TextEditingController();
|
||||
Rx<Jalali> saleDate = Jalali.now().obs;
|
||||
String? key;
|
||||
RxInt pricePerKilo = 0.obs;
|
||||
RxInt totalCost = 0.obs;
|
||||
RxInt weight = 0.obs;
|
||||
RxString otpCode = ''.obs;
|
||||
|
||||
Rx<Resource<PaginationModel<StewardFreeSaleBar>>> salesList =
|
||||
Resource<PaginationModel<StewardFreeSaleBar>>.loading().obs;
|
||||
|
||||
Rxn<ProductModel> selectedProduct = Rxn();
|
||||
Rxn<OutProvinceCarcassesBuyer> selectedBuyer = Rxn();
|
||||
|
||||
RxInt saleType = 2.obs;
|
||||
RxInt quotaType = 1.obs;
|
||||
Rxn<Jalali> productionDate = Rxn();
|
||||
Rxn<int> remainingStock = Rxn(null);
|
||||
Map<String, DayData> freeProductionDateData = {};
|
||||
Map<String, DayData> governmentalProductionDateData = {};
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
routesName.value = [...saleLogic.routesName, 'خارج استان'].toList();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
getOutProvinceSales();
|
||||
getBroadcastPrice();
|
||||
selectedProduct.value = rootLogic.rolesProductsModel.first;
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getOutProvinceSales(),
|
||||
time: Duration(milliseconds: timeDebounce),
|
||||
);
|
||||
setupListeners();
|
||||
|
||||
_updateGovernmentalProductionDateData();
|
||||
_updateFreeProductionDateData();
|
||||
ever(rootLogic.stewardRemainWeight, (callback) {
|
||||
_updateGovernmentalProductionDateData();
|
||||
_updateFreeProductionDateData();
|
||||
});
|
||||
ever(quotaType, (_) {
|
||||
remainingStock.value = null;
|
||||
productionDate.value = null;
|
||||
});
|
||||
debounce(pricePerKilo, time: Duration(milliseconds: 100), (callback) {
|
||||
totalCost.value = callback * (weight.value);
|
||||
});
|
||||
|
||||
ever(totalCost, (callback) {
|
||||
totalCostController.text = callback.separatedByComma;
|
||||
});
|
||||
}
|
||||
|
||||
void _updateGovernmentalProductionDateData() {
|
||||
List<RemainWeightDay> dates = rootLogic.stewardRemainWeight.value?.governmental ?? [];
|
||||
governmentalProductionDateData = {
|
||||
for (var element in dates)
|
||||
element.day.toString().toJalali.formatCompactDate(): DayData(
|
||||
value: element.amount?.toInt(),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
void _updateFreeProductionDateData() {
|
||||
var dates = rootLogic.stewardRemainWeight.value?.free ?? [];
|
||||
freeProductionDateData = {
|
||||
for (var element in dates)
|
||||
element.day.toString().toJalali.formatCompactDate(): DayData(
|
||||
value: element.amount?.toInt(),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
void setSearchValue(String? value) {
|
||||
searchedValue.value = value?.trim();
|
||||
}
|
||||
|
||||
void submitFilter() {
|
||||
fromDateFilter.value = fromDateFilter.value;
|
||||
toDateFilter.value = toDateFilter.value;
|
||||
getOutProvinceSales();
|
||||
}
|
||||
|
||||
Future<void> getOutProvinceSales([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.loading();
|
||||
}
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getStewardFreeSaleBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 20,
|
||||
page: currentPage.value,
|
||||
state: 'buyer-list',
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value ?? '',
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) {
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.empty();
|
||||
} else {
|
||||
salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.success(
|
||||
PaginationModel<StewardFreeSaleBar>(
|
||||
count: res?.count ?? 0,
|
||||
next: res?.next,
|
||||
previous: res?.previous,
|
||||
results: [...(salesList.value.data?.results ?? []), ...(res?.results ?? [])],
|
||||
),
|
||||
);
|
||||
|
||||
isLoadingMoreAllocationsMade.value = false;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void setupListeners() {
|
||||
saleWeightController.addListener(checkSalesFormValid);
|
||||
quarantineCodeController.addListener(checkSalesFormValid);
|
||||
saleWeightController.addListener(() {
|
||||
checkSalesFormValid();
|
||||
weight.value = int.parse(saleWeightController.text.clearComma);
|
||||
var res = (weight / selectedProduct.value!.weightAverage!.toInt()).round();
|
||||
saleCountController.text = res.separatedByComma;
|
||||
});
|
||||
ever(selectedBuyer, (_) => checkSalesFormValid);
|
||||
ever(selectedProduct, (_) => checkSalesFormValid);
|
||||
ever(saleDate, (_) => checkSalesFormValid());
|
||||
}
|
||||
|
||||
void checkSalesFormValid() {
|
||||
isSaleSubmitButtonEnabled.value =
|
||||
saleDate.value.toString().isNotEmpty &&
|
||||
selectedProduct.value != null &&
|
||||
selectedBuyer.value != null &&
|
||||
saleWeightController.text.isNotEmpty &&
|
||||
quarantineCodeController.text.isNotEmpty;
|
||||
}
|
||||
|
||||
void setEditDataSales(StewardFreeSaleBar item) {
|
||||
quarantineCodeController.text = item.clearanceCode ?? '';
|
||||
saleWeightController.text = item.weightOfCarcasses?.toInt().toString() ?? '';
|
||||
saleDate.value = Jalali.fromDateTime(DateTime.parse(item.date!));
|
||||
selectedCity.value = IranProvinceCityModel(name: item.city);
|
||||
selectedBuyer.value = buyerLogic.buyerList.value.data?.results?.firstWhere(
|
||||
(element) => element.key == item.buyer?.key,
|
||||
);
|
||||
selectedProduct.value = rootLogic.rolesProductsModel.first;
|
||||
key = item.key;
|
||||
saleType.value = item.saleType == 'free' ? 2 : 1;
|
||||
quotaType.value = item.quota == 'governmental' ? 1 : 2;
|
||||
isSaleSubmitButtonEnabled.value = true;
|
||||
productionDate.value = item.productionDate.toJalali;
|
||||
pricePerKiloController.text = pricePerKilo.value.toString().separatedByComma;
|
||||
totalCostController.text = totalCost.value.toString().separatedByComma;
|
||||
}
|
||||
|
||||
Future<void> deleteStewardPurchaseOutOfProvince(String key) async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.deleteOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
key: key,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> createSale() async {
|
||||
bool res = false;
|
||||
StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
|
||||
buyerKey: selectedBuyer.value?.key,
|
||||
numberOfCarcasses: int.tryParse(saleCountController.text.clearComma),
|
||||
weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
|
||||
date: saleDate.value.toDateTime().formattedDashedGregorian,
|
||||
clearanceCode: quarantineCodeController.text,
|
||||
productKey: selectedProduct.value?.key,
|
||||
saleType: saleType.value == 2 ? 'free' : 'exclusive',
|
||||
quota: quotaType.value == 1 ? 'governmental' : 'free',
|
||||
productionDate: productionDate.value?.toDateTime().formattedDashedGregorian,
|
||||
);
|
||||
await safeCall(
|
||||
showError: true,
|
||||
call: () => rootLogic.chickenRepository.createOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: requestBody,
|
||||
),
|
||||
onSuccess: (_) {
|
||||
res = true;
|
||||
onRefresh();
|
||||
rootLogic.onRefresh();
|
||||
Future.delayed(
|
||||
Duration(seconds: 1),
|
||||
() => defaultShowSuccessMessage("عملیات با موفقیت انجام شد"),
|
||||
);
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
void clearSaleForm() {
|
||||
quarantineCodeController.clear();
|
||||
saleWeightController.clear();
|
||||
saleDate.value = Jalali.now();
|
||||
productionDate.value = null;
|
||||
saleType.value = 2;
|
||||
quotaType.value = 2;
|
||||
selectedBuyer.value = null;
|
||||
}
|
||||
|
||||
Future<bool> editSale() async {
|
||||
bool res = false;
|
||||
StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
|
||||
numberOfCarcasses: int.tryParse(saleCountController.text.clearComma),
|
||||
weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
|
||||
date: saleDate.value.toDateTime().formattedDashedGregorian,
|
||||
clearanceCode: quarantineCodeController.text,
|
||||
saleType: saleType.value == 2 ? 'free' : 'exclusive',
|
||||
quota: quotaType.value == 1 ? 'governmental' : 'free',
|
||||
key: key,
|
||||
);
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.updateOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: requestBody,
|
||||
),
|
||||
onSuccess: (_) {
|
||||
res = true;
|
||||
onRefresh();
|
||||
Future.delayed(
|
||||
Duration(seconds: 1),
|
||||
() => defaultShowSuccessMessage("عملیات با موفقیت انجام شد"),
|
||||
);
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
Future sendSaleOtpCode(StewardFreeSaleBar item) async {
|
||||
StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
|
||||
buyerKey: item.buyer?.key,
|
||||
buyerName: item.buyer?.fullname,
|
||||
buyerMobile: item.buyer?.mobile,
|
||||
numberOfCarcasses: item.numberOfCarcasses,
|
||||
weightOfCarcasses: item.weightOfCarcasses?.toInt(),
|
||||
date: item.date,
|
||||
clearanceCode: item.clearanceCode,
|
||||
registerCode: otpCode.value,
|
||||
saleType: item.saleType,
|
||||
quota: item.quota,
|
||||
role: "Steward",
|
||||
key: item.key,
|
||||
city: item.city,
|
||||
province: item.province,
|
||||
);
|
||||
await safeCall(
|
||||
showError: true,
|
||||
call: () => rootLogic.chickenRepository.updateOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: requestBody,
|
||||
),
|
||||
onSuccess: (_) {
|
||||
onRefresh();
|
||||
Future.delayed(
|
||||
Duration(seconds: 1),
|
||||
() => defaultShowSuccessMessage("عملیات با موفقیت انجام شد"),
|
||||
);
|
||||
Get.back();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void resetSubmitForm() {
|
||||
selectedCity.value = null;
|
||||
|
||||
key = null;
|
||||
}
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
toggleExpansion();
|
||||
currentPage.value = 1;
|
||||
resetSubmitForm();
|
||||
clearSaleForm();
|
||||
await rootLogic.onRefresh();
|
||||
await getOutProvinceSales();
|
||||
}
|
||||
|
||||
void toggleExpansion({int? index}) {
|
||||
if (expandedListIndex.value == index || index == null) {
|
||||
expandedListIndex.value = -1;
|
||||
} else {
|
||||
expandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getBroadcastPrice() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getBroadcastPrice(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
broadcastPrice.value = result;
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
void setSaleDate(Jalali value) {
|
||||
saleDate.value = value;
|
||||
saleDate.refresh();
|
||||
dateErrorDialog();
|
||||
}
|
||||
|
||||
void setProductionDate(DayInfo value) {
|
||||
productionDate.value = value.date;
|
||||
remainingStock.value = value.remainingStock;
|
||||
dateErrorDialog();
|
||||
}
|
||||
|
||||
void dateErrorDialog() {
|
||||
if ((productionDate.value?.distanceTo(saleDate.value) ?? 0) >= 1) {
|
||||
saleDate.value = Jalali.now();
|
||||
Future.delayed(
|
||||
Duration(milliseconds: 300),
|
||||
() => defaultShowErrorMessage("تاریخ تولید نمی تواند قبل از تاریخ فروش باشد"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,225 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sale/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sales_out_of_province/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionSalesOutOfProvinceBuyersLogic extends GetxController {
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
WarehouseAndDistributionSaleLogic get saleLogic => Get.find<WarehouseAndDistributionSaleLogic>();
|
||||
|
||||
WarehouseAndDistributionSalesOutOfProvinceLogic get saleOutOfProvince => Get.find<WarehouseAndDistributionSalesOutOfProvinceLogic>();
|
||||
|
||||
RxInt currentPage = 1.obs;
|
||||
RxInt expandedListIndex = (-1).obs;
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
|
||||
RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
RxBool isBuyerSubmitButtonEnabled = false.obs;
|
||||
|
||||
RxList<IranProvinceCityModel> cites = <IranProvinceCityModel>[].obs;
|
||||
Rxn<IranProvinceCityModel> selectedProvince = Rxn();
|
||||
Rxn<IranProvinceCityModel> selectedCity = Rxn();
|
||||
|
||||
GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
TextEditingController buyerNameController = TextEditingController();
|
||||
TextEditingController buyerLastNameController = TextEditingController();
|
||||
TextEditingController buyerPhoneController = TextEditingController();
|
||||
TextEditingController buyerUnitNameController = TextEditingController();
|
||||
String? key;
|
||||
|
||||
Rx<Resource<PaginationModel<OutProvinceCarcassesBuyer>>> buyerList =
|
||||
Resource<PaginationModel<OutProvinceCarcassesBuyer>>.loading().obs;
|
||||
|
||||
RxList<String> routesName = RxList();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
routesName.value = [...saleLogic.routesName, 'خریداران'].toList();
|
||||
getOutProvinceCarcassesBuyer();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
|
||||
selectedProvince.listen((p0) => getCites());
|
||||
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getOutProvinceCarcassesBuyer(),
|
||||
time: Duration(milliseconds: timeDebounce),
|
||||
);
|
||||
|
||||
setupListeners();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
buyerNameController.dispose();
|
||||
buyerLastNameController.dispose();
|
||||
buyerPhoneController.dispose();
|
||||
buyerUnitNameController.dispose();
|
||||
selectedCity.value = null;
|
||||
selectedProvince.value = null;
|
||||
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
Future<void> getOutProvinceCarcassesBuyer([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
buyerList.value = Resource<PaginationModel<OutProvinceCarcassesBuyer>>.loading();
|
||||
}
|
||||
|
||||
if (searchedValue.value != null &&
|
||||
searchedValue.value!.trim().isNotEmpty &&
|
||||
currentPage.value > 1) {
|
||||
currentPage.value = 1; // Reset to first page if search value is set
|
||||
}
|
||||
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getOutProvinceCarcassesBuyer(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 20,
|
||||
page: currentPage.value,
|
||||
state: 'buyer-list',
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value ?? '',
|
||||
),
|
||||
),
|
||||
onError: (error, stackTrace) => isLoadingMoreAllocationsMade.value = false,
|
||||
onSuccess: (res) {
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
buyerList.value = Resource<PaginationModel<OutProvinceCarcassesBuyer>>.empty();
|
||||
} else {
|
||||
buyerList.value = Resource<PaginationModel<OutProvinceCarcassesBuyer>>.success(
|
||||
PaginationModel<OutProvinceCarcassesBuyer>(
|
||||
count: res?.count ?? 0,
|
||||
next: res?.next,
|
||||
previous: res?.previous,
|
||||
results: [...(buyerList.value.data?.results ?? []), ...(res?.results ?? [])],
|
||||
),
|
||||
);
|
||||
|
||||
isLoadingMoreAllocationsMade.value = false;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void resetSubmitForm() {
|
||||
buyerNameController.clear();
|
||||
buyerLastNameController.clear();
|
||||
buyerPhoneController.clear();
|
||||
buyerUnitNameController.clear();
|
||||
selectedProvince.value = null;
|
||||
selectedCity.value = null;
|
||||
}
|
||||
|
||||
Future<void> getCites() async {
|
||||
await safeCall(
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''),
|
||||
onSuccess: (result) {
|
||||
if (result != null && result.isNotEmpty) {
|
||||
cites.value = result;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void setupListeners() {
|
||||
buyerNameController.addListener(checkBuyerFormValid);
|
||||
buyerLastNameController.addListener(checkBuyerFormValid);
|
||||
buyerPhoneController.addListener(checkBuyerFormValid);
|
||||
buyerUnitNameController.addListener(checkBuyerFormValid);
|
||||
ever(selectedProvince, (_) => checkBuyerFormValid());
|
||||
ever(selectedCity, (_) => checkBuyerFormValid());
|
||||
}
|
||||
|
||||
void checkBuyerFormValid() {
|
||||
isBuyerSubmitButtonEnabled.value =
|
||||
buyerNameController.text.isNotEmpty &&
|
||||
buyerLastNameController.text.isNotEmpty &&
|
||||
buyerPhoneController.text.isNotEmpty &&
|
||||
buyerUnitNameController.text.isNotEmpty &&
|
||||
selectedProvince.value != null &&
|
||||
selectedCity.value != null;
|
||||
}
|
||||
|
||||
Future<bool> createBuyer() async {
|
||||
bool res = false;
|
||||
if (!(formKey.currentState?.validate() ?? false)) {
|
||||
return res;
|
||||
}
|
||||
await safeCall(
|
||||
call: () async {
|
||||
OutProvinceCarcassesBuyer buyer = OutProvinceCarcassesBuyer(
|
||||
province: selectedProvince.value!.name,
|
||||
city: selectedCity.value!.name,
|
||||
firstName: buyerNameController.text,
|
||||
lastName: buyerLastNameController.text,
|
||||
unitName: buyerUnitNameController.text,
|
||||
mobile: buyerPhoneController.text,
|
||||
role: 'Steward',
|
||||
);
|
||||
await rootLogic.chickenRepository.createOutProvinceCarcassesBuyer(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: buyer,
|
||||
);
|
||||
},
|
||||
onSuccess: (result) {
|
||||
getOutProvinceCarcassesBuyer();
|
||||
resetSubmitForm();
|
||||
res = true;
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
void setEditDataBuyer(OutProvinceCarcassesBuyer item) {
|
||||
buyerNameController.text = item.firstName ?? '';
|
||||
buyerLastNameController.text = item.lastName ?? '';
|
||||
buyerUnitNameController.text = item.unitName ?? '';
|
||||
buyerPhoneController.text = item.mobile ?? '';
|
||||
selectedProvince.value = IranProvinceCityModel(name: item.province);
|
||||
selectedCity.value = IranProvinceCityModel(name: item.city);
|
||||
isBuyerSubmitButtonEnabled.value = true;
|
||||
}
|
||||
|
||||
void setSearchValue(String? value) {
|
||||
searchedValue.value = value?.trim();
|
||||
}
|
||||
|
||||
void submitFilter() {
|
||||
fromDateFilter.value = fromDateFilter.value;
|
||||
toDateFilter.value = toDateFilter.value;
|
||||
getOutProvinceCarcassesBuyer();
|
||||
}
|
||||
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
currentPage.value = 1;
|
||||
await rootLogic.onRefresh();
|
||||
await getOutProvinceCarcassesBuyer();
|
||||
}
|
||||
void toggleExpansion({int? index}) {
|
||||
if (expandedListIndex.value == index || index == null) {
|
||||
expandedListIndex.value = -1;
|
||||
} else {
|
||||
expandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionSalesOutOfProvinceBuyersPage extends GetView<WarehouseAndDistributionSalesOutOfProvinceBuyersLogic> {
|
||||
const WarehouseAndDistributionSalesOutOfProvinceBuyersPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChickenBasePage(
|
||||
routes: controller.routesName,
|
||||
backId: stewardSecondKey,
|
||||
onRefresh: controller.onRefresh,
|
||||
onSearchChanged: (data) => controller.setSearchValue(data),
|
||||
filteringWidget: filterBottomSheet(),
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: Get.width,
|
||||
height: 39,
|
||||
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.greenLight,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.textColor, width: 0.5),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'لیست خریداران خارج از استان',
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
onLoadMore: () async => controller.getOutProvinceCarcassesBuyer(true),
|
||||
hasMore: data.value.data?.next != null,
|
||||
listType: ListType.separated,
|
||||
resource: data.value,
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
|
||||
itemBuilder: (context, index) {
|
||||
var item = data.value.data!.results![index];
|
||||
return ObxValue((val) {
|
||||
return ExpandableListItem2(
|
||||
selected: val.value == index,
|
||||
onTap: () => controller.toggleExpansion(index: index),
|
||||
index: index,
|
||||
child: itemListWidget(item),
|
||||
secondChild: itemListExpandedWidget(item),
|
||||
labelColor: AppColor.blueLight,
|
||||
labelIcon: Assets.vec.userRaduisSvg.path,
|
||||
);
|
||||
}, controller.expandedListIndex);
|
||||
},
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||
);
|
||||
}, controller.buyerList),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 100,
|
||||
child: RFab.add(
|
||||
onPressed: () {
|
||||
Get.bottomSheet(
|
||||
addOrEditBuyerBottomSheet(),
|
||||
isScrollControlled: true,
|
||||
ignoreSafeArea: false,
|
||||
).whenComplete(() => controller.resetSubmitForm());
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget addOrEditBuyerBottomSheet([bool isOnEdit = false]) {
|
||||
return BaseBottomSheet(
|
||||
height: 600,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
isOnEdit ? 'ویرایش خریدار' : 'افزودن خریدار',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Column(spacing: 12, children: [_provinceWidget(), _cityWidget()]),
|
||||
),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
RTextField(
|
||||
controller: controller.buyerNameController,
|
||||
label: 'نام خریدار',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.buyerLastNameController,
|
||||
label: 'نام خانوادگی خریدار',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.buyerPhoneController,
|
||||
label: 'تلفن خریدار',
|
||||
keyboardType: TextInputType.phone,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
maxLength: 11,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'لطفاً شماره موبایل را وارد کنید';
|
||||
}
|
||||
// حذف کاماها برای اعتبارسنجی
|
||||
String cleaned = value.replaceAll(',', '');
|
||||
if (cleaned.length != 11) {
|
||||
return 'شماره موبایل باید ۱۱ رقم باشد';
|
||||
}
|
||||
if (!cleaned.startsWith('09')) {
|
||||
return 'شماره موبایل باید با 09 شروع شود';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.buyerUnitNameController,
|
||||
label: 'نام واحد',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
),
|
||||
|
||||
submitButtonWidget(isOnEdit),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget submitButtonWidget(bool isOnEdit) {
|
||||
return ObxValue((data) {
|
||||
return RElevated(
|
||||
isFullWidth: true,
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
text: isOnEdit ? 'ویرایش' : 'ثبت',
|
||||
onPressed: data.value
|
||||
? () async {
|
||||
var res = await controller.createBuyer();
|
||||
if (res) {
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
: null,
|
||||
height: 40,
|
||||
);
|
||||
}, controller.isBuyerSubmitButtonEnabled);
|
||||
}
|
||||
|
||||
Widget _provinceWidget() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: controller.rootLogic.provinces,
|
||||
onChanged: (value) {
|
||||
controller.selectedProvince.value = value;
|
||||
print('Selected Product: ${value.name}');
|
||||
},
|
||||
selectedItem: controller.selectedProvince.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب استان'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _cityWidget() {
|
||||
return ObxValue((data) {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: data,
|
||||
onChanged: (value) {
|
||||
controller.selectedCity.value = value;
|
||||
print('Selected Product: ${value.name}');
|
||||
},
|
||||
selectedItem: controller.selectedCity.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب شهر'),
|
||||
);
|
||||
}, controller.cites);
|
||||
}
|
||||
|
||||
Padding itemListWidget(OutProvinceCarcassesBuyer item) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 8),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
item.buyer?.fullname ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
item.buyer?.mobile ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
'${item.unitName}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
'${item.buyer?.province}\n${item.buyer?.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDark),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container itemListExpandedWidget(OutProvinceCarcassesBuyer item) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${item.province}-${item.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
|
||||
),
|
||||
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
|
||||
buildRow(title: 'مشخصات خریدار', value: item.fullname ?? 'N/A'),
|
||||
buildRow(title: 'نام واحد', value: item.unitName ?? 'N/A'),
|
||||
buildRow(
|
||||
title: 'تعداد درخواست ها',
|
||||
value: '${item.requestsInfo?.numberOfRequests.separatedByCommaFa}',
|
||||
),
|
||||
buildRow(
|
||||
title: 'حجم تقریبی',
|
||||
value: '${item.requestsInfo?.totalQuantity.separatedByCommaFa}',
|
||||
valueLabel: 'قطعه',
|
||||
),
|
||||
buildRow(
|
||||
title: 'وزن',
|
||||
value: '${item.requestsInfo?.totalWeight.separatedByCommaFa}',
|
||||
valueLabel: 'کیلوگرم',
|
||||
),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16.w,
|
||||
children: [
|
||||
RElevated(
|
||||
text: 'ویرایش',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
controller.setEditDataBuyer(item);
|
||||
Get.bottomSheet(
|
||||
addOrEditBuyerBottomSheet(true),
|
||||
isScrollControlled: true,
|
||||
).whenComplete(() => controller.resetSubmitForm());
|
||||
},
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget filterBottomSheet() => filterBottomSheetWidget(
|
||||
fromDate: controller.fromDateFilter,
|
||||
onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali,
|
||||
toDate: controller.toDateFilter,
|
||||
onChangedToDate: (jalali) => controller.toDateFilter.value = jalali,
|
||||
onSubmit: () => controller.submitFilter(),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sale/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/sales_out_of_province_buyers/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionSalesOutOfProvinceSalesListLogic extends GetxController {
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
WarehouseAndDistributionSaleLogic saleLogic = Get.find<WarehouseAndDistributionSaleLogic>();
|
||||
|
||||
WarehouseAndDistributionSalesOutOfProvinceBuyersLogic buyerLogic = Get.find<WarehouseAndDistributionSalesOutOfProvinceBuyersLogic>();
|
||||
|
||||
RxInt selectedSegmentIndex = 0.obs;
|
||||
RxBool isExpanded = false.obs;
|
||||
RxInt currentPage = 1.obs;
|
||||
RxBool isSaleSubmitButtonEnabled = false.obs;
|
||||
RxInt expandedListIndex = (-1).obs;
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
RxList<String> routesName = RxList();
|
||||
RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
Rxn<IranProvinceCityModel> selectedCity = Rxn();
|
||||
|
||||
//TODO add this to Di
|
||||
ImagePicker imagePicker = ImagePicker();
|
||||
|
||||
|
||||
|
||||
RxInt saleType = 1.obs;
|
||||
RxInt quotaType = 1.obs;
|
||||
|
||||
|
||||
GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
TextEditingController quarantineCodeController = TextEditingController();
|
||||
TextEditingController saleWeightController = TextEditingController();
|
||||
TextEditingController saleCountController = TextEditingController();
|
||||
Rx<Jalali> saleDate = Jalali.now().obs;
|
||||
String? key;
|
||||
|
||||
Rx<Resource<PaginationModel<StewardFreeSaleBar>>> salesList =
|
||||
Resource<PaginationModel<StewardFreeSaleBar>>.loading().obs;
|
||||
|
||||
Rxn<ProductModel> selectedProduct = Rxn();
|
||||
Rxn<OutProvinceCarcassesBuyer> selectedBuyer = Rxn();
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
getOutProvinceSales();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
|
||||
selectedProduct.value = rootLogic.rolesProductsModel.first;
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getOutProvinceSales(),
|
||||
time: Duration(milliseconds: timeDebounce),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
Future<void> getOutProvinceSales([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.loading();
|
||||
}
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getStewardFreeSaleBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 20,
|
||||
page: currentPage.value,
|
||||
state: 'buyer-list',
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value ?? '',
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) {
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.empty();
|
||||
} else {
|
||||
salesList.value = Resource<PaginationModel<StewardFreeSaleBar>>.success(
|
||||
PaginationModel<StewardFreeSaleBar>(
|
||||
count: res?.count ?? 0,
|
||||
next: res?.next,
|
||||
previous: res?.previous,
|
||||
results: [...(salesList.value.data?.results ?? []), ...(res?.results ?? [])],
|
||||
),
|
||||
);
|
||||
|
||||
isLoadingMoreAllocationsMade.value = false;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void setupListeners() {
|
||||
|
||||
quarantineCodeController.addListener(checkSalesFormValid);
|
||||
ever(selectedBuyer, (_) => checkSalesFormValid);
|
||||
ever(selectedProduct, (_) => checkSalesFormValid);
|
||||
ever(saleDate, (_) => checkSalesFormValid());
|
||||
}
|
||||
|
||||
void checkSalesFormValid() {
|
||||
isSaleSubmitButtonEnabled.value =
|
||||
saleDate.value.toString().isNotEmpty &&
|
||||
selectedProduct.value != null &&
|
||||
selectedBuyer.value != null &&
|
||||
saleWeightController.text.isNotEmpty &&
|
||||
quarantineCodeController.text.isNotEmpty;
|
||||
}
|
||||
|
||||
void setEditDataSales(StewardFreeSaleBar item) {
|
||||
quarantineCodeController.text = item.clearanceCode ?? '';
|
||||
saleWeightController.text = item.weightOfCarcasses?.toInt().toString() ?? '';
|
||||
saleDate.value = Jalali.fromDateTime(DateTime.parse(item.date!));
|
||||
selectedCity.value = IranProvinceCityModel(name: item.city);
|
||||
selectedBuyer.value = buyerLogic.buyerList.value.data?.results?.firstWhere(
|
||||
(element) => element.key == item.buyer?.key,
|
||||
);
|
||||
selectedProduct.value = rootLogic.rolesProductsModel.first;
|
||||
key = item.key;
|
||||
isSaleSubmitButtonEnabled.value = true;
|
||||
}
|
||||
|
||||
Future<void> deleteStewardPurchaseOutOfProvince(String key) async {
|
||||
//todo
|
||||
/* await safeCall(
|
||||
call: () => rootLogic.chickenRepository
|
||||
.editStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
stewardFreeBarKey: key,
|
||||
),
|
||||
);*/
|
||||
}
|
||||
|
||||
Future<bool> createSale() async {
|
||||
bool res = false;
|
||||
var tmpWight = int.tryParse(saleWeightController.text.clearComma);
|
||||
var tmpCount = (tmpWight! / selectedProduct.value!.weightAverage!).round();
|
||||
|
||||
StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
|
||||
buyerKey: selectedBuyer.value?.key,
|
||||
numberOfCarcasses: tmpCount,
|
||||
weightOfCarcasses: tmpWight,
|
||||
date: saleDate.value.toDateTime().formattedDashedGregorian,
|
||||
clearanceCode: quarantineCodeController.text,
|
||||
productKey: selectedProduct.value?.key,
|
||||
);
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.createOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: requestBody,
|
||||
),
|
||||
onSuccess: (_) {
|
||||
res = true;
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
void clearSaleForm() {
|
||||
quarantineCodeController.clear();
|
||||
saleWeightController.clear();
|
||||
saleDate.value = Jalali.now();
|
||||
selectedBuyer.value = null;
|
||||
selectedProduct.value = null;
|
||||
}
|
||||
|
||||
Future<bool> editSale() async {
|
||||
bool res = false;
|
||||
StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
|
||||
numberOfCarcasses: 0,
|
||||
weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
|
||||
date: saleDate.value.toDateTime().formattedDashedGregorian,
|
||||
clearanceCode: quarantineCodeController.text,
|
||||
key: key,
|
||||
);
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.updateOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: requestBody,
|
||||
),
|
||||
onSuccess: (_) {
|
||||
res = true;
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
void resetSubmitForm() {
|
||||
selectedCity.value = null;
|
||||
selectedProduct.value = null;
|
||||
key = null;
|
||||
}
|
||||
void toggleExpansion({int? index}) {
|
||||
if (expandedListIndex.value == index || index == null) {
|
||||
expandedListIndex.value = -1;
|
||||
} else {
|
||||
expandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,498 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionSalesOutOfProvinceSalesListPage extends GetView<WarehouseAndDistributionSalesOutOfProvinceSalesListLogic> {
|
||||
const WarehouseAndDistributionSalesOutOfProvinceSalesListPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
onLoadMore: () async => controller.getOutProvinceSales(true),
|
||||
|
||||
hasMore: data.value.data?.next != null,
|
||||
listType: ListType.separated,
|
||||
resource: data.value,
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
|
||||
itemBuilder: (context, index) {
|
||||
var item = data.value.data!.results![index];
|
||||
return ObxValue((val) {
|
||||
return ExpandableListItem2(
|
||||
selected: val.value == index,
|
||||
onTap: () => controller.toggleExpansion(),
|
||||
index: index,
|
||||
child: itemListWidget(item),
|
||||
secondChild: itemListExpandedWidget(item, index),
|
||||
labelColor: AppColor.blueLight,
|
||||
labelIcon: Assets.vec.timerSvg.path,
|
||||
labelIconColor: AppColor.yellowNormal2,
|
||||
);
|
||||
}, controller.expandedListIndex);
|
||||
},
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||
);
|
||||
}, controller.salesList),
|
||||
floatingActionButton: Row(
|
||||
children: [
|
||||
RFab.add(
|
||||
onPressed: () {
|
||||
Get.bottomSheet(
|
||||
addOrEditSaleBottomSheet(),
|
||||
ignoreSafeArea: false,
|
||||
isScrollControlled: true,
|
||||
).whenComplete(() {
|
||||
controller.clearSaleForm();
|
||||
});
|
||||
},
|
||||
),
|
||||
Spacer(),
|
||||
RFab(
|
||||
icon: Icon(CupertinoIcons.person_add_solid, color: Colors.white, size: 35.w),
|
||||
backgroundColor: AppColor.blueNormal,
|
||||
onPressed: () {
|
||||
Get.toNamed(ChickenRoutes.salesOutOfProvinceBuyerSteward, id: 1);
|
||||
},
|
||||
),
|
||||
SizedBox(width: 25),
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
|
||||
);
|
||||
}
|
||||
|
||||
Row itemListWidget(StewardFreeSaleBar item) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
item.date?.formattedJalaliDate ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
item.buyer?.fullname ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
item.buyer?.mobile ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
item.buyer?.unitName ?? 'ندارد',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
Text(
|
||||
'${item.weightOfCarcasses?.separatedByCommaFa ?? 0}KG',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container itemListExpandedWidget(StewardFreeSaleBar item, int index) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'${item.province}-${item.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: AppColor.blueLightHover),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
item.date?.toJalali.formatter.wN ?? 'ندارد',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.y}',
|
||||
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
buildRow(title: 'مشخصات خریدار', value: item.buyer?.fullname ?? 'ندارد'),
|
||||
buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'ندارد'),
|
||||
buildRow(title: 'نام واحد', value: item.buyer?.unitName ?? 'ندارد'),
|
||||
buildRow(title: 'وزن لاشه', value: '${item.weightOfCarcasses?.separatedByCommaFa}'),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16.w,
|
||||
children: [
|
||||
RElevated(
|
||||
text: 'ویرایش',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
controller.setEditDataSales(item);
|
||||
Get.bottomSheet(
|
||||
addOrEditSaleBottomSheet(true),
|
||||
isScrollControlled: true,
|
||||
).whenComplete(() {
|
||||
controller.resetSubmitForm();
|
||||
});
|
||||
},
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
),
|
||||
ROutlinedElevated(
|
||||
text: 'حذف',
|
||||
textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal),
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
buildDeleteDialog(
|
||||
onConfirm: () async {
|
||||
controller.toggleExpansion();
|
||||
controller.deleteStewardPurchaseOutOfProvince(item.key!);
|
||||
},
|
||||
onRefresh: () => controller.getOutProvinceSales(),
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.redNormal,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget addOrEditSaleBottomSheet([bool isOnEdit = false]) {
|
||||
return BaseBottomSheet(
|
||||
height: 500.h,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
isOnEdit ? 'ویرایش فروش' : 'افزودن فروش',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
_productDropDown(),
|
||||
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
date: controller.saleDate,
|
||||
onChanged: (jalali) => controller.saleDate.value = jalali,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
_buyerWidget(),
|
||||
RTextField(
|
||||
controller: controller.saleWeightController,
|
||||
label: 'وزن لاشه',
|
||||
keyboardType: TextInputType.number,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
|
||||
validator: (value) {
|
||||
if (value == null) {
|
||||
return 'لطفاً وزن لاشه را وارد کنید';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.saleCountController,
|
||||
label: 'حجم تقریبی(قطعه)',
|
||||
keyboardType: TextInputType.number,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
|
||||
validator: (value) {
|
||||
if (value == null) {
|
||||
return 'لطفاً وزن لاشه را وارد کنید';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
|
||||
RTextField(
|
||||
controller: controller.quarantineCodeController,
|
||||
label: 'کد قرنطینه',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
validator: (value) {
|
||||
if (value == null) {
|
||||
return 'لطفاً کد قرنطینه را وارد کنید';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
submitButtonWidget(isOnEdit),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget submitButtonWidget(bool isOnEdit) {
|
||||
return ObxValue((data) {
|
||||
return RElevated(
|
||||
isFullWidth: true,
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
text: isOnEdit ? 'ویرایش' : 'ثبت',
|
||||
onPressed: data.value
|
||||
? () async {
|
||||
var res = isOnEdit ? await controller.editSale() : await controller.createSale();
|
||||
if (res) {
|
||||
controller.getOutProvinceSales();
|
||||
controller.clearSaleForm();
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
: null,
|
||||
height: 40,
|
||||
);
|
||||
}, controller.isSaleSubmitButtonEnabled);
|
||||
}
|
||||
|
||||
Widget _buyerWidget() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<OutProvinceCarcassesBuyer>(
|
||||
items: controller.buyerLogic.buyerList.value.data?.results ?? [],
|
||||
onChanged: (value) {
|
||||
controller.selectedBuyer.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedBuyer.value,
|
||||
itemBuilder: (item) => Text(item.buyer?.fullname ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.buyer?.fullname ?? 'انتخاب خریدار'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _productDropDown() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<ProductModel>(
|
||||
items: controller.rootLogic.rolesProductsModel,
|
||||
height: 56,
|
||||
hasDropIcon: false,
|
||||
background: Colors.white,
|
||||
onChanged: (value) {
|
||||
controller.selectedProduct.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedProduct.value,
|
||||
initialValue: controller.selectedProduct.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
(item?.name?.contains('مرغ گرم') ?? false)
|
||||
? Assets.images.chicken.image(width: 40, height: 40)
|
||||
: Assets.vec.placeHolderSvg.svg(width: 40, height: 40),
|
||||
|
||||
Text(item?.name ?? 'انتخاب محصول'),
|
||||
Spacer(),
|
||||
Text(
|
||||
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0}',
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
GestureDetector timeFilterWidget({
|
||||
isFrom = true,
|
||||
required Rx<Jalali> date,
|
||||
required Function(Jalali jalali) onChanged,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.bottomSheet(modalDatePicker((value) => onChanged(value)));
|
||||
},
|
||||
child: Container(
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.bgLight,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 1, color: AppColor.darkGreyLight),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 11, vertical: 4),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Assets.vec.calendarSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: const ColorFilter.mode(AppColor.bgDark, BlendMode.srcIn),
|
||||
),
|
||||
Text('تاریخ', style: AppFonts.yekan16.copyWith(color: AppColor.bgDark)),
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return Text(
|
||||
date.value.formatCompactDate(),
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDark),
|
||||
);
|
||||
}, date),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container modalDatePicker(ValueChanged<Jalali> onDateSelected) {
|
||||
Jalali? tempPickedDate;
|
||||
return Container(
|
||||
height: 250,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'تایید',
|
||||
),
|
||||
Spacer(),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
backgroundColor: AppColor.error,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'لغو',
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 0, thickness: 1),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: PersianCupertinoDatePicker(
|
||||
initialDateTime: controller.saleDate.value,
|
||||
mode: PersianCupertinoDatePickerMode.date,
|
||||
onDateTimeChanged: (dateTime) {
|
||||
tempPickedDate = dateTime;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class WarehouseAndDistributionSegmentationLogic extends GetxController {
|
||||
WarehouseAndDistributionRootLogic rootLogic = Get.find<WarehouseAndDistributionRootLogic>();
|
||||
|
||||
RxBool isLoadingMoreAllocationsMade = false.obs;
|
||||
RxInt currentPage = 1.obs;
|
||||
|
||||
late List<String> routesName;
|
||||
RxInt selectedSegmentIndex = 0.obs;
|
||||
RxBool isExpanded = false.obs;
|
||||
|
||||
RxInt expandedListIndex = (-1).obs;
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
RxInt segmentType = 1.obs;
|
||||
RxInt priceType = 2.obs;
|
||||
RxInt quotaType = 2.obs;
|
||||
GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
TextEditingController weightController = TextEditingController(text: '0');
|
||||
RxBool isSubmitButtonEnabled = false.obs;
|
||||
Rxn<GuildModel> selectedGuildModel = Rxn<GuildModel>();
|
||||
Rxn<ProductModel> selectedProduct = Rxn<ProductModel>();
|
||||
Rxn<SegmentationModel> selectedSegment = Rxn<SegmentationModel>();
|
||||
Rxn<BroadcastPrice> broadcastPrice = Rxn<BroadcastPrice>();
|
||||
Rx<Resource<PaginationModel<SegmentationModel>>> segmentationList =
|
||||
Resource<PaginationModel<SegmentationModel>>.loading().obs;
|
||||
|
||||
RxList<GuildModel> guildsModel = <GuildModel>[].obs;
|
||||
Rx<Jalali> saleDate = Jalali.now().obs;
|
||||
RxInt weight = 0.obs;
|
||||
Rxn<Jalali> productionDate = Rxn(null);
|
||||
Rxn<int> remainingStock = Rxn(null);
|
||||
Map<String, DayData> freeProductionDateData = {};
|
||||
Map<String, DayData> governmentalProductionDateData = {};
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
routesName = ['قطعهبندی'].toList();
|
||||
once(rootLogic.rolesProductsModel, (callback) => selectedProduct.value = callback.first);
|
||||
getAllSegmentation();
|
||||
getGuilds();
|
||||
|
||||
ever(quotaType, (_) {
|
||||
remainingStock.value = null;
|
||||
productionDate.value = null;
|
||||
});
|
||||
_updateGovernmentalProductionDateData();
|
||||
_updateFreeProductionDateData();
|
||||
ever(rootLogic.stewardRemainWeight, (callback) {
|
||||
_updateGovernmentalProductionDateData();
|
||||
_updateFreeProductionDateData();
|
||||
});
|
||||
}
|
||||
|
||||
void _updateGovernmentalProductionDateData() {
|
||||
List<RemainWeightDay> dates = rootLogic.stewardRemainWeight.value?.governmental ?? [];
|
||||
governmentalProductionDateData = {
|
||||
for (var element in dates)
|
||||
element.day.toString().toJalali.formatCompactDate(): DayData(
|
||||
value: element.amount?.toInt(),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
void _updateFreeProductionDateData() {
|
||||
var dates = rootLogic.stewardRemainWeight.value?.free ?? [];
|
||||
freeProductionDateData = {
|
||||
for (var element in dates)
|
||||
element.day.toString().toJalali.formatCompactDate(): DayData(
|
||||
value: element.amount?.toInt(),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
setUpListener();
|
||||
}
|
||||
|
||||
|
||||
void setSearchValue(String? value) {
|
||||
searchedValue.value = value?.trim();
|
||||
}
|
||||
|
||||
void setUpListener() {
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getAllSegmentation(),
|
||||
time: Duration(milliseconds: timeDebounce),
|
||||
);
|
||||
|
||||
everAll([selectedSegment, quotaType, priceType], (_) {
|
||||
validateForm();
|
||||
});
|
||||
|
||||
weightController.addListener(() => validateForm());
|
||||
}
|
||||
|
||||
void setEditData(SegmentationModel item) {
|
||||
selectedSegment.value = item;
|
||||
weightController.text = item.weight.toString();
|
||||
}
|
||||
|
||||
void clearForm() {
|
||||
weightController.text = '0';
|
||||
selectedSegment.value = null;
|
||||
selectedGuildModel.value = null;
|
||||
productionDate.value = null;
|
||||
segmentType.value = 1;
|
||||
priceType.value = 2;
|
||||
quotaType.value = 1;
|
||||
remainingStock.value = null;
|
||||
}
|
||||
|
||||
void validateForm() {
|
||||
var weight = int.tryParse(weightController.text.trim().clearComma) ?? 0;
|
||||
var hasWeight = (remainingStock.value ?? 0) > weight;
|
||||
isSubmitButtonEnabled.value =
|
||||
selectedProduct.value != null &&
|
||||
weightController.text.isNotEmpty &&
|
||||
hasWeight &&
|
||||
productionDate.value != null &&
|
||||
weight > 0 &&
|
||||
(segmentType.value == 1 || (segmentType.value == 2 && selectedGuildModel.value != null));
|
||||
}
|
||||
|
||||
Future<void> getAllSegmentation([bool isLoadingMore = false]) async {
|
||||
if (isLoadingMore) {
|
||||
isLoadingMoreAllocationsMade.value = true;
|
||||
} else {
|
||||
segmentationList.value = Resource<PaginationModel<SegmentationModel>>.loading();
|
||||
}
|
||||
|
||||
if (searchedValue.value != null &&
|
||||
searchedValue.value!.trim().isNotEmpty &&
|
||||
currentPage.value > 1) {
|
||||
currentPage.value = 1; // Reset to first page if search value is set
|
||||
}
|
||||
|
||||
await safeCall(
|
||||
showError: true,
|
||||
call: () async => await rootLogic.chickenRepository.getSegmentation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 20,
|
||||
page: currentPage.value,
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value,
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
|
||||
onSuccess: (result) {
|
||||
if ((result?.count ?? 0) == 0) {
|
||||
segmentationList.value = Resource<PaginationModel<SegmentationModel>>.empty();
|
||||
} else {
|
||||
segmentationList.value = Resource<PaginationModel<SegmentationModel>>.success(
|
||||
PaginationModel<SegmentationModel>(
|
||||
count: result?.count ?? 0,
|
||||
next: result?.next,
|
||||
previous: result?.previous,
|
||||
results: [
|
||||
...(segmentationList.value.data?.results ?? []),
|
||||
...(result?.results ?? []),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
isLoadingMoreAllocationsMade.value = false;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> deleteSegmentation(String key) async {
|
||||
await safeCall(
|
||||
showError: true,
|
||||
showSuccess: true,
|
||||
call: () => rootLogic.chickenRepository.deleteSegmentation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
key: key,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> editSegment() async {
|
||||
var res = true;
|
||||
safeCall(
|
||||
showError: true,
|
||||
call: () async => await rootLogic.chickenRepository.editSegmentation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
model: SegmentationModel(
|
||||
key: selectedSegment.value?.key,
|
||||
weight: int.tryParse(weightController.text.clearComma) ?? 0,
|
||||
productionDate: productionDate.value?.toDateTime().formattedDashedGregorian,
|
||||
),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
res = true;
|
||||
onRefresh();
|
||||
},
|
||||
onError: (error, stacktrace) {
|
||||
res = false;
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<bool> createSegment() async {
|
||||
var res = true;
|
||||
SegmentationModel segmentationModel = SegmentationModel(
|
||||
productKey: selectedProduct.value?.key,
|
||||
weight: int.tryParse(weightController.text.clearComma) ?? 0,
|
||||
saleType: priceType.value == 1 ? 'governmental' : 'free',
|
||||
quota: quotaType.value == 1 ? 'governmental' : 'free',
|
||||
);
|
||||
if (segmentType.value == 2) {
|
||||
segmentationModel = segmentationModel.copyWith(guildKey: selectedGuildModel.value?.key);
|
||||
}
|
||||
segmentationModel = segmentationModel.copyWith(
|
||||
productionDate: productionDate.value?.toDateTime().formattedDashedGregorian,
|
||||
);
|
||||
await safeCall(
|
||||
showError: true,
|
||||
call: () async => await rootLogic.chickenRepository.createSegmentation(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
model: segmentationModel,
|
||||
),
|
||||
onSuccess: (result) async {
|
||||
res = true;
|
||||
isSubmitButtonEnabled.value = false;
|
||||
onRefresh();
|
||||
Future.delayed(
|
||||
Duration(seconds: 1),
|
||||
() => defaultShowSuccessMessage("قطعهبندی با موفقیت ثبت شد!"),
|
||||
);
|
||||
Get.back();
|
||||
},
|
||||
onError: (error, stacktrace) {
|
||||
res = false;
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<void> getGuilds() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getGuilds(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(queryParams: {'all': true}, role: 'Steward'),
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
guildsModel.clear();
|
||||
guildsModel.addAll(result);
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> onRefresh() async {
|
||||
toggleExpansion();
|
||||
currentPage.value = 1;
|
||||
await rootLogic.onRefresh();
|
||||
await getAllSegmentation();
|
||||
await getBroadcastPrice();
|
||||
_updateFreeProductionDateData();
|
||||
_updateGovernmentalProductionDateData();
|
||||
}
|
||||
|
||||
Future<void> getBroadcastPrice() async {
|
||||
safeCall(
|
||||
call: () async => await rootLogic.chickenRepository.getBroadcastPrice(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
broadcastPrice.value = result;
|
||||
if (broadcastPrice.value?.active == true) {
|
||||
priceType.value = 2;
|
||||
}
|
||||
},
|
||||
onError: (error, stacktrace) {},
|
||||
);
|
||||
}
|
||||
|
||||
void toggleExpansion({int? index}) {
|
||||
if (expandedListIndex.value == index || index == null) {
|
||||
expandedListIndex.value = -1;
|
||||
} else {
|
||||
expandedListIndex.value = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/segmentation/widgets/cu_bottom_sheet.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
|
||||
class WarehouseAndDistributionSegmentationPage
|
||||
extends GetView<WarehouseAndDistributionSegmentationLogic> {
|
||||
WarehouseAndDistributionSegmentationPage({super.key});
|
||||
|
||||
final today = Jalali.now();
|
||||
final oneDayAgo = Jalali.now().addDays(-1);
|
||||
final twoDaysAgo = Jalali.now().addDays(-2);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChickenBasePage(
|
||||
routes: controller.routesName,
|
||||
onSearchChanged: (data) => controller.setSearchValue(data),
|
||||
onFilterTap: () {
|
||||
Get.bottomSheet(filterBottomSheet());
|
||||
},
|
||||
onRefresh: controller.onRefresh,
|
||||
hasBack: false,
|
||||
child: Stack(
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
onLoadMore: () async => controller.getAllSegmentation(true),
|
||||
hasMore: data.value.data?.next != null,
|
||||
listType: ListType.separated,
|
||||
resource: data.value,
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
|
||||
itemBuilder: (context, index) {
|
||||
var item = data.value.data!.results![index];
|
||||
return ObxValue((val) {
|
||||
return ExpandableListItem2(
|
||||
selected: val.value == index,
|
||||
onTap: () => controller.toggleExpansion(index: index),
|
||||
index: index,
|
||||
child: itemListWidget(item),
|
||||
secondChild: itemListExpandedWidget(item, index),
|
||||
labelColor: AppColor.blueLight,
|
||||
labelIconColor: AppColor.customGrey,
|
||||
labelIcon: Assets.vec.convertCubeSvg.path,
|
||||
);
|
||||
}, controller.expandedListIndex);
|
||||
},
|
||||
itemCount: data.value.data?.results?.length ?? 0,
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8.h),
|
||||
);
|
||||
}, controller.segmentationList),
|
||||
),
|
||||
Positioned(
|
||||
right: 10,
|
||||
bottom: 90.h,
|
||||
child: RFab.add(
|
||||
onPressed: () {
|
||||
/* Get.bottomSheet(
|
||||
addOrEditBottomSheet(controller),
|
||||
isScrollControlled: true,
|
||||
ignoreSafeArea: false,
|
||||
).whenComplete(() {
|
||||
controller.clearForm();
|
||||
//defaultShowSuccessMessage('با موفقیت ثبت شد');
|
||||
}); */
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget filterBottomSheet() => filterBottomSheetWidget(
|
||||
fromDate: controller.fromDateFilter,
|
||||
onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali,
|
||||
toDate: controller.toDateFilter,
|
||||
onChangedToDate: (jalali) => controller.toDateFilter.value = jalali,
|
||||
onSubmit: () => controller.getAllSegmentation(),
|
||||
);
|
||||
|
||||
Row itemListWidget(SegmentationModel item) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
item.toGuild != null ? 'قطعهبند' : 'مباشر',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Text(
|
||||
item.date?.formattedJalaliDate ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
item.toGuild != null
|
||||
? item.toGuild?.user?.fullname ?? 'N/A'
|
||||
: item.buyer?.fullname ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
item.toGuild != null
|
||||
? item.toGuild?.guildsName ?? 'N/A'
|
||||
: item.buyer?.shop ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
spacing: 4,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
item.weight.separatedByCommaFa.addKg,
|
||||
textAlign: TextAlign.center,
|
||||
textDirection: TextDirection.ltr,
|
||||
style: AppFonts.yekan14Bold.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
item.saleType == "governmental" ? 'دولتی' : 'آزاد',
|
||||
textAlign: TextAlign.center,
|
||||
textDirection: TextDirection.ltr,
|
||||
style: AppFonts.yekan14Bold.copyWith(
|
||||
color: item.saleType == "governmental"
|
||||
? AppColor.blueNormal
|
||||
: AppColor.greenNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Container itemListExpandedWidget(SegmentationModel item, int index) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(width: 1, color: AppColor.blueLightHover),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 3,
|
||||
children: [
|
||||
Text(
|
||||
DateTimeExtensions(item.date)?.toJalali().formatter.wN ??
|
||||
'N/A',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.textColor,
|
||||
),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${DateTimeExtensions(item.date)?.toJalali().formatter.d} ${DateTimeExtensions(item.date)?.toJalali().formatter.mN ?? 'N/A'}',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Text(
|
||||
'${DateTimeExtensions(item.date)?.toJalali().formatter.y}',
|
||||
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
|
||||
Text(
|
||||
'${DateTimeExtensions(item.date)?.toJalali().formatter.tHH}:${DateTimeExtensions(item.date)?.toJalali().formatter.tMM ?? 'N/A'}',
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
buildRow(
|
||||
title: 'مشخصات خریدار',
|
||||
value: item.toGuild != null
|
||||
? item.toGuild?.user?.fullname ?? 'N/A'
|
||||
: item.buyer?.fullname ?? 'N/A',
|
||||
),
|
||||
buildRow(
|
||||
title: 'تلفن خریدار',
|
||||
value: item.toGuild != null
|
||||
? item.toGuild?.user?.mobile ?? 'N/A'
|
||||
: item.buyer?.mobile ?? 'N/A',
|
||||
),
|
||||
buildRow(
|
||||
title: 'نام واحد',
|
||||
value: item.toGuild != null
|
||||
? item.toGuild?.guildsName ?? 'N/A'
|
||||
: item.buyer?.shop ?? 'N/A',
|
||||
),
|
||||
buildRow(
|
||||
title: 'ماهیت',
|
||||
value: item.toGuild != null ? 'قطعهبند' : 'مباشر',
|
||||
),
|
||||
buildRow(
|
||||
title: 'نوع فروش',
|
||||
value: item.saleType == "governmental" ? 'دولتی' : 'آزاد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'انبار فروش',
|
||||
value: item.quota == "governmental" ? 'دولتی' : 'آزاد',
|
||||
),
|
||||
buildRow(
|
||||
title: 'تاریخ تولید گوشت',
|
||||
value: item.productionDate?.toJalali.formatCompactDate() ?? 'ندارد',
|
||||
),
|
||||
|
||||
buildRow(
|
||||
title: 'وزن قطعهبندی',
|
||||
value: item.weight!.separatedByCommaFa,
|
||||
valueLabel: 'کیلوگرم',
|
||||
),
|
||||
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 16.w,
|
||||
children: [
|
||||
RElevated(
|
||||
text: 'ویرایش',
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
controller.setEditData(item);
|
||||
/* Get.bottomSheet(
|
||||
addOrEditBottomSheet(controller, isOnEdit: true),
|
||||
isScrollControlled: true,
|
||||
ignoreSafeArea: false,
|
||||
).whenComplete(() {
|
||||
controller.clearForm();
|
||||
}); */
|
||||
},
|
||||
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
),
|
||||
ROutlinedElevated(
|
||||
text: 'حذف',
|
||||
textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal),
|
||||
width: 150.w,
|
||||
height: 40.h,
|
||||
onPressed: () {
|
||||
buildDeleteDialog(
|
||||
onConfirm: () async {
|
||||
controller.toggleExpansion();
|
||||
controller.deleteSegmentation(item.key!);
|
||||
},
|
||||
onRefresh: () => controller.onRefresh(),
|
||||
);
|
||||
},
|
||||
borderColor: AppColor.redNormal,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/segmentation/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
Widget addOrEditBottomSheet(WarehouseAndDistributionSegmentationLogic controller, {bool isOnEdit = false}) {
|
||||
return BaseBottomSheet(
|
||||
height: isOnEdit ? 350.h : 600.h,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
isOnEdit ? 'ویرایش قطعهبندی' : 'افزودن قطعهبندی',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
_productDropDown(controller),
|
||||
Visibility(
|
||||
visible: isOnEdit == false,
|
||||
child: Container(
|
||||
height: 50.h,
|
||||
clipBehavior: Clip.none,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
alignment: Alignment.center,
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Positioned(
|
||||
child: Container(color: Colors.white, child: Text("انبار")),
|
||||
top: -10,
|
||||
right: 8,
|
||||
),
|
||||
Obx(() {
|
||||
return RadioGroup(
|
||||
groupValue: controller.quotaType.value,
|
||||
onChanged: (value) {
|
||||
controller.quotaType.value = value ?? 0;
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.quotaType.value = 1;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: 1),
|
||||
Text('دولتی', style: AppFonts.yekan14),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.quotaType.value = 2;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: 2),
|
||||
Text('آزاد', style: AppFonts.yekan14),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Obx(() {
|
||||
return MonthlyDataCalendar(
|
||||
label: 'تاریخ تولید گوشت',
|
||||
selectedDate: controller.productionDate.value?.formatCompactDate(),
|
||||
onDateSelect: (value) {
|
||||
controller.productionDate.value = value.date;
|
||||
controller.remainingStock.value = value.remainingStock;
|
||||
},
|
||||
dayData: controller.quotaType.value == 1
|
||||
? controller.governmentalProductionDateData
|
||||
: controller.freeProductionDateData,
|
||||
);
|
||||
}),
|
||||
|
||||
RTextField(
|
||||
controller: controller.weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
autoValidateMode: AutovalidateMode.onUserInteraction,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
filledColor: AppColor.bgLight,
|
||||
filled: true,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
|
||||
validator: (value) {
|
||||
if ((int.tryParse(value?.clearComma ?? '0') ?? 0) >
|
||||
(controller.remainingStock.value ?? 0)) {
|
||||
return 'وزن تخصیصی بیشتر از موجودی انبار است';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onChanged: (p0) {
|
||||
controller.weight.value = int.tryParse(p0.clearComma) ?? 0;
|
||||
},
|
||||
label: 'وزن لاشه (کیلوگرم)',
|
||||
),
|
||||
Visibility(
|
||||
visible: isOnEdit == false,
|
||||
child: Container(
|
||||
height: 58.h,
|
||||
clipBehavior: Clip.none,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
alignment: Alignment.center,
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Positioned(
|
||||
child: Container(color: Colors.white, child: Text("فروش")),
|
||||
top: -10,
|
||||
right: 8,
|
||||
),
|
||||
Obx(() {
|
||||
return RadioGroup(
|
||||
groupValue: controller.priceType.value,
|
||||
onChanged: (value) {
|
||||
controller.priceType.value = value!;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: (controller.broadcastPrice.value?.active ?? false)
|
||||
? () {
|
||||
controller.priceType.value = 1;
|
||||
}
|
||||
: null,
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(
|
||||
value: 1,
|
||||
enabled: controller.broadcastPrice.value?.active ?? false,
|
||||
),
|
||||
Text(
|
||||
'قیمت مصوب',
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: (controller.broadcastPrice.value?.active ?? false)
|
||||
? AppColor.textColor
|
||||
: AppColor.labelTextColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
controller.priceType.value = 2;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Radio(value: 2),
|
||||
Text('قیمت آزاد', style: AppFonts.yekan14),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Visibility(
|
||||
visible: isOnEdit == false,
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: AppColor.darkGreyLight, width: 1),
|
||||
),
|
||||
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: ObxValue((data) {
|
||||
return RadioGroup(
|
||||
onChanged: (value) {
|
||||
controller.segmentType.value = value!;
|
||||
controller.selectedGuildModel.value = null;
|
||||
controller.selectedGuildModel.refresh();
|
||||
},
|
||||
groupValue: controller.segmentType.value,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Radio(value: 1),
|
||||
Text('قطعهبندی(کاربر)', style: AppFonts.yekan14),
|
||||
SizedBox(width: 12),
|
||||
Radio(value: 2),
|
||||
Text('تخصیص به قطعهبند', style: AppFonts.yekan14),
|
||||
],
|
||||
),
|
||||
);
|
||||
}, controller.priceType),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
ObxValue((data) {
|
||||
return Visibility(
|
||||
visible: data.value == 2,
|
||||
child: guildsDropDown(controller),
|
||||
);
|
||||
}, controller.segmentType),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
submitButtonWidget(controller, isOnEdit: isOnEdit),
|
||||
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget submitButtonWidget(WarehouseAndDistributionSegmentationLogic controller, {bool isOnEdit = false}) {
|
||||
return ObxValue((data) {
|
||||
return RElevated(
|
||||
isFullWidth: true,
|
||||
backgroundColor: AppColor.greenNormal,
|
||||
text: isOnEdit ? 'ویرایش' : 'ثبت',
|
||||
onPressed: data.value
|
||||
? () async {
|
||||
var res = isOnEdit
|
||||
? await controller.editSegment()
|
||||
: await controller.createSegment();
|
||||
if (res) {
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
: null,
|
||||
height: 40,
|
||||
);
|
||||
}, controller.isSubmitButtonEnabled);
|
||||
}
|
||||
|
||||
Widget _productDropDown(WarehouseAndDistributionSegmentationLogic controller) {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<ProductModel>(
|
||||
items: controller.rootLogic.rolesProductsModel,
|
||||
height: 56,
|
||||
hasDropIcon: false,
|
||||
background: Colors.white,
|
||||
onChanged: (value) {
|
||||
controller.selectedProduct.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedProduct.value,
|
||||
initialValue: controller.selectedProduct.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
(item?.name?.contains('مرغ گرم') ?? false)
|
||||
? Assets.images.chicken.image(width: 40, height: 40)
|
||||
: Assets.vec.placeHolderSvg.svg(width: 40, height: 40),
|
||||
|
||||
Text(item?.name ?? 'انتخاب محصول'),
|
||||
Spacer(),
|
||||
ObxValue((data) {
|
||||
return Visibility(visible: data.value != null, child: Text('موجودی: $data'));
|
||||
}, controller.remainingStock),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget guildsDropDown(WarehouseAndDistributionSegmentationLogic controller) {
|
||||
return Obx(() {
|
||||
final item = controller.selectedGuildModel.value;
|
||||
return OverlayDropdownWidget<GuildModel>(
|
||||
key: ValueKey(item?.user?.fullname ?? ''),
|
||||
items: controller.guildsModel,
|
||||
onChanged: (value) {
|
||||
controller.selectedGuildModel.value = value;
|
||||
},
|
||||
selectedItem: item,
|
||||
|
||||
itemBuilder: (item) => Text(
|
||||
item.user != null
|
||||
? '${item.steward == true ? 'مباشر' : 'صنف'} ${item.user!.fullname} (${item.user!.mobile})'
|
||||
: 'بدون نام',
|
||||
),
|
||||
labelBuilder: (item) => Text(
|
||||
item?.user != null
|
||||
? '${item?.steward == true ? 'مباشر' : 'صنف'} ${item?.user!.fullname} (${item?.user!.mobile})'
|
||||
: 'انتخاب مباشر/صنف',
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Container modalDatePicker(WarehouseAndDistributionSegmentationLogic controller, ValueChanged<Jalali> onDateSelected) {
|
||||
Jalali currentDate = Jalali.now();
|
||||
Jalali? tempPickedDate;
|
||||
return Container(
|
||||
height: 250,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(width: 20),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'تایید',
|
||||
),
|
||||
Spacer(),
|
||||
RElevated(
|
||||
height: 35,
|
||||
width: 70,
|
||||
backgroundColor: AppColor.error,
|
||||
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
text: 'لغو',
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 0, thickness: 1),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: PersianCupertinoDatePicker(
|
||||
initialDateTime: controller.saleDate.value,
|
||||
mode: PersianCupertinoDatePickerMode.date,
|
||||
maximumDate: currentDate.addDays(3),
|
||||
minimumDate: currentDate.toDateTime().subtract(Duration(days: 1)).toString().toJalali,
|
||||
maximumYear: currentDate.year,
|
||||
minimumYear: currentDate.year,
|
||||
onDateTimeChanged: (dateTime) {
|
||||
tempPickedDate = dateTime;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
export 'buy/logic.dart';
|
||||
export 'buy/view.dart';
|
||||
export 'buy_in_province/logic.dart';
|
||||
export 'buy_in_province/view.dart';
|
||||
export 'buy_in_province_all/logic.dart';
|
||||
export 'buy_in_province_all/view.dart';
|
||||
export 'buy_in_province_waiting/logic.dart';
|
||||
export 'buy_in_province_waiting/view.dart';
|
||||
export 'buy_out_of_province/logic.dart';
|
||||
export 'buy_out_of_province/view.dart';
|
||||
export 'home/logic.dart';
|
||||
export 'home/view.dart';
|
||||
export 'root/logic.dart';
|
||||
export 'root/view.dart';
|
||||
export 'sale/logic.dart';
|
||||
export 'sale/view.dart';
|
||||
export 'sales_in_province/logic.dart';
|
||||
export 'sales_in_province/view.dart';
|
||||
export 'sales_out_of_province/logic.dart';
|
||||
export 'sales_out_of_province/view.dart';
|
||||
export 'sales_out_of_province_buyers/logic.dart';
|
||||
export 'sales_out_of_province_buyers/view.dart';
|
||||
export 'sales_out_of_province_sales_list/logic.dart';
|
||||
export 'sales_out_of_province_sales_list/view.dart';
|
||||
export 'segmentation/logic.dart';
|
||||
export 'segmentation/view.dart';
|
||||
@@ -3,7 +3,7 @@ import 'package:rasadyar_chicken/presentation/pages/steward/buy_in_province_all/
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/buy_in_province_waiting/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/steward/inventory_widget.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
@@ -25,7 +25,10 @@ class BuyInProvincePage extends GetView<BuyInProvinceLogic> {
|
||||
onRefresh: controller.onRefresh,
|
||||
child: Column(
|
||||
children: [
|
||||
inventoryWidget(controller.rootLogic),
|
||||
ObxValue((data) {
|
||||
return InventoryWidget(inventoryModel: data.value!);
|
||||
}, controller.rootLogic.inventoryModel),
|
||||
|
||||
segmentWidget(),
|
||||
ObxValue((index) {
|
||||
return Expanded(
|
||||
|
||||
@@ -8,7 +8,8 @@ import 'package:rasadyar_chicken/data/models/response/roles_products/roles_produ
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/steward/inventory_widget.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart';
|
||||
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
@@ -32,7 +33,10 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
|
||||
Positioned.fill(
|
||||
child: Column(
|
||||
children: [
|
||||
inventoryWidget(controller.rootLogic),
|
||||
ObxValue((data) {
|
||||
return InventoryWidget(inventoryModel: data.value!);
|
||||
}, controller.rootLogic.inventoryModel),
|
||||
|
||||
ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
listType: ListType.separated,
|
||||
|
||||
@@ -28,12 +28,22 @@ enum ErrorLocationType { serviceDisabled, permissionDenied, none }
|
||||
class StewardRootLogic extends GetxController {
|
||||
DateTime? _lastBackPressed;
|
||||
RxInt currentPage = 2.obs;
|
||||
List<Widget> pages = [BuyPage(), SalePage(), HomePage(), SegmentationPage(), ProfilePage()];
|
||||
List<Widget> pages = [
|
||||
BuyPage(),
|
||||
SalePage(),
|
||||
HomePage(),
|
||||
SegmentationPage(),
|
||||
ProfilePage(),
|
||||
];
|
||||
|
||||
final defaultRoutes = <int, String>{0: ChickenRoutes.buySteward, 1: ChickenRoutes.saleSteward};
|
||||
final defaultRoutes = <int, String>{
|
||||
0: ChickenRoutes.buySteward,
|
||||
1: ChickenRoutes.saleSteward,
|
||||
};
|
||||
RxList<ProductModel> rolesProductsModel = RxList<ProductModel>();
|
||||
Rxn<WidelyUsedLocalModel> widelyUsedList = Rxn<WidelyUsedLocalModel>();
|
||||
Rxn<StewardSalesInfoDashboard> stewardSalesInfoDashboard = Rxn<StewardSalesInfoDashboard>();
|
||||
Rxn<StewardSalesInfoDashboard> stewardSalesInfoDashboard =
|
||||
Rxn<StewardSalesInfoDashboard>();
|
||||
Rxn<StewardRemainWeight> stewardRemainWeight = Rxn<StewardRemainWeight>();
|
||||
|
||||
late DioRemote dioRemote;
|
||||
@@ -75,7 +85,9 @@ class StewardRootLogic extends GetxController {
|
||||
|
||||
if (widelyUsedList.value?.hasInit != true) {
|
||||
//TODO
|
||||
localDatasource.initWidleyUsed().then((value) => localDatasource.getAllWidely());
|
||||
localDatasource.initWidleyUsed().then(
|
||||
(value) => localDatasource.getAllWidely(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +127,7 @@ class StewardRootLogic extends GetxController {
|
||||
call: () async => await chickenRepository.getInventory(
|
||||
token: tokenService.accessToken.value!,
|
||||
cancelToken: _inventoryCancelToken,
|
||||
role: 'Steward',
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
@@ -146,7 +159,9 @@ class StewardRootLogic extends GetxController {
|
||||
_provincesCancelToken = CancelToken();
|
||||
|
||||
try {
|
||||
final res = await chickenRepository.getProvince(cancelToken: _provincesCancelToken);
|
||||
final res = await chickenRepository.getProvince(
|
||||
cancelToken: _provincesCancelToken,
|
||||
);
|
||||
if (res != null) {
|
||||
provinces.clear();
|
||||
provinces.value = res;
|
||||
@@ -162,8 +177,9 @@ class StewardRootLogic extends GetxController {
|
||||
|
||||
Future<void> getRolesProducts() async {
|
||||
safeCall(
|
||||
call: () async =>
|
||||
await chickenRepository.getRolesProducts(token: tokenService.accessToken.value!),
|
||||
call: () async => await chickenRepository.getRolesProducts(
|
||||
token: tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
rolesProductsModel.value = result;
|
||||
@@ -190,8 +206,9 @@ class StewardRootLogic extends GetxController {
|
||||
|
||||
Future<void> getStewardRemainWeightData() async {
|
||||
safeCall(
|
||||
call: () async =>
|
||||
await chickenRepository.getStewardRemainWeight(token: tokenService.accessToken.value!),
|
||||
call: () async => await chickenRepository.getStewardRemainWeight(
|
||||
token: tokenService.accessToken.value!,
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null) {
|
||||
stewardRemainWeight.value = result;
|
||||
@@ -231,7 +248,8 @@ class StewardRootLogic extends GetxController {
|
||||
currentNestedKey?.currentState?.popUntil((route) => route.isFirst);
|
||||
} else {
|
||||
final now = DateTime.now();
|
||||
if (_lastBackPressed == null || now.difference(_lastBackPressed!) > Duration(seconds: 2)) {
|
||||
if (_lastBackPressed == null ||
|
||||
now.difference(_lastBackPressed!) > Duration(seconds: 2)) {
|
||||
_lastBackPressed = now;
|
||||
Get.snackbar(
|
||||
'خروج از برنامه',
|
||||
|
||||
@@ -4,7 +4,8 @@ import 'package:rasadyar_chicken/presentation/pages/steward/sales_in_province/wi
|
||||
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/steward/inventory_widget.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart';
|
||||
|
||||
import 'package:rasadyar_core/core.dart' hide modalDatePicker;
|
||||
|
||||
import 'logic.dart';
|
||||
@@ -27,7 +28,10 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
|
||||
Positioned.fill(
|
||||
child: Column(
|
||||
children: [
|
||||
inventoryWidget(controller.rootLogic),
|
||||
ObxValue((data) {
|
||||
return InventoryWidget(inventoryModel: data.value!);
|
||||
}, controller.rootLogic.inventoryModel),
|
||||
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
|
||||
@@ -9,7 +9,7 @@ import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/steward/inventory_widget.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
@@ -32,7 +32,9 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
Positioned.fill(
|
||||
child: Column(
|
||||
children: [
|
||||
inventoryWidget(controller.rootLogic),
|
||||
ObxValue((data) {
|
||||
return InventoryWidget(inventoryModel: data.value!);
|
||||
}, controller.rootLogic.inventoryModel),
|
||||
|
||||
ObxValue((data) {
|
||||
return RPaginatedListView(
|
||||
|
||||
@@ -25,6 +25,8 @@ import 'package:rasadyar_chicken/presentation/pages/poultry_science/poultry_acti
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/view.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/steward.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/kill_house/warehouse_and_distribution/warehouse_and_distribution.dart'
|
||||
as warehouse;
|
||||
import 'package:rasadyar_chicken/presentation/routes/global_binding.dart';
|
||||
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
|
||||
import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
|
||||
@@ -274,6 +276,145 @@ sealed class ChickenPages {
|
||||
}),
|
||||
],
|
||||
),
|
||||
|
||||
//region Warehouse and Distribution Pages
|
||||
GetPage(
|
||||
name: ChickenRoutes.initWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionRootPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
bindings: [
|
||||
GlobalBinding(),
|
||||
BindingsBuilder(() {
|
||||
Get.lazyPut(() => ChickenBaseLogic(), fenix: true);
|
||||
Get.lazyPut(() => warehouse.WarehouseAndDistributionRootLogic());
|
||||
Get.lazyPut(() => warehouse.WarehouseAndDistributionHomeLogic());
|
||||
Get.lazyPut(() => warehouse.WarehouseAndDistributionBuyLogic());
|
||||
Get.lazyPut(() => warehouse.WarehouseAndDistributionSaleLogic());
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionSegmentationLogic(),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
|
||||
GetPage(
|
||||
name: ChickenRoutes.homeWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionHomePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.put(warehouse.WarehouseAndDistributionHomeLogic());
|
||||
Get.lazyPut(() => ChickenBaseLogic());
|
||||
}),
|
||||
),
|
||||
|
||||
//sales
|
||||
GetPage(
|
||||
name: ChickenRoutes.saleWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionSalePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => warehouse.WarehouseAndDistributionSaleLogic());
|
||||
Get.lazyPut(() => ChickenBaseLogic());
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionSalesOutOfProvinceLogic(),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() =>
|
||||
warehouse.WarehouseAndDistributionSalesOutOfProvinceBuyersLogic(),
|
||||
);
|
||||
Get.lazyPut(() => warehouse.WarehouseAndDistributionRootLogic());
|
||||
}),
|
||||
),
|
||||
GetPage(
|
||||
name: ChickenRoutes.salesOutOfProvinceWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionSalesOutOfProvincePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionSalesOutOfProvinceLogic(),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() =>
|
||||
warehouse.WarehouseAndDistributionSalesOutOfProvinceBuyersLogic(),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() =>
|
||||
warehouse.WarehouseAndDistributionSalesOutOfProvinceSalesListLogic(),
|
||||
);
|
||||
}),
|
||||
),
|
||||
GetPage(
|
||||
name: ChickenRoutes.salesOutOfProvinceBuyerWarehouseAndDistribution,
|
||||
page: () =>
|
||||
warehouse.WarehouseAndDistributionSalesOutOfProvinceBuyersPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionSalesOutOfProvinceLogic(),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() =>
|
||||
warehouse.WarehouseAndDistributionSalesOutOfProvinceBuyersLogic(),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() =>
|
||||
warehouse.WarehouseAndDistributionSalesOutOfProvinceSalesListLogic(),
|
||||
);
|
||||
}),
|
||||
),
|
||||
GetPage(
|
||||
name: ChickenRoutes.salesInProvinceWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionSalesInProvincePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => ChickenBaseLogic());
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionSalesInProvinceLogic(),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
||||
//buy
|
||||
GetPage(
|
||||
name: ChickenRoutes.buyWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionBuyPage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => ChickenBaseLogic());
|
||||
Get.lazyPut(() => warehouse.WarehouseAndDistributionBuyLogic());
|
||||
}),
|
||||
),
|
||||
GetPage(
|
||||
name: ChickenRoutes.buysOutOfProvinceWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionBuyOutOfProvincePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => ChickenBaseLogic());
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionBuyOutOfProvinceLogic(),
|
||||
);
|
||||
}),
|
||||
),
|
||||
GetPage(
|
||||
name: ChickenRoutes.buysInProvinceWarehouseAndDistribution,
|
||||
page: () => warehouse.WarehouseAndDistributionBuyInProvincePage(),
|
||||
middlewares: [AuthMiddleware()],
|
||||
binding: BindingsBuilder(() {
|
||||
Get.lazyPut(() => ChickenBaseLogic());
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionBuyInProvinceLogic(),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionBuyInProvinceWaitingLogic(),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => warehouse.WarehouseAndDistributionBuyInProvinceAllLogic(),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
||||
//endregion
|
||||
|
||||
//endregion
|
||||
];
|
||||
}
|
||||
|
||||
@@ -50,5 +50,24 @@ sealed class ChickenRoutes {
|
||||
static const actionKillHouse = '$_killHouse/action';
|
||||
static const submitRequestKillHouse = '$actionKillHouse/submitRequest';
|
||||
|
||||
//region Warehouse and Distribution Routes
|
||||
static const _warehouseAndDistribution = '$_killHouse/warehouseAndDistribution';
|
||||
static const initWarehouseAndDistribution = '$_warehouseAndDistribution/';
|
||||
static const homeWarehouseAndDistribution = '$_warehouseAndDistribution/home';
|
||||
static const buyWarehouseAndDistribution = '$_warehouseAndDistribution/buy';
|
||||
static const saleWarehouseAndDistribution = '$_warehouseAndDistribution/sale';
|
||||
static const segmentationWarehouseAndDistribution = '$_warehouseAndDistribution/segmentation';
|
||||
|
||||
//buys
|
||||
static const buysOutOfProvinceWarehouseAndDistribution = '$buyWarehouseAndDistribution/buyOutOfProvince';
|
||||
static const buysInProvinceWarehouseAndDistribution = '$buyWarehouseAndDistribution/buyInProvince';
|
||||
|
||||
//sales
|
||||
static const salesInProvinceWarehouseAndDistribution = '$saleWarehouseAndDistribution/SalesInProvince';
|
||||
static const salesOutOfProvinceWarehouseAndDistribution = '$saleWarehouseAndDistribution/saleOutOfProvince';
|
||||
static const salesOutOfProvinceBuyerWarehouseAndDistribution = '$saleWarehouseAndDistribution/saleOutOfProvinceBuyer';
|
||||
|
||||
//endregion
|
||||
|
||||
//endregion
|
||||
}
|
||||
|
||||
@@ -14,5 +14,9 @@ const int poultryThirdKey = 107;
|
||||
|
||||
//region kill house Keys
|
||||
const int killHouseActionKey = 108;
|
||||
const int killHouseWarehouseAndDistributionBuyKey = 109;
|
||||
const int killHouseWarehouseAndDistributionSaleKey = 110;
|
||||
|
||||
|
||||
|
||||
//endregion
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
|
||||
|
||||
class InventoryWidget extends StatelessWidget {
|
||||
final InventoryModel? inventoryModel;
|
||||
|
||||
const InventoryWidget({super.key, required this.inventoryModel});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: Get.width,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.w),
|
||||
child: Row(
|
||||
spacing: 8.w,
|
||||
children: [
|
||||
_itemList(
|
||||
title: 'موجودی انبار',
|
||||
value: inventoryModel?.totalRemainWeight?.separatedByCommaFa,
|
||||
color: const Color(0xFFEAFBFC),
|
||||
),
|
||||
_itemList(
|
||||
title: 'مانده دولتی',
|
||||
value: inventoryModel
|
||||
?.totalGovernmentalRemainWeight
|
||||
?.separatedByCommaFa,
|
||||
color: const Color(0xFFF5ECEE),
|
||||
),
|
||||
_itemList(
|
||||
title: 'مانده آزاد',
|
||||
value: inventoryModel?.totalFreeRemainWeight?.separatedByCommaFa,
|
||||
color: const Color(0xFFF1E7FF),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _itemList({
|
||||
required String title,
|
||||
required String? value,
|
||||
String? unit,
|
||||
Color? color,
|
||||
}) {
|
||||
return Container(
|
||||
width: 125.w,
|
||||
height: 50.h,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: ShapeDecoration(
|
||||
color: color ?? Colors.white.withValues(alpha: 0.40),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: const Color(0xFF5B5B5B)),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
value == null || value.isEmpty
|
||||
? const Center(child: CupertinoActivityIndicator())
|
||||
: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.w),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: const Color(0xFF5B5B5B),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
unit ?? 'کیلوگرم',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan10.copyWith(
|
||||
color: const Color(0xFF5B5B5B),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/steward/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
Widget inventoryWidget(StewardRootLogic rootLogic) {
|
||||
return Container(
|
||||
width: Get.width,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.w),
|
||||
child: Row(
|
||||
spacing: 8.w,
|
||||
children: [
|
||||
ObxValue((data) {
|
||||
// بررسی مقدار null بودن و نشان دادن ActivityIndicator
|
||||
final value = data.value?.totalRemainWeight?.separatedByCommaFa;
|
||||
return _itemList(
|
||||
title: 'موجودی انبار',
|
||||
value: value ?? '', // در صورت نال بودن، رشته خالی نمایش داده شود
|
||||
color: const Color(0xFFEAFBFC),
|
||||
);
|
||||
}, rootLogic.inventoryModel),
|
||||
ObxValue((data) {
|
||||
final value = data.value?.totalGovernmentalRemainWeight?.separatedByCommaFa;
|
||||
return _itemList(title: 'مانده دولتی', value: value ?? '',color: const Color(0xFFF5ECEE),);
|
||||
}, rootLogic.stewardSalesInfoDashboard),
|
||||
ObxValue((data) {
|
||||
final value = data.value?.totalFreeRemainWeight?.separatedByCommaFa;
|
||||
return _itemList(title: 'مانده آزاد', value: value ?? '',color: const Color(0xFFF1E7FF));
|
||||
}, rootLogic.stewardSalesInfoDashboard),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _itemList({required String title, required String? value, String? unit,Color? color}) {
|
||||
return Container(
|
||||
width: 125.w,
|
||||
height: 50.h,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: ShapeDecoration(
|
||||
color: color??Colors.white.withValues(alpha: 0.40),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(color: const Color(0xFF5B5B5B)),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
value == null
|
||||
? Center(child: CupertinoActivityIndicator())
|
||||
: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.w),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan16.copyWith(color: const Color(0xFF5B5B5B)),
|
||||
),
|
||||
Text(
|
||||
unit ?? 'کیلوگرم',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan10.copyWith(color: const Color(0xFF5B5B5B)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -49,6 +49,7 @@ class DioRemote implements IHttpClient {
|
||||
@override
|
||||
Future<DioResponse<T>> get<T>(
|
||||
String path, {
|
||||
CancelToken? cancelToken,
|
||||
Map<String, dynamic>? queryParameters,
|
||||
Map<String, String>? headers,
|
||||
ProgressCallback? onReceiveProgress,
|
||||
@@ -61,7 +62,7 @@ class DioRemote implements IHttpClient {
|
||||
queryParameters: queryParameters,
|
||||
options: Options(headers: headers),
|
||||
onReceiveProgress: onReceiveProgress,
|
||||
cancelToken: ApiHandler.globalCancelToken,
|
||||
cancelToken: cancelToken ?? ApiHandler.globalCancelToken,
|
||||
);
|
||||
if (fromJsonListAsync != null && response.data is List) {
|
||||
response.data = await fromJsonListAsync(response.data);
|
||||
|
||||
@@ -21,7 +21,10 @@ class CardIcon extends StatelessWidget {
|
||||
this.iconWidth = 48,
|
||||
this.iconHeight = 48,
|
||||
this.iconColor,
|
||||
}) : assert((svgIcon != null) || (vecIcon != null), 'Either svgIcon or vecIcon must be provided');
|
||||
}) : assert(
|
||||
(svgIcon != null) || (vecIcon != null),
|
||||
'Either svgIcon or vecIcon must be provided',
|
||||
);
|
||||
|
||||
final String title;
|
||||
final int spacing;
|
||||
@@ -83,7 +86,12 @@ class CardIcon extends StatelessWidget {
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: titleStyle ?? AppFonts.yekan16Bold.copyWith(color: titleColor, height: 1.20),
|
||||
style:
|
||||
titleStyle ??
|
||||
AppFonts.yekan16Bold.copyWith(
|
||||
color: titleColor,
|
||||
height: 1.20,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -114,7 +122,10 @@ class GlassMorphismCardIcon extends StatelessWidget {
|
||||
this.iconHeight = 48,
|
||||
this.iconColor,
|
||||
this.gradient,
|
||||
}) : assert((svgIcon != null) || (vecIcon != null), 'Either svgIcon or vecIcon must be provided');
|
||||
}) : assert(
|
||||
(svgIcon != null) || (vecIcon != null),
|
||||
'Either svgIcon or vecIcon must be provided',
|
||||
);
|
||||
|
||||
final String title;
|
||||
final int spacing;
|
||||
@@ -174,7 +185,10 @@ class GlassMorphismCardIcon extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
style:
|
||||
titleStyle ??
|
||||
AppFonts.yekan18Bold.copyWith(color: titleColor, height: 1.20),
|
||||
AppFonts.yekan18Bold.copyWith(
|
||||
color: titleColor,
|
||||
height: 1.20,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -208,13 +222,19 @@ class GlassMorphismCardIcon extends StatelessWidget {
|
||||
fit: BoxFit.cover,
|
||||
width: iconWidth.w,
|
||||
height: iconHeight.h,
|
||||
colorFilter: ColorFilter.mode(iconColor ?? Colors.white, BlendMode.srcIn),
|
||||
colorFilter: ColorFilter.mode(
|
||||
iconColor ?? Colors.white,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
)
|
||||
: SvgGenImage.vec(vecIcon!).svg(
|
||||
fit: BoxFit.fill,
|
||||
width: iconWidth.w,
|
||||
height: iconHeight.h,
|
||||
colorFilter: ColorFilter.mode(iconColor ?? Colors.white, BlendMode.srcIn),
|
||||
colorFilter: ColorFilter.mode(
|
||||
iconColor ?? Colors.white,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -230,12 +250,22 @@ class GlassMorphismCardItem {
|
||||
final String title;
|
||||
final String route;
|
||||
final String icon;
|
||||
final int? navId;
|
||||
|
||||
GlassMorphismCardItem({required this.title, required this.route, required this.icon});
|
||||
GlassMorphismCardItem({
|
||||
required this.title,
|
||||
required this.route,
|
||||
required this.icon,
|
||||
this.navId,
|
||||
});
|
||||
}
|
||||
|
||||
class GlassMorphismGrid extends StatelessWidget {
|
||||
const GlassMorphismGrid({super.key, required this.items, required this.onTap});
|
||||
const GlassMorphismGrid({
|
||||
super.key,
|
||||
required this.items,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final List<GlassMorphismCardItem> items;
|
||||
final void Function(GlassMorphismCardItem item) onTap;
|
||||
|
||||
Reference in New Issue
Block a user