summaryrefslogtreecommitdiff
path: root/fixco_custom/models/upload_payments.py
blob: 7761ce69d4ce9688acda2928a908c5996f983b4b (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
from odoo import models, fields, api, _
from odoo.exceptions import ValidationError
from datetime import datetime
import base64
import xlrd

class UploadPayments(models.Model):
    _name = "upload.payments"
    _description = "Upload Payments"
    _order = "create_date desc"

    payments_lines = fields.One2many('upload.payments.line', 'upload_payments_id', string='Upload Payments Lines', auto_join=True, copy=False)
    number = fields.Char('Number', copy=False)
    date_upload = fields.Date('Upload Date', copy=False, default=fields.Date.context_today)
    user_id = fields.Many2one('res.users', string='Created By', copy=False, default=lambda self: self.env.user.id)
    excel_file = fields.Binary('Excel File', attachment=True)
    filename = fields.Char('File Name')

    @api.model
    def create(self, vals):
        vals['number'] = self.env['ir.sequence'].next_by_code('upload.payments') or '/'
        return super(UploadPayments, self).create(vals)

    def action_import_excel(self):
        self.ensure_one()
        if not self.excel_file:
            raise ValidationError(_("Please upload an Excel file first."))
        
        try:
            file_content = base64.b64decode(self.excel_file)
            workbook = xlrd.open_workbook(file_contents=file_content)
            sheet = workbook.sheet_by_index(0)
        except:
            raise ValidationError(_("Invalid Excel file format."))
        
        # Process Excel rows (skip header row if exists)
        line_vals_list = []
        for row in range(1, sheet.nrows):
            try:
                no_invoice = str(sheet.cell(row, 0).value).strip()
                date_invoice = xlrd.xldate.xldate_as_datetime(sheet.cell(row, 1).value, workbook.datemode).date()
                
                line_vals = {
                    'no_invoice': no_invoice,
                    'date_invoice': date_invoice,
                }
                line_vals_list.append((0, 0, line_vals))
            except:
                continue
        
        # Update current record with lines
        self.write({
            'payments_lines': line_vals_list,
        })
        
        return {
            'type': 'ir.actions.client',
            'tag': 'display_notification',
            'params': {
                'title': _('Success'),
                'message': _('Imported %s lines from Excel.') % len(line_vals_list),
                'sticky': False,
                'next': {'type': 'ir.actions.act_window_close'},
            }
        }
    
    def action_create_payments(self):
        """Membuat payment untuk semua lines yang belum memiliki payment"""
        self.ensure_one()
        created_payments = []
        
        for line in self.payments_lines.filtered(lambda l: not l.payment_id):
            invoice = self.env['account.move'].search([
                ('invoice_marketplace', '=', line.no_invoice),
                ('state', '=', 'posted'),
                ('payment_state', '!=', 'paid'),
            ])

            for move in invoice:
                move._register_payment_automatically(line.date_invoice)

    def queue_job(self, limit=100):
        self.date_upload = fields.Datetime.now()

        lines = self.payments_lines.filtered(
            lambda l: not l.payment_id and not l.is_queued
        )[:limit]


        existing_jobs = self.env['queue.job'].search([
            ('model_name', '=', 'upload.payments.line'),
            ('method_name', '=', 'action_create_payments'),
            ('res_id', 'in', lines.ids),
            ('state', '!=', 'error'),
        ])

        existing_res_ids = set(existing_jobs.mapped('res_id'))

        for line in lines:
            if line.id in existing_res_ids:
                continue

            self.env['queue.job'].create({
                'name': f'Upload Payments {line.no_bu}',  
                'model_name': 'upload.payments.line',
                'method_name': 'action_create_payments',
                'res_id': line.id,
            })
            
            line.is_queued = True
            self.env.cr.commit()


class UploadPaymentsLine(models.Model):
    _name = "upload.payments.line"
    _description = "Upload Payments Line"
    _inherit = ['mail.thread']

    upload_payments_id = fields.Many2one('upload.payments', string='Upload Payments')
    no_invoice = fields.Char('Invoice Number', required=True)
    date_invoice = fields.Date('Invoice Date', required=True)
    move_id = fields.Many2one('account.move', string='Invoice')
    payment_id = fields.Many2one('account.payment', string='Created Payment')
    message_error = fields.Text('Error Message')
    is_queued = fields.Boolean(default=False)

    def action_create_payments(self):
        self.ensure_one()
        invoice = self.env['account.move'].search([
            ('invoice_marketplace', '=', self.no_invoice),
            ('state', '=', 'posted'),
            ('payment_state', '!=', 'paid'),
        ])

        for move in invoice:
            move._register_payment_automatically(self.date_invoice)