Initial commit: Odoo 18.0-20251222 extra-addons
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

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
from . import res_company
from . import res_config_settings
from . import res_partner
from . import sale_order

View File

@@ -0,0 +1,20 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
from odoo import fields, models
class ResCompany(models.Model):
_inherit = "res.company"
invoicing_mode_monthly_day_todo = fields.Integer(
"Invoicing Day",
default="31",
help="Day of the month to execute the invoicing. For a number higher"
"than the number of days in a month, the invoicing will be"
"executed on the last day of the month.",
)
invoicing_mode_monthly_last_execution = fields.Datetime(
string="Last execution (monthly)",
help="Last execution of monthly invoicing.",
)

View File

@@ -0,0 +1,14 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
res_invoicing_mode_monthly_day_todo = fields.Integer(
related="company_id.invoicing_mode_monthly_day_todo", readonly=False
)
res_invoicing_mode_monthly_last_execution = fields.Datetime(
related="company_id.invoicing_mode_monthly_last_execution"
)

View File

@@ -0,0 +1,13 @@
# Copyright 2020 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html)
from odoo import fields, models
class ResPartner(models.Model):
_inherit = "res.partner"
invoicing_mode = fields.Selection(
selection_add=[("monthly", "Monthly")],
ondelete={"monthly": "set default"},
)

View File

@@ -0,0 +1,66 @@
# 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)