
Enables offline capabilities and improved data access for stock picking records. API calls now prioritize local ObjectBox storage when offline and persist fetched data upon successful remote retrieval. Introduces comprehensive model-to-entity conversion logic for stock picking data and its related models. Updates UI components and state management to directly consume ObjectBox entities, optimizing data display and interaction. Adjusts ObjectBox entity schema for improved flexibility and adds utility getters.
332 lines
11 KiB
Dart
332 lines
11 KiB
Dart
import 'package:e_scan/backend/objectbox/entities/stock_picking/stock_picking_record_entity.dart';
|
|
import 'package:e_scan/backend/objectbox/objectbox_manager.dart';
|
|
import 'package:e_scan/backend/schema/auth/auth_model.dart';
|
|
import 'package:e_scan/backend/schema/stock_picking/stock_picking_model.dart';
|
|
import 'package:e_scan/backend/schema/stock_picking/stock_picking_record_model.dart';
|
|
import 'package:e_scan/provider_container.dart';
|
|
import 'package:e_scan/services/dio_service.dart';
|
|
import 'package:e_scan/services/token_provider.dart';
|
|
import 'package:e_scan/utils/utils.dart';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:multiple_result/multiple_result.dart';
|
|
|
|
class ApiCalls {
|
|
static DioService dioService = DioService(
|
|
tokenProvider: providerContainer.read(tokenProvider),
|
|
);
|
|
|
|
static Future<Map<String, dynamic>?> fetchProduct(String barcode) async {
|
|
final Dio dio = Dio(
|
|
BaseOptions(baseUrl: 'https://world.openfoodfacts.org'),
|
|
);
|
|
try {
|
|
final response = await dio.get('/api/v0/product/$barcode.json');
|
|
|
|
if (response.statusCode == 200) {
|
|
final data = response.data;
|
|
if (data['status'] == 1) {
|
|
return data['product'];
|
|
} else {
|
|
debugPrint('Produit non trouvé');
|
|
return null;
|
|
}
|
|
} else {
|
|
debugPrint('Erreur réseau: ${response.statusCode}');
|
|
return null;
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Erreur lors de la requête: $e');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static Future<Result<AuthModel, Error>> signIn({
|
|
required String email,
|
|
required String password,
|
|
}) async {
|
|
try {
|
|
final response = await dioService.post(
|
|
path: '/simpos/v1/sign_in',
|
|
data: {
|
|
"params": {
|
|
"login": email,
|
|
"password": password,
|
|
"db": "bitnami_odoo",
|
|
},
|
|
},
|
|
);
|
|
if (response.statusCode == 200) {
|
|
final data = response.data;
|
|
if (data['result']['success'] == true) {
|
|
String? cookie;
|
|
if (response.headers.map.containsKey('set-cookie')) {
|
|
cookie = response.headers.map['set-cookie']?.firstOrNull;
|
|
}
|
|
final auth = AuthModel.fromJson(
|
|
data['result']['data'],
|
|
).copyWith(sessionId: cookie);
|
|
return Result.success(auth);
|
|
} else {
|
|
return Result.error(Error(data['result']['success']));
|
|
}
|
|
} else {
|
|
debugPrint('Erreur réseau: ${response.statusCode}');
|
|
return Result.error(Error(response.statusMessage));
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Erreur lors de la requête: $e');
|
|
return Result.error(Error(e));
|
|
}
|
|
}
|
|
|
|
static Future<Result<List<StockPickingRecordEntity>, Error>>
|
|
getAllStockPiking() async {
|
|
try {
|
|
final stockPickingRecords = objectboxManager.store
|
|
.box<StockPickingRecordEntity>();
|
|
if (!(await checkInternetConnexion())) {
|
|
// return local data
|
|
return Result.success(stockPickingRecords.getAll());
|
|
}
|
|
final response = await dioService.post(
|
|
path: '/web/dataset/call_kw/stock.picking/web_search_read',
|
|
data: {
|
|
//"id": 23,
|
|
//"jsonrpc": "2.0",
|
|
//"method": "call",
|
|
"params": {
|
|
"model": "stock.picking",
|
|
"method": "web_search_read",
|
|
"args": [],
|
|
"kwargs": {
|
|
"specification": {
|
|
"company_id": {"fields": {}},
|
|
"priority": {},
|
|
"name": {},
|
|
"partner_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"location_dest_id": {
|
|
"fields": {"complete_name": {}},
|
|
},
|
|
"location_id": {
|
|
"fields": {"complete_name": {}},
|
|
},
|
|
"user_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"scheduled_date": {},
|
|
"picking_type_code": {},
|
|
"products_availability_state": {},
|
|
"products_availability": {},
|
|
"date_deadline": {},
|
|
"date_done": {},
|
|
"origin": {},
|
|
"backorder_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"picking_type_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"state": {},
|
|
"activity_exception_decoration": {},
|
|
"activity_exception_icon": {},
|
|
"json_popover": {},
|
|
},
|
|
"offset": 0,
|
|
"order": "",
|
|
"limit": 80,
|
|
"context": {
|
|
"lang": "en_US",
|
|
"tz": "Africa/Nairobi",
|
|
"uid": 2,
|
|
"allowed_company_ids": [1],
|
|
"bin_size": true,
|
|
"active_model": "stock.picking.type",
|
|
"active_id": 2,
|
|
"active_ids": [2],
|
|
"contact_display": "partner_address",
|
|
"default_picking_type_id": 2,
|
|
"default_company_id": 1,
|
|
"current_company_id": 1,
|
|
},
|
|
"count_limit": 10001,
|
|
"domain": [
|
|
["picking_type_code", "=", "incoming"],
|
|
],
|
|
},
|
|
},
|
|
},
|
|
);
|
|
if (response.statusCode == 200) {
|
|
final data = response.data;
|
|
if (data.containsKey('result')) {
|
|
final result = StockPickingResponseModel.fromJson(data);
|
|
final recordsModel =
|
|
result.result?.records ?? <StockPickingRecordModel>[];
|
|
// add data to local
|
|
for (var rec in recordsModel) {
|
|
rec.toEntity();
|
|
}
|
|
return Result.success(stockPickingRecords.getAll());
|
|
} else {
|
|
return Result.error(Error(data['error']));
|
|
}
|
|
} else {
|
|
debugPrint('Erreur réseau: ${response.statusCode}');
|
|
return Result.error(Error(response.statusMessage));
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Erreur lors de la requête: $e');
|
|
return Result.error(Error(e));
|
|
}
|
|
}
|
|
|
|
static Future<Result<StockPickingRecordEntity, Error>> getStockPikingById({
|
|
required int id,
|
|
}) async {
|
|
try {
|
|
final stockPickingRecords = objectboxManager.store
|
|
.box<StockPickingRecordEntity>();
|
|
if (!(await checkInternetConnexion())) {
|
|
// return local data
|
|
final entity = stockPickingRecords.get(id);
|
|
if (entity == null) return Result.error(Error('Not found'));
|
|
return Result.success(entity);
|
|
}
|
|
final response = await dioService.post(
|
|
path: '/web/dataset/call_kw/stock.picking/web_read',
|
|
data: {
|
|
"params": {
|
|
"model": "stock.picking",
|
|
"method": "web_read",
|
|
"args": [
|
|
[id],
|
|
],
|
|
"kwargs": {
|
|
"context": {
|
|
"lang": "en_US",
|
|
"tz": "Africa/Nairobi",
|
|
"uid": 2,
|
|
"allowed_company_ids": [1],
|
|
"bin_size": true,
|
|
"active_model": "stock.picking.type",
|
|
"active_id": 2,
|
|
"active_ids": [2],
|
|
"contact_display": "partner_address",
|
|
"default_picking_type_id": 2,
|
|
"default_company_id": 1,
|
|
},
|
|
"specification": {
|
|
"state": {},
|
|
"return_count": {},
|
|
"priority": {},
|
|
"picking_type_code": {},
|
|
"name": {},
|
|
"partner_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"picking_type_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"location_id": {
|
|
"fields": {"complete_name": {}},
|
|
},
|
|
"location_dest_id": {
|
|
"fields": {"complete_name": {}},
|
|
},
|
|
"backorder_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"use_create_lots": {},
|
|
"scheduled_date": {},
|
|
"json_popover": {},
|
|
"date_deadline": {},
|
|
"products_availability_state": {},
|
|
"products_availability": {},
|
|
"date_done": {},
|
|
"origin": {},
|
|
"picking_properties": {},
|
|
"move_line_ids_without_package": {
|
|
"fields": {
|
|
"product_id": {
|
|
"fields": {"display_name": {}, "barcode": {}},
|
|
},
|
|
"quantity": {}, // quantité
|
|
},
|
|
},
|
|
"move_ids_without_package": {
|
|
"fields": {
|
|
"product_id": {
|
|
"fields": {"display_name": {}, "barcode": {}},
|
|
},
|
|
"quantity": {}, // quantité
|
|
"product_uom_qty": {}, //quantité demandé
|
|
},
|
|
"context": {
|
|
"form_view_ref": "stock.view_stock_move_operations",
|
|
},
|
|
"limit": 40,
|
|
"order": "",
|
|
},
|
|
"id": {},
|
|
"package_level_ids": {
|
|
"fields": {
|
|
"is_fresh_package": {},
|
|
"company_id": {"fields": {}},
|
|
"package_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"state": {}, //done, ready, waiting,
|
|
"is_done": {},
|
|
},
|
|
"limit": 40,
|
|
"order": "",
|
|
},
|
|
"move_type": {},
|
|
"user_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"sale_id": {
|
|
"fields": {"display_name": {}},
|
|
},
|
|
"note": {},
|
|
"show_check_availability": {},
|
|
"has_scrap_move": {},
|
|
"has_packages": {},
|
|
"is_locked": {},
|
|
"show_next_pickings": {},
|
|
"company_id": {"fields": {}},
|
|
"picking_type_entire_packs": {},
|
|
"display_name": {},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
);
|
|
if (response.statusCode == 200) {
|
|
final data = response.data;
|
|
if (data.containsKey('result')) {
|
|
final datas = data['result'] as List;
|
|
if (datas.isNotEmpty) {
|
|
final recordModel = StockPickingRecordModel.fromJson(datas.first);
|
|
final entity = recordModel.toEntity();
|
|
return Result.success(entity);
|
|
} else {
|
|
return Result.error(Error('Data not found'));
|
|
}
|
|
} else {
|
|
return Result.error(Error(data['error']));
|
|
}
|
|
} else {
|
|
debugPrint('Erreur réseau: ${response.statusCode}');
|
|
return Result.error(Error(response.statusMessage));
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Erreur lors de la requête: $e');
|
|
return Result.error(Error(e));
|
|
}
|
|
}
|
|
}
|