import 'package:odoo_rpc/odoo_rpc.dart'; class OdooService { static final OdooService _instance = OdooService._internal(); factory OdooService() => _instance; OdooService._internal(); OdooClient? client; void connect(String url) { client = OdooClient(url); } Future login(String db, String username, String password) async { if (client == null) throw Exception("Connect to Odoo first"); return await client!.authenticate(db, username, password); } Future> getLoyaltyCards(int partnerId) async { if (client == null) throw Exception("Connect to Odoo first"); // In Odoo 19, you might need to adjust the exact fields and model name // depending on the installed modules (e.g. 'loyalty.card'). return await client!.callKw({ 'model': 'loyalty.card', 'method': 'search_read', 'args': [ [['partner_id', '=', partnerId]], ], 'kwargs': {'fields': ['points', 'program_id', 'code']} }) as List; } /// Fetch public branch information using our secure Odoo endpoint /// This completely isolates the Admin API Key from the Flutter Source Code! static Future> getPublicBranches() async { final tempClient = OdooClient('https://erp.mapan.co.id'); try { final res = await tempClient.callRPC( '/api/loyalty/branches', 'call', {} ); if (res != null && res['status'] == 'success') { return res['data'] as List; } else { throw Exception(res?['message'] ?? 'Failed to load branches'); } } catch (e) { rethrow; } finally { tempClient.close(); } } }