<commit_before># -*- coding: utf-8 -*-
# Copyright 2019 Akretion France (http://www.akretion.com/)
# @author: <NAME> <<EMAIL>>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models, fields, _
from odoo.exceptions import UserError
from dateutil.relativedelta import relativedelta
from odoo.tools import float_compare, float_round


class AccountCutoff(models.Model):
    _inherit = 'account.cutoff'

    def get_lines(self):
        res = super(AccountCutoff, self).get_lines()
        if self.type not in ['accrued_expense', 'accrued_revenue']:
            return res
        aml_obj = self.env['account.move.line']
        line_obj = self.env['account.cutoff.line']
        sub_obj = self.env['account.cutoff.accrual.subscription']
        type2subtype = {
            'accrued_expense': 'expense',
            'accrued_revenue': 'revenue',
            }
        sub_type = type2subtype[self.type]
        sign = sub_type == 'revenue' and -1 or 1
        subs = sub_obj.search([
            ('company_id', '=', self.company_id.id),
            ('subscription_type', '=', sub_type),
            ('start_date', '<=', self.cutoff_date),
            ])
        cutoff_date = fields.Date.from_string(self.cutoff_date)
        if subs:
            # check that the cutoff is the last day of a month
            # otherwise, we have pb with when we compute intervals
            # with cutoff date is a day which is not present for all months
            last_day_same_month = cutoff_date + relativedelta(day=31)
            if last_day_same_month.day != cutoff_date.day:
                raise UserError(_(
                    "The cutoffs with subscription only work when the cutoff "
                    "date (%s) is the last day of a month.")
                    % self.cutoff_date)
            if not self.source_journal_ids:
                raise UserError(_('Missing source journals.'))
        periodicity2months = {
            'month': 1,
            'quarter': 3,
            'semester': 6,
            'year': 12,
            }
        company_currency = self.company_currency_id
        prec = company_currency.rounding
        work = {}
        # Generate time intervals and computing existing expenses/revenue
        for sub in subs:
            sub_start_date_dt = fields.Date.from_string(sub.start_date)
            months = periodicity2months[sub.periodicity]
            work[sub] = {'intervals': []}
            end_date = cutoff_date
            for i in range(12 / months):
                start_date = end_date + relativedelta(
                    day=1, months=-(months-1))
                if start_date < sub_start_date_dt:
                    break
                # compute amount
                amount = 0
                # 1. No start/end dates
                no_start_end_res = aml_obj.read_group([
                    ('company_id', '=', sub.company_id.id),
                    ('journal_id', 'in', self.source_journal_ids.ids),
                    ('account_id', '=', sub.account_id.id),
                    ('analytic_account_id', '=',
                        sub.analytic_account_id.id or False),
                    ('date', '<=', fields.Date.to_string(end_date)),
                    ('date', '>=', fields.Date.to_string(start_date)),
                    ('start_date', '=', False),
                    ('end_date', '=', False),
                    ], ['balance'], [])
                amount_no_start_end = no_start_end_res and\
                    no_start_end_res[0]['balance'] or 0
                amount += amount_no_start_end * sign
                # 2. Start/end dates, INSIDE interval
                domain_base = [
                    ('company_id', '=', sub.company_id.id),
                    ('journal_id', 'in', self.source_journal_ids.ids),
                    ('start_date', '!=', False),
                    ('end_date', '!=', False),
                    ('account_id', '=', sub.account_id.id),
                    ('analytic_account_id', '=',
                        sub.analytic_account_id.id or False),
                    ]
                inside_res = aml_obj.read_group(
                    domain_base + [
                        ('start_date', '>=', start_date),
                        ('end_date', '<=', end_date),
                    ], ['balance'], [])
                amount_inside = inside_res and inside_res[0]['balance'] or 0
                amount += amount_inside * sign
                # 3. Start/end dates, OVER interval
                mlines = aml_obj.search(
                    domain_base + [
                        ('start_date', '<', start_date),
                        ('end_date', '>', end_date),
                    ])
                for mline in mlines:
                    total_days = (
                        fields.Date.from_string(mline.end_date) -
                        fields.Date.from_string(mline.start_date)
                        ).days + 1
                    days_in_interval = (end_date - start_date).days + 1
                    amount_in_interval = mline.balance *\
                        days_in_interval / float(total_days)
                    amount += amount_in_interval * sign
                # 4. Start/end dates, start_date before, end_date inside
                mlines = aml_obj.search(
                    domain_base + [
                        ('start_date', '<', start_date),
                        ('end_date', '>=', start_date),
                        ('end_date', '<=', end_date),
                        ])
                for mline in mlines:
                    total_days = (
                        fields.Date.from_string(mline.end_date) -
                        fields.Date.from_string(mline.start_date)
                        ).days + 1
                    days_in_interval = (
                        fields.Date.from_string(mline.end_date)
                        - start_date).days + 1
                    amount_in_interval = mline.balance *\
                        days_in_interval / float(total_days)
                    amount += amount_in_interval * sign
                # 5. Start/end dates, start_date inside, end_date after
                mlines = aml_obj.search(
                    domain_base + [
                        ('start_date', '>=', start_date),
                        ('start_date', '<=', end_date),
                        ('end_date', '>', end_date),
                        ])
                for mline in mlines:
                    total_days = (
                        fields.Date.from_string(mline.end_date) -
                        fields.Date.from_string(mline.start_date)
                        ).days + 1
                    days_in_interval = (
                        end_date -
                        fields.Date.from_string(mline.start_date)).days + 1
                    amount_in_interval = mline.balance *\
                        days_in_interval / float(total_days)
                    amount += amount_in_interval * sign

                work[sub]['intervals'].append({
                    'start': start_date,<commit_msg>[FIX] Add partner_id in domain when searching account moves<commit_after># -*- coding: utf-8 -*-
# Copyright 2019 Akretion France (http://www.akretion.com/)
# @author: <NAME> <<EMAIL>>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models, fields, _
from odoo.exceptions import UserError
from dateutil.relativedelta import relativedelta
from odoo.tools import float_compare, float_round


class AccountCutoff(models.Model):
    _inherit = 'account.cutoff'

    def get_lines(self):
        res = super(AccountCutoff, self).get_lines()
        if self.type not in ['accrued_expense', 'accrued_revenue']:
            return res
        aml_obj = self.env['account.move.line']
        line_obj = self.env['account.cutoff.line']
        sub_obj = self.env['account.cutoff.accrual.subscription']
        type2subtype = {
            'accrued_expense': 'expense',
            'accrued_revenue': 'revenue',
            }
        sub_type = type2subtype[self.type]
        sign = sub_type == 'revenue' and -1 or 1
        subs = sub_obj.search([
            ('company_id', '=', self.company_id.id),
            ('subscription_type', '=', sub_type),
            ('start_date', '<=', self.cutoff_date),
            ])
        cutoff_date = fields.Date.from_string(self.cutoff_date)
        if subs:
            # check that the cutoff is the last day of a month
            # otherwise, we have pb with when we compute intervals
            # with cutoff date is a day which is not present for all months
            last_day_same_month = cutoff_date + relativedelta(day=31)
            if last_day_same_month.day != cutoff_date.day:
                raise UserError(_(
                    "The cutoffs with subscription only work when the cutoff "
                    "date (%s) is the last day of a month.")
                    % self.cutoff_date)
            if not self.source_journal_ids:
                raise UserError(_('Missing source journals.'))
        periodicity2months = {
            'month': 1,
            'quarter': 3,
            'semester': 6,
            'year': 12,
            }
        company_currency = self.company_currency_id
        prec = company_currency.rounding
        work = {}
        # Generate time intervals and computing existing expenses/revenue
        for sub in subs:
            sub_start_date_dt = fields.Date.from_string(sub.start_date)
            months = periodicity2months[sub.periodicity]
            work[sub] = {'intervals': []}
            end_date = cutoff_date
            for i in range(12 / months):
                start_date = end_date + relativedelta(
                    day=1, months=-(months-1))
                if start_date < sub_start_date_dt:
                    break
                # compute amount
                domain_base = [
                    ('company_id', '=', sub.company_id.id),
                    ('journal_id', 'in', self.source_journal_ids.ids),
                    ('account_id', '=', sub.account_id.id),
                    ('analytic_account_id', '=',
                        sub.analytic_account_id.id or False),
                    ('partner_id', '=', sub.partner_id.id),
                    ]
                domain_base_w_start_end = domain_base + [
                    ('start_date', '!=', False),
                    ('end_date', '!=', False),
                    ]
                amount = 0
                # 1. No start/end dates
                no_start_end_res = aml_obj.read_group(
                    domain_base + [
                        ('date', '<=', fields.Date.to_string(end_date)),
                        ('date', '>=', fields.Date.to_string(start_date)),
                        ('start_date', '=', False),
                        ('end_date', '=', False),
                    ], ['balance'], [])
                amount_no_start_end = no_start_end_res and\
                    no_start_end_res[0]['balance'] or 0
                amount += amount_no_start_end * sign
                # 2. Start/end dates, INSIDE interval
                inside_res = aml_obj.read_group(
                    domain_base_w_start_end + [
                        ('start_date', '>=', start_date),
                        ('end_date', '<=', end_date),
                    ], ['balance'], [])
                amount_inside = inside_res and inside_res[0]['balance'] or 0
                amount += amount_inside * sign
                # 3. Start/end dates, OVER interval
                mlines = aml_obj.search(
                    domain_base_w_start_end + [
                        ('start_date', '<', start_date),
                        ('end_date', '>', end_date),
                    ])
                for mline in mlines:
                    total_days = (
                        fields.Date.from_string(mline.end_date) -
                        fields.Date.from_string(mline.start_date)
                        ).days + 1
                    days_in_interval = (end_date - start_date).days + 1
                    amount_in_interval = mline.balance *\
                        days_in_interval / float(total_days)
                    amount += amount_in_interval * sign
                # 4. Start/end dates, start_date before, end_date inside
                mlines = aml_obj.search(
                    domain_base_w_start_end + [
                        ('start_date', '<', start_date),
                        ('end_date', '>=', start_date),
                        ('end_date', '<=', end_date),
                        ])
                for mline in mlines:
                    total_days = (
                        fields.Date.from_string(mline.end_date) -
                        fields.Date.from_string(mline.start_date)
                        ).days + 1
                    days_in_interval = (
                        fields.Date.from_string(mline.end_date)
                        - start_date).days + 1
                    amount_in_interval = mline.balance *\
                        days_in_interval / float(total_days)
                    amount += amount_in_interval * sign
                # 5. Start/end dates, start_date inside, end_date after
                mlines = aml_obj.search(
                    domain_base_w_start_end + [
                        ('start_date', '>=', start_date),
                        ('start_date', '<=', end_date),
                        ('end_date', '>', end_date),
                        ])
                for mline in mlines:
                    total_days = (
                        fields.Date.from_string(mline.end_date) -
                        fields.Date.from_string(mline.start_date)
                        ).days + 1
                    days_in_interval = (
                        end_date -
                        fields.Date.from_string(mline.start_date)).days + 1
                    amount_in_interval = mline.balance *\
                        days_in_interval / float(total_days)
                    amount += amount_in_interval * sign

                work[sub]['intervals'].append({
                    'start': start_date,
{'fraction_non_alphanumeric': 0.10571328426218016, 'fraction_numerical': 0.005608131791097091, 'mean_word_length': 1.3475399045581702, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7148748', 'n_tokens_mistral': 4005, 'n_tokens_neox': 3724, 'n_words': 763}