<commit_before>##############################################################################
#
#    Product - Average Consumption Module for Odoo
#    Copyright (C) 2013-Today GRAP (http://www.grap.coop)
#    @author <NAME>
#    @author <NAME> (https://twitter.com/legalsylvain)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
import datetime
from odoo import models, fields, api, _
from odoo.tools import pycompat
from odoo.tools.float_utils import float_round


class ProductProduct(models.Model):
    _inherit = "product.product"

    average_consumption = fields.Float(
        compute="_average_consumption", string="Average Consumption (max 365 days)"
    )
    total_consumption = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. max 365 days)"
    )
    average_consumption_15 = fields.Float(
        compute="_average_consumption", string="Average Consumption (15 days)"
    )
    total_consumption_15 = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. 15 days)"
    )
    average_consumption_30 = fields.Float(
        compute="_average_consumption", string="Average Consumption (30 days)"
    )
    total_consumption_30 = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. 30 days)"
    )
    average_consumption_90 = fields.Float(
        compute="_average_consumption", string="Average Consumption (90 days)"
    )
    total_consumption_90 = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. 90 days)"
    )
    nb_days = fields.Float(
        compute="_average_consumption",
        string="Number of days for the calculation",
        help="""The calculation will be done for the last 365 days or"""
        """ since the first purchase or sale of the product if it's"""
        """ more recent""",
    )

    @api.multi
    def _min_date(self):
        self.ensure_one()
        query = """SELECT to_char(min(date), 'YYYY-MM-DD') \
                from stock_move
                where product_id = %s
                GROUP BY product_id""" % (self.id)
        self.env.cr.execute(query)
        results = self.env.cr.fetchall()
        return results and results[0] and results[0][0] \
            or time.strftime('%Y-%m-%d')

    @api.multi
    def _create_date(self):
        self.ensure_one()
        query = """SELECT to_char(min(create_date), 'YYYY-MM-DD') \
                from stock_move
                where product_id = %s
                GROUP BY product_id""" % (
            self.id
        )
        self.env.cr.execute(query)
        results = self.env.cr.fetchall()
        return results and results[0] and results[0][0] or time.strftime("%Y-%m-%d")

    @api.multi
    def _write_date(self):
        self.ensure_one()
        query = """SELECT to_char(max(write_date), 'YYYY-MM-DD') \
                from stock_move
                where product_id = %s
                GROUP BY product_id""" % (
            self.id
        )
        self.env.cr.execute(query)
        results = self.env.cr.fetchall()
        return results and results[0] and results[0][0] or time.strftime("%Y-%m-%d")

    @api.multi
    def _average_consumption(self):
        self.refresh()
        product_consumption = self.calculate_average_days_dict(365)
        product_consumption_15 = self.calculate_average_days_dict(15)
        product_consumption_30 = self.calculate_average_days_dict(30)
        product_consumption_90 = self.calculate_average_days_dict(90)
        for product in self:
            product.nb_days = product_consumption[product.id]["nb_days"]
            product.average_consumption = product_consumption[product.id][
                "average_consumption"
            ]
            product.total_consumption = product_consumption[product.id][
                "total_consumption"
            ]
            product.average_consumption_15 = product_consumption_15[product.id][
                "average_consumption_15"
            ]
            product.total_consumption_15 = product_consumption_15[product.id][
                "total_consumption_15"
            ]
            product.average_consumption_30 = product_consumption_30[product.id][
                "average_consumption_30"
            ]
            product.total_consumption_30 = product_consumption_30[product.id][
                "total_consumption_30"
            ]
            product.average_consumption_90 = product_consumption_90[product.id][
                "average_consumption_90"
            ]
            product.total_consumption_90 = product_consumption_90[product.id][
                "total_consumption_90"
            ]
        return True

    @api.multi
    def calculate_average_days_dict(self, n_days):
        first_date = time.strftime("%Y-%m-%d")
        domain_move_out, begin_date, ctx = self.get_domain(self.ids, n_days)
        domain_move_out = self.extra_domain(domain_move_out)
        moves_out = self.env["stock.move"].read_group(
            domain_move_out, ["product_id", "product_qty"], ["product_id"]
        )
        moves_out = dict(
            map(lambda x: (x["product_id"][0], x["product_qty"]), moves_out)
        )
        product_consumption = {}
        order_date = (
            self.env["ir.config_parameter"]
            .sudo()
            .get_param("product_average_consumption_order_dates")
        )
        for product in self:
            product_consumption.setdefault(product.id, {})
            qty_out = float_round(
                moves_out.get(product.id, 0.0),
                precision_rounding=product.uom_id.rounding,
            )
            if order_date == "create_date":
                first_date = product._create_date()
            if order_date == "write_date":
                first_date = product._write_date()
            if n_days == 365:
                last_date = datetime.datetime.today()
                if ctx.get("force_from_date") and ctx.get("to_date"):
                    last_date = datetime.datetime.strptime(ctx["to_date"], "%Y-%m-%d")
                nb_days = (
                    last_date - datetime.datetime.strptime(first_date, "%Y-%m-%d")
                ).days or 1.0
                average_consumption = nb_days and qty_out / nb_days or 0.0
                total_consumption = qty_out or 0.0
                if total_consumption == 0:
                    nb_days = 0.0
                else:
                    nb_days = nb_days or 0.0
                product_consumption[product.id]["nb_days"] = nb_days
                product_consumption[product.id][
                    "average_consumption"
                ] = average_consumption
                product_consumption[product.id]["total_consumption"] = total_consumption
            elif n_days == 15:
                average_consumption_15 = qty_out / 15 or 0.0
                total_consumption_15 = qty_out or 0.0
                product_consumption[product.id][
                    "average_consumption_15"
                ] = average_consumption_15
                product_consumption[product.id][
                    "total_consumption_15"
                ] = total_consumption_15
            elif n_days == 30:
                average_consumption_30 = qty_out / 30 or 0.0
                total_consumption_30 = qty_out or 0.0<commit_msg>[FIX] Tener en cuenta fecha inicio en el cálculo del consumo promedio<commit_after>##############################################################################
#
#    Product - Average Consumption Module for Odoo
#    Copyright (C) 2013-Today GRAP (http://www.grap.coop)
#    @author <NAME>
#    @author <NAME> (https://twitter.com/legalsylvain)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import time
import datetime
from odoo import models, fields, api, _
from odoo.tools import pycompat
from odoo.tools.float_utils import float_round


class ProductProduct(models.Model):
    _inherit = "product.product"

    average_consumption = fields.Float(
        compute="_average_consumption", string="Average Consumption (max 365 days)"
    )
    total_consumption = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. max 365 days)"
    )
    average_consumption_15 = fields.Float(
        compute="_average_consumption", string="Average Consumption (15 days)"
    )
    total_consumption_15 = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. 15 days)"
    )
    average_consumption_30 = fields.Float(
        compute="_average_consumption", string="Average Consumption (30 days)"
    )
    total_consumption_30 = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. 30 days)"
    )
    average_consumption_90 = fields.Float(
        compute="_average_consumption", string="Average Consumption (90 days)"
    )
    total_consumption_90 = fields.Float(
        compute="_average_consumption", string="Total Consumption (ud. 90 days)"
    )
    nb_days = fields.Float(
        compute="_average_consumption",
        string="Number of days for the calculation",
        help="""The calculation will be done for the last 365 days or"""
        """ since the first purchase or sale of the product if it's"""
        """ more recent""",
    )

    @api.multi
    def _min_date(self):
        self.ensure_one()
        query = """SELECT to_char(min(date), 'YYYY-MM-DD') \
                from stock_move
                where product_id = %s
                GROUP BY product_id""" % (
            self.id
        )
        self.env.cr.execute(query)
        results = self.env.cr.fetchall()
        return results and results[0] and results[0][0] or time.strftime("%Y-%m-%d")

    @api.multi
    def _create_date(self):
        self.ensure_one()
        query = """SELECT to_char(min(create_date), 'YYYY-MM-DD') \
                from stock_move
                where product_id = %s
                GROUP BY product_id""" % (
            self.id
        )
        self.env.cr.execute(query)
        results = self.env.cr.fetchall()
        return results and results[0] and results[0][0] or time.strftime("%Y-%m-%d")

    @api.multi
    def _write_date(self):
        self.ensure_one()
        query = """SELECT to_char(max(write_date), 'YYYY-MM-DD') \
                from stock_move
                where product_id = %s
                GROUP BY product_id""" % (
            self.id
        )
        self.env.cr.execute(query)
        results = self.env.cr.fetchall()
        return results and results[0] and results[0][0] or time.strftime("%Y-%m-%d")

    @api.multi
    def _average_consumption(self):
        self.refresh()
        product_consumption = self.calculate_average_days_dict(365)
        product_consumption_15 = self.calculate_average_days_dict(15)
        product_consumption_30 = self.calculate_average_days_dict(30)
        product_consumption_90 = self.calculate_average_days_dict(90)
        for product in self:
            product.nb_days = product_consumption[product.id]["nb_days"]
            product.average_consumption = product_consumption[product.id][
                "average_consumption"
            ]
            product.total_consumption = product_consumption[product.id][
                "total_consumption"
            ]
            product.average_consumption_15 = product_consumption_15[product.id][
                "average_consumption_15"
            ]
            product.total_consumption_15 = product_consumption_15[product.id][
                "total_consumption_15"
            ]
            product.average_consumption_30 = product_consumption_30[product.id][
                "average_consumption_30"
            ]
            product.total_consumption_30 = product_consumption_30[product.id][
                "total_consumption_30"
            ]
            product.average_consumption_90 = product_consumption_90[product.id][
                "average_consumption_90"
            ]
            product.total_consumption_90 = product_consumption_90[product.id][
                "total_consumption_90"
            ]
        return True

    @api.multi
    def calculate_average_days_dict(self, n_days):
        first_date = time.strftime("%Y-%m-%d")
        domain_move_out, begin_date, ctx = self.get_domain(self.ids, n_days)
        domain_move_out = self.extra_domain(domain_move_out)
        moves_out = self.env["stock.move"].read_group(
            domain_move_out, ["product_id", "product_qty"], ["product_id"]
        )
        moves_out = dict(
            map(lambda x: (x["product_id"][0], x["product_qty"]), moves_out)
        )
        product_consumption = {}
        order_date = (
            self.env["ir.config_parameter"]
            .sudo()
            .get_param("product_average_consumption_order_dates")
        )
        for product in self:
            product_consumption.setdefault(product.id, {})
            qty_out = float_round(
                moves_out.get(product.id, 0.0),
                precision_rounding=product.uom_id.rounding,
            )
            if order_date == "create_date":
                first_date = product._create_date()
            if order_date == "write_date":
                first_date = product._write_date()
            if n_days == 365:
                last_date = datetime.datetime.today()
                if ctx.get("force_from_date"):
                    if ctx.get("to_date"):
                        last_date = datetime.datetime.strptime(
                            ctx["to_date"], "%Y-%m-%d"
                        )
                    if ctx.get("from_date"):
                        first_date = ctx["from_date"]
                nb_days = (
                    last_date - datetime.datetime.strptime(first_date, "%Y-%m-%d")
                ).days or 1.0
                average_consumption = nb_days and qty_out / nb_days or 0.0
                total_consumption = qty_out or 0.0
                if total_consumption == 0:
                    nb_days = 0.0
                else:
                    nb_days = nb_days or 0.0
                product_consumption[product.id]["nb_days"] = nb_days
                product_consumption[product.id][
                    "average_consumption"
                ] = average_consumption
                product_consumption[product.id]["total_consumption"] = total_consumption
            elif n_days == 15:
                average_consumption_15 = qty_out / 15 or 0.0
                total_consumption_15 = qty_out or 0.0
                product_consumption[product.id][
                    "average_consumption_15"
                ] = average_consumption_15
                product_consumption[product.id][
                    "total_consumption_15"
                ] = total_consumption_15
            elif n_days == 30:
                average_consumption_30 = qty_out / 30 or 0.0
                total_consumption_30 = qty_out or 0.0
{'fraction_non_alphanumeric': 0.11250686017440088, 'fraction_numerical': 0.017927922434294773, 'mean_word_length': 2.1490015360983103, 'pattern_counts': {'":': 4, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 2, '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': '3390817', 'n_tokens_mistral': 4930, 'n_tokens_neox': 4532, 'n_words': 999}