diff --git a/sale_planner_calendar/__manifest__.py b/sale_planner_calendar/__manifest__.py index e94fa2c3756..c3ce29d5803 100644 --- a/sale_planner_calendar/__manifest__.py +++ b/sale_planner_calendar/__manifest__.py @@ -34,6 +34,7 @@ "web.assets_backend": [ "sale_planner_calendar/static/src/xml/categ_icons_widget_template.xml", "sale_planner_calendar/static/src/xml/sale_planner_calendar_event_sales.xml", + "sale_planner_calendar/static/src/xml/activity_menu_view.xml", "sale_planner_calendar/static/src/scss/sale_planner_calendar.scss", "sale_planner_calendar/static/src/js/*.js", ], diff --git a/sale_planner_calendar/i18n/es.po b/sale_planner_calendar/i18n/es.po index c98bf2116c3..a7143f25cd9 100644 --- a/sale_planner_calendar/i18n/es.po +++ b/sale_planner_calendar/i18n/es.po @@ -6,9 +6,9 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 13.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-10-30 16:12+0000\n" -"PO-Revision-Date: 2024-10-30 17:12+0100\n" -"Last-Translator: Sergio Teruel \n" +"POT-Creation-Date: 2024-11-07 12:50+0000\n" +"PO-Revision-Date: 2024-11-07 13:54+0100\n" +"Last-Translator: Carlos Dauden \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" @@ -390,6 +390,11 @@ msgstr "Meses posteriores para crear eventos de calendario" msgid "Friday" msgstr "Viernes" +#. module: sale_planner_calendar +#: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_search +msgid "Future" +msgstr "Futuro" + #. module: sale_planner_calendar #: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_search #: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_summary_search @@ -693,6 +698,11 @@ msgstr "Pedido" msgid "Orders" msgstr "Pedidos" +#. module: sale_planner_calendar +#: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_search +msgid "Past" +msgstr "Pasado" + #. module: sale_planner_calendar #: model:ir.model.fields,field_description:sale_planner_calendar.field_sale_planner_calendar_reassign_line_wiz__partner_id #: model:ir.model.fields,field_description:sale_planner_calendar.field_sale_planner_calendar_reassign_wiz__partner_id @@ -871,8 +881,11 @@ msgid "Sale planner calendar event" msgstr "Eventos de rutero" #. module: sale_planner_calendar +#. odoo-python +#: code:addons/sale_planner_calendar/models/res_users.py:0 #: model:ir.actions.act_window,name:sale_planner_calendar.action_sale_planner_calendar_event #: model:ir.ui.menu,name:sale_planner_calendar.menu_sale_planner_calendar_event +#, python-format msgid "Sale planner calendar events" msgstr "Eventos de rutero" @@ -1139,6 +1152,7 @@ msgid "Until" msgstr "Hasta" #. module: sale_planner_calendar +#: model:ir.model,name:sale_planner_calendar.model_res_users #: model:ir.model.fields,field_description:sale_planner_calendar.field_sale_planner_calendar_summary__user_id msgid "User" msgstr "Usuario" diff --git a/sale_planner_calendar/i18n/sale_planner_calendar.pot b/sale_planner_calendar/i18n/sale_planner_calendar.pot index f74c9c83c8a..3a9c317d141 100644 --- a/sale_planner_calendar/i18n/sale_planner_calendar.pot +++ b/sale_planner_calendar/i18n/sale_planner_calendar.pot @@ -6,6 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-11-07 12:50+0000\n" +"PO-Revision-Date: 2024-11-07 12:50+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -380,6 +382,11 @@ msgstr "" msgid "Friday" msgstr "" +#. module: sale_planner_calendar +#: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_search +msgid "Future" +msgstr "" + #. module: sale_planner_calendar #: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_search #: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_summary_search @@ -677,6 +684,11 @@ msgstr "" msgid "Orders" msgstr "" +#. module: sale_planner_calendar +#: model_terms:ir.ui.view,arch_db:sale_planner_calendar.view_sale_planner_calendar_search +msgid "Past" +msgstr "" + #. module: sale_planner_calendar #: model:ir.model.fields,field_description:sale_planner_calendar.field_sale_planner_calendar_reassign_line_wiz__partner_id #: model:ir.model.fields,field_description:sale_planner_calendar.field_sale_planner_calendar_reassign_wiz__partner_id @@ -855,8 +867,11 @@ msgid "Sale planner calendar event" msgstr "" #. module: sale_planner_calendar +#. odoo-python +#: code:addons/sale_planner_calendar/models/res_users.py:0 #: model:ir.actions.act_window,name:sale_planner_calendar.action_sale_planner_calendar_event #: model:ir.ui.menu,name:sale_planner_calendar.menu_sale_planner_calendar_event +#, python-format msgid "Sale planner calendar events" msgstr "" @@ -1115,6 +1130,7 @@ msgid "Until" msgstr "" #. module: sale_planner_calendar +#: model:ir.model,name:sale_planner_calendar.model_res_users #: model:ir.model.fields,field_description:sale_planner_calendar.field_sale_planner_calendar_summary__user_id msgid "User" msgstr "" diff --git a/sale_planner_calendar/models/__init__.py b/sale_planner_calendar/models/__init__.py index 29fa5771974..40bac289ec5 100644 --- a/sale_planner_calendar/models/__init__.py +++ b/sale_planner_calendar/models/__init__.py @@ -4,6 +4,7 @@ from . import calendar_attendee from . import res_config_settings from . import res_partner +from . import res_users from . import sale_order from . import sale_payment_sheet from . import sale_planner_calendar_issue_type diff --git a/sale_planner_calendar/models/calendar_event.py b/sale_planner_calendar/models/calendar_event.py index bbf13aaca37..8a8b077f08a 100644 --- a/sale_planner_calendar/models/calendar_event.py +++ b/sale_planner_calendar/models/calendar_event.py @@ -87,6 +87,14 @@ class CalendarEvent(models.Model): sanitized_partner_mobile = fields.Char(compute="_compute_sanitized_partner_mobile") location_url = fields.Char(compute="_compute_location_url") categ_icons = fields.Char(compute="_compute_categ_icons") + sale_planner_rating = fields.Selection( + [ + ("1", "🙁"), + ("3", "😐"), + ("5", "🙂"), + ], + required=True, + ) @api.depends("recurrence_id", "recurrence_id.calendar_event_ids") def _compute_is_base_recurrent_event(self): @@ -350,6 +358,7 @@ def action_pending(self): { "sale_planner_state": "pending", "comment": False, + "sale_planner_rating": False, } ) @@ -363,6 +372,16 @@ def action_open_issue(self): def action_apply_issue(self): pass + def action_open_rating(self): + action = self.env["ir.actions.act_window"]._for_xml_id( + "sale_planner_calendar.action_sale_planner_calendar_rating" + ) + action["res_id"] = self.id + return action + + def action_set_sale_planner_rating(self): + self.action_done() + def _get_hour_tz_offset(self): timezone = self._context.get("tz") or self.env.user.partner_id.tz or "UTC" self_tz = self.with_context(tz=timezone) diff --git a/sale_planner_calendar/models/res_users.py b/sale_planner_calendar/models/res_users.py new file mode 100644 index 00000000000..94d7da753d7 --- /dev/null +++ b/sale_planner_calendar/models/res_users.py @@ -0,0 +1,73 @@ +# Copyright 2024 Tecnativa - Carlos Roca +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import json +from datetime import datetime + +import pytz + +from odoo import _, api, fields, models, modules + + +class ResUsers(models.Model): + _inherit = "res.users" + + def _get_sale_planner_calendar_events_domain(self): + return [ + ("user_id", "=", self.env.user.id), + ("target_partner_id", "!=", False), + ("sale_planner_state", "=", "pending"), + ] + + @api.model + def get_action_sale_planner_calendar_event(self): + return self.env["ir.actions.act_window"]._for_xml_id( + "sale_planner_calendar.action_sale_planner_calendar_event" + ) + + @api.model + def systray_get_activities(self): + res = super().systray_get_activities() + # Get user timezone or UTC if not set + user_tz = pytz.timezone(self.env.user.tz or "UTC") + # Get current time in user's timezone + datetime_now = datetime.now(user_tz) + domain = self._get_sale_planner_calendar_events_domain() + # Start of day in user's timezone + start_date_today_tz = datetime_now.replace(hour=0, minute=0, second=0) + # Convert to UTC for domain + start_date_today_utc = start_date_today_tz.astimezone(pytz.UTC) + # End of day in user's timezone + end_date_today_tz = datetime_now.replace(hour=23, minute=59, second=59) + # Convert to UTC for domain + end_date_today_utc = end_date_today_tz.astimezone(pytz.UTC) + domain_today = domain + [ + ("start", ">=", fields.Datetime.to_string(start_date_today_utc)), + ("start", "<=", fields.Datetime.to_string(end_date_today_utc)), + ] + events_today_count = self.env["calendar.event"].search_count(domain_today) + events_overdue_count = self.env["calendar.event"].search_count( + domain + [("start", "<", start_date_today_utc)] + ) + events_planned_count = self.env["calendar.event"].search_count( + domain + [("start", ">", end_date_today_utc)] + ) + total_count = events_today_count + events_overdue_count + if total_count: + res.append( + { + "id": self.env["ir.model"]._get("calendar.event").id, + "type": "activity", + "name": _("Sale planner calendar events"), + "model": "calendar.event", + "icon": modules.module.get_module_icon( + self.env["calendar.event"]._original_module + ), + "total_count": total_count, + "today_count": events_today_count, + "overdue_count": events_overdue_count, + "planned_count": events_planned_count, + "is_planner": True, + "domain": json.dumps(domain), + } + ) + return res diff --git a/sale_planner_calendar/static/img/rating_1.png b/sale_planner_calendar/static/img/rating_1.png new file mode 100644 index 00000000000..e2919617942 Binary files /dev/null and b/sale_planner_calendar/static/img/rating_1.png differ diff --git a/sale_planner_calendar/static/img/rating_1.svg b/sale_planner_calendar/static/img/rating_1.svg new file mode 100644 index 00000000000..1a03ef19299 --- /dev/null +++ b/sale_planner_calendar/static/img/rating_1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sale_planner_calendar/static/img/rating_3.png b/sale_planner_calendar/static/img/rating_3.png new file mode 100644 index 00000000000..69942a2e20a Binary files /dev/null and b/sale_planner_calendar/static/img/rating_3.png differ diff --git a/sale_planner_calendar/static/img/rating_3.svg b/sale_planner_calendar/static/img/rating_3.svg new file mode 100644 index 00000000000..5cee881f2ab --- /dev/null +++ b/sale_planner_calendar/static/img/rating_3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sale_planner_calendar/static/img/rating_5.png b/sale_planner_calendar/static/img/rating_5.png new file mode 100644 index 00000000000..015baac529b Binary files /dev/null and b/sale_planner_calendar/static/img/rating_5.png differ diff --git a/sale_planner_calendar/static/img/rating_5.svg b/sale_planner_calendar/static/img/rating_5.svg new file mode 100644 index 00000000000..9ac69427d39 --- /dev/null +++ b/sale_planner_calendar/static/img/rating_5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sale_planner_calendar/static/src/js/activity_group_view.esm.js b/sale_planner_calendar/static/src/js/activity_group_view.esm.js new file mode 100644 index 00000000000..bf83a606786 --- /dev/null +++ b/sale_planner_calendar/static/src/js/activity_group_view.esm.js @@ -0,0 +1,50 @@ +/** @odoo-module **/ + +import {registerPatch} from "@mail/model/model_core"; +import {attr} from "@mail/model/model_field"; + +registerPatch({ + name: "ActivityGroup", + modelMethods: { + convertData(data) { + const data2 = this._super(data); + data2.is_planner = data.is_planner; + return data2; + }, + }, + fields: { + is_planner: attr({default: false}), + }, +}); + +registerPatch({ + name: "ActivityGroupView", + recordMethods: { + onClickFilterButton(ev) { + this._super(...arguments); + const data = _.extend({}, $(ev.currentTarget).data(), $(ev.target).data()); + if (data.is_planner === 1) { + const context = {}; + if (data.filter === "my") { + context.search_default_planner_overdue = 1; + context.search_default_planner_today = 1; + } else { + context["search_default_planner_" + data.filter] = 1; + } + this.env.services.orm + .call("res.users", "get_action_sale_planner_calendar_event") + .then((action) => { + action.domain = data.domain; + const action_ctx = JSON.parse( + action.context.replace(/'/g, '"') + ); + action.context = {...action_ctx, ...context}; + delete action.context.search_default_my_event_planner; + this.env.services.action.doAction(action, { + clearBreadcrumbs: true, + }); + }); + } + }, + }, +}); diff --git a/sale_planner_calendar/static/src/xml/activity_menu_view.xml b/sale_planner_calendar/static/src/xml/activity_menu_view.xml new file mode 100644 index 00000000000..558b43a7413 --- /dev/null +++ b/sale_planner_calendar/static/src/xml/activity_menu_view.xml @@ -0,0 +1,13 @@ + + + + + activityGroupView.activityGroup.is_planner ? 1 : 0 + + + diff --git a/sale_planner_calendar/views/sale_planner_calendar_event_view.xml b/sale_planner_calendar/views/sale_planner_calendar_event_view.xml index 58e4c070f4d..33c0417e6f8 100644 --- a/sale_planner_calendar/views/sale_planner_calendar_event_view.xml +++ b/sale_planner_calendar/views/sale_planner_calendar_event_view.xml @@ -36,16 +36,26 @@ domain="[('sale_planner_state','=', 'done')]" /> + + + @@ -88,6 +104,7 @@ /> + @@ -175,6 +192,12 @@ /> +
+ +
@@ -257,6 +280,47 @@ }
+ + sale.planner.calendar.rating.form + calendar.event + + +
+ + + + + + +
+ +
+
+ +
+
+
+
+ + + Sale planner calendar rating + calendar.event + form + new + + {'form_view_ref': 'sale_planner_calendar.view_sale_planner_calendar_rating_form'} + + + sale.planner.calendar.event.kanban calendar.event @@ -284,6 +348,7 @@ +
@@ -308,8 +373,26 @@ +