|  |  | @ -19,7 +19,6 @@ | 
			
		
	
		
			
				
					|  |  |  | #    If not, see <http://www.gnu.org/licenses/>. | 
			
		
	
		
			
				
					|  |  |  | # | 
			
		
	
		
			
				
					|  |  |  | ############################################################################# | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | from odoo import api, fields, models, _ | 
			
		
	
		
			
				
					|  |  |  | from odoo.exceptions import ValidationError | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -30,10 +29,13 @@ class AccountBudgetPost(models.Model): | 
			
		
	
		
			
				
					|  |  |  |     _description = "Budgetary Position" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     name = fields.Char('Name', required=True) | 
			
		
	
		
			
				
					|  |  |  |     account_ids = fields.Many2many('account.account', 'account_budget_rel', 'budget_id', 'account_id', 'Accounts', | 
			
		
	
		
			
				
					|  |  |  |                                    domain=[('deprecated', '=', False)]) | 
			
		
	
		
			
				
					|  |  |  |     budget_line = fields.One2many('budget.lines', 'general_budget_id', 'Budget Lines') | 
			
		
	
		
			
				
					|  |  |  |     company_id = fields.Many2one('res.company', 'Company', required=True, | 
			
		
	
		
			
				
					|  |  |  |     account_ids = fields.Many2many( | 
			
		
	
		
			
				
					|  |  |  |         'account.account', 'account_budget_rel', 'budget_id', 'account_id', | 
			
		
	
		
			
				
					|  |  |  |         string='Accounts', domain=[('deprecated', '=', False)]) | 
			
		
	
		
			
				
					|  |  |  |     budget_line = fields.One2many('budget.lines', 'general_budget_id', | 
			
		
	
		
			
				
					|  |  |  |                                   string='Budget Lines') | 
			
		
	
		
			
				
					|  |  |  |     company_id = fields.Many2one( | 
			
		
	
		
			
				
					|  |  |  |         'res.company', string='Company', required=True, | 
			
		
	
		
			
				
					|  |  |  |         default=lambda self: self.env['res.company']._company_default_get( | 
			
		
	
		
			
				
					|  |  |  |             'account.budget.post')) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -43,7 +45,8 @@ class AccountBudgetPost(models.Model): | 
			
		
	
		
			
				
					|  |  |  |         else: | 
			
		
	
		
			
				
					|  |  |  |             account_ids = self.account_ids | 
			
		
	
		
			
				
					|  |  |  |         if not account_ids: | 
			
		
	
		
			
				
					|  |  |  |             raise ValidationError(_('The budget must have at least one account.')) | 
			
		
	
		
			
				
					|  |  |  |             raise ValidationError( | 
			
		
	
		
			
				
					|  |  |  |                 _('The budget must have at least one account.')) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     @api.model | 
			
		
	
		
			
				
					|  |  |  |     def create(self, vals): | 
			
		
	
	
		
			
				
					|  |  | @ -60,20 +63,27 @@ class Budget(models.Model): | 
			
		
	
		
			
				
					|  |  |  |     _description = "Budget" | 
			
		
	
		
			
				
					|  |  |  |     _inherit = ['mail.thread'] | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     name = fields.Char('Budget Name', required=True, states={'done': [('readonly', True)]}) | 
			
		
	
		
			
				
					|  |  |  |     creating_user_id = fields.Many2one('res.users', 'Responsible', default=lambda self: self.env.user) | 
			
		
	
		
			
				
					|  |  |  |     date_from = fields.Date('Start Date', required=True, states={'done': [('readonly', True)]}) | 
			
		
	
		
			
				
					|  |  |  |     date_to = fields.Date('End Date', required=True, states={'done': [('readonly', True)]}) | 
			
		
	
		
			
				
					|  |  |  |     name = fields.Char( | 
			
		
	
		
			
				
					|  |  |  |         'Budget Name', required=True, states={'done': [('readonly', True)]}) | 
			
		
	
		
			
				
					|  |  |  |     creating_user_id = fields.Many2one( | 
			
		
	
		
			
				
					|  |  |  |         'res.users', 'Responsible', default=lambda self: self.env.user) | 
			
		
	
		
			
				
					|  |  |  |     date_from = fields.Date( | 
			
		
	
		
			
				
					|  |  |  |         'Start Date', required=True, states={'done': [('readonly', True)]}) | 
			
		
	
		
			
				
					|  |  |  |     date_to = fields.Date( | 
			
		
	
		
			
				
					|  |  |  |         'End Date', required=True, states={'done': [('readonly', True)]}) | 
			
		
	
		
			
				
					|  |  |  |     state = fields.Selection([ | 
			
		
	
		
			
				
					|  |  |  |         ('draft', 'Draft'), | 
			
		
	
		
			
				
					|  |  |  |         ('cancel', 'Cancelled'), | 
			
		
	
		
			
				
					|  |  |  |         ('confirm', 'Confirmed'), | 
			
		
	
		
			
				
					|  |  |  |         ('validate', 'Validated'), | 
			
		
	
		
			
				
					|  |  |  |         ('done', 'Done') | 
			
		
	
		
			
				
					|  |  |  |     ], 'Status', default='draft', index=True, required=True, readonly=True, copy=False, track_visibility='always') | 
			
		
	
		
			
				
					|  |  |  |     budget_line = fields.One2many('budget.lines', 'budget_id', 'Budget Lines', | 
			
		
	
		
			
				
					|  |  |  |     ], 'Status', default='draft', index=True, required=True, readonly=True, | 
			
		
	
		
			
				
					|  |  |  |         copy=False, track_visibility='always') | 
			
		
	
		
			
				
					|  |  |  |     budget_line = fields.One2many( | 
			
		
	
		
			
				
					|  |  |  |         'budget.lines', 'budget_id', 'Budget Lines', | 
			
		
	
		
			
				
					|  |  |  |         states={'done': [('readonly', True)]}, copy=True) | 
			
		
	
		
			
				
					|  |  |  |     company_id = fields.Many2one('res.company', 'Company', required=True, | 
			
		
	
		
			
				
					|  |  |  |     company_id = fields.Many2one( | 
			
		
	
		
			
				
					|  |  |  |         'res.company', 'Company', required=True, | 
			
		
	
		
			
				
					|  |  |  |         default=lambda self: self.env['res.company']._company_default_get( | 
			
		
	
		
			
				
					|  |  |  |             'account.budget.post')) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -98,17 +108,25 @@ class BudgetLines(models.Model): | 
			
		
	
		
			
				
					|  |  |  |     _rec_name = "budget_id" | 
			
		
	
		
			
				
					|  |  |  |     _description = "Budget Line" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     budget_id = fields.Many2one('budget.budget', 'Budget', ondelete='cascade', index=True, required=True) | 
			
		
	
		
			
				
					|  |  |  |     analytic_account_id = fields.Many2one('account.analytic.account', 'Analytic Account') | 
			
		
	
		
			
				
					|  |  |  |     general_budget_id = fields.Many2one('account.budget.post', 'Budgetary Position', required=True) | 
			
		
	
		
			
				
					|  |  |  |     date_from = fields.Date('Start Date', required=True) | 
			
		
	
		
			
				
					|  |  |  |     date_to = fields.Date('End Date', required=True) | 
			
		
	
		
			
				
					|  |  |  |     paid_date = fields.Date('Paid Date') | 
			
		
	
		
			
				
					|  |  |  |     planned_amount = fields.Float('Planned Amount', required=True, digits=0) | 
			
		
	
		
			
				
					|  |  |  |     practical_amount = fields.Float(compute='_compute_practical_amount', string='Practical Amount', digits=0) | 
			
		
	
		
			
				
					|  |  |  |     theoretical_amount = fields.Float(compute='_compute_theoretical_amount', string='Theoretical Amount', digits=0) | 
			
		
	
		
			
				
					|  |  |  |     percentage = fields.Float(compute='_compute_percentage', string='Achievement') | 
			
		
	
		
			
				
					|  |  |  |     company_id = fields.Many2one(related='budget_id.company_id', comodel_name='res.company', | 
			
		
	
		
			
				
					|  |  |  |     budget_id = fields.Many2one('budget.budget', string='Budget', | 
			
		
	
		
			
				
					|  |  |  |                                 ondelete='cascade', index=True, required=True) | 
			
		
	
		
			
				
					|  |  |  |     analytic_account_id = fields.Many2one('account.analytic.account', | 
			
		
	
		
			
				
					|  |  |  |                                           string='Analytic Account') | 
			
		
	
		
			
				
					|  |  |  |     general_budget_id = fields.Many2one( | 
			
		
	
		
			
				
					|  |  |  |         'account.budget.post', string='Budgetary Position', required=True) | 
			
		
	
		
			
				
					|  |  |  |     date_from = fields.Date(string='Start Date', required=True) | 
			
		
	
		
			
				
					|  |  |  |     date_to = fields.Date(string='End Date', required=True) | 
			
		
	
		
			
				
					|  |  |  |     paid_date = fields.Date(string='Paid Date') | 
			
		
	
		
			
				
					|  |  |  |     planned_amount = fields.Float( | 
			
		
	
		
			
				
					|  |  |  |         string='Planned Amount', required=True, digits=0) | 
			
		
	
		
			
				
					|  |  |  |     practical_amount = fields.Float(compute='_compute_practical_amount', | 
			
		
	
		
			
				
					|  |  |  |                                     string='Practical Amount', digits=0) | 
			
		
	
		
			
				
					|  |  |  |     theoretical_amount = fields.Float(compute='_compute_theoretical_amount', | 
			
		
	
		
			
				
					|  |  |  |                                       string='Theoretical Amount', digits=0) | 
			
		
	
		
			
				
					|  |  |  |     percentage = fields.Float( | 
			
		
	
		
			
				
					|  |  |  |         compute='_compute_percentage', string='Achievement') | 
			
		
	
		
			
				
					|  |  |  |     company_id = fields.Many2one( | 
			
		
	
		
			
				
					|  |  |  |         related='budget_id.company_id', comodel_name='res.company', | 
			
		
	
		
			
				
					|  |  |  |         string='Company', store=True, readonly=True) | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     def _compute_practical_amount(self): | 
			
		
	
	
		
			
				
					|  |  | @ -116,7 +134,8 @@ class BudgetLines(models.Model): | 
			
		
	
		
			
				
					|  |  |  |             result = 0.0 | 
			
		
	
		
			
				
					|  |  |  |             acc_ids = line.general_budget_id.account_ids.ids | 
			
		
	
		
			
				
					|  |  |  |             date_to = self.env.context.get('wizard_date_to') or line.date_to | 
			
		
	
		
			
				
					|  |  |  |             date_from = self.env.context.get('wizard_date_from') or line.date_from | 
			
		
	
		
			
				
					|  |  |  |             date_from = self.env.context.get( | 
			
		
	
		
			
				
					|  |  |  |                 'wizard_date_from') or line.date_from | 
			
		
	
		
			
				
					|  |  |  |             if line.analytic_account_id.id: | 
			
		
	
		
			
				
					|  |  |  |                 self.env.cr.execute(""" | 
			
		
	
		
			
				
					|  |  |  |                     SELECT SUM(amount) | 
			
		
	
	
		
			
				
					|  |  | @ -124,7 +143,8 @@ class BudgetLines(models.Model): | 
			
		
	
		
			
				
					|  |  |  |                     WHERE account_id=%s | 
			
		
	
		
			
				
					|  |  |  |                         AND date between %s AND %s | 
			
		
	
		
			
				
					|  |  |  |                         AND general_account_id=ANY(%s)""", | 
			
		
	
		
			
				
					|  |  |  |                                     (line.analytic_account_id.id, date_from, date_to, acc_ids,)) | 
			
		
	
		
			
				
					|  |  |  |                                     (line.analytic_account_id.id, date_from, | 
			
		
	
		
			
				
					|  |  |  |                                      date_to, acc_ids,)) | 
			
		
	
		
			
				
					|  |  |  |                 result = self.env.cr.fetchone()[0] or 0.0 | 
			
		
	
		
			
				
					|  |  |  |             line.practical_amount = result | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -134,8 +154,10 @@ class BudgetLines(models.Model): | 
			
		
	
		
			
				
					|  |  |  |             # Used for the report | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             if self.env.context.get('wizard_date_from') and self.env.context.get('wizard_date_to'): | 
			
		
	
		
			
				
					|  |  |  |                 date_from = fields.Datetime.from_string(self.env.context.get('wizard_date_from')) | 
			
		
	
		
			
				
					|  |  |  |                 date_to = fields.Datetime.from_string(self.env.context.get('wizard_date_to')) | 
			
		
	
		
			
				
					|  |  |  |                 date_from = fields.Datetime.from_string( | 
			
		
	
		
			
				
					|  |  |  |                     self.env.context.get('wizard_date_from')) | 
			
		
	
		
			
				
					|  |  |  |                 date_to = fields.Datetime.from_string( | 
			
		
	
		
			
				
					|  |  |  |                     self.env.context.get('wizard_date_to')) | 
			
		
	
		
			
				
					|  |  |  |                 if date_from < fields.Datetime.from_string(line.date_from): | 
			
		
	
		
			
				
					|  |  |  |                     date_from = fields.Datetime.from_string(line.date_from) | 
			
		
	
		
			
				
					|  |  |  |                 elif date_from > fields.Datetime.from_string(line.date_to): | 
			
		
	
	
		
			
				
					|  |  | @ -182,6 +204,7 @@ class BudgetLines(models.Model): | 
			
		
	
		
			
				
					|  |  |  |     def _compute_percentage(self): | 
			
		
	
		
			
				
					|  |  |  |         for line in self: | 
			
		
	
		
			
				
					|  |  |  |             if line.theoretical_amount != 0.00: | 
			
		
	
		
			
				
					|  |  |  |                 line.percentage = float((line.practical_amount or 0.0) / line.theoretical_amount) * 100 | 
			
		
	
		
			
				
					|  |  |  |                 line.percentage = float( | 
			
		
	
		
			
				
					|  |  |  |                     (line.practical_amount or 0.0) / line.theoretical_amount) * 100 | 
			
		
	
		
			
				
					|  |  |  |             else: | 
			
		
	
		
			
				
					|  |  |  |                 line.percentage = 0.00 | 
			
		
	
	
		
			
				
					|  |  | 
 |