Browse Source

migrate to null safety

develop_migrate
Đại Võ 2 years ago
parent
commit
8bac13ecb8
100 changed files with 2261 additions and 2997 deletions
  1. +1
    -0
      .fvm/flutter_sdk
  2. +4
    -0
      .fvm/fvm_config.json
  3. +3
    -0
      .vscode/settings.json
  4. +2
    -2
      android/app/build.gradle
  5. +4
    -4
      lib/app.dart
  6. +6
    -13
      lib/authentication/bloc/authentication_bloc.dart
  7. +4
    -4
      lib/custom_model/ActionEnd.dart
  8. +91
    -94
      lib/custom_model/CropPlot.dart
  9. +33
    -33
      lib/custom_model/CropStatus.dart
  10. +17
    -17
      lib/custom_model/Device.dart
  11. +27
    -27
      lib/custom_model/Disease.dart
  12. +28
    -29
      lib/custom_model/Dung.dart
  13. +18
    -26
      lib/custom_model/End.dart
  14. +51
    -52
      lib/custom_model/Environment.dart
  15. +20
    -26
      lib/custom_model/EnvironmentParameter.dart
  16. +7
    -7
      lib/custom_model/ErrorCommon.dart
  17. +25
    -25
      lib/custom_model/Harvest.dart
  18. +32
    -33
      lib/custom_model/HarvestProcess.dart
  19. +6
    -6
      lib/custom_model/LocationUnit.dart
  20. +3
    -3
      lib/custom_model/Media.dart
  21. +32
    -41
      lib/custom_model/NotificationDTO.dart
  22. +15
    -21
      lib/custom_model/NotificationObjectDTO.dart
  23. +34
    -35
      lib/custom_model/Nursery.dart
  24. +13
    -13
      lib/custom_model/NurseryDetail.dart
  25. +19
    -19
      lib/custom_model/Other.dart
  26. +27
    -27
      lib/custom_model/Packing.dart
  27. +26
    -27
      lib/custom_model/Plant.dart
  28. +26
    -34
      lib/custom_model/RequestDisease.dart
  29. +22
    -28
      lib/custom_model/RequestEnvironment.dart
  30. +22
    -29
      lib/custom_model/RequestGeneralModel.dart
  31. +29
    -29
      lib/custom_model/Sell.dart
  32. +30
    -31
      lib/custom_model/Spraying.dart
  33. +25
    -25
      lib/custom_model/SuppliesUsing.dart
  34. +17
    -25
      lib/custom_model/Supply.dart
  35. +5
    -5
      lib/custom_model/UpdateNoti.dart
  36. +21
    -21
      lib/custom_model/UseWater.dart
  37. +5
    -5
      lib/custom_model/WaterType.dart
  38. +108
    -34
      lib/custom_model/account.dart
  39. +0
    -64
      lib/custom_model/account.g.dart
  40. +17
    -11
      lib/custom_model/password.dart
  41. +0
    -20
      lib/custom_model/password.g.dart
  42. +11
    -9
      lib/custom_model/user.dart
  43. +0
    -15
      lib/custom_model/user.g.dart
  44. +14
    -9
      lib/custom_model/user_request.dart
  45. +0
    -20
      lib/custom_model/user_request.g.dart
  46. +4
    -4
      lib/data/api/app_exception.dart
  47. +67
    -180
      lib/data/api/rest_client.g.dart
  48. +3
    -5
      lib/data/repository/authentication_repository.dart
  49. +25
    -55
      lib/data/repository/repository.dart
  50. +5
    -14
      lib/main.dart
  51. +17
    -11
      lib/models/ActionType.dart
  52. +0
    -21
      lib/models/ActionType.g.dart
  53. +76
    -25
      lib/models/Crop.dart
  54. +0
    -48
      lib/models/Crop.g.dart
  55. +4
    -4
      lib/models/PagedResult.dart
  56. +20
    -12
      lib/models/ResourceHelper.dart
  57. +0
    -23
      lib/models/ResourceHelper.g.dart
  58. +6
    -8
      lib/presentation/custom_widgets/app_bar_widget.dart
  59. +1
    -1
      lib/presentation/custom_widgets/bloc/media_helper_event.dart
  60. +3
    -3
      lib/presentation/custom_widgets/bloc/media_helper_state.dart
  61. +4
    -8
      lib/presentation/custom_widgets/bloc/widget_row_plot_info.dart
  62. +1
    -1
      lib/presentation/custom_widgets/bottom_loader.dart
  63. +20
    -28
      lib/presentation/custom_widgets/button_icon_widget.dart
  64. +6
    -8
      lib/presentation/custom_widgets/button_widget.dart
  65. +33
    -61
      lib/presentation/custom_widgets/camera_helper.dart
  66. +6
    -6
      lib/presentation/custom_widgets/hoz_list_view.dart
  67. +13
    -13
      lib/presentation/custom_widgets/shimmer_image.dart
  68. +10
    -16
      lib/presentation/custom_widgets/widget_field_time_picker.dart
  69. +3
    -3
      lib/presentation/custom_widgets/widget_loading.dart
  70. +64
    -84
      lib/presentation/custom_widgets/widget_media_picker.dart
  71. +5
    -5
      lib/presentation/custom_widgets/widget_rounded_rect_indicator.dart
  72. +3
    -6
      lib/presentation/custom_widgets/widget_search.dart
  73. +9
    -16
      lib/presentation/custom_widgets/widget_show_video.dart
  74. +7
    -11
      lib/presentation/custom_widgets/widget_text_field_description.dart
  75. +10
    -13
      lib/presentation/custom_widgets/widget_text_form_field.dart
  76. +4
    -4
      lib/presentation/custom_widgets/widget_toast.dart
  77. +8
    -12
      lib/presentation/custom_widgets/widget_utils.dart
  78. +7
    -7
      lib/presentation/screens/account/sc_account.dart
  79. +3
    -5
      lib/presentation/screens/actions/bloc/action_detail_bloc.dart
  80. +1
    -4
      lib/presentation/screens/actions/bloc/action_detail_event.dart
  81. +4
    -4
      lib/presentation/screens/actions/bloc/action_detail_state.dart
  82. +2
    -3
      lib/presentation/screens/actions/bloc_get_harvest.dart
  83. +5
    -5
      lib/presentation/screens/actions/controller/ChangeDevice.dart
  84. +1
    -1
      lib/presentation/screens/actions/controller/ChangeFieldInForm.dart
  85. +1
    -1
      lib/presentation/screens/actions/controller/ChangeFormButton.dart
  86. +3
    -3
      lib/presentation/screens/actions/controller/ChangeSupplyUsing.dart
  87. +2
    -2
      lib/presentation/screens/actions/controller/ChangeUnit.dart
  88. +88
    -110
      lib/presentation/screens/actions/crop_status/sc_edit_action_crop_status.dart
  89. +75
    -99
      lib/presentation/screens/actions/disease/sc_edit_action_disease.dart
  90. +62
    -97
      lib/presentation/screens/actions/dung/sc_edit_action_dung.dart
  91. +112
    -168
      lib/presentation/screens/actions/dung/widget_dung_supply.dart
  92. +44
    -66
      lib/presentation/screens/actions/end/sc_edit_action_end.dart
  93. +86
    -110
      lib/presentation/screens/actions/environment_update/sc_edit_action_environment_update.dart
  94. +69
    -89
      lib/presentation/screens/actions/harvest/sc_edit_action_harvest.dart
  95. +98
    -125
      lib/presentation/screens/actions/harvest_process/sc_edit_action_harvest_process.dart
  96. +113
    -172
      lib/presentation/screens/actions/harvest_process/widget_harvest_process_supply.dart
  97. +6
    -6
      lib/presentation/screens/actions/nursery/bloc/expansion_list_bloc.dart
  98. +3
    -3
      lib/presentation/screens/actions/nursery/bloc/expansion_list_event.dart
  99. +3
    -3
      lib/presentation/screens/actions/nursery/bloc/expansion_list_state.dart
  100. +136
    -207
      lib/presentation/screens/actions/nursery/sc_edit_action_nursery.dart

+ 1
- 0
.fvm/flutter_sdk View File

@@ -0,0 +1 @@
/Users/daivph/fvm/versions/3.0.5

+ 4
- 0
.fvm/fvm_config.json View File

@@ -0,0 +1,4 @@
{
"flutterSdkVersion": "3.0.5",
"flavors": {}
}

+ 3
- 0
.vscode/settings.json View File

@@ -0,0 +1,3 @@
{
"dart.flutterSdkPath": "/Users/daivph/fvm/versions/3.0.5"
}

+ 2
- 2
android/app/build.gradle View File

@@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) {
}

android {
compileSdkVersion 29
compileSdkVersion 33

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -46,7 +46,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "vn.azteam.tpfarm"
minSdkVersion 21
targetSdkVersion 29
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}

+ 4
- 4
lib/app.dart View File

@@ -12,8 +12,8 @@ import 'data/repository/authentication_repository.dart';

class App extends StatelessWidget {
const App({
Key key,
@required this.authenticationRepository,
Key? key,
required this.authenticationRepository,
}) : assert(authenticationRepository != null),
super(key: key);

@@ -25,7 +25,7 @@ class App extends StatelessWidget {
value: authenticationRepository,
child: BlocProvider(
create: (_) => AuthenticationBloc(
authenticationRepository: authenticationRepository,
repository: authenticationRepository,
),
child: AppView(),
),
@@ -41,7 +41,7 @@ class AppView extends StatefulWidget {
class _AppViewState extends State<AppView> {
final _navigatorKey = GlobalKey<NavigatorState>();

NavigatorState get _navigator => _navigatorKey.currentState;
NavigatorState get _navigator => _navigatorKey.currentState!;

@override
Widget build(BuildContext context) {

+ 6
- 13
lib/authentication/bloc/authentication_bloc.dart View File

@@ -8,20 +8,13 @@ import 'package:meta/meta.dart';
part 'authentication_event.dart';
part 'authentication_state.dart';

class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
AuthenticationBloc(
{@required AuthenticationRepository authenticationRepository})
: assert(authenticationRepository != null),
_authenticationRepository = authenticationRepository,
super(const AuthenticationState.unknown()) {
_authenticationStatusSubscription = _authenticationRepository.status.listen(
(status) => add(AuthenticationStatusChanged(status)),
);
}
class AuthenticationBloc extends Bloc<AuthenticationEvent, AuthenticationState> {
AuthenticationBloc({required AuthenticationRepository repository})
: _authenticationRepository = repository,
super(const AuthenticationState.unknown()) {}

final AuthenticationRepository _authenticationRepository;
StreamSubscription<AuthenticationStatus> _authenticationStatusSubscription;
StreamSubscription<AuthenticationStatus>? _authenticationStatusSubscription;

@override
Stream<AuthenticationState> mapEventToState(
@@ -48,7 +41,7 @@ class AuthenticationBloc
case AuthenticationStatus.unauthenticated:
return const AuthenticationState.unauthenticated();
case AuthenticationStatus.authenticated:
return AuthenticationState.authenticated();
return const AuthenticationState.authenticated();
default:
return const AuthenticationState.unknown();
}

+ 4
- 4
lib/custom_model/ActionEnd.dart View File

@@ -1,8 +1,8 @@
class ActionEnd {
int id;
int activityId;
String executeDate;
String description;
int? id;
int? activityId;
String? executeDate;
String? description;

ActionEnd({this.id, this.activityId, this.executeDate, this.description});


+ 91
- 94
lib/custom_model/CropPlot.dart View File

@@ -1,12 +1,12 @@
class CropPlot {
TbCropDTO tbCropDTO;
List<Activities> activities;
String sowingDate;
int soakSeedsTime;
int seedIncubationTime;
int numberPlants;
int numberCurrentPlants;
String endOfFarmingDate;
TbCropDTO? tbCropDTO;
List<Activities>? activities;
String? sowingDate;
int? soakSeedsTime;
int? seedIncubationTime;
int? numberPlants;
int? numberCurrentPlants;
String? endOfFarmingDate;

CropPlot(
{this.tbCropDTO,
@@ -19,13 +19,11 @@ class CropPlot {
this.endOfFarmingDate});

CropPlot.fromJson(Map<String, dynamic> json) {
tbCropDTO = json['tbCropDTO'] != null
? new TbCropDTO.fromJson(json['tbCropDTO'])
: null;
tbCropDTO = json['tbCropDTO'] != null ? TbCropDTO.fromJson(json['tbCropDTO']) : null;
if (json['activities'] != null) {
activities = new List<Activities>();
activities = <Activities>[];
json['activities'].forEach((v) {
activities.add(new Activities.fromJson(v));
activities?.add(Activities.fromJson(v));
});
}
sowingDate = json['sowingDate'];
@@ -37,42 +35,42 @@ class CropPlot {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.tbCropDTO != null) {
data['tbCropDTO'] = this.tbCropDTO.toJson();
final data = <String, dynamic>{};
if (tbCropDTO != null) {
data['tbCropDTO'] = tbCropDTO?.toJson();
}
if (this.activities != null) {
data['activities'] = this.activities.map((v) => v.toJson()).toList();
if (activities != null) {
data['activities'] = activities?.map((v) => v.toJson()).toList();
}
data['sowingDate'] = this.sowingDate;
data['soakSeedsTime'] = this.soakSeedsTime;
data['seedIncubationTime'] = this.seedIncubationTime;
data['numberPlants'] = this.numberPlants;
data['numberCurrentPlants'] = this.numberCurrentPlants;
data['endOfFarmingDate'] = this.endOfFarmingDate;
data['sowingDate'] = sowingDate;
data['soakSeedsTime'] = soakSeedsTime;
data['seedIncubationTime'] = seedIncubationTime;
data['numberPlants'] = numberPlants;
data['numberCurrentPlants'] = numberCurrentPlants;
data['endOfFarmingDate'] = endOfFarmingDate;
return data;
}
}

class TbCropDTO {
int id;
String qrCode;
String code;
num areaM2;
int type;
String startDate;
String endDate;
String status;
String description;
int ageDayStartAt;
int tbSuppliesId;
String suppliesName;
int tbGuidelineId;
int netHouseId;
String netHouseName;
int areaId;
String area;
List<TbDetailUsers> tbDetailUsers;
int? id;
String? qrCode;
String? code;
num? areaM2;
int? type;
String? startDate;
String? endDate;
String? status;
String? description;
int? ageDayStartAt;
int? tbSuppliesId;
String? suppliesName;
int? tbGuidelineId;
int? netHouseId;
String? netHouseName;
int? areaId;
String? area;
List<TbDetailUsers>? tbDetailUsers;

TbCropDTO(
{this.id,
@@ -113,44 +111,43 @@ class TbCropDTO {
areaId = json['areaId'];
area = json['area'];
if (json['tbDetailUsers'] != null) {
tbDetailUsers = new List<TbDetailUsers>();
tbDetailUsers = <TbDetailUsers>[];
json['tbDetailUsers'].forEach((v) {
tbDetailUsers.add(new TbDetailUsers.fromJson(v));
tbDetailUsers?.add(TbDetailUsers.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['qrCode'] = this.qrCode;
data['code'] = this.code;
data['areaM2'] = this.areaM2;
data['type'] = this.type;
data['startDate'] = this.startDate;
data['endDate'] = this.endDate;
data['status'] = this.status;
data['description'] = this.description;
data['ageDayStartAt'] = this.ageDayStartAt;
data['tbSuppliesId'] = this.tbSuppliesId;
data['suppliesName'] = this.suppliesName;
data['tbGuidelineId'] = this.tbGuidelineId;
data['netHouseId'] = this.netHouseId;
data['netHouseName'] = this.netHouseName;
data['areaId'] = this.areaId;
data['area'] = this.area;
if (this.tbDetailUsers != null) {
data['tbDetailUsers'] =
this.tbDetailUsers.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['qrCode'] = qrCode;
data['code'] = code;
data['areaM2'] = areaM2;
data['type'] = type;
data['startDate'] = startDate;
data['endDate'] = endDate;
data['status'] = status;
data['description'] = description;
data['ageDayStartAt'] = ageDayStartAt;
data['tbSuppliesId'] = tbSuppliesId;
data['suppliesName'] = suppliesName;
data['tbGuidelineId'] = tbGuidelineId;
data['netHouseId'] = netHouseId;
data['netHouseName'] = netHouseName;
data['areaId'] = areaId;
data['area'] = area;
if (tbDetailUsers != null) {
data['tbDetailUsers'] = tbDetailUsers?.map((v) => v.toJson()).toList();
}
return data;
}
}

class TbDetailUsers {
int id;
String fullName;
String phone;
int? id;
String? fullName;
String? phone;

TbDetailUsers({this.id, this.fullName, this.phone});

@@ -161,23 +158,23 @@ class TbDetailUsers {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['fullName'] = this.fullName;
data['phone'] = this.phone;
final data = <String, dynamic>{};
data['id'] = id;
data['fullName'] = fullName;
data['phone'] = phone;
return data;
}
}

class Activities {
int id;
int ageDay;
int cropId;
String executeDate;
String description;
int activityTypeId;
String activityTypeName;
String activityTypeDescription;
int? id;
int? ageDay;
int? cropId;
String? executeDate;
String? description;
int? activityTypeId;
String? activityTypeName;
String? activityTypeDescription;

Activities(
{this.id,
@@ -190,11 +187,11 @@ class Activities {
this.activityTypeDescription});

Activities.clone(Activities activities) {
this.id = activities.id;
this.cropId = activities.cropId;
this.activityTypeName = activities.activityTypeName;
this.activityTypeDescription = activities.activityTypeDescription;
this.executeDate = activities.executeDate;
id = activities.id;
cropId = activities.cropId;
activityTypeName = activities.activityTypeName;
activityTypeDescription = activities.activityTypeDescription;
executeDate = activities.executeDate;
}

Activities.fromJson(Map<String, dynamic> json) {
@@ -209,15 +206,15 @@ class Activities {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['ageDay'] = this.ageDay;
data['cropId'] = this.cropId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['activityTypeId'] = this.activityTypeId;
data['activityTypeName'] = this.activityTypeName;
data['activityTypeDescription'] = this.activityTypeDescription;
final data = <String, dynamic>{};
data['id'] = id;
data['ageDay'] = ageDay;
data['cropId'] = cropId;
data['executeDate'] = executeDate;
data['description'] = description;
data['activityTypeId'] = activityTypeId;
data['activityTypeName'] = activityTypeName;
data['activityTypeDescription'] = activityTypeDescription;
return data;
}
}

+ 33
- 33
lib/custom_model/CropStatus.dart View File

@@ -1,20 +1,20 @@
class CropStatus {
int id;
int cropId;
int activityId;
String executeDate;
String cropRate;
String numberOfTreeToGrow;
String heightOfTree;
String numberOfLeaf;
String leafSize;
String leafColor;
String abilityProduceBuds;
String internodeLength;
String description;
String executeBy;
String media;
List<String> mediaDel;
int? id;
int? cropId;
int? activityId;
String? executeDate;
String? cropRate;
String? numberOfTreeToGrow;
String? heightOfTree;
String? numberOfLeaf;
String? leafSize;
String? leafColor;
String? abilityProduceBuds;
String? internodeLength;
String? description;
String? executeBy;
String? media;
List<String>? mediaDel;

CropStatus(
{this.id,
@@ -53,23 +53,23 @@ class CropStatus {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['cropRate'] = this.cropRate;
data['numberOfTreeToGrow'] = this.numberOfTreeToGrow;
data['heightOfTree'] = this.heightOfTree;
data['numberOfLeaf'] = this.numberOfLeaf;
data['leafSize'] = this.leafSize;
data['leafColor'] = this.leafColor;
data['abilityProduceBuds'] = this.abilityProduceBuds;
data['internodeLength'] = this.internodeLength;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['executeDate'] = executeDate;
data['cropRate'] = cropRate;
data['numberOfTreeToGrow'] = numberOfTreeToGrow;
data['heightOfTree'] = heightOfTree;
data['numberOfLeaf'] = numberOfLeaf;
data['leafSize'] = leafSize;
data['leafColor'] = leafColor;
data['abilityProduceBuds'] = abilityProduceBuds;
data['internodeLength'] = internodeLength;
data['description'] = description;
data['executeBy'] = executeBy;
data['media'] = media;
data['media_del'] = mediaDel;
return data;
}
}

+ 17
- 17
lib/custom_model/Device.dart View File

@@ -1,19 +1,19 @@
class Device {
int id;
String name;
String status;
String location;
num mode;
bool isSelected;
int? id;
String? name;
String? status;
String? location;
num? mode;
bool? isSelected;

Device({this.id, this.name, this.status, this.location, this.mode});

Device.clone(Device device) {
this.id = device.id;
this.name = device.name;
this.status = device.status;
this.location = device.location;
this.mode = device.mode;
id = device.id;
name = device.name;
status = device.status;
location = device.location;
mode = device.mode;
}

Device.fromJson(Map<String, dynamic> json) {
@@ -26,12 +26,12 @@ class Device {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['status'] = this.status;
data['location'] = this.location;
data['mode'] = this.mode;
final data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['status'] = status;
data['location'] = location;
data['mode'] = mode;
return data;
}
}

+ 27
- 27
lib/custom_model/Disease.dart View File

@@ -1,17 +1,17 @@
class Disease {
int id;
int activityId;
int cropId;
String executeDate;
String media;
String typesOfPest;
String harmLevel;
String treePercent;
String location;
String naturalEnemy;
String treatmentMeasures;
String description;
String executeBy;
int? id;
int? activityId;
int? cropId;
String? executeDate;
String? media;
String? typesOfPest;
String? harmLevel;
String? treePercent;
String? location;
String? naturalEnemy;
String? treatmentMeasures;
String? description;
String? executeBy;

Disease(
{this.id,
@@ -45,20 +45,20 @@ class Disease {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['activityId'] = this.activityId;
data['cropId'] = this.cropId;
data['executeDate'] = this.executeDate;
data['media'] = this.media;
data['typesOfPest'] = this.typesOfPest;
data['harmLevel'] = this.harmLevel;
data['treePercent'] = this.treePercent;
data['location'] = this.location;
data['naturalEnemy'] = this.naturalEnemy;
data['treatmentMeasures'] = this.treatmentMeasures;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
final data = <String, dynamic>{};
data['id'] = id;
data['activityId'] = activityId;
data['cropId'] = cropId;
data['executeDate'] = executeDate;
data['media'] = media;
data['typesOfPest'] = typesOfPest;
data['harmLevel'] = harmLevel;
data['treePercent'] = treePercent;
data['location'] = location;
data['naturalEnemy'] = naturalEnemy;
data['treatmentMeasures'] = treatmentMeasures;
data['description'] = description;
data['executeBy'] = executeBy;
return data;
}
}

+ 28
- 29
lib/custom_model/Dung.dart View File

@@ -1,18 +1,18 @@
import 'SuppliesUsing.dart';

class Dung {
int id;
int activityId;
int cropId;
String executeDate;
String description;
String media;
num quarantinePeriod;
String weatherConditions;
String purpose;
String executeBy;
List<String> mediaDel;
List<SuppliesUsing> suppliesUsing;
int? id;
int? activityId;
int? cropId;
String? executeDate;
String? description;
String? media;
num? quarantinePeriod;
String? weatherConditions;
String? purpose;
String? executeBy;
List<String>? mediaDel;
List<SuppliesUsing>? suppliesUsing;

Dung(
{this.id,
@@ -40,29 +40,28 @@ class Dung {
purpose = json['purpose'];
executeBy = json['executeBy'];
if (json['suppliesUsing'] != null) {
suppliesUsing = new List<SuppliesUsing>();
suppliesUsing = <SuppliesUsing>[];
json['suppliesUsing'].forEach((v) {
suppliesUsing.add(new SuppliesUsing.fromJson(v));
suppliesUsing?.add(SuppliesUsing.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['media'] = this.media;
data['quarantinePeriod'] = this.quarantinePeriod;
data['weatherConditions'] = this.weatherConditions;
data['purpose'] = this.purpose;
data['executeBy'] = this.executeBy;
data['media_del'] = this.mediaDel;
if (this.suppliesUsing != null) {
data['suppliesUsing'] =
this.suppliesUsing.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['executeDate'] = executeDate;
data['description'] = description;
data['media'] = media;
data['quarantinePeriod'] = quarantinePeriod;
data['weatherConditions'] = weatherConditions;
data['purpose'] = purpose;
data['executeBy'] = executeBy;
data['media_del'] = mediaDel;
if (suppliesUsing != null) {
data['suppliesUsing'] = suppliesUsing?.map((v) => v.toJson()).toList();
}
return data;
}

+ 18
- 26
lib/custom_model/End.dart View File

@@ -1,22 +1,14 @@
class End {
int id;
int cropId;
int activityId;
String executeDate;
String description;
String createdByName;
List<String> mediaDel;
String media;
int? id;
int? cropId;
int? activityId;
String? executeDate;
String? description;
String? createdByName;
List<String>? mediaDel;
String? media;

End(
{this.id,
this.cropId,
this.activityId,
this.executeDate,
this.description,
this.createdByName,
this.mediaDel,
this.media});
End({this.id, this.cropId, this.activityId, this.executeDate, this.description, this.createdByName, this.mediaDel, this.media});

End.fromJson(Map<String, dynamic> json) {
id = json['id'];
@@ -29,15 +21,15 @@ class End {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['createdByName'] = this.createdByName;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['executeDate'] = executeDate;
data['description'] = description;
data['createdByName'] = createdByName;
data['media'] = media;
data['media_del'] = mediaDel;
return data;
}
}

+ 51
- 52
lib/custom_model/Environment.dart View File

@@ -1,18 +1,18 @@
class Environment {
int id;
int activityId;
int cropId;
String executeDate;
String media;
String description;
String executeBy;
String pH;
String ec;
String ocdd;
String temperature;
String dodo;
String lln;
List<EnvironmentUpdates> environmentUpdates;
int? id;
int? activityId;
int? cropId;
String? executeDate;
String? media;
String? description;
String? executeBy;
String? pH;
String? ec;
String? ocdd;
String? temperature;
String? dodo;
String? lln;
List<EnvironmentUpdates>? environmentUpdates;

Environment(
{this.id,
@@ -45,46 +45,45 @@ class Environment {
dodo = json['dodo'];
lln = json['lln'];
if (json['environmentUpdates'] != null) {
environmentUpdates = new List<EnvironmentUpdates>();
environmentUpdates = <EnvironmentUpdates>[];
json['environmentUpdates'].forEach((v) {
environmentUpdates.add(new EnvironmentUpdates.fromJson(v));
environmentUpdates?.add(EnvironmentUpdates.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['activityId'] = this.activityId;
data['cropId'] = this.cropId;
data['executeDate'] = this.executeDate;
data['media'] = this.media;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['pH'] = this.pH;
data['ec'] = this.ec;
data['ocdd'] = this.ocdd;
data['temperature'] = this.temperature;
data['dodo'] = this.dodo;
data['lln'] = this.lln;
if (this.environmentUpdates != null) {
data['environmentUpdates'] =
this.environmentUpdates.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['activityId'] = activityId;
data['cropId'] = cropId;
data['executeDate'] = executeDate;
data['media'] = media;
data['description'] = description;
data['executeBy'] = executeBy;
data['pH'] = pH;
data['ec'] = ec;
data['ocdd'] = ocdd;
data['temperature'] = temperature;
data['dodo'] = dodo;
data['lln'] = lln;
if (environmentUpdates != null) {
data['environmentUpdates'] = environmentUpdates?.map((v) => v.toJson()).toList();
}
return data;
}
}

class EnvironmentUpdates {
int id;
num index;
num times;
int tbEnvironmentalId;
String tbEnvironmentalName;
String tbEnvironmentalUnit;
String tbEnvironmentalDescription;
int tbActivityId;
num tbEquipmentOfCustomerId;
int? id;
num? index;
num? times;
int? tbEnvironmentalId;
String? tbEnvironmentalName;
String? tbEnvironmentalUnit;
String? tbEnvironmentalDescription;
int? tbActivityId;
num? tbEquipmentOfCustomerId;

EnvironmentUpdates(
{this.id,
@@ -110,16 +109,16 @@ class EnvironmentUpdates {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['index'] = this.index;
data['times'] = this.times;
data['tbEnvironmentalId'] = this.tbEnvironmentalId;
data['tbEnvironmentalName'] = this.tbEnvironmentalName;
data['tbEnvironmentalUnit'] = this.tbEnvironmentalUnit;
data['tbEnvironmentalDescription'] = this.tbEnvironmentalDescription;
data['tbActivityId'] = this.tbActivityId;
data['tbEquipmentOfCustomerId'] = this.tbEquipmentOfCustomerId;
final data = <String, dynamic>{};
data['id'] = id;
data['index'] = index;
data['times'] = times;
data['tbEnvironmentalId'] = tbEnvironmentalId;
data['tbEnvironmentalName'] = tbEnvironmentalName;
data['tbEnvironmentalUnit'] = tbEnvironmentalUnit;
data['tbEnvironmentalDescription'] = tbEnvironmentalDescription;
data['tbActivityId'] = tbActivityId;
data['tbEquipmentOfCustomerId'] = tbEquipmentOfCustomerId;
return data;
}
}

+ 20
- 26
lib/custom_model/EnvironmentParameter.dart View File

@@ -1,26 +1,20 @@
class EnvironmentParameter {
int id;
String name;
num index;
int activityId;
String executeDate;
bool status;
int? id;
String? name;
num? index;
int? activityId;
String? executeDate;
bool? status;

EnvironmentParameter(
{this.id,
this.name,
this.index,
this.activityId,
this.executeDate,
this.status});
EnvironmentParameter({this.id, this.name, this.index, this.activityId, this.executeDate, this.status});

EnvironmentParameter.clone(EnvironmentParameter e) {
this.id = e.id;
this.name = e.name;
this.index = e.index;
this.activityId = e.activityId;
this.executeDate = e.executeDate;
this.status = e.status;
id = e.id;
name = e.name;
index = e.index;
activityId = e.activityId;
executeDate = e.executeDate;
status = e.status;
}

EnvironmentParameter.fromJson(Map<String, dynamic> json) {
@@ -33,13 +27,13 @@ class EnvironmentParameter {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['index'] = this.index;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['status'] = this.status;
final data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['index'] = index;
data['activityId'] = activityId;
data['executeDate'] = executeDate;
data['status'] = status;
return data;
}
}

+ 7
- 7
lib/custom_model/ErrorCommon.dart View File

@@ -1,7 +1,7 @@
class ErrorCommon {
String entityName;
String errorKey;
int status;
String? entityName;
String? errorKey;
int? status;

ErrorCommon({this.entityName, this.errorKey, this.status});

@@ -12,10 +12,10 @@ class ErrorCommon {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['entityName'] = this.entityName;
data['errorKey'] = this.errorKey;
data['status'] = this.status;
final data = <String, dynamic>{};
data['entityName'] = entityName;
data['errorKey'] = errorKey;
data['status'] = status;
return data;
}
}

+ 25
- 25
lib/custom_model/Harvest.dart View File

@@ -1,16 +1,16 @@
class Harvest {
int id;
int cropId;
int activityId;
String executeDate;
String description;
String executeBy;
String media;
List<String> mediaDel;
num collectedQuantityLv1;
num collectedQuantityLv2;
num collectedQuantityLv3;
num removedQuantity;
int? id;
int? cropId;
int? activityId;
String? executeDate;
String? description;
String? executeBy;
String? media;
List<String>? mediaDel;
num? collectedQuantityLv1;
num? collectedQuantityLv2;
num? collectedQuantityLv3;
num? removedQuantity;

Harvest(
{this.id,
@@ -41,19 +41,19 @@ class Harvest {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['collectedQuantityLv1'] = this.collectedQuantityLv1;
data['collectedQuantityLv2'] = this.collectedQuantityLv2;
data['collectedQuantityLv3'] = this.collectedQuantityLv3;
data['removedQuantity'] = this.removedQuantity;
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['executeDate'] = executeDate;
data['description'] = description;
data['executeBy'] = executeBy;
data['media'] = media;
data['media_del'] = mediaDel;
data['collectedQuantityLv1'] = collectedQuantityLv1;
data['collectedQuantityLv2'] = collectedQuantityLv2;
data['collectedQuantityLv3'] = collectedQuantityLv3;
data['removedQuantity'] = removedQuantity;
return data;
}
}

+ 32
- 33
lib/custom_model/HarvestProcess.dart View File

@@ -1,20 +1,20 @@
import 'SuppliesUsing.dart';

class HarvestProcess {
int id;
int cropId;
int activityId;
int harvestId;
String executeDate;
String description;
String executeBy;
String media;
List<String> mediaDel;
num quantityLv1;
num quantityLv2;
num quantityLv3;
num removedQuantity;
List<SuppliesUsing> suppliesUsing;
int? id;
int? cropId;
int? activityId;
int? harvestId;
String? executeDate;
String? description;
String? executeBy;
String? media;
List<String>? mediaDel;
num? quantityLv1;
num? quantityLv2;
num? quantityLv3;
num? removedQuantity;
List<SuppliesUsing>? suppliesUsing;

HarvestProcess(
{this.id,
@@ -46,31 +46,30 @@ class HarvestProcess {
quantityLv3 = json['quantityLv3'];
removedQuantity = json['removedQuantity'];
if (json['suppliesUsing'] != null) {
suppliesUsing = new List<SuppliesUsing>();
suppliesUsing = <SuppliesUsing>[];
json['suppliesUsing'].forEach((v) {
suppliesUsing.add(new SuppliesUsing.fromJson(v));
suppliesUsing?.add(SuppliesUsing.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['harvestId'] = this.harvestId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['quantityLv1'] = this.quantityLv1;
data['quantityLv2'] = this.quantityLv2;
data['quantityLv3'] = this.quantityLv3;
data['removedQuantity'] = this.removedQuantity;
if (this.suppliesUsing != null) {
data['suppliesUsing'] =
this.suppliesUsing.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['harvestId'] = harvestId;
data['executeDate'] = executeDate;
data['description'] = description;
data['executeBy'] = executeBy;
data['media'] = media;
data['media_del'] = mediaDel;
data['quantityLv1'] = quantityLv1;
data['quantityLv2'] = quantityLv2;
data['quantityLv3'] = quantityLv3;
data['removedQuantity'] = removedQuantity;
if (suppliesUsing != null) {
data['suppliesUsing'] = suppliesUsing?.map((v) => v.toJson()).toList();
}
return data;
}

+ 6
- 6
lib/custom_model/LocationUnit.dart View File

@@ -1,7 +1,7 @@
class LocationUnit {
int id;
String name;
bool isSelected;
int? id;
String? name;
bool? isSelected;

LocationUnit({this.id, this.name});

@@ -12,9 +12,9 @@ class LocationUnit {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
final data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
return data;
}
}

+ 3
- 3
lib/custom_model/Media.dart View File

@@ -1,5 +1,5 @@
class Media {
String pathFile;
bool isVideo;
bool isServerFile = false;
String? pathFile;
bool? isVideo;
bool? isServerFile = false;
}

+ 32
- 41
lib/custom_model/NotificationDTO.dart View File

@@ -1,37 +1,28 @@
class NotificationDTO {
int id;
String subject;
String message;
int tbCropId;
int tbEntityId;
String contents;
String createdDate;
String sendDate;
int isRead;
String type;
int? id;
String? subject;
String? message;
int? tbCropId;
int? tbEntityId;
String? contents;
String? createdDate;
String? sendDate;
int? isRead;
String? type;

NotificationDTO(
{this.id,
this.subject,
this.message,
this.tbCropId,
this.tbEntityId,
this.contents,
this.createdDate,
this.sendDate,
this.type,
this.isRead});
{this.id, this.subject, this.message, this.tbCropId, this.tbEntityId, this.contents, this.createdDate, this.sendDate, this.type, this.isRead});
NotificationDTO.clone(NotificationDTO noti) {
this.id = noti.id;
this.contents = noti.contents;
this.tbCropId = noti.tbCropId;
this.tbEntityId = noti.tbEntityId;
this.subject = noti.subject;
this.message = noti.message;
this.createdDate = noti.createdDate;
this.sendDate = noti.sendDate;
this.type = noti.type;
this.isRead = noti.isRead;
id = noti.id;
contents = noti.contents;
tbCropId = noti.tbCropId;
tbEntityId = noti.tbEntityId;
subject = noti.subject;
message = noti.message;
createdDate = noti.createdDate;
sendDate = noti.sendDate;
type = noti.type;
isRead = noti.isRead;
}
NotificationDTO.fromJson(Map<String, dynamic> json) {
id = json['id'];
@@ -47,17 +38,17 @@ class NotificationDTO {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['subject'] = this.subject;
data['message'] = this.message;
data['tbCropId'] = this.tbCropId;
data['tbEntityId'] = this.tbEntityId;
data['contents'] = this.contents;
data['createdDate'] = this.createdDate;
data['sendDate'] = this.sendDate;
data['type'] = this.type;
data['isRead'] = this.isRead;
final data = <String, dynamic>{};
data['id'] = id;
data['subject'] = subject;
data['message'] = message;
data['tbCropId'] = tbCropId;
data['tbEntityId'] = tbEntityId;
data['contents'] = contents;
data['createdDate'] = createdDate;
data['sendDate'] = sendDate;
data['type'] = type;
data['isRead'] = isRead;
return data;
}
}

+ 15
- 21
lib/custom_model/NotificationObjectDTO.dart View File

@@ -1,18 +1,13 @@
import 'NotificationDTO.dart';

class NotificationObjectDTO {
int numberUnreadPage;
int numberReadPage;
int numberUnreadTotal;
int numberReadTotal;
List<NotificationDTO> notificationDTO;
int? numberUnreadPage;
int? numberReadPage;
int? numberUnreadTotal;
int? numberReadTotal;
List<NotificationDTO>? notificationDTO;

NotificationObjectDTO(
{this.numberUnreadPage,
this.numberReadPage,
this.numberUnreadTotal,
this.numberReadTotal,
this.notificationDTO});
NotificationObjectDTO({this.numberUnreadPage, this.numberReadPage, this.numberUnreadTotal, this.numberReadTotal, this.notificationDTO});

NotificationObjectDTO.fromJson(Map<String, dynamic> json) {
numberUnreadPage = json['numberUnreadPage'];
@@ -20,22 +15,21 @@ class NotificationObjectDTO {
numberUnreadTotal = json['numberUnreadTotal'];
numberReadTotal = json['numberReadTotal'];
if (json['tbnotificationDTOs'] != null) {
notificationDTO = new List<NotificationDTO>();
notificationDTO = <NotificationDTO>[];
json['tbnotificationDTOs'].forEach((v) {
notificationDTO.add(new NotificationDTO.fromJson(v));
notificationDTO?.add(NotificationDTO.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['numberUnreadPage'] = this.numberUnreadPage;
data['numberReadPage'] = this.numberReadPage;
data['numberUnreadTotal'] = this.numberUnreadTotal;
data['numberReadTotal'] = this.numberReadTotal;
if (this.notificationDTO != null) {
data['tbnotificationDTOs'] =
this.notificationDTO.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['numberUnreadPage'] = numberUnreadPage;
data['numberReadPage'] = numberReadPage;
data['numberUnreadTotal'] = numberUnreadTotal;
data['numberReadTotal'] = numberReadTotal;
if (notificationDTO != null) {
data['tbnotificationDTOs'] = notificationDTO?.map((v) => v.toJson()).toList();
}
return data;
}

+ 34
- 35
lib/custom_model/Nursery.dart View File

@@ -1,21 +1,21 @@
import 'NurseryDetail.dart';

class Nursery {
int id;
int activityId;
int cropId;
String executeDate;
String description;
String executeBy;
String media;
List<String> mediaDel;
String seedName;
num substratesId;
String substrateName;
num seedLength;
num quantity;
num seedIncubationTime;
List<NurseryDetail> nurseryDetail;
int? id;
int? activityId;
int? cropId;
String? executeDate;
String? description;
String? executeBy;
String? media;
List<String>? mediaDel;
String? seedName;
num? substratesId;
String? substrateName;
num? seedLength;
num? quantity;
num? seedIncubationTime;
List<NurseryDetail>? nurseryDetail;

Nursery(
{this.id,
@@ -49,32 +49,31 @@ class Nursery {
quantity = json['quantity'];
seedIncubationTime = json['seedIncubationTime'];
if (json['nurseryDetail'] != null) {
nurseryDetail = new List<NurseryDetail>();
nurseryDetail = <NurseryDetail>[];
json['nurseryDetail'].forEach((v) {
nurseryDetail.add(new NurseryDetail.fromJson(v));
nurseryDetail?.add(NurseryDetail.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['activityId'] = this.activityId;
data['cropId'] = this.cropId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['seedName'] = this.seedName;
data['substratesId'] = this.substratesId;
data['substrateName'] = this.substrateName;
data['seedLength'] = this.seedLength;
data['quantity'] = this.quantity;
data['seedIncubationTime'] = this.seedIncubationTime;
if (this.nurseryDetail != null) {
data['nurseryDetail'] =
this.nurseryDetail.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['activityId'] = activityId;
data['cropId'] = cropId;
data['executeDate'] = executeDate;
data['description'] = description;
data['executeBy'] = executeBy;
data['media'] = media;
data['media_del'] = mediaDel;
data['seedName'] = seedName;
data['substratesId'] = substratesId;
data['substrateName'] = substrateName;
data['seedLength'] = seedLength;
data['quantity'] = quantity;
data['seedIncubationTime'] = seedIncubationTime;
if (nurseryDetail != null) {
data['nurseryDetail'] = nurseryDetail?.map((v) => v.toJson()).toList();
}
return data;
}

+ 13
- 13
lib/custom_model/NurseryDetail.dart View File

@@ -1,16 +1,16 @@
class NurseryDetail {
int id;
String workerName;
String trayNumber;
int tbNurseryId;
int? id;
String? workerName;
String? trayNumber;
int? tbNurseryId;

NurseryDetail({this.id, this.workerName, this.trayNumber, this.tbNurseryId});

NurseryDetail.clone(NurseryDetail nurseryDetail) {
this.id = nurseryDetail.id;
this.workerName = nurseryDetail.workerName;
this.trayNumber = nurseryDetail.trayNumber;
this.tbNurseryId = nurseryDetail.tbNurseryId;
id = nurseryDetail.id;
workerName = nurseryDetail.workerName;
trayNumber = nurseryDetail.trayNumber;
tbNurseryId = nurseryDetail.tbNurseryId;
}

NurseryDetail.fromJson(Map<String, dynamic> json) {
@@ -21,11 +21,11 @@ class NurseryDetail {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['workerName'] = this.workerName;
data['trayNumber'] = this.trayNumber;
data['tbNurseryId'] = this.tbNurseryId;
final data = <String, dynamic>{};
data['id'] = id;
data['workerName'] = workerName;
data['trayNumber'] = trayNumber;
data['tbNurseryId'] = tbNurseryId;
return data;
}
}

+ 19
- 19
lib/custom_model/Other.dart View File

@@ -1,13 +1,13 @@
class Other {
int id;
int cropId;
int activityId;
String media;
List<String> mediaDel;
String executeDate;
String description;
String createdByName;
String activityTypeName;
int? id;
int? cropId;
int? activityId;
String? media;
List<String>? mediaDel;
String? executeDate;
String? description;
String? createdByName;
String? activityTypeName;

Other(
{this.id,
@@ -32,16 +32,16 @@ class Other {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['createdByName'] = this.createdByName;
data['activityTypeName'] = this.activityTypeName;
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['media'] = media;
data['media_del'] = mediaDel;
data['executeDate'] = executeDate;
data['description'] = description;
data['createdByName'] = createdByName;
data['activityTypeName'] = activityTypeName;
return data;
}
}

+ 27
- 27
lib/custom_model/Packing.dart View File

@@ -1,17 +1,17 @@
class Packing {
int id;
int cropId;
int activityId;
int harvestId;
String executeDate;
String description;
String executeBy;
String media;
List<String> mediaDel;
num quantityLv1;
num quantityLv2;
num quantityLv3;
num removedQuantity;
int? id;
int? cropId;
int? activityId;
int? harvestId;
String? executeDate;
String? description;
String? executeBy;
String? media;
List<String>? mediaDel;
num? quantityLv1;
num? quantityLv2;
num? quantityLv3;
num? removedQuantity;

Packing(
{this.id,
@@ -44,20 +44,20 @@ class Packing {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['harvestId'] = this.harvestId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['quantityLv1'] = this.quantityLv1;
data['quantityLv2'] = this.quantityLv2;
data['quantityLv3'] = this.quantityLv3;
data['removedQuantity'] = this.removedQuantity;
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['harvestId'] = harvestId;
data['executeDate'] = executeDate;
data['description'] = description;
data['executeBy'] = executeBy;
data['media'] = media;
data['media_del'] = mediaDel;
data['quantityLv1'] = quantityLv1;
data['quantityLv2'] = quantityLv2;
data['quantityLv3'] = quantityLv3;
data['removedQuantity'] = removedQuantity;
return data;
}
}

+ 26
- 27
lib/custom_model/Plant.dart View File

@@ -1,17 +1,17 @@
import 'SuppliesUsing.dart';

class Plant {
int id;
int cropId;
int activityId;
String executeDate;
String description;
String executeBy;
String density;
num quantity;
String media;
List<String> mediaDel;
List<SuppliesUsing> suppliesUsing;
int? id;
int? cropId;
int? activityId;
String? executeDate;
String? description;
String? executeBy;
String? density;
num? quantity;
String? media;
List<String>? mediaDel;
List<SuppliesUsing>? suppliesUsing;

Plant(
{this.id,
@@ -37,28 +37,27 @@ class Plant {
quantity = json['quantity'];
media = json['media'];
if (json['suppliesUsing'] != null) {
suppliesUsing = new List<SuppliesUsing>();
suppliesUsing = <SuppliesUsing>[];
json['suppliesUsing'].forEach((v) {
suppliesUsing.add(new SuppliesUsing.fromJson(v));
suppliesUsing?.add(SuppliesUsing.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['activityId'] = this.activityId;
data['cropId'] = this.cropId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['density'] = this.density;
data['quantity'] = this.quantity;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
if (this.suppliesUsing != null) {
data['suppliesUsing'] =
this.suppliesUsing.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['activityId'] = activityId;
data['cropId'] = cropId;
data['executeDate'] = executeDate;
data['description'] = description;
data['executeBy'] = executeBy;
data['density'] = density;
data['quantity'] = quantity;
data['media'] = media;
data['media_del'] = mediaDel;
if (suppliesUsing != null) {
data['suppliesUsing'] = suppliesUsing?.map((v) => v.toJson()).toList();
}
return data;
}

+ 26
- 34
lib/custom_model/RequestDisease.dart View File

@@ -1,20 +1,13 @@
class RequestDisease {
int id;
int activityId;
int cropId;
String executeDate;
String description;
List<String> mediaDel;
List<ObjectUpdateDetail> objectUpdateDetail;
int? id;
int? activityId;
int? cropId;
String? executeDate;
String? description;
List<String>? mediaDel;
List<ObjectUpdateDetail>? objectUpdateDetail;

RequestDisease(
{this.id,
this.activityId,
this.cropId,
this.executeDate,
this.description,
this.mediaDel,
this.objectUpdateDetail});
RequestDisease({this.id, this.activityId, this.cropId, this.executeDate, this.description, this.mediaDel, this.objectUpdateDetail});

RequestDisease.fromJson(Map<String, dynamic> json) {
id = json['id'];
@@ -23,33 +16,32 @@ class RequestDisease {
executeDate = json['executeDate'];
description = json['description'];
if (json['objectUpdateDetail'] != null) {
objectUpdateDetail = new List<ObjectUpdateDetail>();
objectUpdateDetail = <ObjectUpdateDetail>[];
json['objectUpdateDetail'].forEach((v) {
objectUpdateDetail.add(new ObjectUpdateDetail.fromJson(v));
objectUpdateDetail?.add(ObjectUpdateDetail.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['media_del'] = this.mediaDel;
if (this.objectUpdateDetail != null) {
data['objectUpdateDetail'] =
this.objectUpdateDetail.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['executeDate'] = executeDate;
data['description'] = description;
data['media_del'] = mediaDel;
if (objectUpdateDetail != null) {
data['objectUpdateDetail'] = objectUpdateDetail?.map((v) => v.toJson()).toList();
}
return data;
}
}

class ObjectUpdateDetail {
int id;
String name;
String index;
int? id;
String? name;
String? index;

ObjectUpdateDetail({this.id, this.name, this.index});

@@ -60,10 +52,10 @@ class ObjectUpdateDetail {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['index'] = this.index;
final data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['index'] = index;
return data;
}
}

+ 22
- 28
lib/custom_model/RequestEnvironment.dart View File

@@ -1,18 +1,12 @@
class RequestEnvironment {
int activityId;
int cropId;
String executeDate;
String description;
List<String> mediaDel;
List<EnvDetail> envDetail;
int? activityId;
int? cropId;
String? executeDate;
String? description;
List<String>? mediaDel;
List<EnvDetail>? envDetail;

RequestEnvironment(
{this.activityId,
this.cropId,
this.executeDate,
this.description,
this.mediaDel,
this.envDetail});
RequestEnvironment({this.activityId, this.cropId, this.executeDate, this.description, this.mediaDel, this.envDetail});

RequestEnvironment.fromJson(Map<String, dynamic> json) {
activityId = json['activityId'];
@@ -20,30 +14,30 @@ class RequestEnvironment {
executeDate = json['executeDate'];
description = json['description'];
if (json['envDetail'] != null) {
envDetail = new List<EnvDetail>();
envDetail = <EnvDetail>[];
json['envDetail'].forEach((v) {
envDetail.add(new EnvDetail.fromJson(v));
envDetail?.add(EnvDetail.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['activityId'] = this.activityId;
data['cropId'] = this.cropId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['media_del'] = this.mediaDel;
if (this.envDetail != null) {
data['envDetail'] = this.envDetail.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['activityId'] = activityId;
data['cropId'] = cropId;
data['executeDate'] = executeDate;
data['description'] = description;
data['media_del'] = mediaDel;
if (envDetail != null) {
data['envDetail'] = envDetail?.map((v) => v.toJson()).toList();
}
return data;
}
}

class EnvDetail {
String name;
String index;
String? name;
String? index;

EnvDetail({this.name, this.index});

@@ -53,9 +47,9 @@ class EnvDetail {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['index'] = this.index;
final data = <String, dynamic>{};
data['name'] = name;
data['index'] = index;
return data;
}
}

+ 22
- 29
lib/custom_model/RequestGeneralModel.dart View File

@@ -1,18 +1,12 @@
class RequestGeneralModel {
int cropId;
int activityId;
String executeDate;
String description;
List<String> mediaDel;
List<ObjectUpdateDetail> objectUpdateDetail;
int? cropId;
int? activityId;
String? executeDate;
String? description;
List<String>? mediaDel;
List<ObjectUpdateDetail>? objectUpdateDetail;

RequestGeneralModel(
{this.cropId,
this.activityId,
this.executeDate,
this.description,
this.mediaDel,
this.objectUpdateDetail});
RequestGeneralModel({this.cropId, this.activityId, this.executeDate, this.description, this.mediaDel, this.objectUpdateDetail});

RequestGeneralModel.fromJson(Map<String, dynamic> json) {
cropId = json['cropId'];
@@ -20,31 +14,30 @@ class RequestGeneralModel {
executeDate = json['executeDate'];
description = json['description'];
if (json['objectUpdateDetail'] != null) {
objectUpdateDetail = new List<ObjectUpdateDetail>();
objectUpdateDetail = <ObjectUpdateDetail>[];
json['objectUpdateDetail'].forEach((v) {
objectUpdateDetail.add(new ObjectUpdateDetail.fromJson(v));
objectUpdateDetail?.add(ObjectUpdateDetail.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['media_del'] = this.mediaDel;
if (this.objectUpdateDetail != null) {
data['objectUpdateDetail'] =
this.objectUpdateDetail.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['cropId'] = cropId;
data['activityId'] = activityId;
data['executeDate'] = executeDate;
data['description'] = description;
data['media_del'] = mediaDel;
if (objectUpdateDetail != null) {
data['objectUpdateDetail'] = objectUpdateDetail?.map((v) => v.toJson()).toList();
}
return data;
}
}

class ObjectUpdateDetail {
String name;
String index;
String? name;
String? index;

ObjectUpdateDetail({this.name, this.index});

@@ -54,9 +47,9 @@ class ObjectUpdateDetail {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['index'] = this.index;
final data = <String, dynamic>{};
data['name'] = name;
data['index'] = index;
return data;
}
}

+ 29
- 29
lib/custom_model/Sell.dart View File

@@ -1,18 +1,18 @@
class Sell {
int id;
int cropId;
int activityId;
int harvestId;
String executeDate;
String description;
String executeBy;
String media;
List<String> mediaDel;
num quantityLv1;
num quantityLv2;
num quantityLv3;
num removedQuantity;
String buyer;
int? id;
int? cropId;
int? activityId;
int? harvestId;
String? executeDate;
String? description;
String? executeBy;
String? media;
List<String>? mediaDel;
num? quantityLv1;
num? quantityLv2;
num? quantityLv3;
num? removedQuantity;
String? buyer;

Sell(
{this.id,
@@ -47,21 +47,21 @@ class Sell {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cropId'] = this.cropId;
data['activityId'] = this.activityId;
data['harvestId'] = this.harvestId;
data['executeDate'] = this.executeDate;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['quantityLv1'] = this.quantityLv1;
data['quantityLv2'] = this.quantityLv2;
data['quantityLv3'] = this.quantityLv3;
data['removedQuantity'] = this.removedQuantity;
data['buyer'] = this.buyer;
final data = <String, dynamic>{};
data['id'] = id;
data['cropId'] = cropId;
data['activityId'] = activityId;
data['harvestId'] = harvestId;
data['executeDate'] = executeDate;
data['description'] = description;
data['executeBy'] = executeBy;
data['media'] = media;
data['media_del'] = mediaDel;
data['quantityLv1'] = quantityLv1;
data['quantityLv2'] = quantityLv2;
data['quantityLv3'] = quantityLv3;
data['removedQuantity'] = removedQuantity;
data['buyer'] = buyer;
return data;
}
}

+ 30
- 31
lib/custom_model/Spraying.dart View File

@@ -1,19 +1,19 @@
import 'SuppliesUsing.dart';

class Spraying {
int id;
int activityId;
int cropId;
String media;
List<String> mediaDel;
String executeDate;
num quarantinePeriod;
String resultAt;
String weatherConditions;
String purpose;
String description;
String executeBy;
List<SuppliesUsing> suppliesUsing;
int? id;
int? activityId;
int? cropId;
String? media;
List<String>? mediaDel;
String? executeDate;
num? quarantinePeriod;
String? resultAt;
String? weatherConditions;
String? purpose;
String? description;
String? executeBy;
List<SuppliesUsing>? suppliesUsing;

Spraying(
{this.id,
@@ -43,30 +43,29 @@ class Spraying {
description = json['description'];
executeBy = json['executeBy'];
if (json['suppliesUsing'] != null) {
suppliesUsing = new List<SuppliesUsing>();
suppliesUsing = <SuppliesUsing>[];
json['suppliesUsing'].forEach((v) {
suppliesUsing.add(new SuppliesUsing.fromJson(v));
suppliesUsing?.add(SuppliesUsing.fromJson(v));
});
}
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['activityId'] = this.activityId;
data['cropId'] = this.cropId;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['executeDate'] = this.executeDate;
data['quarantinePeriod'] = this.quarantinePeriod;
data['resultAt'] = this.resultAt;
data['weatherConditions'] = this.weatherConditions;
data['purpose'] = this.purpose;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
if (this.suppliesUsing != null) {
data['suppliesUsing'] =
this.suppliesUsing.map((v) => v.toJson()).toList();
final data = <String, dynamic>{};
data['id'] = id;
data['activityId'] = activityId;
data['cropId'] = cropId;
data['media'] = media;
data['media_del'] = mediaDel;
data['executeDate'] = executeDate;
data['quarantinePeriod'] = quarantinePeriod;
data['resultAt'] = resultAt;
data['weatherConditions'] = weatherConditions;
data['purpose'] = purpose;
data['description'] = description;
data['executeBy'] = executeBy;
if (suppliesUsing != null) {
data['suppliesUsing'] = suppliesUsing?.map((v) => v.toJson()).toList();
}
return data;
}

+ 25
- 25
lib/custom_model/SuppliesUsing.dart View File

@@ -1,16 +1,16 @@
class SuppliesUsing {
int id;
String dosage;
num quantity;
String unit;
String howToUse;
int suppliesInWarehouseId;
int tbSuppliesInWarehouseId;
String supplyName;
String supplyUnit;
int tbEquipmentOfCustomerId;
int equipmentOfCustomerId;
String equipmentName;
int? id;
String? dosage;
num? quantity;
String? unit;
String? howToUse;
int? suppliesInWarehouseId;
int? tbSuppliesInWarehouseId;
String? supplyName;
String? supplyUnit;
int? tbEquipmentOfCustomerId;
int? equipmentOfCustomerId;
String? equipmentName;

SuppliesUsing(
{this.id,
@@ -42,19 +42,19 @@ class SuppliesUsing {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['dosage'] = this.dosage;
data['quantity'] = this.quantity;
data['unit'] = this.unit;
data['howToUse'] = this.howToUse;
data['suppliesInWarehouseId'] = this.suppliesInWarehouseId;
data['tbEquipmentOfCustomerId'] = this.tbEquipmentOfCustomerId;
data['equipmentOfCustomerId'] = this.equipmentOfCustomerId;
data['equipmentName'] = this.equipmentName;
data['tbSuppliesInWarehouseId'] = this.tbSuppliesInWarehouseId;
data['supplyName'] = this.supplyName;
data['supplyUnit'] = this.supplyUnit;
final data = <String, dynamic>{};
data['id'] = id;
data['dosage'] = dosage;
data['quantity'] = quantity;
data['unit'] = unit;
data['howToUse'] = howToUse;
data['suppliesInWarehouseId'] = suppliesInWarehouseId;
data['tbEquipmentOfCustomerId'] = tbEquipmentOfCustomerId;
data['equipmentOfCustomerId'] = equipmentOfCustomerId;
data['equipmentName'] = equipmentName;
data['tbSuppliesInWarehouseId'] = tbSuppliesInWarehouseId;
data['supplyName'] = supplyName;
data['supplyUnit'] = supplyUnit;
return data;
}
}

+ 17
- 25
lib/custom_model/Supply.dart View File

@@ -1,22 +1,14 @@
class Supply {
int id;
num quantity;
String unit;
int tbWarehouseId;
String tbWarehouseName;
String tbSuppliesName;
int tbSuppliesId;
bool isSelected;
int? id;
num? quantity;
String? unit;
int? tbWarehouseId;
String? tbWarehouseName;
String? tbSuppliesName;
int? tbSuppliesId;
bool? isSelected;

Supply(
{this.id,
this.quantity,
this.unit,
this.tbWarehouseId,
this.tbWarehouseName,
this.tbSuppliesName,
this.tbSuppliesId,
this.isSelected});
Supply({this.id, this.quantity, this.unit, this.tbWarehouseId, this.tbWarehouseName, this.tbSuppliesName, this.tbSuppliesId, this.isSelected});

Supply.fromJson(Map<String, dynamic> json) {
id = json['id'];
@@ -30,14 +22,14 @@ class Supply {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['quantity'] = this.quantity;
data['unit'] = this.unit;
data['tbWarehouseId'] = this.tbWarehouseId;
data['tbWarehouseName'] = this.tbWarehouseName;
data['tbSuppliesName'] = this.tbSuppliesName;
data['tbSuppliesId'] = this.tbSuppliesId;
final data = <String, dynamic>{};
data['id'] = id;
data['quantity'] = quantity;
data['unit'] = unit;
data['tbWarehouseId'] = tbWarehouseId;
data['tbWarehouseName'] = tbWarehouseName;
data['tbSuppliesName'] = tbSuppliesName;
data['tbSuppliesId'] = tbSuppliesId;
return data;
}
}

+ 5
- 5
lib/custom_model/UpdateNoti.dart View File

@@ -1,6 +1,6 @@
class UpdateNoti {
int id;
int isRead;
int? id;
int? isRead;

UpdateNoti({this.id, this.isRead});

@@ -10,9 +10,9 @@ class UpdateNoti {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['isRead'] = this.isRead;
final data = <String, dynamic>{};
data['id'] = id;
data['isRead'] = isRead;
return data;
}
}

+ 21
- 21
lib/custom_model/UseWater.dart View File

@@ -1,14 +1,14 @@
class UseWater {
int id;
int activityId;
int cropId;
String executeDate;
String media;
List<String> mediaDel;
String waterType;
num amount;
String description;
String executeBy;
int? id;
int? activityId;
int? cropId;
String? executeDate;
String? media;
List<String>? mediaDel;
String? waterType;
num? amount;
String? description;
String? executeBy;

UseWater(
{this.id,
@@ -35,17 +35,17 @@ class UseWater {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['activityId'] = this.activityId;
data['cropId'] = this.cropId;
data['executeDate'] = this.executeDate;
data['media'] = this.media;
data['media_del'] = this.mediaDel;
data['waterType'] = this.waterType;
data['amount'] = this.amount;
data['description'] = this.description;
data['executeBy'] = this.executeBy;
final data = <String, dynamic>{};
data['id'] = id;
data['activityId'] = activityId;
data['cropId'] = cropId;
data['executeDate'] = executeDate;
data['media'] = media;
data['media_del'] = mediaDel;
data['waterType'] = waterType;
data['amount'] = amount;
data['description'] = description;
data['executeBy'] = executeBy;
return data;
}
}

+ 5
- 5
lib/custom_model/WaterType.dart View File

@@ -1,6 +1,6 @@
class WaterType {
String waterTypeName;
String waterTypeDescription;
String? waterTypeName;
String? waterTypeDescription;

WaterType({this.waterTypeName, this.waterTypeDescription});

@@ -10,9 +10,9 @@ class WaterType {
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['waterTypeName'] = this.waterTypeName;
data['waterTypeDescription'] = this.waterTypeDescription;
final data = <String, dynamic>{};
data['waterTypeName'] = waterTypeName;
data['waterTypeDescription'] = waterTypeDescription;
return data;
}
}

+ 108
- 34
lib/custom_model/account.dart View File

@@ -1,38 +1,112 @@
import 'package:json_annotation/json_annotation.dart';

part 'account.g.dart';

@JsonSerializable()
class Account {
Account();
num? id;
String? login;
String? firstName;
String? lastName;
String? midleName;
String? fullName;
String? phone;
String? address;
String? avartar;
num? vaiTroId;
String? tenVaiTro;
num? donViCanhTacId;
String? tenDonVi;
String? email;
String? imageUrl;
bool? activated;
num? countryId;
String? countryName;
num? cityId;
String? cityName;
num? districtId;
String? districtName;
num? wardId;
String? wardName;
List<String>? authorities;

Account(
{this.id,
this.login,
this.firstName,
this.lastName,
this.midleName,
this.fullName,
this.phone,
this.address,
this.avartar,
this.vaiTroId,
this.tenVaiTro,
this.donViCanhTacId,
this.tenDonVi,
this.email,
this.imageUrl,
this.activated,
this.countryId,
this.countryName,
this.cityId,
this.cityName,
this.districtId,
this.districtName,
this.wardId,
this.wardName,
this.authorities});

num id;
String login;
String firstName;
String lastName;
String midleName;
String fullName;
String phone;
String address;
String avartar;
num vaiTroId;
String tenVaiTro;
num donViCanhTacId;
String tenDonVi;
String email;
String imageUrl;
bool activated;
int countryId;
String countryName;
int cityId;
String cityName;
int districtId;
String districtName;
int wardId;
String wardName;
List authorities;
Account.fromJson(Map<String, dynamic> json) {
id = json['id'];
login = json['login'];
firstName = json['firstName'];
lastName = json['lastName'];
midleName = json['midleName'];
fullName = json['fullName'];
phone = json['phone'];
address = json['address'];
avartar = json['avartar'];
vaiTroId = json['vaiTroId'];
tenVaiTro = json['tenVaiTro'];
donViCanhTacId = json['donViCanhTacId'];
tenDonVi = json['tenDonVi'];
email = json['email'];
imageUrl = json['imageUrl'];
activated = json['activated'];
countryId = json['countryId'];
countryName = json['countryName'];
cityId = json['cityId'];
cityName = json['cityName'];
districtId = json['districtId'];
districtName = json['districtName'];
wardId = json['wardId'];
wardName = json['wardName'];
authorities = json['authorities'].cast<String>();
}

factory Account.fromJson(Map<String, dynamic> json) =>
_$AccountFromJson(json);
Map<String, dynamic> toJson() => _$AccountToJson(this);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['login'] = this.login;
data['firstName'] = this.firstName;
data['lastName'] = this.lastName;
data['midleName'] = this.midleName;
data['fullName'] = this.fullName;
data['phone'] = this.phone;
data['address'] = this.address;
data['avartar'] = this.avartar;
data['vaiTroId'] = this.vaiTroId;
data['tenVaiTro'] = this.tenVaiTro;
data['donViCanhTacId'] = this.donViCanhTacId;
data['tenDonVi'] = this.tenDonVi;
data['email'] = this.email;
data['imageUrl'] = this.imageUrl;
data['activated'] = this.activated;
data['countryId'] = this.countryId;
data['countryName'] = this.countryName;
data['cityId'] = this.cityId;
data['cityName'] = this.cityName;
data['districtId'] = this.districtId;
data['districtName'] = this.districtName;
data['wardId'] = this.wardId;
data['wardName'] = this.wardName;
data['authorities'] = this.authorities;
return data;
}
}

+ 0
- 64
lib/custom_model/account.g.dart View File

@@ -1,64 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'account.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Account _$AccountFromJson(Map<String, dynamic> json) {
return Account()
..id = json['id'] as num
..login = json['login'] as String
..firstName = json['firstName'] as String
..lastName = json['lastName'] as String
..midleName = json['midleName'] as String
..fullName = json['fullName'] as String
..phone = json['phone'] as String
..address = json['address'] as String
..avartar = json['avartar'] as String
..vaiTroId = json['vaiTroId'] as num
..tenVaiTro = json['tenVaiTro'] as String
..donViCanhTacId = json['donViCanhTacId'] as num
..tenDonVi = json['tenDonVi'] as String
..email = json['email'] as String
..imageUrl = json['imageUrl'] as String
..activated = json['activated'] as bool
..countryId = json['countryId'] as num
..countryName = json['countryName'] as String
..cityId = json['cityId'] as num
..cityName = json['cityName'] as String
..districtId = json['districtId'] as num
..districtName = json['districtName'] as String
..wardId = json['wardId'] as num
..wardName = json['wardName'] as String
..authorities = json['authorities'] as List;
}

Map<String, dynamic> _$AccountToJson(Account instance) => <String, dynamic>{
'id': instance.id,
'login': instance.login,
'firstName': instance.firstName,
'lastName': instance.lastName,
'midleName': instance.midleName,
'fullName': instance.fullName,
'phone': instance.phone,
'address': instance.address,
'avartar': instance.avartar,
'vaiTroId': instance.vaiTroId,
'tenVaiTro': instance.tenVaiTro,
'donViCanhTacId': instance.donViCanhTacId,
'tenDonVi': instance.tenDonVi,
'email': instance.email,
'imageUrl': instance.imageUrl,
'activated': instance.activated,
'countryId': instance.countryId,
'countryName': instance.countryName,
'cityId': instance.cityId,
'cityName': instance.cityName,
'districtId': instance.districtId,
'districtName': instance.districtName,
'wardId': instance.wardId,
'wardName': instance.wardName,
'authorities': instance.authorities,
};

+ 17
- 11
lib/custom_model/password.dart View File

@@ -1,15 +1,21 @@
import 'package:json_annotation/json_annotation.dart';
class Password {
String? key;
String? currentPassword;
String? newPassword;

part 'password.g.dart';
Password({this.key, this.currentPassword, this.newPassword});

@JsonSerializable()
class Password {
Password();
Password.fromJson(Map<String, dynamic> json) {
key = json['key'];
currentPassword = json['currentPassword'];
newPassword = json['newPassword'];
}

String key;
String currentPassword;
String newPassword;
factory Password.fromJson(Map<String,dynamic> json) => _$PasswordFromJson(json);
Map<String, dynamic> toJson() => _$PasswordToJson(this);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['key'] = this.key;
data['currentPassword'] = this.currentPassword;
data['newPassword'] = this.newPassword;
return data;
}
}

+ 0
- 20
lib/custom_model/password.g.dart View File

@@ -1,20 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'password.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Password _$PasswordFromJson(Map<String, dynamic> json) {
return Password()
..key = json['key'] as String
..currentPassword = json['currentPassword'] as String
..newPassword = json['newPassword'] as String;
}

Map<String, dynamic> _$PasswordToJson(Password instance) => <String, dynamic>{
'key': instance.key,
'currentPassword': instance.currentPassword,
'newPassword': instance.newPassword,
};

+ 11
- 9
lib/custom_model/user.dart View File

@@ -1,13 +1,15 @@
import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
User();
String? idToken;

User({this.idToken});

String idToken;
User.fromJson(Map<String, dynamic> json) {
idToken = json['idToken'];
}

factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['idToken'] = this.idToken;
return data;
}
}

+ 0
- 15
lib/custom_model/user.g.dart View File

@@ -1,15 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

User _$UserFromJson(Map<String, dynamic> json) {
return User()..idToken = json['id_token'] as String;
}

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'id_token': instance.idToken,
};

+ 14
- 9
lib/custom_model/user_request.dart View File

@@ -1,13 +1,18 @@
import 'package:json_annotation/json_annotation.dart';
part 'user_request.g.dart';

@JsonSerializable()
class UserRequest {
final String username;
final String password;
String? username;
String? password;

UserRequest({this.username, this.password});

factory UserRequest.fromJson(Map<String, dynamic> json) =>
_$UserRequestFromJson(json);
Map<String, dynamic> toJson() => _$UserRequestToJson(this);
UserRequest.fromJson(Map<String, dynamic> json) {
username = json['username'];
password = json['password'];
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['username'] = this.username;
data['password'] = this.password;
return data;
}
}

+ 0
- 20
lib/custom_model/user_request.g.dart View File

@@ -1,20 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user_request.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

UserRequest _$UserRequestFromJson(Map<String, dynamic> json) {
return UserRequest(
username: json['username'] as String,
password: json['password'] as String,
);
}

Map<String, dynamic> _$UserRequestToJson(UserRequest instance) =>
<String, dynamic>{
'username': instance.username,
'password': instance.password,
};

+ 4
- 4
lib/data/api/app_exception.dart View File

@@ -5,11 +5,11 @@ import 'package:farm_tpf/custom_model/ErrorCommon.dart';
import 'package:farm_tpf/utils/const_string.dart';

class AppException {
static String handleError(dynamic error, {String customMessageError}) {
String errorDescription = "";
static String handleError(dynamic error, {String? customMessageError}) {
var errorDescription = "";

try {
DioError dioError = error as DioError;
var dioError = error as DioError;
switch (dioError.type) {
case DioErrorType.CANCEL:
errorDescription = exception_dio_cancle;
@@ -28,7 +28,7 @@ class AppException {
if (statusCode == 400) {
errorDescription = customMessageError ?? exception_dio_400;
try {
Map errorMap = jsonDecode(dioError.response.data);
Map<String, dynamic> errorMap = jsonDecode(dioError.response.data);
var errorCode = ErrorCommon.fromJson(errorMap).errorKey;

switch (errorCode) {

+ 67
- 180
lib/data/api/rest_client.g.dart View File

@@ -9,12 +9,12 @@ part of 'rest_client.dart';
class _RestClient implements RestClient {
_RestClient(this._dio, {this.baseUrl}) {
ArgumentError.checkNotNull(_dio, '_dio');
this.baseUrl ??= 'https://tpf.aztrace.vn';
baseUrl ??= 'https://smf.presshome.vn/';
}

final Dio _dio;

String baseUrl;
String? baseUrl;

@override
login(userRequest) async {
@@ -23,14 +23,9 @@ class _RestClient implements RestClient {
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(userRequest?.toJson() ?? <String, dynamic>{});
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/authenticate',
final Response<Map<String, dynamic>> _result = await _dio.request('/api/authenticate',
queryParameters: queryParameters,
options: RequestOptions(
method: 'POST',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = User.fromJson(_result.data);
return value;
@@ -41,14 +36,9 @@ class _RestClient implements RestClient {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/account',
final Response<Map<String, dynamic>> _result = await _dio.request('/api/account',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = Account.fromJson(_result.data);
return value;
@@ -62,11 +52,7 @@ class _RestClient implements RestClient {
final _data = email;
await _dio.request<void>('/api/account/reset-password/init',
queryParameters: queryParameters,
options: RequestOptions(
method: 'POST',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}
@@ -80,11 +66,7 @@ class _RestClient implements RestClient {
_data.addAll(password?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/account/reset-password/finish',
queryParameters: queryParameters,
options: RequestOptions(
method: 'POST',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}
@@ -98,11 +80,7 @@ class _RestClient implements RestClient {
_data.addAll(password?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/account/change-password',
queryParameters: queryParameters,
options: RequestOptions(
method: 'POST',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'POST', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}
@@ -114,37 +92,27 @@ class _RestClient implements RestClient {
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(account?.toJson() ?? <String, dynamic>{});
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/update-my-profile',
final Response<Map<String, dynamic>> _result = await _dio.request('/api/update-my-profile',
queryParameters: queryParameters,
options: RequestOptions(
method: 'PUT',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = Account.fromJson(_result.data);
return value;
}

@override
getSupplies(type, {options, query = ""}) async {
getSupplies(type, {Options? options, query = ""}) async {
ArgumentError.checkNotNull(type, 'type');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
'/api/list-supplies-in-warehouses/$type?q=$query',
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => Supply.fromJson(i as Map<String, dynamic>))
.toList();
final Response<List<dynamic>> _result = await _dio.request('/api/list-supplies-in-warehouses/$type?q=$query',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => Supply.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@@ -156,11 +124,7 @@ class _RestClient implements RestClient {
final _data = token;
await _dio.request<void>('/api/update-fcmToken',
queryParameters: queryParameters,
options: RequestOptions(
method: 'PUT',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}
@@ -173,11 +137,7 @@ class _RestClient implements RestClient {
final _data = token;
await _dio.request<void>('/api/delete-fcmToken',
queryParameters: queryParameters,
options: RequestOptions(
method: 'PUT',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}
@@ -188,98 +148,71 @@ class _RestClient implements RestClient {
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final Response<List<dynamic>> _result = await _dio.request(
'/api/_search/tb-crops?page=$page&size=$size&sort=id,asc&query=$query',
final Response<List<dynamic>> _result = await _dio.request('/api/_search/tb-crops?page=$page&size=$size&sort=id,asc&query=$query',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => Crop.fromJson(i as Map<String, dynamic>))
.toList();
var value = _result.data.map((dynamic i) => Crop.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@override
getActionTypes({options}) async {
getActionTypes({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
'/api/listActivityTypesOther',
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>))
.toList();
final Response<List<dynamic>> _result = await _dio.request('/api/listActivityTypesOther',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@override
getWaterTypes({options}) async {
getWaterTypes({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
'/api/water-types',
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => WaterType.fromJson(i as Map<String, dynamic>))
.toList();
final Response<List<dynamic>> _result = await _dio.request('/api/water-types',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => WaterType.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@override
getHarvests({options}) async {
getHarvests({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-harvests',
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => Harvest.fromJson(i as Map<String, dynamic>))
.toList();
final Response<List<dynamic>> _result = await _dio.request('/api/tb-harvests',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => Harvest.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@override
getDeviceForActivity({options}) async {
getDeviceForActivity({Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
'/api/listDeviceForActivity',
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>))
.toList();
final Response<List<dynamic>> _result = await _dio.request('/api/listDeviceForActivity',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@@ -291,11 +224,7 @@ class _RestClient implements RestClient {
final _data = status;
await _dio.request<void>('/api/notifications/update-all',
queryParameters: queryParameters,
options: RequestOptions(
method: 'PUT',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}
@@ -309,43 +238,34 @@ class _RestClient implements RestClient {
_data.addAll(updateNoti?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/notifications/update',
queryParameters: queryParameters,
options: RequestOptions(
method: 'PUT',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}

@override
getCountries({page = 0, size = 400, query = '', options}) async {
getCountries({page = 0, size = 400, query = '', Options? options}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
'/api/tb-countries?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>))
.toList();
final Response<List<dynamic>> _result = await _dio.request('/api/tb-countries?page=$page&size=$size&query=$query&&sort=name,ASC',
queryParameters: queryParameters, options: newOptions.merge(method: 'GET', baseUrl: baseUrl), data: _data);
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@override
getProvinces(countryId, {page = 0, size = 20, query = '', options}) async {
getProvinces(countryId, {page = 0, size = 20, query = '', Options? options}) async {
ArgumentError.checkNotNull(countryId, 'countryId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
@@ -353,20 +273,18 @@ class _RestClient implements RestClient {
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>))
.toList();
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@override
getDistricts(provinceId, {page = 0, size = 20, query = '', options}) async {
getDistricts(provinceId, {page = 0, size = 20, query = '', Options? options}) async {
ArgumentError.checkNotNull(provinceId, 'provinceId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
@@ -374,20 +292,18 @@ class _RestClient implements RestClient {
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>))
.toList();
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@override
getWards(districtId, {page = 0, size = 20, query = '', options}) async {
getWards(districtId, {page = 0, size = 20, query = '', Options? options}) async {
ArgumentError.checkNotNull(districtId, 'districtId');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final newOptions = newRequestOptions(options);
final newOptions = newRequestOptions(options ?? Options());
newOptions.extra.addAll(_extra);
newOptions.headers.addAll(<String, dynamic>{});
final Response<List<dynamic>> _result = await _dio.request(
@@ -395,9 +311,7 @@ class _RestClient implements RestClient {
queryParameters: queryParameters,
options: newOptions.merge(method: 'GET', baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>))
.toList();
var value = _result.data.map((dynamic i) => LocationUnit.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@@ -411,11 +325,7 @@ class _RestClient implements RestClient {
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/tb-crops-detail-for-app/$cropId?page=$page&size=$size&sort=executeDate,DESC',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = CropPlot.fromJson(_result.data);
return value;
@@ -431,11 +341,7 @@ class _RestClient implements RestClient {
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/tb-crops-scan-qrCode/$cropCode?page=$page&size=$size&sort=executeDate,DESC',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
final value = CropPlot.fromJson(_result.data);
return value;
@@ -450,32 +356,21 @@ class _RestClient implements RestClient {
_data.addAll(crop?.toJson() ?? <String, dynamic>{});
await _dio.request<void>('/api/tb-crops',
queryParameters: queryParameters,
options: RequestOptions(
method: 'PUT',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'PUT', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
return null;
}

@override
getDevices({query}) async {
getDevices({String? query}) async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
final Response<List<dynamic>> _result = await _dio.request(
'/api/listDeviceOfUserCustomers?query=$query',
final Response<List<dynamic>> _result = await _dio.request('/api/listDeviceOfUserCustomers?query=$query',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>))
.toList();
var value = _result.data.map((dynamic i) => Device.fromJson(i as Map<String, dynamic>)).toList();
return value;
}

@@ -486,19 +381,11 @@ class _RestClient implements RestClient {
final queryParameters = <String, dynamic>{};
queryParameters.removeWhere((k, v) => v == null);
final _data = <String, dynamic>{};
final Response<List<dynamic>> _result = await _dio.request(
'/api/list-environment-updates-display/$cropId?page=$page&size=$size',
final Response<List<dynamic>> _result = await _dio.request('/api/list-environment-updates-display/$cropId?page=$page&size=$size',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
options: RequestOptions(method: 'GET', headers: <String, dynamic>{}, extra: _extra, baseUrl: baseUrl),
data: _data);
var value = _result.data
.map((dynamic i) =>
EnvironmentParameter.fromJson(i as Map<String, dynamic>))
.toList();
var value = _result.data.map((dynamic i) => EnvironmentParameter.fromJson(i as Map<String, dynamic>)).toList();
return value;
}


+ 3
- 5
lib/data/repository/authentication_repository.dart View File

@@ -18,9 +18,8 @@ class AuthenticationRepository {
try {
var token = await pref.getString(DATA_CONST.TOKEN_KEY);
var expiredTime = await pref.getString(DATA_CONST.EXPIRED_TIME);
int currentTime = DateTime.now().millisecondsSinceEpoch;
bool isNotExpired =
(currentTime - int.tryParse(expiredTime)) < ConstCommon.kExpiredTime;
var currentTime = DateTime.now().millisecondsSinceEpoch;
var isNotExpired = (currentTime - (int.tryParse(expiredTime) ?? 0)) < ConstCommon.kExpiredTime;

if (token.isNotEmpty && isNotExpired) {
yield AuthenticationStatus.authenticated;
@@ -35,8 +34,7 @@ class AuthenticationRepository {

Future<User> signInWithCredentials(String username, String password) {
final client = RestClient(dio);
var result =
client.login(UserRequest(username: username, password: password));
var result = client.login(UserRequest(username: username, password: password));
return result;
}


+ 25
- 55
lib/data/repository/repository.dart View File

@@ -23,36 +23,33 @@ class Repository {

Future<List<ActionType>> getActionTypes() {
final client = RestClient(dio);
var op = buildConfigurableCacheOptions(
forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
return client.getActionTypes(options: op);
}

Future<List<Harvest>> getHarvests() {
final client = RestClient(dio);
var op = buildConfigurableCacheOptions(
forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
return client.getHarvests(options: op);
}

Future<List<WaterType>> getWaterTypes() {
final client = RestClient(dio);
var op = buildConfigurableCacheOptions(
forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
return client.getWaterTypes(options: op);
}

Future<CropPlot> getPlotDetail(int cropId, {int page, int size}) {
Future<CropPlot> getPlotDetail(int cropId, {int page = 0, int size = 20}) {
final client = RestClient(dio);
return client.getCropDetail(cropId, page: page, size: size);
}

Future<CropPlot> getPlotDetailByCode(String cropCode, {int page, int size}) {
Future<CropPlot> getPlotDetailByCode(String cropCode, {int page = 0, int size = 20}) {
final client = RestClient(dio);
return client.getCropDetailByCode(cropCode, page: page, size: size);
}

Future<List<Crop>> getPlots({int page, int size, String searchString}) {
Future<List<Crop>> getPlots({int page = 0, int size = 20, String searchString = ''}) {
final client = RestClient(dio);
return client.getPlots(page: page, size: size, query: searchString);
}
@@ -67,11 +64,9 @@ class Repository {
return client.login(UserRequest(username: username, password: password));
}

Future<PagedResult<T>> getInfinityList<T>(String url,
{int page = 0, int size = 20}) async {
Future<PagedResult<T>> getInfinityList<T>(String url, {int page = 0, int size = 20}) async {
var initUrl = "/api/activities/latest-env-by-activity-type/1/2";
var url =
ConstCommon.baseUrl + initUrl + "?page=$page&paged=true&size=$size";
var url = ConstCommon.baseUrl + initUrl + "?page=$page&paged=true&size=$size";
var response = await dio.get(url);

final value = PagedResult<T>.fromJson(response.data, getInstanceClass());
@@ -80,15 +75,13 @@ class Repository {

Future<List<Supply>> getSupplies(String type, {String query = ""}) async {
final client = RestClient(dio);
var op = buildConfigurableCacheOptions(
forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
return client.getSupplies(type, query: query, options: op);
}

Future<List<Device>> getDeviceForActivity() async {
final client = RestClient(dio);
var op = buildConfigurableCacheOptions(
forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
return client.getDeviceForActivity(options: op);
}

@@ -102,10 +95,8 @@ class Repository {
return client.updateNoti(updateNoti);
}

Future<NotificationObjectDTO> getNotifications(
{int page = 0, int size = 20}) async {
var url = ConstCommon.baseUrl +
"/api/notifications-current-user?page=$page&size=$size&sort=sendDate,DESC";
Future<NotificationObjectDTO> getNotifications({int page = 0, int size = 20}) async {
var url = ConstCommon.baseUrl + "/api/notifications-current-user?page=$page&size=$size&sort=sendDate,DESC";
var response = await dio.get(url);

final value = NotificationObjectDTO.fromJson(response.data);
@@ -113,27 +104,19 @@ class Repository {
}

Future<List<LocationUnit>> getLocationUnits(
{@required LocationType locationType,
int filterId,
int page = 0,
int size = 500,
String query = ''}) {
{required LocationType locationType, required int filterId, int page = 0, int size = 500, String query = ''}) {
final client = RestClient(dio);
var op = buildConfigurableCacheOptions(
forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
var response;
switch (locationType) {
case LocationType.province:
response = client.getProvinces(filterId,
options: op, page: page, size: size, query: query);
response = client.getProvinces(filterId, options: op, page: page, size: size, query: query);
break;
case LocationType.district:
response = client.getDistricts(filterId,
options: op, page: page, size: size, query: query);
response = client.getDistricts(filterId, options: op, page: page, size: size, query: query);
break;
case LocationType.ward:
response = client.getWards(filterId,
options: op, page: page, size: size, query: query);
response = client.getWards(filterId, options: op, page: page, size: size, query: query);
break;
default:
response = client.getCountries(query: query);
@@ -144,27 +127,21 @@ class Repository {
Object getInstanceClass() {
var instanceClass;
if (1 == 1) {
instanceClass = new Crop();
instanceClass = Crop();
}
return instanceClass;
}

//Action
Future<void> createAction(
Function(dynamic) onSuccess, Function(dynamic) onError,
{String apiAddAction,
String paramActivity,
String activityAction,
List<String> filePaths}) async {
Future<void> createAction(Function(dynamic) onSuccess, Function(dynamic) onError,
{required String apiAddAction, required String paramActivity, required String activityAction, required List<String> filePaths}) async {
var formData = FormData();
filePaths.forEach((f) {
formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
});
formData.fields.add(MapEntry(paramActivity, activityAction));
try {
await dio
.post("${ConstCommon.baseUrl}/$apiAddAction", data: formData)
.then((value) {
await dio.post("${ConstCommon.baseUrl}/$apiAddAction", data: formData).then((value) {
onSuccess(value.data);
});
} on DioError catch (e) {
@@ -172,21 +149,15 @@ class Repository {
}
}

Future<void> updateAction(
Function(dynamic) onSuccess, Function(dynamic) onError,
{String apiUpdateAction,
String paramActivity,
String activityAction,
List<String> filePaths}) async {
Future<void> updateAction(Function(dynamic) onSuccess, Function(dynamic) onError,
{required String apiUpdateAction, required String paramActivity, required String activityAction, required List<String> filePaths}) async {
var formData = FormData();
filePaths.forEach((f) {
formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
});
formData.fields.add(MapEntry(paramActivity, activityAction));
try {
await dio
.post("${ConstCommon.baseUrl}/$apiUpdateAction", data: formData)
.then((value) {
await dio.post("${ConstCommon.baseUrl}/$apiUpdateAction", data: formData).then((value) {
onSuccess(value.data);
});
} on DioError catch (e) {
@@ -201,8 +172,7 @@ class Repository {
}

//Environment Parameter
Future<List<EnvironmentParameter>> getEnvironmentParameters(
{@required int cropId, int page, int size}) {
Future<List<EnvironmentParameter>> getEnvironmentParameters({required int cropId, int page = 0, int size = 20}) {
final client = RestClient(dio);
return client.getEnvironmentParameters(cropId, page: page, size: size);
}

+ 5
- 14
lib/main.dart View File

@@ -21,7 +21,7 @@ Future<void> main() async {
runApp(App(authenticationRepository: AuthenticationRepository()));
}

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
void myBackgroundMessageHandler(Map<String, dynamic> message) {
if (message.containsKey('data')) {
// Handle data message
final dynamic data = message['data'];
@@ -70,22 +70,13 @@ Future scan(BuildContext context) async {
}
}

_showAlertCheckCropCode(
BuildContext context, String cropCode, Repository repository) async {
Get.defaultDialog(
title: "Kiểm tra thông tin lô ....",
middleText: "",
content: CircularProgressIndicator());
_showAlertCheckCropCode(BuildContext context, String cropCode, Repository repository) async {
Get.defaultDialog(title: "Kiểm tra thông tin lô ....", middleText: "", content: const CircularProgressIndicator());
try {
await repository
.getPlotDetailByCode(cropCode, page: 1, size: 1)
.then((value) {
await repository.getPlotDetailByCode(cropCode, page: 1, size: 1).then((value) {
print("ok");
if (Get.isDialogOpen) Get.back();
Get.to(PlotDetailScreen(
cropId: value.tbCropDTO.id,
cropType: value.tbCropDTO.type,
initialIndex: 0));
Get.to(PlotDetailScreen(cropId: value.tbCropDTO?.id ?? -1, cropType: value.tbCropDTO?.type ?? -1, initialIndex: 0));
}).catchError((onError) {
Utils.showDialog(
title: "Không tìm thấy lô",

+ 17
- 11
lib/models/ActionType.dart View File

@@ -1,15 +1,21 @@
import 'package:json_annotation/json_annotation.dart';
class ActionType {
int? id;
String? name;
String? description;

part 'ActionType.g.dart';
ActionType({this.id, this.name, this.description});

@JsonSerializable()
class ActionType {
ActionType();
ActionType.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
description = json['description'];
}

num id;
String name;
String description;
factory ActionType.fromJson(Map<String,dynamic> json) => _$ActionTypeFromJson(json);
Map<String, dynamic> toJson() => _$ActionTypeToJson(this);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['description'] = this.description;
return data;
}
}

+ 0
- 21
lib/models/ActionType.g.dart View File

@@ -1,21 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'ActionType.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

ActionType _$ActionTypeFromJson(Map<String, dynamic> json) {
return ActionType()
..id = json['id'] as num
..name = json['name'] as String
..description = json['description'] as String;
}

Map<String, dynamic> _$ActionTypeToJson(ActionType instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'description': instance.description,
};

+ 76
- 25
lib/models/Crop.dart View File

@@ -1,29 +1,80 @@
import 'package:json_annotation/json_annotation.dart';
class Crop {
num? id;
String? qrCode;
String? code;
double? areaM2;
num? type;
String? startDate;
String? endDate;
String? status;
String? description;
num? ageDayStartAt;
num? tbSuppliesId;
String? suppliesName;
num? tbGuidelineId;
num? netHouseId;
String? netHouseName;
num? areaId;
String? area;

part 'Crop.g.dart';
Crop(
{this.id,
this.qrCode,
this.code,
this.areaM2,
this.type,
this.startDate,
this.endDate,
this.status,
this.description,
this.ageDayStartAt,
this.tbSuppliesId,
this.suppliesName,
this.tbGuidelineId,
this.netHouseId,
this.netHouseName,
this.areaId,
this.area});

@JsonSerializable()
class Crop {
Crop();
Crop.fromJson(Map<String, dynamic> json) {
id = json['id'];
qrCode = json['qrCode'];
code = json['code'];
areaM2 = json['areaM2'];
type = json['type'];
startDate = json['startDate'];
endDate = json['endDate'];
status = json['status'];
description = json['description'];
ageDayStartAt = json['ageDayStartAt'];
tbSuppliesId = json['tbSuppliesId'];
suppliesName = json['suppliesName'];
tbGuidelineId = json['tbGuidelineId'];
netHouseId = json['netHouseId'];
netHouseName = json['netHouseName'];
areaId = json['areaId'];
area = json['area'];
}

num id;
String qrCode;
String code;
num areaM2;
num type;
String startDate;
String endDate;
String status;
String description;
num ageDayStartAt;
num tbSuppliesId;
String suppliesName;
num tbGuidelineId;
num netHouseId;
String netHouseName;
num areaId;
String area;
factory Crop.fromJson(Map<String,dynamic> json) => _$CropFromJson(json);
Map<String, dynamic> toJson() => _$CropToJson(this);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['qrCode'] = this.qrCode;
data['code'] = this.code;
data['areaM2'] = this.areaM2;
data['type'] = this.type;
data['startDate'] = this.startDate;
data['endDate'] = this.endDate;
data['status'] = this.status;
data['description'] = this.description;
data['ageDayStartAt'] = this.ageDayStartAt;
data['tbSuppliesId'] = this.tbSuppliesId;
data['suppliesName'] = this.suppliesName;
data['tbGuidelineId'] = this.tbGuidelineId;
data['netHouseId'] = this.netHouseId;
data['netHouseName'] = this.netHouseName;
data['areaId'] = this.areaId;
data['area'] = this.area;
return data;
}
}

+ 0
- 48
lib/models/Crop.g.dart View File

@@ -1,48 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'Crop.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Crop _$CropFromJson(Map<String, dynamic> json) {
return Crop()
..id = json['id'] as num
..qrCode = json['qrCode'] as String
..code = json['code'] as String
..areaM2 = json['areaM2'] as num
..type = json['type'] as num
..startDate = json['startDate'] as String
..endDate = json['endDate'] as String
..status = json['status'] as String
..description = json['description'] as String
..ageDayStartAt = json['ageDayStartAt'] as num
..tbSuppliesId = json['tbSuppliesId'] as num
..suppliesName = json['suppliesName'] as String
..tbGuidelineId = json['tbGuidelineId'] as num
..netHouseId = json['netHouseId'] as num
..netHouseName = json['netHouseName'] as String
..areaId = json['areaId'] as num
..area = json['area'] as String;
}

Map<String, dynamic> _$CropToJson(Crop instance) => <String, dynamic>{
'id': instance.id,
'qrCode': instance.qrCode,
'code': instance.code,
'areaM2': instance.areaM2,
'type': instance.type,
'startDate': instance.startDate,
'endDate': instance.endDate,
'status': instance.status,
'description': instance.description,
'ageDayStartAt': instance.ageDayStartAt,
'tbSuppliesId': instance.tbSuppliesId,
'suppliesName': instance.suppliesName,
'tbGuidelineId': instance.tbGuidelineId,
'netHouseId': instance.netHouseId,
'netHouseName': instance.netHouseName,
'areaId': instance.areaId,
'area': instance.area,
};

+ 4
- 4
lib/models/PagedResult.dart View File

@@ -1,14 +1,14 @@
class PagedResult<T> {
final int totalElements;
final int? totalElements;
final List<T> results;

PagedResult({this.totalElements, this.results});
PagedResult({this.totalElements, required this.results});

factory PagedResult.fromJson(Map<String, dynamic> json, object) {
final items = json['content'].cast<Map<String, dynamic>>();
final listItems =
new List<T>.from(items.map((itemsJson) => object.fromJson(itemsJson)));
List<T>.from(items.map((itemsJson) => object.fromJson(itemsJson)));
final total = json['totalElements'] as num;
return PagedResult<T>(totalElements: total, results: listItems);
return PagedResult<T>(totalElements: total.toInt(), results: listItems);
}
}

+ 20
- 12
lib/models/ResourceHelper.dart View File

@@ -1,16 +1,24 @@
import 'package:json_annotation/json_annotation.dart';
class ResourceHelper {
int? id;
String? name;
String? description;
bool? isSelected;

part 'ResourceHelper.g.dart';
ResourceHelper({this.id, this.name, this.description, this.isSelected});

@JsonSerializable()
class ResourceHelper {
ResourceHelper();
ResourceHelper.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
description = json['description'];
isSelected = json['isSelected'];
}

num id;
String name;
String description;
bool isSelected;
factory ResourceHelper.fromJson(Map<String,dynamic> json) => _$ResourceHelperFromJson(json);
Map<String, dynamic> toJson() => _$ResourceHelperToJson(this);
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['description'] = this.description;
data['isSelected'] = this.isSelected;
return data;
}
}

+ 0
- 23
lib/models/ResourceHelper.g.dart View File

@@ -1,23 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'ResourceHelper.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

ResourceHelper _$ResourceHelperFromJson(Map<String, dynamic> json) {
return ResourceHelper()
..id = json['id'] as num
..name = json['name'] as String
..description = json['description'] as String
..isSelected = json['isSelected'] as bool;
}

Map<String, dynamic> _$ResourceHelperToJson(ResourceHelper instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'description': instance.description,
'isSelected': instance.isSelected,
};

+ 6
- 8
lib/presentation/custom_widgets/app_bar_widget.dart View File

@@ -4,7 +4,7 @@ import 'package:get/get.dart';

class AppBarWidget extends StatelessWidget implements PreferredSizeWidget {
final bool isBack;
final Widget action;
final Widget? action;
AppBarWidget({this.isBack = true, this.action});
@override
Widget build(BuildContext context) {
@@ -26,15 +26,13 @@ class AppBarWidget extends StatelessWidget implements PreferredSizeWidget {
Text(
'Quay lại',
maxLines: 1,
style: TextStyle(
color: AppColors.YELLOW,
fontWeight: FontWeight.normal),
style: TextStyle(color: AppColors.YELLOW, fontWeight: FontWeight.normal),
),
SizedBox(width: 4),
const SizedBox(width: 4),
Expanded(
child: Align(
alignment: Alignment.centerRight,
child: action ?? SizedBox(),
child: action ?? const SizedBox(),
))
],
),
@@ -43,9 +41,9 @@ class AppBarWidget extends StatelessWidget implements PreferredSizeWidget {
Get.back();
},
)
: SizedBox(),
: const SizedBox(),
automaticallyImplyLeading: false,
actions: [SizedBox()],
actions: [const SizedBox()],
),
);
}

+ 1
- 1
lib/presentation/custom_widgets/bloc/media_helper_event.dart View File

@@ -9,5 +9,5 @@ abstract class MediaHelperEvent {

class ChangeListMedia extends MediaHelperEvent {
final List<Media> items;
ChangeListMedia({@required this.items});
ChangeListMedia({required this.items});
}

+ 3
- 3
lib/presentation/custom_widgets/bloc/media_helper_state.dart View File

@@ -11,15 +11,15 @@ class MediaHelperInitial extends MediaHelperState {}

class MediaHelperFailure extends MediaHelperState {
final String errorString;
MediaHelperFailure({@required this.errorString});
MediaHelperFailure({required this.errorString});
}

class MediaHelperSuccess extends MediaHelperState {
final List<Media> items;

const MediaHelperSuccess({@required this.items});
const MediaHelperSuccess({required this.items});

MediaHelperSuccess copyWith({List<Media> items}) {
MediaHelperSuccess copyWith({List<Media>? items}) {
return MediaHelperSuccess(items: items ?? this.items);
}


+ 4
- 8
lib/presentation/custom_widgets/bloc/widget_row_plot_info.dart View File

@@ -4,8 +4,7 @@ class WidgetRowPlotInfo extends StatelessWidget {
final Color color;
final String name;
final String value;
WidgetRowPlotInfo(
{@required this.color, @required this.name, @required this.value});
WidgetRowPlotInfo({required this.color, required this.name, required this.value});
@override
Widget build(BuildContext context) {
return Container(
@@ -16,10 +15,10 @@ class WidgetRowPlotInfo extends StatelessWidget {
children: [
Expanded(
child: Container(
padding: EdgeInsets.all(12),
padding: const EdgeInsets.all(12),
child: Text(
name,
style: TextStyle(fontSize: 16),
style: const TextStyle(fontSize: 16),
),
),
),
@@ -29,10 +28,7 @@ class WidgetRowPlotInfo extends StatelessWidget {
),
Expanded(
child: Container(
padding: EdgeInsets.all(12),
child: Text(value ?? '--',
textAlign: TextAlign.end,
style: TextStyle(fontSize: 16))),
padding: const EdgeInsets.all(12), child: Text(value ?? '--', textAlign: TextAlign.end, style: const TextStyle(fontSize: 16))),
),
],
),

+ 1
- 1
lib/presentation/custom_widgets/bottom_loader.dart View File

@@ -5,7 +5,7 @@ class BottomLoader extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Center(
child: const Center(
child: SizedBox(
width: 33,
height: 33,

+ 20
- 28
lib/presentation/custom_widgets/button_icon_widget.dart View File

@@ -4,16 +4,16 @@ import 'package:flutter_svg/flutter_svg.dart';

class ButtonIconWidget extends StatelessWidget {
final String title;
final TextStyle titleStyle;
final String subTitle;
final TextStyle? titleStyle;
final String? subTitle;
final Function onTap;
final String leadingIcon;
final String trailingIcon;
final String? leadingIcon;
final String? trailingIcon;
final bool isTopBorder;
final bool isBottomBorder;
ButtonIconWidget(
{@required this.title,
@required this.onTap,
{required this.title,
required this.onTap,
this.titleStyle,
this.subTitle,
this.leadingIcon,
@@ -25,29 +25,22 @@ class ButtonIconWidget extends StatelessWidget {
return SizedBox(
width: double.infinity,
child: MaterialButton(
padding: EdgeInsets.all(0),
onPressed: onTap,
padding: const EdgeInsets.all(0),
onPressed: () {
onTap();
},
child: Container(
padding: EdgeInsets.all(12),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border(
top: isTopBorder
? BorderSide(color: AppColors.GRAY1, width: 0.35)
: BorderSide.none,
bottom: isBottomBorder
? BorderSide(color: AppColors.GRAY1, width: 0.35)
: BorderSide.none)),
top: isTopBorder ? BorderSide(color: AppColors.GRAY1, width: 0.35) : BorderSide.none,
bottom: isBottomBorder ? BorderSide(color: AppColors.GRAY1, width: 0.35) : BorderSide.none)),
width: double.infinity,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
leadingIcon == null
? SizedBox()
: SizedBox(
width: 20,
height: 20,
child: SvgPicture.asset(leadingIcon)),
SizedBox(width: 4),
leadingIcon == null ? const SizedBox() : SizedBox(width: 20, height: 20, child: SvgPicture.asset(leadingIcon)),
const SizedBox(width: 4),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -55,19 +48,18 @@ class ButtonIconWidget extends StatelessWidget {
children: [
Text(
title,
style: titleStyle ??
TextStyle(fontSize: 16, fontWeight: FontWeight.w100),
style: titleStyle ?? const TextStyle(fontSize: 16, fontWeight: FontWeight.w100),
),
subTitle == null
? SizedBox()
? const SizedBox()
: Text(
subTitle,
style: TextStyle(fontSize: 14),
subTitle ?? '',
style: const TextStyle(fontSize: 14),
)
],
),
),
trailingIcon == null ? SizedBox() : SvgPicture.asset(trailingIcon)
trailingIcon == null ? const SizedBox() : SvgPicture.asset(trailingIcon)
],
),
),

+ 6
- 8
lib/presentation/custom_widgets/button_widget.dart View File

@@ -4,23 +4,21 @@ import 'package:flutter/material.dart';
class ButtonWidget extends StatelessWidget {
final Function onPressed;
final String title;
ButtonWidget({@required this.title, @required this.onPressed});
ButtonWidget({required this.title, required this.onPressed});
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 55,
child: FlatButton(
onPressed: onPressed,
onPressed: () {
onPressed();
},
color: AppColors.DEFAULT,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(7.0),
borderRadius: BorderRadius.circular(7.0),
),
child: Text(title.toUpperCase(),
style: TextStyle(
fontWeight: FontWeight.bold,
color: AppColors.WHITE,
fontSize: 18)),
child: Text(title.toUpperCase(), style: TextStyle(fontWeight: FontWeight.bold, color: AppColors.WHITE, fontSize: 18)),
),
);
}

+ 33
- 61
lib/presentation/custom_widgets/camera_helper.dart View File

@@ -27,36 +27,33 @@ IconData getCameraLensIcon(CameraLensDirection direction) {
throw ArgumentError('Unknown lens direction');
}

void logError(String code, String message) =>
print('Error: $code\nError Message: $message');

class _CameraHelperState extends State<CameraHelper>
with WidgetsBindingObserver {
CameraController controller;
String imagePath;
String videoPath;
VideoPlayerController videoController;
VoidCallback videoPlayerListener;
void logError(String code, String message) => print('Error: $code\nError Message: $message');

class _CameraHelperState extends State<CameraHelper> with WidgetsBindingObserver {
late CameraController controller;
String? imagePath;
String? videoPath;
VideoPlayerController? videoController;
VoidCallback? videoPlayerListener;
bool enableAudio = true;
int indexCamera = 0;

@override
void initState() {
super.initState();
controller =
CameraController(cameras[indexCamera], ResolutionPreset.medium);
controller = CameraController(cameras[indexCamera], ResolutionPreset.medium);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance?.addObserver(this);
}

@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}

@@ -97,14 +94,8 @@ class _CameraHelperState extends State<CameraHelper>
decoration: BoxDecoration(
color: Colors.black,
border: Border.all(
color:
controller != null && controller.value.isRecordingVideo
? Colors.redAccent
: Colors.grey,
width:
controller != null && controller.value.isRecordingVideo
? 1.0
: 0.0,
color: controller != null && controller.value.isRecordingVideo ? Colors.redAccent : Colors.grey,
width: controller != null && controller.value.isRecordingVideo ? 1.0 : 0.0,
),
),
),
@@ -142,7 +133,7 @@ class _CameraHelperState extends State<CameraHelper>
mainAxisSize: MainAxisSize.max,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
icon: const Icon(Icons.arrow_back),
onPressed: () {
Get.back();
}),
@@ -153,42 +144,24 @@ class _CameraHelperState extends State<CameraHelper>
size: 30,
),
color: Colors.blue,
onPressed: controller != null &&
controller.value.isInitialized &&
!controller.value.isRecordingVideo
? onTakePictureButtonPressed
: null,
onPressed: controller != null && controller.value.isInitialized && !controller.value.isRecordingVideo ? onTakePictureButtonPressed : null,
),
IconButton(
icon: const Icon(Icons.videocam, size: 35),
color: Colors.blue,
onPressed: controller != null &&
controller.value.isInitialized &&
!controller.value.isRecordingVideo
? onVideoRecordButtonPressed
: null,
onPressed: controller != null && controller.value.isInitialized && !controller.value.isRecordingVideo ? onVideoRecordButtonPressed : null,
),
IconButton(
icon: controller != null && controller.value.isRecordingPaused
? Icon(Icons.play_arrow)
: Icon(Icons.pause),
icon: controller != null && controller.value.isRecordingPaused ? const Icon(Icons.play_arrow) : const Icon(Icons.pause),
color: Colors.blue,
onPressed: controller != null &&
controller.value.isInitialized &&
controller.value.isRecordingVideo
? (controller != null && controller.value.isRecordingPaused
? onResumeButtonPressed
: onPauseButtonPressed)
onPressed: controller != null && controller.value.isInitialized && controller.value.isRecordingVideo
? (controller != null && controller.value.isRecordingPaused ? onResumeButtonPressed : onPauseButtonPressed)
: null,
),
IconButton(
icon: const Icon(Icons.stop),
color: Colors.red,
onPressed: controller != null &&
controller.value.isInitialized &&
controller.value.isRecordingVideo
? onStopButtonPressed
: null,
onPressed: controller != null && controller.value.isInitialized && controller.value.isRecordingVideo ? onStopButtonPressed : null,
)
],
);
@@ -199,15 +172,14 @@ class _CameraHelperState extends State<CameraHelper>
if (cameras.isEmpty) {
return const Text('Không có camera');
} else {
bool disableSwitch =
controller != null && controller.value.isRecordingVideo;
var disableSwitch = controller != null && controller.value.isRecordingVideo;
if (indexCamera == cameras.length - 1) {
indexCamera = 0;
} else {
indexCamera++;
}
return IconButton(
icon: Icon(
icon: const Icon(
Icons.switch_camera,
color: Colors.green,
),
@@ -260,7 +232,7 @@ class _CameraHelperState extends State<CameraHelper>
setState(() {
imagePath = filePath;
videoController?.dispose();
videoController = null;
// videoController = null;
});
if (filePath != null) {
print('Picture saved to $filePath');
@@ -306,17 +278,17 @@ class _CameraHelperState extends State<CameraHelper>
Future<String> startVideoRecording() async {
if (!controller.value.isInitialized) {
showInSnackBar('Vui lòng chọn camera');
return null;
// return null;
}

final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Movies/tpf';
final dirPath = '${extDir.path}/Movies/tpf';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.mp4';
final filePath = '$dirPath/${timestamp()}.mp4';

if (controller.value.isRecordingVideo) {
// A recording is already started, do nothing.
return null;
// return null;
}

try {
@@ -324,7 +296,7 @@ class _CameraHelperState extends State<CameraHelper>
await controller.startVideoRecording(filePath);
} on CameraException catch (e) {
_showCameraException(e);
return null;
// return null;
}
return filePath;
}
@@ -371,23 +343,23 @@ class _CameraHelperState extends State<CameraHelper>
Future<String> takePicture() async {
if (!controller.value.isInitialized) {
showInSnackBar('Vui lòng chọn camera');
return null;
// return null;
}
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/tpf';
final dirPath = '${extDir.path}/Pictures/tpf';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
final filePath = '$dirPath/${timestamp()}.jpg';

if (controller.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
// return null;
}

try {
await controller.takePicture(filePath);
} on CameraException catch (e) {
_showCameraException(e);
return null;
// return null;
}
return filePath;
}

+ 6
- 6
lib/presentation/custom_widgets/hoz_list_view.dart View File

@@ -7,9 +7,9 @@ class WrapContentHozListView<T> extends StatefulWidget {
IndexedWidgetBuilder separatorBuilder;

WrapContentHozListView({
@required this.list,
@required this.itemBuilder,
this.separatorBuilder,
required this.list,
required this.itemBuilder,
required this.separatorBuilder,
});

@override
@@ -18,8 +18,8 @@ class WrapContentHozListView<T> extends StatefulWidget {

class _WrapContentHozListViewState extends State<WrapContentHozListView> {
List<Widget> _generateItemWidgets() {
List<Widget> items = [];
for (int i = 0; i < widget.list.length; i++) {
var items = <Widget>[];
for (var i = 0; i < widget.list.length; i++) {
items.add(widget.itemBuilder(context, i));
if (widget.separatorBuilder != null) {
items.add(widget.separatorBuilder(context, i));
@@ -34,7 +34,7 @@ class _WrapContentHozListViewState extends State<WrapContentHozListView> {
return SingleChildScrollView(
reverse: false,
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
physics: const BouncingScrollPhysics(),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,

+ 13
- 13
lib/presentation/custom_widgets/shimmer_image.dart View File

@@ -3,11 +3,11 @@ import 'package:shimmer/shimmer.dart';

class ShimmerImage extends StatelessWidget {
String url;
BoxFit fit;
double width;
double height;
double aspectRatio;
double iconHolderSize = 40;
BoxFit? fit;
double? width;
double? height;
double? aspectRatio;
double? iconHolderSize = 40;

ShimmerImage(
this.url, {
@@ -25,22 +25,22 @@ class ShimmerImage extends StatelessWidget {
Shimmer.fromColors(
baseColor: Colors.grey[200],
highlightColor: Colors.grey[100],
child: this.aspectRatio != null
child: aspectRatio != null
? AspectRatio(
aspectRatio: aspectRatio,
aspectRatio: aspectRatio ?? 1,
child: Container(
child: _buildIcon(),
),
)
: Container(
width: this.width,
height: this.height,
width: width,
height: height,
child: _buildIcon(),
),
),
this.aspectRatio != null
aspectRatio != null
? AspectRatio(
aspectRatio: aspectRatio,
aspectRatio: aspectRatio ?? 1,
child: Image.network(
url,
fit: fit ?? BoxFit.contain,
@@ -48,8 +48,8 @@ class ShimmerImage extends StatelessWidget {
)
: Image.network(
url,
width: this.width,
height: this.height,
width: width,
height: height,
fit: fit ?? BoxFit.contain,
),
],

+ 10
- 16
lib/presentation/custom_widgets/widget_field_time_picker.dart View File

@@ -8,11 +8,9 @@ import 'package:get/state_manager.dart';
class WidgetFieldDateTimePicker extends StatefulWidget {
final DateTime initDateTime;
final Function(DateTime selectedDateTimeLocal) onUpdateDateTime;
WidgetFieldDateTimePicker(
{@required this.initDateTime, @required this.onUpdateDateTime});
WidgetFieldDateTimePicker({required this.initDateTime, required this.onUpdateDateTime});
@override
_WidgetFieldDateTimePickerState createState() =>
_WidgetFieldDateTimePickerState();
_WidgetFieldDateTimePickerState createState() => _WidgetFieldDateTimePickerState();
}

class _WidgetFieldDateTimePickerState extends State<WidgetFieldDateTimePicker> {
@@ -28,20 +26,16 @@ class _WidgetFieldDateTimePickerState extends State<WidgetFieldDateTimePicker> {
Widget build(BuildContext context) {
return GetBuilder<ChangeDateTimePicker>(builder: (value) {
return FlatButton(
padding:
EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
onPressed: () {
DatePicker.showDateTimePicker(context,
showTitleActions: true,
onChanged: (date) {}, onConfirm: (date) {
DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
changeDate.change(date);
widget.onUpdateDateTime(date);
}, currentTime: value.selectedDateTime, locale: LocaleType.vi);
},
child: Container(
padding: EdgeInsets.only(
top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: BoxDecoration(
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: const BoxDecoration(
border: kBorderTextField,
),
child: Row(
@@ -49,9 +43,9 @@ class _WidgetFieldDateTimePickerState extends State<WidgetFieldDateTimePicker> {
Expanded(
child: Text(
value.selectedDateTime.displayDateTime_DDMMYYYY_HHmm(),
style: TextStyle(fontSize: 14.0, color: Colors.black87),
style: const TextStyle(fontSize: 14.0, color: Colors.black87),
)),
Icon(
const Icon(
Icons.date_range,
color: Colors.grey,
),
@@ -62,8 +56,8 @@ class _WidgetFieldDateTimePickerState extends State<WidgetFieldDateTimePicker> {
}

class ChangeDateTimePicker extends GetxController {
DateTime selectedDateTime;
initValue({DateTime selectedDate}) {
DateTime selectedDateTime = DateTime.now();
initValue({DateTime? selectedDate}) {
selectedDateTime = selectedDate ?? DateTime.now();
update();
}

+ 3
- 3
lib/presentation/custom_widgets/widget_loading.dart View File

@@ -18,10 +18,10 @@ class LoadingDialog {
Align(
alignment: Alignment.center,
child: Container(
decoration: new BoxDecoration(
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
new BorderRadius.all(Radius.circular(16.0))),
const BorderRadius.all(Radius.circular(16.0))),
width: 80.0,
height: 80.0),
),
@@ -34,7 +34,7 @@ class LoadingDialog {
),
Container(
alignment: Alignment.center,
child: SizedBox(
child: const SizedBox(
child: CircularProgressIndicator(
strokeWidth: 2.0,
),

+ 64
- 84
lib/presentation/custom_widgets/widget_media_picker.dart View File

@@ -18,18 +18,17 @@ import 'bloc/media_helper_bloc.dart';
import 'hoz_list_view.dart';

class WidgetMediaPicker extends StatefulWidget {
final List<Media> currentItems;
final Function(List<String> addNewFilePaths, List<String> deleteFilePaths)
onChangeFiles;
WidgetMediaPicker({this.currentItems, @required this.onChangeFiles});
final List<Media>? currentItems;
final Function(List<String> addNewFilePaths, List<String> deleteFilePaths) onChangeFiles;
WidgetMediaPicker({this.currentItems, required this.onChangeFiles});
@override
_WidgetMediaPickerState createState() => _WidgetMediaPickerState();
}

class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
List<Media> currentItems = [];
List<String> addNewFilePaths = new List<String>();
List<String> deleteFilePaths = new List<String>();
List<String> addNewFilePaths = <String>[];
List<String> deleteFilePaths = <String>[];

@override
void initState() {
@@ -39,22 +38,19 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
@override
Widget build(BuildContext context) {
return BlocProvider<MediaHelperBloc>(
create: (BuildContext contextA) =>
MediaHelperBloc()..add(ChangeListMedia(items: currentItems)),
child: BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (contextB, state) {
create: (BuildContext contextA) => MediaHelperBloc()..add(ChangeListMedia(items: currentItems)),
child: BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (contextB, state) {
if (state is MediaHelperFailure) {
return Container();
} else if (state is MediaHelperSuccess) {
currentItems = widget.currentItems ?? [];
return Container(
padding: EdgeInsets.all(8),
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Hình ảnh/ Video',
style: TextStyle(color: Colors.black54, fontSize: 16)),
SizedBox(
const Text('Hình ảnh/ Video', style: TextStyle(color: Colors.black54, fontSize: 16)),
const SizedBox(
height: 8,
),
Row(
@@ -76,7 +72,7 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
));
},
),
SizedBox(
const SizedBox(
width: 8.0,
),
Expanded(
@@ -93,33 +89,30 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {

Widget multipleChoice(BuildContext context) {
return CupertinoAlertDialog(
title: Text(label_title_select_media),
title: const Text(label_title_select_media),
actions: <Widget>[
CupertinoDialogAction(
child: const Text(label_take_photo_or_video),
onPressed: () {
Navigator.pop(context, 'Discard');
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => CameraHelper()))
.then((value) {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => CameraHelper())).then((value) {
if (value != null) {
print("ok");
print(value);
String filePath = value[0];
File f = File(filePath);
var f = File(filePath);
f.length().then((lengthFileInBytes) {
if (lengthFileInBytes > ConstCommon.kFileSize) {
Utils.showSnackBarWarning(message: label_file_to_large);
} else {
bool isVideo = value[1];
Media newMedia = Media()
var newMedia = Media()
..isVideo = isVideo
..isServerFile = false
..pathFile = filePath;
currentItems.add(newMedia);
addNewFilePaths.add(filePath);
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
}
});
@@ -130,20 +123,19 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
child: const Text(label_select_image_from_library),
onPressed: () async {
Navigator.pop(context, 'Discard');
FilePickerResult result = await FilePicker.platform
.pickFiles(type: FileType.image, allowMultiple: true);
FilePickerResult result = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true);
if (result != null) {
var listFuture = List<Future<File>>();
var listFuture = <Future<File>>[];
result.files.forEach((element) {
listFuture.add(UtilAction.compressImage(File(element.path)));
});
Future.wait(listFuture).then((values) {
bool isExistedFileTooLarge = false;
var isExistedFileTooLarge = false;
values.forEach((compressFile) {
if (compressFile.lengthSync() > ConstCommon.kFileSize) {
isExistedFileTooLarge = true;
} else {
Media newMedia = Media()
var newMedia = Media()
..isVideo = false
..isServerFile = false
..pathFile = compressFile.path;
@@ -152,11 +144,9 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
}
});
if (isExistedFileTooLarge) {
Utils.showSnackBarWarning(
message: "Tập tin có kích thước lớn đã được loại bỏ.");
Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ.");
}
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
});
}
@@ -165,16 +155,15 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
child: const Text(label_select_video_from_library),
onPressed: () async {
Navigator.pop(context, 'Discard');
FilePickerResult result = await FilePicker.platform
.pickFiles(type: FileType.video, allowMultiple: true);
FilePickerResult result = await FilePicker.platform.pickFiles(type: FileType.video, allowMultiple: true);

if (result != null) {
bool isExistedFileTooLarge = false;
var isExistedFileTooLarge = false;
result.files?.forEach((videoFile) {
if (videoFile.size * 1000 > ConstCommon.kFileSize) {
isExistedFileTooLarge = true;
} else {
Media newMedia = Media()
var newMedia = Media()
..isVideo = true
..isServerFile = false
..pathFile = videoFile.path;
@@ -183,17 +172,15 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
}
});
if (isExistedFileTooLarge) {
Utils.showSnackBarWarning(
message: "Tập tin có kích thước lớn đã được loại bỏ.");
Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ.");
}
BlocProvider.of<MediaHelperBloc>(context)
..add(ChangeListMedia(items: currentItems));
BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems));
widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
}
}),
CupertinoDialogAction(
child: const Text(label_cancel),
textStyle: TextStyle(fontWeight: FontWeight.bold),
textStyle: const TextStyle(fontWeight: FontWeight.bold),
isDefaultAction: true,
onPressed: () {
Navigator.pop(context, 'Cancel');
@@ -203,32 +190,33 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> {
}

_buildListPoster() {
return BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (context, state) {
return BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
return WrapContentHozListView(
list: currentItems,
itemBuilder: (context, index) {
var item = currentItems[index];
return Container(
width: 120,
height: 120,
child: _WidgetItemMedia(
item: item,
deleteImage: (item) {
if (item.isServerFile) {
var url = item.pathFile
.replaceAll(ConstCommon.baseImageUrl, '');
deleteFilePaths.add(url);
}
addNewFilePaths.remove(item.pathFile);
currentItems.remove(item);
widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(items: currentItems));
}),
);
});
list: currentItems,
itemBuilder: (context, index) {
var item = currentItems[index];
return Container(
width: 120,
height: 120,
child: _WidgetItemMedia(
item: item,
deleteImage: (item) {
if (item.isServerFile ?? false) {
var url = item.pathFile?.replaceAll(ConstCommon.baseImageUrl, '');
deleteFilePaths.add(url ?? '');
}
addNewFilePaths.remove(item.pathFile);
currentItems.remove(item);
widget.onChangeFiles(addNewFilePaths, deleteFilePaths);
BlocProvider.of<MediaHelperBloc>(context).add(ChangeListMedia(items: currentItems));
}),
);
},
separatorBuilder: (BuildContext context, int index) {
return const SizedBox.shrink();
},
);
}
return Container();
});
@@ -239,48 +227,40 @@ class _WidgetItemMedia extends StatelessWidget {
ItemMediaCallback deleteImage;
final Media item;

_WidgetItemMedia({@required this.item, @required this.deleteImage});
_WidgetItemMedia({required this.item, required this.deleteImage});

BuildContext _context;
double positionIconDelete = -(120.0 - 36);

@override
Widget build(BuildContext context) {
_context = context;
return GestureDetector(
onTap: () {
print("Show preview image or video");
},
child: Stack(
alignment: Alignment.topRight,
overflow: Overflow.visible,
// overflow: Overflow.visible,
children: <Widget>[
Positioned.fill(
child: item.isVideo
child: (item.isVideo ?? false)
? VideoWidget(
pathFile: item.pathFile,
isServerFile: item.isServerFile,
pathFile: item.pathFile ?? '',
isServerFile: item.isServerFile ?? false,
play: false,
)
: Container(
margin: EdgeInsets.all(4.0),
margin: const EdgeInsets.all(4.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
borderRadius:
BorderRadius.all(Radius.circular(8.0))),
child: item.isServerFile
? CachedNetworkImage(
placeholder: (context, url) =>
Icon(Icons.crop_original),
imageUrl: item.pathFile)
: Image.file(File(item.pathFile)),
color: Colors.white, border: Border.all(color: Colors.grey), borderRadius: const BorderRadius.all(Radius.circular(8.0))),
child: (item.isServerFile ?? false)
? CachedNetworkImage(placeholder: (context, url) => const Icon(Icons.crop_original), imageUrl: item.pathFile)
: Image.file(File(item.pathFile ?? '')),
)),
Positioned.fill(
top: positionIconDelete,
right: positionIconDelete,
child: IconButton(
icon: Icon(
icon: const Icon(
Icons.delete,
color: Colors.redAccent,
size: 24,

+ 5
- 5
lib/presentation/custom_widgets/widget_rounded_rect_indicator.dart View File

@@ -4,14 +4,14 @@ class RoundedRectIndicator extends Decoration {
final BoxPainter _painter;

RoundedRectIndicator({
@required Color color,
@required double radius,
required Color color,
required double radius,
double padding = 0.0,
double weight = 3.0,
}) : _painter = _RectPainter(color, radius, padding, weight);

@override
BoxPainter createBoxPainter([onChanged]) {
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _painter;
}
}
@@ -30,8 +30,8 @@ class _RectPainter extends BoxPainter {

@override
void paint(Canvas canvas, Offset offset, ImageConfiguration cfg) {
var width = cfg.size.width;
var height = cfg.size.height;
var width = cfg.size?.width ?? 0.0;
var height = cfg.size?.height ?? 0.0;

var left = 0.0;
var top = height - indicatorPaddingBottom;

+ 3
- 6
lib/presentation/custom_widgets/widget_search.dart View File

@@ -3,13 +3,12 @@ import 'package:flutter/material.dart';

class SearchWidget extends StatefulWidget {
final Function(String) searchPressed;
SearchWidget({@required this.searchPressed});
SearchWidget({required this.searchPressed});
@override
_SearchWidgetState createState() => _SearchWidgetState();
}

class _SearchWidgetState extends State<SearchWidget> {
BuildContext _blocContext;
TextEditingController _searchController = TextEditingController();

@override
@@ -34,8 +33,7 @@ class _SearchWidgetState extends State<SearchWidget> {
padding: const EdgeInsets.only(right: 8, top: 0, bottom: 0),
child: Container(
child: Padding(
padding: const EdgeInsets.only(
left: 16, right: 16, top: 4, bottom: 4),
padding: const EdgeInsets.only(left: 16, right: 16, top: 4, bottom: 4),
child: TextField(
textInputAction: TextInputAction.done,
controller: _searchController,
@@ -43,7 +41,7 @@ class _SearchWidgetState extends State<SearchWidget> {
cursorColor: AppColors.GRAY1,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
icon: const Icon(
Icons.search,
size: 30,
),
@@ -66,7 +64,6 @@ class _SearchWidgetState extends State<SearchWidget> {

@override
Widget build(BuildContext context) {
_blocContext = context;
return Container(child: getSearchBarUI());
}


+ 9
- 16
lib/presentation/custom_widgets/widget_show_video.dart View File

@@ -9,20 +9,15 @@ class VideoWidget extends StatefulWidget {
final bool isServerFile;
final String pathFile;

const VideoWidget(
{Key key,
@required this.pathFile,
@required this.play,
@required this.isServerFile})
: super(key: key);
const VideoWidget({Key? key, required this.pathFile, required this.play, required this.isServerFile}) : super(key: key);

@override
_VideoWidgetState createState() => _VideoWidgetState();
}

class _VideoWidgetState extends State<VideoWidget> {
VideoPlayerController videoPlayerController;
Future<void> _initializeVideoPlayerFuture;
late VideoPlayerController videoPlayerController;
late Future<void> _initializeVideoPlayerFuture;

@override
void initState() {
@@ -37,7 +32,7 @@ class _VideoWidgetState extends State<VideoWidget> {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
videoPlayerController.play();
videoPlayerController.setVolume(0.0);
Timer.periodic(Duration(seconds: 1), (_) {
Timer.periodic(const Duration(seconds: 1), (_) {
videoPlayerController.pause();
});
setState(() {});
@@ -57,23 +52,21 @@ class _VideoWidgetState extends State<VideoWidget> {
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return new Container(
return Container(
child: Container(
key: new PageStorageKey(widget.pathFile),
key: PageStorageKey(widget.pathFile),
child: Container(
padding: EdgeInsets.all(1),
padding: const EdgeInsets.all(1),
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(8.0))),
color: Colors.white, border: Border.all(color: Colors.red), borderRadius: const BorderRadius.all(Radius.circular(8.0))),
child: VideoPlayer(videoPlayerController),
),
),
);
} else {
return Center(
return const Center(
child: CircularProgressIndicator(),
);
}

+ 7
- 11
lib/presentation/custom_widgets/widget_text_field_description.dart View File

@@ -4,23 +4,19 @@ import 'package:farm_tpf/utils/const_color.dart';
class TextFieldDescriptionWidget extends StatelessWidget {
final TextEditingController controller;
final Function onSaved;
TextFieldDescriptionWidget(
{@required this.onSaved, @required this.controller});
TextFieldDescriptionWidget({required this.onSaved, required this.controller});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: AppColors.YELLOW.withOpacity(0.1),
borderRadius: BorderRadius.circular(8)),
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(color: AppColors.YELLOW.withOpacity(0.1), borderRadius: BorderRadius.circular(8)),
child: TextFormField(
keyboardType: TextInputType.text,
controller: controller,
decoration: InputDecoration(
labelText: "Ghi chú",
hintText: 'Ghi chú',
border: InputBorder.none),
onSaved: onSaved,
decoration: const InputDecoration(labelText: "Ghi chú", hintText: 'Ghi chú', border: InputBorder.none),
onSaved: (v) {
onSaved();
},
),
);
}

+ 10
- 13
lib/presentation/custom_widgets/widget_text_form_field.dart View File

@@ -8,20 +8,16 @@ import 'package:pattern_formatter/pattern_formatter.dart';

class WidgetTextFormFieldNumber extends StatelessWidget {
final TextEditingController textController;
final void Function(String) onSaved;
final void Function(String) validator;
final void Function(String?) onSaved;
final void Function(String?) validator;
final void Function(String) onChanged;
final String hintValue;
WidgetTextFormFieldNumber(
{@required this.textController,
this.onSaved,
@required this.hintValue,
this.validator,
this.onChanged});
{required this.textController, required this.onSaved, required this.hintValue, required this.validator, required this.onChanged});
@override
Widget build(BuildContext context) {
return TextFormField(
keyboardType: TextInputType.numberWithOptions(decimal: true),
keyboardType: const TextInputType.numberWithOptions(decimal: true),
inputFormatters: [
FilteringTextInputFormatter.allow(ConstCommon.regExpDecimal),
ThousandsFormatter(allowFraction: true),
@@ -29,12 +25,13 @@ class WidgetTextFormFieldNumber extends StatelessWidget {
decoration: InputDecoration(
labelText: hintValue,
),
validator: validator ??
(String value) {
return Validators.validNumberOrEmpty(value, label_invalid_number);
},
validator: (v) {
validator(v);
},
controller: textController,
onSaved: onSaved,
onSaved: (v) {
onSaved(v);
},
onChanged: onChanged,
);
}

+ 4
- 4
lib/presentation/custom_widgets/widget_toast.dart View File

@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';

class WidgetToast extends StatelessWidget {
String message;
Color color = Colors.green;
WidgetToast({@required this.message, this.color});
Color? color = Colors.green;
WidgetToast({required this.message, this.color});

@override
Widget build(BuildContext context) {
@@ -16,8 +16,8 @@ class WidgetToast extends StatelessWidget {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.check),
SizedBox(
const Icon(Icons.check),
const SizedBox(
width: 12.0,
),
Text(message),

+ 8
- 12
lib/presentation/custom_widgets/widget_utils.dart View File

@@ -2,10 +2,10 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';

class Utils {
static void showSnackBarSuccess({String message}) {
static void showSnackBarSuccess({required String message}) {
if (Get.isSnackbarOpen) Get.back();
Get.snackbar(null, message,
icon: Icon(
icon: const Icon(
Icons.done,
color: Colors.white,
),
@@ -13,10 +13,10 @@ class Utils {
backgroundColor: Colors.green);
}

static void showSnackBarError({String message}) {
static void showSnackBarError({required String message}) {
if (Get.isSnackbarOpen) Get.back();
Get.snackbar(null, message,
icon: Icon(
icon: const Icon(
Icons.error,
color: Colors.white,
),
@@ -24,10 +24,10 @@ class Utils {
backgroundColor: Colors.red);
}

static void showSnackBarWarning({String message}) {
static void showSnackBarWarning({required String message}) {
if (Get.isSnackbarOpen) Get.back();
Get.snackbar(null, message,
icon: Icon(
icon: const Icon(
Icons.warning,
color: Colors.yellow,
),
@@ -36,11 +36,7 @@ class Utils {
}

static void showDialog(
{@required String title,
@required String message,
@required String textConfirm,
@required String textCancel,
@required Function() onConfirm}) {
{required String title, required String message, required String textConfirm, required String textCancel, required Function() onConfirm}) {
if (Get.isDialogOpen) Get.back();
Get.defaultDialog(
title: title,
@@ -52,7 +48,7 @@ class Utils {
);
}

static void showDialogConfirmSupply({@required Function() onConfirm}) {
static void showDialogConfirmSupply({required Function() onConfirm}) {
if (Get.isDialogOpen) Get.back();
Get.defaultDialog(
title: "Vật tư chưa được thêm",

+ 7
- 7
lib/presentation/screens/account/sc_account.dart View File

@@ -40,7 +40,7 @@ class _AccountScreenState extends State<AccountScreen> {
_clickSignOut() async {
context.bloc<AuthenticationBloc>().add(AuthenticationLogoutRequested());
try {
String pushKey = await pref.getString(DATA_CONST.PUSH_KEY);
var pushKey = await pref.getString(DATA_CONST.PUSH_KEY);
if (pushKey.isNotEmpty) {
_userRepository
.deleteFcmToken(pushKey)
@@ -67,13 +67,13 @@ class _AccountScreenState extends State<AccountScreen> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(
const SizedBox(
height: 8,
),
Container(
padding: EdgeInsets.all(8),
padding: const EdgeInsets.all(8),
color: Colors.white,
child: Text(
child: const Text(
'Cá nhân',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
)),
@@ -103,10 +103,10 @@ class _AccountScreenState extends State<AccountScreen> {
),
Container(
padding:
EdgeInsets.only(left: 12, right: 8, top: 14, bottom: 14),
const EdgeInsets.only(left: 12, right: 8, top: 14, bottom: 14),
child: Row(
children: [
Expanded(
const Expanded(
child: Text(
'Phiên bản',
style:
@@ -118,7 +118,7 @@ class _AccountScreenState extends State<AccountScreen> {
),
ButtonIconWidget(
title: 'Đăng xuất',
titleStyle: TextStyle(
titleStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w100,
color: Colors.red),

+ 3
- 5
lib/presentation/screens/actions/bloc/action_detail_bloc.dart View File

@@ -17,7 +17,7 @@ part 'action_detail_state.dart';

class ActionDetailBloc extends Bloc<ActionDetailEvent, ActionDetailState> {
final Repository repository;
ActionDetailBloc({@required this.repository}) : super(ActionDetailInitial());
ActionDetailBloc({required this.repository}) : super(ActionDetailInitial());
final dio = DioProvider.instance();

@override
@@ -30,13 +30,11 @@ class ActionDetailBloc extends Bloc<ActionDetailEvent, ActionDetailState> {
} else {
try {
yield ActionDetailLoading();
Response<String> response = await dio.get(
"${ConstCommon.baseUrl}/${event.apiActivity}/${event.activityId}");
Response<String> response = await dio.get("${ConstCommon.baseUrl}/${event.apiActivity}/${event.activityId}");
final jsonData = json.decode(response.data);
yield ActionDetailSuccess(item: jsonData);
} catch (error) {
yield ActionDetailFailure(
errorString: AppException.handleError(error));
yield ActionDetailFailure(errorString: AppException.handleError(error));
}
}
}

+ 1
- 4
lib/presentation/screens/actions/bloc/action_detail_event.dart View File

@@ -11,8 +11,5 @@ class FetchData extends ActionDetailEvent {
final bool isNeedFetchData;
final String apiActivity;
final int activityId;
FetchData(
{@required this.isNeedFetchData,
@required this.apiActivity,
@required this.activityId});
FetchData({required this.isNeedFetchData, required this.apiActivity, required this.activityId});
}

+ 4
- 4
lib/presentation/screens/actions/bloc/action_detail_state.dart View File

@@ -13,14 +13,14 @@ class ActionDetailLoading extends ActionDetailState {}

class ActionDetailFailure extends ActionDetailState {
final String errorString;
ActionDetailFailure({@required this.errorString});
ActionDetailFailure({required this.errorString});
}

class ActionDetailSuccess<T> extends ActionDetailState {
final T item;

ActionDetailSuccess({this.item});
ActionDetailSuccess({required this.item});

@override
List<Object> get props => [item];
// @override
// List<Object> get props => [item];
}

+ 2
- 3
lib/presentation/screens/actions/bloc_get_harvest.dart View File

@@ -7,8 +7,7 @@ class GetHarvestBloc {

Stream<dynamic> get actions => _getHarvestFetcher.stream;

void getHarvests(
Function(dynamic) onSuccess, Function(String) onError) async {
void getHarvests(Function(dynamic) onSuccess, Function(String) onError) async {
try {
_repository.getHarvests().then((value) {
onSuccess(value);
@@ -19,7 +18,7 @@ class GetHarvestBloc {
});
} catch (e) {
_getHarvestFetcher.addError(e);
onError(e);
onError(e.toString());
}
}


+ 5
- 5
lib/presentation/screens/actions/controller/ChangeDevice.dart View File

@@ -2,9 +2,9 @@ import 'package:farm_tpf/custom_model/Device.dart';
import 'package:get/get.dart';

class ChangeDevice extends GetxController {
Device currentDevice;
int selectedDeviceId;
String selectedDeviceName;
Device currentDevice = Device();
int selectedDeviceId = -1;
String selectedDeviceName = '';

void initValue() {
currentDevice = Device();
@@ -15,8 +15,8 @@ class ChangeDevice extends GetxController {

void change(Device device) {
currentDevice = device;
selectedDeviceId = device.id;
selectedDeviceName = device.name;
selectedDeviceId = device.id ?? -1;
selectedDeviceName = device.name ?? '';
update();
}


+ 1
- 1
lib/presentation/screens/actions/controller/ChangeFieldInForm.dart View File

@@ -1,7 +1,7 @@
import 'package:get/get.dart';

class ChangeFieldFormSupply extends GetxController {
bool isChanged;
bool isChanged = false;
void init() {
isChanged = false;
update();

+ 1
- 1
lib/presentation/screens/actions/controller/ChangeFormButton.dart View File

@@ -1,7 +1,7 @@
import 'package:get/get.dart';

class ChangeButtonInForm extends GetxController {
bool isEdit;
bool isEdit = false;
void resetValue() {
isEdit = false;
update();

+ 3
- 3
lib/presentation/screens/actions/controller/ChangeSupplyUsing.dart View File

@@ -2,9 +2,9 @@ import 'package:farm_tpf/custom_model/SuppliesUsing.dart';
import 'package:get/get.dart';

class ChangeSupplyUsing extends GetxController {
List<SuppliesUsing> currentItems;
SuppliesUsing currentSupplyUsing;
int currentIndex;
List<SuppliesUsing> currentItems = <SuppliesUsing>[];
SuppliesUsing currentSupplyUsing = SuppliesUsing();
int currentIndex = -1;
void init(List<SuppliesUsing> initItems) {
currentItems = initItems;
currentSupplyUsing = SuppliesUsing();

+ 2
- 2
lib/presentation/screens/actions/controller/ChangeUnit.dart View File

@@ -1,8 +1,8 @@
import 'package:get/get.dart';

class ChangeUnit extends GetxController {
List<String> currentUnits;
String selectedUnit;
List<String> currentUnits = [];
String selectedUnit = '';

initValue() {
currentUnits = [];

+ 88
- 110
lib/presentation/screens/actions/crop_status/sc_edit_action_crop_status.dart View File

@@ -33,17 +33,14 @@ import 'package:farm_tpf/utils/formatter.dart';
class EditActionCropStatusScreen extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
EditActionCropStatusScreen(
{@required this.cropId, this.isEdit = false, this.activityId});
final int? activityId;
EditActionCropStatusScreen({required this.cropId, this.isEdit = false, this.activityId});
@override
_EditActionCropStatusScreenState createState() =>
_EditActionCropStatusScreenState();
_EditActionCropStatusScreenState createState() => _EditActionCropStatusScreenState();
}

class _EditActionCropStatusScreenState
extends State<EditActionCropStatusScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
class _EditActionCropStatusScreenState extends State<EditActionCropStatusScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
bool _autoValidate = false;
@@ -61,7 +58,7 @@ class _EditActionCropStatusScreenState
final _executeByController = TextEditingController();

DateTime executeTime = DateTime.now();
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -78,18 +75,18 @@ class _EditActionCropStatusScreenState
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
filePaths = Get.find<ChangeFileController>().newFiles;
//Create request general model
try {
RequestGeneralModel generalModel = RequestGeneralModel()
var generalModel = RequestGeneralModel()
..cropId = _cropStatus.cropId
..activityId = _cropStatus.activityId
..description = _cropStatus.description
..executeDate = _cropStatus.executeDate;
var generalDetail = List<ObjectUpdateDetail>();
var generalDetail = <ObjectUpdateDetail>[];
generalDetail.add(ObjectUpdateDetail()
..name = "TY_LE_CAY_TRONG"
..index = _cropStatus.cropRate);
@@ -159,8 +156,7 @@ class _EditActionCropStatusScreenState
return WidgetFieldDateTimePicker(
initDateTime: executeTime,
onUpdateDateTime: (selectedDate) {
_cropStatus.executeDate =
selectedDate.convertLocalDateTimeToStringUtcDateTime();
_cropStatus.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
});
}

@@ -169,8 +165,10 @@ class _EditActionCropStatusScreenState
hintValue: "Tỉ lệ lên cây",
textController: _cropRateController,
onSaved: (newValue) {
_cropStatus.cropRate = newValue;
_cropStatus.cropRate = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -179,8 +177,10 @@ class _EditActionCropStatusScreenState
hintValue: "Số lượng lên cây",
textController: _numTreeController,
onSaved: (newValue) {
_cropStatus.numberOfTreeToGrow = newValue;
_cropStatus.numberOfTreeToGrow = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -189,8 +189,10 @@ class _EditActionCropStatusScreenState
hintValue: "Chiều cao cây",
textController: _heightOfTreeController,
onSaved: (newValue) {
_cropStatus.heightOfTree = newValue;
_cropStatus.heightOfTree = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -199,8 +201,10 @@ class _EditActionCropStatusScreenState
hintValue: "Số lá",
textController: _numberOfLeafController,
onSaved: (newValue) {
_cropStatus.numberOfLeaf = newValue;
_cropStatus.numberOfLeaf = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -209,19 +213,23 @@ class _EditActionCropStatusScreenState
hintValue: "Kích thước lá",
textController: _leafSizeController,
onSaved: (newValue) {
_cropStatus.leafSize = newValue;
_cropStatus.leafSize = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

Widget _leafColorField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Màu lá"),
decoration: const InputDecoration(labelText: "Màu lá"),
controller: _leafColorController,
onSaved: (newValue) {
_cropStatus.leafColor = newValue;
_cropStatus.leafColor = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -230,19 +238,23 @@ class _EditActionCropStatusScreenState
hintValue: "Dài đốt thân",
textController: _internodeLengthController,
onSaved: (newValue) {
_cropStatus.internodeLength = newValue;
_cropStatus.internodeLength = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

Widget _abilityProduceBudsField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Khả năng sinh chồi"),
decoration: const InputDecoration(labelText: "Khả năng sinh chồi"),
controller: _abilityProduceBudsController,
onSaved: (newValue) {
_cropStatus.abilityProduceBuds = newValue;
_cropStatus.abilityProduceBuds = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -257,7 +269,7 @@ class _EditActionCropStatusScreenState
Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -276,10 +288,9 @@ class _EditActionCropStatusScreenState
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -291,24 +302,21 @@ class _EditActionCropStatusScreenState
child: MultiBlocProvider(
providers: [
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailCropStatus,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(isNeedFetchData: widget.isEdit, apiActivity: ConstCommon.apiDetailCropStatus, activityId: widget.activityId ?? -1),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child:
BlocConsumer<ActionDetailBloc, ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
print("fail");
@@ -318,43 +326,25 @@ class _EditActionCropStatusScreenState
print("success");
print(state.item);
_cropStatus = CropStatus.fromJson(state.item);
_cropStatus.activityId = widget.activityId;
_cropRateController.text = _cropStatus.cropRate
.formatStringToStringDecimal();
_numTreeController.text = _cropStatus
.numberOfTreeToGrow
.formatStringToStringDecimal();
_heightOfTreeController.text = _cropStatus
.heightOfTree
.formatStringToStringDecimal();
_numberOfLeafController.text = _cropStatus
.numberOfLeaf
.formatStringToStringDecimal();
_leafSizeController.text = _cropStatus.leafSize
.formatStringToStringDecimal();
_leafColorController.text =
_cropStatus.leafColor ?? "";
_abilityProduceBudsController.text =
_cropStatus.abilityProduceBuds ?? "";
_internodeLengthController.text = _cropStatus
.internodeLength
.formatStringToStringDecimal();
_descriptionController.text =
_cropStatus.description ?? "";
_executeByController.text =
_cropStatus.executeBy ?? "";
_cropStatus.activityId = widget.activityId ?? -1;
_cropRateController.text = _cropStatus.cropRate?.formatStringToStringDecimal() ?? '';
_numTreeController.text = _cropStatus.numberOfTreeToGrow?.formatStringToStringDecimal() ?? '';
_heightOfTreeController.text = _cropStatus.heightOfTree?.formatStringToStringDecimal() ?? '';
_numberOfLeafController.text = _cropStatus.numberOfLeaf?.formatStringToStringDecimal() ?? '';
_leafSizeController.text = _cropStatus.leafSize?.formatStringToStringDecimal() ?? '';
_leafColorController.text = _cropStatus.leafColor ?? "";
_abilityProduceBudsController.text = _cropStatus.abilityProduceBuds ?? "";
_internodeLengthController.text = _cropStatus.internodeLength?.formatStringToStringDecimal() ?? '';
_descriptionController.text = _cropStatus.description ?? "";
_executeByController.text = _cropStatus.executeBy ?? "";

Get.find<ChangeDateTimePicker>().change(_cropStatus
.executeDate
.convertStringServerDateTimeToLocalDateTime());
Get.find<ChangeDateTimePicker>().change(
_cropStatus.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
);
//Show media
if (Validators.stringNotNullOrEmpty(
_cropStatus.media)) {
BlocProvider.of<MediaHelperBloc>(context).add(
ChangeListMedia(
items:
UtilAction.convertFilePathToMedia(
_cropStatus.media)));
if (Validators.stringNotNullOrEmpty(_cropStatus.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_cropStatus.media ?? '')));
}
} else if (state is ActionDetailInitial) {
print("init");
@@ -369,69 +359,64 @@ class _EditActionCropStatusScreenState
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
plot_action_crop_status,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_cropRateField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_numTreeField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_hightOfTreeField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_numberOfLeafField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_leafSizeField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_leafColorField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_internodeLengthField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_abilityProduceBudsField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_desciptionField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -442,22 +427,16 @@ class _EditActionCropStatusScreenState
height: 16,
color: Colors.grey[200],
),
BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
print("length: " +
state.items.length.toString());
print("length: " + state.items.length.toString());
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
Padding(
@@ -465,8 +444,7 @@ class _EditActionCropStatusScreenState
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}

+ 75
- 99
lib/presentation/screens/actions/disease/sc_edit_action_disease.dart View File

@@ -30,16 +30,14 @@ import '../util_action.dart';
class EditActionDiseaseScreen extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
EditActionDiseaseScreen(
{@required this.cropId, this.isEdit = false, this.activityId});
final int? activityId;
EditActionDiseaseScreen({required this.cropId, this.isEdit = false, this.activityId});
@override
_EditActionDiseaseScreenState createState() =>
_EditActionDiseaseScreenState();
_EditActionDiseaseScreenState createState() => _EditActionDiseaseScreenState();
}

class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
bool _autoValidate = false;
@@ -56,7 +54,7 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
final _executeByController = TextEditingController();

DateTime executeTime = DateTime.now();
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -73,18 +71,18 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
filePaths = Get.find<ChangeFileController>().newFiles;
//Create request general model
try {
RequestDisease requestDisease = RequestDisease()
var requestDisease = RequestDisease()
..cropId = _disease.cropId
..activityId = _disease.activityId
..description = _disease.description
..executeDate = _disease.executeDate;
var generalDetail = List<ObjectUpdateDetail>();
var generalDetail = <ObjectUpdateDetail>[];
generalDetail.add(ObjectUpdateDetail()
..name = "LOAI_DICH_HAI"
..index = _disease.typesOfPest);
@@ -149,22 +147,20 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
return WidgetFieldDateTimePicker(
initDateTime: executeTime,
onUpdateDateTime: (selectedDate) {
_disease.executeDate =
selectedDate.convertLocalDateTimeToStringUtcDateTime();
_disease.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
});
}

Widget _typeOfPestField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Loại dịch hại *"),
decoration: const InputDecoration(labelText: "Loại dịch hại *"),
controller: _typesOfPestController,
validator: (String value) {
return Validators.validateNotNullOrEmpty(
value, label_validate_input_empty);
validator: (value) {
return Validators.validateNotNullOrEmpty(value!, label_validate_input_empty);
},
onSaved: (newValue) {
_disease.typesOfPest = newValue;
_disease.typesOfPest = newValue!;
},
);
}
@@ -172,10 +168,10 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
Widget _harmLevelField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Mức độ gây hại"),
decoration: const InputDecoration(labelText: "Mức độ gây hại"),
controller: _harmLevelController,
onSaved: (newValue) {
_disease.harmLevel = newValue;
_disease.harmLevel = newValue!;
},
);
}
@@ -185,18 +181,20 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
hintValue: "% cây",
textController: _treePercentController,
onSaved: (newValue) {
_disease.treePercent = newValue;
_disease.treePercent = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

Widget _locationField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Vị trí"),
decoration: const InputDecoration(labelText: "Vị trí"),
controller: _locationController,
onSaved: (newValue) {
_disease.location = newValue;
_disease.location = newValue!;
},
);
}
@@ -204,10 +202,10 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
Widget _naturalEnemyField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Thiên địch"),
decoration: const InputDecoration(labelText: "Thiên địch"),
controller: _naturalEnemyController,
onSaved: (newValue) {
_disease.naturalEnemy = newValue;
_disease.naturalEnemy = newValue!;
},
);
}
@@ -215,10 +213,10 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
Widget _treatmentMeasuresField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Biện pháp xử lý"),
decoration: const InputDecoration(labelText: "Biện pháp xử lý"),
controller: _treatmentMeasuresController,
onSaved: (newValue) {
_disease.treatmentMeasures = newValue;
_disease.treatmentMeasures = newValue!;
},
);
}
@@ -235,7 +233,7 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -254,10 +252,9 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -269,24 +266,25 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
child: MultiBlocProvider(
providers: [
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailDisease,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailDisease,
activityId: widget.activityId ?? 0,
),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child:
BlocConsumer<ActionDetailBloc, ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
LoadingDialog.hideLoadingDialog(context);
@@ -294,34 +292,23 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
LoadingDialog.hideLoadingDialog(context);
print(state.item);
_disease = Disease.fromJson(state.item);
_disease.activityId = widget.activityId;
_typesOfPestController.text =
_disease.typesOfPest ?? "";
_harmLevelController.text =
_disease.harmLevel ?? "";
_treePercentController.text = _disease.treePercent
.formatStringToStringDecimal();
_locationController.text =
_disease.location ?? "";
_naturalEnemyController.text =
_disease.naturalEnemy ?? "";
_treatmentMeasuresController.text =
_disease.treatmentMeasures ?? "";
_descriptionController.text =
_disease.description ?? "";
_executeByController.text = _disease.executeBy;
_disease.activityId = widget.activityId ?? 0;
_typesOfPestController.text = _disease.typesOfPest ?? "";
_harmLevelController.text = _disease.harmLevel ?? "";
_treePercentController.text = _disease.treePercent?.formatStringToStringDecimal() ?? '';
_locationController.text = _disease.location ?? "";
_naturalEnemyController.text = _disease.naturalEnemy ?? "";
_treatmentMeasuresController.text = _disease.treatmentMeasures ?? "";
_descriptionController.text = _disease.description ?? "";
_executeByController.text = _disease.executeBy ?? '';

Get.find<ChangeDateTimePicker>().change(_disease
.executeDate
.convertStringServerDateTimeToLocalDateTime());
Get.find<ChangeDateTimePicker>().change(
_disease.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
);
//Show media
if (Validators.stringNotNullOrEmpty(
_disease.media)) {
BlocProvider.of<MediaHelperBloc>(context).add(
ChangeListMedia(
items:
UtilAction.convertFilePathToMedia(
_disease.media)));
if (Validators.stringNotNullOrEmpty(_disease.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_disease.media ?? '')));
}
} else if (state is ActionDetailInitial) {
} else if (state is ActionDetailLoading) {
@@ -334,61 +321,56 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
plot_action_disease,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_typeOfPestField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_harmLevelField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_treePercentField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_locationField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_naturalEnemyField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_treatmentMeasuresField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_descriptionField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -399,20 +381,15 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
height: 16,
color: Colors.grey[200],
),
BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
Padding(
@@ -420,8 +397,7 @@ class _EditActionDiseaseScreenState extends State<EditActionDiseaseScreen> {
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}

+ 62
- 97
lib/presentation/screens/actions/dung/sc_edit_action_dung.dart View File

@@ -38,15 +38,14 @@ import '../util_action.dart';
class EditActionDungScreen extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
EditActionDungScreen(
{@required this.cropId, this.isEdit = false, this.activityId});
final int? activityId;
EditActionDungScreen({required this.cropId, this.isEdit = false, this.activityId});
@override
_EditActionDungScreenState createState() => _EditActionDungScreenState();
}

class _EditActionDungScreenState extends State<EditActionDungScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
bool _autoValidate = false;
@@ -57,10 +56,10 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
final _weatherController = TextEditingController();
final _executeByController = TextEditingController();
final _quarantinePeriodController = TextEditingController();
List<SuppliesUsing> suppliesUsing = new List<SuppliesUsing>();
List<SuppliesUsing> suppliesUsing = <SuppliesUsing>[];

DateTime executeTime = DateTime.now();
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -73,16 +72,16 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
super.initState();
getSharedPrefs();
changeFileController.initValue();
_dung.suppliesUsing = new List<SuppliesUsing>();
_dung.suppliesUsing = <SuppliesUsing>[];
_dung.cropId = widget.cropId;
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
filePaths = Get.find<ChangeFileController>().newFiles;
List<SuppliesUsing> newSups = [];
var newSups = <SuppliesUsing>[];
suppliesUsing.forEach((sup) {
var newSup = sup;
newSup.suppliesInWarehouseId = sup.tbSuppliesInWarehouseId;
@@ -101,11 +100,7 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
}, (error) {
LoadingDialog.hideLoadingDialog(context);
Utils.showSnackBarError(message: AppException.handleError(error));
},
apiAddAction: ConstCommon.apiAddDung,
paramActivity: ConstCommon.paramsActionDung,
activityAction: activityDung,
filePaths: filePaths);
}, apiAddAction: ConstCommon.apiAddDung, paramActivity: ConstCommon.paramsActionDung, activityAction: activityDung, filePaths: filePaths);
} else {
//UPDATE
_repository.updateAction((value) {
@@ -130,18 +125,17 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
return WidgetFieldDateTimePicker(
initDateTime: executeTime,
onUpdateDateTime: (selectedDate) {
_dung.executeDate =
selectedDate.convertLocalDateTimeToStringUtcDateTime();
_dung.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
});
}

Widget _purposeField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Lý do sử dụng"),
decoration: const InputDecoration(labelText: "Lý do sử dụng"),
controller: _purposeController,
onSaved: (newValue) {
_dung.purpose = newValue;
_dung.purpose = newValue ?? '';
},
);
}
@@ -151,18 +145,20 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
hintValue: "Thời gian cách ly",
textController: _quarantinePeriodController,
onSaved: (newValue) {
_dung.quarantinePeriod = newValue.parseDoubleThousand();
_dung.quarantinePeriod = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

Widget _weatherField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Thời tiết"),
decoration: const InputDecoration(labelText: "Thời tiết"),
controller: _weatherController,
onSaved: (newValue) {
_dung.weatherConditions = newValue;
_dung.weatherConditions = newValue ?? '';
},
);
}
@@ -178,7 +174,7 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -197,10 +193,9 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -212,57 +207,44 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
child: MultiBlocProvider(
providers: [
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailDung,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(isNeedFetchData: widget.isEdit, apiActivity: ConstCommon.apiDetailDung, activityId: widget.activityId ?? -1),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child: BlocConsumer<ActionDetailBloc,
ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
LoadingDialog.hideLoadingDialog(context);
} else if (state is ActionDetailSuccess) {
LoadingDialog.hideLoadingDialog(context);
_dung = Dung.fromJson(state.item);
_dung.activityId = widget.activityId;
_purposeController.text =
_dung.purpose ?? "";
_quarantinePeriodController.text = _dung
.quarantinePeriod
.formatNumtoStringDecimal();
_weatherController.text =
_dung.weatherConditions ?? "";
_descriptionController.text =
_dung.description;
_executeByController.text = _dung.executeBy;
Get.find<ChangeDateTimePicker>().change(_dung
.executeDate
.convertStringServerDateTimeToLocalDateTime());
_dung.activityId = widget.activityId ?? -1;
_purposeController.text = _dung.purpose ?? "";
_quarantinePeriodController.text = _dung.quarantinePeriod?.formatNumtoStringDecimal() ?? '';
_weatherController.text = _dung.weatherConditions ?? "";
_descriptionController.text = _dung.description ?? '';
_executeByController.text = _dung.executeBy ?? '';
Get.find<ChangeDateTimePicker>().change(
_dung.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
);
//Show media
if (Validators.stringNotNullOrEmpty(
_dung.media)) {
if (Validators.stringNotNullOrEmpty(_dung.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(
items: UtilAction
.convertFilePathToMedia(
_dung.media)));
.add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_dung.media ?? '')));
}
//list supply
suppliesUsing = _dung.suppliesUsing;
Get.find<ChangeSupplyUsing>()
.changeInitList(suppliesUsing);
suppliesUsing = _dung.suppliesUsing ?? <SuppliesUsing>[];
Get.find<ChangeSupplyUsing>().changeInitList(suppliesUsing);
} else if (state is ActionDetailInitial) {
print("init");
} else if (state is ActionDetailLoading) {
@@ -276,49 +258,44 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
plot_action_dung,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_purposeField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_quarantinePeriodField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_weatherField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_desciptionField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -339,22 +316,15 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
height: 16,
color: Colors.grey[200],
),
BlocBuilder<MediaHelperBloc,
MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child:
CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
Padding(
@@ -362,17 +332,12 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> {
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
if (!currentFocus
.hasPrimaryFocus) {
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
if (Get.find<
ChangeFieldFormSupply>()
.isChanged) {
Utils.showDialogConfirmSupply(
onConfirm: () {
if (Get.find<ChangeFieldFormSupply>().isChanged) {
Utils.showDialogConfirmSupply(onConfirm: () {
Get.back();
_validateInputs();
});

+ 112
- 168
lib/presentation/screens/actions/dung/widget_dung_supply.dart View File

@@ -25,7 +25,7 @@ import '../util_action.dart';
class WidgetDungSupply extends StatefulWidget {
final List<SuppliesUsing> currentItems;
final Function(List<SuppliesUsing> supplyChanges) onChangeSupplies;
WidgetDungSupply({this.currentItems, @required this.onChangeSupplies});
WidgetDungSupply({required this.currentItems, required this.onChangeSupplies});
@override
_WidgetDungSupplyState createState() => _WidgetDungSupplyState();
}
@@ -62,7 +62,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
return Container(
height: 120,
child: ListView.builder(
physics: ClampingScrollPhysics(),
physics: const ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: value.currentItems.length,
@@ -84,64 +84,47 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
..name = editedSupplyUsing.equipmentName;
changeSelectedDevice.change(editedDevice);

changeUnit
.updateListByUnitName(editedSupplyUsing.supplyUnit);
changeUnit.updateSelected(editedSupplyUsing.supplyUnit);
_dosageController.text = editedSupplyUsing.dosage;
_howToUseController.text = editedSupplyUsing.howToUse;
_quantityController.text = editedSupplyUsing.quantity
.formatNumtoStringDecimal();
changeUnit.updateListByUnitName(editedSupplyUsing.supplyUnit ?? '');
changeUnit.updateSelected(editedSupplyUsing.supplyUnit ?? '');
_dosageController.text = editedSupplyUsing.dosage ?? '';
_howToUseController.text = editedSupplyUsing.howToUse ?? '';
_quantityController.text = editedSupplyUsing.quantity?.formatNumtoStringDecimal() ?? '';
},
child: Card(
child: Stack(
alignment: Alignment.bottomCenter,
overflow: Overflow.visible,
// overflow: Overflow.visible,
children: <Widget>[
Positioned(
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
padding: EdgeInsets.all(4),
padding: const EdgeInsets.all(4),
width: 150,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
const SizedBox(
height: 12.0,
),
Flexible(
child: Text(
value.currentItems[index].supplyName ??
"",
overflow: TextOverflow.ellipsis,
maxLines: 1),
child: Text(value.currentItems[index].supplyName ?? "", overflow: TextOverflow.ellipsis, maxLines: 1),
),
Validators.stringNotNullOrEmpty(
value.currentItems[index].dosage)
Validators.stringNotNullOrEmpty(value.currentItems[index].dosage ?? '')
? Flexible(child: Text("${value.currentItems[index].dosage ?? ""}"))
: const SizedBox(),
Validators.stringNotNullOrEmpty(value.currentItems[index].quantity?.formatNumtoStringDecimal() ?? '')
? Flexible(
child: Text(
"${value.currentItems[index].dosage ?? ""}"))
: SizedBox(),
Validators.stringNotNullOrEmpty(value
.currentItems[index].quantity
.formatNumtoStringDecimal())
? Flexible(
child: Text(
"${value.currentItems[index].quantity.formatNumtoStringDecimal() ?? ""} ${value.currentItems[index].supplyUnit ?? ""}"))
: SizedBox(),
Validators.stringNotNullOrEmpty(value
.currentItems[index].equipmentName)
? Flexible(
child: Text(
"${value.currentItems[index].equipmentName ?? ""}"))
: SizedBox(),
Validators.stringNotNullOrEmpty(
value.currentItems[index].howToUse)
? Flexible(
child: Text(
"${value.currentItems[index].howToUse ?? ""}"))
: SizedBox(),
"${value.currentItems[index].quantity?.formatNumtoStringDecimal() ?? ""} ${value.currentItems[index].supplyUnit ?? ""}"))
: const SizedBox(),
Validators.stringNotNullOrEmpty(value.currentItems[index].equipmentName ?? '')
? Flexible(child: Text("${value.currentItems[index].equipmentName ?? ""}"))
: const SizedBox(),
Validators.stringNotNullOrEmpty(value.currentItems[index].howToUse ?? '')
? Flexible(child: Text("${value.currentItems[index].howToUse ?? ""}"))
: const SizedBox(),
],
),
),
@@ -150,7 +133,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
top: -10,
right: -10,
child: IconButton(
icon: Icon(
icon: const Icon(
Icons.cancel,
color: Colors.redAccent,
),
@@ -168,8 +151,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
Widget _btnSelectSubstrates() {
return GetBuilder<ChangeSupply>(builder: (data) {
return FlatButton(
padding:
EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
onPressed: () {
var currentIndexEdit = changeSupplyUsing.currentIndex;
Navigator.of(context)
@@ -179,17 +161,15 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
type: ConstCommon.supplyTypeDung,
selectedId: changeSelectedSupply.selectedSupplyId,
currentItems: changeSupplyUsing.currentItems,
currentEditId: (currentIndexEdit >= 0)
? changeSupplyUsing.currentItems[currentIndexEdit]
.tbSuppliesInWarehouseId
: -1,
currentEditId:
(currentIndexEdit >= 0) ? changeSupplyUsing.currentItems[currentIndexEdit].tbSuppliesInWarehouseId ?? -1 : -1,
),
fullscreenDialog: false))
.then((value) {
if (value != null) {
var result = value as Supply;
changeSelectedSupply.change(result);
changeUnit.updateListByUnitName(result.unit);
changeUnit.updateListByUnitName(result.unit ?? '');
changeFormField.change(true);
}
});
@@ -200,35 +180,28 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(
top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: isValid ? Colors.grey : Colors.red[900])),
bottom: BorderSide(
width: 1,
color: isValid ? Colors.grey : Colors.red,
),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tên thương mại *',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.normal,
color:
isValid ? Colors.black54 : Colors.red[600]),
style: TextStyle(fontSize: 13, fontWeight: FontWeight.normal, color: isValid ? Colors.black54 : Colors.red[600]),
),
Row(
children: [
Expanded(
child: Text(
changeSelectedSupply.selectedSupplyName ??
"Tên thương mại",
style: TextStyle(
fontSize: 14.0,
color: Colors.black87))),
Icon(
child: Text(changeSelectedSupply.selectedSupplyName ?? "Tên thương mại",
style: const TextStyle(fontSize: 14.0, color: Colors.black87))),
const Icon(
Icons.arrow_drop_down,
color: Colors.grey,
),
@@ -236,7 +209,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
)
],
)),
isValid ? SizedBox() : WidgetErrorTextField()
isValid ? const SizedBox() : WidgetErrorTextField()
],
);
}));
@@ -246,14 +219,11 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
Widget _btnSelectDevice() {
return GetBuilder<ChangeDevice>(builder: (data) {
return FlatButton(
padding:
EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (_) => ListDeviceActivity(
selectedId: changeSelectedDevice.selectedDeviceId),
fullscreenDialog: false))
.push(
MaterialPageRoute(builder: (_) => ListDeviceActivity(selectedId: changeSelectedDevice.selectedDeviceId), fullscreenDialog: false))
.then((value) {
if (value != null) {
var result = value as Device;
@@ -263,21 +233,17 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
});
},
child: Container(
padding: EdgeInsets.only(
top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: BoxDecoration(
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: const BoxDecoration(
border: kBorderTextField,
),
child: Row(
children: [
GetBuilder<ChangeSupply>(
builder: (_) => Expanded(
child: Text(
changeSelectedDevice.selectedDeviceName ??
"Thiết bị",
style: TextStyle(
fontSize: 14.0, color: Colors.black87)))),
Icon(
child: Text(changeSelectedDevice.selectedDeviceName ?? "Thiết bị",
style: const TextStyle(fontSize: 14.0, color: Colors.black87)))),
const Icon(
Icons.arrow_drop_down,
color: Colors.grey,
),
@@ -304,14 +270,11 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
var oldSelected = data.selectedUnit;
if (oldSelected == value) {
} else {
assignValue = UtilAction.convertUnit(
inputValue: assignValue,
oldUnit: oldSelected,
newUnit: value);
assignValue = UtilAction.convertUnit(inputValue: assignValue, oldUnit: oldSelected, newUnit: value ?? '');
}
_quantityController.text = assignValue.formatNumtoStringDecimal();
}
changeUnit.updateSelected(value);
changeUnit.updateSelected(value ?? '');
},
);
});
@@ -321,9 +284,8 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
return WidgetTextFormFieldNumber(
hintValue: "Tổng lượng sử dụng *",
textController: _quantityController,
validator: (String value) {
return Validators.validateNotNullOrEmpty(
value, label_validate_input_empty);
validator: (String? value) {
// return Validators.validateNotNullOrEmpty(value, label_validate_input_empty);
},
onChanged: (value) {
if (!Validators.stringNotNullOrEmpty(value) &&
@@ -336,6 +298,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
changeFormField.change(true);
}
},
onSaved: (_) {},
);
}

@@ -345,42 +308,36 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_.isEdit
? OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(8.0)),
child: Text("Huỷ"),
onPressed: () {
? InkWell(
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
child: const Text("Huỷ"),
onTap: () {
changeButton.resetValue();
_resetForm();
_hidenKeyboard(context);
})
: SizedBox(),
: const SizedBox(),
_.isEdit
? Expanded(
child: FlatButton(
onPressed: () {
if (_formSupplyKey.currentState.validate()) {
_formSupplyKey.currentState.save();
if (_formSupplyKey.currentState!.validate()) {
_formSupplyKey.currentState!.save();
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
changeSelectedSupply.changeValid(true);
}
var currentSupply =
changeSelectedSupply.currentSupply;
var currentDevice =
changeSelectedDevice.currentDevice;
var currentQuantity =
_quantityController.text.parseDoubleThousand();
if (currentSupply.id != null &&
(currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit =
UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply
.currentSupply.unit);
SuppliesUsing newSup = SuppliesUsing()
var currentSupply = changeSelectedSupply.currentSupply;
var currentDevice = changeSelectedDevice.currentDevice;
var currentQuantity = _quantityController.text.parseDoubleThousand();
if (currentSupply.id != null && (currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit = UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply.currentSupply.unit ?? '',
);
var newSup = SuppliesUsing()
..dosage = _dosageController.text
..howToUse = _howToUseController.text
..quantity = quantityWithCurrentSupplyUnit
@@ -392,18 +349,14 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
..equipmentName = currentDevice.name
..supplyUnit = currentSupply.unit
..unit = currentSupply.unit;
changeSupplyUsing.editSupply(
changeSupplyUsing.currentIndex, newSup);
changeSupplyUsing.editSupply(changeSupplyUsing.currentIndex, newSup);
_resetForm();
_hidenKeyboard(context);
} else if (currentSupply.id == null ||
((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
} else if (currentSupply.id == null || ((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
}
} else {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
@@ -411,7 +364,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
}
}
},
child: Text(
child: const Text(
"Sửa phân bón",
style: TextStyle(color: Colors.blue),
)),
@@ -419,28 +372,23 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
: Expanded(
child: FlatButton(
onPressed: () {
if (_formSupplyKey.currentState.validate()) {
_formSupplyKey.currentState.save();
if (_formSupplyKey.currentState!.validate()) {
_formSupplyKey.currentState!.save();
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
changeSelectedSupply.changeValid(true);
}
var currentSupply =
changeSelectedSupply.currentSupply;
var currentDevice =
changeSelectedDevice.currentDevice;
var currentQuantity =
_quantityController.text.parseDoubleThousand();
if (currentSupply.id != null &&
(currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit =
UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply
.currentSupply.unit);
SuppliesUsing newSup = SuppliesUsing()
var currentSupply = changeSelectedSupply.currentSupply;
var currentDevice = changeSelectedDevice.currentDevice;
var currentQuantity = _quantityController.text.parseDoubleThousand();
if (currentSupply.id != null && (currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit = UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply.currentSupply.unit ?? '',
);
var newSup = SuppliesUsing()
..dosage = _dosageController.text
..howToUse = _howToUseController.text
..quantity = quantityWithCurrentSupplyUnit
@@ -455,14 +403,11 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
changeSupplyUsing.addSupply(newSup);
_resetForm();
_hidenKeyboard(context);
} else if (currentSupply.id == null ||
((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
} else if (currentSupply.id == null || ((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
}
} else {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
@@ -471,7 +416,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
//
}
},
child: Text(
child: const Text(
"+ Thêm phân bón",
style: TextStyle(color: Colors.blue),
)),
@@ -487,26 +432,27 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
child: Column(
children: [
Container(
padding: EdgeInsets.all(8.0),
margin: EdgeInsets.all(8.0),
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(color: Colors.grey[300])),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(
color: Colors.grey,
),
),
child: Column(
children: [
_btnSelectSubstrates(),
TextFormField(
keyboardType: TextInputType.text,
controller: _dosageController,
decoration: InputDecoration(labelText: "Liều lượng sử dụng"),
decoration: const InputDecoration(labelText: "Liều lượng sử dụng"),
onSaved: (newValue) {},
onChanged: (value) {
if (!Validators.stringNotNullOrEmpty(
_quantityController.text) &&
!Validators.stringNotNullOrEmpty(
_howToUseController.text) &&
if (!Validators.stringNotNullOrEmpty(_quantityController.text) &&
!Validators.stringNotNullOrEmpty(_howToUseController.text) &&
!Validators.stringNotNullOrEmpty(value) &&
Get.find<ChangeSupply>().selectedSupplyId <= 0 &&
changeSelectedDevice.selectedDeviceId <= 0) {
@@ -528,7 +474,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
child: _quantityField(),
),
),
SizedBox(
const SizedBox(
width: 16.0,
),
Expanded(
@@ -540,7 +486,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
]),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Thiết bị",
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
@@ -549,14 +495,12 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
TextFormField(
keyboardType: TextInputType.text,
controller: _howToUseController,
decoration: InputDecoration(labelText: "Phương pháp sử dụng"),
decoration: const InputDecoration(labelText: "Phương pháp sử dụng"),
onSaved: (newValue) {},
onChanged: (value) {
if (!Validators.stringNotNullOrEmpty(
_quantityController.text) &&
if (!Validators.stringNotNullOrEmpty(_quantityController.text) &&
!Validators.stringNotNullOrEmpty(value) &&
!Validators.stringNotNullOrEmpty(
_dosageController.text) &&
!Validators.stringNotNullOrEmpty(_dosageController.text) &&
Get.find<ChangeSupply>().selectedSupplyId <= 0 &&
changeSelectedDevice.selectedDeviceId <= 0) {
changeFormField.change(false);
@@ -587,7 +531,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
}

_hidenKeyboard(BuildContext context) {
FocusScopeNode currentFocus = FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
@@ -597,8 +541,8 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
const Padding(
padding: EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
@@ -608,11 +552,11 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> {
),
),
_buildListSupply(),
SizedBox(
const SizedBox(
height: 8.0,
),
_formEdit(),
SizedBox(
const SizedBox(
height: 8.0,
),
],

+ 44
- 66
lib/presentation/screens/actions/end/sc_edit_action_end.dart View File

@@ -28,15 +28,14 @@ import '../util_action.dart';
class EditActionEndScreen extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
EditActionEndScreen(
{@required this.cropId, this.isEdit = false, this.activityId});
final int? activityId;
EditActionEndScreen({required this.cropId, this.isEdit = false, this.activityId});
@override
_EditActionEndScreenState createState() => _EditActionEndScreenState();
}

class _EditActionEndScreenState extends State<EditActionEndScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
bool _autoValidate = false;
@@ -46,7 +45,7 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {

var pref = LocalPref();
DateTime executeTime = DateTime.now();
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -63,8 +62,8 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
filePaths = Get.find<ChangeFileController>().newFiles;
try {
@@ -79,11 +78,7 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
}, (error) {
LoadingDialog.hideLoadingDialog(context);
Utils.showSnackBarError(message: AppException.handleError(error));
},
apiAddAction: ConstCommon.apiAddEnd,
paramActivity: ConstCommon.paramsActionEnd,
activityAction: activityEnd,
filePaths: filePaths);
}, apiAddAction: ConstCommon.apiAddEnd, paramActivity: ConstCommon.paramsActionEnd, activityAction: activityEnd, filePaths: filePaths);
} else {
//UPDATE
_repository.updateAction((value) {
@@ -112,8 +107,7 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
return WidgetFieldDateTimePicker(
initDateTime: executeTime,
onUpdateDateTime: (selectedDate) {
_end.executeDate =
selectedDate.convertLocalDateTimeToStringUtcDateTime();
_end.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
});
}

@@ -128,7 +122,7 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -147,10 +141,9 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -162,45 +155,41 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
child: MultiBlocProvider(
providers: [
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailEnd,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(isNeedFetchData: widget.isEdit, apiActivity: ConstCommon.apiDetailEnd, activityId: widget.activityId ?? -1),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child:
BlocConsumer<ActionDetailBloc, ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
LoadingDialog.hideLoadingDialog(context);
} else if (state is ActionDetailSuccess) {
LoadingDialog.hideLoadingDialog(context);
_end = End.fromJson(state.item);
_end.activityId = widget.activityId;
_descriptionController.text =
_end.description ?? "";
_executeByController.text = _end.createdByName;
_end.activityId = widget.activityId ?? -1;
_descriptionController.text = _end.description ?? "";
_executeByController.text = _end.createdByName ?? '';

Get.find<ChangeDateTimePicker>().change(_end
.executeDate
.convertStringServerDateTimeToLocalDateTime());
Get.find<ChangeDateTimePicker>().change(
_end.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
);
//Show media
if (Validators.stringNotNullOrEmpty(_end.media)) {
if (Validators.stringNotNullOrEmpty(_end.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context).add(
ChangeListMedia(
items:
UtilAction.convertFilePathToMedia(
_end.media)));
ChangeListMedia(
items: UtilAction.convertFilePathToMedia(_end.media ?? ''),
),
);
}
} else if (state is ActionDetailInitial) {
} else if (state is ActionDetailLoading) {
@@ -213,37 +202,32 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
plot_action_finish,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_descriptionField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -254,20 +238,15 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
height: 16,
color: Colors.grey[200],
),
BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
Padding(
@@ -275,8 +254,7 @@ class _EditActionEndScreenState extends State<EditActionEndScreen> {
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}

+ 86
- 110
lib/presentation/screens/actions/environment_update/sc_edit_action_environment_update.dart View File

@@ -32,17 +32,14 @@ import 'package:farm_tpf/utils/formatter.dart';
class EditActionEnvironmentUpdate extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
EditActionEnvironmentUpdate(
{@required this.cropId, this.isEdit = false, this.activityId});
final int? activityId;
EditActionEnvironmentUpdate({required this.cropId, this.isEdit = false, this.activityId});
@override
_EditActionEnvironmentUpdateState createState() =>
_EditActionEnvironmentUpdateState();
_EditActionEnvironmentUpdateState createState() => _EditActionEnvironmentUpdateState();
}

class _EditActionEnvironmentUpdateState
extends State<EditActionEnvironmentUpdate> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
class _EditActionEnvironmentUpdateState extends State<EditActionEnvironmentUpdate> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
bool _autoValidate = false;
@@ -57,7 +54,7 @@ class _EditActionEnvironmentUpdateState
final _executeByController = TextEditingController();

DateTime executeTime = DateTime.now();
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -74,17 +71,17 @@ class _EditActionEnvironmentUpdateState
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
filePaths = Get.find<ChangeFileController>().newFiles;
//Create request general model
try {
RequestEnvironment requestEnvironment = RequestEnvironment()
var requestEnvironment = RequestEnvironment()
..cropId = _environment.cropId
..activityId = _environment.activityId
..executeDate = _environment.executeDate;
var envDetail = List<EnvDetail>();
var envDetail = <EnvDetail>[];
envDetail.add(EnvDetail()
..name = "EC"
..index = _environment.ec);
@@ -104,10 +101,8 @@ class _EditActionEnvironmentUpdateState
..name = "LLN"
..index = _environment.lln);
requestEnvironment.envDetail = envDetail;
requestEnvironment.mediaDel =
Get.find<ChangeFileController>().deleteFiles;
var activityEnvironmentUpdate =
jsonEncode(requestEnvironment.toJson()).toString();
requestEnvironment.mediaDel = Get.find<ChangeFileController>().deleteFiles;
var activityEnvironmentUpdate = jsonEncode(requestEnvironment.toJson()).toString();
//ADD NEW
if (_environment.activityId == null) {
_repository.createAction((value) {
@@ -150,8 +145,7 @@ class _EditActionEnvironmentUpdateState
return WidgetFieldDateTimePicker(
initDateTime: executeTime,
onUpdateDateTime: (selectedDate) {
_environment.executeDate =
selectedDate.convertLocalDateTimeToStringUtcDateTime();
_environment.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
});
}

@@ -160,8 +154,10 @@ class _EditActionEnvironmentUpdateState
hintValue: "EC",
textController: _ecController,
onSaved: (newValue) {
_environment.ec = newValue;
_environment.ec = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -170,8 +166,10 @@ class _EditActionEnvironmentUpdateState
hintValue: "pH",
textController: _phController,
onSaved: (newValue) {
_environment.pH = newValue;
_environment.pH = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -180,8 +178,10 @@ class _EditActionEnvironmentUpdateState
hintValue: "Nhiệt độ dung dịch",
textController: _ocddController,
onSaved: (newValue) {
_environment.ocdd = newValue;
_environment.ocdd = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -190,8 +190,10 @@ class _EditActionEnvironmentUpdateState
hintValue: "Nhiệt độ môi trường",
textController: _temperatureController,
onSaved: (newValue) {
_environment.temperature = newValue;
_environment.temperature = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -200,8 +202,10 @@ class _EditActionEnvironmentUpdateState
hintValue: "Độ ẩm",
textController: _doController,
onSaved: (newValue) {
_environment.dodo = newValue;
_environment.dodo = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -210,15 +214,17 @@ class _EditActionEnvironmentUpdateState
hintValue: "Lưu lượng nước",
textController: _llnController,
onSaved: (newValue) {
_environment.lln = newValue;
_environment.lln = newValue ?? '';
},
onChanged: (_) {},
validator: (_) {},
);
}

Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -237,10 +243,9 @@ class _EditActionEnvironmentUpdateState
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -252,24 +257,25 @@ class _EditActionEnvironmentUpdateState
child: MultiBlocProvider(
providers: [
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailEnvUpdate,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailEnvUpdate,
activityId: widget.activityId ?? -1,
),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child:
BlocConsumer<ActionDetailBloc, ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
print("fail");
@@ -280,65 +286,46 @@ class _EditActionEnvironmentUpdateState
print(state.item);
_environment = Environment.fromJson(state.item);
//Parse theo API :')
_environment.environmentUpdates
.forEach((envDetail) {
_environment.environmentUpdates?.forEach((envDetail) {
switch (envDetail.tbEnvironmentalName) {
case "EC":
_environment.ec =
envDetail.index.toString();
_environment.ec = envDetail.index.toString();
break;
case "pH":
_environment.pH =
envDetail.index.toString();
_environment.pH = envDetail.index.toString();
break;
case "OCDD":
_environment.ocdd =
envDetail.index.toString();
_environment.ocdd = envDetail.index.toString();
break;
case "TEMPERATURE":
_environment.temperature =
envDetail.index.toString();
_environment.temperature = envDetail.index.toString();
break;
case "DO":
_environment.dodo =
envDetail.index.toString();
_environment.dodo = envDetail.index.toString();
break;
case "LLN":
_environment.lln =
envDetail.index.toString();
_environment.lln = envDetail.index.toString();
break;
default:
break;
}
});
_environment.activityId = widget.activityId;
_ecController.text =
_environment.ec.formatStringToStringDecimal();
_phController.text =
_environment.pH.formatStringToStringDecimal();
_ocddController.text = _environment.ocdd
.formatStringToStringDecimal();
_temperatureController.text = _environment
.temperature
.formatStringToStringDecimal();
_doController.text = _environment.dodo
.formatStringToStringDecimal();
_llnController.text = _environment.lln
.formatStringToStringDecimal();
_executeByController.text =
_environment.executeBy;
_environment.activityId = widget.activityId ?? -1;
_ecController.text = _environment.ec?.formatStringToStringDecimal() ?? '';
_phController.text = _environment.pH?.formatStringToStringDecimal() ?? '';
_ocddController.text = _environment.ocdd?.formatStringToStringDecimal() ?? '';
_temperatureController.text = _environment.temperature?.formatStringToStringDecimal() ?? '';
_doController.text = _environment.dodo?.formatStringToStringDecimal() ?? '';
_llnController.text = _environment.lln?.formatStringToStringDecimal() ?? '';
_executeByController.text = _environment.executeBy ?? '';

Get.find<ChangeDateTimePicker>().change(_environment
.executeDate
.convertStringServerDateTimeToLocalDateTime());
Get.find<ChangeDateTimePicker>().change(
_environment.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
);
//Show media
if (Validators.stringNotNullOrEmpty(
_environment.media)) {
BlocProvider.of<MediaHelperBloc>(context).add(
ChangeListMedia(
items:
UtilAction.convertFilePathToMedia(
_environment.media)));
if (Validators.stringNotNullOrEmpty(_environment.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_environment.media ?? '')));
}
} else if (state is ActionDetailInitial) {
print("init");
@@ -353,57 +340,52 @@ class _EditActionEnvironmentUpdateState
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
plot_action_environment_update,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_ecField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_phField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_ocddField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_temperatureField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_doField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_llnField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -414,20 +396,15 @@ class _EditActionEnvironmentUpdateState
height: 16,
color: Colors.grey[200],
),
BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
Padding(
@@ -435,8 +412,7 @@ class _EditActionEnvironmentUpdateState
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}

+ 69
- 89
lib/presentation/screens/actions/harvest/sc_edit_action_harvest.dart View File

@@ -37,16 +37,14 @@ import 'package:farm_tpf/utils/formatter.dart';
class EditActionHarvestScreen extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
EditActionHarvestScreen(
{@required this.cropId, this.isEdit = false, this.activityId});
final int? activityId;
EditActionHarvestScreen({required this.cropId, this.isEdit = false, this.activityId});
@override
_EditActionHarvestScreenState createState() =>
_EditActionHarvestScreenState();
_EditActionHarvestScreenState createState() => _EditActionHarvestScreenState();
}

class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
bool _autoValidate = false;
@@ -60,7 +58,7 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {

var pref = LocalPref();
DateTime executeTime = DateTime.now();
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -77,8 +75,8 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
filePaths = Get.find<ChangeFileController>().newFiles;
try {
@@ -126,8 +124,7 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
return WidgetFieldDateTimePicker(
initDateTime: executeTime,
onUpdateDateTime: (selectedDate) {
_harvest.executeDate =
selectedDate.convertLocalDateTimeToStringUtcDateTime();
_harvest.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
});
}

@@ -136,8 +133,10 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
hintValue: "Số lượng/khối lượng loại 1",
textController: _l1Controller,
onSaved: (newValue) {
_harvest.collectedQuantityLv1 = newValue.parseDoubleThousand();
_harvest.collectedQuantityLv1 = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -146,8 +145,10 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
hintValue: "Số lượng/khối lượng loại 2",
textController: _l2Controller,
onSaved: (newValue) {
_harvest.collectedQuantityLv2 = newValue.parseDoubleThousand();
_harvest.collectedQuantityLv2 = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -156,8 +157,10 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
hintValue: "Số lượng/khối lượng loại 3",
textController: _l3Controller,
onSaved: (newValue) {
_harvest.collectedQuantityLv3 = newValue.parseDoubleThousand();
_harvest.collectedQuantityLv3 = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -166,8 +169,10 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
hintValue: "Số lượng/khối lượng loại bỏ",
textController: _removedQuantityController,
onSaved: (newValue) {
_harvest.removedQuantity = newValue.parseDoubleThousand();
_harvest.removedQuantity = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -182,7 +187,7 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -201,10 +206,9 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -216,24 +220,25 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
child: MultiBlocProvider(
providers: [
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailHarvest,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailHarvest,
activityId: widget.activityId ?? -1,
),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child:
BlocConsumer<ActionDetailBloc, ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
LoadingDialog.hideLoadingDialog(context);
@@ -241,31 +246,20 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
LoadingDialog.hideLoadingDialog(context);
print(state.item);
_harvest = Harvest.fromJson(state.item);
_harvest.activityId = widget.activityId;
_l1Controller.text = _harvest.collectedQuantityLv1
.formatNumtoStringDecimal();
_l2Controller.text = _harvest.collectedQuantityLv2
.formatNumtoStringDecimal();
_l3Controller.text = _harvest.collectedQuantityLv3
.formatNumtoStringDecimal();
_removedQuantityController.text = _harvest
.removedQuantity
.formatNumtoStringDecimal();
_descriptionController.text =
_harvest.description ?? "";
_executeByController.text = _harvest.executeBy;
_harvest.activityId = widget.activityId ?? -1;
_l1Controller.text = _harvest.collectedQuantityLv1?.formatNumtoStringDecimal() ?? '';
_l2Controller.text = _harvest.collectedQuantityLv2?.formatNumtoStringDecimal() ?? '';
_l3Controller.text = _harvest.collectedQuantityLv3?.formatNumtoStringDecimal() ?? '';
_removedQuantityController.text = _harvest.removedQuantity?.formatNumtoStringDecimal() ?? '';
_descriptionController.text = _harvest.description ?? "";
_executeByController.text = _harvest.executeBy ?? '';

Get.find<ChangeDateTimePicker>().change(_harvest
.executeDate
.convertStringServerDateTimeToLocalDateTime());
Get.find<ChangeDateTimePicker>()
.change(_harvest.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now());
//Show media
if (Validators.stringNotNullOrEmpty(
_harvest.media)) {
BlocProvider.of<MediaHelperBloc>(context).add(
ChangeListMedia(
items:
UtilAction.convertFilePathToMedia(
_harvest.media)));
if (Validators.stringNotNullOrEmpty(_harvest.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_harvest.media ?? '')));
}
} else if (state is ActionDetailInitial) {
} else if (state is ActionDetailLoading) {
@@ -278,53 +272,48 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
plot_action_harvest,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_l1Field(),
SizedBox(
const SizedBox(
height: 8.0,
),
_l2Field(),
SizedBox(
const SizedBox(
height: 8.0,
),
_l3Field(),
SizedBox(
const SizedBox(
height: 8.0,
),
_removedQuantityField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_descriptionField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -335,20 +324,15 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
height: 16,
color: Colors.grey[200],
),
BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
Container(
@@ -367,8 +351,7 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
harvestId: _harvest.id,
));
} else {
Get.to(EditActionHarvestProcessScreen(
cropId: widget.cropId));
Get.to(EditActionHarvestProcessScreen(cropId: widget.cropId));
}
}),
ButtonIconWidget(
@@ -382,8 +365,7 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
harvestId: _harvest.id,
));
} else {
Get.to(EditActionPackingScreen(
cropId: widget.cropId));
Get.to(EditActionPackingScreen(cropId: widget.cropId));
}
}),
ButtonIconWidget(
@@ -397,11 +379,10 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
harvestId: _harvest.id,
));
} else {
Get.to(EditActionSellScreen(
cropId: widget.cropId));
Get.to(EditActionSellScreen(cropId: widget.cropId));
}
}),
SizedBox(
const SizedBox(
height: 16,
),
Padding(
@@ -409,8 +390,7 @@ class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}

+ 98
- 125
lib/presentation/screens/actions/harvest_process/sc_edit_action_harvest_process.dart View File

@@ -39,21 +39,20 @@ import '../util_action.dart';
class EditActionHarvestProcessScreen extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
final int harvestId;
EditActionHarvestProcessScreen(
{@required this.cropId,
this.isEdit = false,
this.activityId,
this.harvestId});
final int? activityId;
final int? harvestId;
EditActionHarvestProcessScreen({
required this.cropId,
this.isEdit = false,
this.activityId,
this.harvestId,
});
@override
_EditActionHarvestProcessScreenState createState() =>
_EditActionHarvestProcessScreenState();
_EditActionHarvestProcessScreenState createState() => _EditActionHarvestProcessScreenState();
}

class _EditActionHarvestProcessScreenState
extends State<EditActionHarvestProcessScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
class _EditActionHarvestProcessScreenState extends State<EditActionHarvestProcessScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
bool _autoValidate = false;
@@ -64,14 +63,14 @@ class _EditActionHarvestProcessScreenState
TextEditingController _removedQuantityController = TextEditingController();
TextEditingController _descriptionController = TextEditingController();
final _executeByController = TextEditingController();
List<SuppliesUsing> suppliesUsing = new List<SuppliesUsing>();
List<SuppliesUsing> suppliesUsing = <SuppliesUsing>[];

var pref = LocalPref();
List<Harvest> _harvests = List<Harvest>();
Harvest harvestValue;
String executeTimeView;
List<Harvest> _harvests = <Harvest>[];
Harvest harvestValue = Harvest();
String executeTimeView = '';
DateTime executeTime = DateTime.now();
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -84,9 +83,8 @@ class _EditActionHarvestProcessScreenState
super.initState();
getSharedPrefs();
changeFileController.initValue();
_harvestProcess.suppliesUsing = new List<SuppliesUsing>();
_harvestProcess.executeDate =
executeTime.convertLocalDateTimeToStringUtcDateTime();
_harvestProcess.suppliesUsing = <SuppliesUsing>[];
_harvestProcess.executeDate = executeTime.convertLocalDateTimeToStringUtcDateTime();
executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm();
_harvestProcess.cropId = widget.cropId;

@@ -104,11 +102,11 @@ class _EditActionHarvestProcessScreenState
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
filePaths = Get.find<ChangeFileController>().newFiles;
List<SuppliesUsing> newSups = [];
var newSups = <SuppliesUsing>[];
suppliesUsing.forEach((sup) {
var newSup = sup;
newSup.suppliesInWarehouseId = sup.tbSuppliesInWarehouseId;
@@ -118,8 +116,7 @@ class _EditActionHarvestProcessScreenState
_harvestProcess.suppliesUsing = newSups;
_harvestProcess.mediaDel = Get.find<ChangeFileController>().deleteFiles;
try {
var activityHarvestProcess =
jsonEncode(_harvestProcess.toJson()).toString();
var activityHarvestProcess = jsonEncode(_harvestProcess.toJson()).toString();
//ADD NEW
if (_harvestProcess.activityId == null) {
_repository.createAction((value) {
@@ -174,17 +171,17 @@ class _EditActionHarvestProcessScreenState
if (snapshot.hasData) {
return DropdownButtonFormField<Harvest>(
value: harvestValue,
hint: Text("Mã thu hoạch"),
onChanged: (Harvest newValue) {
hint: const Text("Mã thu hoạch"),
onChanged: (Harvest? newValue) {
setState(() {
harvestValue = newValue;
_harvestProcess.harvestId = newValue.id;
harvestValue = newValue ?? Harvest();
_harvestProcess.harvestId = newValue?.id ?? -1;
});
},
isExpanded: true,
items: _buildDropMenu(_harvests));
} else {
return Center(
return const Center(
child: CircularProgressIndicator(),
);
}
@@ -194,22 +191,19 @@ class _EditActionHarvestProcessScreenState

Widget _btnExecuteTimePicker() {
return FlatButton(
padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
onPressed: () {
DatePicker.showDateTimePicker(context,
showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
setState(() {
executeTime = date;
_harvestProcess.executeDate =
executeTime.convertLocalDateTimeToStringUtcDateTime();
_harvestProcess.executeDate = executeTime.convertLocalDateTimeToStringUtcDateTime();
executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm();
});
}, currentTime: executeTime, locale: LocaleType.vi);
},
child: Container(
padding:
EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: BoxDecoration(
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: const BoxDecoration(
border: kBorderTextField,
),
child: Row(
@@ -218,9 +212,9 @@ class _EditActionHarvestProcessScreenState
child: Text(
//TODO: check condition
executeTimeView == null ? "$executeTime" : executeTimeView,
style: TextStyle(fontSize: 14.0, color: Colors.black87),
style: const TextStyle(fontSize: 14.0, color: Colors.black87),
)),
Icon(
const Icon(
Icons.date_range,
color: Colors.grey,
),
@@ -233,8 +227,10 @@ class _EditActionHarvestProcessScreenState
hintValue: "Số lượng/khối lượng loại 1",
textController: _l1Controller,
onSaved: (newValue) {
_harvestProcess.quantityLv1 = newValue.parseDoubleThousand();
_harvestProcess.quantityLv1 = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -243,8 +239,10 @@ class _EditActionHarvestProcessScreenState
hintValue: "Số lượng/khối lượng loại 2",
textController: _l2Controller,
onSaved: (newValue) {
_harvestProcess.quantityLv2 = newValue.parseDoubleThousand();
_harvestProcess.quantityLv2 = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -253,8 +251,10 @@ class _EditActionHarvestProcessScreenState
hintValue: "Số lượng/khối lượng loại 3",
textController: _l3Controller,
onSaved: (newValue) {
_harvestProcess.quantityLv3 = newValue.parseDoubleThousand();
_harvestProcess.quantityLv3 = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -263,8 +263,10 @@ class _EditActionHarvestProcessScreenState
hintValue: "Số lượng/khối lượng loại bỏ",
textController: _removedQuantityController,
onSaved: (newValue) {
_harvestProcess.removedQuantity = newValue.parseDoubleThousand();
_harvestProcess.removedQuantity = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -279,7 +281,7 @@ class _EditActionHarvestProcessScreenState
Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -298,10 +300,9 @@ class _EditActionHarvestProcessScreenState
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -313,47 +314,39 @@ class _EditActionHarvestProcessScreenState
child: MultiBlocProvider(
providers: [
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity:
ConstCommon.apiDetailHarvestProcess,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailHarvestProcess,
activityId: widget.activityId ?? -1,
),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child:
BlocConsumer<ActionDetailBloc, ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
LoadingDialog.hideLoadingDialog(context);
} else if (state is ActionDetailSuccess) {
LoadingDialog.hideLoadingDialog(context);
print(state.item);
_harvestProcess =
HarvestProcess.fromJson(state.item);
_harvestProcess.activityId = widget.activityId;
_l1Controller.text = _harvestProcess.quantityLv1
.formatNumtoStringDecimal();
_l2Controller.text = _harvestProcess.quantityLv2
.formatNumtoStringDecimal();
_l3Controller.text = _harvestProcess.quantityLv3
.formatNumtoStringDecimal();
_removedQuantityController.text = _harvestProcess
.removedQuantity
.formatNumtoStringDecimal();
_descriptionController.text =
_harvestProcess.description ?? "";
_executeByController.text =
_harvestProcess.executeBy;
_harvestProcess = HarvestProcess.fromJson(state.item);
_harvestProcess.activityId = widget.activityId ?? -1;
_l1Controller.text = _harvestProcess.quantityLv1?.formatNumtoStringDecimal() ?? '';
_l2Controller.text = _harvestProcess.quantityLv2?.formatNumtoStringDecimal() ?? '';
_l3Controller.text = _harvestProcess.quantityLv3?.formatNumtoStringDecimal() ?? '';
_removedQuantityController.text = _harvestProcess.removedQuantity?.formatNumtoStringDecimal() ?? '';
_descriptionController.text = _harvestProcess.description ?? "";
_executeByController.text = _harvestProcess.executeBy ?? '';

//select harvest
getHarvestBloc.getHarvests((data) {
@@ -366,23 +359,16 @@ class _EditActionHarvestProcessScreenState
}
}, (err) {});

executeTime = _harvestProcess.executeDate
.convertStringServerDateTimeToLocalDateTime();
executeTimeView =
executeTime.displayDateTime_DDMMYYYY_HHmm();
executeTime = _harvestProcess.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now();
executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm();
//Show media
if (Validators.stringNotNullOrEmpty(
_harvestProcess.media)) {
BlocProvider.of<MediaHelperBloc>(context).add(
ChangeListMedia(
items:
UtilAction.convertFilePathToMedia(
_harvestProcess.media)));
if (Validators.stringNotNullOrEmpty(_harvestProcess.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_harvestProcess.media ?? '')));
}
//list supply
suppliesUsing = _harvestProcess.suppliesUsing;
Get.find<ChangeSupplyUsing>()
.changeInitList(suppliesUsing);
suppliesUsing = _harvestProcess.suppliesUsing ?? <SuppliesUsing>[];
Get.find<ChangeSupplyUsing>().changeInitList(suppliesUsing);
} else if (state is ActionDetailInitial) {
} else if (state is ActionDetailLoading) {
LoadingDialog.showLoadingDialog(context);
@@ -394,57 +380,52 @@ class _EditActionHarvestProcessScreenState
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
plot_action_harvest_process,
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_dropdownHarvest(),
SizedBox(
const SizedBox(
height: 8.0,
),
_l1Field(),
SizedBox(
const SizedBox(
height: 8.0,
),
_l2Field(),
SizedBox(
const SizedBox(
height: 8.0,
),
_l3Field(),
SizedBox(
const SizedBox(
height: 8.0,
),
_removedQuantityField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_descriptionField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -460,7 +441,7 @@ class _EditActionHarvestProcessScreenState
onChangeSupplies: (value) {
suppliesUsing = value;
}),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
@@ -468,20 +449,15 @@ class _EditActionHarvestProcessScreenState
height: 16,
color: Colors.grey[200],
),
BlocBuilder<MediaHelperBloc, MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child: CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
Padding(
@@ -489,15 +465,12 @@ class _EditActionHarvestProcessScreenState
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
if (Get.find<ChangeFieldFormSupply>()
.isChanged) {
Utils.showDialogConfirmSupply(
onConfirm: () {
if (Get.find<ChangeFieldFormSupply>().isChanged) {
Utils.showDialogConfirmSupply(onConfirm: () {
Get.back();
_validateInputs();
});

+ 113
- 172
lib/presentation/screens/actions/harvest_process/widget_harvest_process_supply.dart View File

@@ -25,15 +25,12 @@ import '../util_action.dart';
class WidgetHarvestProcessSupply extends StatefulWidget {
final List<SuppliesUsing> currentItems;
final Function(List<SuppliesUsing> supplyChanges) onChangeSupplies;
WidgetHarvestProcessSupply(
{this.currentItems, @required this.onChangeSupplies});
WidgetHarvestProcessSupply({required this.currentItems, required this.onChangeSupplies});
@override
_WidgetHarvestProcessSupplyState createState() =>
_WidgetHarvestProcessSupplyState();
_WidgetHarvestProcessSupplyState createState() => _WidgetHarvestProcessSupplyState();
}

class _WidgetHarvestProcessSupplyState
extends State<WidgetHarvestProcessSupply> {
class _WidgetHarvestProcessSupplyState extends State<WidgetHarvestProcessSupply> {
final _dosageController = TextEditingController();
final _quantityController = TextEditingController();
final _howToUseController = TextEditingController();
@@ -65,7 +62,7 @@ class _WidgetHarvestProcessSupplyState
return Container(
height: 120,
child: ListView.builder(
physics: ClampingScrollPhysics(),
physics: const ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: value.currentItems.length,
@@ -87,63 +84,46 @@ class _WidgetHarvestProcessSupplyState
..name = editedSupplyUsing.equipmentName;
changeSelectedDevice.change(editedDevice);

changeUnit
.updateListByUnitName(editedSupplyUsing.supplyUnit);
changeUnit.updateSelected(editedSupplyUsing.supplyUnit);
_dosageController.text = editedSupplyUsing.dosage;
_howToUseController.text = editedSupplyUsing.howToUse;
_quantityController.text = editedSupplyUsing.quantity
.formatNumtoStringDecimal();
changeUnit.updateListByUnitName(editedSupplyUsing.supplyUnit ?? '');
changeUnit.updateSelected(editedSupplyUsing.supplyUnit ?? '');
_dosageController.text = editedSupplyUsing.dosage ?? '';
_howToUseController.text = editedSupplyUsing.howToUse ?? '';
_quantityController.text = editedSupplyUsing.quantity?.formatNumtoStringDecimal() ?? '';
},
child: Card(
child: Stack(
alignment: Alignment.bottomCenter,
overflow: Overflow.visible,
// overflow: Overflow.visible,
children: <Widget>[
Positioned(
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
padding: EdgeInsets.all(4),
padding: const EdgeInsets.all(4),
width: 150,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
const SizedBox(
height: 12.0,
),
Flexible(
child: Text(
value.currentItems[index].supplyName ??
"",
overflow: TextOverflow.ellipsis,
maxLines: 1),
child: Text(value.currentItems[index].supplyName ?? "", overflow: TextOverflow.ellipsis, maxLines: 1),
),
Validators.stringNotNullOrEmpty(
value.currentItems[index].dosage)
Validators.stringNotNullOrEmpty(value.currentItems[index].dosage ?? '')
? Flexible(child: Text("${value.currentItems[index].dosage ?? ""}"))
: const SizedBox(),
Validators.stringNotNullOrEmpty(value.currentItems[index].quantity?.formatNumtoStringDecimal() ?? '')
? Flexible(
child: Text(
"${value.currentItems[index].dosage ?? ""}"))
: SizedBox(),
Validators.stringNotNullOrEmpty(value
.currentItems[index].quantity
.formatNumtoStringDecimal())
? Flexible(
child: Text(
"${value.currentItems[index].quantity.formatNumtoStringDecimal() ?? ""} ${value.currentItems[index].supplyUnit ?? ""}"))
: SizedBox(),
Validators.stringNotNullOrEmpty(value
.currentItems[index].equipmentName)
? Flexible(
child: Text(
"${value.currentItems[index].equipmentName ?? ""}"))
: SizedBox(),
Validators.stringNotNullOrEmpty(
value.currentItems[index].howToUse)
? Flexible(
child: Text(
"${value.currentItems[index].howToUse ?? ""}"))
: SizedBox(),
"${value.currentItems[index].quantity?.formatNumtoStringDecimal() ?? ""} ${value.currentItems[index].supplyUnit ?? ""}"))
: const SizedBox(),
Validators.stringNotNullOrEmpty(value.currentItems[index].equipmentName ?? '')
? Flexible(child: Text("${value.currentItems[index].equipmentName ?? ""}"))
: const SizedBox(),
Validators.stringNotNullOrEmpty(value.currentItems[index].howToUse ?? '')
? Flexible(child: Text("${value.currentItems[index].howToUse ?? ""}"))
: const SizedBox(),
],
),
),
@@ -152,7 +132,7 @@ class _WidgetHarvestProcessSupplyState
top: -10,
right: -10,
child: IconButton(
icon: Icon(
icon: const Icon(
Icons.cancel,
color: Colors.redAccent,
),
@@ -170,8 +150,7 @@ class _WidgetHarvestProcessSupplyState
Widget _btnSelectSubstrates() {
return GetBuilder<ChangeSupply>(builder: (data) {
return FlatButton(
padding:
EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
onPressed: () {
var currentIndexEdit = changeSupplyUsing.currentIndex;
Navigator.of(context)
@@ -181,17 +160,15 @@ class _WidgetHarvestProcessSupplyState
type: ConstCommon.supplyTypeAll,
selectedId: changeSelectedSupply.selectedSupplyId,
currentItems: changeSupplyUsing.currentItems,
currentEditId: (currentIndexEdit >= 0)
? changeSupplyUsing.currentItems[currentIndexEdit]
.tbSuppliesInWarehouseId
: -1,
currentEditId:
(currentIndexEdit >= 0) ? changeSupplyUsing.currentItems[currentIndexEdit].tbSuppliesInWarehouseId ?? -1 : -1,
),
fullscreenDialog: false))
.then((value) {
if (value != null) {
var result = value as Supply;
changeSelectedSupply.change(result);
changeUnit.updateListByUnitName(result.unit);
changeUnit.updateListByUnitName(result.unit ?? '');
changeFormField.change(true);
}
});
@@ -202,35 +179,28 @@ class _WidgetHarvestProcessSupplyState
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(
top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: isValid ? Colors.grey : Colors.red[900])),
bottom: BorderSide(
width: 1,
color: isValid ? Colors.grey : Colors.red,
),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Hoá chất xử lý *',
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.normal,
color:
isValid ? Colors.black54 : Colors.red[600]),
style: TextStyle(fontSize: 13, fontWeight: FontWeight.normal, color: isValid ? Colors.black54 : Colors.red[600]),
),
Row(
children: [
Expanded(
child: Text(
changeSelectedSupply.selectedSupplyName ??
"Hoá chất xử lý",
style: TextStyle(
fontSize: 14.0,
color: Colors.black87))),
Icon(
child: Text(changeSelectedSupply.selectedSupplyName ?? "Hoá chất xử lý",
style: const TextStyle(fontSize: 14.0, color: Colors.black87))),
const Icon(
Icons.arrow_drop_down,
color: Colors.grey,
),
@@ -238,7 +208,7 @@ class _WidgetHarvestProcessSupplyState
),
],
)),
isValid ? SizedBox() : WidgetErrorTextField()
isValid ? const SizedBox() : WidgetErrorTextField()
],
);
}));
@@ -248,14 +218,11 @@ class _WidgetHarvestProcessSupplyState
Widget _btnSelectDevice() {
return GetBuilder<ChangeDevice>(builder: (data) {
return FlatButton(
padding:
EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(
builder: (_) => ListDeviceActivity(
selectedId: changeSelectedDevice.selectedDeviceId),
fullscreenDialog: false))
.push(
MaterialPageRoute(builder: (_) => ListDeviceActivity(selectedId: changeSelectedDevice.selectedDeviceId), fullscreenDialog: false))
.then((value) {
if (value != null) {
var result = value as Device;
@@ -265,21 +232,17 @@ class _WidgetHarvestProcessSupplyState
});
},
child: Container(
padding: EdgeInsets.only(
top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: BoxDecoration(
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: const BoxDecoration(
border: kBorderTextField,
),
child: Row(
children: [
GetBuilder<ChangeSupply>(
builder: (_) => Expanded(
child: Text(
changeSelectedDevice.selectedDeviceName ??
"Thiết bị",
style: TextStyle(
fontSize: 14.0, color: Colors.black87)))),
Icon(
child: Text(changeSelectedDevice.selectedDeviceName ?? "Thiết bị",
style: const TextStyle(fontSize: 14.0, color: Colors.black87)))),
const Icon(
Icons.arrow_drop_down,
color: Colors.grey,
),
@@ -306,14 +269,11 @@ class _WidgetHarvestProcessSupplyState
var oldSelected = data.selectedUnit;
if (oldSelected == value) {
} else {
assignValue = UtilAction.convertUnit(
inputValue: assignValue,
oldUnit: oldSelected,
newUnit: value);
assignValue = UtilAction.convertUnit(inputValue: assignValue, oldUnit: oldSelected, newUnit: value ?? '');
}
_quantityController.text = assignValue.formatNumtoStringDecimal();
}
changeUnit.updateSelected(value);
changeUnit.updateSelected(value ?? '');
},
);
});
@@ -323,9 +283,8 @@ class _WidgetHarvestProcessSupplyState
return WidgetTextFormFieldNumber(
hintValue: "Tổng lượng sử dụng *",
textController: _quantityController,
validator: (String value) {
return Validators.validateNotNullOrEmpty(
value, label_validate_input_empty);
validator: (String? value) {
// return Validators.validateNotNullOrEmpty(value, label_validate_input_empty);
},
onChanged: (value) {
if (!Validators.stringNotNullOrEmpty(value) &&
@@ -338,6 +297,7 @@ class _WidgetHarvestProcessSupplyState
changeFormField.change(true);
}
},
onSaved: (_) {},
);
}

@@ -347,42 +307,36 @@ class _WidgetHarvestProcessSupplyState
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_.isEdit
? OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(8.0)),
child: Text("Huỷ"),
onPressed: () {
? InkWell(
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
child: const Text("Huỷ"),
onTap: () {
changeButton.resetValue();
_resetForm();
_hidenKeyboard(context);
})
: SizedBox(),
: const SizedBox(),
_.isEdit
? Expanded(
child: FlatButton(
onPressed: () {
if (_formSupplyKey.currentState.validate()) {
_formSupplyKey.currentState.save();
if (_formSupplyKey.currentState!.validate()) {
_formSupplyKey.currentState!.save();
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
changeSelectedSupply.changeValid(true);
}
var currentSupply =
changeSelectedSupply.currentSupply;
var currentDevice =
changeSelectedDevice.currentDevice;
var currentQuantity =
_quantityController.text.parseDoubleThousand();
if (currentSupply.id != null &&
(currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit =
UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply
.currentSupply.unit);
SuppliesUsing newSup = SuppliesUsing()
var currentSupply = changeSelectedSupply.currentSupply;
var currentDevice = changeSelectedDevice.currentDevice;
var currentQuantity = _quantityController.text.parseDoubleThousand();
if (currentSupply.id != null && (currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit = UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply.currentSupply.unit ?? '',
);
var newSup = SuppliesUsing()
..dosage = _dosageController.text
..howToUse = _howToUseController.text
..quantity = quantityWithCurrentSupplyUnit
@@ -394,18 +348,14 @@ class _WidgetHarvestProcessSupplyState
..equipmentName = currentDevice.name
..supplyUnit = currentSupply.unit
..unit = currentSupply.unit;
changeSupplyUsing.editSupply(
changeSupplyUsing.currentIndex, newSup);
changeSupplyUsing.editSupply(changeSupplyUsing.currentIndex, newSup);
_resetForm();
_hidenKeyboard(context);
} else if (currentSupply.id == null ||
((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
} else if (currentSupply.id == null || ((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
}
} else {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
@@ -413,7 +363,7 @@ class _WidgetHarvestProcessSupplyState
}
}
},
child: Text(
child: const Text(
"Sửa hoá chất xử lý",
style: TextStyle(color: Colors.blue),
)),
@@ -421,28 +371,23 @@ class _WidgetHarvestProcessSupplyState
: Expanded(
child: FlatButton(
onPressed: () {
if (_formSupplyKey.currentState.validate()) {
_formSupplyKey.currentState.save();
if (_formSupplyKey.currentState!.validate()) {
_formSupplyKey.currentState!.save();
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
changeSelectedSupply.changeValid(true);
}
var currentSupply =
changeSelectedSupply.currentSupply;
var currentDevice =
changeSelectedDevice.currentDevice;
var currentQuantity =
_quantityController.text.parseDoubleThousand();
if (currentSupply.id != null &&
(currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit =
UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply
.currentSupply.unit);
SuppliesUsing newSup = SuppliesUsing()
var currentSupply = changeSelectedSupply.currentSupply;
var currentDevice = changeSelectedDevice.currentDevice;
var currentQuantity = _quantityController.text.parseDoubleThousand();
if (currentSupply.id != null && (currentQuantity ?? 0) > 0) {
var quantityWithCurrentSupplyUnit = UtilAction.convertUnit(
inputValue: currentQuantity,
oldUnit: changeUnit.selectedUnit,
newUnit: changeSelectedSupply.currentSupply.unit ?? '',
);
var newSup = SuppliesUsing()
..dosage = _dosageController.text
..howToUse = _howToUseController.text
..quantity = quantityWithCurrentSupplyUnit
@@ -457,14 +402,11 @@ class _WidgetHarvestProcessSupplyState
changeSupplyUsing.addSupply(newSup);
_resetForm();
_hidenKeyboard(context);
} else if (currentSupply.id == null ||
((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
} else if (currentSupply.id == null || ((currentQuantity ?? 0) <= 0)) {
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
}
} else {
Utils.showSnackBarWarning(
message: "Vui lòng nhập vật tư và số lượng");
Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
if (changeSelectedSupply.selectedSupplyId <= 0) {
changeSelectedSupply.changeValid(false);
} else {
@@ -472,7 +414,7 @@ class _WidgetHarvestProcessSupplyState
}
}
},
child: Text(
child: const Text(
"+ Thêm hoá chất xử lý",
style: TextStyle(color: Colors.blue),
)),
@@ -488,26 +430,27 @@ class _WidgetHarvestProcessSupplyState
child: Column(
children: [
Container(
padding: EdgeInsets.all(8.0),
margin: EdgeInsets.all(8.0),
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(color: Colors.grey[300])),
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(
color: Colors.grey,
),
),
child: Column(
children: [
_btnSelectSubstrates(),
TextFormField(
keyboardType: TextInputType.text,
controller: _dosageController,
decoration: InputDecoration(labelText: "Liều lượng sử dụng"),
decoration: const InputDecoration(labelText: "Liều lượng sử dụng"),
onSaved: (newValue) {},
onChanged: (value) {
if (!Validators.stringNotNullOrEmpty(
_quantityController.text) &&
!Validators.stringNotNullOrEmpty(
_howToUseController.text) &&
if (!Validators.stringNotNullOrEmpty(_quantityController.text) &&
!Validators.stringNotNullOrEmpty(_howToUseController.text) &&
!Validators.stringNotNullOrEmpty(value) &&
Get.find<ChangeSupply>().selectedSupplyId <= 0 &&
changeSelectedDevice.selectedDeviceId <= 0) {
@@ -529,7 +472,7 @@ class _WidgetHarvestProcessSupplyState
child: _quantityField(),
),
),
SizedBox(
const SizedBox(
width: 16.0,
),
Expanded(
@@ -541,7 +484,7 @@ class _WidgetHarvestProcessSupplyState
]),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Thiết bị",
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
@@ -550,14 +493,12 @@ class _WidgetHarvestProcessSupplyState
TextFormField(
keyboardType: TextInputType.text,
controller: _howToUseController,
decoration: InputDecoration(labelText: "Phương pháp sử dụng"),
decoration: const InputDecoration(labelText: "Phương pháp sử dụng"),
onSaved: (newValue) {},
onChanged: (value) {
if (!Validators.stringNotNullOrEmpty(
_quantityController.text) &&
if (!Validators.stringNotNullOrEmpty(_quantityController.text) &&
!Validators.stringNotNullOrEmpty(value) &&
!Validators.stringNotNullOrEmpty(
_dosageController.text) &&
!Validators.stringNotNullOrEmpty(_dosageController.text) &&
Get.find<ChangeSupply>().selectedSupplyId <= 0 &&
changeSelectedDevice.selectedDeviceId <= 0) {
changeFormField.change(false);
@@ -588,7 +529,7 @@ class _WidgetHarvestProcessSupplyState
}

_hidenKeyboard(BuildContext context) {
FocusScopeNode currentFocus = FocusScope.of(context);
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
@@ -598,8 +539,8 @@ class _WidgetHarvestProcessSupplyState
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
const Padding(
padding: EdgeInsets.all(8.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
@@ -609,7 +550,7 @@ class _WidgetHarvestProcessSupplyState
),
),
_buildListSupply(),
SizedBox(
const SizedBox(
height: 8.0,
),
_formEdit()

+ 6
- 6
lib/presentation/screens/actions/nursery/bloc/expansion_list_bloc.dart View File

@@ -18,15 +18,15 @@ class ExpansionListBloc extends Bloc<ExpansionListEvent, ExpansionListState> {
ExpansionListEvent event,
) async* {
if (event is AddNew) {
List<NurseryDetail> items = new List<NurseryDetail>();
for (int i = 0; i < event.items.length; i++) {
var items = <NurseryDetail>[];
for (var i = 0; i < event.items.length; i++) {
var current = event.items[i];
items.add(NurseryDetail.clone(current));
}
yield ExpansionListSuccess(items: items);
} else if (event is DeleteItem) {
List<NurseryDetail> items = new List<NurseryDetail>();
for (int i = 0; i < event.items.length; i++) {
var items = <NurseryDetail>[];
for (var i = 0; i < event.items.length; i++) {
var current = event.items[i];
if (i == event.index) {
//ignore
@@ -37,8 +37,8 @@ class ExpansionListBloc extends Bloc<ExpansionListEvent, ExpansionListState> {

yield ExpansionListSuccess(items: items);
} else if (event is Update) {
List<NurseryDetail> items = new List<NurseryDetail>();
for (int i = 0; i < event.items.length; i++) {
var items = <NurseryDetail>[];
for (var i = 0; i < event.items.length; i++) {
var current = event.items[i];
if (i == event.index) {
items.add(NurseryDetail.clone(event.item));

+ 3
- 3
lib/presentation/screens/actions/nursery/bloc/expansion_list_event.dart View File

@@ -11,16 +11,16 @@ class Update extends ExpansionListEvent {
final int index;
final NurseryDetail item;
final List<NurseryDetail> items;
Update({@required this.index, @required this.item, @required this.items});
Update({required this.index, required this.item, required this.items});
}

class AddNew extends ExpansionListEvent {
final List<NurseryDetail> items;
AddNew({@required this.items});
AddNew({required this.items});
}

class DeleteItem extends ExpansionListEvent {
final int index;
final List<NurseryDetail> items;
DeleteItem({@required this.index, @required this.items});
DeleteItem({required this.index, required this.items});
}

+ 3
- 3
lib/presentation/screens/actions/nursery/bloc/expansion_list_state.dart View File

@@ -11,15 +11,15 @@ class ExpansionListInitial extends ExpansionListState {}

class ExpansionListFailure extends ExpansionListState {
final String errorString;
ExpansionListFailure({@required this.errorString});
ExpansionListFailure({required this.errorString});
}

class ExpansionListSuccess extends ExpansionListState {
final List<NurseryDetail> items;

const ExpansionListSuccess({this.items});
const ExpansionListSuccess({required this.items});

ExpansionListSuccess copyWith({List<NurseryDetail> items}) {
ExpansionListSuccess copyWith({List<NurseryDetail>? items}) {
return ExpansionListSuccess(items: items ?? this.items);
}


+ 136
- 207
lib/presentation/screens/actions/nursery/sc_edit_action_nursery.dart View File

@@ -37,15 +37,14 @@ import '../util_action.dart';
class EditActionNurseryScreen extends StatefulWidget {
final int cropId;
final bool isEdit;
final int activityId;
EditActionNurseryScreen(
{@required this.cropId, this.isEdit = false, this.activityId});
final int? activityId;
EditActionNurseryScreen({required this.cropId, this.isEdit = false, this.activityId});
@override
_EditActionNurseryState createState() => _EditActionNurseryState();
}

class _EditActionNurseryState extends State<EditActionNurseryScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final _repository = Repository();
GlobalKey<FormState> _formKey = GlobalKey();
GlobalKey<FormState> _formWorkerKey = GlobalKey();
@@ -61,12 +60,12 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
TextEditingController _trayNumberController = TextEditingController();
final _executeByController = TextEditingController();
DateTime executeTime = DateTime.now();
List<NurseryDetail> currentNurseryDetail = List<NurseryDetail>();
List<NurseryDetail> currentNurseryDetail = <NurseryDetail>[];
int currentIndexUpdate = -1;
bool isResetForm = true;
final changeSupply = Get.put(ChangeSupply());
int selectedSupplyId = -1;
List<String> filePaths = List<String>();
List<String> filePaths = <String>[];
var changeFileController = Get.put(ChangeFileController());

Future<Null> getSharedPrefs() async {
@@ -80,13 +79,13 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
getSharedPrefs();
changeSupply.initValue();
changeFileController.initValue();
_nursery.nurseryDetail = new List<NurseryDetail>();
_nursery.nurseryDetail = <NurseryDetail>[];
_nursery.cropId = widget.cropId;
}

_validateInputs() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
LoadingDialog.showLoadingDialog(context);
_nursery.nurseryDetail = currentNurseryDetail;
filePaths = Get.find<ChangeFileController>().newFiles;
@@ -130,14 +129,13 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
return WidgetFieldDateTimePicker(
initDateTime: executeTime,
onUpdateDateTime: (selectedDate) {
_nursery.executeDate =
selectedDate.convertLocalDateTimeToStringUtcDateTime();
_nursery.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime();
});
}

Widget _btnSelectSubstrates() {
return FlatButton(
padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(
@@ -158,22 +156,17 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
});
},
child: Container(
padding:
EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: BoxDecoration(
padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
decoration: const BoxDecoration(
border: kBorderTextField,
),
child: Row(
children: [
GetBuilder<ChangeSupply>(
builder: (_) => Expanded(
child: Text(
changeSupply.selectedSupplyName == null
? "Loại giá thể"
: changeSupply.selectedSupplyName.toString(),
style: TextStyle(
fontSize: 14.0, color: Colors.black87)))),
Icon(
child: Text(changeSupply.selectedSupplyName == null ? "Loại giá thể" : changeSupply.selectedSupplyName.toString(),
style: const TextStyle(fontSize: 14.0, color: Colors.black87)))),
const Icon(
Icons.arrow_drop_down,
color: Colors.grey,
),
@@ -186,8 +179,10 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
hintValue: "Chiều dài mầm",
textController: _seedLengthController,
onSaved: (newValue) {
_nursery.seedLength = newValue.parseDoubleThousand();
_nursery.seedLength = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -196,8 +191,10 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
hintValue: "Số lượng hạt gieo",
textController: _quantityController,
onSaved: (newValue) {
_nursery.quantity = newValue.parseDoubleThousand();
_nursery.quantity = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -206,8 +203,10 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
hintValue: "Thời gian ngâm hạt",
textController: _seedIncubationTimeController,
onSaved: (newValue) {
_nursery.seedIncubationTime = newValue.parseDoubleThousand();
_nursery.seedIncubationTime = (newValue ?? '0').parseDoubleThousand();
},
onChanged: (_) {},
validator: (_) {},
);
}

@@ -222,7 +221,7 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
Widget _executeByField() {
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(labelText: "Người thực hiện"),
decoration: const InputDecoration(labelText: "Người thực hiện"),
enabled: false,
controller: _executeByController,
onSaved: (newValue) {},
@@ -232,12 +231,11 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
Widget _btnAddWorker() {
//TODO :check flow error sua item -> xoa list -> bam nut them
return Builder(builder: (context) {
return BlocConsumer<StatusAddFormBloc, StatusAddFormState>(
listener: (context, state) {
return BlocConsumer<StatusAddFormBloc, StatusAddFormState>(listener: (context, state) {
if (state is Edit) {
isResetForm = false;
_workerNameController.text = state.nurseryDetail.workerName;
_trayNumberController.text = state.nurseryDetail.trayNumber;
_workerNameController.text = state.nurseryDetail.workerName ?? '';
_trayNumberController.text = state.nurseryDetail.trayNumber ?? '';
} else if (state is Delete) {
if (currentIndexUpdate == state.index) {
isResetForm = true;
@@ -256,90 +254,80 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
child: Column(
children: [
Container(
padding: EdgeInsets.all(8.0),
margin: EdgeInsets.all(8),
padding: const EdgeInsets.all(8.0),
margin: const EdgeInsets.all(8),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border.all(color: Colors.grey[300])),
shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(10), color: Colors.white, border: Border.all(color: Colors.grey)),
child: Column(
children: [
TextFormField(
keyboardType: TextInputType.text,
controller: _workerNameController,
decoration: InputDecoration(labelText: "Tên công nhân *"),
decoration: const InputDecoration(labelText: "Tên công nhân *"),
validator: (value) {
return Validators.validateNotNullOrEmpty(
value, label_validate_input_empty);
return Validators.validateNotNullOrEmpty(value ?? '', label_validate_input_empty);
},
onSaved: (newValue) {},
),
TextFormField(
keyboardType: TextInputType.text,
controller: _trayNumberController,
decoration: InputDecoration(labelText: "Ươm khây số"),
decoration: const InputDecoration(labelText: "Ươm khây số"),
onSaved: (newValue) {},
),
],
),
),
Container(
margin: EdgeInsets.all(8),
margin: const EdgeInsets.all(8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
isResetForm
? Container()
: OutlineButton(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(8.0)),
child: Text("Huỷ"),
onPressed: () {
: InkWell(
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
child: const Text("Huỷ"),
onTap: () {
context.bloc<StatusAddFormBloc>().add(Reset());
}),
Expanded(
child: FlatButton(
onPressed: () {
if (_formWorkerKey.currentState.validate()) {
_formWorkerKey.currentState.save();
if (Validators.stringNotNullOrEmpty(
_workerNameController.text)) {
NurseryDetail _nurseryDetail = NurseryDetail()
if (_formWorkerKey.currentState!.validate()) {
_formWorkerKey.currentState!.save();
if (Validators.stringNotNullOrEmpty(_workerNameController.text)) {
var _nurseryDetail = NurseryDetail()
..workerName = _workerNameController.text
..trayNumber = _trayNumberController.text;

if (state is Edit) {
context.bloc<ExpansionListBloc>().add(Update(
index: state.index,
item: _nurseryDetail,
items: state.items));
context.bloc<ExpansionListBloc>().add(
Update(
index: state.index,
item: _nurseryDetail,
items: state.items ?? <NurseryDetail>[],
),
);
} else {
currentNurseryDetail.insert(
0, _nurseryDetail);
BlocProvider.of<ExpansionListBloc>(context)
.add(AddNew(items: currentNurseryDetail));
currentNurseryDetail.insert(0, _nurseryDetail);
BlocProvider.of<ExpansionListBloc>(context).add(AddNew(items: currentNurseryDetail));
}
context.bloc<StatusAddFormBloc>().add(Reset());
} else {
Utils.showSnackBarWarning(
message: "Vui lòng nhập tên công nhân");
Utils.showSnackBarWarning(message: "Vui lòng nhập tên công nhân");
}
} else {
//
if (!Validators.stringNotNullOrEmpty(
_workerNameController.text)) {
Utils.showSnackBarWarning(
message: "Vui lòng nhập tên công nhân");
if (!Validators.stringNotNullOrEmpty(_workerNameController.text)) {
Utils.showSnackBarWarning(message: "Vui lòng nhập tên công nhân");
}
}
},
child: Text(
(state is Edit)
? "Sửa người thực hiện"
: "+ Thêm người thực hiện",
style: TextStyle(color: Colors.blue),
(state is Edit) ? "Sửa người thực hiện" : "+ Thêm người thực hiện",
style: const TextStyle(color: Colors.blue),
)),
)
],
@@ -354,8 +342,7 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {

Widget _buildListAddWorker() {
return Builder(builder: (context) {
return BlocBuilder<ExpansionListBloc, ExpansionListState>(
builder: (context, state) {
return BlocBuilder<ExpansionListBloc, ExpansionListState>(builder: (context, state) {
if (state is ExpansionListSuccess) {
currentNurseryDetail = state.items;
if (currentNurseryDetail.isEmpty) {
@@ -364,7 +351,7 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
return Container(
height: 70,
child: ListView.builder(
physics: ClampingScrollPhysics(),
physics: const ClampingScrollPhysics(),
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: currentNurseryDetail.length,
@@ -374,45 +361,31 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
print("edit worker");
currentIndexUpdate = index;
context.bloc<StatusAddFormBloc>().add(Changed(
status: CRUDStatus.edit,
index: index,
nurseryDetail: currentNurseryDetail[index],
items: currentNurseryDetail));
status: CRUDStatus.edit, index: index, nurseryDetail: currentNurseryDetail[index], items: currentNurseryDetail));
},
child: Card(
child: Stack(
alignment: Alignment.bottomCenter,
overflow: Overflow.visible,
// overflow: Overflow.visible,
children: <Widget>[
Positioned(
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Container(
padding: EdgeInsets.all(4),
padding: const EdgeInsets.all(4),
width: 120,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
const SizedBox(
height: 12.0,
),
Flexible(
child: Text(
currentNurseryDetail[index]
.workerName ??
"",
overflow: TextOverflow.ellipsis,
maxLines: 1),
child: Text(currentNurseryDetail[index].workerName ?? "", overflow: TextOverflow.ellipsis, maxLines: 1),
),
Validators.stringNotNullOrEmpty(
currentNurseryDetail[index]
.trayNumber)
? Flexible(
child: Text(
currentNurseryDetail[index]
.trayNumber ??
""))
: SizedBox()
Validators.stringNotNullOrEmpty(currentNurseryDetail[index].trayNumber ?? '')
? Flexible(child: Text(currentNurseryDetail[index].trayNumber ?? ""))
: const SizedBox()
],
),
),
@@ -421,23 +394,18 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
top: -10,
right: -10,
child: IconButton(
icon: Icon(
icon: const Icon(
Icons.cancel,
color: Colors.redAccent,
),
onPressed: () {
print("Delete worker");
context.bloc<ExpansionListBloc>().add(
DeleteItem(
index: index,
items: currentNurseryDetail));
context.bloc<StatusAddFormBloc>().add(
Changed(
status: CRUDStatus.delete,
index: index,
nurseryDetail:
currentNurseryDetail[index],
items: currentNurseryDetail));
context.bloc<ExpansionListBloc>().add(DeleteItem(index: index, items: currentNurseryDetail));
context.bloc<StatusAddFormBloc>().add(Changed(
status: CRUDStatus.delete,
index: index,
nurseryDetail: currentNurseryDetail[index],
items: currentNurseryDetail));
}),
)
],
@@ -464,10 +432,9 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
appBar: AppBarWidget(
isBack: true,
action: InkWell(
child: Text(
child: const Text(
'Huỷ',
style: TextStyle(
color: Colors.red, fontWeight: FontWeight.normal),
style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal),
),
onTap: () {
if (Get.isSnackbarOpen) Get.back();
@@ -485,24 +452,25 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
create: (context) => StatusAddFormBloc(),
),
BlocProvider<ActionDetailBloc>(
create: (context) =>
ActionDetailBloc(repository: Repository())
..add(FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailNursery,
activityId: widget.activityId))),
create: (context) => ActionDetailBloc(repository: Repository())
..add(
FetchData(
isNeedFetchData: widget.isEdit,
apiActivity: ConstCommon.apiDetailNursery,
activityId: widget.activityId ?? -1,
),
),
),
BlocProvider<MediaHelperBloc>(
create: (context) =>
MediaHelperBloc()..add(ChangeListMedia(items: [])),
create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])),
)
],
child: Form(
key: _formKey,
autovalidate: _autoValidate,
// autovalidate: _autoValidate,
child: SafeArea(
child: SingleChildScrollView(
child: BlocConsumer<ActionDetailBloc,
ActionDetailState>(
child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
listener: (context, state) async {
if (state is ActionDetailFailure) {
print("fail");
@@ -512,43 +480,29 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
print("success");
print(state.item);
_nursery = Nursery.fromJson(state.item);
_seedLengthController.text = _nursery
.seedLength
.formatNumtoStringDecimal();
_quantityController.text = _nursery.quantity
.formatNumtoStringDecimal();
_seedIncubationTimeController.text =
_nursery.seedIncubationTime
.formatNumtoStringDecimal();
_descriptionController.text =
_nursery.description;
_executeByController.text =
_nursery.executeBy;
Get.find<ChangeDateTimePicker>().change(_nursery
.executeDate
.convertStringServerDateTimeToLocalDateTime());
_seedLengthController.text = _nursery.seedLength?.formatNumtoStringDecimal() ?? '';
_quantityController.text = _nursery.quantity?.formatNumtoStringDecimal() ?? '';
_seedIncubationTimeController.text = _nursery.seedIncubationTime?.formatNumtoStringDecimal() ?? '';
_descriptionController.text = _nursery.description ?? '';
_executeByController.text = _nursery.executeBy ?? '';
Get.find<ChangeDateTimePicker>().change(
_nursery.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(),
);
//Show media
if (Validators.stringNotNullOrEmpty(
_nursery.media)) {
if (Validators.stringNotNullOrEmpty(_nursery.media ?? '')) {
BlocProvider.of<MediaHelperBloc>(context)
.add(ChangeListMedia(
items: UtilAction
.convertFilePathToMedia(
_nursery.media)));
.add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_nursery.media ?? '')));
}
//Show worker
if (_nursery.nurseryDetail.length > 0) {
BlocProvider.of<ExpansionListBloc>(
context)
.add(AddNew(
items: _nursery.nurseryDetail));
if (_nursery.nurseryDetail != null) {
if (_nursery.nurseryDetail!.length > 0) {
BlocProvider.of<ExpansionListBloc>(context).add(AddNew(items: _nursery.nurseryDetail!));
}
}
//change subStrates

if (_nursery.substratesId != null) {
Get.find<ChangeSupply>()
.changeByIdAndName(
_nursery.substratesId,
_nursery.substrateName);
Get.find<ChangeSupply>().changeByIdAndName(_nursery.substratesId!.toInt(), _nursery.substrateName ?? '');
}
} else if (state is ActionDetailInitial) {
print("init");
@@ -561,64 +515,57 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
return Column(
children: [
Padding(
padding: EdgeInsets.all(8),
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
const Text(
'Ươm',
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 22),
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22),
),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Ngày thực hiện *",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnExecuteTimePicker(),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
width: double.infinity,
child: Text(
child: const Text(
"Loại giá thể",
style: TextStyle(
color: Colors.black54,
fontSize: 13.0),
style: TextStyle(color: Colors.black54, fontSize: 13.0),
),
),
_btnSelectSubstrates(),
SizedBox(
const SizedBox(
height: 8.0,
),
_seedLengthField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_quantityField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_seedIncubationTimeField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_desciptionField(),
SizedBox(
const SizedBox(
height: 8.0,
),
_executeByField(),
SizedBox(
const SizedBox(
height: 8.0,
),
],
@@ -629,15 +576,15 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
height: 16,
color: Colors.grey[200],
),
SizedBox(
const SizedBox(
height: 8.0,
),
_buildListAddWorker(),
SizedBox(
const SizedBox(
height: 8.0,
),
_btnAddWorker(),
SizedBox(
const SizedBox(
height: 8.0,
),
Container(
@@ -645,30 +592,22 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
height: 16,
color: Colors.grey[200],
),
SizedBox(
const SizedBox(
height: 8.0,
),
BlocBuilder<MediaHelperBloc,
MediaHelperState>(
builder: (context, state) {
BlocBuilder<MediaHelperBloc, MediaHelperState>(builder: (context, state) {
if (state is MediaHelperSuccess) {
print("length: " +
state.items.length.toString());
print("length: " + state.items.length.toString());
return WidgetMediaPicker(
currentItems: state.items,
onChangeFiles: (newPathFiles,
deletePathFiles) async {
Get.find<ChangeFileController>()
.change(newPathFiles,
deletePathFiles);
onChangeFiles: (newPathFiles, deletePathFiles) async {
Get.find<ChangeFileController>().change(newPathFiles, deletePathFiles);
});
} else {
return Center(
child:
CircularProgressIndicator());
return const Center(child: CircularProgressIndicator());
}
}),
SizedBox(
const SizedBox(
height: 16,
),
Padding(
@@ -676,27 +615,17 @@ class _EditActionNurseryState extends State<EditActionNurseryScreen> {
child: ButtonWidget(
title: 'CẬP NHẬT',
onPressed: () {
FocusScopeNode currentFocus =
FocusScope.of(context);
if (!currentFocus
.hasPrimaryFocus) {
var currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
if (!Validators
.stringNotNullOrEmpty(
_workerNameController
.text) &&
!Validators
.stringNotNullOrEmpty(
_trayNumberController
.text)) {
if (!Validators.stringNotNullOrEmpty(_workerNameController.text) &&
!Validators.stringNotNullOrEmpty(_trayNumberController.text)) {
_validateInputs();
} else {
Utils.showDialog(
title:
"Tên công nhân hoặc khây trồng đang cập nhật",
message:
"Bạn có muốn cập nhật?",
title: "Tên công nhân hoặc khây trồng đang cập nhật",
message: "Bạn có muốn cập nhật?",
textConfirm: "Tiếp tục",
textCancel: "Xem lại",
onConfirm: () {

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save