mirror of
https://github.com/bringout/oca-mrp.git
synced 2026-04-25 00:12:02 +02:00
Initial commit: OCA Mrp packages (117 packages)
This commit is contained in:
commit
277e84fd7a
4403 changed files with 395154 additions and 0 deletions
|
|
@ -0,0 +1,4 @@
|
|||
from . import account_analytic_line
|
||||
from . import project_project
|
||||
from . import sale
|
||||
from . import account_move
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
# Copyright 2019 Camptocamp SA
|
||||
# Copyright 2020 Tecnativa - Pedro M. Baeza
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.tools.float_utils import float_round
|
||||
|
||||
|
||||
class AccountAnalyticLine(models.Model):
|
||||
|
||||
_inherit = "account.analytic.line"
|
||||
|
||||
unit_amount_rounded = fields.Float(
|
||||
string="Quantity rounded",
|
||||
compute="_compute_unit_rounded",
|
||||
store=True,
|
||||
readonly=False,
|
||||
copy=False,
|
||||
)
|
||||
|
||||
@api.depends("timesheet_invoice_id.state")
|
||||
def _compute_project_id(self):
|
||||
field_rounded = self._fields["unit_amount_rounded"]
|
||||
if self._context.get("timesheet_no_recompute", False):
|
||||
self.env.remove_to_compute(field_rounded, self)
|
||||
return super()._compute_project_id()
|
||||
|
||||
@api.depends("project_id", "unit_amount")
|
||||
def _compute_unit_rounded(self):
|
||||
for record in self:
|
||||
record.unit_amount_rounded = record._calc_unit_amount_rounded()
|
||||
|
||||
def _calc_unit_amount_rounded(self):
|
||||
self.ensure_one()
|
||||
project_rounding = (
|
||||
self.project_id and self.project_id.timesheet_rounding_method != "NO"
|
||||
)
|
||||
if project_rounding:
|
||||
return self._calc_rounded_amount(
|
||||
self.project_id.timesheet_rounding_unit,
|
||||
self.project_id.timesheet_rounding_method,
|
||||
self.project_id.timesheet_rounding_factor,
|
||||
self.unit_amount,
|
||||
)
|
||||
else:
|
||||
return self.unit_amount
|
||||
|
||||
@staticmethod
|
||||
def _calc_rounded_amount(rounding_unit, rounding_method, factor, amount):
|
||||
factor = factor / 100.0
|
||||
if rounding_unit:
|
||||
unit_amount_rounded = float_round(
|
||||
amount * factor,
|
||||
precision_rounding=rounding_unit,
|
||||
rounding_method=rounding_method,
|
||||
)
|
||||
else:
|
||||
unit_amount_rounded = amount * factor
|
||||
return unit_amount_rounded
|
||||
|
||||
####################################################
|
||||
# ORM Overrides
|
||||
####################################################
|
||||
|
||||
@api.model
|
||||
def read_group(
|
||||
self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True
|
||||
):
|
||||
"""Replace the value of unit_amount by unit_amount_rounded.
|
||||
|
||||
When context key `timesheet_rounding` is True
|
||||
we change the value of unit_amount with the rounded one.
|
||||
This affects `sale_order_line._compute_delivered_quantity`
|
||||
which in turns compute the delivered qty on SO line.
|
||||
"""
|
||||
ctx_ts_rounded = self.env.context.get("timesheet_rounding")
|
||||
fields_local = list(fields) if fields else []
|
||||
if ctx_ts_rounded and "unit_amount_rounded" not in fields_local:
|
||||
# To add the unit_amount_rounded value on read_group
|
||||
fields_local.append("unit_amount_rounded")
|
||||
res = super().read_group(
|
||||
domain,
|
||||
fields_local,
|
||||
groupby,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
orderby=orderby,
|
||||
lazy=lazy,
|
||||
)
|
||||
if ctx_ts_rounded:
|
||||
# To set the unit_amount_rounded value instead of unit_amount
|
||||
for rec in res:
|
||||
rec["unit_amount"] = rec["unit_amount_rounded"]
|
||||
return res
|
||||
|
||||
def read(self, fields=None, load="_classic_read"):
|
||||
"""Replace the value of unit_amount by unit_amount_rounded.
|
||||
|
||||
When context key `timesheet_rounding` is True
|
||||
we change the value of unit_amount with the rounded one.
|
||||
This affects `account_analytic_line._sale_determine_order_line`.
|
||||
"""
|
||||
ctx_ts_rounded = self.env.context.get("timesheet_rounding")
|
||||
fields_local = list(fields) if fields else []
|
||||
read_unit_amount = "unit_amount" in fields_local or not fields_local
|
||||
if ctx_ts_rounded and read_unit_amount and fields_local:
|
||||
if "unit_amount_rounded" not in fields_local:
|
||||
# To add the unit_amount_rounded value on read
|
||||
fields_local.append("unit_amount_rounded")
|
||||
res = super().read(fields=fields_local, load=load)
|
||||
if ctx_ts_rounded and read_unit_amount:
|
||||
# To set the unit_amount_rounded value instead of unit_amount
|
||||
for rec in res:
|
||||
rec["unit_amount"] = rec["unit_amount_rounded"]
|
||||
return res
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# Copyright 2023 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class AccountMove(models.Model):
|
||||
|
||||
_inherit = "account.move"
|
||||
|
||||
def _post(self, soft=True):
|
||||
# We must avoid the recomputation of the unit amount rounded called by
|
||||
# the compute_project_id (especially when project has not been changed)
|
||||
return super(AccountMove, self.with_context(timesheet_no_recompute=True))._post(
|
||||
soft=soft
|
||||
)
|
||||
|
||||
def unlink(self):
|
||||
return super(
|
||||
AccountMove, self.with_context(timesheet_no_recompute=True)
|
||||
).unlink()
|
||||
|
||||
def button_cancel(self):
|
||||
return super(
|
||||
AccountMove, self.with_context(timesheet_no_recompute=True)
|
||||
).button_cancel()
|
||||
|
||||
def button_draft(self):
|
||||
return super(
|
||||
AccountMove, self.with_context(timesheet_no_recompute=True)
|
||||
).button_draft()
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# Copyright 2019 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ProjectProject(models.Model):
|
||||
|
||||
_inherit = "project.project"
|
||||
|
||||
timesheet_rounding_unit = fields.Float(
|
||||
string="Rounding Unit",
|
||||
default=0.0,
|
||||
help="""1.0 = hour
|
||||
0.25 = 15 min
|
||||
0.084 ~= 5 min
|
||||
0.017 ~= 1 min
|
||||
""",
|
||||
)
|
||||
timesheet_rounding_method = fields.Selection(
|
||||
string="Rounding method",
|
||||
selection=[
|
||||
("NO", "No rounding"),
|
||||
("UP", "Up"),
|
||||
("HALF_UP", "Closest"),
|
||||
("DOWN", "Down"),
|
||||
],
|
||||
default="NO",
|
||||
required=True,
|
||||
help="If you activate the rounding of timesheet lines, only new "
|
||||
"entries will be rounded (i.e. existing lines will not be "
|
||||
"rounded automatically).",
|
||||
)
|
||||
timesheet_rounding_factor = fields.Float(
|
||||
string="Timesheet rounding factor in percentage", default=100.0
|
||||
)
|
||||
|
||||
_sql_constraints = [
|
||||
(
|
||||
"check_timesheet_rounding_factor",
|
||||
"CHECK(0 <= timesheet_rounding_factor "
|
||||
"AND timesheet_rounding_factor <= 500)",
|
||||
"Timesheet rounding factor should stay between 0 and 500,"
|
||||
" endpoints included.",
|
||||
)
|
||||
]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2019 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class SaleOrderLine(models.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
def _get_delivered_quantity_by_analytic(self, additional_domain):
|
||||
# If we land here is only because we are dealing w/ SO lines
|
||||
# having `qty_delivered_method` equal to `analytic` or `timesheet`.
|
||||
# The 1st case matches expenses lines the latter TS lines.
|
||||
# Expenses are already discarded in our a.a.l. overrides
|
||||
# so it's fine to set the ctx key here anyway.
|
||||
return super(
|
||||
SaleOrderLine, self.with_context(timesheet_rounding=True)
|
||||
)._get_delivered_quantity_by_analytic(additional_domain)
|
||||
|
||||
@api.depends("analytic_line_ids.unit_amount_rounded")
|
||||
def _compute_qty_delivered(self):
|
||||
"""Adds the dependency on unit_amount_rounded."""
|
||||
return super()._compute_qty_delivered()
|
||||
Loading…
Add table
Add a link
Reference in a new issue