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.

604 lines
19KB

  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 type, {String query = ""}) async {
  115. final client = RestClient(dio);
  116. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  117. return client.getSupplies(type, query: query, options: op);
  118. }
  119. Future<List<Device>> getDeviceForActivity() async {
  120. final client = RestClient(dio);
  121. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  122. return client.getDeviceForActivity(options: op);
  123. }
  124. Future<void> updateAllNotification(String status) {
  125. final client = RestClient(dio);
  126. return client.updateAllNotification(status);
  127. }
  128. Future<void> updateNoti(UpdateNoti updateNoti) {
  129. final client = RestClient(dio);
  130. return client.updateNoti(updateNoti);
  131. }
  132. Future<NotificationObjectDTO> getNotifications({int page = 0, int size = 20}) async {
  133. var url = ConstCommon.baseUrl + "/api/notifications-current-user?page=$page&size=$size&sort=sendDate,DESC";
  134. var response = await dio.get(url);
  135. final value = NotificationObjectDTO.fromJson(response.data);
  136. return value;
  137. }
  138. Future<List<LocationUnit>> getLocationUnits(
  139. {required LocationType locationType, int filterId = -1, int page = 0, int size = 500, String query = ''}) {
  140. final client = RestClient(dio);
  141. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  142. var response;
  143. switch (locationType) {
  144. case LocationType.province:
  145. response = client.getProvinces(filterId, options: op, page: page, size: size, query: query);
  146. break;
  147. case LocationType.district:
  148. response = client.getDistricts(filterId, options: op, page: page, size: size, query: query);
  149. break;
  150. case LocationType.ward:
  151. response = client.getWards(filterId, options: op, page: page, size: size, query: query);
  152. break;
  153. default:
  154. response = client.getCountries(query: query);
  155. }
  156. return response;
  157. }
  158. Object getInstanceClass() {
  159. var instanceClass;
  160. if (1 == 1) {
  161. instanceClass = new TbCropDTO();
  162. }
  163. return instanceClass;
  164. }
  165. //Action
  166. Future<void> createAction(Function(dynamic) onSuccess, Function(dynamic) onError,
  167. {String? apiAddAction, String? paramActivity, String? activityAction, List<String>? filePaths}) async {
  168. var formData = FormData();
  169. filePaths?.forEach((f) {
  170. formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
  171. });
  172. formData.fields.add(MapEntry(paramActivity ?? '', activityAction ?? ''));
  173. try {
  174. await dio.post("${ConstCommon.baseUrl}/$apiAddAction", data: formData).then((value) {
  175. onSuccess(value.data);
  176. });
  177. } on DioError catch (e) {
  178. onError(e);
  179. }
  180. }
  181. Future<void> updateAction(Function(dynamic) onSuccess, Function(dynamic) onError,
  182. {String? apiUpdateAction, String? paramActivity, String? activityAction, List<String>? filePaths}) async {
  183. var formData = FormData();
  184. if (filePaths != null) {
  185. filePaths.forEach((f) {
  186. formData.files.add(MapEntry("images", MultipartFile.fromFileSync(f)));
  187. });
  188. }
  189. formData.fields.add(MapEntry(paramActivity ?? '', activityAction ?? ''));
  190. try {
  191. await dio.post("${ConstCommon.baseUrl}/$apiUpdateAction", data: formData).then((value) {
  192. onSuccess(value.data);
  193. });
  194. } on DioError catch (e) {
  195. onError(e);
  196. }
  197. }
  198. //Device
  199. Future<List<Device>> getDevices(String query) {
  200. final client = RestClient(dio);
  201. return client.getDevices(query);
  202. }
  203. //Environment Parameter
  204. Future<List<EnvironmentParameter>> getEnvironmentParameters({required int cropId, int page = 0, int size = 20}) {
  205. final client = RestClient(dio);
  206. return client.getEnvironmentParameters(cropId, page: page, size: size);
  207. }
  208. //NEW IMPLEMENT
  209. Future<void> allActionTypes(int cropTypeId, Function(List<ActionType>) onSuccess, Function(dynamic) onError) async {
  210. try {
  211. var url = '${ConstCommon.baseUrl}/api/listActivityTypesCulture/$cropTypeId';
  212. final Response<List<dynamic>> _result = await dio.get(url);
  213. var value = _result.data?.map((dynamic i) => ActionType.fromJson(i as Map<String, dynamic>)).toList();
  214. onSuccess(value ?? []);
  215. } on DioError catch (e) {
  216. onError(e);
  217. }
  218. }
  219. Future<ActionUIForm> getActionUIForm({required int idAction}) {
  220. final client = RestClient(dio);
  221. var op = buildConfigurableCacheOptions(forceRefresh: true, maxAge: Duration(days: ConstCommon.kMaxAgeCache));
  222. return client.getActionUIForm(idAction, op);
  223. }
  224. Future<List<CommonData>> getCommonData({required String tableSupply, required String condition}) async {
  225. var url = '${ConstCommon.baseUrl}/api/get-data-from-table-common?tableName=$tableSupply&condition=$condition';
  226. final Response<List<dynamic>> _result = await dio.get(url);
  227. var value = _result.data?.map((dynamic i) => CommonData.fromJson(i as Map<String, dynamic>)).toList();
  228. return value ?? [];
  229. }
  230. Future<void> createActionCommon(Function(dynamic) onSuccess, Function(dynamic) onError,
  231. {required String activityType, required String activityData, List<String>? filePaths}) async {
  232. var formData = FormData();
  233. if (filePaths != null) {
  234. filePaths.forEach((f) {
  235. formData.files.add(MapEntry('images', MultipartFile.fromFileSync(f)));
  236. });
  237. }
  238. formData.fields.add(MapEntry('tbCommonActivityDTO', activityData));
  239. try {
  240. await dio.post("${ConstCommon.baseUrl}/api/create-common-activity/$activityType", data: formData).then((value) {
  241. onSuccess(value.data);
  242. });
  243. } on DioError catch (e) {
  244. onError(e);
  245. }
  246. }
  247. Future<void> updateActionCommon(Function(dynamic) onSuccess, Function(dynamic) onError,
  248. {required String activityType, required String activityData, List<String>? filePaths}) async {
  249. var formData = FormData();
  250. if (filePaths != null) {
  251. filePaths.forEach((f) {
  252. formData.files.add(MapEntry('images', MultipartFile.fromFileSync(f)));
  253. });
  254. }
  255. formData.fields.add(MapEntry('tbCommonActivityDTO', activityData));
  256. try {
  257. await dio.post("${ConstCommon.baseUrl}/api/update-common-activity/$activityType", data: formData).then((value) {
  258. onSuccess(value.data);
  259. });
  260. } on DioError catch (e) {
  261. onError(e);
  262. }
  263. }
  264. Future<RequestActivity> detailCommonAction({required int activityId, required String activityType}) async {
  265. final client = RestClient(dio);
  266. return client.getDetailActivityCommon(activityType, activityId);
  267. }
  268. // Stamp
  269. Future<List<Stamp>> stamps({
  270. int page = 0,
  271. int size = 20,
  272. required StampFilterRequest filter,
  273. }) async {
  274. try {
  275. var url = '${ConstCommon.baseUrl}/api/tb-codes/list?page=$page&size=$size&sort=createdDate,${filter.sort ?? 'asc'}';
  276. var res = await dio.post(url, data: {
  277. 'status': filter.status,
  278. 'description': filter.description,
  279. });
  280. return (res.data as List).map((e) => Stamp.fromJson(e)).toList();
  281. } catch (e) {
  282. rethrow;
  283. }
  284. }
  285. Future<List<StampType>> stampTypes() async {
  286. try {
  287. var url = '${ConstCommon.baseUrl}/api/tb-example-stamp/dropdown-list';
  288. var res = await dio.get(
  289. url,
  290. );
  291. return (res.data as List).map((e) => StampType.fromJson(e)).toList();
  292. } catch (e) {
  293. rethrow;
  294. }
  295. }
  296. Future<void> createStamp(
  297. Function(dynamic) onSuccess,
  298. Function(String) onError, {
  299. required RequestStamp item,
  300. }) async {
  301. try {
  302. var url = '${ConstCommon.baseUrl}/api/tb-codes';
  303. await dio.post(url, data: item).then(
  304. (value) {
  305. onSuccess(value);
  306. },
  307. ).catchError((e) {
  308. onError(AppException.handleError(e));
  309. });
  310. } catch (e) {
  311. onError(AppException.handleError(e));
  312. }
  313. }
  314. Future<List<ActivityType>> activityTypes() async {
  315. try {
  316. var url = '${ConstCommon.baseUrl}/api/tb-activity-types-dropdown-list-after-harvest';
  317. var res = await dio.get(
  318. url,
  319. );
  320. return (res.data as List).map((e) => ActivityType.fromJson(e)).toList();
  321. } catch (e) {
  322. rethrow;
  323. }
  324. }
  325. Future<void> updateActivity(
  326. Function(dynamic) onSuccess,
  327. Function(String) onError, {
  328. required ActivityRequest item,
  329. }) async {
  330. try {
  331. var url = '${ConstCommon.baseUrl}/api/tb-codes/create/activity';
  332. var formData = FormData();
  333. formData.fields.add(MapEntry('code', item.code ?? ''));
  334. formData.fields.add(MapEntry('activityTypeId', item.activityTypeId?.toString() ?? ''));
  335. formData.fields.add(MapEntry('executeDate', item.executeDate ?? ''));
  336. formData.fields.add(MapEntry('description', item.description ?? ''));
  337. formData.fields.add(MapEntry('location', item.location ?? ''));
  338. await dio.post(url, data: formData).then(
  339. (value) {
  340. onSuccess(value);
  341. },
  342. ).catchError((e) {
  343. onError(AppException.handleError(e));
  344. });
  345. } catch (e) {
  346. onError(AppException.handleError(e));
  347. }
  348. }
  349. Future<Stamp> getStampDetail({required int id}) async {
  350. try {
  351. var url = '${ConstCommon.baseUrl}/api/tb-codes/$id';
  352. var res = await dio.get(url);
  353. return Stamp.fromJson(res.data);
  354. } catch (e) {
  355. rethrow;
  356. }
  357. }
  358. Future<Stamp> getStampDetailByCode({required String code}) async {
  359. try {
  360. var url = '${ConstCommon.baseUrl}/api/tb-codes-scan-qrCode/$code';
  361. var res = await dio.get(url);
  362. return Stamp.fromJson(res.data);
  363. } catch (e) {
  364. rethrow;
  365. }
  366. }
  367. Future<StampTimeline> getStampTimeline({required int stampId}) async {
  368. try {
  369. var url = '${ConstCommon.baseUrl}/api/tb-codes-timeline/$stampId';
  370. var res = await dio.get(url);
  371. return StampTimeline.fromJson(res.data);
  372. } catch (e) {
  373. rethrow;
  374. }
  375. }
  376. Future<void> updateStampStatus(
  377. Function(dynamic) onSuccess,
  378. Function(String) onError, {
  379. required int stampId,
  380. required String status,
  381. }) async {
  382. try {
  383. var url = '${ConstCommon.baseUrl}/api/tb-codes/update/$stampId/status/$status';
  384. await dio.put(url).then(
  385. (value) {
  386. onSuccess(value);
  387. },
  388. ).catchError((e) {
  389. onError(AppException.handleError(e));
  390. });
  391. } catch (e) {
  392. onError(AppException.handleError(e));
  393. }
  394. }
  395. Future<List<TbCropDTO>> getPlotsWithoutPaging() async {
  396. try {
  397. var url = '${ConstCommon.baseUrl}/api/_search/tb-crops';
  398. var res = await dio.get(
  399. url,
  400. );
  401. return (res.data as List).map((e) => TbCropDTO.fromJson(e)).toList();
  402. } catch (e) {
  403. rethrow;
  404. }
  405. }
  406. // Task
  407. Future<List<Task>> tasks({
  408. int page = 0,
  409. int size = 20,
  410. required TaskFilterRequest filter,
  411. }) async {
  412. try {
  413. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists/list?page=$page&size=$size&sort=deadline,${filter.sort ?? 'asc'}';
  414. var status = <bool>[];
  415. if (filter.status != null) {
  416. status = filter.status!.map((e) {
  417. if (e == describeEnum(TaskStatus.completed)) {
  418. return true;
  419. } else {
  420. return false;
  421. }
  422. }).toList();
  423. }
  424. var res = await dio.post(url, data: {
  425. 'completed': status,
  426. "crop_id": filter.cropId,
  427. });
  428. return (res.data as List).map((e) => Task.fromJson(e)).toList();
  429. } catch (e) {
  430. rethrow;
  431. }
  432. }
  433. Future<void> createTask(
  434. Function(dynamic) onSuccess,
  435. Function(String) onError, {
  436. required RequestTask item,
  437. }) async {
  438. try {
  439. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists';
  440. await dio.post(url, data: item).then(
  441. (value) {
  442. onSuccess(value);
  443. },
  444. ).catchError((e) {
  445. onError(AppException.handleError(e));
  446. });
  447. } catch (e) {
  448. onError(AppException.handleError(e));
  449. }
  450. }
  451. Future<void> updateTask(
  452. Function(dynamic) onSuccess,
  453. Function(String) onError, {
  454. required RequestTaskUpdate item,
  455. }) async {
  456. try {
  457. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists/';
  458. await dio.put(url, data: item).then(
  459. (value) {
  460. onSuccess(value);
  461. },
  462. ).catchError((e) {
  463. onError(AppException.handleError(e));
  464. });
  465. } catch (e) {
  466. onError(AppException.handleError(e));
  467. }
  468. }
  469. Future<List<Employee>> getEmployees() async {
  470. try {
  471. var url = '${ConstCommon.baseUrl}/api/get-all-users-by-login-info';
  472. var res = await dio.get(
  473. url,
  474. );
  475. return (res.data as List).map((e) => Employee.fromJson(e)).toList();
  476. } catch (e) {
  477. rethrow;
  478. }
  479. }
  480. Future<List<Employee>> getEmployeesByCropId(int cropId) async {
  481. try {
  482. var url = '${ConstCommon.baseUrl}/api/get-all-users-by-crop-id/$cropId';
  483. var res = await dio.get(
  484. url,
  485. );
  486. return (res.data as List).map((e) => Employee.fromJson(e)).toList();
  487. } catch (e) {
  488. rethrow;
  489. }
  490. }
  491. Future<List<SupplyFilter>> getSuppliesFilter() async {
  492. try {
  493. var url = '${ConstCommon.baseUrl}/api/tb-supplies/by-login-info';
  494. var res = await dio.get(
  495. url,
  496. );
  497. return (res.data as List).map((e) => SupplyFilter.fromJson(e)).toList();
  498. } catch (e) {
  499. rethrow;
  500. }
  501. }
  502. //api/tb-entities/area
  503. Future<List<AreaFilter>> getAreasFilter() async {
  504. try {
  505. var url = '${ConstCommon.baseUrl}/api/tb-entities/area';
  506. var res = await dio.get(
  507. url,
  508. );
  509. return (res.data as List).map((e) => AreaFilter.fromJson(e)).toList();
  510. } catch (e) {
  511. rethrow;
  512. }
  513. }
  514. // Crop
  515. Future<List<TbCropDTO>> crops({
  516. int page = 0,
  517. int size = 1000,
  518. required CropFilterRequest filter,
  519. }) async {
  520. try {
  521. var url = '${ConstCommon.baseUrl}/api/tb-crops/list?page=$page&size=$size&sort=createdDate,desc';
  522. var res = await dio.post(url, data: {
  523. 'tbSuppliesIds': filter.supplyIds,
  524. 'areaIds': filter.netHouseIds,
  525. 'code': filter.code,
  526. });
  527. return (res.data as List).map((e) => TbCropDTO.fromJson(e)).toList();
  528. } catch (e) {
  529. rethrow;
  530. }
  531. }
  532. Future<Task> getTaskDetail({required int id}) async {
  533. try {
  534. var url = '${ConstCommon.baseUrl}/api/tb-todo-lists/$id';
  535. var res = await dio.get(url);
  536. return Task.fromJson(res.data);
  537. } catch (e) {
  538. rethrow;
  539. }
  540. }
  541. }