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 (25)
Showing
with 336 additions and 60 deletions
......@@ -28,6 +28,8 @@
"data/ir_sequence_data.xml",
"data/ir_attactment_data.xml",
"data/custom_paper_format_views.xml",
"data/contract_line_qty_formula_data.xml",
"views/contract_views.xml",
"views/selfconsumption_views.xml",
"views/supply_point_views.xml",
"views/res_partner_views.xml",
......@@ -37,6 +39,7 @@
"wizards/distribution_table_import_wizard_views.xml",
"wizards/contract_generation_wizard_views.xml",
"wizards/define_invoicing_mode_wizard_view.xml",
"wizards/invoicing_wizard_views.xml",
"reports/selfconsumption_reports.xml",
],
}
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record id="power_acquired_formula" model="contract.line.qty.formula">
<field name="name">Power Acquired Formula</field>
<field name="code">
days_timedelta = contract.next_period_date_end - contract.next_period_date_start
if days_timedelta:
# Add one so it counts the same day too (month = 29 + 1)
days_between = days_timedelta.days + 1
else:
days_between = 0
result = contract.supply_point_assignation_id.distribution_table_id.selfconsumption_project_id.power * contract.supply_point_assignation_id.coefficient * days_between
</field>
</record>
<record id="energy_delivered_formula" model="contract.line.qty.formula">
<field name="name">Energy Delivered Formula</field>
<field name="code">
days_timedelta = contract.next_period_date_end - contract.next_period_date_start
energy_delivered = 0
if days_timedelta:
# Add one so it counts the same day too (month = 29 + 1)
days_between = days_timedelta.days + 1
else:
days_between = 0
if 'energy_delivered' in context:
energy_delivered = context['energy_delivered']
result = energy_delivered * contract.supply_point_assignation_id.coefficient * days_between
</field>
</record>
<record
id="energy_delivered_variable_formula"
model="contract.line.qty.formula"
>
<field name="name">Energy Delivered Variable Formula</field>
<field name="code">
result = 0
</field>
</record>
</data>
</odoo>
......@@ -4,6 +4,5 @@ from . import partner
from . import distribution_table
from . import supply_point_assignation
from . import project
from . import contract_line
from . import contract
from . import product
......@@ -4,9 +4,61 @@ from odoo import fields, models
class Contract(models.Model):
_inherit = "contract.contract"
supply_point_assignation_id = fields.Many2one(
"energy_selfconsumption.supply_point_assignation",
string="Selfconsumption project",
)
project_id = fields.Many2one(
"energy_project.project",
ondelete="restrict",
string="Energy Project",
check_company=True,
related="supply_point_assignation_id.distribution_table_id.selfconsumption_project_id.project_id",
)
code = fields.Char(related="supply_point_assignation_id.supply_point_id.code")
supply_point_name = fields.Char(
related="supply_point_assignation_id.supply_point_id.name"
)
last_period_date_start = fields.Date(
string="Last Period Start",
readonly=True,
)
last_period_date_end = fields.Date(
string="Last Period End",
readonly=True,
)
def invoicing_wizard_action(self):
"""
We create the wizard first, so it triggers the constraint of the contract_ids
:return: Window action with the wizard already created
"""
wizard_id = self.env["energy_selfconsumption.invoicing.wizard"].create(
{"contract_ids": [(6, 0, self.ids)]}
)
action = self.env.ref(
"energy_selfconsumption.invoicing_wizard_act_window"
).read()[0]
action["res_id"] = wizard_id.id
return action
def _recurring_create_invoice(self, date_ref=False):
last_period_date_start = last_period_date_end = False
if len(self) > 1:
last_period_date_start = self[0].next_period_date_start
last_period_date_end = self[0].next_period_date_end
res = super()._recurring_create_invoice(date_ref=date_ref)
if res and last_period_date_start and last_period_date_end:
self.write(
{
"last_period_date_start": last_period_date_start,
"last_period_date_end": last_period_date_end,
}
)
return res
class ContractRecurrencyMixin(models.AbstractModel):
_inherit = "contract.recurrency.mixin"
next_period_date_start = fields.Date(store=True)
next_period_date_end = fields.Date(store=True)
from odoo import api, fields, models
class ContractLine(models.Model):
_inherit = "contract.line"
supply_point_assignation_id = fields.Many2one(
"energy_selfconsumption.supply_point_assignation",
string="Selfconsumption project",
)
......@@ -125,10 +125,18 @@ class Selfconsumption(models.Model):
return {
"type": "ir.actions.act_window",
"name": "Contracts",
"view_mode": "tree,form",
"views": [
[self.env.ref("energy_selfconsumption.contract_tree_view").id, "tree"],
[False, "form"],
],
"res_model": "contract.contract",
"domain": [("project_id", "=", self.id)],
"context": {"create": True, "default_project_id": self.id},
"context": {
"create": True,
"default_project_id": self.id,
"search_default_filter_next_period_date_start": True,
"search_default_filter_next_period_date_end": True,
},
}
def distribution_table_state(self, actual_state, new_state):
......
......@@ -72,7 +72,7 @@ class SupplyPointAssignation(models.Model):
@api.constrains("supply_point_id")
def constraint_supply_point_id(self):
for record in self:
supply_points = record.distribution_table_id.selfconsumption_project_id.project_id.inscription_ids.mapped(
supply_points = record.distribution_table_id.selfconsumption_project_id.inscription_ids.mapped(
"partner_id.supply_ids"
)
if record.supply_point_id.id not in supply_points.ids:
......
......@@ -12,3 +12,4 @@ access_energy_selfconsumption_distribution_table_import_wizard_admin,energy_self
access_energy_selfconsumption_contract_generation_wizard_admin,energy_selfconsumption.contract_generation.wizard.admin,model_energy_selfconsumption_contract_generation_wizard,energy_project.group_admin,1,1,1,1
accces_energy_selfconsumption_coefficient_report,energy_selfconsumption.coefficient_report.admin,model_energy_selfconsumption_coefficient_report,energy_project.group_admin,1,1,1,1
access_energy_elfconsumptionn_define_invoicing_mode_admin,energy_selfconsumption.define_invoicing_mode.wizard.admin,model_energy_selfconsumption_define_invoicing_mode_wizard,energy_project.group_admin,1,1,1,1
access_energy_selfconsumption_invoicing_wizard_admin,energy_selfconsumption.invoicing.wizard.admin,model_energy_selfconsumption_invoicing_wizard,energy_project.group_admin,1,1,1,1
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record id="contract_tree_view" model="ir.ui.view">
<field name="name">energy_selfconsumption.contract.tree</field>
<field name="model">contract.contract</field>
<field name="arch" type="xml">
<tree string="Contracts" expand="1">
<field name="partner_id" />
<field name="supply_point_name" />
<field name="code" />
<field name="next_period_date_start" />
<field name="next_period_date_end" />
<field name="last_period_date_start" />
<field name="last_period_date_end" />
</tree>
</field>
</record>
<record id="contract_search_view" model="ir.ui.view">
<field name="name">energy_selfconsumption.contract.search</field>
<field name="model">contract.contract</field>
<field name="inherit_id" ref="contract.contract_contract_search_view" />
<field name="arch" type="xml">
<xpath expr="/search" position="inside">
<group expand="1" string="Group By">
<filter
string="Next Period Date Start"
name="filter_next_period_date_start"
domain="[]"
context="{'group_by':'next_period_date_start'}"
/>
<filter
string="Next Period Date End"
name="filter_next_period_date_end"
domain="[]"
context="{'group_by':'next_period_date_end'}"
/>
</group>
</xpath>
</field>
</record>
<record id="contract_invoicing_wizard_action" model="ir.actions.server">
<field name="name">Invoice Energy Recurrency</field>
<field name="model_id" ref="model_contract_contract" />
<field name="binding_model_id" ref="contract.model_contract_contract" />
<field name="binding_type">action</field>
<field name="binding_view_types">list,form</field>
<field name="groups_id" eval="[(4,ref('energy_project.group_admin'))]" />
<field name="state">code</field>
<field name="code">action = records.invoicing_wizard_action()</field>
</record>
</data>
</odoo>
......@@ -2,3 +2,4 @@ from . import selfconsumption_import_wizard
from . import distribution_table_import_wizard
from . import contract_generation_wizard
from . import define_invoicing_mode_wizard
from . import invoicing_wizard
......@@ -43,7 +43,7 @@ class ContractGenerationWizard(models.TransientModel):
supply_point_assignation.supply_point_id.partner_id.name,
),
"partner_id": supply_point_assignation.supply_point_id.partner_id.id,
"project_id": self.selfconsumption_id.id,
"supply_point_assignation_id": supply_point_assignation.id,
"company_id": self.env.company.id,
"date_start": fields.date.today(),
"contract_template_id": self.selfconsumption_id.product_id.contract_template_id.id,
......@@ -58,7 +58,6 @@ class ContractGenerationWizard(models.TransientModel):
code=supply_point_assignation.supply_point_id.code,
owner_id=supply_point_assignation.supply_point_id.owner_id.display_name,
),
"supply_point_assignation_id": supply_point_assignation.id,
}
)
# Update selfconsumption and distribution_table state
......
......@@ -51,12 +51,6 @@ class ContractGenerationWizard(models.TransientModel):
"uom_po_id": uom_kw_id.id,
}
def _prepare_formula_values(self, code):
return {
"name": _("Formula - %s") % (self.selfconsumption_id.name),
"code": code,
}
def _prepare_contract_template_values(self, journal_id, contract_line):
return {
"name": self.selfconsumption_id.name,
......@@ -87,49 +81,19 @@ class ContractGenerationWizard(models.TransientModel):
# Create product
product_id = self.env["product.product"].create(self._prepare_product_values())
# Create contract formula
# TODO:Update formula energy_delivered and energy_delivered_variable.
# TODO:Update formula energy_delivered_variable.
formula_contract_id = None
if self.invoicing_mode == "power_acquired":
code = f"""
days_timedelta = line.next_period_date_end - line.next_period_date_start
if days_timedelta:
# Add one so it counts the same day too (month = 29 + 1)
days_between = days_timedelta.days + 1
else:
days_between = 0
result = line.supply_point_assignation_id.distribution_table_id.selfconsumption_project_id.power * line.supply_point_assignation_id.coefficient * days_between
"""
formula_contract_id = self.env["contract.line.qty.formula"].create(
self._prepare_formula_values(code)
formula_contract_id = self.env.ref(
"energy_selfconsumption.power_acquired_formula"
)
elif self.invoicing_mode == "energy_delivered":
code = f"""
days_timedelta = line.next_period_date_end - line.next_period_date_start
if days_timedelta:
# Add one so it counts the same day too (month = 29 + 1)
days_between = days_timedelta.days + 1
else:
days_between = 0
result = line.supply_point_assignation_id.distribution_table_id.selfconsumption_project_id.power * line.supply_point_assignation_id.coefficient * days_between
"""
formula_contract_id = self.env["contract.line.qty.formula"].create(
self._prepare_formula_values(code)
formula_contract_id = self.env.ref(
"energy_selfconsumption.energy_delivered_formula"
)
elif self.invoicing_mode == "energy_delivered_variable":
code = (
f"""
days_timedelta = line.next_period_date_end - line.next_period_date_start
if days_timedelta:
# Add one so it counts the same day too (month = 29 + 1)
days_between = days_timedelta.days + 1
else:
days_between = 0
result = line.supply_point_assignation_id.distribution_table_id.selfconsumption_project_id.power * line.supply_point_assignation_id.coefficient * days_between
""",
)
formula_contract_id = self.env["contract.line.qty.formula"].create(
self._prepare_formula_values(code)
formula_contract_id = self.env.ref(
"energy_selfconsumption.energy_delivered_variable_formula"
)
# Search accounting journal
......
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class InvoicingWizard(models.TransientModel):
_name = "energy_selfconsumption.invoicing.wizard"
power = fields.Float(string="Total Energy Generated (kWh)")
contract_ids = fields.Many2many("contract.contract", readonly=True)
next_period_date_start = fields.Date(
string="Next Period Start",
compute="_compute_next_period_date_start_and_end",
readonly=True,
)
next_period_date_end = fields.Date(
string="Next Period End",
compute="_compute_next_period_date_start_and_end",
readonly=True,
)
@api.depends("contract_ids")
def _compute_next_period_date_start_and_end(self):
for record in self:
if len(record.contract_ids) > 0:
record.next_period_date_start = record.contract_ids[
0
].next_period_date_start
record.next_period_date_end = record.contract_ids[
0
].next_period_date_end
@api.constrains("contract_ids")
def constraint_contract_ids(self):
for record in self:
contract_list = record.contract_ids
all_same_project = all(
element.project_id == contract_list[0].project_id
for element in contract_list
)
if not all_same_project:
raise ValidationError(
_(
"""
Some of the contract selected are not of the same self-consumption project.
Please make sure that you are invoicing for only the same self-consumption project ({project_name}.
"""
).format(
project_name=contract_list[0].project_id.selfconsumption_id.name
)
)
valid_invoicing_mode = ["energy_delivered"]
all_invoicing_mode = all(
element.project_id.selfconsumption_id.invoicing_mode
in valid_invoicing_mode
for element in contract_list
)
if not all_invoicing_mode:
raise ValidationError(
_(
"""
Some of the contract selected are not defined as energy delivered self-consumption projects.
Please make sure that you are invoicing the correct self-consumption project.
"""
)
)
all_equal_period = all(
element.next_period_date_start
== contract_list[0].next_period_date_start
and element.next_period_date_end
== contract_list[0].next_period_date_end
for element in contract_list
)
if not all_equal_period:
raise ValidationError(
_(
"""
Select only contracts with the same period of invoicing.
Make sure that all the selected contracts have the same next period start and end.
Next period start: {next_period_date_start}
Next period end: {next_period_date_end}"""
).format(
next_period_date_start=contract_list[0].next_period_date_start,
next_period_date_end=contract_list[0].next_period_date_end,
)
)
@api.constrains("power")
def constraint_power(self):
for record in self:
if not record.power or record.power <= 0:
raise ValidationError(
_("You must enter a valid total energy generated (kWh).")
)
def generate_invoices(self):
for contract in self.contract_ids:
template_name = contract.contract_template_id.contract_line_ids[0].name
template_name += _("Energy Delivered: {energy_delivered} kWh")
contract.contract_line_ids.write(
{
"name": template_name.format(
energy_delivered=self.power,
code=contract.supply_point_assignation_id.supply_point_id.code,
owner_id=contract.supply_point_assignation_id.supply_point_id.owner_id.display_name,
)
}
)
return self.with_context(
{"energy_delivered": self.power}
).contract_ids._recurring_create_invoice()
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record id="invoicing_wizard_form_view" model="ir.ui.view">
<field name="name">energy_selfconsumption.invoicing_wizard.form
</field>
<field name="model">energy_selfconsumption.invoicing.wizard</field>
<field name="arch" type="xml">
<form string="Invoicing Energy Delivered">
<sheet>
<group>
<field name="next_period_date_start" />
<field name="next_period_date_end" />
</group>
<group>
<field name="power" />
<field name="contract_ids">
<tree>
<field name="partner_id" />
<field name="supply_point_name" />
<field name="code" />
<field name="next_period_date_start" />
<field name="next_period_date_end" />
</tree>
</field>
</group>
</sheet>
<footer>
<button type="object" name="generate_invoices">Generate</button>
</footer>
</form>
</field>
</record>
<record id="invoicing_wizard_act_window" model="ir.actions.act_window">
<field name="name">Invoice Energy Delivered</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">energy_selfconsumption.invoicing.wizard</field>
<field name="groups_id" eval="[(4,ref('energy_project.group_admin'))]" />
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</odoo>