Files
saat-app/README.md
2026-09-17 20:40:59 +07:00

257 lines
8.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Aplikasi Catat Jual-Beli Saham — Odoo 17 + Flutter
Backend Odoo ERP (Community 17) untuk mencatat pembelian & penjualan saham,
diakses dari aplikasi **Flutter** (Android).
## Arsitektur
```
Flutter app (Android) ──JSON-RPC──► Odoo 17 (Python)
│ custom addon: saat_invest
▼
PostgreSQL 16
```
## Stack
| Layer | Teknologi | Port |
|---|---|---|
| Backend | Odoo 17 Community (`odoo:17.0`) | `18069` (host) |
| Database | PostgreSQL 16 (`postgres:16`) | internal (5432, tdk di-publish) |
| Mobile | Flutter (Android) | — |
## Struktur proyek
```
saat-app/
├── docker-compose.yml # Odoo 17 + PostgreSQL 16
├── .env # RAHASIA: password (jangan commit)
├── addons/ # custom addon buatan sendiri (saat_invest)
└── README.md
```
## Cara menjalankan
```bash
cd /home/ardhi/workspace/erp/odoo-app/saat-app
docker compose config # validasi
docker compose up -d # start
```
Akses UI: http://localhost:18069 — login `admin` dengan password
`ODOO_ADMIN_PASSWORD` di `.env`.
## Status
- ✅ Odoo 17 container jalan (port 18069), DB PostgreSQL 16 healthy
- ✅ JSON-RPC aktif (uid `admin` verified) — endpoint yang akan dipakai Flutter
- ✅ **Addon `saat_invest` terinstal** (model saham, transaksi, portofolio + seed 5 saham IDX)
- ✅ **Portofolio auto-sync**: otomatis diperbarui tiap transaksi ditambah/ubah/hapus
(tidak perlu tombol manual; buka menu Portofolio selalu datanya segar)
- ✅ **Live harga pasar (cron)**: ambil & update harga dari Yahoo Finance (.JK)
tiap 6 menit SAAT jam bursa IDX (08:45–16:00 WIB). Update hanya bila berubah.
- ✅ End-to-end teruji: buat beli/jual → portofolio ter-update → hitung avg cost & realized/unrealized P/L
- ⏳ Aplikasi Flutter (login, catat jual/beli, portfolio, P/L)
## Install / upgrade addon saat_invest
```bash
cd /home/ardhi/Application/saat-app
set -a && source .env && set +a
# install pertama kali
docker exec -e PASSWORD="$POSTGRES_PASSWORD" saat-odoo odoo \
-d "$POSTGRES_DB" --db_host=db --db_user="$POSTGRES_USER" \
--db_password="$POSTGRES_PASSWORD" --no-http --stop-after-init -i saat_invest
# upgrade setelah ubah kode
docker exec -e PASSWORD="$POSTGRES_PASSWORD" saat-odoo odoo \
-d "$POSTGRES_DB" --db_host=db --db_user="$POSTGRES_USER" \
--db_password="$POSTGRES_PASSWORD" --no-http --stop-after-init -u saat_invest
docker restart saat-odoo
```
> Catatan Odoo: `<list>` view di Odoo 17 kadang bermasalah, pakai `<tree>`
> (kompatibel lintas versi) seperti yang sudah dilakukan.
## Troubleshooting PermissionError sessions
Jika muncul:
```text
PermissionError: [Errno 13] Permission denied: '/var/lib/odoo/sessions'
```
Odoo 17 berjalan sebagai user `odoo` dengan UID/GID `101`. Perbaiki
ownership seluruh volume data Odoo dari container yang sedang berjalan:
```bash
cid=$(docker compose ps -q odoo)
docker exec --user root "$cid" sh -c \
'chown -R 101:101 /var/lib/odoo && \
chmod 755 /var/lib/odoo && chmod 700 /var/lib/odoo/sessions'
```
Verifikasi write access sebagai user Odoo, lalu restart dan cek log:
```bash
docker exec --user odoo "$cid" sh -c \
'touch /var/lib/odoo/sessions/.write-check && \
rm /var/lib/odoo/sessions/.write-check'
docker compose restart odoo
docker compose logs --since=30s odoo
```
Gunakan hanya satu mount volume utama berikut pada Compose:
```yaml
volumes:
- saat_odoo_filestore:/var/lib/odoo
```
Jangan menambahkan mount terpisah ke `/var/lib/odoo/session` (singular).
Path yang dipakai Odoo adalah `/var/lib/odoo/sessions` (plural). Jangan
menggunakan `chmod 777`; cukup berikan ownership kepada user Odoo.
## Rencana migrasi Odoo 17 ke Odoo 18
Migrasi major version harus mengubah schema database. Mengganti image secara
langsung dari `odoo:17.0` ke `odoo:18.0` **bukan** prosedur migrasi dan dapat
menyebabkan error seperti `column res_lang.short_time_format does not exist`.
Compose harus tetap menggunakan `odoo:17.0` sampai database selesai dimigrasi.
### 1. Persiapan dan backup
Pastikan `.env` terisi dan jangan commit file tersebut. Hentikan penulisan data,
lalu buat backup database dan filestore:
```bash
set -a && source .env && set +a
backup_dir="backups/odoo17-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$backup_dir"
docker compose exec -T db pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc \
> "$backup_dir/database.dump"
volume=$(docker inspect saat-odoo --format '{{range .Mounts}}{{if eq .Destination "/var/lib/odoo"}}{{.Name}}{{end}}{{end}}')
docker run --rm -v "$volume:/source:ro" -v "$PWD/$backup_dir:/backup" alpine \
sh -c 'tar czf /backup/filestore.tar.gz -C /source .'
```
Validasi backup dengan `pg_restore --list` dari image PostgreSQL 16 dan pastikan
arsip filestore berisi direktori `filestore/`.
### 2. Migrasi pada salinan
Jangan menguji migrasi pada volume produksi. Restore `database.dump` dan
`filestore.tar.gz` ke environment staging yang terpisah, lalu gunakan salah
satu jalur resmi berikut:
- Odoo Upgrade Service untuk database Enterprise.
- OpenUpgrade dengan branch yang sesuai untuk migrasi Community 17 ke 18.
Migrasikan database terlebih dahulu. Sesuaikan custom addon `saat_invest`
dengan API, view, security, dan dependency Odoo 18, lalu install/upgrade addon
di database staging hasil migrasi.
### 3. Validasi staging
Uji login, menu saham, create/update/delete transaksi, kalkulasi portofolio,
cron harga pasar, attachment/filestore, dan seluruh endpoint JSON-RPC yang
dipakai Flutter. Periksa log untuk `ERROR`, `Traceback`, `UndefinedColumn`, dan
`PermissionError`.
### 4. Cutover produksi
Setelah staging lulus, hentikan Odoo 17, buat backup final, restore atau jalankan
migrasi pada database produksi sesuai prosedur tool migrasi, kemudian ubah:
```yaml
image: odoo:18.0
```
Pastikan ownership volume sesuai user Odoo 18 sebelum start, jalankan
`docker compose up -d`, dan ulangi seluruh validasi staging.
### 5. Rollback
Jika migrasi gagal, jangan menjalankan Odoo 17 pada database yang sudah sebagian
dimigrasi. Hentikan stack, restore database dan filestore dari backup Odoo 17
ke volume/database terpisah, ubah image kembali ke `odoo:17.0`, lalu validasi
aplikasi sebelum cutover ulang.
## Cara menyelesaikan merge conflict Git
Contoh berikut menggabungkan branch `odoo18` ke `master`. Pastikan perubahan
lokal sudah disimpan atau di-commit sebelum memulai:
```bash
git status
git fetch origin
git switch master
git pull --ff-only origin master
git merge --no-ff odoo18
```
Jika merge conflict terjadi, lihat file yang belum terselesaikan:
```bash
git status
git diff --name-only --diff-filter=U
```
Buka setiap file tersebut dan cari marker berikut:
```text
[marker pembuka] perubahan dari branch saat ini
[marker pemisah] perubahan dari branch yang sedang di-merge
[marker penutup]
```
Hapus marker dan gabungkan isi yang benar secara manual. Jangan langsung
memilih seluruh file dari salah satu branch jika kedua perubahan diperlukan.
Untuk memilih satu sisi secara sengaja, gunakan:
```bash
# Pilih isi dari branch saat ini
git checkout --ours -- path/to/file
# Pilih isi dari branch yang sedang di-merge
git checkout --theirs -- path/to/file
```
Setelah semua conflict diperbaiki, validasi proyek sebelum commit:
```bash
git diff --check
docker compose config
git diff --name-only --diff-filter=U
```
Perintah terakhir harus menghasilkan output kosong. Kemudian stage file yang
sudah diselesaikan dan buat merge commit:
```bash
git add path/to/resolved-file
git add -u
git commit -m "Merge odoo18 branch into master"
git status --short --branch
git push origin master
```
Jika ingin membatalkan merge sebelum commit:
```bash
git merge --abort
```
Jangan commit `.env`, backup database, password, atau token ketika menyelesaikan
conflict. Periksa `git diff --cached` sebelum commit untuk memastikan rahasia
tidak ikut ter-stage.
## API untuk Flutter (via JSON-RPC `execute_kw`)
Semua melalui `POST /jsonrpc` dengan `{service:'object', method:'execute_kw'}`.
Login: `common.authenticate(db, user, pass)` → `uid`.
- List saham: `saat.saham search_read [domain] {fields}`
- Catat transaksi: `saat.transaksi create [{vals}]`
- List transaksi: `saat.transaksi search_read [domain] {fields}`
- **Rekalkulasi portofolio**: `saat.portofolio action_recalculate [[]]`
- Baca portofolio: `saat.portofolio search_read [domain] {fields}`
(sisa_lembar, avg_cost, total_beli_biaya, realized_pl, unrealized_pl, nilai_sekarang)
## Catatan keamanan
- `.env` berisi rahasia → **tidak boleh di-commit** (sudah di `.gitignore`)
- PostgreSQL tidak di-publish ke host, hanya akses antar-container
- Ganti `ADMIN_PASSWD` segera setelah setup awal