1 koneksi untuk semua service menggunakan Odoo Await

 

✅ Rangkuman Implementasi Koneksi Odoo yang Efisien di NestJS

Agar koneksi ke Odoo hanya dilakukan satu kali dan bisa digunakan di semua service tanpa membuat koneksi berulang, kita bisa menggunakan Singleton Pattern dengan Provider NestJS.


1️⃣ Buat OdooProvider sebagai Singleton

Gunakan provider global yang hanya membuat koneksi sekali saja, lalu digunakan di seluruh aplikasi.

📌 Buat odoo.provider.ts

import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as Odoo from 'odoo-await';

@Injectable()
export class OdooProvider implements OnModuleInit, OnModuleDestroy {
  private static odooInstance: Odoo;
  private static isConnected = false;

  constructor(private readonly configService: ConfigService) {
    if (!OdooProvider.odooInstance) {
      OdooProvider.odooInstance = new Odoo({
        baseUrl: this.configService.get<string>('ODOO_BASE_URL'),
        db: this.configService.get<string>('ODOO_DB'),
        username: this.configService.get<string>('ODOO_USERNAME'),
        password: this.configService.get<string>('ODOO_PASSWORD'),
      });
    }
  }

  async onModuleInit() {
    await this.connect();
  }

  async connect(): Promise<Odoo> {
    if (!OdooProvider.isConnected) {
      await OdooProvider.odooInstance.connect();
      OdooProvider.isConnected = true;
      console.log('✅ Connected to Odoo');
    }
    return OdooProvider.odooInstance;
  }

  getOdooInstance(): Odoo {
    return OdooProvider.odooInstance;
  }

  async onModuleDestroy() {
    OdooProvider.isConnected = false;
    console.log('❌ Odoo connection closed');
  }
}

🛠️ Penjelasan:

  • OdooProvider sebagai Singleton → Tidak akan membuat banyak instance.
  • onModuleInit untuk koneksi pertama kali → Menghubungkan ke Odoo saat modul di-load.
  • getOdooInstance → Mengembalikan instance yang sudah terhubung agar digunakan di service lain.

2️⃣ Tambahkan OdooProvider ke app.module.ts

Pastikan provider ini global agar bisa digunakan di semua service.

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { OdooProvider } from './odoo.provider';

@Module({
  imports: [ConfigModule.forRoot()],
  providers: [OdooProvider],
  exports: [OdooProvider], // 🔥 Supaya bisa digunakan di module lain
})
export class AppModule {}
  • exports: [OdooProvider] → Memungkinkan module lain mengakses OdooProvider.

3️⃣ Gunakan OdooProvider di Service Mana Pun

📌 Contoh di payment.service.ts

import { Injectable } from '@nestjs/common';
import { OdooProvider } from '../odoo.provider';

@Injectable()
export class PaymentService {
  private odoo: any;

  constructor(private readonly odooProvider: OdooProvider) {
    this.odoo = this.odooProvider.getOdooInstance();
  }

  async cancelPayment(billId: number, requestedVia: string) {
    const model = requestedVia === 'so' ? 'sale.order' : 'account.move';
    const bill = await this.odoo.searchRead(model, [['id', '=', billId]], ['id']);

    if (!bill.length) {
      throw new Error('Bill not found');
    }

    const history = await this.odoo.searchRead('payment.gateway.history', [[requestedVia === 'so' ? 'so_id' : 'inv_id', '=', billId]], [], { limit: 1 });

    if (!history.length) {
      throw new Error('Payment history not found');
    }

    return await this.odoo.execute_kw('payment.gateway.history', 'cancel_espay', [[history[0].id]]);
  }
}
  • this.odoo = this.odooProvider.getOdooInstance(); → Menggunakan instance yang sudah terhubung, tanpa koneksi baru.

🎯 Kesimpulan

Hanya satu koneksi ke Odoo (efisien, tidak membuat koneksi baru di setiap service).
Provider bisa digunakan di semua service dengan getOdooInstance().
Aplikasi lebih cepat & lebih ringan, karena tidak ada koneksi yang dibuat berulang.

🚀 Sekarang Odoo hanya terhubung sekali dan bisa digunakan di mana saja!