# Copyright 2023 Le Filament (https://le-filament.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from datetime import date from dateutil.relativedelta import relativedelta from odoo import api, fields, models class HallContract(models.Model): _inherit = "hall.contract" # ------------------------------------------------------ # Fields declaration # ------------------------------------------------------ # ------------------------------------------------------ # SQL Constrains # ------------------------------------------------------ # ------------------------------------------------------ # Compute functions # ------------------------------------------------------ # ------------------------------------------------------ # Action buttons # ------------------------------------------------------ def show_overview(self): self.ensure_one() action = self.env["ir.actions.actions"]._for_xml_id( "festa_dashboard.hall_contract_overview_action" ) action["context"] = { "active_id": self.id, "active_ids": self.ids, "active_test": False, "search_default_display_name": self.display_name, } return action @api.model def update_cashpad_values(self): self.search([("cashpad_id", "!=", False)]).get_sales() # ------------------------------------------------------ # Common functions # ------------------------------------------------------ def is_running(self, date_filter): """ :param date date_filter: date de référence """ self.ensure_one() if self.date_start <= date_filter and not self.date_end: return True elif self.date_start <= date_filter <= self.date_end: return True else: return False def get_overview(self): job_ids = ( self.env["queue.job"] .sudo() .search( [ ("model_name", "=", "hall.contract"), ("method_name", "=", "_import_sales"), ("state", "in", ["pending", "enqueued", "started", "failed"]), ] ) ) return { "contract_ids": self, "hall_ids": self.mapped("hall_id"), "company_id": self.env.company, "sales": self.get_overview_sales(), "flow": self.get_overview_flow(), "job_ids": job_ids, } def get_overview_flow(self): """ Get visitor & Passerby data """ yesterday = date.today() - relativedelta(days=1) start_year = date(yesterday.year, 1, 1) date(yesterday.year, yesterday.month, 1) flow_ids = self.env["hall.flow"].search( [ ("hall_id", "in", self.mapped("hall_id").ids), ("date", ">=", start_year), ] ) visitor_ids = flow_ids.filtered(lambda f: f.flow_type == "visitor") passerby_ids = flow_ids.filtered(lambda f: f.flow_type == "passerby") return { "visitor_ids": visitor_ids, "passerby_ids": passerby_ids, } # # # { # "visitor": sum(visitor_ids.filtered( # lambda f: f.date >= yesterday).mapped("count")), # "passerby": sum(passerby_ids.filtered( # lambda f: f.date >= yesterday).mapped("count")), # }, # "this_month": { # "visitor": sum(visitor_ids.filtered( # lambda f: f.date >= start_month).mapped("count")), # "passerby": sum(passerby_ids.filtered( # lambda f: f.date >= start_month).mapped("count")), # }, # "this_year": { # "visitor": sum(visitor_ids.mapped("count")), # "passerby": sum(passerby_ids.mapped("count")), # }, # } def get_overview_sales(self): """ Retourne les datas pour la vue QWEB """ today = date.today() yesterday = date.today() - relativedelta(days=1) start_year = date(yesterday.year, 1, 1) start_month = date(yesterday.year, yesterday.month, 1) start_last_month = start_month - relativedelta(months=1) end_last_month = start_month - relativedelta(days=1) return { "yesterday": self._get_sale_amount(yesterday, yesterday), "last_year": self._get_sale_amount( yesterday.replace(year=yesterday.year - 1), yesterday.replace(year=yesterday.year - 1), ), "this_month": self._get_sale_amount(start_month, today), "last_month": self._get_sale_amount(start_last_month, end_last_month), "this_year": self._get_sale_amount(start_year, today), "target_month": self._get_target(today.year, today.month), "target_last_month": self._get_target( start_last_month.year, start_last_month.month ), "target_year": self._get_target(today.year), "revenue_detail": self._get_revenue_detail(), "day": yesterday, "month": start_month, "year": start_year, } def _get_sale_amount(self, start, end): """ Retourne le montant HT des ventes en fonction de dates pour des contrats :param start date: :param end date: @returns float amount untaxed """ sale_ids = self.sale_ids.search( [ ("contract_id", "in", self.ids), ("day_date", ">=", start), ("day_date", "<=", end), ("is_test_datas", "=", False), ] ) total_sales = sum(sale_ids.mapped("sales_excl_taxes")) total_receipts = sum(sale_ids.mapped("nb_receipts")) average_sales = total_sales / total_receipts if total_receipts > 0 else 0 return { "total_sales": total_sales, "total_receipts": total_receipts, "average_sales": average_sales, } def _get_target(self, year, month=None): """ :param int year: :param int month: """ granularity = "month" if month else "year" month = month if month else 1 start = date(year, month, 1) end = fields.Date.end_of(start, granularity) target_ids = self.target_ids.search( [ ("contract_id", "in", self.ids), ("date_target", ">=", start), ("date_target", "<=", end), ] ) return sum(target_ids.mapped("amount_untaxed_target")) def _get_revenue_detail(self): if len(self) != 1: return False today = fields.Date.today() start = today.replace(day=1) - relativedelta(months=12) end = today.replace(day=1) target_report_ids = self.env["hall.contract.target.report"].search( [ ("contract_id", "=", self.id), ("day_date", ">=", start), ("day_date", "<=", end), ], order="day_date", limit=12, ) return target_report_ids