Skip to content
Snippets Groups Projects
Commit 0c1641e1 authored by emanuel buzey's avatar emanuel buzey
Browse files

Merge branch 'feature/IMP_recurring_invoice_setup' into...

Merge branch 'feature/IMP_recurring_invoice_setup' into 'feature/IMP_energy_selfconsumption_invoicing_acquired_power'

Feature/imp recurring invoice setup

See merge request !221
parents 4c22d074 6d6be76c
No related branches found
No related tags found
1 merge request!221Feature/imp recurring invoice setup
Pipeline #59713 passed
......@@ -35,6 +35,7 @@
"wizards/selfconsumption_import_wizard_views.xml",
"wizards/distribution_table_import_wizard_views.xml",
"wizards/contract_generation_wizard_views.xml",
"wizards/define_invoicing_mode_wizard_view.xml",
"reports/selfconsumption_reports.xml",
],
}
......@@ -6,3 +6,4 @@ from . import supply_point_assignation
from . import project
from . import contract_line
from . import contract
from . import product
......@@ -6,7 +6,6 @@ class Contract(models.Model):
project_id = fields.Many2one(
"energy_project.project",
required=True,
ondelete="restrict",
string="Energy Project",
check_company=True,
......
from odoo import fields, models
class Product(models.Model):
_inherit = "product.product"
project_id = fields.Many2one(
"energy_project.project",
required=True,
ondelete="restrict",
string="Energy Project",
check_company=True,
)
......@@ -3,6 +3,15 @@ from datetime import datetime
from odoo import _, fields, models
from odoo.exceptions import ValidationError
INVOICING_VALUES = [
("power_acquired", _("Power Acquired")),
("energy_delivered", _("Energy Delivered")),
(
"energy_delivered_variable",
_("Energy Delivered Variable Hourly Coefficient"),
),
]
class Selfconsumption(models.Model):
_name = "energy_selfconsumption.selfconsumption"
......@@ -76,6 +85,9 @@ class Selfconsumption(models.Model):
)
inscription_count = fields.Integer(compute=_compute_inscription_count)
contracts_count = fields.Integer(compute=_compute_contract_count)
invoicing_mode = fields.Selection(INVOICING_VALUES, string="Invoicing Mode")
product_id = fields.Many2one("product.product", string="Product")
contract_template_id = fields.Many2one("contract.template")
def get_distribution_tables(self):
self.ensure_one()
......@@ -162,6 +174,18 @@ class Selfconsumption(models.Model):
"context": {"default_selfconsumption_id": self.id},
}
def set_invoicing_mode(self):
return {
"name": _("Define Invoicing Mode"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "energy_selfconsumption.define_invoicing_mode.wizard",
"views": [(False, "form")],
"view_id": False,
"target": "new",
"context": {"default_selfconsumption_id": self.id},
}
def action_selfconsumption_import_wizard(self):
self.ensure_one()
return {
......
......@@ -11,3 +11,4 @@ access_energy_selfconsumption_selfconsumption_import_wizard_admin,energy_selfcon
access_energy_selfconsumption_distribution_table_import_wizard_admin,energy_selfconsumption.distribution_table_import.wizard.admin,model_energy_selfconsumption_distribution_table_import_wizard,energy_project.group_admin,1,1,1,1
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
......@@ -69,6 +69,12 @@
string="Download Partition Coefficient"
attrs="{'invisible':[('state','not in',['activation', 'active'])]}"
/>
<button
type="object"
string="Define Invoicing Mode"
name="set_invoicing_mode"
attrs="{'invisible':[('invoicing_mode', '!=', False)]}"
/>
<field
name="state"
......@@ -121,7 +127,6 @@
/>
</button>
</div>
<widget
name="web_ribbon"
......@@ -212,6 +217,25 @@
</div>
</group>
</group>
<notebook colspan="4">
<page
string="Invoicing Mode"
name="invoicing_mode"
autofocus="autofocus"
attrs="{'invisible':[('invoicing_mode', '==', False)]}"
>
<group>
<field name="invoicing_mode" readonly="True" />
<field name="product_id" readonly="True" />
<field
name="contract_template_id"
readonly="True"
/>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" />
......
from . import selfconsumption_import_wizard
from . import distribution_table_import_wizard
from . import contract_generation_wizard
from . import define_invoicing_mode_wizard
from odoo import _, fields, models
from odoo.exceptions import UserError
from ..models.selfconsumption import INVOICING_VALUES
class ContractGenerationWizard(models.TransientModel):
_name = "energy_selfconsumption.define_invoicing_mode.wizard"
RULE_TYPE_OPTIONS = [
("daily", _("Day(s)")),
("weekly", _("Week(s)")),
("monthly", _("Month(s)")),
("monthlylastday", _("Month(s) last day")),
("quarterly", _("Quarter(s)")),
("semesterly", _("Semester(s)")),
("yearly", _("Year(s)")),
]
invoicing_mode = fields.Selection(
INVOICING_VALUES,
string="Invoicing Mode",
default="power_acquired",
required=True,
)
price = fields.Float(required=True)
recurrence_interval = fields.Integer(
default=1,
string="Invoice Every",
required=True,
help=_("Invoice every (Days/Week/Month/Year)"),
)
recurring_rule_type = fields.Selection(
RULE_TYPE_OPTIONS,
default="monthlylastday",
string="Recurrence",
required=True,
help=_("Specify Interval for automatic invoice generation."),
)
selfconsumption_id = fields.Many2one(
"energy_selfconsumption.selfconsumption", readonly=True
)
def _prepare_product_values(self):
return {
"name": self.selfconsumption_id.name,
"lst_price": self.price,
"company_id": self.env.company.id,
"project_id": self.selfconsumption_id.project_id.id,
}
def _prepare_formula_values(self, code):
return {
"name": _("Formula - %s") % (self.selfconsumption_id.name),
"code": code,
}
def _prepare_contract_values(self, journal_id, contract_line):
return {
"name": self.selfconsumption_id.name,
"journal_id": journal_id.id,
"company_id": self.env.company.id,
"contract_line_ids": contract_line,
"recurring_interval": self.recurrence_interval,
"recurring_rule_type": self.recurring_rule_type,
}
def save_data_to_selfconsumption(self):
if self.invoicing_mode == "energy_delivered_variable":
raise UserError(_("This invoicing mode is not yet implemented"))
# 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.
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)
)
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)
)
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)
)
# Search accounting journal
journal_id = self.env["account.journal"].search(
[("company_id", "=", self.env.company.id), ("type", "=", "sale")], limit=1
)
if not journal_id:
raise UserWarning(_("Accounting Journal not found."))
# Create Contract Template
contract_line = [
(
0,
0,
{
"product_id": product_id.id,
"automatic_price": True,
"company_id": self.env.company.id,
"qty_type": "variable",
"qty_formula_id": formula_contract_id.id,
"name": "",
},
)
]
contract_template_id = self.env["contract.template"].create(
self._prepare_contract_values(journal_id, contract_line)
)
self.selfconsumption_id.write(
{
"invoicing_mode": self.invoicing_mode,
"product_id": product_id,
"contract_template_id": contract_template_id,
}
)
return {
"type": "ir.actions.act_window_close",
}
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record model="ir.ui.view" id="define_invoicing_mode_wizard_form_view">
<field
name="name"
>energy_selfconsumption.define_invoicing_mode.wizard.form</field>
<field
name="model"
>energy_selfconsumption.define_invoicing_mode.wizard</field>
<field name="arch" type="xml">
<form string="Define Invoicing Mode Wizard">
<sheet>
<group>
<group col="1">
<field name="invoicing_mode" />
<field
name="price"
string="kWh Price (€/kWh)"
attrs="{'invisible': [('invoicing_mode', 'not in', ['energy_delivered', 'energy_delivered_variable'])]}"
/>
<field
name="price"
string="kWn Price per day (€/kWn/day)"
attrs="{'invisible': [('invoicing_mode', '!=', 'power_acquired')]}"
/>
</group>
<group col="2">
<field name="recurrence_interval" />
<field name="recurring_rule_type" />
</group>
</group>
</sheet>
<footer>
<button
name="save_data_to_selfconsumption"
string="Save Data"
type="object"
class="btn-primary"
/>
</footer>
</form>
</field>
</record>
</data>
</odoo>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment