Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • coopdevs/comunitats-energetiques/odoo-ce
1 result
Show changes
Commits on Source (67)
Showing
with 638 additions and 59 deletions
......@@ -16,6 +16,7 @@
"base_technical_features",
"base_user_role",
"base_user_role_company",
"calendar",
"community_maps",
"contacts",
"event",
......
from . import collections
from .user_creator import UserCreator
from .contract_utils import ContractUtils
from .sale_order_utils import SaleOrderUtils
from odoo.addons.component.core import Component
class ContractUtils(Component):
_name = "contract.utils"
_usage = "contract.utils"
_apply_on = "contract.contract"
_collection = "utils.backend"
from odoo.addons.component.core import Component
class SaleOrderUtils(Component):
_name = "sale.order.utils"
_usage = "sale.order.utils"
_apply_on = "sale.order"
_collection = "utils.backend"
......@@ -30,6 +30,12 @@ class ResPartner(models.Model):
compute="compute_company_hierarchy_level",
store=True,
)
related_company_id = fields.Many2one(
"res.company",
string="Represented company",
compute="compute_related_company_id",
store=False,
)
company_ids_info = fields.Many2many(
string="Companies",
comodel_name="res.company",
......@@ -53,11 +59,22 @@ class ResPartner(models.Model):
def compute_company_hierarchy_level(self):
for record in self:
rel_company = self.env["res.company"].search(
[("partner_id", "=", record.id)]
record.company_hierarchy_level = "none"
if record.related_company_id:
record.company_hierarchy_level = (
record.related_company_id.hierarchy_level
)
def compute_related_company_id(self):
for record in self:
record.related_company_id = False
related_company_id = (
self.env["res.company"]
.sudo()
.search([("partner_id", "=", record.id)], limit=1)
)
if rel_company:
record.company_hierarchy_level = rel_company.hierarchy_level
if related_company_id:
record.related_company_id = related_company_id[0].id
@api.constrains("company_ids")
def _constrains_partner_company_ids(self):
......
<?xml version="1.0" ?>
<odoo>
<record model="ir.rule" id="landing_page_company_rule">
<field name="name">Landing Page multi-company</field>
<field name="model_id" ref="energy_communities.model_landing_page" />
<field name="global" eval="True" />
<field
name="domain_force"
>['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
<field name="domain_force">
['|',('company_id', '=', False),('company_id', 'in', company_ids)]
</field>
</record>
<record model="ir.rule" id="mail_message_company_rule">
<field name="name">mail.message multi-company</field>
<field name="model_id" ref="mail.model_mail_message" />
<field name="global" eval="True" />
<field name="domain_force">['|', ('author_id.company_ids', '=', False),
('author_id.company_ids', 'in', company_ids)]</field>
<field name="domain_force">
['|',('author_id.company_ids', '=', False),('author_id.company_ids', 'in', company_ids)]
</field>
</record>
<record model="ir.rule" id="mail_followers_company_rule">
<field name="name">mail.followers multi-company</field>
<field name="model_id" ref="mail.model_mail_followers" />
<field name="global" eval="True" />
<field name="domain_force">['|', ('partner_id.company_ids', '=', False),
('partner_id.company_ids', 'in', company_ids)]</field>
<field name="domain_force">
['|',('partner_id.company_ids', '=', False),('partner_id.company_ids', 'in', company_ids)]
</field>
</record>
<record model="ir.rule" id="mail_activity_company_rule">
<field name="name">mail.activity multi-company</field>
<field name="model_id" ref="mail.model_mail_activity" />
<field name="global" eval="True" />
<field name="domain_force">['|', ('user_id.partner_id.company_ids', '=', False),
('user_id.partner_id.company_ids', 'in', company_ids)]
<field name="domain_force">
['|',('user_id.partner_id.company_ids', '=', False),('user_id.partner_id.company_ids', 'in', company_ids)]
</field>
</record>
......@@ -45,9 +46,9 @@
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
<field
name="domain_force"
>['|', ('company_ids', '=', False), ('company_ids', 'in', company_ids)]</field>
<field name="domain_force">
['|',('company_ids', '=', False),('company_ids', 'in', company_ids)]
</field>
</record>
<function name="write" model="ir.model.data">
<function name="search" model="ir.model.data">
......@@ -58,9 +59,7 @@
<function name="write" model="ir.model.data">
<function name="search" model="ir.model.data">
<value
eval="[('module', '=', 'base'),('name', '=', 'res_partner_rule_private_employee')]"
/>
<value eval="[('module', '=', 'base'),('name', '=', 'res_partner_rule_private_employee')]"/>
</function>
<value eval="{'noupdate': False}" />
</function>
......@@ -69,9 +68,7 @@
</record>
<function name="write" model="ir.model.data">
<function name="search" model="ir.model.data">
<value
eval="[('module', '=', 'base'),('name', '=', 'res_partner_rule_private_employee')]"
/>
<value eval="[('module', '=', 'base'),('name', '=', 'res_partner_rule_private_employee')]"/>
</function>
<value eval="{'noupdate': True}" />
</function>
......@@ -80,9 +77,16 @@
<field name="name">res.partner multi-company</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="groups" eval="[(4, ref('base.group_user'))]" />
<field
name="domain_force"
>["&amp;","|",('company_ids', '=', False),('company_ids', 'in', company_ids),"|",('type', '!=', 'private'), ('type', '=', False)]</field>
<field name="domain_force">
[
'&amp;','|',
('company_ids', '=', False),
('company_ids', 'in', company_ids),
'|',
('type', '!=', 'private'),
('type', '=', False)
]
</field>
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
......@@ -93,9 +97,15 @@
<field name="name">res.partner Platform-admin multi-company</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="groups" eval="[(4, ref('base.group_user'))]" />
<field
name="domain_force"
>['&amp;',('user_current_role', '=', 'role_platform_admin'),'|', ('type', '!=', 'private'), ('type', '=', False)]</field>
<field name="domain_force">
[
'&amp;',
('user_current_role', '=', 'role_platform_admin'),
'|',
('type', '!=', 'private'),
('type', '=', False)
]
</field>
<field name="perm_read" eval="False" />
<field name="perm_write" eval="True" />
<field name="perm_create" eval="True" />
......@@ -106,9 +116,16 @@
<field name="name">res.partner Coordinator-admin-worker multi-company</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="groups" eval="[(4, ref('base.group_user'))]" />
<field
name="domain_force"
>['&amp;','&amp;',('user_current_role', 'in', ['role_coord_admin','role_coord_worker']),('company_hierarchy_level','!=','instance'),'|', ('type', '!=', 'private'), ('type', '=', False)]</field>
<field name="domain_force">
[
'&amp;','&amp;',
('user_current_role', 'in', ['role_coord_admin','role_coord_worker']),
('company_hierarchy_level','!=','instance'),
'|',
('type', '!=', 'private'),
('type', '=', False)
]
</field>
<field name="perm_read" eval="False" />
<field name="perm_write" eval="True" />
<field name="perm_create" eval="True" />
......@@ -119,9 +136,16 @@
<field name="name">res.partner Community-manager-admin multi-company</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="groups" eval="[(4, ref('base.group_user'))]" />
<field
name="domain_force"
>['&amp;','&amp;',('user_current_role', 'in', ['role_ce_manager','role_ce_admin']),('company_hierarchy_level','not in',['instance','coordinator']),'|', ('type', '!=', 'private'), ('type', '=', False)]</field>
<field name="domain_force">
[
'&amp;','&amp;',
('user_current_role', 'in', ['role_ce_manager','role_ce_admin']),
('company_hierarchy_level','not in',['instance','coordinator']),
'|',
('type', '!=', 'private'),
('type', '=', False)
]
</field>
<field name="perm_read" eval="False" />
<field name="perm_write" eval="True" />
<field name="perm_create" eval="True" />
......@@ -133,11 +157,12 @@
<field name="model_id" ref="account_reconcile_oca.model_account_account_reconcile"/>
<field name="groups" eval="[(4, ref('base.group_user'))]" />
<field name="domain_force">
[('company_id', 'in', company_ids)]
[('company_id', 'in', company_ids)]
</field>
<field name="perm_read" eval="True" />
<field name="perm_write" eval="True" />
<field name="perm_create" eval="True" />
<field name="perm_unlink" eval="False" />
</record>
</odoo>
from contextlib import contextmanager
from typing import Any
from odoo.api import Environment
from odoo.tools.translate import code_translations
from odoo.addons.component.core import Component, WorkContext
from odoo.addons.contract.models.contract import ContractContract
def _get_component(
env: Environment, model_name: str, usage: str, record: Any = None
) -> Component:
backend = env["utils.backend"].browse(1)
work = WorkContext(model_name=model_name, collection=backend, record=record)
return work.component(usage=usage)
@contextmanager
def user_creator(
env: Environment,
) -> Component:
backend = env["utils.backend"].browse(1)
work = WorkContext(
model_name="res.users",
collection=backend,
)
yield work.component(usage="user.create")
yield _get_component(env, "res.users", "user.create")
@contextmanager
def contract_utils(
env: Environment,
contract_id: ContractContract,
) -> Component:
yield _get_component(env, "contract.contract", "contract.utils", contract_id)
@contextmanager
def sale_order_utils(
env: Environment,
) -> Component:
yield _get_component(env, "sale.order", "sale.order.utils")
def get_translation(source, lang, mods):
......
......@@ -4,31 +4,86 @@
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<menuitem
<record
id="view_ec_formulas_window"
model="ir.actions.act_window"
>
<field name="name">Formulas (quantity)</field>
<field name="res_model">contract.line.qty.formula</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
id="ce_root_menu"
name="Energy Communities"
name="Community Management"
sequence="10"
groups="group_platform_manager"
groups="role_platform_admin_res_groups,role_coord_admin_res_groups,role_coord_worker_res_groups,role_ce_admin,role_ce_manager"
web_icon="energy_communities,static/description/icon.png"
/>
<menuitem id="ce_config_menu" name="Configuration" parent="ce_root_menu" />
<menuitem
<!--<menuitem-->
<!-- id="ce_root_menu_coord_admin"-->
<!-- name="Coordinator management"-->
<!-- sequence="10"-->
<!-- groups="role_coord_admin_res_groups,role_coord_worker_res_groups"-->
<!-- web_icon="energy_communities,static/description/icon.png"-->
<!--/>-->
<!--<menuitem-->
<!-- id="ce_root_menu_community_admin"-->
<!-- name="Community management"-->
<!-- sequence="10"-->
<!-- groups="role_ce_admin,role_ce_manager"-->
<!-- web_icon="energy_communities,static/description/icon.png"-->
<!--/>-->
<menuitem
id="ce_assistants_menu"
name="Assistants"
parent="ce_root_menu"
groups="role_platform_admin_res_groups"
sequence="99"
/>
<menuitem
id="ce_config_menu"
name="Configuration"
parent="ce_root_menu"
groups="role_platform_admin_res_groups"
sequence="999"
/>
<menuitem
id="ce_config_sources_menu"
name="Source types"
parent="ce_config_menu"
action="ce_utm_sources_action"
groups="group_platform_manager"
/>
<menuitem
<menuitem
id="energy_actions_menu"
name="Energy actions"
parent="ce_config_menu"
action="energy_action_views"
groups="group_platform_manager"
/>
<menuitem
id="ec_formulas_menu"
name="Formulas"
parent="ce_config_menu"
action="view_ec_formulas_window"
groups="group_platform_manager"
/>
<!-- Hide menu items unless platform manager -->
<record model="ir.ui.menu" id="mail.menu_root_discuss">
<field name="groups_id" eval="[(6,0,[ref('group_platform_manager')])]" />
</record>
<record model="ir.ui.menu" id="calendar.mail_menu_calendar">
<field name="groups_id" eval="[(6,0,[ref('group_platform_manager')])]" />
</record>
<record model="ir.ui.menu" id="base.menu_board_root">
<field name="groups_id" eval="[(6,0,[ref('group_platform_manager')])]" />
</record>
<record model="ir.ui.menu" id="spreadsheet_dashboard.spreadsheet_dashboard_menu_root">
<field name="groups_id" eval="[(6,0,[ref('group_platform_manager')])]" />
</record>
<record model="ir.ui.menu" id="community_maps.menu_root">
<field name="groups_id" eval="[(6,0,[ref('group_platform_manager')])]" />
</record>
......
......@@ -46,20 +46,21 @@
<xpath expr="//field[@name='vat']" position="after">
<field name="company_hierarchy_level" invisible="1" />
<field name="user_current_role" />
<field name="related_company_id" options="{'no_open': True}" readonly="1" attrs="{'invisible': [('company_hierarchy_level', '=', 'none')]}" />
</xpath>
<xpath expr="//field[@name='name']" position="before">
<h4
style="color:green;"
attrs="{'invisible': [('company_hierarchy_level', '!=', 'instance')]}"
>Platform company</h4>
style="color:green;"
attrs="{'invisible': [('company_hierarchy_level', '!=', 'instance')]}"
>Platform company</h4>
<h4
style="color:green;"
attrs="{'invisible': [('company_hierarchy_level', '!=', 'coordinator')]}"
>Coordinator company</h4>
style="color:green;"
attrs="{'invisible': [('company_hierarchy_level', '!=', 'coordinator')]}"
>Coordinator company</h4>
<h4
style="color:green;"
attrs="{'invisible': [('company_hierarchy_level', '!=', 'community')]}"
>Community company</h4>
style="color:green;"
attrs="{'invisible': [('company_hierarchy_level', '!=', 'community')]}"
>Community company</h4>
</xpath>
<xpath expr="//field[@name='child_ids']" position="after">
<label
......
from . import components
from . import models
from . import wizards
{
"name": "energy_communities_service_invoicing",
"summary": """
Short (1 phrase/line) summary of the module's purpose, used as
subtitle on modules listing or apps.openerp.com""",
"description": """
Long description of module's purpose
""",
"author": "Som comunitats",
"website": "https://coopdevs.org",
"category": "Contract Management",
"version": "16.0.0.1.1",
# any module necessary for this one to work correctly
"depends": [
"base",
"contract",
"sale",
"purchase",
"product",
"product_contract",
"contract_variable_quantity",
"energy_communities",
"energy_communities_cooperator", # TODO: This dependency is needed for active members formula. Need to refactor this.
],
# always loaded
"data": [
"security/ir.model.access.csv",
"security/ir_rule_data.xml",
"data/contract_cron.xml",
"data/contract_line_qty_formula_data.xml",
"data/product_data.xml",
"views/contract_line_formula_views.xml",
"views/contract_template_views.xml",
"views/contract_views.xml",
"views/res_company_views.xml",
"views/res_partner_views.xml",
"views/sale_order_views.xml",
"views/service_invoicing_views.xml",
"views/menus.xml",
"wizards/service_invoicing_action.xml",
"wizards/service_invoicing_action_create.xml",
],
# only loaded in demonstration mode
"demo": [],
}
from . import contract_utils
from . import sale_order_utils
from odoo.addons.component.core import Component
class ContractUtils(Component):
_inherit = "contract.utils"
def setup_initial_data(self):
for line in self.work.record.contract_line_ids:
line.write(
{
"ordered_qty_type": line.qty_type,
"ordered_quantity": line.quantity,
"ordered_qty_formula_id": line.qty_formula_id.id,
"qty_type": "fixed",
"quantity": 0,
}
)
self.work.record.write({"status": "paused"})
def _activate_contract_lines(self, execution_date):
for line in self.work.record.contract_line_ids:
line.write(
{
"date_start": execution_date,
"next_period_date_start": execution_date,
"recurring_next_date": execution_date,
"last_date_invoiced": None,
"qty_type": line.ordered_qty_type,
"quantity": line.ordered_quantity,
"qty_formula_id": line.ordered_qty_formula_id.id,
}
)
line._compute_state()
def set_contract_status_active(self, execution_date):
self._activate_contract_lines(execution_date)
self.set_start_date(execution_date)
self.work.record.write({"status": "in_progress"})
def set_contract_status_closed(self, execution_date):
for line in self.work.record.contract_line_ids:
if self.work.record.status == "paused" or self.work.record.is_free_pack:
self._activate_contract_lines(execution_date)
line.write({"date_end": execution_date})
line._compute_state()
self.work.record.set_close_status_type_by_date()
def set_start_date(self, date_start):
self.work.record.write({"date_start": date_start})
for line in self.work.record.contract_line_ids:
line.write({"date_start": date_start})
line._compute_state()
def set_discount(self, discount):
for line in self.work.record.contract_line_ids:
line.write({"discount": discount})
def set_configuration_service_invoicing_journal_if_defined(self):
journal_id = self.work.record.company_id.service_invoicing_journal_id
if journal_id:
self.work.record.write({"journal_id": journal_id.id})
def clean_non_service_lines(self):
for line in self.work.record.contract_line_ids:
if not self._is_service_line(line):
line.cancel()
line.unlink()
def modify(
self,
execution_date,
executed_modification_action,
pricelist_id=None,
service_pack_id=None,
discount=None,
payment_mode_id=None,
):
initial_status = self.work.record.status
# TODO: control closing date in order to being able modify contract with previous date.
# on contract line:
# skip last_date_invoice validation for modification action if contract is ready to start or active on free plan.
self.set_contract_status_closed(execution_date)
sale_order_utils = self.component(
usage="sale.order.utils", model_name="sale.order"
)
service_invoicing_params = self._build_service_invoicing_params(
"modification",
executed_modification_action,
execution_date,
pricelist_id,
service_pack_id,
discount,
payment_mode_id,
)
new_service_invoicing_id = sale_order_utils.create_service_invoicing_initial(
**service_invoicing_params
)
# TODO:
# Do we really want new contract to be in_progress on a modification??
# if initial_status == "in_progress" and not self.work.record.is_free_pack:
# self.set_contract_status_active()
self._setup_successors_and_predecessors(new_service_invoicing_id)
return new_service_invoicing_id
def reopen(
self,
execution_date,
pricelist_id=None,
service_pack_id=None,
discount=None,
payment_mode_id=None,
):
self.set_contract_status_closed(execution_date)
new_service_invoicing_id = self.component(
usage="sale.order.utils", model_name="sale.order"
).create_service_invoicing_initial(
**self._build_service_invoicing_params(
"reopen",
"modify_service_pack,modify_pricelist,modify_discount,modify_payment_mode",
execution_date,
pricelist_id,
service_pack_id,
discount,
payment_mode_id,
)
)
self._setup_successors_and_predecessors(new_service_invoicing_id)
return new_service_invoicing_id
def _build_service_invoicing_params(
self,
executed_action,
executed_action_description,
execution_date,
pricelist_id=None,
service_pack_id=None,
discount=None,
payment_mode_id=None,
):
executed_action_description_list = executed_action_description.split(",")
return {
"company_id": self.work.record.partner_id.related_company_id,
"community_company_id": self.work.record.community_company_id,
"service_pack_id": service_pack_id
if "modify_service_pack" in executed_action_description_list
else self.work.record.service_pack_id,
"pricelist_id": pricelist_id
if "modify_pricelist" in executed_action_description_list
else self.work.record.pricelist_id,
"payment_mode_id": payment_mode_id
if "modify_payment_mode" in executed_action_description_list
else self.work.record.payment_mode_id,
"start_date": execution_date,
"executed_action": executed_action,
"executed_action_description": executed_action_description,
"discount": discount
if "modify_discount" in executed_action_description_list
else self.work.record.discount,
}
def _is_service_line(self, contract_line):
if self.work.record.contract_template_id:
contract_template_services = (
self.work.record.contract_template_id.contract_line_ids.mapped(
"product_id"
)
)
return contract_line.product_id in contract_template_services
return False
def _setup_successors_and_predecessors(self, new_service_invoicing_id):
self.work.record.write({"successor_contract_id": new_service_invoicing_id.id})
new_service_invoicing_id.write({"predecessor_contract_id": self.work.record.id})
from odoo.addons.component.core import Component
from odoo.addons.energy_communities.utils import contract_utils
class SaleOrderUtils(Component):
_inherit = "sale.order.utils"
def create_service_invoicing_sale_order(
self,
company_id,
community_company_id,
service_pack_id,
pricelist_id,
payment_mode_id,
start_date,
executed_action,
executed_action_description,
):
so_creation_dict = {
"partner_id": company_id.partner_id.id,
# "company_id": company_id.id,
"community_company_id": community_company_id.id,
"pricelist_id": pricelist_id.id,
"service_invoicing_action": executed_action,
"service_invoicing_action_description": executed_action_description,
"payment_mode_id": payment_mode_id.id,
"order_line": [
(
0,
0,
{
"product_id": service_pack_id.id,
"date_start": start_date,
"date_end": start_date,
},
)
],
}
sale_order = self.env["sale.order"].create(so_creation_dict)
# Trigger name computattion in oder to include product's description_sale
for order_line in sale_order.order_line:
order_line._compute_name()
return self.env["sale.order"].create(so_creation_dict)
def _create_service_invoicing(
self,
company_id,
community_company_id,
service_pack_id,
pricelist_id,
payment_mode_id,
start_date,
discount,
executed_action,
executed_action_description="none",
):
so = self.create_service_invoicing_sale_order(
company_id,
community_company_id,
service_pack_id,
pricelist_id,
payment_mode_id,
start_date,
executed_action,
executed_action_description,
)
so.action_confirm()
service_invoicing_id = self._get_related_contracts(so)
# TODO: We must call contract_utils with a better component and workcontext modification approach
with contract_utils(self.env, service_invoicing_id) as component:
component.clean_non_service_lines()
component.set_start_date(start_date)
component.set_discount(discount)
component.set_configuration_service_invoicing_journal_if_defined()
return service_invoicing_id
def create_service_invoicing_initial(
self,
company_id,
community_company_id,
service_pack_id,
pricelist_id,
payment_mode_id,
start_date,
discount,
executed_action,
executed_action_description="none",
):
service_invoicing_id = self._create_service_invoicing(
company_id,
community_company_id,
service_pack_id,
pricelist_id,
payment_mode_id,
start_date,
discount,
executed_action,
executed_action_description,
)
# TODO: We must call contract_utils with a better component and workcontext modification approach
with contract_utils(self.env, service_invoicing_id) as component:
component.setup_initial_data()
if service_invoicing_id.is_free_pack:
component.set_contract_status_active(start_date)
return service_invoicing_id
def _get_related_contracts(self, sale_order):
return (
self.env["contract.line"]
.search([("sale_order_line_id", "in", sale_order.order_line.ids)])
.mapped("contract_id")
)
<odoo noupdate="1">
<record model="ir.cron" id="contract_cron_for_invoice_closure">
<field name="name">Close today's (closed planned) Contracts </field>
<field name="model_id" ref="model_contract_contract" />
<field name="state">code</field>
<field name="code">model.cron_close_todays_closed_planned_contacts()</field>
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
</record>
</odoo>
<odoo>
<data>
<record
id="community_members_formula"
model="contract.line.qty.formula"
>
<field name="name">Community members</field>
<field name="code">
result = env['cooperative.membership'].sudo().search_count([
('company_id','=',contract.community_company_id.id),
('member','=',True)
])
</field>
<field name="company_id" eval="ref('base.main_company')" />
</record>
</data>
</odoo>
<odoo>
<record id="product_category_pack" model="product.category">
<field name="name">Service Pack</field>
</record>
<record id="product_category_service" model="product.category">
<field name="name">Service</field>
</record>
</odoo>
from . import service_invoicing_info_mixin
from . import abstract_contract
from . import account_move
from . import contract
from . import contract_line
from . import contract_line_formula
from . import contract_template
from . import product_template
from . import res_company
from . import res_partner
from . import sale_order
from odoo import fields, models
class ContractAbstractContract(models.AbstractModel):
_inherit = "contract.abstract.contract"
_check_company_auto = False
company_id = fields.Many2one(
required=False,
default=None,
)
class ContractAbstractContractLine(models.AbstractModel):
_inherit = "contract.abstract.contract.line"
price_unit = fields.Float(
string="Unit Price",
compute="_compute_price_unit",
inverse="_inverse_price_unit",
digits="Product Price",
)
price_subtotal = fields.Float(
compute="_compute_price_subtotal", string="Sub Total", digits="Product Price"
)
from odoo import api, fields, models
class AccountMove(models.Model):
_inherit = "account.move"
ref_invoice_id = fields.Many2one(
compute="_compute_ref_invoice_id_and_is_pack", store=False
)
is_pack = fields.Boolean(compute="_compute_ref_invoice_id_and_is_pack", store=True)
@api.depends("invoice_line_ids", "ref")
def _compute_ref_invoice_id_and_is_pack(self):
for record in self:
record.ref_invoice_id = False
record.is_pack = False
rel_inv = False
if record.ref:
rel_inv = (
self.env["account.move"]
.sudo()
.search([("name", "=", record.ref)], limit=1)
)
if rel_inv:
record.ref_invoice_id = rel_inv.id
record.is_pack = rel_inv.is_pack
else:
if record.invoice_line_ids:
first_move_line = record.invoice_line_ids[0]
if first_move_line.contract_line_id:
record.is_pack = (
first_move_line.contract_line_id.contract_id.is_pack
)