149 lines
4.3 KiB
Dart
149 lines
4.3 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import '../odoo_rpc_helper.dart';
|
|
|
|
/// Klien JSON-RPC utk Odoo 17. Authenticate + execute_kw.
|
|
class OdooClient {
|
|
OdooClient({required this.baseUrl, required this.db, required this.username, required this.password})
|
|
: _http = http.Client();
|
|
|
|
final String baseUrl; // mis: http://192.168.x.x:18069
|
|
final String db; // nama db, default 'odoo'
|
|
final String username;
|
|
final String password;
|
|
|
|
final http.Client _http;
|
|
int? _uid;
|
|
|
|
Uri get _endpoint => Uri.parse('$baseUrl/jsonrpc');
|
|
|
|
Future<int> authenticate() async {
|
|
final result = await _call('common', 'authenticate', [db, username, password, {}]);
|
|
if (result is int && result > 0) {
|
|
_uid = result;
|
|
return result;
|
|
}
|
|
throw Exception('Login gagal: periksa kredensial / URL Odoo');
|
|
}
|
|
|
|
Future<dynamic> executeKwd(String model, String method,
|
|
{List<dynamic> args = const [], Map<String, dynamic>? kwargs}) async {
|
|
_uid ??= await authenticate();
|
|
final params = [
|
|
db,
|
|
_uid,
|
|
password,
|
|
model,
|
|
method,
|
|
args,
|
|
if (kwargs != null) kwargs,
|
|
];
|
|
return _call('object', 'execute_kw', params);
|
|
}
|
|
|
|
Future<dynamic> executeKwdWithArgs(String model, String method,
|
|
{List<dynamic> fields = const [], Map<String, dynamic>? kwargs}) async {
|
|
_uid ??= await authenticate();
|
|
final args = [
|
|
|
|
db,
|
|
_uid,
|
|
password,
|
|
model,
|
|
method,
|
|
[],
|
|
fields,
|
|
|
|
if (kwargs != null) kwargs,
|
|
];
|
|
return _call('object', 'execute_kw', args);
|
|
}
|
|
|
|
Future<dynamic> executeSearchReadPayload(String model, List<String> fields) async {
|
|
int uid = await authenticate();
|
|
final payload = OdooRpcHelper.searchRead(
|
|
db: db,
|
|
uid: uid,
|
|
password: password,
|
|
model: model,
|
|
domain: [[]],
|
|
fields: fields,
|
|
limit: 20,
|
|
);
|
|
|
|
return _callSearchRead(payload);
|
|
}
|
|
|
|
Future<dynamic> _callSearchRead(Map<String, dynamic> payload) async{
|
|
// Use jsonEncode along with a JsonEncoder for indentation
|
|
JsonEncoder encoder = const JsonEncoder.withIndent(' ');
|
|
String prettyString = encoder.convert(payload);
|
|
|
|
debugPrint(prettyString);
|
|
|
|
try {
|
|
final resp = await _http
|
|
.post(_endpoint,
|
|
headers: {'Content-Type': 'application/json'}, body: jsonEncode(payload))
|
|
.timeout(const Duration(seconds: 25));
|
|
final json = jsonDecode(resp.body) as Map<String, dynamic>;
|
|
if (json.containsKey('error')) {
|
|
final err = json['error'] as Map?;
|
|
String? message = (err?['data'] as Map?)?['message'] as String? ??
|
|
(err?['message'] as String?) ??
|
|
'Unknown Odoo error';
|
|
throw Exception('Odoo error: $message');
|
|
}
|
|
return json['result'];
|
|
} on TimeoutException {
|
|
throw Exception('Timeout — pastikan server Odoo:18069 tercapai');
|
|
} on http.ClientException catch (e) {
|
|
throw Exception('Koneksi gagal: ${e.message}');
|
|
}
|
|
|
|
}
|
|
|
|
Future<dynamic> _call(String service, String method, List<dynamic> args) async {
|
|
final body = {
|
|
'jsonrpc': '2.0',
|
|
'method': 'call',
|
|
'params': {
|
|
'service': service,
|
|
'method': method,
|
|
'args': args,
|
|
},
|
|
};
|
|
|
|
// Use jsonEncode along with a JsonEncoder for indentation
|
|
JsonEncoder encoder = const JsonEncoder.withIndent(' ');
|
|
String prettyString = encoder.convert(body);
|
|
|
|
debugPrint(prettyString);
|
|
|
|
try {
|
|
final resp = await _http
|
|
.post(_endpoint,
|
|
headers: {'Content-Type': 'application/json'}, body: jsonEncode(body))
|
|
.timeout(const Duration(seconds: 25));
|
|
final json = jsonDecode(resp.body) as Map<String, dynamic>;
|
|
if (json.containsKey('error')) {
|
|
final err = json['error'] as Map?;
|
|
String? message = (err?['data'] as Map?)?['message'] as String? ??
|
|
(err?['message'] as String?) ??
|
|
'Unknown Odoo error';
|
|
throw Exception('Odoo error: $message');
|
|
}
|
|
return json['result'];
|
|
} on TimeoutException {
|
|
throw Exception('Timeout — pastikan server Odoo:18069 tercapai');
|
|
} on http.ClientException catch (e) {
|
|
throw Exception('Koneksi gagal: ${e.message}');
|
|
}
|
|
}
|
|
|
|
void close() => _http.close();
|
|
}
|