Aplikasi catat jual-beli saham: Odoo 17 + Postgres 16 + addon saat_invest

- docker-compose.yml: odoo:17.0 (port 8069) + postgres:16 (internal, no publish)
- Addon saat_invest: model saat.saham / saat.transaksi / saat.portofolio
  - P/L computed (realized FIFO, unrealized dari harga_sekarang)
  - action_recalculate() endpoint untuk Flutter
  - seed 5 saham IDX (BBRI, TLKM, BBCA, ASII, PTBA)
- JSON-RPC end-to-end terverifikasi: create beli/jual -> recalculate -> portfolio
  (avg_cost 4525, realized 65000, unrealized 220000, nilai 3840000)
- PLAN.md: rancangan disetujui Bozz
- Login Odoo admin/admin (ganti password master di .env, jangan commit)
This commit is contained in:
2026-09-02 11:23:39 +07:00
commit d657a0a8f0
19 changed files with 608 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_saat_portofolio_list" model="ir.ui.view">
<field name="name">saat.portofolio.list</field>
<field name="model">saat.portofolio</field>
<field name="arch" type="xml">
<tree string="Portofolio Saham" create="false" delete="false">
<field name="saham_id"/>
<field name="sisa_lembar"/>
<field name="avg_cost"/>
<field name="harga_sekarang"/>
<field name="nilai_sekarang"/>
<field name="realized_pl" widget="monetary"/>
<field name="unrealized_pl" widget="monetary"/>
</tree>
</field>
</record>
<record id="view_saat_portofolio_form" model="ir.ui.view">
<field name="name">saat.portofolio.form</field>
<field name="model">saat.portofolio</field>
<field name="arch" type="xml">
<form string="Portofolio">
<sheet>
<group>
<field name="saham_id" readonly="1"/>
<field name="harga_sekarang"/>
</group>
<group string="Posisi">
<group>
<field name="total_beli_lembar"/>
<field name="total_beli_biaya"/>
<field name="total_jual_lembar"/>
<field name="total_jual_hasil"/>
</group>
<group>
<field name="sisa_lembar"/>
<field name="avg_cost"/>
<field name="nilai_sekarang"/>
<field name="realized_pl"/>
<field name="unrealized_pl"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_saat_portofolio" model="ir.actions.act_window">
<field name="name">Portofolio</field>
<field name="res_model">saat.portofolio</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Klik <b>Rekalkulasi</b> (menu Form) untuk memperbarui posisi dari transaksi.
</p>
</field>
</record>
<menuitem id="menu_saat_portofolio" name="Portofolio" parent="menu_saat_root"
action="action_saat_portofolio" sequence="30"/>
</odoo>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_saat_saham_list" model="ir.ui.view">
<field name="name">saat.saham.list</field>
<field name="model">saat.saham</field>
<field name="arch" type="xml">
<tree string="Daftar Saham" create="true">
<field name="name"/>
<field name="perusahaan"/>
<field name="bursa"/>
<field name="sector"/>
</tree>
</field>
</record>
<record id="view_saat_saham_form" model="ir.ui.view">
<field name="name">saat.saham.form</field>
<field name="model">saat.saham</field>
<field name="arch" type="xml">
<form string="Saham">
<sheet>
<group>
<field name="name"/>
<field name="perusahaan"/>
<field name="bursa"/>
<field name="sector"/>
<field name="active"/>
</group>
<notebook>
<page string="Transaksi">
<field name="transaksi_ids">
<tree>
<field name="tanggal"/>
<field name="tipe"/>
<field name="volume"/>
<field name="harga"/>
<field name="total"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="action_saat_saham" model="ir.actions.act_window">
<field name="name">Saham</field>
<field name="res_model">saat.saham</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">Daftar saham/emiten yang dicatat.</p>
</field>
</record>
<menuitem id="menu_saat_root" name="Investasi Saham" sequence="50"/>
<menuitem id="menu_saat_saham" name="Saham" parent="menu_saat_root"
action="action_saat_saham" sequence="10"/>
</odoo>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_saat_transaksi_list" model="ir.ui.view">
<field name="name">saat.transaksi.list</field>
<field name="model">saat.transaksi</field>
<field name="arch" type="xml">
<tree string="Transaksi Jual/Beli" create="true">
<field name="tanggal"/>
<field name="tipe"/>
<field name="saham_id"/>
<field name="volume"/>
<field name="harga"/>
<field name="fee"/>
<field name="total"/>
</tree>
</field>
</record>
<record id="view_saat_transaksi_form" model="ir.ui.view">
<field name="name">saat.transaksi.form</field>
<field name="model">saat.transaksi</field>
<field name="arch" type="xml">
<form string="Transaksi">
<sheet>
<group>
<group>
<field name="tanggal"/>
<field name="tipe"/>
<field name="saham_id"/>
<field name="volume"/>
<field name="harga"/>
</group>
<group>
<field name="fee"/>
<field name="total" readonly="1"/>
<field name="catatan" colspan="2"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_saat_transaksi" model="ir.actions.act_window">
<field name="name">Transaksi</field>
<field name="res_model">saat.transaksi</field>
<field name="view_mode">list,form</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">Catat pembelian / penjualan saham di sini.</p>
</field>
</record>
<menuitem id="menu_saat_transaksi" name="Transaksi" parent="menu_saat_root"
action="action_saat_transaksi" sequence="20"/>
</odoo>