| @@ -3,6 +3,7 @@ class Device { | |||
| String name; | |||
| String status; | |||
| String location; | |||
| bool isSelected; | |||
| Device({this.id, this.name, this.status, this.location}); | |||
| @@ -18,6 +19,7 @@ class Device { | |||
| name = json['name']; | |||
| status = json['status']; | |||
| location = json['location']; | |||
| isSelected = false; | |||
| } | |||
| Map<String, dynamic> toJson() { | |||
| @@ -5,10 +5,12 @@ class SuppliesUsing { | |||
| String unit; | |||
| String howToUse; | |||
| int suppliesInWarehouseId; | |||
| int equipmentOfCustomerId; | |||
| int tbSuppliesInWarehouseId; | |||
| String supplyName; | |||
| String supplyUnit; | |||
| int tbEquipmentOfCustomerId; | |||
| int equipmentOfCustomerId; | |||
| String equipmentName; | |||
| SuppliesUsing( | |||
| {this.id, | |||
| @@ -17,7 +19,9 @@ class SuppliesUsing { | |||
| this.unit, | |||
| this.howToUse, | |||
| this.suppliesInWarehouseId, | |||
| this.tbEquipmentOfCustomerId, | |||
| this.equipmentOfCustomerId, | |||
| this.equipmentName, | |||
| this.tbSuppliesInWarehouseId, | |||
| this.supplyName, | |||
| this.supplyUnit}); | |||
| @@ -29,7 +33,9 @@ class SuppliesUsing { | |||
| unit = json['unit']; | |||
| howToUse = json['howToUse']; | |||
| suppliesInWarehouseId = json['suppliesInWarehouseId']; | |||
| tbEquipmentOfCustomerId = json['tbEquipmentOfCustomerId']; | |||
| equipmentOfCustomerId = json['equipmentOfCustomerId']; | |||
| equipmentName = json['equipmentName']; | |||
| tbSuppliesInWarehouseId = json['tbSuppliesInWarehouseId']; | |||
| supplyName = json['supplyName']; | |||
| supplyUnit = json['supplyUnit']; | |||
| @@ -43,7 +49,9 @@ class SuppliesUsing { | |||
| 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; | |||
| @@ -60,6 +60,9 @@ abstract class RestClient { | |||
| @GET("/api/tb-harvests") | |||
| Future<List<Harvest>> getHarvests({@DioOptions() Options options}); | |||
| @GET("/api/listDeviceForActivity") | |||
| Future<List<Device>> getDeviceForActivity({@DioOptions() Options options}); | |||
| //Crop | |||
| @GET( | |||
| "/api/tb-crops-detail-for-app/{cropId}?page={page}&size={size}&sort=executeDate,DESC") | |||
| @@ -262,6 +262,26 @@ class _RestClient implements RestClient { | |||
| return value; | |||
| } | |||
| @override | |||
| getDeviceForActivity({options}) async { | |||
| const _extra = <String, dynamic>{}; | |||
| final queryParameters = <String, dynamic>{}; | |||
| queryParameters.removeWhere((k, v) => v == null); | |||
| final _data = <String, dynamic>{}; | |||
| final newOptions = newRequestOptions(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(); | |||
| return value; | |||
| } | |||
| @override | |||
| getCropDetail(cropId, {page = 0, size = 20}) async { | |||
| ArgumentError.checkNotNull(cropId, 'cropId'); | |||
| @@ -85,6 +85,13 @@ class Repository { | |||
| return client.getSupplies(query: query, options: op); | |||
| } | |||
| Future<List<Device>> getDeviceForActivity() async { | |||
| final client = RestClient(dio); | |||
| var op = buildConfigurableCacheOptions( | |||
| forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache)); | |||
| return client.getDeviceForActivity(options: op); | |||
| } | |||
| Object getInstanceClass() { | |||
| var instanceClass; | |||
| if (1 == 1) { | |||
| @@ -0,0 +1,28 @@ | |||
| import 'package:farm_tpf/custom_model/Device.dart'; | |||
| import 'package:get/get.dart'; | |||
| class ChangeDevice extends GetxController { | |||
| Device currentDevice; | |||
| int selectedDeviceId; | |||
| String selectedDeviceName; | |||
| void initValue() { | |||
| currentDevice = Device(); | |||
| selectedDeviceName = ""; | |||
| selectedDeviceId = -1; | |||
| update(); | |||
| } | |||
| void change(Device device) { | |||
| currentDevice = device; | |||
| selectedDeviceId = device.id; | |||
| selectedDeviceName = device.name; | |||
| update(); | |||
| } | |||
| void changeByIdAndName(int id, String name) { | |||
| selectedDeviceId = id; | |||
| selectedDeviceName = name; | |||
| update(); | |||
| } | |||
| } | |||
| @@ -35,7 +35,9 @@ class ChangeSupplyUsing extends GetxController { | |||
| } | |||
| void editSupply(int index, SuppliesUsing supplyUsing) { | |||
| currentItems[index] = supplyUsing; | |||
| var newSup = supplyUsing; | |||
| newSup.id = currentItems[index].id; | |||
| currentItems[index] = newSup; | |||
| currentSupplyUsing = SuppliesUsing(); | |||
| update(); | |||
| } | |||
| @@ -82,6 +82,7 @@ class _EditActionDungScreenState extends State<EditActionDungScreen> { | |||
| suppliesUsing.forEach((sup) { | |||
| var newSup = sup; | |||
| newSup.suppliesInWarehouseId = sup.tbSuppliesInWarehouseId; | |||
| newSup.equipmentOfCustomerId = sup.tbEquipmentOfCustomerId; | |||
| newSups.add(newSup); | |||
| }); | |||
| _dung.suppliesUsing = newSups; | |||
| @@ -1,8 +1,11 @@ | |||
| import 'package:farm_tpf/custom_model/Device.dart'; | |||
| import 'package:farm_tpf/custom_model/SuppliesUsing.dart'; | |||
| import 'package:farm_tpf/custom_model/Supply.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/controller/ChangeDevice.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/controller/ChangeFormButton.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/controller/ChangeSupplyUsing.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/controller/ChangeUnit.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/resource_device_activity/sc_device_activity.dart'; | |||
| import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_supply.dart'; | |||
| import 'package:farm_tpf/presentation/screens/resources/sc_resource_helper.dart'; | |||
| import 'package:farm_tpf/utils/const_color.dart'; | |||
| @@ -32,11 +35,13 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| final changeSupplyUsing = Get.put(ChangeSupplyUsing()); | |||
| final changeUnit = Get.put(ChangeUnit()); | |||
| final changeButton = Get.put(ChangeButtonInForm()); | |||
| final changeSelectedDevice = Get.put(ChangeDevice()); | |||
| @override | |||
| void initState() { | |||
| super.initState(); | |||
| changeSelectedSupply.initValue(); | |||
| changeSelectedDevice.initValue(); | |||
| changeSupplyUsing.init(widget.currentItems); | |||
| changeUnit.initValue(); | |||
| changeButton.resetValue(); | |||
| @@ -49,7 +54,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| return Container(); | |||
| } else { | |||
| return Container( | |||
| height: 100, | |||
| height: 120, | |||
| child: ListView.builder( | |||
| physics: ClampingScrollPhysics(), | |||
| scrollDirection: Axis.horizontal, | |||
| @@ -67,6 +72,12 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| ..tbSuppliesName = editedSupplyUsing.supplyName | |||
| ..unit = editedSupplyUsing.supplyUnit; | |||
| changeSelectedSupply.change(editedSupply); | |||
| var editedDevice = Device() | |||
| ..id = editedSupplyUsing.tbEquipmentOfCustomerId | |||
| ..name = editedSupplyUsing.equipmentName; | |||
| changeSelectedDevice.change(editedDevice); | |||
| changeUnit | |||
| .updateListByUnitName(editedSupplyUsing.supplyUnit); | |||
| changeUnit.updateSelected(editedSupplyUsing.supplyUnit); | |||
| @@ -104,6 +115,9 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| Flexible( | |||
| child: Text( | |||
| "${value.currentItems[index].quantity.formatNumtoStringDecimal() ?? ""} ${value.currentItems[index].supplyUnit ?? ""}")), | |||
| Flexible( | |||
| child: Text( | |||
| "${value.currentItems[index].equipmentName ?? ""}")), | |||
| Flexible( | |||
| child: Text( | |||
| "${value.currentItems[index].howToUse ?? ""}")), | |||
| @@ -140,7 +154,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| .push(MaterialPageRoute( | |||
| builder: (_) => ResourceHelperScreen( | |||
| titleName: "Phân bón", | |||
| type: ConstCommon.supplyTypeDung, | |||
| type: ConstCommon.supplyTypeAll, | |||
| selectedId: changeSelectedSupply.selectedSupplyId), | |||
| fullscreenDialog: false)) | |||
| .then((value) { | |||
| @@ -175,6 +189,48 @@ 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), | |||
| onPressed: () { | |||
| Navigator.of(context) | |||
| .push(MaterialPageRoute( | |||
| builder: (_) => ListDeviceActivity( | |||
| selectedId: changeSelectedDevice.selectedDeviceId), | |||
| fullscreenDialog: false)) | |||
| .then((value) { | |||
| if (value != null) { | |||
| var result = value as Device; | |||
| changeSelectedDevice.change(result); | |||
| } | |||
| }); | |||
| }, | |||
| child: Container( | |||
| padding: EdgeInsets.only( | |||
| top: 0.0, right: 0.0, bottom: 10.5, left: 0.0), | |||
| decoration: 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( | |||
| Icons.arrow_drop_down, | |||
| color: Colors.grey, | |||
| ), | |||
| ], | |||
| ))); | |||
| }); | |||
| } | |||
| Widget _dropdownUnitTypes() { | |||
| return GetBuilder<ChangeUnit>(builder: (data) { | |||
| return DropdownButtonFormField<String>( | |||
| @@ -242,6 +298,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| borderRadius: new BorderRadius.circular(8.0)), | |||
| onPressed: () { | |||
| var currentSupply = changeSelectedSupply.currentSupply; | |||
| var currentDevice = changeSelectedDevice.currentDevice; | |||
| var currentQuantity = | |||
| _quantityController.text.parseDoubleThousand(); | |||
| if (currentSupply.id != null && currentQuantity > 0) { | |||
| @@ -258,6 +315,9 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| ..tbSuppliesInWarehouseId = currentSupply.id | |||
| ..suppliesInWarehouseId = currentSupply.id | |||
| ..supplyName = currentSupply.tbSuppliesName | |||
| ..tbEquipmentOfCustomerId = currentDevice.id | |||
| ..equipmentOfCustomerId = currentDevice.id | |||
| ..equipmentName = currentDevice.name | |||
| ..supplyUnit = currentSupply.unit | |||
| ..unit = currentSupply.unit; | |||
| changeSupplyUsing.editSupply( | |||
| @@ -276,6 +336,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| borderRadius: new BorderRadius.circular(8.0)), | |||
| onPressed: () { | |||
| var currentSupply = changeSelectedSupply.currentSupply; | |||
| var currentDevice = changeSelectedDevice.currentDevice; | |||
| var currentQuantity = | |||
| _quantityController.text.parseDoubleThousand(); | |||
| if (currentSupply.id != null && currentQuantity > 0) { | |||
| @@ -293,6 +354,9 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| ..suppliesInWarehouseId = currentSupply.id | |||
| ..supplyName = currentSupply.tbSuppliesName | |||
| ..supplyUnit = currentSupply.unit | |||
| ..tbEquipmentOfCustomerId = currentDevice.id | |||
| ..equipmentOfCustomerId = currentDevice.id | |||
| ..equipmentName = currentDevice.name | |||
| ..unit = currentSupply.unit; | |||
| changeSupplyUsing.addSupply(newSup); | |||
| _resetForm(); | |||
| @@ -355,6 +419,14 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| child: _dropdownUnitTypes(), | |||
| )), | |||
| ]), | |||
| Container( | |||
| width: double.infinity, | |||
| child: Text( | |||
| "Thiết bị", | |||
| style: TextStyle(color: Colors.black54, fontSize: 13.0), | |||
| ), | |||
| ), | |||
| _btnSelectDevice(), | |||
| TextFormField( | |||
| keyboardType: TextInputType.text, | |||
| controller: _howToUseController, | |||
| @@ -374,6 +446,7 @@ class _WidgetDungSupplyState extends State<WidgetDungSupply> { | |||
| _quantityController.text = ""; | |||
| changeUnit.initValue(); | |||
| changeSelectedSupply.initValue(); | |||
| changeSelectedDevice.initValue(); | |||
| } | |||
| _hidenKeyboard(BuildContext context) { | |||
| @@ -0,0 +1,50 @@ | |||
| import 'dart:async'; | |||
| import 'package:bloc/bloc.dart'; | |||
| import 'package:equatable/equatable.dart'; | |||
| import 'package:farm_tpf/custom_model/Device.dart'; | |||
| import 'package:farm_tpf/data/repository/repository.dart'; | |||
| import 'package:meta/meta.dart'; | |||
| part 'device_activity_event.dart'; | |||
| part 'device_activity_state.dart'; | |||
| class DeviceActivityBloc | |||
| extends Bloc<DeviceActivityEvent, DeviceActivityState> { | |||
| final Repository repository; | |||
| DeviceActivityBloc({@required this.repository}) | |||
| : super(DeviceActivityInitial()); | |||
| @override | |||
| Stream<DeviceActivityState> mapEventToState( | |||
| DeviceActivityEvent event, | |||
| ) async* { | |||
| if (event is DataFetched) { | |||
| try { | |||
| final response = await repository.getDeviceForActivity(); | |||
| List<Device> devices = response.map((device) { | |||
| if (device.id == event.selectedId) { | |||
| device.isSelected = true; | |||
| } | |||
| return device; | |||
| }).toList(); | |||
| yield DeviceActivitySuccess(items: devices); | |||
| } catch (_) { | |||
| yield DeviceActivityFailure(); | |||
| } | |||
| } else if (event is OnRefresh) { | |||
| try { | |||
| final response = await repository.getDeviceForActivity(); | |||
| List<Device> devices = response.map((device) { | |||
| if (device.id == event.selectedId) { | |||
| device.isSelected = true; | |||
| } | |||
| return device; | |||
| }).toList(); | |||
| yield DeviceActivitySuccess(items: devices); | |||
| } catch (_) { | |||
| yield DeviceActivityFailure(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| part of 'device_activity_bloc.dart'; | |||
| abstract class DeviceActivityEvent extends Equatable { | |||
| const DeviceActivityEvent(); | |||
| @override | |||
| List<Object> get props => []; | |||
| } | |||
| class DataFetched extends DeviceActivityEvent { | |||
| final int selectedId; | |||
| DataFetched({this.selectedId}); | |||
| } | |||
| class OnRefresh extends DeviceActivityEvent { | |||
| final int selectedId; | |||
| OnRefresh({this.selectedId}); | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| part of 'device_activity_bloc.dart'; | |||
| abstract class DeviceActivityState extends Equatable { | |||
| const DeviceActivityState(); | |||
| @override | |||
| List<Object> get props => []; | |||
| } | |||
| class DeviceActivityInitial extends DeviceActivityState {} | |||
| class DeviceActivityFailure extends DeviceActivityState {} | |||
| class DeviceActivitySuccess<T> extends DeviceActivityState { | |||
| final List<T> items; | |||
| const DeviceActivitySuccess({this.items}); | |||
| DeviceActivitySuccess copyWith({List<T> items}) { | |||
| return DeviceActivitySuccess(items: items ?? this.items); | |||
| } | |||
| @override | |||
| List<Object> get props => [items]; | |||
| } | |||
| @@ -0,0 +1,116 @@ | |||
| import 'package:farm_tpf/custom_model/Device.dart'; | |||
| import 'package:farm_tpf/data/repository/repository.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/bottom_loader.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart'; | |||
| import 'package:farm_tpf/utils/const_string.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'bloc/device_activity_bloc.dart'; | |||
| class ListDeviceActivity extends StatefulWidget { | |||
| final int selectedId; | |||
| ListDeviceActivity({@required this.selectedId}); | |||
| @override | |||
| _ListDeviceActivityState createState() => _ListDeviceActivityState(); | |||
| } | |||
| class _ListDeviceActivityState extends State<ListDeviceActivity> { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return BlocProvider( | |||
| create: (context) => DeviceActivityBloc(repository: Repository()) | |||
| ..add(DataFetched(selectedId: widget.selectedId)), | |||
| child: HoldInfinityWidget(selectedId: widget.selectedId), | |||
| ); | |||
| } | |||
| } | |||
| class HoldInfinityWidget extends StatelessWidget { | |||
| final int selectedId; | |||
| HoldInfinityWidget({@required this.selectedId}); | |||
| final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return Scaffold( | |||
| key: _scaffoldKey, | |||
| appBar: AppBar(title: Text("Chọn thiết bị")), | |||
| body: InfinityView(selectedId: selectedId)); | |||
| } | |||
| } | |||
| class InfinityView extends StatefulWidget { | |||
| final int selectedId; | |||
| InfinityView({@required this.selectedId}); | |||
| @override | |||
| _InfinityViewState createState() => _InfinityViewState(); | |||
| } | |||
| class _InfinityViewState extends State<InfinityView> { | |||
| DeviceActivityBloc _deviceActivityBloc; | |||
| @override | |||
| void initState() { | |||
| _deviceActivityBloc = BlocProvider.of<DeviceActivityBloc>(context); | |||
| _deviceActivityBloc.add(DataFetched(selectedId: widget.selectedId)); | |||
| super.initState(); | |||
| } | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return BlocBuilder<DeviceActivityBloc, DeviceActivityState>( | |||
| builder: (context, state) { | |||
| if (state is DeviceActivityFailure) { | |||
| return Center(child: Text(label_error_get_data)); | |||
| } | |||
| if (state is DeviceActivitySuccess) { | |||
| if (state.items.isEmpty) { | |||
| return Center(child: Text(label_list_empty)); | |||
| } | |||
| return RefreshIndicator( | |||
| child: ListView.builder( | |||
| itemBuilder: (BuildContext context, int index) { | |||
| return index >= state.items.length | |||
| ? BottomLoader() | |||
| : ItemInfinityWidget(item: state.items[index]); | |||
| }, | |||
| itemCount: state.items.length), | |||
| onRefresh: () async { | |||
| _deviceActivityBloc | |||
| .add(OnRefresh(selectedId: widget.selectedId)); | |||
| }); | |||
| } | |||
| return Center( | |||
| child: LoadingListPage(), | |||
| ); | |||
| }, | |||
| ); | |||
| } | |||
| @override | |||
| void dispose() { | |||
| super.dispose(); | |||
| } | |||
| } | |||
| class ItemInfinityWidget extends StatelessWidget { | |||
| final Device item; | |||
| const ItemInfinityWidget({Key key, @required this.item}) : super(key: key); | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return GestureDetector( | |||
| child: Card( | |||
| child: Material( | |||
| child: RadioListTile( | |||
| title: Text(item.name.toString()), | |||
| value: item, | |||
| groupValue: item.isSelected == false ? null : item, | |||
| onChanged: (Device value) { | |||
| Navigator.of(context).pop(value); | |||
| }), | |||
| )), | |||
| onTap: () {}); | |||
| } | |||
| } | |||
| @@ -2,7 +2,7 @@ name: farm_tpf | |||
| description: A new Flutter project. | |||
| publish_to: 'none' | |||
| version: 0.2.0+1 | |||
| version: 0.3.0+1 | |||
| environment: | |||
| sdk: ">=2.7.0 <3.0.0" | |||