summaryrefslogtreecommitdiff
path: root/account_fiscal_year_period/models/models.py
blob: cf59f4509688a0313439b6df27282f803668076a (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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# -*- coding: utf-8 -*-

from odoo import models, fields, api,_
from dateutil.relativedelta import relativedelta
from odoo.exceptions import UserError, ValidationError

class AccountFiscalyear(models.Model):
    _name = "account.fiscalyear.periods"
    _inherit = ['mail.thread']
    _description = "Fiscal Year"
    _rec_name = 'fiscal_year_id'

    fiscal_year_id = fields.Many2one('account.fiscal.year',required=True, tracking=True)
    code = fields.Char('Code',required=True, tracking=True,default='/',readonly=True)
    company_id = fields.Many2one('res.company',related='fiscal_year_id.company_id',store=True,tracking=True)
    date_start = fields.Date('Start Date',related='fiscal_year_id.date_from',store=True, tracking=True)
    date_stop = fields.Date('Ending Date',related='fiscal_year_id.date_to',store=True, tracking=True)
    period_ids = fields.One2many('account.month.period', 'fiscalyear_id', 'Periods', tracking=True)
    state = fields.Selection(
        [('draft', 'Draft'),
         ('open', 'Open'),('done', 'Closed')],
        'Status', readonly=True, default='draft', tracking=True)
    comments = fields.Text('Comments')

    @api.onchange('fiscal_year_id')
    def _onchange_fiscal_year_id(self):
        if self.fiscal_year_id:
            self.code = 'FY/'+str(self.fiscal_year_id.name)


    @api.model
    def create(self, vals):
        return super(AccountFiscalyear, self).create(vals)

    def open(self):
        for rec in self:
            rec.write({'state':'open'})


    def set_to_draft(self):
        for rec in self:
            rec.write({'state':'draft'})
    def done(self):
        for rec in self:
            rec.period_ids.write({'special':False})
            rec.write({'state':'done'})        

    #def get_month(self, date_from):
    #    locale = self.env.context.get('lang') or 'en_US'
    #    new_dates =  tools.ustr(babel.dates.format_date(date=date_from, format='MMMM y', locale=locale)) 
    #    return new_date        

    '''@api.multi
    @api.constrains('date_start','date_stop')
    def _check_period(self):
        for rec in self:
            if rec.date_start and rec.date_stop:
                if rec.date_start > rec.date_stop:
                    raise ValidationError(_('The start date must be before end date.'))
                fiscal_rec_start = self.search([('date_start','<=',rec.date_start),('date_stop','>=',rec.date_start),('id','!=',rec.id)])
                if fiscal_rec_start:
                    raise ValidationError(_('The start date is within other fiscal year period.'))
                fiscal_rec_end = self.search([('date_start','<=',rec.date_stop),('date_stop','>=',rec.date_stop),('id','!=',rec.id)])
                if fiscal_rec_end:
                    raise ValidationError(_('The end date is within other fiscal year period.'))'''
    _sql_constraints = [
        ('fiscalyear_uniq', 'unique(fiscal_year_id)', 'The Fiscal Year must be unique For Periods!')
    ]            

    @api.constrains('date_start', 'date_stop', 'company_id')
    def _check_dates(self):
        for fy in self:
            # Starting date must be prior to the ending date
            date_from = fy.date_start
            date_to = fy.date_stop
            if date_to < date_from:
                raise ValidationError(_('The ending date must not be prior to the starting date.'))


            domain = [
                ('id', '!=', fy.id),
                ('company_id', '=', fy.company_id.id),
                '|', '|',
                '&', ('date_start', '<=', fy.date_start), ('date_stop', '>=', fy.date_start),
                '&', ('date_start', '<=', fy.date_stop), ('date_stop', '>=', fy.date_stop),
                '&', ('date_start', '<=', fy.date_start), ('date_stop', '>=', fy.date_stop),
            ]

            if self.search_count(domain) > 0:
                raise ValidationError(_('You can not have an overlap between two fiscal years, please correct the start and/or end dates of your fiscal years.'))



    def create_periods(self):
        period_obj = self.env['account.month.period']
        for rec in self:
            rec.period_ids.unlink()
            start_date = fields.Date.from_string(rec.date_start)
            end_date = fields.Date.from_string(rec.date_stop)
            index = 1
            while start_date < end_date:
                de = start_date + relativedelta(months=1, days=-1)

                if de > end_date:
                    de = end_date

                period_obj.create({
                    'sequence': index,
                    'code': '%02d/' % int(index) + start_date.strftime('%Y'),
                    'date_start': start_date.strftime('%Y-%m-%d'),
                    'date_stop': de.strftime('%Y-%m-%d'),
                    'fiscalyear_id': rec.id,
                })
                start_date = start_date + relativedelta(months=1)
                index += 1

class AccountMonthPeriod(models.Model):
    _name = "account.month.period"
    _description = "Account Month period"
    _inherit = ['mail.thread']
    _order = "date_start asc"

    sequence = fields.Integer('Period Sequence', default=1)
    code = fields.Char('Code', size=14, tracking=True)
    special = fields.Boolean('Opening/Closing Period', tracking=True)
    date_start = fields.Date('From', required=True, tracking=True)
    date_stop = fields.Date('To', required=True, tracking=True)
    fiscalyear_id = fields.Many2one('account.fiscalyear.periods', 'Fiscal Year', select=True, tracking=True)
    company_id = fields.Many2one('res.company',string='Company',related='fiscalyear_id.company_id')

    def get_closest_open_date(self,dates):
        period = self.sudo().search([('date_start', '<=', dates), ('date_stop', '>=', dates),('special','=',True)])
        if period:
            return dates
        else:
            period = self.sudo().search([('date_start', '>=', dates),('special','=',True)],limit=1)
            if period:
                return period.date_start
            else:
                return dates


    def get_closest_open_by_period(self,dates):
        period = self.sudo().search([('date_start', '<=', dates), ('date_stop', '>=', dates),('special','=',True)])
        if period:
            return {'date_from':period['date_start'],'date_to':period['date_stop']}
        else:
            period = self.sudo().search([('special','=',True)],order='date_start desc',limit=1)
            if period:
                return {'date_from':period['date_start'],'date_to':period['date_stop']}    
            else:          
                return False          
                 
class AccountMove(models.Model):
    _inherit = 'account.move'

    def _check_fiscalyear_lock_date(self):
        res = super(AccountMove, self)._check_fiscalyear_lock_date()
        if res:
            for rec in self:
                fiscal_year_obj = self.env['account.fiscalyear.periods']
                period_obj = self.env['account.month.period']
                fiscal_rec = fiscal_year_obj.sudo().search([('date_start','<=',rec.date),('date_stop','>=',rec.date)])
                if not fiscal_rec:
                    raise ValidationError(_('The date must be within the fiscal year period'))
                elif fiscal_rec.state == 'open':
                    period_rec = period_obj.sudo().search([('date_start', '<=', rec.date), ('date_stop', '>=', rec.date)])
                    if not period_rec:
                        raise ValidationError(
                            _('The date must be within the period duration.'))
                    elif not period_rec.special:
                        raise ValidationError(_('The Fiscal year period is closed'))
                    else:return True
                else:raise ValidationError(
                            _('The Fiscal year must opened first'))
        else: return res