| @@ -5,8 +5,9 @@ class RequestActivity { | |||
| String executeDate; | |||
| String externalTable; | |||
| String description; | |||
| List<TbObjectUpdateDTOList> tbObjectUpdateDTOList; | |||
| List<TbObjectUpdateDTO> tbObjectUpdateDTOList; | |||
| List<TbSuppliesUsingDetailsDTOs> tbSuppliesUsingDetailsDTOs; | |||
| List<TbNurseryDetailsDTO> tbNurseryDetailsDTOList; | |||
| RequestActivity( | |||
| {this.tbActivityTypeId, | |||
| @@ -16,7 +17,8 @@ class RequestActivity { | |||
| this.externalTable, | |||
| this.description, | |||
| this.tbObjectUpdateDTOList, | |||
| this.tbSuppliesUsingDetailsDTOs}); | |||
| this.tbSuppliesUsingDetailsDTOs, | |||
| this.tbNurseryDetailsDTOList}); | |||
| RequestActivity.fromJson(Map<String, dynamic> json) { | |||
| tbActivityTypeId = json['tbActivityTypeId']; | |||
| @@ -26,9 +28,9 @@ class RequestActivity { | |||
| externalTable = json['externalTable']; | |||
| description = json['description']; | |||
| if (json['tbObjectUpdateDTOList'] != null) { | |||
| tbObjectUpdateDTOList = new List<TbObjectUpdateDTOList>(); | |||
| tbObjectUpdateDTOList = new List<TbObjectUpdateDTO>(); | |||
| json['tbObjectUpdateDTOList'].forEach((v) { | |||
| tbObjectUpdateDTOList.add(new TbObjectUpdateDTOList.fromJson(v)); | |||
| tbObjectUpdateDTOList.add(new TbObjectUpdateDTO.fromJson(v)); | |||
| }); | |||
| } | |||
| if (json['tbSuppliesUsingDetailsDTOs'] != null) { | |||
| @@ -38,6 +40,12 @@ class RequestActivity { | |||
| .add(new TbSuppliesUsingDetailsDTOs.fromJson(v)); | |||
| }); | |||
| } | |||
| if (json['tbNurseryDetailsDTOList'] != null) { | |||
| tbNurseryDetailsDTOList = new List<TbNurseryDetailsDTO>(); | |||
| json['tbNurseryDetailsDTOList'].forEach((v) { | |||
| tbNurseryDetailsDTOList.add(new TbNurseryDetailsDTO.fromJson(v)); | |||
| }); | |||
| } | |||
| } | |||
| Map<String, dynamic> toJson() { | |||
| @@ -56,17 +64,21 @@ class RequestActivity { | |||
| data['tbSuppliesUsingDetailsDTOs'] = | |||
| this.tbSuppliesUsingDetailsDTOs.map((v) => v.toJson()).toList(); | |||
| } | |||
| if (this.tbNurseryDetailsDTOList != null) { | |||
| data['tbNurseryDetailsDTOList'] = | |||
| this.tbNurseryDetailsDTOList.map((v) => v.toJson()).toList(); | |||
| } | |||
| return data; | |||
| } | |||
| } | |||
| class TbObjectUpdateDTOList { | |||
| class TbObjectUpdateDTO { | |||
| int tbObjectParameterId; | |||
| String index; | |||
| TbObjectUpdateDTOList({this.tbObjectParameterId, this.index}); | |||
| TbObjectUpdateDTO({this.tbObjectParameterId, this.index}); | |||
| TbObjectUpdateDTOList.fromJson(Map<String, dynamic> json) { | |||
| TbObjectUpdateDTO.fromJson(Map<String, dynamic> json) { | |||
| tbObjectParameterId = json['tbObjectParameterId']; | |||
| index = json['index']; | |||
| } | |||
| @@ -111,3 +123,22 @@ class TbSuppliesUsingDetailsDTOs { | |||
| return data; | |||
| } | |||
| } | |||
| class TbNurseryDetailsDTO { | |||
| String workerName; | |||
| String trayNumber; | |||
| TbNurseryDetailsDTO({this.workerName, this.trayNumber}); | |||
| TbNurseryDetailsDTO.fromJson(Map<String, dynamic> json) { | |||
| workerName = json['workerName']; | |||
| trayNumber = json['trayNumber']; | |||
| } | |||
| Map<String, dynamic> toJson() { | |||
| final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
| data['workerName'] = this.workerName; | |||
| data['trayNumber'] = this.trayNumber; | |||
| return data; | |||
| } | |||
| } | |||
| @@ -245,4 +245,50 @@ class Repository { | |||
| .toList(); | |||
| return value; | |||
| } | |||
| Future<void> createActionCommon( | |||
| Function(dynamic) onSuccess, Function(dynamic) onError, | |||
| {@required String activityType, | |||
| @required String activityData, | |||
| List<String> filePaths}) async { | |||
| var formData = FormData(); | |||
| filePaths.forEach((f) { | |||
| formData.files.add(MapEntry('images', MultipartFile.fromFileSync(f))); | |||
| }); | |||
| formData.fields.add(MapEntry('tbCommonActivityDTO', activityData)); | |||
| try { | |||
| await dio | |||
| .post( | |||
| "${ConstCommon.baseUrl}/api/create-common-activity/$activityType", | |||
| data: formData) | |||
| .then((value) { | |||
| onSuccess(value.data); | |||
| }); | |||
| } on DioError catch (e) { | |||
| onError(e); | |||
| } | |||
| } | |||
| Future<void> updateActionCommon( | |||
| Function(dynamic) onSuccess, Function(dynamic) onError, | |||
| {String activityType, | |||
| String activityAction, | |||
| List<String> filePaths}) async { | |||
| var formData = FormData(); | |||
| filePaths.forEach((f) { | |||
| formData.files.add(MapEntry('images', MultipartFile.fromFileSync(f))); | |||
| }); | |||
| formData.fields.add(MapEntry('tbCommonActivityDTO', activityAction)); | |||
| try { | |||
| await dio | |||
| .put( | |||
| "${ConstCommon.baseUrl}/api/update-common-activity/$activityType", | |||
| data: formData) | |||
| .then((value) { | |||
| onSuccess(value.data); | |||
| }); | |||
| } on DioError catch (e) { | |||
| onError(e); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,13 +1,13 @@ | |||
| import 'package:farm_tpf/custom_model/NurseryDetail.dart'; | |||
| import 'package:farm_tpf/custom_model/action_form/RequestActivity.dart'; | |||
| import 'package:get/get_state_manager/get_state_manager.dart'; | |||
| class ChangeWorker extends GetxController { | |||
| List<NurseryDetail> currentItems; | |||
| NurseryDetail currentItem; | |||
| List<TbNurseryDetailsDTO> currentItems; | |||
| TbNurseryDetailsDTO currentItem; | |||
| int currentIndex; | |||
| void init(List<NurseryDetail> initItems) { | |||
| void init(List<TbNurseryDetailsDTO> initItems) { | |||
| currentItems = initItems ?? []; | |||
| currentItem = NurseryDetail(); | |||
| currentItem = TbNurseryDetailsDTO(); | |||
| currentIndex = -1; | |||
| update(); | |||
| } | |||
| @@ -17,28 +17,20 @@ class ChangeWorker extends GetxController { | |||
| update(); | |||
| } | |||
| void changeInitList(List<NurseryDetail> initListWorkers) { | |||
| void changeInitList(List<TbNurseryDetailsDTO> initListWorkers) { | |||
| currentItems = initListWorkers; | |||
| update(); | |||
| } | |||
| void addSupply(NurseryDetail nurseryDetail) { | |||
| void addNurseryDetail(TbNurseryDetailsDTO nurseryDetail) { | |||
| currentItems.insert(0, nurseryDetail); | |||
| currentItem = NurseryDetail(); | |||
| currentItem = TbNurseryDetailsDTO(); | |||
| update(); | |||
| } | |||
| void deleteSupply(int index) { | |||
| void deleteNurseryDetail(int index) { | |||
| currentItems.removeAt(index); | |||
| currentItem = NurseryDetail(); | |||
| update(); | |||
| } | |||
| void editSupply(int index, NurseryDetail supplyUsing) { | |||
| var newSup = supplyUsing; | |||
| newSup.id = currentItems[index].id; | |||
| currentItems[index] = newSup; | |||
| currentItem = NurseryDetail(); | |||
| currentItem = TbNurseryDetailsDTO(); | |||
| update(); | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| import 'package:farm_tpf/custom_model/NurseryDetail.dart'; | |||
| import 'package:farm_tpf/custom_model/action_form/RequestActivity.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/controller/ChangeWorker.dart'; | |||
| import 'package:farm_tpf/utils/const_string.dart'; | |||
| @@ -8,6 +8,9 @@ import 'package:get/get.dart'; | |||
| import 'package:get/get_state_manager/get_state_manager.dart'; | |||
| class WidgetWorker extends StatefulWidget { | |||
| final Function(List<TbNurseryDetailsDTO>) onChangeWorkers; | |||
| const WidgetWorker({@required this.onChangeWorkers}); | |||
| @override | |||
| _WidgetWorkerState createState() => _WidgetWorkerState(); | |||
| } | |||
| @@ -26,6 +29,7 @@ class _WidgetWorkerState extends State<WidgetWorker> { | |||
| Widget _buildListWorker() { | |||
| return GetBuilder<ChangeWorker>(builder: (data) { | |||
| widget.onChangeWorkers(data.currentItems); | |||
| if (data.currentItems.length == 0) { | |||
| return Container(); | |||
| } else { | |||
| @@ -85,7 +89,7 @@ class _WidgetWorkerState extends State<WidgetWorker> { | |||
| color: Colors.redAccent, | |||
| ), | |||
| onPressed: () { | |||
| controller.deleteSupply(index); | |||
| controller.deleteNurseryDetail(index); | |||
| print("Delete worker"); | |||
| }), | |||
| ) | |||
| @@ -160,10 +164,11 @@ class _WidgetWorkerState extends State<WidgetWorker> { | |||
| _formWorkerKey.currentState.save(); | |||
| if (Validators.stringNotNullOrEmpty( | |||
| _workerNameController.text)) { | |||
| NurseryDetail _nurseryDetail = NurseryDetail() | |||
| ..workerName = _workerNameController.text | |||
| ..trayNumber = _trayNumberController.text; | |||
| controller.addSupply(_nurseryDetail); | |||
| TbNurseryDetailsDTO _nurseryDetail = | |||
| TbNurseryDetailsDTO() | |||
| ..workerName = _workerNameController.text | |||
| ..trayNumber = _trayNumberController.text; | |||
| controller.addNurseryDetail(_nurseryDetail); | |||
| _workerNameController.clear(); | |||
| _trayNumberController.clear(); | |||
| } else { | |||
| @@ -1,5 +1,10 @@ | |||
| import 'dart:convert'; | |||
| import 'package:farm_tpf/custom_model/NurseryDetail.dart'; | |||
| import 'package:farm_tpf/custom_model/action_form/ActionUIField.dart'; | |||
| import 'package:farm_tpf/custom_model/action_form/ActionUIForm.dart'; | |||
| import 'package:farm_tpf/custom_model/action_form/RequestActivity.dart'; | |||
| import 'package:farm_tpf/data/api/app_exception.dart'; | |||
| import 'package:farm_tpf/data/repository/repository.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart'; | |||
| @@ -11,13 +16,16 @@ import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_area.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/cubit/action_ui_cubit.dart'; | |||
| import 'package:farm_tpf/utils/const_string.dart'; | |||
| import 'package:farm_tpf/utils/pref.dart'; | |||
| import 'package:farm_tpf/utils/validators.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:get/get.dart'; | |||
| import 'package:keyboard_dismisser/keyboard_dismisser.dart'; | |||
| import 'package:farm_tpf/utils/formatter.dart'; | |||
| import 'dung/widget_dung_supply.dart'; | |||
| import 'nursery/widget_worker.dart'; | |||
| @@ -26,11 +34,13 @@ import 'spraying/widget_spraying_supply.dart'; | |||
| import 'state_management_helper/change_file_controller.dart'; | |||
| class ActionScreen extends StatefulWidget { | |||
| final int cropId; | |||
| final int idAction; | |||
| final String activityType; | |||
| final String title; | |||
| ActionScreen( | |||
| {@required this.idAction, | |||
| {@required this.cropId, | |||
| @required this.idAction, | |||
| @required this.title, | |||
| @required this.activityType}); | |||
| @@ -44,9 +54,15 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| var pref = LocalPref(); | |||
| final _executeByController = TextEditingController(); | |||
| DateTime executeTime = DateTime.now(); | |||
| List<String> filePaths = List<String>(); | |||
| List<String> filePaths = <String>[]; | |||
| var changeFileController = Get.put(ChangeFileController()); | |||
| Map<String, TextEditingController> textFieldControllers = {}; | |||
| Map<String, String> valueObjects = {}; | |||
| var _requestActivity = RequestActivity(); | |||
| final _repository = Repository(); | |||
| var _actionUIForm = ActionUIForm(); | |||
| var _nurseryDetails = <TbNurseryDetailsDTO>[]; | |||
| Future<Null> getSharedPrefs() async { | |||
| var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME); | |||
| @@ -57,21 +73,59 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| void initState() { | |||
| super.initState(); | |||
| getSharedPrefs(); | |||
| changeFileController.initValue(); | |||
| } | |||
| _validateInputs() async { | |||
| if (_formKey.currentState.validate()) { | |||
| _formKey.currentState.save(); | |||
| LoadingDialog.showLoadingDialog(context); | |||
| filePaths = Get.find<ChangeFileController>().newFiles; | |||
| //Create request general model | |||
| try { | |||
| LoadingDialog.hideLoadingDialog(context); | |||
| //ADD NEW | |||
| //Update | |||
| LoadingDialog.showLoadingDialog(context); | |||
| filePaths = Get.find<ChangeFileController>().newFiles; | |||
| //Create request general model | |||
| _requestActivity | |||
| ..tbActivityTypeId = widget.idAction | |||
| ..tbCropId = widget.cropId | |||
| ..externalTable = | |||
| _actionUIForm?.activityExtendTypeDTOList?.first?.externalTable ?? | |||
| ''; | |||
| filePaths = Get.find<ChangeFileController>().newFiles; | |||
| textFieldControllers.forEach((key, value) { | |||
| print(textFieldControllers[key].text); | |||
| valueObjects[key] = textFieldControllers[key].text; | |||
| }); | |||
| //tbObjectUpdateDTOList | |||
| var _objectPrameters = <TbObjectUpdateDTO>[]; | |||
| valueObjects.forEach((key, value) { | |||
| var objectUpdate = TbObjectUpdateDTO() | |||
| ..tbObjectParameterId = int.tryParse(key) | |||
| ..index = value; | |||
| _objectPrameters.add(objectUpdate); | |||
| }); | |||
| _requestActivity.tbObjectUpdateDTOList = _objectPrameters; | |||
| //CHECK NURSERY | |||
| if (widget.activityType == 'ACTIVE_TYPE_NURSERY') { | |||
| _requestActivity.tbNurseryDetailsDTOList = _nurseryDetails; | |||
| } | |||
| //convert data to json | |||
| var activityCommonData = | |||
| jsonEncode(_requestActivity.toJson()).toString(); | |||
| print(activityCommonData); | |||
| _repository.createActionCommon((data) { | |||
| LoadingDialog.hideLoadingDialog(context); | |||
| Get.back(result: 'ok'); | |||
| Utils.showSnackBarSuccess(message: label_add_success); | |||
| }, (error) { | |||
| LoadingDialog.hideLoadingDialog(context); | |||
| Utils.showSnackBarError(message: AppException.handleError(error)); | |||
| }, | |||
| activityType: widget.activityType, | |||
| activityData: activityCommonData, | |||
| filePaths: filePaths); | |||
| //ADD NEW | |||
| //Update | |||
| } catch (e) { | |||
| LoadingDialog.hideLoadingDialog(context); | |||
| print(e.toString()); | |||
| @@ -85,7 +139,8 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| return WidgetFieldDateTimePicker( | |||
| initDateTime: executeTime, | |||
| onUpdateDateTime: (selectedDate) { | |||
| // | |||
| _requestActivity.executeDate = | |||
| selectedDate.convertLocalDateTimeToStringUtcDateTime(); | |||
| }); | |||
| } | |||
| @@ -158,7 +213,9 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| condition: field.tbActivityExtendTypeCondition, | |||
| invalidMessage: '', | |||
| onPressed: (commonData) { | |||
| print(commonData.name); | |||
| valueObjects[field.id.toString()] = | |||
| commonData.id.toString(); | |||
| print(valueObjects[field.id.toString()]); | |||
| }); | |||
| } else if (field.tbControlTypeName == 'date') { | |||
| return FieldDateWidget( | |||
| @@ -198,7 +255,9 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| Widget generateSupply(String activityType) { | |||
| switch (activityType) { | |||
| case 'ACTIVE_TYPE_NURSERY': | |||
| return WidgetWorker(); | |||
| return WidgetWorker(onChangeWorkers: (nurseryDetails) { | |||
| _nurseryDetails = nurseryDetails; | |||
| }); | |||
| break; | |||
| case 'ACTIVE_TYPE_PLANTING': | |||
| return Column( | |||
| @@ -291,14 +350,22 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| print('loading...'); | |||
| return Center(child: CircularProgressIndicator()); | |||
| } else if (state is ActionUiSuccess) { | |||
| var actionUiForm = state.item as ActionUIForm; | |||
| actionUiForm.objectParameterDTOList | |||
| _actionUIForm = state.item as ActionUIForm; | |||
| _actionUIForm.objectParameterDTOList | |||
| .forEach((element) { | |||
| var textEditingController = | |||
| new TextEditingController(); | |||
| textFieldControllers.putIfAbsent( | |||
| element.id.toString(), | |||
| () => textEditingController); | |||
| //generate controller | |||
| if (element.tbControlTypeName == 'text' || | |||
| element.tbControlTypeName == 'number' || | |||
| element.tbControlTypeName == 'textarea') { | |||
| var textEditingController = | |||
| new TextEditingController(); | |||
| textFieldControllers.putIfAbsent( | |||
| element.id.toString(), | |||
| () => textEditingController); | |||
| } | |||
| // generate value each parameter | |||
| valueObjects.putIfAbsent( | |||
| element.id.toString(), () => ''); | |||
| }); | |||
| return Column( | |||
| children: [ | |||
| @@ -319,7 +386,7 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| SizedBox( | |||
| height: 8.0, | |||
| ), | |||
| generateTextField(actionUiForm | |||
| generateTextField(_actionUIForm | |||
| .objectParameterDTOList), | |||
| _executeByField(), | |||
| SizedBox( | |||
| @@ -379,6 +446,9 @@ class _ActionScreenState extends State<ActionScreen> { | |||
| @override | |||
| void dispose() { | |||
| _executeByController.dispose(); | |||
| textFieldControllers.forEach((key, value) { | |||
| textFieldControllers[key].dispose(); | |||
| }); | |||
| super.dispose(); | |||
| } | |||
| } | |||
| @@ -11,9 +11,9 @@ import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:get/get.dart'; | |||
| class PlotActionScreen extends StatefulWidget { | |||
| int cropId; | |||
| String cropCode; | |||
| int cropType; | |||
| final int cropId; | |||
| final String cropCode; | |||
| final int cropType; | |||
| PlotActionScreen({this.cropId, this.cropCode, this.cropType}); | |||
| @override | |||
| _PlotActionScreenState createState() => _PlotActionScreenState(); | |||
| @@ -21,7 +21,7 @@ class PlotActionScreen extends StatefulWidget { | |||
| class _PlotActionScreenState extends State<PlotActionScreen> | |||
| with AutomaticKeepAliveClientMixin { | |||
| List<ActionType> actions = new List<ActionType>(); | |||
| List<ActionType> actions = <ActionType>[]; | |||
| @override | |||
| void initState() { | |||
| @@ -112,10 +112,10 @@ class _PlotActionScreenState extends State<PlotActionScreen> | |||
| return GestureDetector( | |||
| onTap: () { | |||
| Get.to(ActionScreen( | |||
| idAction: actionType.id, | |||
| title: actionType.description, | |||
| activityType: actionType.name, | |||
| )); | |||
| cropId: widget.cropId, | |||
| idAction: actionType.id, | |||
| title: actionType.description, | |||
| activityType: actionType.name)); | |||
| }, | |||
| child: Container( | |||
| margin: EdgeInsets.all(8), | |||