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.

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