Newer
Older
# 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):
"""
Affiche le tableau de bors pour un contrat
"""
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,
"search_default_display_name": self.display_name,
}
return action
@api.model
def update_cashpad_values(self):
"""
Fonction de mise à jour de chargement des ventes depuis le Dashboard
"""
self.search([("cashpad_id", "!=", False)]).get_sales()
# ------------------------------------------------------
# Common functions
# ------------------------------------------------------
def is_running(self, date_filter):
"""
Fonction permettant de calculer si un contrat est en cours à une date donnée
: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
"""
Retourne les données pour la vue Qweb du Dashboard
"""
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,
}
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),
]
)
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):
"""
Retourne le CA cible pour une année ou un mois donné
:param int year: année
:param int month: mois
@returns monetary target: montant cible
"""
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):
"""
Retourne le détail du CA pour un contrat pour permettre l'affichage
détaillé par mois
Retourne False si il y a plus d'un contrat dans self
"""
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),
limit=12,
)
return target_report_ids