diff options
| author | Indoteknik . <it@fixcomart.co.id> | 2025-09-02 17:35:47 +0700 |
|---|---|---|
| committer | Indoteknik . <it@fixcomart.co.id> | 2025-09-02 17:35:47 +0700 |
| commit | d43eb7ff8ffd4b11120a7354295e86736135344a (patch) | |
| tree | 0e6bce3428149b694f12e22e29ba0ca561271fb9 | |
| parent | a35dcc5907500e5189516459160c972bb72e1686 (diff) | |
(andri) add menu surat piutang
| -rwxr-xr-x | indoteknik_custom/__manifest__.py | 1 | ||||
| -rwxr-xr-x | indoteknik_custom/models/__init__.py | 3 | ||||
| -rw-r--r-- | indoteknik_custom/models/letter_receivable.py | 90 | ||||
| -rwxr-xr-x | indoteknik_custom/security/ir.model.access.csv | 4 | ||||
| -rw-r--r-- | indoteknik_custom/views/ir_sequence.xml | 9 | ||||
| -rw-r--r-- | indoteknik_custom/views/letter_receivable.xml | 79 |
6 files changed, 184 insertions, 2 deletions
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py index 9ebab15e..e300670a 100755 --- a/indoteknik_custom/__manifest__.py +++ b/indoteknik_custom/__manifest__.py @@ -178,6 +178,7 @@ # 'views/refund_sale_order.xml', 'views/update_date_planned_po_wizard_view.xml', 'views/unpaid_invoice_view.xml', + 'views/letter_receivable.xml', ], 'demo': [], 'css': [], diff --git a/indoteknik_custom/models/__init__.py b/indoteknik_custom/models/__init__.py index ba3dbad9..c8910669 100755 --- a/indoteknik_custom/models/__init__.py +++ b/indoteknik_custom/models/__init__.py @@ -157,4 +157,5 @@ from . import refund_sale_order from . import tukar_guling from . import tukar_guling_po from . import update_date_planned_po_wizard -from . import unpaid_invoice_view
\ No newline at end of file +from . import unpaid_invoice_view +from . import letter_receivable
\ No newline at end of file diff --git a/indoteknik_custom/models/letter_receivable.py b/indoteknik_custom/models/letter_receivable.py new file mode 100644 index 00000000..541f64ff --- /dev/null +++ b/indoteknik_custom/models/letter_receivable.py @@ -0,0 +1,90 @@ +from odoo import models, fields, api + +class SuratPiutang(models.Model): + _name = "surat.piutang" + _description = "Surat Piutang" + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string="Nomor Surat", readonly=True, copy=False) + partner_id = fields.Many2one("res.partner", string="Customer", required=True) + tujuan_nama = fields.Char(string="Nama Tujuan") + tujuan_email = fields.Char(string="Email Tujuan") + perihal = fields.Selection([ + ('sp1', 'Surat Peringatan Piutang'), + ('sp2', 'Surat Peringatan Piutang ke-2'), + ('sp3', 'Surat Peringatan Piutang ke-3') + ], string="Perihal", required=True, tracking=True) + line_ids = fields.One2many("surat.piutang.line", "surat_id", string="Invoice Lines") + state = fields.Selection([ + ("draft", "Draft"), + ("sent", "Sent") + ], default="draft", tracking=True) + send_date = fields.Datetime(string="Tanggal Kirim", tracking=True) + + currency_id = fields.Many2one('res.currency') + + # Grand total (total sisa semua line yang dicentang) + grand_total = fields.Monetary( + string='Total Sisa', + currency_field='currency_id', + compute='_compute_grand_total', + ) + + @api.depends('line_ids.amount_residual', 'line_ids.selected') + def _compute_grand_total(self): + for rec in self: + rec.grand_total = sum( + line.amount_residual or 0.0 for line in rec.line_ids if line.selected + ) + + @api.onchange('partner_id') + def _onchange_partner_id(self): + if self.partner_id: + invoice_lines = self.env['unpaid.invoice.view'].search( + [('partner_id', '=', self.partner_id.id)], + order='new_invoice_day_to_due asc' + ) + lines = [(0, 0, { + 'invoice_view_id': inv.id, + 'invoice_id': inv.invoice_id.id, + 'invoice_number': inv.invoice_number, + 'invoice_date': inv.invoice_date, + 'invoice_date_due': inv.invoice_date_due, + 'invoice_day_to_due': inv.invoice_day_to_due, + 'ref': inv.ref, + 'amount_residual': inv.amount_residual, + 'currency_id': inv.currency_id.id, + 'payment_term_id': inv.payment_term_id.id, + 'selected': False + }) for inv in invoice_lines] + self.line_ids = lines + + @api.model + def create(self, vals): + # Generate nomor surat otomatis + if not vals.get("name"): + seq = self.env["ir.sequence"].next_by_code("surat.piutang") or "000" + today = fields.Date.today() + bulan_romawi = ["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII"][today.month-1] + tahun = today.strftime("%y") + vals["name"] = f"{seq}/LO/FAT/IDG/{bulan_romawi}/{tahun}" + + return super().create(vals) + +class SuratPiutangLine(models.Model): + _name = 'surat.piutang.line' + _description = 'Surat Piutang Line' + + surat_id = fields.Many2one('surat.piutang', string='Surat Piutang', ondelete='cascade') + invoice_view_id = fields.Many2one('unpaid.invoice.view', string='Unpaid Invoice') + invoice_id = fields.Many2one('account.move', string='Invoice') + selected = fields.Boolean(string="Pilih", default=False) + + invoice_number = fields.Char(string='Invoice Number') + invoice_date = fields.Date(string='Invoice Date') + invoice_date_due = fields.Date(string='Due Date') + invoice_day_to_due = fields.Integer(string='Day to Due') + ref = fields.Char(string='Reference') + amount_residual = fields.Monetary(string='Amount Due Signed') + currency_id = fields.Many2one('res.currency') + payment_term_id = fields.Many2one('account.payment.term', string='Payment Terms') diff --git a/indoteknik_custom/security/ir.model.access.csv b/indoteknik_custom/security/ir.model.access.csv index 4649c743..25273893 100755 --- a/indoteknik_custom/security/ir.model.access.csv +++ b/indoteknik_custom/security/ir.model.access.csv @@ -196,4 +196,6 @@ access_purchase_order_update_date_wizard,access.purchase.order.update.date.wizar access_sync_promise_date_wizard,access.sync.promise.date.wizard,model_sync_promise_date_wizard,base.group_user,1,1,1,1 access_sync_promise_date_wizard_line,access.sync.promise.date.wizard.line,model_sync_promise_date_wizard_line,base.group_user,1,1,1,1 access_change_date_planned_wizard,access.change.date.planned.wizard,model_change_date_planned_wizard,,1,1,1,1 -access_unpaid_invoice_view,access.unpaid.invoice.view,model_unpaid_invoice_view,base.group_user,1,1,1,1
\ No newline at end of file +access_unpaid_invoice_view,access.unpaid.invoice.view,model_unpaid_invoice_view,base.group_user,1,1,1,1 +access_surat_piutang_user,surat.piutang user,model_surat_piutang,base.group_user,1,1,1,1 +access_surat_piutang_line_user,surat.piutang.line user,model_surat_piutang_line,base.group_user,1,1,1,1
\ No newline at end of file diff --git a/indoteknik_custom/views/ir_sequence.xml b/indoteknik_custom/views/ir_sequence.xml index 94c2cd07..4b8fec53 100644 --- a/indoteknik_custom/views/ir_sequence.xml +++ b/indoteknik_custom/views/ir_sequence.xml @@ -228,5 +228,14 @@ <field name="number_increment">1</field> <field name="active">True</field> </record> + + <record id="seq_surat_piutang" model="ir.sequence"> + <field name="name">Surat Piutang</field> + <field name="code">surat.piutang</field> + <field name="prefix"></field> <!-- format manual di model --> + <field name="padding">3</field> + <field name="number_next">1</field> + <field name="number_increment">1</field> + </record> </data> </odoo>
\ No newline at end of file diff --git a/indoteknik_custom/views/letter_receivable.xml b/indoteknik_custom/views/letter_receivable.xml new file mode 100644 index 00000000..72eae640 --- /dev/null +++ b/indoteknik_custom/views/letter_receivable.xml @@ -0,0 +1,79 @@ +<odoo> + <!-- Tree View --> + <record id="view_surat_piutang_tree" model="ir.ui.view"> + <field name="name">surat.piutang.tree</field> + <field name="model">surat.piutang</field> + <field name="arch" type="xml"> + <tree string="Surat Piutang"> + <field name="name"/> + <field name="partner_id"/> + <field name="perihal"/> + <field name="state"/> + <field name="send_date"/> + <field name="line_ids" widget="one2many_list"/> + </tree> + </field> + </record> + + <!-- Form View --> + <record id="view_surat_piutang_form" model="ir.ui.view"> + <field name="name">surat.piutang.form</field> + <field name="model">surat.piutang</field> + <field name="arch" type="xml"> + <form string="Surat Piutang"> + <header> + <field name="state" widget="statusbar" statusbar_visible="draft,sent"/> + <!-- <button name="action_send_surat" type="object" string="Kirim Surat" + states="draft" class="btn-primary"/> --> + </header> + <sheet> + <group> + <field name="name" readonly="1"/> + <field name="partner_id" options="{'no_create': True}"/> + <field name="perihal"/> + <field name="tujuan_nama"/> + <field name="tujuan_email"/> + <field name="send_date" readonly="1"/> + </group> + <notebook> + <page string="Invoice Lines"> + <field name="line_ids"> + <tree editable="bottom"> + <field name="selected"/> + <field name="invoice_number" readonly="1" force_save="1"/> + <field name="ref" readonly="1" force_save="1"/> + <field name="invoice_date" readonly="1" force_save="1"/> + <field name="invoice_date_due" readonly="1" force_save="1"/> + <field name="invoice_day_to_due" readonly="1" force_save="1"/> + <field name="amount_residual" readonly="1" force_save="1" sum="Grand Total"/> + <!-- <field name="currency_id" readonly="1" force_save="1"/> --> + <field name="payment_term_id" readonly="1" force_save="1"/> + </tree> + </field> + </page> + </notebook> + </sheet> + </form> + </field> + </record> + + <!-- Menu --> + <record id="menu_surat_piutang_root" model="ir.ui.menu"> + <field name="name">Surat Piutang</field> + <field name="parent_id" ref="account.menu_finance"/> + <field name="sequence" eval="10"/> + </record> + + <record id="action_surat_piutang" model="ir.actions.act_window"> + <field name="name">Surat Piutang</field> + <field name="res_model">surat.piutang</field> + <field name="view_mode">tree,form</field> + <field name="view_id" ref="view_surat_piutang_tree"/> + </record> + + <menuitem id="menu_surat_piutang" + name="Surat Piutang" + parent="account.menu_finance_receivables" + action="action_surat_piutang" + sequence="1"/> +</odoo> |
