<commit_before># -*- encoding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: <NAME> <<EMAIL>>
#
#    The licence is in the file __openerp__.py
#
##############################################################################

from datetime import datetime
from dateutil.relativedelta import relativedelta

from openerp.osv import orm, fields
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from openerp.tools.translate import _


class contract_group(orm.Model):
    _name = 'recurring.contract.group'
    _description = 'A group of contracts'
    _inherit = 'mail.thread'
    _rec_name = 'ref'

    def _get_next_invoice_date(self, cr, uid, ids, name, args, context=None):
        res = {}
        for group in self.browse(cr, uid, ids, context):
            res[group.id] = min(
                [c.next_invoice_date for c in group.contract_ids
                 if c.state == 'active']
                or [group.next_invoice_date])  # When no active contract

        return res

    def _get_groups_from_contract(self, cr, uid, ids, context=None):
        group_ids = set()
        contract_obj = self.pool.get('recurring.contract')
        for contract in contract_obj.browse(cr, uid, ids, context):
            group_ids.add(contract.group_id.id)
        return list(group_ids)

    _columns = {
        # TODO sequence for name/ref ?
        'ref': fields.char(_('Reference')),
        'recurring_unit': fields.selection([
            ('day', _('Day(s)')),
            ('week', _('Week(s)')),
            ('month', _('Month(s)')),
            ('year', _('Year(s)'))], _('Reccurency'), required=True,
            track_visibility="onchange"),
        'recurring_value': fields.integer(
            _('Generate every'), required=True, track_visibility="onchange"),
        'partner_id': fields.many2one(
            'res.partner', _('Partner'), required=True,
            ondelete='cascade', track_visibility="onchange"),
        'contract_ids': fields.one2many(
            'recurring.contract', 'group_id', _('Contracts'),
            readonly=True),
        'advance_billing': fields.selection([
            ('bimonthly', _('Bimonthly')),
            ('quarterly', _('Quarterly')),
            ('fourmonthly', _('Four-monthly')),
            ('biannual', _('Bi-annual')),
            ('annual', _('Annual'))], _('Advance billing'),
            help=_('Advance billing allows you to generate invoices in '
                   'advance. For example, you can generate the invoices '
                   'for each month of the year and send them to the '
                   'customer in january.'), track_visibility="onchange"),
        'payment_term_id': fields.many2one('account.payment.term',
                                           _('Payment Term'),
                                           track_visibility="onchange"),
        'next_invoice_date': fields.function(
            _get_next_invoice_date, type='date',
            string=_('Next invoice date'),
            store={
                'recurring.contract': (
                    _get_groups_from_contract, ['next_invoice_date'], 20),
            }),
    }

    _defaults = {
        'ref': '/',
        'recurring_unit': 'month',
        'recurring_value': 1,
    }

    def generate_invoices(self, cr, uid, ids, invoicer_id=None, context=None):
        ''' Checks all contracts and generate invoices if needed.
        Create an invoice per contract group per date.
        '''
        inv_obj = self.pool.get('account.invoice')
        journal_obj = self.pool.get('account.journal')
        contract_obj = self.pool.get('recurring.contract')

        if not ids:
            ids = self.search(cr, uid, [], context=context)

        journal_ids = journal_obj.search(
            cr, uid, [('type', '=', 'sale'), ('company_id', '=', 1 or False)],
            limit=1)
        delay_dict = {'annual': 12, 'biannual': 6, 'fourmonthly': 4,
                      'quarterly': 3, 'bimonthly': 2}
        # Invoice lines are generated for an active contract
        # If group.next_inv_date <= today
        #   and contr.next_inv_date <= group.next_inv_date
        #   or (group.next_inv_date > today
        #      and contr.next_inv_date <= group.next_inv_date + adv_billing
        #      and contract had an invoice generated in the process)
        #
        # The last condition ensures that we won't start to do advance billing
        # for contract who had initial next_invoice_date > today.
        for group_id in ids:
            adv_bill_candidate = set()
            contract_group = self.browse(cr, uid, group_id, context)
            month_delta = contract_group.advance_billing and \
                delay_dict.get(contract_group.advance_billing) or 0
            limit_date = datetime.today() + relativedelta(months=+month_delta)
            in_one_month = datetime.today() + relativedelta(months=+1)
            while True:  # Emulate a do-while loop
                # contract_group update 'cause next_inv_date has been modified
                contract_group = self.browse(cr, uid, group_id, context)
                group_inv_date = contract_group.next_invoice_date
                contr_ids = []
                if group_inv_date and \
                   datetime.strptime(group_inv_date, DF) <= in_one_month:
                    contr_ids = [c.id
                                 for c in contract_group.contract_ids
                                 if c.next_invoice_date <= group_inv_date
                                 and c.state in self._get_gen_states()]
                    adv_bill_candidate.update(contr_ids)
                elif datetime.strptime(group_inv_date, DF) <= limit_date:
                    contr_ids = [c.id
                                 for c in contract_group.contract_ids
                                 if c.next_invoice_date <= group_inv_date
                                 and c.id in adv_bill_candidate
                                 and c.state in self._get_gen_states()]

                if not contr_ids:
                    break

                inv_data = self._setup_inv_data(cr, uid, contract_group,
                                                journal_ids, invoicer_id,
                                                context=context)
                invoice_id = inv_obj.create(cr, uid, inv_data, context=context)

                for contract in contract_obj.browse(cr, uid, contr_ids,<commit_msg>Another cron bug fixed.<commit_after># -*- encoding: utf-8 -*-
##############################################################################
#
#    Copyright (C) 2014 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: <NAME> <<EMAIL>>
#
#    The licence is in the file __openerp__.py
#
##############################################################################

from datetime import datetime
from dateutil.relativedelta import relativedelta

from openerp.osv import orm, fields
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from openerp.tools.translate import _


class contract_group(orm.Model):
    _name = 'recurring.contract.group'
    _description = 'A group of contracts'
    _inherit = 'mail.thread'
    _rec_name = 'ref'

    def _get_next_invoice_date(self, cr, uid, ids, name, args, context=None):
        res = {}
        for group in self.browse(cr, uid, ids, context):
            res[group.id] = min(
                [c.next_invoice_date for c in group.contract_ids
                 if c.state == 'active']
                or [group.next_invoice_date])  # When no active contract

        return res

    def _get_groups_from_contract(self, cr, uid, ids, context=None):
        group_ids = set()
        contract_obj = self.pool.get('recurring.contract')
        for contract in contract_obj.browse(cr, uid, ids, context):
            group_ids.add(contract.group_id.id)
        return list(group_ids)

    _columns = {
        # TODO sequence for name/ref ?
        'ref': fields.char(_('Reference')),
        'recurring_unit': fields.selection([
            ('day', _('Day(s)')),
            ('week', _('Week(s)')),
            ('month', _('Month(s)')),
            ('year', _('Year(s)'))], _('Reccurency'), required=True,
            track_visibility="onchange"),
        'recurring_value': fields.integer(
            _('Generate every'), required=True, track_visibility="onchange"),
        'partner_id': fields.many2one(
            'res.partner', _('Partner'), required=True,
            ondelete='cascade', track_visibility="onchange"),
        'contract_ids': fields.one2many(
            'recurring.contract', 'group_id', _('Contracts'),
            readonly=True),
        'advance_billing': fields.selection([
            ('bimonthly', _('Bimonthly')),
            ('quarterly', _('Quarterly')),
            ('fourmonthly', _('Four-monthly')),
            ('biannual', _('Bi-annual')),
            ('annual', _('Annual'))], _('Advance billing'),
            help=_('Advance billing allows you to generate invoices in '
                   'advance. For example, you can generate the invoices '
                   'for each month of the year and send them to the '
                   'customer in january.'), track_visibility="onchange"),
        'payment_term_id': fields.many2one('account.payment.term',
                                           _('Payment Term'),
                                           track_visibility="onchange"),
        'next_invoice_date': fields.function(
            _get_next_invoice_date, type='date',
            string=_('Next invoice date'),
            store={
                'recurring.contract': (
                    _get_groups_from_contract, ['next_invoice_date'], 20),
            }),
    }

    _defaults = {
        'ref': '/',
        'recurring_unit': 'month',
        'recurring_value': 1,
    }

    def generate_invoices(self, cr, uid, ids, invoicer_id=None, context=None):
        ''' Checks all contracts and generate invoices if needed.
        Create an invoice per contract group per date.
        '''
        inv_obj = self.pool.get('account.invoice')
        journal_obj = self.pool.get('account.journal')
        contract_obj = self.pool.get('recurring.contract')

        if not ids:
            ids = self.search(cr, uid, [], context=context)

        journal_ids = journal_obj.search(
            cr, uid, [('type', '=', 'sale'), ('company_id', '=', 1 or False)],
            limit=1)
        delay_dict = {'annual': 12, 'biannual': 6, 'fourmonthly': 4,
                      'quarterly': 3, 'bimonthly': 2}
        # Invoice lines are generated for an active contract
        # If group.next_inv_date <= today
        #   and contr.next_inv_date <= group.next_inv_date
        #   or (group.next_inv_date > today
        #      and contr.next_inv_date <= group.next_inv_date + adv_billing
        #      and contract had an invoice generated in the process)
        #
        # The last condition ensures that we won't start to do advance billing
        # for contract who had initial next_invoice_date > today.
        for group_id in ids:
            adv_bill_candidate = set()
            contract_group = self.browse(cr, uid, group_id, context)
            month_delta = contract_group.advance_billing and \
                delay_dict.get(contract_group.advance_billing) or 0
            limit_date = datetime.today() + relativedelta(months=+month_delta)
            in_one_month = datetime.today() + relativedelta(months=+1)
            while True:  # Emulate a do-while loop
                # contract_group update 'cause next_inv_date has been modified
                contract_group = self.browse(cr, uid, group_id, context)
                group_inv_date = contract_group.next_invoice_date
                contr_ids = []
                if group_inv_date and \
                   datetime.strptime(group_inv_date, DF) <= in_one_month:
                    contr_ids = [c.id
                                 for c in contract_group.contract_ids
                                 if c.next_invoice_date <= group_inv_date
                                 and c.state in self._get_gen_states()]
                    adv_bill_candidate.update(contr_ids)
                elif group_inv_date and \
                     datetime.strptime(group_inv_date, DF) <= limit_date:
                    contr_ids = [c.id
                                 for c in contract_group.contract_ids
                                 if c.next_invoice_date <= group_inv_date
                                 and c.id in adv_bill_candidate
                                 and c.state in self._get_gen_states()]

                if not contr_ids:
                    break

                inv_data = self._setup_inv_data(cr, uid, contract_group,
                                                journal_ids, invoicer_id,
                                                context=context)
                invoice_id = inv_obj.create(cr, uid, inv_data, context=context)

                for contract in contract_obj.browse(cr, uid, contr_ids,
{'fraction_non_alphanumeric': 0.12778111846061335, 'fraction_numerical': 0.0031569452796151535, 'mean_word_length': 1.9566666666666668, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7546805', 'n_tokens_mistral': 3822, 'n_tokens_neox': 3606, 'n_words': 876}