You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

613 lines
20KB

  1. import 'package:dio/dio.dart';
  2. import 'package:dio_http_cache/dio_http_cache.dart';
  3. import 'package:farm_tpf/custom_model/ActionType.dart';
  4. import 'package:farm_tpf/custom_model/CropPlot.dart';
  5. import 'package:farm_tpf/custom_model/Device.dart';
  6. import 'package:farm_tpf/custom_model/EnvironmentParameter.dart';
  7. import 'package:farm_tpf/custom_model/Harvest.dart';
  8. import 'package:farm_tpf/custom_model/LocationUnit.dart';
  9. import 'package:farm_tpf/custom_model/NotificationObjectDTO.dart';
  10. import 'package:farm_tpf/custom_model/Supply.dart';
  11. import 'package:farm_tpf/custom_model/TbCropDTO.dart';
  12. import 'package:farm_tpf/custom_model/UpdateNoti.dart';
  13. import 'package:farm_tpf/custom_model/WaterType.dart';
  14. import 'package:farm_tpf/custom_model/action_form/ActionUIForm.dart';
  15. import 'package:farm_tpf/custom_model/action_form/CommonData.dart';
  16. import 'package:farm_tpf/custom_model/action_form/RequestActivity.dart';
  17. import 'package:farm_tpf/custom_model/user.dart';
  18. import 'package:farm_tpf/custom_model/user_request.dart';
  19. import 'package:farm_tpf/data/api/dio_provider.dart';
  20. import 'package:farm_tpf/data/api/rest_client.dart';
  21. import 'package:farm_tpf/models/PagedResult.dart';
  22. import 'package:farm_tpf/presentation/screens/codes/models/activity_request.dart';
  23. import 'package:farm_tpf/presentation/screens/codes/models/activity_type.dart';
  24. import 'package:farm_tpf/presentation/screens/codes/models/stamp.dart';
  25. import 'package:farm_tpf/presentation/screens/codes/models/stamp_filter_request.dart';
  26. import 'package:farm_tpf/presentation/screens/codes/models/stamp_request.dart';
  27. import 'package:farm_tpf/presentation/screens/codes/models/stamp_timeline.dart';
  28. import 'package:farm_tpf/presentation/screens/plot/models/crop_filter_request.dart';
  29. import 'package:farm_tpf/presentation/screens/task/models/employee.dart';
  30. import 'package:farm_tpf/presentation/screens/task/models/supply_filter.dart';
  31. import 'package:farm_tpf/presentation/screens/task/models/task_request.dart';
  32. import 'package:farm_tpf/utils/const_common.dart';
  33. import 'package:flutter/foundation.dart';
  34. import 'package:flutter/material.dart';
  35. import '../../presentation/screens/codes/models/stamp_type.dart';
  36. import '../../presentation/screens/login/models/request_user.dart';
  37. import '../../presentation/screens/login/models/response_user.dart';
  38. import '../../presentation/screens/plot/models/area_filter.request.dart';
  39. import '../../presentation/screens/task/models/task.dart';
  40. import '../../presentation/screens/task/models/task_filter_request.dart';
  41. import '../../presentation/screens/task/models/task_update_request.dart';
  42. import '../api/app_exception.dart';
  43. class Repository {
  44. final dio = DioProvider();
  45. Future<void> login(
  46. Function(ResponseUser) onSuccess,
  47. Function(String) onError, {
  48. required RequestUser requestUser,
  49. }) async {
  50. try {
  51. var url = ConstCommon.baseUrl + '/api/authenticate';
  52. await dio.post(
  53. url,
  54. data: {
  55. 'username': requestUser.username ?? '',
  56. 'password': requestUser.password ?? '',
  57. },
  58. ).then(
  59. (value) {
  60. var res = ResponseUser.fromJson(value.data);
  61. onSuccess(res);
  62. },
  63. ).catchError((error) {
  64. var dioError = error as DioError;
  65. var message = dioError.response?.data['Error'];
  66. onError(message);
  67. });
  68. } catch (e) {
  69. onError('Đã có lỗi xảy ra');
  70. }
  71. }
  72. Future<List<ActionType>> getActionTypes() {
  73. final client = RestClient(dio);
  74. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  75. return client.getActionTypes(options: op);
  76. }
  77. Future<List<Harvest>> getHarvests() {
  78. final client = RestClient(dio);
  79. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  80. return client.getHarvests(options: op);
  81. }
  82. Future<List<WaterType>> getWaterTypes() {
  83. final client = RestClient(dio);
  84. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  85. return client.getWaterTypes(options: op);
  86. }
  87. Future<CropPlot> getPlotDetail(int cropId, {int page = 0, int size = 20}) {
  88. final client = RestClient(dio);
  89. return client.getCropDetail(cropId, page: page, size: size);
  90. }
  91. Future<CropPlot> getPlotDetailByCode(String cropCode) {
  92. final client = RestClient(dio);
  93. return client.getCropDetailByCode(cropCode);
  94. }
  95. Future<List<TbCropDTO>> getPlots({int page = 0, int size = 20, String searchString = ''}) {
  96. final client = RestClient(dio);
  97. return client.getPlots(page: page, size: size, query: searchString);
  98. }
  99. Future<void> updatePlot(TbCropDTO tbCropDTO) {
  100. final client = RestClient(dio);
  101. return client.updateCrop(tbCropDTO);
  102. }
  103. Future<User> signInWithCredentials(String username, String password) {
  104. final client = RestClient(dio);
  105. return client.login(UserRequest(username: username, password: password));
  106. }
  107. Future<PagedResult<T>> getInfinityList<T>(String url, {int page = 0, int size = 20}) async {
  108. var initUrl = "/api/activities/latest-env-by-activity-type/1/2";
  109. var url = ConstCommon.baseUrl + initUrl + "?page=$page&paged=true&size=$size";
  110. var response = await dio.get(url);
  111. final value = PagedResult<T>.fromJson(response.data, getInstanceClass());
  112. return value;
  113. }
  114. Future<List<Supply>> getSupplies(String urlSupply, {String query = ""}) async {
  115. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  116. try {
  117. final result = await dio.get("${ConstCommon.baseUrl}$urlSupply?q=$query", options: op);
  118. final data = result.data;
  119. if (data is List) {
  120. return data.map((i) => Supply.fromJson(i as Map<String, dynamic>)).toList();
  121. } else {
  122. return [];
  123. }
  124. } on DioError catch (e) {
  125. return [];
  126. }
  127. }
  128. Future<List<Device>> getDeviceForActivity() async {
  129. final client = RestClient(dio);
  130. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  131. return client.getDeviceForActivity(options: op);
  132. }
  133. Future<void> updateAllNotification(String status) {
  134. final client = RestClient(dio);
  135. return client.updateAllNotification(status);
  136. }
  137. Future<void> updateNoti(UpdateNoti updateNoti) {
  138. final client = RestClient(dio);
  139. return client.updateNoti(updateNoti);
  140. }
  141. Future<NotificationObjectDTO> getNotifications({int page = 0, int size = 20}) async {
  142. var url = ConstCommon.baseUrl + "/api/notifications-current-user?page=$page&size=$size&sort=sendDate,DESC";
  143. var response = await dio.get(url);
  144. final value = NotificationObjectDTO.fromJson(response.data);
  145. return value;
  146. }
  147. Future<List<LocationUnit>> getLocationUnits(
  148. {required LocationType locationType, int filterId = -1, int page = 0, int size = 500, String query = ''}) {
  149. final client = RestClient(dio);
  150. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  151. var response;
  152. switch (locationType) {
  153. case LocationType.province:
  154. response = client.getProvinces(filterId, options: op, page: page, size: size, query: query);
  155. break;
  156. case LocationType.district:
  157. response = client.getDistricts(filterId, options: op, page: page, size: size, query: query);
  158. break;
  159. case LocationType.ward:
  160. response = client.getWards(filterId, options: op, page: page, size: size, query: query);
  161. break;
  162. default:
  163. response = client.getCountries(query: query);
  164. }
  165. return response;
  166. }
  167. Object getInstanceClass() {
  168. var instanceClass;
  169. if (1 == 1) {
  170. instanceClass = new TbCropDTO();
  171. }
  172. return instanceClass;
  173. }
  174. //Action
  175. Future<void> createAction(Function(dynamic) onSuccess, Function(dynamic) onError,
  176. {String? apiAddAction, String? paramActivity, String? activityAction, List<String>? filePaths}) async {
  177. var formData = FormData();
  178. filePaths?.forEach((f) {
  179. formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
  180. });
  181. formData.fields.add(MapEntry(paramActivity ?? '', activityAction ?? ''));
  182. try {
  183. await dio.post("${ConstCommon.baseUrl}/$apiAddAction", data: formData).then((value) {
  184. onSuccess(value.data);
  185. });
  186. } on DioError catch (e) {
  187. onError(e);
  188. }
  189. }
  190. Future<void> updateAction(Function(dynamic) onSuccess, Function(dynamic) onError,
  191. {String? apiUpdateAction, String? paramActivity, String? activityAction, List<String>? filePaths}) async {
  192. var formData = FormData();
  193. if (filePaths != null) {
  194. filePaths.forEach((f) {
  195. formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
  196. });
  197. }
  198. formData.fields.add(MapEntry(paramActivity ?? '', activityAction ?? ''));
  199. try {
  200. await dio.post("${ConstCommon.baseUrl}/$apiUpdateAction", data: formData).then((value) {
  201. onSuccess(value.data);
  202. });
  203. } on DioError catch (e) {
  204. onError(e);
  205. }
  206. }
  207. //Device
  208. Future<List<Device>> getDevices(String query) {
  209. final client = RestClient(dio);
  210. return client.getDevices(query);
  211. }
  212. //Environment Parameter
  213. Future<List<EnvironmentParameter>> getEnvironmentParameters({required int cropId, int page = 0, int size = 20}) {
  214. final client = RestClient(dio);
  215. return client.getEnvironmentParameters(cropId, page: page, size: size);
  216. }
  217. //NEW IMPLEMENT
  218. Future<void> allActionTypes(int cropTypeId, Function(List<ActionType>) onSuccess, Function(dynamic) onError) async {
  219. try {
  220. var url = '${ConstCommon.baseUrl}/api/listActivityTypesCulture/$cropTypeId';
  221. final Response<List<dynamic>> _result = await dio.get(url);
  222. var value = _result.data?.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>)).toList();
  223. onSuccess(value ?? []);
  224. } on DioError catch (e) {
  225. onError(e);
  226. }
  227. }
  228. Future<ActionUIForm> getActionUIForm({required int idAction}) {
  229. final client = RestClient(dio);
  230. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  231. return client.getActionUIForm(idAction, op);
  232. }
  233. Future<List<CommonData>> getCommonData({required String tableSupply, required String condition}) async {
  234. var url = '${ConstCommon.baseUrl}/api/get-data-from-table-common?tableName=$tableSupply&condition=$condition';
  235. final Response<List<dynamic>> _result = await dio.get(url);
  236. var value = _result.data?.map((dynamic i) => CommonData.fromJson(i as Map<String, dynamic>)).toList();
  237. return value ?? [];
  238. }
  239. Future<void> createActionCommon(Function(dynamic) onSuccess, Function(dynamic) onError,
  240. {required String activityData, List<String>? filePaths}) async {
  241. var formData = FormData();
  242. if (filePaths != null) {
  243. filePaths.forEach((f) {
  244. formData.files.add(MapEntry('images', MultipartFile.fromFileSync(f)));
  245. });
  246. }
  247. formData.fields.add(MapEntry('tbCommonActivityDTO', activityData));
  248. try {
  249. await dio.post("${ConstCommon.baseUrl}/api/create-common-activity", data: formData).then((value) {
  250. onSuccess(value.data);
  251. });
  252. } on DioError catch (e) {
  253. onError(e);
  254. }
  255. }
  256. Future<void> updateActionCommon(Function(dynamic) onSuccess, Function(dynamic) onError,
  257. {required String activityData, List<String>? filePaths}) async {
  258. var formData = FormData();
  259. if (filePaths != null) {
  260. filePaths.forEach((f) {
  261. formData.files.add(MapEntry('images', MultipartFile.fromFileSync(f)));
  262. });
  263. }
  264. formData.fields.add(MapEntry('tbCommonActivityDTO', activityData));
  265. try {
  266. await dio.post("${ConstCommon.baseUrl}/api/update-common-activity", data: formData).then((value) {
  267. onSuccess(value.data);
  268. });
  269. } on DioError catch (e) {
  270. onError(e);
  271. }
  272. }
  273. Future<RequestActivity> detailCommonAction({required int activityId}) async {
  274. final client = RestClient(dio);
  275. return client.getDetailActivityCommon(activityId);
  276. }
  277. // Stamp
  278. Future<List<Stamp>> stamps({
  279. int page = 0,
  280. int size = 20,
  281. required StampFilterRequest filter,
  282. }) async {
  283. try {
  284. var url = '${ConstCommon.baseUrl}/api/tb-codes/list?page=$page&size=$size&sort=createdDate,${filter.sort ?? 'asc'}';
  285. var res = await dio.post(url, data: {
  286. 'status': filter.status,
  287. 'description': filter.description,
  288. });
  289. return (res.data as List).map((e) => Stamp.fromJson(e)).toList();
  290. } catch (e) {
  291. rethrow;
  292. }
  293. }
  294. Future<List<StampType>> stampTypes() async {
  295. try {
  296. var url = '${ConstCommon.baseUrl}/api/tb-example-stamp/dropdown-list';
  297. var res = await dio.get(
  298. url,
  299. );
  300. return (res.data as List).map((e) => StampType.fromJson(e)).toList();
  301. } catch (e) {
  302. rethrow;
  303. }
  304. }
  305. Future<void> createStamp(
  306. Function(dynamic) onSuccess,
  307. Function(String) onError, {
  308. required RequestStamp item,
  309. }) async {
  310. try {
  311. var url = '${ConstCommon.baseUrl}/api/tb-codes';
  312. await dio.post(url, data: item).then(
  313. (value) {
  314. onSuccess(value);
  315. },
  316. ).catchError((e) {
  317. onError(AppException.handleError(e));
  318. });
  319. } catch (e) {
  320. onError(AppException.handleError(e));
  321. }
  322. }
  323. Future<List<ActivityType>> activityTypes() async {
  324. try {
  325. var url = '${ConstCommon.baseUrl}/api/tb-activity-types-dropdown-list-after-harvest';
  326. var res = await dio.get(
  327. url,
  328. );
  329. return (res.data as List).map((e) => ActivityType.fromJson(e)).toList();
  330. } catch (e) {
  331. rethrow;
  332. }
  333. }
  334. Future<void> updateActivity(
  335. Function(dynamic) onSuccess,
  336. Function(String) onError, {
  337. required ActivityRequest item,
  338. }) async {
  339. try {
  340. var url = '${ConstCommon.baseUrl}/api/tb-codes/create/activity';
  341. var formData = FormData();
  342. formData.fields.add(MapEntry('code', item.code ?? ''));
  343. formData.fields.add(MapEntry('activityTypeId', item.activityTypeId?.toString() ?? ''));
  344. formData.fields.add(MapEntry('executeDate', item.executeDate ?? ''));
  345. formData.fields.add(MapEntry('description', item.description ?? ''));
  346. formData.fields.add(MapEntry('location', item.location ?? ''));
  347. await dio.post(url, data: formData).then(
  348. (value) {
  349. onSuccess(value);
  350. },
  351. ).catchError((e) {
  352. onError(AppException.handleError(e));
  353. });
  354. } catch (e) {
  355. onError(AppException.handleError(e));
  356. }
  357. }
  358. Future<Stamp> getStampDetail({required int id}) async {
  359. try {
  360. var url = '${ConstCommon.baseUrl}/api/tb-codes/$id';
  361. var res = await dio.get(url);
  362. return Stamp.fromJson(res.data);
  363. } catch (e) {
  364. rethrow;
  365. }
  366. }
  367. Future<Stamp> getStampDetailByCode({required String code}) async {
  368. try {
  369. var url = '${ConstCommon.baseUrl}/api/tb-codes-scan-qrCode/$code';
  370. var res = await dio.get(url);
  371. return Stamp.fromJson(res.data);
  372. } catch (e) {
  373. rethrow;
  374. }
  375. }
  376. Future<StampTimeline> getStampTimeline({required int stampId}) async {
  377. try {
  378. var url = '${ConstCommon.baseUrl}/api/tb-codes-timeline/$stampId';
  379. var res = await dio.get(url);
  380. return StampTimeline.fromJson(res.data);
  381. } catch (e) {
  382. rethrow;
  383. }
  384. }
  385. Future<void> updateStampStatus(
  386. Function(dynamic) onSuccess,
  387. Function(String) onError, {
  388. required int stampId,
  389. required String status,
  390. }) async {
  391. try {
  392. var url = '${ConstCommon.baseUrl}/api/tb-codes/update/$stampId/status/$status';
  393. await dio.put(url).then(
  394. (value) {
  395. onSuccess(value);
  396. },
  397. ).catchError((e) {
  398. onError(AppException.handleError(e));
  399. });
  400. } catch (e) {
  401. onError(AppException.handleError(e));
  402. }
  403. }
  404. Future<List<TbCropDTO>> getPlotsWithoutPaging() async {
  405. try {
  406. var url = '${ConstCommon.baseUrl}/api/_search/tb-crops';
  407. var res = await dio.get(
  408. url,
  409. );
  410. return (res.data as List).map((e) => TbCropDTO.fromJson(e)).toList();
  411. } catch (e) {
  412. rethrow;
  413. }
  414. }
  415. // Task
  416. Future<List<Task>> tasks({
  417. int page = 0,
  418. int size = 20,
  419. required TaskFilterRequest filter,
  420. }) async {
  421. try {
  422. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists/list?page=$page&size=$size&sort=deadline,${filter.sort ?? 'asc'}';
  423. var status = <bool>[];
  424. if (filter.status != null) {
  425. status = filter.status!.map((e) {
  426. if (e == describeEnum(TaskStatus.completed)) {
  427. return true;
  428. } else {
  429. return false;
  430. }
  431. }).toList();
  432. }
  433. var res = await dio.post(url, data: {
  434. 'completed': status,
  435. "crop_id": filter.cropId,
  436. });
  437. return (res.data as List).map((e) => Task.fromJson(e)).toList();
  438. } catch (e) {
  439. rethrow;
  440. }
  441. }
  442. Future<void> createTask(
  443. Function(dynamic) onSuccess,
  444. Function(String) onError, {
  445. required RequestTask item,
  446. }) async {
  447. try {
  448. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists';
  449. await dio.post(url, data: item).then(
  450. (value) {
  451. onSuccess(value);
  452. },
  453. ).catchError((e) {
  454. onError(AppException.handleError(e));
  455. });
  456. } catch (e) {
  457. onError(AppException.handleError(e));
  458. }
  459. }
  460. Future<void> updateTask(
  461. Function(dynamic) onSuccess,
  462. Function(String) onError, {
  463. required RequestTaskUpdate item,
  464. }) async {
  465. try {
  466. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists/';
  467. await dio.put(url, data: item).then(
  468. (value) {
  469. onSuccess(value);
  470. },
  471. ).catchError((e) {
  472. onError(AppException.handleError(e));
  473. });
  474. } catch (e) {
  475. onError(AppException.handleError(e));
  476. }
  477. }
  478. Future<List<Employee>> getEmployees() async {
  479. try {
  480. var url = '${ConstCommon.baseUrl}/api/get-all-users-by-login-info';
  481. var res = await dio.get(
  482. url,
  483. );
  484. return (res.data as List).map((e) => Employee.fromJson(e)).toList();
  485. } catch (e) {
  486. rethrow;
  487. }
  488. }
  489. Future<List<Employee>> getEmployeesByCropId(int cropId) async {
  490. try {
  491. var url = '${ConstCommon.baseUrl}/api/get-all-users-by-crop-id/$cropId';
  492. var res = await dio.get(
  493. url,
  494. );
  495. return (res.data as List).map((e) => Employee.fromJson(e)).toList();
  496. } catch (e) {
  497. rethrow;
  498. }
  499. }
  500. Future<List<SupplyFilter>> getSuppliesFilter() async {
  501. try {
  502. var url = '${ConstCommon.baseUrl}/api/tb-supplies/by-login-info';
  503. var res = await dio.get(
  504. url,
  505. );
  506. return (res.data as List).map((e) => SupplyFilter.fromJson(e)).toList();
  507. } catch (e) {
  508. rethrow;
  509. }
  510. }
  511. //api/tb-entities/area
  512. Future<List<AreaFilter>> getAreasFilter() async {
  513. try {
  514. var url = '${ConstCommon.baseUrl}/api/tb-entities/area';
  515. var res = await dio.get(
  516. url,
  517. );
  518. return (res.data as List).map((e) => AreaFilter.fromJson(e)).toList();
  519. } catch (e) {
  520. rethrow;
  521. }
  522. }
  523. // Crop
  524. Future<List<TbCropDTO>> crops({
  525. int page = 0,
  526. int size = 1000,
  527. required CropFilterRequest filter,
  528. }) async {
  529. try {
  530. var url = '${ConstCommon.baseUrl}/api/tb-crops/list?page=$page&size=$size&sort=createdDate,desc';
  531. var res = await dio.post(url, data: {
  532. 'tbSuppliesIds': filter.supplyIds,
  533. 'areaIds': filter.netHouseIds,
  534. 'code': filter.code,
  535. });
  536. return (res.data as List).map((e) => TbCropDTO.fromJson(e)).toList();
  537. } catch (e) {
  538. rethrow;
  539. }
  540. }
  541. Future<Task> getTaskDetail({required int id}) async {
  542. try {
  543. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists/$id';
  544. var res = await dio.get(url);
  545. return Task.fromJson(res.data);
  546. } catch (e) {
  547. rethrow;
  548. }
  549. }
  550. }