summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/account_move.py
diff options
context:
space:
mode:
Diffstat (limited to 'indoteknik_custom/models/account_move.py')
-rw-r--r--indoteknik_custom/models/account_move.py227
1 files changed, 216 insertions, 11 deletions
diff --git a/indoteknik_custom/models/account_move.py b/indoteknik_custom/models/account_move.py
index 30de67be..1a6fad1c 100644
--- a/indoteknik_custom/models/account_move.py
+++ b/indoteknik_custom/models/account_move.py
@@ -1,5 +1,6 @@
from odoo import models, api, fields
from odoo.exceptions import AccessError, UserError, ValidationError
+from markupsafe import escape as html_escape
from datetime import timedelta, date, datetime
from pytz import timezone, utc
import logging
@@ -8,12 +9,15 @@ import PyPDF2
import os
import re
from terbilang import Terbilang
+from collections import defaultdict
+from odoo.tools.misc import formatLang
_logger = logging.getLogger(__name__)
class AccountMove(models.Model):
_inherit = 'account.move'
+ _description = 'Account Move'
invoice_day_to_due = fields.Integer(string="Day to Due", compute="_compute_invoice_day_to_due")
bill_day_to_due = fields.Date(string="Day to Due", compute="_compute_bill_day_to_due")
date_send_fp = fields.Datetime(string="Tanggal Kirim Faktur Pajak")
@@ -67,13 +71,189 @@ class AccountMove(models.Model):
is_hr = fields.Boolean(string="Is HR?", default=False)
purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order')
length_of_payment = fields.Integer(string="Length of Payment", compute='compute_length_of_payment')
+ reklas_misc_id = fields.Many2one('account.move', string='Journal Entries Reklas')
+ # Di model account.move
+ bill_id = fields.Many2one('account.move', string='Vendor Bill', domain=[('move_type', '=', 'in_invoice')], help='Bill asal dari proses reklas ini')
+ down_payment = fields.Boolean('Down Payments?')
+ refund_id = fields.Many2one('refund.sale.order', string='Refund Reference')
+ refund_so_ids = fields.Many2many(
+ 'sale.order',
+ 'account_move_sale_order_rel',
+ 'move_id',
+ 'sale_order_id',
+ string='Group SO Number'
+ )
+
+ refund_so_links = fields.Html(
+ string="Group SO Numbers",
+ compute="_compute_refund_so_links",
+ )
+
+ has_refund_so = fields.Boolean(
+ string='Has Refund SO',
+ compute='_compute_has_refund_so',
+ )
+
+ # def name_get(self):
+ # result = []
+ # for move in self:
+ # if move.move_type == 'entry':
+ # # Jika masih draft, tampilkan 'Draft CAB'
+ # if move.state == 'draft':
+ # label = 'Draft CAB'
+ # else:
+ # label = move.name
+ # result.append((move.id, label))
+ # else:
+ # # Untuk invoice dan lainnya, pakai default
+ # result.append((move.id, move.display_name))
+ # return result
+
+ # def send_due_invoice_reminder(self):
+ # today = fields.Date.today()
+ # target_dates = [
+ # today - timedelta(days=7),
+ # today - timedelta(days=3),
+ # today,
+ # today + timedelta(days=3),
+ # today + timedelta(days=7),
+ # ]
+
+ # partner = self.env['res.partner'].search([('name', 'ilike', 'BANGUNAN TEKNIK GRUP')], limit=1)
+ # if not partner:
+ # _logger.info("Partner tidak ditemukan.")
+ # return
+
+ # invoices = self.env['account.move'].search([
+ # ('move_type', '=', 'out_invoice'),
+ # ('state', '=', 'posted'),
+ # ('payment_state', 'not in', ['paid','in_payment', 'reversed']),
+ # ('invoice_date_due', 'in', target_dates),
+ # ('partner_id', '=', partner.id),
+ # ])
+
+ # _logger.info(f"Invoices tahap 1: {invoices}")
+
+ # invoices = invoices.filtered(
+ # lambda inv: inv.invoice_payment_term_id and 'tempo' in (inv.invoice_payment_term_id.name or '').lower()
+ # )
+ # _logger.info(f"Invoices tahap 2: {invoices}")
+
+ # if not invoices:
+ # _logger.info(f"Tidak ada invoice yang due untuk partner: {partner.name}")
+ # return
+
+ # grouped = {}
+ # for inv in invoices:
+ # grouped.setdefault(inv.partner_id, []).append(inv)
+
+ # template = self.env.ref('indoteknik_custom.mail_template_invoice_due_reminder')
+
+ # for partner, invs in grouped.items():
+ # if not partner.email:
+ # _logger.info(f"Partner {partner.name} tidak memiliki email")
+ # continue
+
+ # invoice_table_rows = ""
+ # for inv in invs:
+ # days_to_due = (inv.invoice_date_due - today).days if inv.invoice_date_due else 0
+ # invoice_table_rows += f"""
+ # <tr>
+ # <td>{inv.name}</td>
+ # <td>{fields.Date.to_string(inv.invoice_date) or '-'}</td>
+ # <td>{fields.Date.to_string(inv.invoice_date_due) or '-'}</td>
+ # <td>{days_to_due}</td>
+ # <td>{formatLang(self.env, inv.amount_total, currency_obj=inv.currency_id)}</td>
+ # <td>{inv.ref or '-'}</td>
+ # </tr>
+ # """
+
+ # subject = f"Reminder Invoice Due - {partner.name}"
+ # body_html = re.sub(
+ # r"<tbody[^>]*>.*?</tbody>",
+ # f"<tbody>{invoice_table_rows}</tbody>",
+ # template.body_html,
+ # flags=re.DOTALL
+ # ).replace('${object.name}', partner.name) \
+ # .replace('${object.partner_id.name}', partner.name)
+ # # .replace('${object.email}', partner.email or '')
+
+ # values = {
+ # 'subject': subject,
+ # 'email_to': 'andrifebriyadiputra@gmail.com', # Ubah ke partner.email untuk produksi
+ # 'email_from': 'finance@indoteknik.co.id',
+ # 'body_html': body_html,
+ # 'reply_to': f'invoice+account.move_{invs[0].id}@indoteknik.co.id',
+ # }
+
+ # _logger.info(f"VALUES: {values}")
+
+ # template.send_mail(invs[0].id, force_send=True, email_values=values)
+
+ # # Default System User
+ # user_system = self.env['res.users'].browse(25)
+ # system_id = user_system.partner_id.id if user_system else False
+ # _logger.info(f"System User: {user_system.name} ({user_system.id})")
+ # _logger.info(f"System User ID: {system_id}")
+
+ # for inv in invs:
+ # inv.message_post(
+ # subject=subject,
+ # body=body_html,
+ # subtype_id=self.env.ref('mail.mt_note').id,
+ # author_id=system_id,
+ # )
+
+ # _logger.info(f"Reminder terkirim ke {partner.name} ({values['email_to']}) → {len(invs)} invoice")
+
+
+ @api.onchange('invoice_date')
+ def _onchange_invoice_date(self):
+ if self.invoice_date:
+ self.date = self.invoice_date
+
+ @api.onchange('date')
+ def _onchange_date(self):
+ if self.date:
+ self.invoice_date = self.date
+
+ @api.depends('refund_so_ids')
+ def _compute_refund_so_links(self):
+ for rec in self:
+ links = []
+ for so in rec.refund_so_ids:
+ url = f"/web#id={so.id}&model=sale.order&view_type=form"
+ name = html_escape(so.name or so.display_name)
+ links.append(f'<a href="{url}" target="_blank">{name}</a>')
+ rec.refund_so_links = ', '.join(links) if links else "-"
+
+ @api.depends('refund_so_ids')
+ def _compute_has_refund_so(self):
+ for rec in self:
+ rec.has_refund_so = bool(rec.refund_so_ids)
+
+
+ # def compute_length_of_payment(self):
+ # for rec in self:
+ # payment_term = rec.invoice_payment_term_id.line_ids[0].days
+ # terima_faktur = rec.date_terima_tukar_faktur
+ # payment = self.search([('ref', '=', rec.name), ('move_type', '=', 'entry')], limit=1)
+
+ # if payment and terima_faktur:
+ # date_diff = terima_faktur - payment.date
+ # rec.length_of_payment = date_diff.days + payment_term
+ # else:
+ # rec.length_of_payment = 0
def compute_length_of_payment(self):
for rec in self:
- payment_term = rec.invoice_payment_term_id.line_ids[0].days
+ payment_term = 0
+ if rec.invoice_payment_term_id and rec.invoice_payment_term_id.line_ids:
+ payment_term = rec.invoice_payment_term_id.line_ids[0].days
+
terima_faktur = rec.date_terima_tukar_faktur
payment = self.search([('ref', '=', rec.name), ('move_type', '=', 'entry')], limit=1)
-
+
if payment and terima_faktur:
date_diff = terima_faktur - payment.date
rec.length_of_payment = date_diff.days + payment_term
@@ -126,13 +306,38 @@ class AccountMove(models.Model):
}
template.send_mail(record.id, email_values=email_values, force_send=True)
+ # @api.model
+ # def create(self, vals):
+ # vals['nomor_kwitansi'] = self.env['ir.sequence'].next_by_code('nomor.kwitansi') or '0'
+ # result = super(AccountMove, self).create(vals)
+ # # result._update_line_name_from_ref()
+ # return result
+
@api.model
def create(self, vals):
- vals['nomor_kwitansi'] = self.env['ir.sequence'].next_by_code('nomor.kwitansi') or '0'
+ vals['nomor_kwitansi'] = self.env['ir.sequence'].next_by_code('nomor.kwitansi') or '0'
result = super(AccountMove, self).create(vals)
- # result._update_line_name_from_ref()
+
+ # Tambahan: jika ini Vendor Bill dan tanggal belum diisi
+ if result.move_type == 'in_invoice' and not vals.get('invoice_date') and not vals.get('date'):
+ po = result.purchase_order_id
+ if po:
+ # Cari receipt dari PO
+ picking = self.env['stock.picking'].search([
+ ('purchase_id', '=', po.id),
+ ('picking_type_code', '=', 'incoming'),
+ ('state', '=', 'done'),
+ ('date_done', '!=', False),
+ ], order='date_done desc', limit=1)
+
+ if picking:
+ receipt_date = picking.date_done
+ result.invoice_date = receipt_date
+ result.date = receipt_date
+
return result
+
def compute_so_shipping_paid_by(self):
for record in self:
record.so_shipping_paid_by = record.sale_id.shipping_paid_by
@@ -381,18 +586,18 @@ class AccountMove(models.Model):
return invoices
def export_faktur_to_xml(self):
-
valid_invoices = self
- # Panggil model coretax.faktur untuk menghasilkan XML
coretax_faktur = self.env['coretax.faktur'].create({})
- response = coretax_faktur.export_to_download(invoices=valid_invoices)
- current_time = datetime.utcnow()
- # Tandai faktur sebagai sudah diekspor
+ response = coretax_faktur.export_to_download(
+ invoices=valid_invoices,
+ down_payments=[inv.down_payment for inv in valid_invoices],
+ )
+
valid_invoices.write({
'is_efaktur_exported': True,
- 'date_efaktur_exported': current_time, # Set tanggal ekspor
+ 'date_efaktur_exported': datetime.utcnow(),
})
- return response
+ return response \ No newline at end of file