142 lines
6.2 KiB
Python
142 lines
6.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from datetime import date
|
|
from dateutil.relativedelta import relativedelta
|
|
from odoo import models, fields, api, _
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class RecurringPayment(models.Model):
|
|
_name = 'recurring.payment'
|
|
_description = 'Recurring Payment('
|
|
_rec_name = 'name'
|
|
|
|
name = fields.Char('Name', readonly=True)
|
|
partner_id = fields.Many2one('res.partner', string="Partner", required=True)
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company.id)
|
|
currency_id = fields.Many2one('res.currency', string='Currency', related='company_id.currency_id')
|
|
amount = fields.Monetary(string="Amount", currency_field='currency_id')
|
|
journal_id = fields.Many2one('account.journal', 'Journal',
|
|
related='template_id.journal_id', readonly=False, required=True)
|
|
payment_type = fields.Selection([
|
|
('outbound', 'Send Money'),
|
|
('inbound', 'Receive Money'),
|
|
], string='Payment Type', required=True, default='inbound')
|
|
state = fields.Selection(selection=[('draft', 'Draft'),
|
|
('done', 'Done')], default='draft', string='Status')
|
|
date_begin = fields.Date(string='Start Date', required=True)
|
|
date_end = fields.Date(string='End Date', required=True)
|
|
template_id = fields.Many2one('account.recurring.template', 'Recurring Template',
|
|
domain=[('state', '=', 'done')],required=True)
|
|
recurring_period = fields.Selection(related='template_id.recurring_period')
|
|
recurring_interval = fields.Integer('Recurring Interval', required=True,
|
|
related='template_id.recurring_interval', readonly=True)
|
|
journal_state = fields.Selection(required=True, string='Generate Journal As',
|
|
related='template_id.journal_state')
|
|
|
|
description = fields.Text('Description')
|
|
line_ids = fields.One2many('recurring.payment.line', 'recurring_payment_id', string='Recurring Lines')
|
|
|
|
def compute_next_date(self, date):
|
|
period = self.recurring_period
|
|
interval = self.recurring_interval
|
|
if period == 'days':
|
|
date += relativedelta(days=interval)
|
|
elif period == 'weeks':
|
|
date += relativedelta(weeks=interval)
|
|
elif period == 'months':
|
|
date += relativedelta(months=interval)
|
|
else:
|
|
date += relativedelta(years=interval)
|
|
return date
|
|
|
|
def action_create_lines(self, date):
|
|
ids = self.env['recurring.payment.line']
|
|
vals = {
|
|
'partner_id': self.partner_id.id,
|
|
'amount': self.amount,
|
|
'date': date,
|
|
'recurring_payment_id': self.id,
|
|
'journal_id': self.journal_id.id,
|
|
'currency_id': self.currency_id.id,
|
|
'state': 'draft'
|
|
}
|
|
ids.create(vals)
|
|
|
|
def action_done(self):
|
|
date_begin = self.date_begin
|
|
while date_begin < self.date_end:
|
|
date = date_begin
|
|
self.action_create_lines(date)
|
|
date_begin = self.compute_next_date(date)
|
|
self.state = 'done'
|
|
|
|
def action_draft(self):
|
|
if self.line_ids.filtered(lambda t: t.state == 'done'):
|
|
raise ValidationError(_('You cannot Set to Draft as one of the line is already in done state'))
|
|
else:
|
|
for line in self.line_ids:
|
|
line.unlink()
|
|
self.state = 'draft'
|
|
|
|
def action_generate_payment(self):
|
|
line_ids = self.env['recurring.payment.line'].search([('date', '<=', date.today()),
|
|
('state', '!=', 'done')])
|
|
for line in line_ids:
|
|
line.action_create_payment()
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
for vals in vals_list:
|
|
if 'company_id' in vals:
|
|
vals['name'] = self.env['ir.sequence'].with_context(force_company=vals['company_id']).next_by_code(
|
|
'recurring.payment') or _('New')
|
|
else:
|
|
vals['name'] = self.env['ir.sequence'].next_by_code('recurring.payment') or _('New')
|
|
return super(RecurringPayment, self).create(vals)
|
|
|
|
@api.constrains('amount')
|
|
def _check_amount(self):
|
|
if self.amount <= 0:
|
|
raise ValidationError(_('Amount Must Be Non-Zero Positive Number'))
|
|
|
|
def unlink(self):
|
|
for rec in self:
|
|
if rec.state == 'done':
|
|
raise ValidationError(_('Cannot delete done records !'))
|
|
return super(RecurringPayment, self).unlink()
|
|
|
|
|
|
class RecurringPaymentLine(models.Model):
|
|
_name = 'recurring.payment.line'
|
|
_description = 'Recurring Payment Line'
|
|
|
|
recurring_payment_id = fields.Many2one('recurring.payment', string="Recurring Payment")
|
|
partner_id = fields.Many2one('res.partner', 'Partner', required=True)
|
|
amount = fields.Monetary('Amount', required=True, default=0.0)
|
|
date = fields.Date('Date', required=True, default=date.today())
|
|
journal_id = fields.Many2one('account.journal', 'Journal', required=True)
|
|
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company.id)
|
|
currency_id = fields.Many2one('res.currency', string='Currency', related='company_id.currency_id')
|
|
payment_id = fields.Many2one('account.payment', string='Payment')
|
|
state = fields.Selection(selection=[('draft', 'Draft'),
|
|
('done', 'Done')], default='draft', string='Status')
|
|
|
|
def action_create_payment(self):
|
|
vals = {
|
|
'payment_type': self.recurring_payment_id.payment_type,
|
|
'amount': self.amount,
|
|
'currency_id': self.currency_id.id,
|
|
'journal_id': self.journal_id.id,
|
|
'company_id': self.company_id.id,
|
|
'date': self.date,
|
|
'ref': self.recurring_payment_id.name,
|
|
'partner_id': self.partner_id.id,
|
|
}
|
|
payment = self.env['account.payment'].create(vals)
|
|
if payment:
|
|
if self.recurring_payment_id.journal_state == 'posted':
|
|
payment.action_post()
|
|
self.write({'state': 'done', 'payment_id': payment.id})
|
|
|