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 (211)
Showing
with 1899 additions and 499 deletions
{
"name": "Energy Community",
"version": "14.0.2.1.0",
"version": "14.0.3.2.0",
"depends": [
"account",
"cooperator_account_banking_mandate",
......@@ -12,6 +12,7 @@
"auth_api_key",
"auth_oauth",
"auth_oidc",
"auth_signup",
"base_rest",
"base_technical_features",
"base_user_role",
......@@ -78,6 +79,7 @@
"data/mail_template_update_data.xml",
"wizards/assign_crm_to_coordinator_company.xml",
"wizards/multicompany_easy_creation.xml",
"wizards/assign_admin_wizard.xml",
],
"installable": True,
"application": True,
......
class MapClientConfig:
# mapping between landings params and place params
MAPPING__INSTANCE_ID = 1
MAPPING__LANDING_ACTIVE_SERVICES__MAP_FILTER = {
"energy_communities.ce_tag_common_generation": "generacio-renovable-comunitaria",
"energy_communities.ce_tag_energy_efficiency": "eficiencia-energetica",
"energy_communities.ce_tag_sustainable_mobility": "mobilitat-sostenible",
"energy_communities.ce_tag_citizen_education": "formacio-ciutadana",
"energy_communities.ce_tag_thermal_energy": "energia-termica-i-climatitzacio",
"energy_communities.ce_tag_collective_purchases": "compres-col-lectives",
"energy_communities.ce_tag_renewable_energy": "subministrament-d-energia-100-renovable",
"energy_communities.ce_tag_aggregate_demand": "agregacio-i-flexibilitat-de-la-demanda",
}
MAPPING__MAP = "campanya"
MAPPING__LANDING_COMMUNITY_STATUS__MAP_FILTER = {"open": "oberta"}
MAPPING__LANDING_STATUS__MAP_PLACE_STATUS = {
"draft": "draft",
"publish": "published",
}
MAPPING__LANDING_COMMUNITY_TYPE__MAP_CATEGORY = {
"citizen": "ciutadania",
"industrial": "industrial",
}
MAPPING__LANDING_COMMUNITY_STATUS__MAP_PRESENTER = {"open": "CE Oberta"}
MAPPING__OPEN_PLACE_DESCRIPTION_META_KEY = "po2_description"
MAPPING__OPEN_PLACE_SOCIAL_HEADLINE_META_KEY = "po2_social_headline"
MAPPING__OPEN_PLACE_SOCIAL_HEADLINE_ORIGINAL = "<div class='flex justify-center align-center text-center'><p class='font-semibold text-white'>Comparteix i fem créixer la Comunitat Energètica</p></div>"
MAPPING__OPEN_PLACE_SOCIAL_HEADLINE_TRANSLATION = {
"es_ES": "<div class='flex justify-center align-center text-center'><p class='font-semibold text-white'>Comparte y hagamos crecer la Comunidad Energética</p></div>"
}
MAPPING__EXTERNAL_LINK__BECOME_COOPERATOR__LINK_LABEL = {
"ca_ES": "Fes-te'n soci/a",
"es_ES": "Hazte socio/a",
"eu_ES": "Bazkide bihurtu",
}
MAPPING__EXTERNAL_LINK__CONTACT__LINK_LABEL = {
"ca_ES": "Posa-t'hi en contacte",
"es_ES": "Ponte en contacto",
"eu_ES": "Jarri harremanetan",
}
MAPPING__EXTERNAL_LINK__LANDING__LINK_LABEL = {
"ca_ES": "Veure pàgina de la Comunitat",
"es_ES": "Ver página de la Comunidad",
"eu_ES": "Ikus Komunitatearen orria",
}
MAPPING__BUTTON_COLOR_CONFIG_NAME = {
"green": "Coorporate green dark button",
"yellow": "Coorporate yellow button",
}
from odoo import _
from odoo.exceptions import UserError
from ...pywordpress_client.resources.authenticate import Authenticate
from ...pywordpress_client.resources.landing_page import (
LandingPage as LandingPageResource,
)
from ..config import MapClientConfig
class LandingCmPlace:
_name = "landing_cmplace"
def __init__(self, landing):
self.landing = landing
self.wp_landing_data = self._get_wp_landing_data()
button_configs = self._get_button_color_configs()
if button_configs["errors"]:
raise UserError(error_msg)
else:
self.button_configs = button_configs["button_color_configs"]
def create(self):
"""
Creates a place from a landing instance.
"""
self._create_update_place("create")
def update(self):
"""
Updates a place from a landing instance.
"""
self._create_update_place("update")
def _create_update_place(self, mode):
validated_place_data = self._validate_and_prepare_place_data()
if validated_place_data["errors"]:
error_msg = ""
for error in validated_place_data["errors"]:
error_msg += error + "\n"
raise UserError(error_msg)
else:
if mode == "create":
place = self.landing.env["cm.place"].create(
validated_place_data["data"]
)
self.landing.write({"map_place_id": place.id})
if mode == "update":
place = self.landing.map_place_id
place.write(validated_place_data["data"])
self._place_extra_data_setup(place)
def _place_extra_data_setup(self, place):
place._get_slug_id()
place.build_presenter_metadata_ids()
# setup description
self._setup_place_description(place)
# setup external links
self._setup_external_links(place)
# apply translations
self._apply_place_metadatas_translations(place)
def _validate_and_prepare_place_data(self):
"""
Try to generate a place data dictionary and collect errors if they're
@returns: dictionary with 'data' key as the dict to be used for place creation or update and 'errors' key to collect errors if they're
"""
ret_dict = {
"data": {
"company_id": MapClientConfig.MAPPING__INSTANCE_ID,
"name": self.landing.name,
"type": "place",
"status": MapClientConfig.MAPPING__LANDING_STATUS__MAP_PLACE_STATUS[
self.landing.status
],
"interaction_method": "external_link",
"filter_mids": [(5, 0, 0)],
"address_txt": self._get_address_txt(),
},
"errors": [],
}
# Permissions
# TODO: Decide the permission level for this action
if self.landing.env.user.company_id.hierarchy_level not in [
"coordinator",
"instance",
]:
ret_dict["errors"].append(
_(
"Only users that belongs to the 'Coordinator' or 'Instance' company can create new Map Places."
)
)
# Map reference
map = self.landing.env["cm.map"].search(
[("slug_id", "=", MapClientConfig.MAPPING__MAP)]
)
if map:
ret_dict["data"]["map_id"] = map.id
else:
ret_dict["errors"].append(
_("Map not found slug_id: {}").format(self.MAPPING__MAP)
)
# Lat and Lng
if self.landing.lat:
ret_dict["data"]["lat"] = self.landing.lat
else:
ret_dict["errors"].append(
_("Landing lat param required for place creation")
)
if self.landing.lng:
ret_dict["data"]["lng"] = self.landing.lng
else:
ret_dict["errors"].append(
_("Landing lng param required for place creation")
)
# Place category
categories = self.landing.env["cm.place.category"].search([])
place_category_slug = (
MapClientConfig.MAPPING__LANDING_COMMUNITY_TYPE__MAP_CATEGORY[
self.landing.community_type
]
)
place_category = categories.filtered(lambda r: r.slug_id == place_category_slug)
if place_category:
ret_dict["data"]["place_category_id"] = place_category.id
else:
ret_dict["errors"].append(
_("Place category not found slug_id: {}").format(place_category_slug)
)
# Community status filter
filters = self.landing.env["cm.filter"].search([])
place_community_status_slug = (
MapClientConfig.MAPPING__LANDING_COMMUNITY_STATUS__MAP_FILTER[
self.landing.community_status
]
)
place_community_status = filters.filtered(
lambda r: r.slug_id == place_community_status_slug
)
if place_community_status:
ret_dict["data"]["marker_color"] = place_community_status.id
ret_dict["data"]["filter_mids"].append((4, place_community_status.id))
else:
ret_dict["errors"].append(
_("Place status filter not found slug_id: {}").format(
place_community_status_slug
)
)
# Community active services
for service in self.landing.community_active_services:
service_slug = MapClientConfig.MAPPING__LANDING_ACTIVE_SERVICES__MAP_FILTER[
service.tag_ext_id
]
place_service = filters.filtered(lambda r: r.slug_id == service_slug)
if place_service:
ret_dict["data"]["filter_mids"].append((4, place_service.id))
else:
ret_dict["errors"].append(
_("Place status filter not found slug_id: {}").format(service_slug)
)
# Presenter
presenter_name = (
MapClientConfig.MAPPING__LANDING_COMMUNITY_STATUS__MAP_PRESENTER[
self.landing.community_status
]
)
presenter = self.landing.env["cm.presenter.model"].search(
[("name", "=", presenter_name)]
)
if presenter:
ret_dict["data"]["presenter_model_id"] = presenter.id
else:
ret_dict["errors"].append(
_("Place presenter not found slug_id: {}").format(presenter_name)
)
return ret_dict
def _get_address_txt(self):
address_txt = ""
if self.landing.street:
address_txt = self.landing.street
if self.landing.postal_code:
if address_txt == "":
address_txt = self.landing.postal_code
else:
address_txt += ", " + self.landing.postal_code
if self.landing.city:
if address_txt == "":
address_txt = self.landing.city
else:
address_txt += ", " + self.landing.city
return address_txt
def _get_button_color_configs(self):
ret_dict = {"button_color_configs": {}, "errors": []}
button_color_configs = self.landing.env["cm.button.color.config"].search([])
ret_dict["button_color_configs"]["green"] = button_color_configs.filtered(
lambda r: r.name
== MapClientConfig.MAPPING__BUTTON_COLOR_CONFIG_NAME["green"]
)
ret_dict["button_color_configs"]["yellow"] = button_color_configs.filtered(
lambda r: r.name
== MapClientConfig.MAPPING__BUTTON_COLOR_CONFIG_NAME["yellow"]
)
if (
not ret_dict["button_color_configs"]["green"]
or not ret_dict["button_color_configs"]["yellow"]
):
ret_dict["errors"] = _("Button configs not found.")
return ret_dict
def _get_wp_landing_data(self):
instance_company = self.landing.env["res.company"].search(
[("hierarchy_level", "=", "instance")]
)
if instance_company:
baseurl = instance_company.wordpress_base_url
username = instance_company.wordpress_db_username
password = instance_company.wordpress_db_password
auth = Authenticate(baseurl, username, password).authenticate()
token = "Bearer %s" % auth["token"]
landing_page_wp_data = LandingPageResource(
token, baseurl, self.landing.wp_landing_page_id
).get()
return landing_page_wp_data
return False
def _setup_place_description(self, place):
desc_meta = self.landing.env["cm.place.presenter.metadata"].search(
[
("place_id", "=", place.id),
("key", "=", MapClientConfig.MAPPING__OPEN_PLACE_DESCRIPTION_META_KEY),
]
)
desc_meta.write({"value": self.landing.short_description})
def _setup_external_links(self, place):
new_external_links_ids = []
existing_external_links = self.landing.env["cm.place.external.link"].search(
[("place_id", "=", place.id)]
)
if self.landing.allow_new_members:
new_external_links_ids.append(
self._become_cooperator_external_link(place.id).id
)
else:
new_external_links_ids.append(self._contact_external_link(place.id).id)
new_external_links_ids.append(self._landing_external_link(place.id).id)
# remove old external_links if needed
for existing_external_link in existing_external_links:
if existing_external_link.id not in new_external_links_ids:
existing_external_link.unlink()
def _get_or_create_external_link(
self, place_id, name, url, target, button_color_config_id, sort_order
):
existing_external_links = self.landing.env["cm.place.external.link"].search(
[
("place_id", "=", place_id),
("name", "=", name),
("url", "=", url),
("target", "=", target),
("button_color_config_id", "=", button_color_config_id),
("sort_order", "=", sort_order),
]
)
if existing_external_links:
return existing_external_links[0]
else:
return self.landing.env["cm.place.external.link"].create(
{
"place_id": place_id,
"name": name,
"url": url,
"target": target,
"button_color_config_id": button_color_config_id,
"sort_order": sort_order,
}
)
def _become_cooperator_external_link(self, place_id):
external_link = self._get_or_create_external_link(
place_id,
MapClientConfig.MAPPING__EXTERNAL_LINK__BECOME_COOPERATOR__LINK_LABEL[
"ca_ES"
],
"{base_url}/become_cooperator?odoo_company_id={odoo_company_id}".format(
base_url=self.landing.env["ir.config_parameter"].get_param(
"web.base.url"
),
odoo_company_id=self.landing.company_id.id,
),
"_blank",
self.button_configs["yellow"].id,
0,
)
# es_ES Translation
self._update_translation(
"cm.place.external.link,name",
external_link.id,
MapClientConfig.MAPPING__EXTERNAL_LINK__BECOME_COOPERATOR__LINK_LABEL[
"ca_ES"
],
MapClientConfig.MAPPING__EXTERNAL_LINK__BECOME_COOPERATOR__LINK_LABEL[
"es_ES"
],
"es_ES",
)
self._update_translation(
"cm.place.external.link,url",
external_link.id,
"{base_url}/become_cooperator?odoo_company_id={odoo_company_id}".format(
base_url=self.landing.env["ir.config_parameter"].get_param(
"web.base.url"
),
odoo_company_id=self.landing.company_id.id,
),
"{base_url}/es/become_cooperator?odoo_company_id={odoo_company_id}".format(
base_url=self.landing.env["ir.config_parameter"].get_param(
"web.base.url"
),
odoo_company_id=self.landing.company_id.id,
),
"es_ES",
)
return external_link
def _contact_external_link(self, place_id):
external_link = self._get_or_create_external_link(
place_id,
MapClientConfig.MAPPING__EXTERNAL_LINK__CONTACT__LINK_LABEL["ca_ES"],
"{landing_link}/#contacte".format(
landing_link=self.wp_landing_data["link"]
),
"_top",
self.button_configs["yellow"].id,
0,
)
# es_ES Translation
self._update_translation(
"cm.place.external.link,name",
external_link.id,
MapClientConfig.MAPPING__EXTERNAL_LINK__CONTACT__LINK_LABEL["ca_ES"],
MapClientConfig.MAPPING__EXTERNAL_LINK__CONTACT__LINK_LABEL["es_ES"],
"es_ES",
)
if "es" in self.wp_landing_data["translations"].keys():
self._update_translation(
"cm.place.external.link,url",
external_link.id,
"{landing_link}/#contacte".format(
landing_link=self.wp_landing_data["link"]
),
"{landing_link}/#contacte".format(
landing_link=self.wp_landing_data["translations"]["es"]
),
"es_ES",
)
return external_link
def _landing_external_link(self, place_id):
external_link = self._get_or_create_external_link(
place_id,
MapClientConfig.MAPPING__EXTERNAL_LINK__LANDING__LINK_LABEL["ca_ES"],
self.wp_landing_data["link"],
"_top",
self.button_configs["green"].id,
1,
)
# es_ES Translation
self._update_translation(
"cm.place.external.link,name",
external_link.id,
MapClientConfig.MAPPING__EXTERNAL_LINK__LANDING__LINK_LABEL["ca_ES"],
MapClientConfig.MAPPING__EXTERNAL_LINK__LANDING__LINK_LABEL["es_ES"],
"es_ES",
)
if "es" in self.wp_landing_data["translations"].keys():
self._update_translation(
"cm.place.external.link,url",
external_link.id,
self.wp_landing_data["link"],
self.wp_landing_data["translations"]["es"],
"es_ES",
)
return external_link
def _apply_place_metadatas_translations(self, place):
for lang_code in self._get_active_languages():
# place description: applied from landing short_description already translated
landing_short_description_trans = self._get_translation(
"landing.page,short_description",
self.landing.id,
lang_code,
translated=True,
)
if landing_short_description_trans:
self._apply_place_metadata_translation(
place.id,
MapClientConfig.MAPPING__OPEN_PLACE_DESCRIPTION_META_KEY,
landing_short_description_trans.src,
landing_short_description_trans.value,
lang_code,
)
# place social headline: es_ES
self._apply_place_metadata_translation(
place.id,
MapClientConfig.MAPPING__OPEN_PLACE_SOCIAL_HEADLINE_META_KEY,
MapClientConfig.MAPPING__OPEN_PLACE_SOCIAL_HEADLINE_ORIGINAL,
MapClientConfig.MAPPING__OPEN_PLACE_SOCIAL_HEADLINE_TRANSLATION["es_ES"],
"es_ES",
)
def _apply_place_metadata_translation(
self, place_id, meta_key, original_value, trans_value, lang
):
related_meta = self.landing.env["cm.place.presenter.metadata"].search(
[("place_id", "=", place_id), ("key", "=", meta_key)]
)
if related_meta:
self._update_translation(
"cm.place.presenter.metadata,value",
related_meta.id,
original_value,
trans_value,
lang,
)
# TODO: Make all this translation block more compliant with ir.translation model
def _get_active_languages(self):
return self.landing.env["res.lang"].search([("active", "=", 1)]).mapped("code")
def _get_translation(self, translation_name, res_id, lang, translated=False):
query = [
("name", "=", translation_name),
("res_id", "=", res_id),
("lang", "=", lang),
]
if translated:
query.append(("state", "=", "translated"))
return self.landing.env["ir.translation"].search(query)
def _update_translation(
self, translation_name, res_id, original_value, trans_value, lang
):
translation = self._get_translation(translation_name, res_id, lang)
if translation:
translation.write(
{"src": original_value, "value": trans_value, "state": "translated"}
)
else:
self.landing.env["ir.translation"].create(
{
"name": translation_name,
"res_id": res_id,
"lang": lang,
"type": "model",
"src": original_value,
"value": trans_value,
"state": "translated",
}
)
......@@ -9,9 +9,10 @@
<field name="email_from">${object.company_id.email}</field>
<field
name="subject"
>[Somcomunitats.coop] Request for registration of the Energy Community on the platform</field>
>[Som Comunitats] Request for registration of the Energy Community on the platform</field>
<field name="email_to">${ctx.get('email_to')}</field>
<field name="model_id" ref="model_crm_lead" />
<field name="auto_delete" eval="False" />
<field name="lang">${object.company_id.partner_id.lang}</field>
<field name="body_html">
<![CDATA[
......@@ -21,7 +22,7 @@
<p>Go to Odoo to track this registration.</p><br/>
<p>Yours faithfully,</p>
<p>Somcomunitats.coop team</p>
<p><a href="https://web-test.somcomunitats.coop/recursos/">Resources and FAQs</a></p>
<p><a href="https://somcomunitats.coop/recursos/">Resources and FAQs</a></p>
</div>
]]>
</field>
......@@ -30,11 +31,16 @@
<record id="email_templ_lead_ce_creation_receipt_confirm_id" model="mail.template">
<field name="name">Confirmation Email for CE Creation Lead Receipt</field>
<field name="email_from">${object.company_id.email}</field>
<field name="subject">[Somcomunitats.coop] New Community Creation Request to the platform</field>
<field
name="subject"
>[Som Comunitats] New Community Creation Request</field>
<field name="email_to">${ctx.get('email_to')}</field>
<field name="model_id" ref="model_crm_lead" />
<field name="auto_delete" eval="False" />
<field name="lang">${ctx.get('lang')}</field>
<field name="body_html"><![CDATA[
<field
name="body_html"
><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello,</p>
<p>Thank you for filling out the form and requesting the membership of your Energy Community on the Somcomunitats.coop platform.</p>
......@@ -43,69 +49,90 @@
<p>We keep in touch for any questions.</p>
<p>Yours faithfully,</p>
<p>Somcomunitats.coop team </p>
<p><a href="https://web-test.somcomunitats.coop/recursos/">Resources and FAQs</a></p>
<p><a href="https://somcomunitats.coop/recursos/">Resources and FAQs</a></p>
</div>
]]></field>
</record>
<record id="email_templ_lead_request_contact_confirm_id" model="mail.template">
<field name="name">Confirmation Email for CE Contact Request Lead Receipt</field>
<field
name="name"
>Confirmation Email for CE Contact Request Lead Receipt</field>
<field name="email_from">${object.company_id.email}</field>
<field name="subject">[Somcomunitats.coop] Community Contact Request</field>
<field name="subject">[Som Comunitats] Community Contact Request</field>
<field name="email_to">${object.email_from}</field>
<field name="email_cc">${object.company_id.email}</field>
<field name="reply_to">${object.company_id.email}</field>
<field name="model_id" ref="model_crm_lead" />
<field name="auto_delete" eval="True" />
<field name="auto_delete" eval="False" />
<field name="lang">${ctx.get('lang')}</field>
<field name="body_html"><![CDATA[
<field
name="body_html"
><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello,</p>
<p>Thank you for contact.</p>
<p>We have received your email and we have we have forwarded it to the Community so that they can contact you as soon as possible.</p>
<br />
<p>We keep in touch for any questions.</p>
<p>Yours faithfully,</p>
<p>Somcomunitats.coop team </p>
<p><a href="https://web-test.somcomunitats.coop/recursos/">Resources and FAQs</a></p>
<p><a href="https://somcomunitats.coop/recursos/">Resources and FAQs</a></p>
</div>
]]></field>
</record>
<record id="email_templ_lead_request_ce_news_confirm_id" model="mail.template">
<field name="name">Confirmation Email for CE News Request Lead Receipt</field>
<field
name="name"
>Confirmation Email for CE News Request Lead Receipt</field>
<field name="email_from">${object.company_id.email}</field>
<field name="subject">[Somcomunitats.coop] Community Newsletter Subscription Request</field>
<field
name="subject"
>[Som Comunitats] Community Newsletter Subscription Request</field>
<field name="email_to">${object.email_from}</field>
<field name="email_cc">${object.company_id.email}</field>
<field name="reply_to">${object.company_id.email}</field>
<field name="model_id" ref="model_crm_lead" />
<field name="auto_delete" eval="True" />
<field name="auto_delete" eval="False" />
<field name="lang">${ctx.get('lang')}</field>
<field name="body_html"><![CDATA[
<field
name="body_html"
><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello,</p>
<p>Thank you for filling out the form.</p>
<p>You have been subscribed correctly to the Community Newsletter.</p>
<p>We will notify you if there is anything new in this community.</p>
<br />
<p>We remain in contact for any questions.</p>
<br />
<p>Yours faithfully,</p>
<p>Somcomunitats.coop team </p>
<p><a href="https://web-test.somcomunitats.coop/recursos/">Resources and FAQs</a></p>
<p><a href="https://somcomunitats.coop/recursos/">Resources and FAQs</a></p>
</div>
]]></field>
</record>
<record id="email_templ_lead_request_advise_future_ce_confirm_id" model="mail.template">
<field name="name">Confirmation Email for furture CE Contact Request Lead Receipt</field>
<record
id="email_templ_lead_request_advise_future_ce_confirm_id"
model="mail.template"
>
<field
name="name"
>Confirmation Email for furture CE Contact Request Lead Receipt</field>
<field name="email_from">${object.company_id.email}</field>
<field name="subject">[Somcomunitats.coop] Interested in Communities in your area</field>
<field
name="subject"
>[Som Comunitats] Interested in Communities in your area</field>
<field name="email_to">${object.email_from}</field>
<field name="email_cc">${object.company_id.email}</field>
<field name="reply_to">${object.company_id.email}</field>
<field name="model_id" ref="model_crm_lead" />
<field name="auto_delete" eval="True" />
<field name="auto_delete" eval="False" />
<field name="lang">${ctx.get('lang')}</field>
<field name="body_html"><![CDATA[
<field
name="body_html"
><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello,</p>
<p>Thank you for filling out the form.</p>
......@@ -114,22 +141,31 @@
<p>We keep in touch for any questions.</p>
<p>Yours faithfully,</p>
<p>Somcomunitats.coop team </p>
<p><a href="https://web-test.somcomunitats.coop/recursos/">Resources and FAQs</a></p>
<p><a href="https://somcomunitats.coop/recursos/">Resources and FAQs</a></p>
</div>
]]></field>
</record>
<record id="email_templ_lead_request_platform_news_confirm_id" model="mail.template">
<field name="name">Confirmation Email for Platform News Request Lead Receipt</field>
<record
id="email_templ_lead_request_platform_news_confirm_id"
model="mail.template"
>
<field
name="name"
>Confirmation Email for Platform News Request Lead Receipt</field>
<field name="email_from">${object.company_id.email}</field>
<field name="subject">[Somcomunitats.coop] Platform Newsletter Subscription Request</field>
<field
name="subject"
>[Som Comunitats] Newsletter Subscription Request</field>
<field name="email_to">${object.email_from}</field>
<field name="email_cc">${object.company_id.email}</field>
<field name="reply_to">${object.company_id.email}</field>
<field name="model_id" ref="model_crm_lead" />
<field name="auto_delete" eval="True" />
<field name="auto_delete" eval="False" />
<field name="lang">${ctx.get('lang')}</field>
<field name="body_html"><![CDATA[
<field
name="body_html"
><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello,</p>
<p>Thank you for filling out the form.</p>
......@@ -138,7 +174,30 @@
<br />
<p>Yours faithfully,</p>
<p>Somcomunitats.coop team </p>
<p><a href="https://web-test.somcomunitats.coop/recursos/">Resources and FAQs</a></p>
<p><a href="https://somcomunitats.coop/recursos/">Resources and FAQs</a></p>
</div>
]]></field>
</record>
<record id="email_templ_contact_platform_confirm_id" model="mail.template">
<field name="name">Confirmation Email Contact Platform Receipt</field>
<field name="email_from">${object.company_id.email}</field>
<field name="subject">[Som Comunitats] Contact to the platform</field>
<field name="email_to">${ctx.get('email_to')}</field>
<field name="model_id" ref="model_crm_lead" />
<field name="auto_delete" eval="False" />
<field name="lang">${ctx.get('lang')}</field>
<field
name="body_html"
><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: #FFF; ">
<p>Hello,</p>
<p>Thank you for getting in touch.</p>
<p>We have received your email. We will contact you as soon as possible.</p>
<br />
<p>Yours faithfully,</p>
<p>Somcomunitats.coop team </p>
<p><a href="https://somcomunitats.coop/recursos/">Resources and FAQs</a></p>
</div>
]]></field>
</record>
......
......@@ -20,7 +20,7 @@
>${(object.company_id.coop_email_contact or object.company_id.email)|safe}</field>
<field
name="subject"
>[Somcomunitats.coop] Application to become Community membership</field>
>[Som Comunitats] Application to become Community membership</field>
<field name="email_to">${object.email}</field>
<field name="email_cc">info+altausuari@somcomunitats.coop</field>
<field
......@@ -97,7 +97,7 @@
>${(object.company_id.coop_email_contact or object.company_id.email)|safe}</field>
<field
name="subject"
>[Somcomunitats.coop] Request to become member of Energy Community ${object.company_id.name}</field>
>[Som Comunitats] Request to become member of Energy Community ${object.company_id.name}</field>
<field name="partner_to">${object.partner_id.id}</field>
<field name="email_cc">info+altausuari@somcomunitats.coop</field>
<!--<field name="email_bcc">${object.company_id.email}</field>-->
......@@ -287,7 +287,7 @@
>${(object.company_id.coop_email_contact or object.company_id.email)|safe}</field>
<field
name="subject"
>[Somcomunitats.coop] Application to become Community membership</field>
>[Som Comunitats] Application to become Community membership</field>
<field name="email_to">${object.email}</field>
<field name="email_cc">info+altausuari@somcomunitats.coop</field>
<field
......
......@@ -13,6 +13,9 @@
<record model="utm.source" id="ce_source_existing_ce_contact">
<field name="name">Contact a existing CE</field>
</record>
<record model="utm.source" id="ce_source_general_contact">
<field name="name">Contact to the Platform</field>
</record>
<!-- CE Other Sources -->
<record model="utm.source" id="ce_source_creation_ce_proposal">
<field name="name">CE creation</field>
......
......@@ -36,6 +36,7 @@
name="property_cooperator_account"
ref="l10n_es.account_common_4300"
/>
<field name="hook_cron">False</field>
</record>
<!-- action_accept method expects singletons, so it must be called for every community company-->
......@@ -81,6 +82,7 @@
name="property_cooperator_account"
ref="l10n_es.account_common_4300"
/>
<field name="hook_cron">False</field>
</record>
<function
......@@ -123,6 +125,7 @@
name="property_cooperator_account"
ref="l10n_es.account_common_4300"
/>
<field name="hook_cron">False</field>
</record>
<function
......
......@@ -242,7 +242,7 @@
</record>
<record id="res_partner_admin_coordinator_1_demo" model="res.partner">
<field name="name">Adminitrador Coordinadora 1</field>
<field name="name">Administrador Coordinadora 1</field>
<field name="is_company" eval="False" />
<field name="email">admin@coordinator.coop</field>
<field name="street">Carrer Major, 23</field>
......@@ -346,7 +346,7 @@
</record>
<record id="res_partner_admin_plataforma_demo" model="res.partner">
<field name="name">Adminitrador Plataforma</field>
<field name="name">Administrador Plataforma</field>
<field name="is_company" eval="False" />
<field name="email">admin@plataforma.coop</field>
<field name="street">Carrer Major, 23</field>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2985,16 +2985,16 @@ msgstr "Codi postal"
#. module: cooperator
#: model:mail.template,subject:cooperator.email_template_confirmation
msgid "[Somcomunitats.coop] Application to become Community membership"
msgstr "[Somcomunitats.coop] Sol·licitud d'adhesió a Comunitat Energètica"
msgid "[Som Comunitats] Application to become Community membership"
msgstr "[Som Comunitats] Sol·licitud d'adhesió a Comunitat Energètica"
#. module: cooperator
#: model:mail.template,subject:cooperator.email_template_release_capital
msgid ""
"[Somcomunitats.coop] Request to become member of Energy Community "
"[Som Comunitats] Request to become member of Energy Community "
"${object.company_id.name}"
msgstr ""
"[Somcomunitats.coop] Sol·licitud d'adhesió a la Comunitat Energètica "
"[Som Comunitats] Sol·licitud d'adhesió a la Comunitat Energètica "
"${object.company_id.name}"
#. module: cooperator
......
......@@ -2989,16 +2989,16 @@ msgstr "Código Postal"
#. module: cooperator
#: model:mail.template,subject:cooperator.email_template_confirmation
msgid "[Somcomunitats.coop] Application to become Community membership"
msgstr "[Somcomunitats.coop] Solicitud adhesión a Comunidad Energética"
msgid "[Som Comunitats] Application to become Community membership"
msgstr "[Somos Comunidades] Solicitud adhesión a Comunidad Energética"
#. module: cooperator
#: model:mail.template,subject:cooperator.email_template_release_capital
msgid ""
"[Somcomunitats.coop] Request to become member of Energy Community "
"[Som Comunitats] Request to become member of Energy Community "
"${object.company_id.name}"
msgstr ""
"[Somcomunitats.coop] Solicitud adhesión a Comunidad Energética "
"[Somos Comunidades] Solicitud adhesión a Comunidad Energética "
"${object.company_id.name}"
#. module: cooperator
......
......@@ -2942,16 +2942,16 @@ msgstr "Código Postal"
#. module: cooperator
#: model:mail.template,subject:cooperator.email_template_confirmation
msgid "[Somcomunitats.coop] Application to become Community membership"
msgstr "[Somcomunitats.coop] Solicitud adhesión a Comunidad Energética"
msgid "[Som Comunitats] Application to become Community membership"
msgstr "[Komunitateak Gara] Solicitud adhesión a Comunidad Energética"
#. module: cooperator
#: model:mail.template,subject:cooperator.email_template_release_capital
msgid ""
"[Somcomunitats.coop] Request to become member of Energy Community "
"[Som Comunitats] Request to become member of Energy Community "
"${object.company_id.name}"
msgstr ""
"[Somcomunitats.coop] Solicitud adhesión a Comunidad Energética "
"[Komunitateak Gara] Solicitud adhesión a Comunidad Energética "
"${object.company_id.name}"
#. module: cooperator
......
from . import cm_coordinates_mixin
from . import auth_oauth_provider
from . import account_chart_template
from . import landing_page
from . import res_company
from . import res_config_settings
from . import res_partner
from . import res_partner_bank
from . import res_users
from . import res_users_role
from . import subscription_request
......
......@@ -10,6 +10,7 @@ URL_AUTH = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/auth"
URL_VALIDATION = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/userinfo"
URL_TOKEN = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/token"
URL_JWKS = "{root_endpoint}realms/{realm_name}/protocol/openid-connect/certs"
URL_RESET_PASSWORD = "{root_endpoint}admin/realms/{realm_name}/users/{kc_uid}/execute-actions-email?redirect_uri={odoo_url}&client_id={cliend_id}"
class OAuthProvider(models.Model):
......@@ -29,13 +30,15 @@ class OAuthProvider(models.Model):
placeholder='I hope is not "admin"',
required=False,
)
admin_user_endpoint = fields.Char(string="User admin URL", required=True)
admin_user_endpoint = fields.Char(string="User admin URL")
root_endpoint = fields.Char(
string="Root URL",
required=True,
default="http://keycloak-ccee.local:8080/auth/",
)
realm_name = fields.Char(string="Realm name", required=True, default="0")
reset_password_endpoint = fields.Char(string="Reset password URL")
redirect_admin_url = fields.Char(string="Redirect Link after update password")
def validate_admin_provider(self):
if not self.client_secret:
......@@ -43,8 +46,8 @@ class OAuthProvider(models.Model):
if not self.superuser_pwd:
raise UserError("Admin provider doesn't have a valid superuser password")
@api.onchange("root_endpoint")
def _onchange_root_endpoint(self):
@api.onchange("root_endpoint", "realm_name", "redirect_admin_url")
def _onchange_update_endpoints(self):
if self.is_keycloak_provider and self.root_endpoint and self.realm_name:
self.admin_user_endpoint = URL_ADMIN_USERS.format(
**{"root_endpoint": self.root_endpoint, "realm_name": self.realm_name}
......@@ -61,24 +64,12 @@ class OAuthProvider(models.Model):
self.jwks_uri = URL_JWKS.format(
**{"root_endpoint": self.root_endpoint, "realm_name": self.realm_name}
)
@api.onchange("realm_name")
def _onchange_realm_name(self):
if self.is_keycloak_provider and self.root_endpoint and self.realm_name:
self.admin_user_endpoint = URL_ADMIN_USERS.format(
**{"root_endpoint": self.root_endpoint, "realm_name": self.realm_name}
)
self.auth_endpoint = URL_AUTH.format(
**{"root_endpoint": self.root_endpoint, "realm_name": self.realm_name}
)
self.validation_endpoint = URL_VALIDATION.format(
**{"root_endpoint": self.root_endpoint, "realm_name": self.realm_name}
)
self.token_endpoint = URL_TOKEN.format(
**{"root_endpoint": self.root_endpoint, "realm_name": self.realm_name}
)
self.jwks_uri = URL_JWKS.format(
**{"root_endpoint": self.root_endpoint, "realm_name": self.realm_name}
self.reset_password_endpoint = URL_RESET_PASSWORD.format(
root_endpoint=self.root_endpoint,
realm_name=self.realm_name,
kc_uid="{kc_uid}",
odoo_url=self.redirect_admin_url,
cliend_id=self.client_id,
)
def get_auth_link(self):
......
from odoo import fields, models
class CmCoordinatesMixin(models.AbstractModel):
_name = "cm.coordinates.mixin"
_description = "Add map coordinates to any model"
lat = fields.Char(string="Latitude")
lng = fields.Char(string="Longitude")
......@@ -7,18 +7,6 @@ from odoo.exceptions import UserError
class CrmLead(models.Model):
_inherit = "crm.lead"
# mapping between the xml_ids related to crm.lead.tag_ids and cm.filter xmlids
_XMLID_MAPPING_LEADTAGS_CMFILTERS = [
("ce_tag_common_generation", "ce_cm_filter_community_renewal_generation"),
("ce_tag_energy_efficiency", "ce_cm_filter_energetic_eficiency"),
("ce_tag_sustainable_mobility", "ce_cm_filter_sustainable_mobility"),
("ce_tag_citizen_education", "ce_cm_filter_citizen_education"),
("ce_tag_thermal_energy", "ce_cm_filter_thermical_energy"),
("ce_tag_collective_purchases", "ce_cm_filter_collective_purchase"),
("ce_tag_renewable_energy", "ce_cm_filter_renewal_energy_supply"),
("ce_tag_aggregate_demand", "ce_cm_filter_demand_flexibility_and_aggregation"),
]
lang = fields.Char(string="Language")
ce_tag_ids = fields.Many2many(
"crm.tag",
......@@ -28,179 +16,38 @@ class CrmLead(models.Model):
string="CE Tags",
help="CE Classify and analyze categories",
)
community_company_id = fields.Many2one(
string="Related Community",
comodel_name="res.company",
domain="[('coordinator','!=',True)]",
help="Community related to this Lead",
)
finished = fields.Boolean(
related="stage_id.is_won",
readonly=True,
)
company_hierarchy_level = fields.Selection(
related="company_id.hierarchy_level",
readonly=True,
)
can_be_assigned_to_coordinator = fields.Boolean(
string="Can be assigned to coordinator",
compute="_get_can_be_assigned_to_coordinator",
store=False,
)
is_instance_company = fields.Boolean(
string="Is instance company", compute="_is_instance_company"
)
def _create_map_place_proposal(self):
if not self.env.user.company_id.coordinator:
raise UserError(
_(
"Only users that belongs to the 'Coordinator' company can create new Map Places from Leads."
)
)
active_categ_id = self.env["ir.model.data"].get_object_reference(
"ce", "ce_cm_place_category_active"
)[1]
building_categ_id = self.env["ir.model.data"].get_object_reference(
"ce", "ce_cm_place_category_building"
)[1]
default_ce_map_id = self.env["ir.model.data"].get_object_reference(
"ce", "ce_default_cm_map"
)[1]
creation_ce_source_id = self.env["ir.model.data"].get_object_reference(
"ce", "ce_source_creation_ce_proposal"
)[1]
for lead in self:
if self.env["crm.team"].search(
[
("proposal_form_submission_id", "=", lead.id),
("map_id", "=", default_ce_map_id),
]
):
raise UserError(
_(
"There is an allready existing Map Place related to this Lead: {}."
).format(lead.name)
)
if not lead.source_id or lead.source_id.id != creation_ce_source_id:
raise UserError(
_(
"The Source {} of Lead {} do not allow the creation of Map Proposals"
).format(lead.source_id.name, lead.name)
)
place_creation_data = {
"name": lead.name,
"map_id": default_ce_map_id,
"team_type": "map_place_proposal",
"user_id": self.env.user.id,
"proposal_form_submission_id": lead.id,
"interaction_method": "external_link",
"external_link_target": "_top",
}
# read metadata key/value pairs
m_dict = {m.key: m.value for m in lead.form_submission_metadata_ids}
if (
m_dict.get("partner_legal_state", False)
and m_dict["partner_legal_state"]
):
if m_dict["partner_legal_state"] == "active":
place_creation_data["place_category_id"] = active_categ_id
else:
place_creation_data["place_category_id"] = building_categ_id
else:
raise UserError(
_(
"Unable to get the Category (mandatory map place field) from Lead: {}"
).format(lead.name)
)
if m_dict.get("partner_latitude", False) and m_dict["partner_latitude"]:
place_creation_data["lat"] = m_dict["partner_latitude"]
else:
raise UserError(
_(
"Unable to get the Latitude (mandatory map place field) from Lead: {}"
).format(lead.name)
)
if m_dict.get("partner_longitude", False) and m_dict["partner_longitude"]:
place_creation_data["lng"] = m_dict["partner_longitude"]
else:
raise UserError(
_(
"Unable to get the Longitude (mandatory map place field) from Lead: {}"
).format(lead.name)
)
if (
m_dict.get("partner_map_place_form_url", False)
and m_dict["partner_map_place_form_url"]
):
place_creation_data["external_link_url"] = m_dict[
"partner_map_place_form_url"
]
place_creation_data["address_txt"] = lead._get_address_txt() or None
place_creation_data["filter_mids"] = [(6, 0, lead._get_cmfilter_ids())]
place = self.env["crm.team"].create(place_creation_data)
# we need to do call those next 2 functions because the @api.onchange('map_id') defined on community_maps module
# is not being called on crm_team.create(). TODO: review why it happens and fix it.
place._get_slug_id()
place._get_config_relations_attrs()
place._build_presenter_metadata_ids()
place.place_category_id = place_creation_data["place_category_id"]
place.message_subscribe([self.env.user.partner_id.id])
pmnd_ids = [
m
for m in place.place_presenter_metadata_ids
if m.key == "p_description"
]
description_pmnd_id = pmnd_ids and pmnd_ids[0] or None
if description_pmnd_id and lead.description:
description_pmnd_id.value = "<p class='m-2'>{}</p>".format(
lead.description
)
# lead update
lead.write(
{
"team_id": place.id,
"submission_type": "place_proposal_submission",
}
)
def _get_cmfilter_ids(self):
self.ensure_one()
md = self.env["ir.model.data"]
id_pairs = {}
for pair in self._XMLID_MAPPING_LEADTAGS_CMFILTERS:
id_pairs[
md.get_object_reference("ce", pair[0])[1]
] = md.get_object_reference("ce", pair[1])[1]
return [id_pairs[t.id] for t in self.tag_ids if t.id in id_pairs]
def _get_address_txt(self):
self.ensure_one()
ret = ""
meta_address_txt = [
meta.value
for meta in self.form_submission_metadata_ids
if meta.key == "partner_full_address"
]
if self.street and (self.city or self.zip):
ret = "{}{}. {}{}".format(
self.street,
(self.street2 and " " + self.street2) or "",
self.zip or "",
(self.city and " " + self.city) or "",
)
if self.state_id:
ret += ", {}".format(self.state_id.name)
if self.country_id:
ret += ". {}".format(self.country_id.name)
elif meta_address_txt and meta_address_txt[0]:
ret = meta_address_txt[0]
return ret
def _is_instance_company(self):
company = self.env.company
instance_companies = self.env["res.company"].search(
[("hierarchy_level", "=", "instance")]
)
if company in instance_companies:
self.is_instance_company = True
else:
self.is_instance_company = False
def _build_community_company(self):
if not self.env.user.company_id.coordinator:
......@@ -226,7 +73,7 @@ class CrmLead(models.Model):
if not lead.community_company_id:
# Create the new company using very basic starting Data
company = self.env["res.company"].create(
lead._get_company_create_vals()
lead._get_default_community_wizard()
)
# Update Lead & Map Place (if exist) fields accordingly
......@@ -244,20 +91,17 @@ class CrmLead(models.Model):
lead.community_company_id._create_keycloak_realm()
lead.community_company_id._community_post_keycloak_creation_tasks()
def _get_company_create_vals(self):
def _get_default_community_wizard(self):
self.ensure_one()
m_dict = {m.key: m.value for m in self.form_submission_metadata_ids}
metadata = {m.key: m.value for m in self.metadata_line_ids}
foundation_date = None
if (
m_dict.get("partner_foundation_date", False)
and m_dict["partner_foundation_date"]
):
if metadata.get("ce_creation_date", False) and metadata["ce_creation_date"]:
date_formats = ["%Y-%m-%d", "%d-%m-%Y", "%Y/%m/%d", "%d/%m/%Y"]
for date_format in date_formats:
try:
foundation_date = datetime.strptime(
m_dict["partner_foundation_date"], date_format
metadata["ce_creation_date"], date_format
)
except:
pass
......@@ -265,60 +109,52 @@ class CrmLead(models.Model):
raise UserError(
_(
"The Foundation Date value {} have a non valid format. It must be: yyyy-mm-dd or dd-mm-yyyy or yyyy/mm/dd or dd/mm/yyyy"
).format(m_dict["partner_foundation_date"])
).format(metadata["partner_foundation_date"])
)
initial_share_amount = 0.00
if (
m_dict.get("partner_initial_share_amount", False)
and m_dict["partner_initial_share_amount"]
or None
):
try:
initial_share_amount = float(m_dict["partner_initial_share_amount"])
except:
pass
lang_id = None
if m_dict.get("partner_language", False) and m_dict["partner_language"] or None:
if metadata.get("current_lang", False) and metadata["current_lang"] or None:
lang_id = self.env["res.lang"].search(
[("code", "=", m_dict["partner_language"])], limit=1
[("code", "=", metadata["current_lang"])], limit=1
)
create_vals = {
users = [user.id for user in self.company_id.get_users()]
return {
"name": self.name,
"street": self.street,
"street2": self.street2,
"city": self.city,
"zip": self.zip,
"state_id": self.state_id.id,
"country_id": self.country_id.id,
"website": self.website,
"phone": self.phone,
"email": self.email_from
or (m_dict.get("contact_email", False) and m_dict["contact_email"])
or None,
"vat": m_dict.get("partner_vat", False) and m_dict["partner_vat"] or None,
"social_twitter": m_dict.get("partner_twitter", False)
and m_dict["partner_twitter"]
or None,
"social_facebook": m_dict.get("partner_facebook", False)
and m_dict["partner_facebook"]
"parent_id": self.company_id.id,
"crm_lead_id": self.id,
"user_ids": users,
"street": metadata.get("ce_address", False)
and metadata["ce_address"]
or None,
"social_instagram": m_dict.get("partner_instagram", False)
and m_dict["partner_instagram"]
"city": metadata.get("ce_city", False) and metadata["ce_city"] or None,
"zip_code": metadata.get("ce_zip", False) and metadata["ce_zip"] or None,
"phone": metadata.get("contact_phone", False)
and metadata["contact_phone"]
or None,
"social_telegram": m_dict.get("partner_telegram", False)
and m_dict["partner_telegram"]
"email": metadata.get("email_from", False)
and metadata["email_from"]
or None,
"create_user": True,
"vat": metadata.get("ce_vat", False) and metadata["ce_vat"] or None,
"foundation_date": foundation_date,
"initial_subscription_share_amount": initial_share_amount,
"default_lang_id": lang_id and lang_id.id or None,
"chart_template_id": self.env.ref(
"l10n_es.account_chart_template_pymes"
).id,
"update_default_taxes": True,
"default_sale_tax_id": self.env.ref(
"l10n_es.account_tax_template_s_iva21s"
).id,
"default_purchase_tax_id": self.env.ref(
"l10n_es.account_tax_template_p_iva21_bc"
).id,
"property_cooperator_account": self.env["account.account"]
.search([("code", "like", "44000%")], limit=1)
.id,
"create_user": False,
}
return create_vals
def _create_keycloak_realm(self):
for lead in self:
if not lead.community_company_id:
......@@ -329,9 +165,6 @@ class CrmLead(models.Model):
)
lead.community_company_id._create_keycloak_realm()
def post_template_to_chatter(self, template_id):
self.message_post_with_template(template_id)
def _create_community_initial_users(self):
for lead in self:
pass
......@@ -345,6 +178,34 @@ class CrmLead(models.Model):
"target": "new",
}
def action_create_community(self):
data = self._get_default_community_wizard()
wizard = self.env["account.multicompany.easy.creation.wiz"].create(data)
return {
"type": "ir.actions.act_window",
"name": _("Create community"),
"res_model": "account.multicompany.easy.creation.wiz",
"view_type": "form",
"view_mode": "form",
"target": "new",
"res_id": wizard.id,
}
@api.depends("source_id")
def _get_can_be_assigned_to_coordinator(self):
for record in self:
record.can_be_assigned_to_coordinator = (
record.source_id.id
in [
self.env.ref("energy_communities.ce_source_general_info").id,
self.env.ref("energy_communities.ce_source_existing_ce_contact").id,
self.env.ref(
"energy_communities.ce_source_creation_ce_proposal"
).id,
]
and self.company_id.hierarchy_level == "instance"
)
def add_follower(self):
instance_admin = self.env.ref("energy_communities.role_ce_manager").id
company_id = self.company_id.id
......