Sale planner calendar

sale_planner_calendar
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/18.0/sale_planner_calendar
VERSION
VERSION 1.0.2
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA)
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA)
COMMITTERS
COMMITTERSsergio-teruel, Víctor Martínez, Weblate, OCA-git-bot, oca-ci, Carlos Roca
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:11
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/sale-workflow:
    - sale_payment_sheet
odoo/odoo:
    - calendar
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - sale
    - sales_team
    - account_payment
    - account
    - onboarding
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module allows to manage commercial visits to partners by using
recurrence events.

Code Analysis

Views touched (23)
XML IDNameModelTypeStatus
res_config_settings_view_form res.config.settings app Inherits sale.res_config_settings_view_form
view_calendar_event_form calendar.event field Inherits calendar.view_calendar_event_form
view_calendar_event_kanban calendar.event.kanban calendar.event kanban New
view_calendar_event_search calendar.event field Inherits calendar.view_calendar_event_search
view_calendar_event_tree calendar.event field Inherits calendar.view_calendar_event_tree
view_calendar_event_tree_primary_only calendar.event.primary.only calendar.event list New
view_calendar_event_type_tree calendar.event.type calendar.event.type field Inherits calendar.view_calendar_event_type_tree
view_partner_form res.partner div Inherits base.view_partner_form
view_sale_planner_calendar_change_hour_form sale.planner.calendar.change.hour.form calendar.event form New
view_sale_planner_calendar_form sale.planner.calendar.event.form calendar.event form New
view_sale_planner_calendar_issue_form sale.planner.calendar.issue.form calendar.event form New
view_sale_planner_calendar_issue_tree sale.planner.calendar.issue.tree calendar.event list New
view_sale_planner_calendar_issue_type_tree sale.planner.calendar.issue.type.tree sale.planner.calendar.issue.type list New
view_sale_planner_calendar_kanban sale.planner.calendar.event.kanban calendar.event kanban New
view_sale_planner_calendar_rating_form sale.planner.calendar.rating.form calendar.event form New
view_sale_planner_calendar_reassign_wiz sale.planner.calendar.reassign.wiz sale.planner.calendar.reassign.wiz form New
view_sale_planner_calendar_search sale.planner.calendar.event calendar.event search New
view_sale_planner_calendar_summary_form sale.planner.calendar.summary.form sale.planner.calendar.summary form New
view_sale_planner_calendar_summary_kanban sale.planner.calendar.event.kanban sale.planner.calendar.summary kanban New
view_sale_planner_calendar_summary_search sale.planner.calendar.summary sale.planner.calendar.summary search New
view_sale_planner_calendar_summary_tree sale.planner.calendar.summary.tree sale.planner.calendar.summary list New
view_sale_planner_calendar_tree sale.planner.calendar.event.tree calendar.event list New
view_sale_planner_calendar_wizard sale.planner.calendar.wizard sale.planner.calendar.wizard form New
Models touched (15)

New fields (0)

No new fields.

Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (32)
  • advanced_cycle Boolean
  • calendar_issue_type_id Many2one → sale.planner.calendar.issue.type
    comodel_name='sale.planner.calendar.issue.type' ondelete='restrict'
  • calendar_summary_id Many2one → sale.planner.calendar.summary
    comodel_name='sale.planner.calendar.summary' copy=False
  • categ_icons Char
    compute='_compute_categ_icons'
  • comment Text
  • cycle_number Integer
  • cycle_skip Integer
  • hour Float
    compute='_compute_hour' inverse='_inverse_hour'
  • invoice_amount_residual Monetary
    compute='_compute_invoice_amount_residual' compute_sudo=True currency_field='sale_planner_currency_id' string='Invoice amount due'
  • invoice_date_due Date
    compute='_compute_invoice_amount_residual' compute_sudo=True string='Due Date'
  • is_base_recurrent_event Boolean
    compute='_compute_is_base_recurrent_event' store=True
  • is_dynamic_end_date Boolean
    copy=False
  • location_url Char
    compute='_compute_location_url'
  • off_planning Boolean
    copy=False
  • partner_city Char
    related='target_partner_id.city'
  • partner_commercial_name Char
    related='target_partner_id.commercial_partner_id.name' string='Commercial partner name'
  • partner_contact_name Char
    compute='_compute_contact'
  • partner_mobile Char
    compute='_compute_contact'
  • partner_name Char
    compute='_compute_partner_name'
  • partner_ref Char
    related='target_partner_id.ref'
  • partner_street Char
    related='target_partner_id.street'
  • partner_user_id Many2one
    related='target_partner_id.user_id' string='Partner salesperson'
  • payment_sheet_line_ids One2many → sale.payment.sheet.line
    comodel_name='sale.payment.sheet.line' inverse_name='sale_planner_calendar_event_id'
  • sale_ids One2many → sale.order
    comodel_name='sale.order' inverse_name='sale_planner_calendar_event_id'
  • sale_order_subtotal Monetary
    compute='_compute_sale_order_subtotal' currency_field='sale_planner_currency_id'
  • sale_planner_currency_id Many2one → res.currency
    comodel_name='res.currency' related='target_partner_id.currency_id'
  • sale_planner_rating Selection
    args: [('1', '😞︎'), ('3', '😐︎'), ('5', '😊︎')]
  • sale_planner_state Selection
    default='pending' readonly=True tracking=True args: [('pending', 'Pending'), ('done', 'Done'), ('cancel', 'Cancelled')]
  • sanitized_partner_mobile Char
    compute='_compute_sanitized_partner_mobile'
  • target_partner_id Many2one → res.partner
    comodel_name='res.partner' help='Is the partner used in planner' string='Sale planner partner'
  • target_partner_mobile Char
    related='target_partner_id.mobile'
  • unsubscribe_date Date
Public methods (14)
  • action_apply_change_hour_wiz(self)
  • action_apply_issue(self)
  • action_cancel(self)
  • action_done(self)
  • action_open_change_hour_wiz(self)
  • action_open_invoices(self)
  • action_open_issue(self)
  • action_open_rating(self)
  • action_open_sale_order(self, new_order=False)
    Search or Create an event planner linked to sale order
  • action_open_unpaid_invoice(self)
  • action_pending(self)
  • action_set_sale_planner_rating(self)
  • cron_update_dynamic_final_date(self)
    @api.model
  • get_week_days_count(self)

New fields (2)
  • duration Float
  • icon Char
    help='Font awesome icon e.g. fa-tasks'
Public methods (0)

No public methods.

New fields (5)
  • sale_planner_done_on_sale_confirm Boolean
    string='Event done when confirm sale'
  • sale_planner_forward_months Integer
    default=12
  • sale_planner_mail_to_attendees Boolean
    default=True string='Send invitation to attendees'
  • sale_planner_order_cut_hour Float
  • susbscriptions_backward_days Integer
    default=180
Public methods (0)

No public methods.

New fields (6)
  • sale_planner_calendar_max_duration Float
    config_parameter='sale_planner_calendar.max_duration' string='Calendar event max duration'
  • sale_planner_done_on_sale_confirm Boolean
    readonly=False related='company_id.sale_planner_done_on_sale_confirm'
  • sale_planner_forward_months Integer
    readonly=False related='company_id.sale_planner_forward_months'
  • sale_planner_mail_to_attendees Boolean
    readonly=False related='company_id.sale_planner_mail_to_attendees'
  • sale_planner_order_cut_hour Float
    readonly=False related='company_id.sale_planner_order_cut_hour'
  • susbscriptions_backward_days Integer
    readonly=False related='company_id.susbscriptions_backward_days'
Public methods (0)

No public methods.

New fields (1)
  • is_sale_planner_contact Boolean
Public methods (2)
  • action_calendar_planner(self)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (1)
  • get_action_sale_planner_calendar_event(self)
    @api.model

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event'
Public methods (0)

No public methods.

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event'
Public methods (2)
  • action_set_planner_calendar_event(self, planner_summary=False)
  • create(self, vals_list)
    @api.model_create_multi

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event'
Public methods (0)

No public methods.

New fields (1)
  • name Char
    translate=True
Public methods (0)

No public methods.

New fields (11)
  • calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event' readonly=True
  • event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' related='calendar_event_id.categ_ids'
  • event_start Datetime
    readonly=True
  • event_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" readonly=True string='Planner salesperson'
  • new_event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' help='Forces new tags for the specified period. Leave empty to keep current tags.' string='New tags'
  • new_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]"
  • partner_id Many2one → res.partner
    comodel_name='res.partner' readonly=True
  • partner_user_id Many2one → res.users
    comodel_name='res.users' string='Partner salesperson'
  • reassign_wiz_id Many2one → sale.planner.calendar.reassign.wiz
    comodel_name='sale.planner.calendar.reassign.wiz'
  • selected Boolean
  • until Datetime
    readonly=True
Public methods (1)
  • update_subscriptions(self)

New fields (12)
  • assign_new_salesperson_to_partner Boolean
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • line_ids One2many → sale.planner.calendar.reassign.line.wiz
    comodel_name='sale.planner.calendar.reassign.line.wiz' inverse_name='reassign_wiz_id'
  • new_end Date
  • new_event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' help='Forces new tags for the specified period. Leave empty to keep current tags.' string='New tags'
  • new_start Date
  • new_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" string='New salesperson'
  • partner_id Many2one → res.partner
    comodel_name='res.partner'
  • partner_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" string='Partner salesperson'
  • unsuscribe_old_salesperson Boolean
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" string='Salesperson'
  • week_list Selection
    string='Weekday' args: [('mon', 'Monday'), ('tue', 'Tuesday'), ('wed', 'Wednesday'), ('thu', 'Thursday'), ('fri', 'Friday'), ('sat', 'Saturday'), ('sun', 'Sunday')]
Public methods (7)
  • action_assign_new_values(self)
  • action_get_lines(self)
  • apply(self)
  • cron_unsubscribe(self, date=None)
    @api.model
  • onchange_filter_values(self)
    @api.onchange('user_id', 'event_type_id', 'week_list', 'partner_user_id', 'partner_id')
  • select_all_lines(self)
  • unselect_all_lines(self)

New fields (17)
  • comment Text
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr>
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id'
  • date Date
    default=fields.Date.context_today
  • event_done_count Integer
    compute='_compute_event_planner_count'
  • event_effective_count Integer
    compute='_compute_event_planner_count'
  • event_off_planning_count Integer
    compute='_compute_event_planner_count'
  • event_total_count Integer
    compute='_compute_event_planner_count'
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • payment_amount Monetary
    compute='_compute_event_planner_count'
  • payment_count Integer
    compute='_compute_event_planner_count'
  • sale_ids One2many → sale.order
    comodel_name='sale.order' compute='_compute_sale_ids'
  • sale_order_count Integer
    compute='_compute_sale_ids'
  • sale_order_subtotal Monetary
    compute='_compute_sale_ids' currency_field='currency_id'
  • sale_planner_calendar_event_ids One2many → calendar.event
    comodel_name='calendar.event' inverse_name='calendar_summary_id'
  • state Selection
    default='pending' args: [('pending', 'Pending'), ('done', 'Done'), ('cancel', 'Cancelled')]
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" index=True
Public methods (9)
  • action_cancel(self)
  • action_done(self)
  • action_event_planner(self)
  • action_get_today_summary(self)
    @api.model
  • action_open_issue(self)
    Open issues related to any event
  • action_open_payment_sheet(self)
    Open payments sheets related to any event
  • action_open_sale_order(self)
    Search or Create an event planner linked to sale order
  • action_pending(self)
  • action_process(self)

New fields (4)
  • calendar_event_ids One2many → calendar.event
    comodel_name='calendar.event' compute='_compute_calendar_event_ids' readonly=False
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" string='Salesperson'
  • week_list Selection
    string='Weekday' args: [('mon', 'Monday'), ('tue', 'Tuesday'), ('wed', 'Wednesday'), ('thu', 'Thursday'), ('fri', 'Friday'), ('sat', 'Saturday'), ('sun', 'Sunday')]
Public methods (2)
  • apply(self)
  • write(self, vals)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/16.0/sale_planner_calendar
VERSION
VERSION 3.1.0
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA)
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA)
COMMITTERS
COMMITTERSCarlos Dauden, Miquel Raïch, sergio-teruel, Weblate, OCA-git-bot, oca-ci, Carlos Roca, pilarvargas-tecnativa
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:53:45
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/sale-workflow:
    - sale_payment_sheet
odoo/odoo:
    - calendar
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - sale
    - sales_team
    - account_payment
    - account
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - payment
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (23)
XML IDNameModelTypeStatus
res_config_settings_view_form res.config.settings div Inherits sale.res_config_settings_view_form
view_calendar_event_form calendar.event field Inherits calendar.view_calendar_event_form
view_calendar_event_kanban calendar.event.kanban calendar.event kanban New
view_calendar_event_search calendar.event field Inherits calendar.view_calendar_event_search
view_calendar_event_tree calendar.event field Inherits calendar.view_calendar_event_tree
view_calendar_event_tree_primary_only calendar.event.primary.only calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type field Inherits calendar.view_calendar_event_type_tree
view_partner_form res.partner div Inherits base.view_partner_form
view_sale_planner_calendar_change_hour_form sale.planner.calendar.change.hour.form calendar.event form New
view_sale_planner_calendar_form sale.planner.calendar.event.form calendar.event form New
view_sale_planner_calendar_issue_form sale.planner.calendar.issue.form calendar.event form New
view_sale_planner_calendar_issue_tree sale.planner.calendar.issue.tree calendar.event tree New
view_sale_planner_calendar_issue_type_tree sale.planner.calendar.issue.type.tree sale.planner.calendar.issue.type tree New
view_sale_planner_calendar_kanban sale.planner.calendar.event.kanban calendar.event kanban New
view_sale_planner_calendar_rating_form sale.planner.calendar.rating.form calendar.event form New
view_sale_planner_calendar_reassign_wiz sale.planner.calendar.reassign.wiz sale.planner.calendar.reassign.wiz form New
view_sale_planner_calendar_search sale.planner.calendar.event calendar.event search New
view_sale_planner_calendar_summary_form sale.planner.calendar.summary.form sale.planner.calendar.summary form New
view_sale_planner_calendar_summary_kanban sale.planner.calendar.event.kanban sale.planner.calendar.summary kanban New
view_sale_planner_calendar_summary_search sale.planner.calendar.summary sale.planner.calendar.summary search New
view_sale_planner_calendar_summary_tree sale.planner.calendar.summary.tree sale.planner.calendar.summary tree New
view_sale_planner_calendar_tree sale.planner.calendar.event.tree calendar.event tree New
view_sale_planner_calendar_wizard sale.planner.calendar.wizard sale.planner.calendar.wizard form New
Models touched (15)

New fields (0)

No new fields.

Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (32)
  • advanced_cycle Boolean
  • calendar_issue_type_id Many2one → sale.planner.calendar.issue.type
    comodel_name='sale.planner.calendar.issue.type' ondelete='restrict'
  • calendar_summary_id Many2one → sale.planner.calendar.summary
    comodel_name='sale.planner.calendar.summary' copy=False
  • categ_icons Char
    compute='_compute_categ_icons'
  • comment Text
  • cycle_number Integer
  • cycle_skip Integer
  • hour Float
    compute='_compute_hour' inverse='_inverse_hour'
  • invoice_amount_residual Monetary
    compute='_compute_invoice_amount_residual' compute_sudo=True currency_field='sale_planner_currency_id' string='Invoice amount due'
  • invoice_date_due Date
    compute='_compute_invoice_amount_residual' compute_sudo=True string='Due Date'
  • is_base_recurrent_event Boolean
    compute='_compute_is_base_recurrent_event' store=True
  • is_dynamic_end_date Boolean
    copy=False
  • location_url Char
    compute='_compute_location_url'
  • off_planning Boolean
    copy=False
  • partner_city Char
    related='target_partner_id.city'
  • partner_commercial_name Char
    related='target_partner_id.commercial_partner_id.name' string='Commercial partner name'
  • partner_contact_name Char
    compute='_compute_contact'
  • partner_mobile Char
    compute='_compute_contact'
  • partner_name Char
    compute='_compute_partner_name'
  • partner_ref Char
    related='target_partner_id.ref'
  • partner_street Char
    related='target_partner_id.street'
  • partner_user_id Many2one
    related='target_partner_id.user_id' string='Partner salesperson'
  • payment_sheet_line_ids One2many → sale.payment.sheet.line
    comodel_name='sale.payment.sheet.line' inverse_name='sale_planner_calendar_event_id'
  • sale_ids One2many → sale.order
    comodel_name='sale.order' inverse_name='sale_planner_calendar_event_id'
  • sale_order_subtotal Monetary
    compute='_compute_sale_order_subtotal' currency_field='sale_planner_currency_id'
  • sale_planner_currency_id Many2one → res.currency
    comodel_name='res.currency' related='target_partner_id.currency_id'
  • sale_planner_rating Selection
    args: [('1', '😞︎'), ('3', '😐︎'), ('5', '😊︎')]
  • sale_planner_state Selection
    default='pending' readonly=True tracking=True args: [('pending', 'Pending'), ('done', 'Done'), ('cancel', 'Cancelled')]
  • sanitized_partner_mobile Char
    compute='_compute_sanitized_partner_mobile'
  • target_partner_id Many2one → res.partner
    comodel_name='res.partner' help='Is the partner used in planner' string='Sale planner partner'
  • target_partner_mobile Char
    related='target_partner_id.mobile'
  • unsubscribe_date Date
Public methods (14)
  • action_apply_change_hour_wiz(self)
  • action_apply_issue(self)
  • action_cancel(self)
  • action_done(self)
  • action_open_change_hour_wiz(self)
  • action_open_invoices(self)
  • action_open_issue(self)
  • action_open_rating(self)
  • action_open_sale_order(self, new_order=False)
    Search or Create an event planner linked to sale order
  • action_open_unpaid_invoice(self)
  • action_pending(self)
  • action_set_sale_planner_rating(self)
  • cron_update_dynamic_final_date(self)
    @api.model
  • get_week_days_count(self)

New fields (2)
  • duration Float
  • icon Char
    help='Font awesome icon e.g. fa-tasks'
Public methods (0)

No public methods.

New fields (5)
  • sale_planner_done_on_sale_confirm Boolean
    string='Event done when confirm sale'
  • sale_planner_forward_months Integer
    default=12
  • sale_planner_mail_to_attendees Boolean
    default=True string='Send invitation to attendees'
  • sale_planner_order_cut_hour Float
  • susbscriptions_backward_days Integer
    default=180
Public methods (0)

No public methods.

New fields (6)
  • sale_planner_calendar_max_duration Float
    config_parameter='sale_planner_calendar.max_duration' string='Calendar event max duration'
  • sale_planner_done_on_sale_confirm Boolean
    readonly=False related='company_id.sale_planner_done_on_sale_confirm'
  • sale_planner_forward_months Integer
    readonly=False related='company_id.sale_planner_forward_months'
  • sale_planner_mail_to_attendees Boolean
    readonly=False related='company_id.sale_planner_mail_to_attendees'
  • sale_planner_order_cut_hour Float
    readonly=False related='company_id.sale_planner_order_cut_hour'
  • susbscriptions_backward_days Integer
    readonly=False related='company_id.susbscriptions_backward_days'
Public methods (0)

No public methods.

New fields (1)
  • is_sale_planner_contact Boolean
Public methods (2)
  • action_calendar_planner(self)
  • write(self, vals)

New fields (0)

No new fields.

Public methods (2)
  • get_action_sale_planner_calendar_event(self)
    @api.model
  • systray_get_activities(self)
    @api.model

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event'
Public methods (0)

No public methods.

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event'
Public methods (2)
  • action_set_planner_calendar_event(self, planner_summary=False)
  • create(self, vals_list)
    @api.model_create_multi

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event'
Public methods (0)

No public methods.

New fields (1)
  • name Char
    translate=True
Public methods (0)

No public methods.

New fields (11)
  • calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event' readonly=True
  • event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' related='calendar_event_id.categ_ids'
  • event_start Datetime
    readonly=True
  • event_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" readonly=True string='Planner salesperson'
  • new_event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' help='Forces new tags for the specified period. Leave empty to keep current tags.' string='New tags'
  • new_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]"
  • partner_id Many2one → res.partner
    comodel_name='res.partner' readonly=True
  • partner_user_id Many2one → res.users
    comodel_name='res.users' string='Partner salesperson'
  • reassign_wiz_id Many2one → sale.planner.calendar.reassign.wiz
    comodel_name='sale.planner.calendar.reassign.wiz'
  • selected Boolean
  • until Datetime
    readonly=True
Public methods (1)
  • update_subscriptions(self)

New fields (12)
  • assign_new_salesperson_to_partner Boolean
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • line_ids One2many → sale.planner.calendar.reassign.line.wiz
    comodel_name='sale.planner.calendar.reassign.line.wiz' inverse_name='reassign_wiz_id'
  • new_end Date
  • new_event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' help='Forces new tags for the specified period. Leave empty to keep current tags.' string='New tags'
  • new_start Date
  • new_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" string='New salesperson'
  • partner_id Many2one → res.partner
    comodel_name='res.partner'
  • partner_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" string='Partner salesperson'
  • unsuscribe_old_salesperson Boolean
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" string='Salesperson'
  • week_list Selection
    string='Weekday' args: [('mon', 'Monday'), ('tue', 'Tuesday'), ('wed', 'Wednesday'), ('thu', 'Thursday'), ('fri', 'Friday'), ('sat', 'Saturday'), ('sun', 'Sunday')]
Public methods (7)
  • action_assign_new_values(self)
  • action_get_lines(self)
  • apply(self)
  • cron_unsubscribe(self, date=None)
    @api.model
  • onchange_filter_values(self)
    @api.onchange('user_id', 'event_type_id', 'week_list', 'partner_user_id', 'partner_id')
  • select_all_lines(self)
  • unselect_all_lines(self)

New fields (17)
  • comment Text
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr>
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id'
  • date Date
    default=fields.Date.context_today
  • event_done_count Integer
    compute='_compute_event_planner_count'
  • event_effective_count Integer
    compute='_compute_event_planner_count'
  • event_off_planning_count Integer
    compute='_compute_event_planner_count'
  • event_total_count Integer
    compute='_compute_event_planner_count'
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • payment_amount Monetary
    compute='_compute_event_planner_count'
  • payment_count Integer
    compute='_compute_event_planner_count'
  • sale_ids One2many → sale.order
    comodel_name='sale.order' compute='_compute_sale_ids'
  • sale_order_count Integer
    compute='_compute_sale_ids'
  • sale_order_subtotal Monetary
    compute='_compute_sale_ids' currency_field='currency_id'
  • sale_planner_calendar_event_ids One2many → calendar.event
    comodel_name='calendar.event' inverse_name='calendar_summary_id'
  • state Selection
    default='pending' args: [('pending', 'Pending'), ('done', 'Done'), ('cancel', 'Cancelled')]
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" index=True
Public methods (10)
  • action_cancel(self)
  • action_done(self)
  • action_event_planner(self)
  • action_get_today_summary(self)
    @api.model
  • action_open_issue(self)
    Open issues related to any event
  • action_open_payment_sheet(self)
    Open payments sheets related to any event
  • action_open_sale_order(self)
    Search or Create an event planner linked to sale order
  • action_pending(self)
  • action_process(self)
  • name_get(self)

New fields (4)
  • calendar_event_ids One2many → calendar.event
    comodel_name='calendar.event' compute='_compute_calendar_event_ids' readonly=False
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" string='Salesperson'
  • week_list Selection
    string='Weekday' args: [('mon', 'Monday'), ('tue', 'Tuesday'), ('wed', 'Wednesday'), ('thu', 'Thursday'), ('fri', 'Friday'), ('sat', 'Saturday'), ('sun', 'Sunday')]
Public methods (3)
  • apply(self)
  • name_get(self)
    @api.depends('user_id', 'event_type_id')
  • write(self, vals)
REPOSITORY
REPOSITORYOCA/sale-workflow
GIT
GIThttps://github.com/OCA/sale-workflow.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/sale-workflow/tree/15.0/sale_planner_calendar
VERSION
VERSION 4.0.3
CATEGORY
CATEGORYSale
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA)
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA)
COMMITTERS
COMMITTERSCarlos Dauden, sergio-teruel, Ernesto Tejeda, Weblate, OCA-git-bot, oca-ci, Carlos Roca, pilarvargas-tecnativa, CarlosRoca13, Carolina Fernandez, Andrii9090-tecnativa, josep-tecnativa
WEBSITE
WEBSITEhttps://github.com/OCA/sale-workflow
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:46:33
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/sale-workflow:
    - sale_payment_sheet
odoo/odoo:
    - calendar
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - sale
    - sales_team
    - payment
    - account
    - product
    - uom
    - analytic
    - portal
    - web_editor
    - http_routing
    - auth_signup
    - digest
    - resource
    - utm
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION

Code Analysis

Views touched (22)
XML IDNameModelTypeStatus
res_config_settings_view_form res.config.settings div Inherits sale.res_config_settings_view_form
view_calendar_event_form calendar.event field Inherits calendar.view_calendar_event_form
view_calendar_event_kanban calendar.event.kanban calendar.event kanban New
view_calendar_event_search calendar.event field Inherits calendar.view_calendar_event_search
view_calendar_event_tree calendar.event field Inherits calendar.view_calendar_event_tree
view_calendar_event_tree_primary_only calendar.event.primary.only calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type field Inherits calendar.view_calendar_event_type_tree
view_partner_form res.partner div Inherits base.view_partner_form
view_sale_planner_calendar_change_hour_form sale.planner.calendar.change.hour.form calendar.event form New
view_sale_planner_calendar_form sale.planner.calendar.event.form calendar.event form New
view_sale_planner_calendar_issue_form sale.planner.calendar.issue.form calendar.event form New
view_sale_planner_calendar_issue_tree sale.planner.calendar.issue.tree calendar.event tree New
view_sale_planner_calendar_issue_type_tree sale.planner.calendar.issue.type.tree sale.planner.calendar.issue.type tree New
view_sale_planner_calendar_kanban sale.planner.calendar.event.kanban calendar.event kanban New
view_sale_planner_calendar_reassign_wiz sale.planner.calendar.reassign.wiz sale.planner.calendar.reassign.wiz form New
view_sale_planner_calendar_search sale.planner.calendar.event calendar.event search New
view_sale_planner_calendar_summary_form sale.planner.calendar.summary.form sale.planner.calendar.summary form New
view_sale_planner_calendar_summary_kanban sale.planner.calendar.event.kanban sale.planner.calendar.summary kanban New
view_sale_planner_calendar_summary_search sale.planner.calendar.summary sale.planner.calendar.summary search New
view_sale_planner_calendar_summary_tree sale.planner.calendar.summary.tree sale.planner.calendar.summary tree New
view_sale_planner_calendar_tree sale.planner.calendar.event.tree calendar.event tree New
view_sale_planner_calendar_wizard sale.planner.calendar.wizard sale.planner.calendar.wizard form New
Models touched (15)

New fields (0)

No new fields.

Public methods (1)
  • create(self, vals_list)
    @api.model_create_multi

New fields (31)
  • advanced_cycle Boolean
  • calendar_issue_type_id Many2one → sale.planner.calendar.issue.type
    comodel_name='sale.planner.calendar.issue.type' ondelete='restrict'
  • calendar_summary_id Many2one → sale.planner.calendar.summary
    comodel_name='sale.planner.calendar.summary' copy=False
  • comment Text
  • cycle_number Integer
  • cycle_skip Integer
  • hour Float
    compute='_compute_hour' inverse='_inverse_hour'
  • invoice_amount_residual Monetary
    compute='_compute_invoice_amount_residual' compute_sudo=True currency_field='sale_planner_currency_id' string='Invoice amount due'
  • invoice_date_due Date
    compute='_compute_invoice_amount_residual' compute_sudo=True string='Due Date'
  • is_base_recurrent_event Boolean
    compute='_compute_is_base_recurrent_event' store=True
  • is_dynamic_end_date Boolean
    copy=False
  • location_url Char
    compute='_compute_location_url'
  • off_planning Boolean
    copy=False
  • partner_city Char
    related='target_partner_id.city'
  • partner_commercial_name Char
    related='target_partner_id.commercial_partner_id.name' string='Commercial partner name'
  • partner_contact_name Char
    compute='_compute_contact'
  • partner_mobile Char
    compute='_compute_contact'
  • partner_name Char
    compute='_compute_partner_name'
  • partner_ref Char
    related='target_partner_id.ref'
  • partner_street Char
    related='target_partner_id.street'
  • partner_user_id Many2one
    related='target_partner_id.user_id' string='Partner salesperson'
  • payment_sheet_line_ids One2many → sale.payment.sheet.line
    comodel_name='sale.payment.sheet.line' inverse_name='sale_planner_calendar_event_id'
  • profile_icon Char
    related='categ_ids.icon'
  • sale_ids One2many → sale.order
    comodel_name='sale.order' inverse_name='sale_planner_calendar_event_id'
  • sale_order_subtotal Monetary
    compute='_compute_sale_order_subtotal' currency_field='sale_planner_currency_id'
  • sale_planner_currency_id Many2one → res.currency
    comodel_name='res.currency' related='target_partner_id.currency_id'
  • sale_planner_state Selection
    default='pending' readonly=True tracking=True args: [('pending', 'Pending'), ('done', 'Done'), ('cancel', 'Cancelled')]
  • sanitized_partner_mobile Char
    compute='_compute_sanitized_partner_mobile'
  • target_partner_id Many2one → res.partner
    comodel_name='res.partner' help='Is the partner used in planner' string='Sale planner partner'
  • target_partner_mobile Char
    related='target_partner_id.mobile'
  • unsubscribe_date Date
Public methods (11)
  • action_apply_change_hour_wiz(self)
  • action_apply_issue(self)
  • action_cancel(self)
  • action_done(self)
  • action_open_invoices(self)
  • action_open_issue(self)
  • action_open_sale_order(self, new_order=False)
    Search or Create an event planner linked to sale order
  • action_open_unpaid_invoice(self)
  • action_pending(self)
  • cron_update_dynamic_final_date(self)
    @api.model
  • get_week_days_count(self)

New fields (2)
  • duration Float
  • icon Char
    help='Font awesome icon e.g. fa-tasks'
Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one
    index=True
Public methods (0)

No public methods.

New fields (5)
  • sale_planner_done_on_sale_confirm Boolean
    string='Event done when confirm sale'
  • sale_planner_forward_months Integer
    default=12
  • sale_planner_mail_to_attendees Boolean
    default=True string='Send invitation to attendees'
  • sale_planner_order_cut_hour Float
  • susbscriptions_backward_days Integer
    default=180
Public methods (0)

No public methods.

New fields (6)
  • sale_planner_calendar_max_duration Float
    config_parameter='sale_planner_calendar.max_duration' string='Calendar event max duration'
  • sale_planner_done_on_sale_confirm Boolean
    readonly=False related='company_id.sale_planner_done_on_sale_confirm'
  • sale_planner_forward_months Integer
    readonly=False related='company_id.sale_planner_forward_months'
  • sale_planner_mail_to_attendees Boolean
    readonly=False related='company_id.sale_planner_mail_to_attendees'
  • sale_planner_order_cut_hour Float
    readonly=False related='company_id.sale_planner_order_cut_hour'
  • susbscriptions_backward_days Integer
    readonly=False related='company_id.susbscriptions_backward_days'
Public methods (0)

No public methods.

New fields (1)
  • is_sale_planner_contact Boolean
Public methods (2)
  • action_calendar_planner(self)
  • write(self, vals)

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event'
Public methods (0)

No public methods.

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event' index=True
Public methods (2)
  • action_set_planner_calendar_event(self, planner_summary=False)
  • create(self, vals_list)
    @api.model_create_multi

New fields (1)
  • sale_planner_calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event' index=True
Public methods (0)

No public methods.

New fields (1)
  • name Char
    translate=True
Public methods (0)

No public methods.

New fields (11)
  • calendar_event_id Many2one → calendar.event
    comodel_name='calendar.event' readonly=True
  • event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' related='calendar_event_id.categ_ids'
  • event_start Datetime
    readonly=True
  • event_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" readonly=True string='Planner salesperson'
  • new_event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' help='Forces new tags for the specified period. Leave empty to keep current tags.' string='New tags'
  • new_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]"
  • partner_id Many2one → res.partner
    comodel_name='res.partner' readonly=True
  • partner_user_id Many2one → res.users
    comodel_name='res.users' string='Partner salesperson'
  • reassign_wiz_id Many2one → sale.planner.calendar.reassign.wiz
    comodel_name='sale.planner.calendar.reassign.wiz'
  • selected Boolean
  • until Datetime
    readonly=True
Public methods (1)
  • update_subscriptions(self)

New fields (12)
  • assign_new_salesperson_to_partner Boolean
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • line_ids One2many → sale.planner.calendar.reassign.line.wiz
    comodel_name='sale.planner.calendar.reassign.line.wiz' inverse_name='reassign_wiz_id'
  • new_end Date
  • new_event_categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' help='Forces new tags for the specified period. Leave empty to keep current tags.' string='New tags'
  • new_start Date
  • new_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" string='New salesperson'
  • partner_id Many2one → res.partner
    comodel_name='res.partner'
  • partner_user_id Many2one → res.users
    comodel_name='res.users' domain="[('share','=',False)]" string='Partner salesperson'
  • unsuscribe_old_salesperson Boolean
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" string='Salesperson'
  • week_list Selection
    string='Weekday' args: [('mon', 'Monday'), ('tue', 'Tuesday'), ('wed', 'Wednesday'), ('thu', 'Thursday'), ('fri', 'Friday'), ('sat', 'Saturday'), ('sun', 'Sunday')]
Public methods (7)
  • action_assign_new_values(self)
  • action_get_lines(self)
  • apply(self)
  • cron_unsubscribe(self, date=None)
    @api.model
  • onchange_filter_values(self)
    @api.onchange('user_id', 'event_type_id', 'week_list', 'partner_user_id', 'partner_id')
  • select_all_lines(self)
  • unselect_all_lines(self)

New fields (17)
  • comment Text
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr>
  • currency_id Many2one → res.currency
    comodel_name='res.currency' related='company_id.currency_id'
  • date Date
    default=fields.Date.context_today
  • event_done_count Integer
    compute='_compute_event_planner_count'
  • event_effective_count Integer
    compute='_compute_event_planner_count'
  • event_off_planning_count Integer
    compute='_compute_event_planner_count'
  • event_total_count Integer
    compute='_compute_event_planner_count'
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • payment_amount Monetary
    compute='_compute_event_planner_count'
  • payment_count Integer
    compute='_compute_event_planner_count'
  • sale_ids One2many → sale.order
    comodel_name='sale.order' compute='_compute_sale_ids'
  • sale_order_count Integer
    compute='_compute_sale_ids'
  • sale_order_subtotal Monetary
    compute='_compute_sale_ids' currency_field='currency_id'
  • sale_planner_calendar_event_ids One2many → calendar.event
    comodel_name='calendar.event' inverse_name='calendar_summary_id'
  • state Selection
    default='pending' args: [('pending', 'Pending'), ('done', 'Done'), ('cancel', 'Cancelled')]
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" index=True
Public methods (10)
  • action_cancel(self)
  • action_done(self)
  • action_event_planner(self)
  • action_get_today_summary(self)
    @api.model
  • action_open_issue(self)
    Open issues related to any event
  • action_open_payment_sheet(self)
    Open payments sheets related to any event
  • action_open_sale_order(self)
    Search or Create an event planner linked to sale order
  • action_pending(self)
  • action_process(self)
  • name_get(self)

New fields (4)
  • calendar_event_ids One2many → calendar.event
    comodel_name='calendar.event' compute='_compute_calendar_event_ids' readonly=False
  • event_type_id Many2one → calendar.event.type
    comodel_name='calendar.event.type' string='Event type'
  • user_id Many2one → res.users
    comodel_name='res.users' default=<expr> domain="[('share','=',False)]" string='Salesperson'
  • week_list Selection
    string='Weekday' args: [('mon', 'Monday'), ('tue', 'Tuesday'), ('wed', 'Wednesday'), ('thu', 'Thursday'), ('fri', 'Friday'), ('sat', 'Saturday'), ('sun', 'Sunday')]
Public methods (3)
  • apply(self)
  • name_get(self)
    @api.depends('user_id', 'event_type_id')
  • write(self, vals)