Penggunaan QR Code semakin hari semakin populer dengan kemudahan dan kecepatannya. Sehingga banyak perusahaan menggunakan QR code dalam mempercepat proses bisnis.

Saya akan membagikan pengalaman implementasi odoo dengan APlikasi Android dan iOS maupun implementasi QR Code di Odoo tanpa aplikasi atau menggunakan PWA
1. Implementasi QR Code Odoo Dengan Aplikasi Mobile
Implementasi Odoo QR Code dengan Aplikasi merupakan implementasi yang menggunakan Android atau iOS untuk menangkap kode QR Code yang kemudian digunakan untuk memproses data yang ada di Odoo menggunakan API.
Dalam case ini saya akan memberikan contoh penggunaan QR Code di Flutter untuk bahasanya menggunakan bahasa Dart.
Dalam contoh ini QR Code digunakan untuk sistem patroli yang mencatat titik lokasi yang ditempel QR Code yang sudah disetting sebelumnya. Hasil dari tangkapan QR Code akan dikirim ke server Odoo dengan tujuan menandakan bahwa titik patroli tersebut sudah dilakukan patroli pada jam tersebut.
Tampilannya seperti ini :

Kelebihan versi Aplikasi Mobile bisa diberikan fitur menyalakan lampu flash untuk jaga-jaga jika di lokasi tidak terdapat penerangan yang cukup.
Kelebihan lain dari QR Code versi Aplikasi juga lebih stabil dalam mendeteksi QR Code.
Kekurangan dari versi Aplikasi adalah diperlukan resource lebih untuk melakukan perawatan kode sumber karena harus merawat 2 kode sumber yaitu kode di modul Odoo dan kode di Flutter.
Berikut ini kode Flutter yang saya gunakan untuk implementasi QR Code Odoo dengan Flutter :
class QRScanPage extends StatefulWidget {
final int checkPointReportId;
final int patrolReportId;
final String code;
final String json_question;
final OdooClient odooClient;
final String jadwalName;
final int jadwalId;
final int checkPointId;
final String checkPointName;
QRScanPage(
{required this.checkPointReportId,
required this.patrolReportId,
required this.code,
required this.json_question,
required this.odooClient,
required this.jadwalName,
required this.jadwalId,
required this.checkPointId,
required this.checkPointName});
@override
_QRScanPageState createState() => _QRScanPageState();
}
class _QRScanPageState extends State<QRScanPage> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
bool isFlashOn = false;
@override
void reassemble() {
super.reassemble();
controller?.pauseCamera();
controller?.resumeCamera();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Arahkan kamera ke QR Code'),
backgroundColor: const Color.fromARGB(255, 207, 33, 40),
foregroundColor: Colors.white,
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => PatrolQRListPage(
odooClient: widget.odooClient,
jadwalName: widget.jadwalName,
patrolReportId: widget.patrolReportId,
),
),
);
},
),
),
body: Stack(
children: <Widget>[
// QR Scanner
QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
),
// Overlay untuk area luar kotak yang gelap total
Positioned.fill(
child: ClipPath(
// clipper: QRScannerOverlay(screenHeight: screenHeight),
child: Container(
color:
Colors.black.withOpacity(0), // Gelap total di luar kotak
),
),
),
// Kotak dengan border putih di sudut-sudut
Align(
alignment: Alignment(0, -0.3),
child: Container(
width: 300,
height: 300,
decoration: BoxDecoration(
border: Border.all(
color: const Color.fromARGB(
0, 255, 255, 255), // Warna border putih
width: 0,
),
),
child: Stack(
children: [
Positioned(
top: 0,
left: 0,
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.white, width: 4),
left: BorderSide(color: Colors.white, width: 4),
),
),
),
),
Positioned(
top: 0,
right: 0,
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.white, width: 4),
right: BorderSide(color: Colors.white, width: 4),
),
),
),
),
Positioned(
bottom: 0,
left: 0,
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.white, width: 4),
left: BorderSide(color: Colors.white, width: 4),
),
),
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.white, width: 4),
right: BorderSide(color: Colors.white, width: 4),
),
),
),
),
],
),
),
),
// Icon flashlight di pojok kanan atas
Positioned(
top: 20,
right: 20,
child: IconButton(
icon: Icon(isFlashOn ? Icons.flash_on : Icons.flash_off,
color: Colors.white),
onPressed: () async {
await controller?.toggleFlash();
setState(() {
isFlashOn = !isFlashOn;
});
},
),
),
// Teks di bagian bawah
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
color: Colors.white,
padding: EdgeInsets.all(50),
child: Text(
widget.checkPointName,
style: TextStyle(
fontSize: 18,
color: Colors.black,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
),
],
),
);
}
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) async {
setState(() {
result = scanData;
});
if (result != null) {
if (result!.code != widget.code) {
// jika qr code tidak sesuai dengan qr code yang ditentukan
controller.pauseCamera();
showErrorDialog(context, 'QR Code tidak valid..!');
} else {
// pause kamera
controller.pauseCamera();
// munculkan form survey
final survey = Survey.fromJson(jsonDecode(widget.json_question));
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SurveyForm(
survey: survey,
odooClient: widget.odooClient,
jadwalName: widget.jadwalName,
patrolReportId: widget.patrolReportId,
checkPointId: widget.checkPointId,
checkPointReportId: widget.checkPointReportId,
)),
);
}
}
});
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
void showErrorDialog(BuildContext context, String message) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Error'),
content: Text(message),
actions: <Widget>[
TextButton(
child: Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
2. Implementasi Odoo dengan Qr Code tanpa Aplikasi Mobile (Menggunakan PWA dan Web)
Sebenernya kita juga bisa menggunakan web dari modul Odoo langsung tanpa menggunakan tambahan Aplikasi Mobile untuk menambahkan fitur QR Code di Odoo.
Kelebihan menggunakan web atau PWA adalah lebih mudah dalam pembuatan dan lebih mudah alam maintenance kode untuk kedepannya karena tidak perlu melakukan maintenance 2 kode sumber.
Kelebihan lain juga lebih praktis karena jaman sekarang hampir semua broses mendukung install PWA
Tampilan dari QR Code versi PWA seperti ini


Librari yang saya pakai menggunakan html5-qrcode, dan seperti ini contoh kode untuk menggunakannya
var html5QrcodeScanner;
document.addEventListener("DOMContentLoaded", function() {
const observer = new MutationObserver(function(mutations) {
let elemen_qr = document.getElementById('qrdiv');
let button_cancel = document.getElementsByClassName('o_form_button_cancel');
console.dir(button_cancel);
// disable camera untuk popup log dari ipm area
if (button_cancel[1]){
return;
}
let pestisida_0 = document.getElementById('pestisida_0');
if (pestisida_0){
elemen_qr.style.display = 'none';
return;
}
let action_checkout = document.getElementsByName('action_checkout');
if (action_checkout[0]){
return;
}
let elemen_reader = document.getElementById('reader__scan_region');
if (elemen_reader){
return;
}
if (elemen_qr) {
if (elemen_qr.style.display == 'none'){
console.log('3');
console.dir(elemen_qr);
return;
}
html5QrcodeScanner = new Html5QrcodeScanner("reader", { fps: 10, qrbox: 150 });
html5QrcodeScanner.render(onScanSuccess);
} else {
console.log('tidak ada');
}
});
observer.observe(document.body, {
childList: true,
attributes: true,
subtree: true
});
});
Kekurangan dari versi PWA adalah performance dan fitur yang tidak sebaik versi Aplikasi Mobile.
Baik versi APlikasi maupun versi PWA memiliki kelebihan dan kekurangan masing-masing, teman-teman bebas menentukan versi mana yang dipilih dan bisa juga kedua versi dipasang bersamaan.
Catatan : Versi Odoo 17