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): # Cari invoice berdasarkan invoice_marketplace 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) 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')