summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/dunning_run.py
blob: 2562c3054604039b108187e3e1f244a843e0a95f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from odoo import models, api, fields
from odoo.exceptions import AccessError, UserError, ValidationError
from datetime import timedelta, date
import logging


_logger = logging.getLogger(__name__)


class DunningRun(models.Model):
    _name = 'dunning.run'
    _description = 'Dunning Run'
    _order = 'dunning_date desc, id desc'
    _inherit = ['mail.thread']
    _rec_name = 'number'

    number = fields.Char(string='Document No', index=True, copy=False, readonly=True)
    dunning_date = fields.Date(string='Dunning Date', required=True)
    partner_id = fields.Many2one(
        'res.partner', string='Customer',
        required=True, change_default=True, index=True, tracking=1)
    dunning_line = fields.One2many('dunning.run.line', 'dunning_id', string='Dunning Lines', auto_join=True, order='invoice_id desc')
    # dunning_level = fields.Integer(string='Dunning Level', default=30, help='30 hari sebelum jatuh tempo invoice')
    date_kirim_tukar_faktur = fields.Date(string='Kirim Faktur')
    resi_tukar_faktur = fields.Char(string='Resi Faktur')
    date_terima_tukar_faktur = fields.Date(string='Terima Faktur')
    shipper_faktur_id = fields.Many2one('delivery.carrier', string='Shipper Faktur')
    is_validated = fields.Boolean(string='Validated')
    notification = fields.Char(string='Notification')
    is_paid = fields.Boolean(string='Paid')
    description = fields.Char(string='Description')
    comment = fields.Char(string='Comment')
    grand_total = fields.Float(string='Grand Total', compute="_compute_grand_total")

    def _compute_grand_total(self):
        for record in self:
            grand_total = 0
            for line in record.dunning_line:
                grand_total += line.total_amt
            record.grand_total = grand_total

    def copy_date_faktur(self):
        if not self.is_validated:
            raise UserError('Harus di validate dulu')
        for line in self.dunning_line:
            invoice = line.invoice_id
            if not invoice.date_kirim_tukar_faktur and self.date_kirim_tukar_faktur:
                invoice.date_kirim_tukar_faktur = self.date_kirim_tukar_faktur
                tukar_date = self.date_kirim_tukar_faktur
                term = invoice.invoice_payment_term_id
                add_days = 0
                for line in term.line_ids:
                    add_days += line.days
                due_date = tukar_date + timedelta(days=add_days)
                invoice.invoice_date_due = due_date
            if not invoice.resi_tukar_faktur:
                invoice.resi_tukar_faktur = self.resi_tukar_faktur
            if not invoice.date_terima_tukar_faktur and self.date_terima_tukar_faktur:
                invoice.date_terima_tukar_faktur = self.date_terima_tukar_faktur
                tukar_date = self.date_terima_tukar_faktur
                term = invoice.invoice_payment_term_id
                add_days = 0
                for line in term.line_ids:
                    add_days += line.days
                due_date = tukar_date + timedelta(days=add_days)
                invoice.invoice_date_due = due_date
            if not invoice.shipper_faktur_id:
                invoice.shipper_faktur_id = self.shipper_faktur_id
        self.notification = 'Berhasil copy tanggal terima faktur ke setiap invoice %s' % self.date_terima_tukar_faktur

    def validate_dunning(self):
        if not self.dunning_line:
            raise UserError('Dunning Line masih kosong, generate dulu')
        else:
            self.is_validated = True
            self.notification = 'Jangan lupa klik Copy Date jika sudah ada tanggal kirim / tanggal terima faktur'

    def generate_dunning_line(self):
        if self.is_validated:
            raise UserError('Sudah di validate, tidak bisa digenerate ulang')
        if self.dunning_line:
            raise UserError('Harus hapus semua line jika ingin generate ulang')
        if self.partner_id.parent_id:
            raise UserError('Harus pilih parent company')

        partners = []
        partners += self.partner_id.child_ids
        partners.append(self.partner_id)

        for partner in partners:
            query = [
                ('move_type', '=', 'out_invoice'),
                ('state', '=', 'posted'),
                ('partner_id', '=', partner.id),
                ('date_kirim_tukar_faktur', '=', False),
            ]
            invoices = self.env['account.move'].search(query)

            # sort full berdasarkan tahun, bulan, nomor
            def invoice_key(x):
                try:
                    parts = x.name.split('/')
                    tahun = int(parts[1])
                    bulan = int(parts[2])
                    nomor = int(parts[3])
                    return (tahun, bulan, nomor)
                except Exception:
                    return (0, 0, 0)

            invoices = sorted(invoices, key=invoice_key)

            count = 0
            for invoice in invoices:
                self.env['dunning.run.line'].create([{
                    'dunning_id': self.id,
                    'partner_id': invoice.partner_id.id,
                    'invoice_id': invoice.id,
                    'date_invoice': invoice.invoice_date,
                    'efaktur_id': invoice.efaktur_id.id,
                    'reference': invoice.ref,
                    'total_amt': invoice.amount_total,
                    'open_amt': invoice.amount_residual_signed,
                    'due_date': invoice.invoice_date_due
                }])
                count += 1
            _logger.info("Dunning Line generated %s" % count)

    @api.model
    def create(self, vals):
        vals['number'] = self.env['ir.sequence'].next_by_code('dunning.run') or '0'
        result = super(DunningRun, self).create(vals)
        return result


class DunningRunLine(models.Model):
    _name = 'dunning.run.line'
    _description = 'Dunning Run Line'
    # _order = 'dunning_id, id'
    _order = 'invoice_number asc, id'

    invoice_number = fields.Char('Invoice Number', related='invoice_id.name')
    dunning_id = fields.Many2one('dunning.run', string='Dunning Ref', required=True, ondelete='cascade', index=True, copy=False)
    partner_id = fields.Many2one('res.partner', string='Customer')
    invoice_id = fields.Many2one('account.move', string='Invoice')
    date_invoice = fields.Date(string='Invoice Date')
    # due_date = fields.Date(string='Due Date')
    efaktur_id = fields.Many2one('vit.efaktur', string='Faktur Pajak')
    reference = fields.Char(string='Reference')
    total_amt = fields.Float(string='Total Amount')
    open_amt = fields.Float(string='Open Amount')
    due_date = fields.Date(string='Due Date')
    payment_term = fields.Many2one('account.payment.term', related='invoice_id.invoice_payment_term_id', string='Payment Term')
    information_line = fields.Text(string='Information')