Files
saat-app/addons/saat_invest/models/transaksi.py
Alex Ardhian 3417e077c7 Portofolio auto-sync: otomatis update saat transaksi berubah + tombol Rekalkulasi
- saat.transaksi.create/write/unlink memicu rekalkulasi portofolio otomatis
  (buka menu Portofolio selalu data segar, tanpa klik manual)
- Tambah tombol 'Rekalkulasi' di form portofolio sbg cadangan (action_recalc_click)
- Perbaiki help teks portofolio yg sebelumnya menyesatkan
2026-09-02 13:30:42 +07:00

73 lines
2.8 KiB
Python

# -*- coding: utf-8 -*-
from odoo import api, fields, models
class SaatTransaksi(models.Model):
"""Catat setiap pembelian / penjualan saham."""
_name = 'saat.transaksi'
_description = "Transaksi Jual/Beli Saham"
_order = 'tanggal desc, id desc'
TIPE = [('buy', 'Beli'), ('sell', 'Jual')]
name = fields.Char(string="Referensi", compute='_compute_name', store=True)
tanggal = fields.Date(string="Tanggal", required=True, default=fields.Date.context_today)
tipe = fields.Selection(TIPE, string="Tipe", required=True, default='buy')
saham_id = fields.Many2one('saat.saham', string="Saham", required=True, ondelete='restrict')
volume = fields.Integer(string="Jumlah Lembar", required=True)
harga = fields.Monetary(string="Harga/Lembar", currency_field='currency_id', required=True)
fee = fields.Monetary(string="Biaya (Komisi/PPN)", currency_field='currency_id', default=0.0)
total = fields.Monetary(
string="Total Biaya", currency_field='currency_id',
compute='_compute_total', store=True)
catatan = fields.Text(string="Catatan")
user_id = fields.Many2one('res.users', string="Pencatat", default=lambda self: self.env.user)
currency_id = fields.Many2one(
'res.currency', string="Mata Uang", default=lambda self: self._default_currency())
@api.model
def _default_currency(self):
# IDR
return self.env.ref('base.IDR', raise_if_not_found=False) or self.env.company.currency_id
@api.depends('tanggal', 'tipe', 'saham_id')
def _compute_name(self):
for r in self:
ticker = r.saham_id.name or ''
tipe_label = dict(self.TIPE).get(r.tipe, '')
r.name = f"{r.tanggal or ''} {tipe_label} {ticker}"
@api.depends('volume', 'harga', 'fee', 'tipe')
def _compute_total(self):
for r in self:
r.total = (r.volume or 0) * (r.harga or 0) + (r.fee or 0)
@api.constrains('volume', 'harga')
def _check_positive(self):
for r in self:
if r.volume <= 0:
raise models.ValidationError("Volume harus lebih dari 0.")
if r.harga < 0:
raise models.ValidationError("Harga tidak boleh negatif.")
# --- auto-sync portofolio: setiap transaksi berubah, portofolio diperbarui ---
def _resync_portofolio(self):
"""Rekalkulasi portofolio dari seluruh transaksi (idempoten)."""
self.env['saat.portofolio'].action_recalculate()
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
res._resync_portofolio()
return res
def write(self, vals):
res = super().write(vals)
self._resync_portofolio()
return res
def unlink(self):
res = super().unlink()
self._resync_portofolio()
return res