Files
Odoo-18.0-20251222/partner_invoicing_mode_monthly/models/sale_order.py
tocmo0nlord adbe430761
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled
Initial commit: Odoo 18.0-20251222 extra-addons
2026-03-13 20:43:25 +00:00

67 lines
2.5 KiB
Python

# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
from datetime import datetime
from dateutil.relativedelta import relativedelta
from odoo import api, models
from odoo.osv.expression import OR
class SaleOrder(models.Model):
_inherit = "sale.order"
@api.model
def cron_generate_monthly_invoices(self):
"""Cron called daily to check if monthly invoicing needs to be done."""
company_ids = self._company_monthly_invoicing_today()
if company_ids:
self.generate_monthly_invoices(company_ids)
@api.model
def generate_monthly_invoices(self, companies=None):
# TODO: Kept former function for backward compatibility. To remove
# in further version.
return self.generate_invoices(
companies,
invoicing_mode="monthly",
last_execution_field="invoicing_mode_monthly_last_execution",
)
@api.model
def _company_monthly_invoicing_today(self):
"""Get company ids for which today is monthly invoicing day."""
today = datetime.now()
first_day_this_month = today.replace(
day=1, hour=0, minute=0, second=0, microsecond=0
)
first_day_last_month = first_day_this_month - relativedelta(months=1)
last_day_of_this_month = (today + relativedelta(day=31)).day
# Last month still not executed, it needs to be done
domain_last_month = [
("invoicing_mode_monthly_last_execution", "<", first_day_last_month),
]
# Invoicing day is today or in the past and invoicing not yet done
domain_this_month = [
"|",
("invoicing_mode_monthly_last_execution", "<", first_day_this_month),
("invoicing_mode_monthly_last_execution", "=", False),
("invoicing_mode_monthly_day_todo", "<=", today.day),
]
# Make sure non exisiting days are done at the end of the month
domain_last_day_of_month = [
"|",
("invoicing_mode_monthly_last_execution", "<", first_day_this_month),
("invoicing_mode_monthly_last_execution", "=", False),
("invoicing_mode_monthly_day_todo", ">", today.day),
]
if today.day == last_day_of_this_month:
domain = OR(
[domain_last_month, domain_this_month, domain_last_day_of_month]
)
else:
domain = OR([domain_last_month, domain_this_month])
return self.env["res.company"].search(domain)