summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <it@fixcomart.co.id>2025-09-17 16:29:04 +0700
committerunknown <it@fixcomart.co.id>2025-09-17 16:29:04 +0700
commitaaff9c4fa47ca2ee114ab1dc3a8140aec300ce26 (patch)
tree7a07de89b48ccb532d79d2773d408f1af84b8847
parent83608402d79a4b90d43a377aefbffbd17ae778c9 (diff)
(andri) button surat lanjutan + fix bug
-rwxr-xr-xindoteknik_custom/__manifest__.py2
-rw-r--r--indoteknik_custom/models/letter_receivable.py83
-rw-r--r--indoteknik_custom/views/letter_receivable.xml48
3 files changed, 113 insertions, 20 deletions
diff --git a/indoteknik_custom/__manifest__.py b/indoteknik_custom/__manifest__.py
index 806d5706..cf7cf1e4 100755
--- a/indoteknik_custom/__manifest__.py
+++ b/indoteknik_custom/__manifest__.py
@@ -181,7 +181,7 @@
'views/update_date_planned_po_wizard_view.xml',
'views/unpaid_invoice_view.xml',
'views/letter_receivable.xml',
- 'views/letter_receivable_mail_template.xml'
+ 'views/letter_receivable_mail_template.xml',
# 'views/reimburse.xml',
'views/sj_tele.xml'
],
diff --git a/indoteknik_custom/models/letter_receivable.py b/indoteknik_custom/models/letter_receivable.py
index 84a3fc35..b1c82b12 100644
--- a/indoteknik_custom/models/letter_receivable.py
+++ b/indoteknik_custom/models/letter_receivable.py
@@ -32,11 +32,11 @@ class SuratPiutang(models.Model):
state = fields.Selection([
("draft", "Draft"),
("waiting_approval_sales", "Menunggu Approval Sales Manager"),
- ("waiting_approval_pimpinan", "Menunggu Approval Pimpinan"),
+ ("waiting_approval_pimpinan", "Menunggu Approval Pimpinan / Kirim Surat"),
("sent", "Approved & Sent")
], default="draft", tracking=True)
send_date = fields.Datetime(string="Tanggal Kirim", tracking=True)
- seven_days_after_sent_date = fields.Char(string="7 Hari Setelah Tanggal Kirim", tracking=True)
+ seven_days_after_sent_date = fields.Char(string="7 Hari Setelah Tanggal Kirim")
periode_invoices_terpilih = fields.Char(
string="Periode Invoices Terpilih",
compute="_compute_periode_invoices",
@@ -62,6 +62,12 @@ class SuratPiutang(models.Model):
sales_person_id = fields.Many2one('res.users', string='Salesperson', related='partner_id.user_id', readonly=True)
+ PERIHAL_SEQUENCE = {
+ "penagihan": "sp1",
+ "sp1": "sp2",
+ "sp2": "sp3",
+ }
+
@api.onchange('partner_id')
def _onchange_partner_id_domain(self):
unpaid_partner_ids = self.env['unpaid.invoice.view'].search([]).mapped('partner_id.id')
@@ -74,9 +80,68 @@ class SuratPiutang(models.Model):
for rec in self:
rec.perihal_label = dict(self._fields['perihal'].selection).get(rec.perihal, '')
- # def action_print_surat_piutang(self):
- # self.ensure_one()
- # return self.env.ref('indoteknik_custom.report_surat_piutang_formal').report_action(self)
+ def action_create_next_letter(self):
+ for rec in self:
+ if rec.state != "sent":
+ raise UserError("Surat harus sudah terkirim sebelum bisa membuat surat lanjutan.")
+
+ next_perihal = self.PERIHAL_SEQUENCE.get(rec.perihal)
+ if not next_perihal:
+ raise UserError("Surat ini sudah pada tahap terakhir (SP3). Tidak bisa membuat lanjutan lagi.")
+
+ existing = self.search([
+ ('partner_id', '=', rec.partner_id.id),
+ ('perihal', '=', next_perihal),
+ ('state', '!=', 'draft') # optional: cek hanya yang sudah dikirim
+ ])
+ if existing:
+ raise UserError(f"Surat lanjutan {dict(self._fields['perihal'].selection).get(next_perihal)} "
+ f"untuk customer ini sudah dibuat: {', '.join(existing.mapped('name'))}")
+
+ # copy surat lama
+ new_vals = {
+ "tujuan_nama": rec.tujuan_nama,
+ "tujuan_email": rec.tujuan_email,
+ "perihal": next_perihal,
+ "partner_id": rec.partner_id.id,
+ "line_ids": [(0, 0, {
+ 'invoice_id': line.invoice_id.id,
+ 'invoice_number': line.invoice_number,
+ 'invoice_date': line.invoice_date,
+ 'invoice_date_due': line.invoice_date_due,
+ 'invoice_day_to_due': line.invoice_day_to_due,
+ 'new_invoice_day_to_due': line.new_invoice_day_to_due,
+ 'ref': line.ref,
+ 'amount_residual': line.amount_residual,
+ 'currency_id': line.currency_id.id,
+ 'payment_term_id': line.payment_term_id.id,
+ 'date_kirim_tukar_faktur': line.date_kirim_tukar_faktur,
+ 'date_terima_tukar_faktur': line.date_terima_tukar_faktur,
+ 'invoice_user_id': line.invoice_user_id.id,
+ 'sale_id': line.sale_id.id,
+ "selected": line.selected,
+ }) for line in rec.line_ids],
+ }
+ new_letter = self.create(new_vals)
+ self.env.user.notify_info(
+ message=f"Surat lanjutan {dict(self._fields['perihal'].selection).get(next_perihal)} berhasil dibuat ({new_letter.name}).",
+ title="Informasi",
+ sticky=False
+ )
+ new_letter.message_post(
+ body=
+ f"Surat lanjutan dengan perihal <b>{dict(self._fields['perihal'].selection).get(next_perihal)}</b> "
+ f"berhasil dibuat berdasarkan surat sebelumnya.<br/>"
+ f"Nomor Surat: <b>{new_letter.name}</b>"
+ )
+ rec.message_post(
+ body=(
+ f"Surat lanjutan dengan perihal <b>{dict(self._fields['perihal'].selection).get(next_perihal)}</b> "
+ f"telah dibuat sebagai kelanjutan dari surat ini.<br/>"
+ f"Nomor Surat Baru: <a href='/web#id={new_letter.id}&model=surat.piutang&view_type=form'><b>{new_letter.name}</b></a>"
+ )
+ )
+ return True
@api.depends("line_ids.selected", "line_ids.invoice_date")
@@ -170,7 +235,7 @@ class SuratPiutang(models.Model):
now_utc = now_wib.astimezone(pytz.UTC).replace(tzinfo=None)
rec.send_date = now_utc
rec.action_send_letter()
- rec.message_post(body="Surat Penagihan disetujui Pimpinan dan berhasil dikirim.")
+ rec.message_post(body="Surat Penagihan disetujui dan berhasil dikirim.")
self.env.user.notify_info(
message=f"Surat piutang {rec.name} berhasil dikirim ke {rec.partner_id.name} ({rec.tujuan_email})",
@@ -268,7 +333,11 @@ class SuratPiutang(models.Model):
'reply_to': 'finance@indoteknik.co.id',
}
- template.send_mail(self.id, force_send=True, email_values=values)
+ template.with_context(mail_post_autofollow=False).send_mail(
+ self.id,
+ force_send=True,
+ email_values=values
+ )
_logger.info(
f"Surat Piutang {self.name} terkirim ke {self.tujuan_email} "
diff --git a/indoteknik_custom/views/letter_receivable.xml b/indoteknik_custom/views/letter_receivable.xml
index 1a8980a3..86c28765 100644
--- a/indoteknik_custom/views/letter_receivable.xml
+++ b/indoteknik_custom/views/letter_receivable.xml
@@ -26,7 +26,17 @@
<form string="Surat Piutang">
<header>
<field name="state" widget="statusbar" statusbar_visible="draft,waiting_approval_sales,waiting_approval_pimpinan,sent"/>
- <button name="action_approve" type="object" string="Approve" class="btn-primary"/>
+ <button name="action_approve"
+ type="object"
+ string="Approve"
+ class="btn-primary"
+ attrs="{'invisible':[('state', '=', 'sent')]}"/>
+ <button name="action_create_next_letter"
+ string="Buat Surat Lanjutan"
+ type="object"
+ class="btn-primary"
+
+ />
<!-- <button name="action_send_letter" type="object" string="Email Send" class="btn-primary"/> -->
</header>
<div class="alert alert-info"
@@ -38,14 +48,28 @@
<div class="alert alert-info"
role="alert"
style="height: 40px; margin-bottom:0px;"
- attrs="{'invisible':[('state', '!=', 'waiting_approval')]}">
- <strong>Info!</strong> Surat piutang telah diajukan &amp; surat otomatis terkirim bila telah di Approved (khusus SP1,SP2,SP3 yang bisa approved hanya pimpinan).
+ attrs="{'invisible': ['|', ('perihal', '!=', 'penagihan'), ('state', '!=', 'waiting_approval_pimpinan')]}">
+ <strong>Info!</strong> Surat resmi penagihan telah diajukan &amp; surat otomatis terkirim bila telah di approve.
+ </div>
+ <div class="alert alert-info"
+ role="alert"
+ style="height: 40px; margin-bottom:0px;"
+ attrs="{'invisible':[('state', '!=', 'waiting_approval_sales')]}">
+ <strong>Info!</strong> Surat peringatan piutang ini sedang menunggu persetujuan dari <b>Sales Manager</b>.
+ Silakan hubungi Sales Manager terkait untuk melakukan approval agar proses dapat dilanjutkan ke tahap berikutnya.
+ </div>
+ <div class="alert alert-info"
+ role="alert"
+ style="margin-bottom:0px;"
+ attrs="{'invisible': ['|', ('perihal', '=', 'penagihan'), ('state', '!=', 'waiting_approval_pimpinan')]}">
+ <strong>Info!</strong> Surat peringatan piutang ini sedang menunggu persetujuan dari <b>Pimpinan</b>.
+ Silakan hubungi Pimpinan terkait untuk melakukan approval agar surat dapat terkirim otomatis ke customer.
</div>
<div class="alert alert-success"
role="alert"
style="height: 40px; margin-bottom:0px;"
- attrs="{'invisible':[('state', '!=', 'sent')]}">
- Surat Piutang berhasil terkirim.
+ attrs="{'invisible': ['|', ('perihal', '!=', 'sp3'), ('state', 'not in', ['draft', 'sent'])]}">
+ Surat Piutang berhasil terkirim dan silahkan klik tombol 'Buat Surat Lanjutan' untuk membuat surat piutang lanjutan.
</div>
<sheet>
<div class="oe_title">
@@ -55,10 +79,10 @@
</div>
<group colspan="2">
<group>
- <field name="tujuan_nama"/>
- <field name="tujuan_email"/>
- <field name="perihal"/>
- <field name="partner_id" options="{'no_create': True}"/>
+ <field name="tujuan_nama" attrs="{'readonly':[('state','=','sent')]}"/>
+ <field name="tujuan_email" attrs="{'readonly':[('state','=','sent')]}"/>
+ <field name="perihal" attrs="{'readonly':[('state','=','sent')]}"/>
+ <field name="partner_id" options="{'no_create': True}" attrs="{'readonly':[('state','=','sent')]}"/>
</group>
<group>
<field name="payment_difficulty"/>
@@ -66,13 +90,13 @@
<field name="send_date" readonly="1"/>
</group>
</group>
- <group>
+ <!-- <group>
<button name="action_refresh_lines"
string="Refresh Invoices"
type="object"
class="btn-primary"
help="Refresh Invoices agar data tetap update"/>
- </group>
+ </group> -->
<notebook>
<page string="Invoice Lines">
<div class="alert alert-info"
@@ -105,7 +129,7 @@
help="Refresh Invoices agar data tetap update"/>
</div>
</div>
- <field name="line_ids">
+ <field name="line_ids" attrs="{'readonly': [('state', '=', 'sent')]}">
<tree editable="bottom" create="false" delete="false">
<field name="selected"/>
<field name="invoice_id" readonly="1" optional="hide" force_save="1"/>