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