diff --git a/extra-addons/approvals/__manifest__.py b/extra-addons/approvals/__manifest__.py index 92fbca0ac..a0992081c 100644 --- a/extra-addons/approvals/__manifest__.py +++ b/extra-addons/approvals/__manifest__.py @@ -16,24 +16,23 @@ procurements, contract approval, etc. According to the approval type configuration, a request creates next activities for the related approvers. """, - 'depends': ['mail', 'hr', 'product'], + 'depends': ['mail', 'hr', 'product','hr_promote'], 'data': [ 'security/approval_security.xml', 'security/ir.model.access.csv', - 'data/approval_category_data.xml', 'data/mail_activity_type_data.xml', 'data/mail_message_subtype_data.xml', - 'views/approval_category_views.xml', 'views/approval_category_approver_views.xml', 'views/approval_product_line_views.xml', 'views/approval_products_views.xml', + 'views/approval_promotion_line_views.xml', 'views/approval_request_template.xml', 'report/approval_request_report.xml', 'views/approval_request_views.xml', 'views/res_users_views.xml', - 'views/approval_condition_views.xml' + 'views/approval_condition_views.xml', ], 'demo':[ 'data/approval_demo.xml', diff --git a/extra-addons/approvals/data/approval_category_data.xml b/extra-addons/approvals/data/approval_category_data.xml index 570e3b0f6..0b915b127 100644 --- a/extra-addons/approvals/data/approval_category_data.xml +++ b/extra-addons/approvals/data/approval_category_data.xml @@ -135,5 +135,20 @@ optional 1 + + Promote + + 80 + no + required + no + no + no + optional + no + no + required + optional + diff --git a/extra-addons/approvals/models/__init__.py b/extra-addons/approvals/models/__init__.py index 7ac1bd6ae..8d2fca50c 100644 --- a/extra-addons/approvals/models/__init__.py +++ b/extra-addons/approvals/models/__init__.py @@ -7,4 +7,5 @@ from . import approval_product_line from . import approval_request from . import mail_activity from . import ir_attachment -from . import approval_condition +from . import approval_category_condition +from . import approval_promotion_line \ No newline at end of file diff --git a/extra-addons/approvals/models/approval_category.py b/extra-addons/approvals/models/approval_category.py index c9d2bad1e..c928729ac 100644 --- a/extra-addons/approvals/models/approval_category.py +++ b/extra-addons/approvals/models/approval_category.py @@ -59,10 +59,15 @@ class ApprovalCategory(models.Model): has_product = fields.Selection( CATEGORY_SELECTION, string="Has Product", default="no", required=True, help="Additional products that should be specified on the request.") + has_promotion = fields.Selection( + CATEGORY_SELECTION, string="Has Promotion", default="no", required=True, + help="Additional promotion that should be specified on the request.") + + requirer_document = fields.Selection([('required', 'Required'), ('optional', 'Optional')], string="Documents", default="optional", required=True) approval_minimum = fields.Integer(string="Minimum Approval", default="1", required=True) - invalid_minimum = fields.Boolean(compute='_compute_invalid_minimum') - invalid_minimum_warning = fields.Char(compute='_compute_invalid_minimum') + # invalid_minimum = fields.Boolean(compute='_compute_invalid_minimum') + # invalid_minimum_warning = fields.Char(compute='_compute_invalid_minimum') approval_type = fields.Selection(string="Approval Type", selection=[], help="Allows you to define which documents you would like to create once the request has been approved") manager_approval = fields.Selection([('approver', 'Is Approver'), ('required', 'Is Required Approver')], @@ -74,16 +79,12 @@ class ApprovalCategory(models.Model): Is Required Approver: the employee's manager will be required to approve the request. """) - # Python code - code = fields.Text(string='Python Code', groups='base.group_system', - default=DEFAULT_PYTHON_CODE, - help="Write Python code that the action will execute. Some variables are " - "available for use; help about python expression is given in the help tab.") # ---------------------------------------- Relational ----------------------------------------- user_ids = fields.Many2many('res.users', compute='_compute_user_ids', string="Approver Users") approver_ids = fields.One2many('approval.category.approver', 'category_id', string="Approvers") + conditions_ids = fields.One2many('approval.category.condition', 'category_id', string="Approval Condition") approver_sequence = fields.Boolean('Approvers Sequence?', help="If checked, the approvers have to approve in sequence (one after the other). If Employee's Manager is selected as approver, they will be the first in line.") request_to_validate_count = fields.Integer("Number of requests to validate", compute="_compute_request_to_validate_count") @@ -93,12 +94,28 @@ class ApprovalCategory(models.Model): sequence_code = fields.Char(string="Code") sequence_id = fields.Many2one('ir.sequence', 'Reference Sequence', copy=False, check_company=True) - - model_id = fields.Many2one('ir.model', 'Model',copy=False) + model_id = fields.Many2one('ir.model', string='Model', store=True) + model_name = fields.Char(string='Model Name', related='model_id.model', store=True) - conditions_ids = fields.Many2many('approval.condition', 'approval_category_condition_rel', 'category_id', 'condition_id') + invalid_minimum = fields.Boolean("Invalid Minimum", compute="_compute_invalid_minimum", store=True, readonly=False) + invalid_minimum_warning = fields.Boolean("Invalid minimum Warning",compute="_compute_invalid_minimum_warning") + domain = fields.Char(compute='_compute_domain') + + + # ---------------------------------------- Methods ----------------------------------------- - + + def _compute_domain(self): + for record in self: + record.domain = record.conditions_ids.domain if record.conditions_ids else '[]' + @api.depends('conditions_ids') + def _compute_invalid_minimum(self): + for record in self.filtered('conditions_ids'): + record.invalid_minimum = record.conditions_ids.invalid_minimum + @api.depends('conditions_ids') + def _compute_invalid_minimum_warning(self): + for record in self.filtered('conditions_ids'): + record.invalid_minimum_warning = record.conditions_ids.invalid_minimum_warning def _compute_request_to_validate_count(self): domain = [('request_status', '=', 'pending'), ('approver_ids.user_id', '=', self.env.user.id)] requests_data = self.env['approval.request']._read_group(domain, ['category_id'], ['__count']) @@ -106,29 +123,25 @@ class ApprovalCategory(models.Model): for category in self: category.request_to_validate_count = requests_mapped_data.get(category.id, 0) - - - - @api.depends_context('lang') - @api.depends('approval_minimum', 'approver_ids', 'manager_approval') - def _compute_invalid_minimum(self): - for record in self: - if record.approval_minimum > len(record.approver_ids) + int(bool(record.manager_approval)): - record.invalid_minimum = True - else: - record.invalid_minimum = False - record.invalid_minimum_warning = record.invalid_minimum and _('Your minimum approval exceeds the total of default approvers.') - + # @api.depends_context('lang') + # @api.depends('approval_minimum', 'approver_ids', 'manager_approval') + # def _compute_invalid_minimum(self): + # for record in self: + # if record.approval_minimum > len(record.approver_ids) + int(bool(record.manager_approval)): + # record.invalid_minimum = True + # else: + # record.invalid_minimum = False + # record.invalid_minimum_warning = record.invalid_minimum and _('Your minimum approval exceeds the total of default approvers.') @api.depends('approver_ids') def _compute_user_ids(self): for record in self: record.user_ids = record.approver_ids.user_id - @api.constrains('approval_minimum', 'approver_ids') - def _constrains_approval_minimum(self): - for record in self: - if record.approval_minimum < len(record.approver_ids.filtered('required')): - raise ValidationError(_('Minimum Approval must be equal or superior to the sum of required Approvers.')) + # @api.constrains('approval_minimum', 'approver_ids') + # def _constrains_approval_minimum(self): + # for record in self: + # if record.approval_minimum < len(record.approver_ids.filtered('required')): + # raise ValidationError(_('Minimum Approval must be equal or superior to the sum of required Approvers.')) @api.constrains('approver_ids') def _constrains_approver_ids(self): @@ -139,11 +152,10 @@ class ApprovalCategory(models.Model): for record in self: if len(record.approver_ids) != len(record.approver_ids.user_id): raise ValidationError(_('An user may not be in the approver list multiple times.')) - - @api.constrains('approver_sequence', 'approval_minimum') - def _constrains_approver_sequence(self): - if any(a.approver_sequence and not a.approval_minimum for a in self): - raise ValidationError(_('Approver Sequence can only be activated with at least 1 minimum approver.')) + # @api.constrains('approver_sequence', 'approval_minimum') + # def _constrains_approver_sequence(self): + # if any(a.approver_sequence and not a.approval_minimum for a in self): + # raise ValidationError(_('Approver Sequence can only be activated with at least 1 minimum approver.')) @api.model_create_multi def create(self, vals_list): diff --git a/extra-addons/approvals/models/approval_category_approver.py b/extra-addons/approvals/models/approval_category_approver.py index 800aa276d..15ab43b5e 100644 --- a/extra-addons/approvals/models/approval_category_approver.py +++ b/extra-addons/approvals/models/approval_category_approver.py @@ -11,16 +11,28 @@ class ApprovalCategoryApprover(models.Model): _description = 'Approval Type Approver' _rec_name = 'user_id' _order = 'sequence' - sequence = fields.Integer('Sequence', default=10) - category_id = fields.Many2one('approval.category', string='Approval Type', ondelete='cascade', required=True) + category_id = fields.Many2one('approval.category', string='Approval Type', required=True) company_id = fields.Many2one('res.company', related='category_id.company_id') user_id = fields.Many2one('res.users', string='User', ondelete='cascade', required=True, check_company=True, domain="[('company_ids', 'in', company_id), ('id', 'not in', existing_user_ids)]") + job_title = fields.Char(string='Job Position', compute='_compute_job_title', store=True) + existing_user_ids = fields.Many2many('res.users', compute='_compute_existing_user_ids') required = fields.Boolean(default=False) - existing_user_ids = fields.Many2many('res.users', compute='_compute_existing_user_ids') + @api.depends('user_id', 'company_id') + def _compute_job_title(self): + for record in self: + if record.user_id and record.company_id: + # Search for the employee linked to the user and company + employee = self.env['hr.employee'].search([ + ('user_id', '=', record.user_id.id), + ('company_id', '=', record.company_id.id) + ], limit=1) + record.job_title = employee.job_title if employee else '' + else: + record.job_title = '' @api.depends('category_id') def _compute_existing_user_ids(self): for record in self: diff --git a/extra-addons/approvals/models/approval_category_condition.py b/extra-addons/approvals/models/approval_category_condition.py new file mode 100644 index 000000000..629b15d32 --- /dev/null +++ b/extra-addons/approvals/models/approval_category_condition.py @@ -0,0 +1,72 @@ +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + +class ApprovalConditions(models.Model): + _name = 'approval.category.condition' + _description = 'Approval Condition' + _order = 'sequence, id' + + sequence = fields.Integer(default=1) + description = fields.Text(string="Description") + approver_sequence = fields.Boolean('Approvers Sequence?', help="If checked, the approvers have to approve in sequence.") + approval_minimum = fields.Integer(string="Minimum Approval", default=5, required=True) + invalid_minimum = fields.Boolean(compute='_compute_invalid_minimum') + invalid_minimum_warning = fields.Char(compute='_compute_invalid_minimum') + approver_ids = fields.One2many('approval.category.approver', 'category_id', string="Approvers") + category_id = fields.Many2one('approval.category', string="Approval Category", required=True,ondelete="cascade") + model_id = fields.Many2one('ir.model', string='Model', related='category_id.model_id', store=True, readonly=True) + model_name = fields.Char( + string='Model Name', + related='model_id.model', + store=True, + readonly=True + ) + domain = fields.Char(string="Conditions", compute='_compute_domain', readonly=False, store=True) + + # @api.depends('category_id.model_id') + # def _compute_model_id(self): + # """Compute the model_id from the related approval category.""" + # for record in self: + # record.model_id = record.category_id.model_id + + + @api.depends('model_id') + def _compute_domain(self): + for record in self: + record.domain = '[]' + + @api.depends('approval_minimum', 'approver_ids') + def _compute_invalid_minimum(self): + for record in self: + if record.approval_minimum >= len(record.approver_ids): + record.invalid_minimum = False + else: + record.invalid_minimum = True + record.invalid_minimum_warning = record.invalid_minimum and _('Your minimum approval exceeds the total of default approvers.') + + # @api.depends('approver_ids') + # def _compute_user_ids(self): + # for record in self: + # record.user_ids = record.approver_ids.user_id + + # @api.depends('model_name') + # def _compute_filter_id(self): + # for record in self: + # record.filter_id = False + + @api.constrains('approval_minimum', 'approver_ids') + def _constrains_approval_minimum(self): + for record in self: + if record.approval_minimum < len(record.approver_ids): + raise ValidationError(_('Minimum Approval must be equal or superior to the sum of required Approvers.')) + + @api.constrains('approver_sequence', 'approval_minimum') + def _constrains_approver_sequence(self): + for record in self: + if record.approver_sequence and record.approval_minimum < 1: + raise ValidationError(_('Approver Sequence can only be activated with at least 1 minimum approver.')) + + def delete_condition(self): + for record in self: + record.unlink() + diff --git a/extra-addons/approvals/models/approval_condition.py b/extra-addons/approvals/models/approval_condition.py deleted file mode 100644 index f39de8204..000000000 --- a/extra-addons/approvals/models/approval_condition.py +++ /dev/null @@ -1,77 +0,0 @@ -from odoo import api, fields, models - -class ApprovalConditions(models.Model): - _name = 'approval.condition' - _description = 'Approval Condition' - _order = 'sequence, id' - - name = fields.Char(string="Name", required=True) - description = fields.Text(string="Description", required=True) - - filter_pre_condition = fields.Char( - string='Condition', - compute='_compute_filter_pre_condition', - readonly=False, store=True, - help="If present, this condition must be satisfied before the update of the record. " - "Not checked on record creation.") - - trigger = fields.Selection( - [ - ('on_stage_set', "Stage is set to"), - ('on_user_set', "User is set"), - ('on_tag_set', "Tag is added"), - ('on_state_set', "State is set to"), - ('on_priority_set', "Priority is set to"), - ('on_archive', "On archived"), - ('on_unarchive', "On unarchived"), - ('on_create_or_write', "On save"), - ('on_create', "On creation"), # deprecated, use 'on_create_or_write' instead - ('on_write', "On update"), # deprecated, use 'on_create_or_write' instead - ('on_unlink', "On deletion"), - ('on_change', "On UI change"), - ('on_time', "Based on date field"), - ('on_time_created', "After creation"), - ('on_time_updated', "After last update"), - ("on_message_received", "On incoming message"), - ("on_message_sent", "On outgoing message"), - ('on_webhook', "On webhook"), - ], string='Trigger', - compute='_compute_trigger', readonly=False, store=True, required=True - ) - - trigger_field_ids = fields.Many2many( - 'ir.model.fields', string='Trigger Fields', - compute='_compute_trigger_field_ids', readonly=False, store=True, - help="The automation rule will be triggered if and only if one of these fields is updated." - "If empty, all fields are watched.") - - trg_field_ref = fields.Reference( - selection=[('ir.model.fields', 'Field Reference')], - string='Trigger Reference', - readonly=False, - store=True, - help="Some triggers need a reference to another field. This field is used to store it." - ) - - sequence = fields.Boolean('Approvers Sequence?', help="If checked, the approvers have to approve in sequence.") - approval_minimum = fields.Integer(string="Minimum Approval", default=1, required=True) - user_ids = fields.Many2many('res.users', compute='_compute_user_ids', string="Approver Users") - approver_ids = fields.One2many('approval.category.approver', 'category_id', string="Approvers") - @api.depends('approver_ids') - def _compute_user_ids(self): - for record in self: - record.user_ids = record.approver_ids.user_id - @api.depends('trigger', 'trigger_field_ids', 'trg_field_ref') - def _compute_filter_pre_condition(self): - for automation in self: - if automation.trigger != 'on_tag_set' or len(automation.trigger_field_ids) != 1: - automation.filter_pre_condition = False - else: - field = automation.trigger_field_ids.name - value = automation.trg_field_ref - automation.filter_pre_condition = f"[('{field}', 'not in', [{value}])]" if value else False - - def delete_condition(self): - for record in self: - record.unlink() - diff --git a/extra-addons/approvals/models/approval_promotion_line.py b/extra-addons/approvals/models/approval_promotion_line.py new file mode 100644 index 000000000..71622890d --- /dev/null +++ b/extra-addons/approvals/models/approval_promotion_line.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + +class ApprovalPromotionLine(models.Model): + _name = 'approval.promotion.line' + _description = 'Promote Line' + + _check_company_auto = True + + approval_request_id = fields.Many2one('approval.request', required=True) + description = fields.Char( + "Description", required=True, + compute="_compute_promotion", store=True, readonly=False, precompute=True) + + company_id = fields.Many2one( + string='Company', related='approval_request_id.company_id', + store=True, readonly=True, index=True) + promote_id = fields.Many2one('hr.promote', string="Promotion", check_company=True) + current_job = fields.Char( + "Current Job", required=True, + compute="_compute_promotion", store=True, readonly=True, precompute=True) + designation_job = fields.Char( + "New Designation", required=True, + compute="_compute_promotion", store=True, readonly=True, precompute=True) + @api.depends('promote_id') + def _compute_promotion(self): + for line in self: + line.description = line.promote_id.description or line.promote_id.display_name + line.current_job = line.promote_id.job_id.name or '' + line.designation_job = line.promote_id.designation_id.name or '' + \ No newline at end of file diff --git a/extra-addons/approvals/models/approval_request.py b/extra-addons/approvals/models/approval_request.py index 2f8212d6f..f9c77ed98 100644 --- a/extra-addons/approvals/models/approval_request.py +++ b/extra-addons/approvals/models/approval_request.py @@ -14,7 +14,7 @@ class ApprovalRequest(models.Model): _check_company_auto = True name = fields.Char(string="Approval Subject", tracking=True) - category_id = fields.Many2one('approval.category', string="Category", required=True) + category_id = fields.Many2one('approval.category', string="Category", required=True,ondelete='cascade') category_image = fields.Binary(related='category_id.image') approver_ids = fields.One2many('approval.approver', 'request_id', string="Approvers", check_company=True, compute='_compute_approver_ids', store=True, readonly=False) @@ -57,7 +57,7 @@ class ApprovalRequest(models.Model): attachment_ids = fields.One2many(comodel_name='ir.attachment', inverse_name='res_id', domain=[('res_model', '=', 'approval.request')], string='Attachments') attachment_number = fields.Integer('Number of Attachments', compute='_compute_attachment_number') product_line_ids = fields.One2many('approval.product.line', 'approval_request_id', check_company=True) - + promotion_line_ids = fields.One2many('approval.promotion.line', 'approval_request_id', check_company=True) has_date = fields.Selection(related="category_id.has_date") has_period = fields.Selection(related="category_id.has_period") has_quantity = fields.Selection(related="category_id.has_quantity") @@ -67,12 +67,13 @@ class ApprovalRequest(models.Model): has_payment_method = fields.Selection(related="category_id.has_payment_method") has_location = fields.Selection(related="category_id.has_location") has_product = fields.Selection(related="category_id.has_product") + has_promotion = fields.Selection(related="category_id.has_promotion") + requirer_document = fields.Selection(related="category_id.requirer_document") approval_minimum = fields.Integer(related="category_id.approval_minimum") approval_type = fields.Selection(related="category_id.approval_type") approver_sequence = fields.Boolean(related="category_id.approver_sequence") automated_sequence = fields.Boolean(related="category_id.automated_sequence") - @api.depends('approver_ids') def _compute_user_ids(self): for request in self: @@ -105,11 +106,23 @@ class ApprovalRequest(models.Model): category = 'category_id' in vals and self.env['approval.category'].browse(vals['category_id']) if category and category.automated_sequence: vals['name'] = category.sequence_id.next_by_id() + self._check_conditions_promotion(vals) created_requests = super().create(vals_list) for request in created_requests: request.message_subscribe(partner_ids=request.request_owner_id.partner_id.ids) return created_requests + def _check_conditions_promotion(self,vals): + if vals.get('has_promotion'): + promotion_lines = vals.get('promotion_line_ids', []) + approval_conditions_to_add = [] + if promotion_lines: + for promotion_line in promotion_lines: + promotion_line_record = self.env['approval.promotion.line'].browse(promotion_line) + if promotion_line_record and promotion_line_record.promote_id: + + return + return @api.ondelete(at_uninstall=False) def unlink_attachments(self): attachment_ids = self.env['ir.attachment'].search([ @@ -121,6 +134,7 @@ class ApprovalRequest(models.Model): def unlink(self): self.filtered(lambda a: a.has_product).product_line_ids.unlink() + self.filtered(lambda a: a.has_promotion).promotion_line_ids.unlink() return super().unlink() def action_get_attachment_view(self): diff --git a/extra-addons/approvals/security/ir.model.access.csv b/extra-addons/approvals/security/ir.model.access.csv index aea42a037..dec603991 100644 --- a/extra-addons/approvals/security/ir.model.access.csv +++ b/extra-addons/approvals/security/ir.model.access.csv @@ -6,6 +6,7 @@ access_approval_category,access_approval_category,model_approval_category,base.g access_approval_category_user,access_approval_category,model_approval_category,group_approval_user,1,0,0,0 access_approval_category_manager,access_approval_category,model_approval_category,group_approval_manager,1,1,1,1 access_approval_category_approver,access_approval_category_approver,model_approval_category_approver,base.group_user,1,0,0,0 +access_approval_category_condition,access_approval_category_condition,model_approval_category_condition,base.group_user,1,1,1,1 access_approval_category_approver_user,access_approval_category_approver,model_approval_category_approver,group_approval_user,1,0,0,0 access_approval_category_approver_manager,access_approval_category_approver,model_approval_category_approver,group_approval_manager,1,1,1,1 access_approval_approver,access_approval_approver,model_approval_approver,base.group_user,1,1,1,1 @@ -13,5 +14,8 @@ access_approval_approver_user,access_approval_approver,model_approval_approver,g access_approval_approver_manager,access_approval_approver,model_approval_approver,group_approval_manager,1,1,1,1 access_approval_product_line_user,access_approval_product_line,model_approval_product_line,base.group_user,1,1,1,1 access_approval_product_line_manager,access_approval_product_line,model_approval_product_line,group_approval_manager,1,1,1,1 -access_approval_condition,access_approval_condition,model_approval_condition,base.group_user,1,1,1,1 +access_approval_promotion_line_user,access_approval_promotion_line,model_approval_promotion_line,base.group_user,1,1,1,1 +access_approval_promotion_line,access_approval_promotion_line,model_approval_promotion_line,base.group_user,1,1,1,1 +access_approval_promotion_line_user,access_approval_promotion_line,model_approval_promotion_line,base.group_user,1,1,1,1 +access_approval_promotion_line_manager,access_approval_promotion_line,model_approval_promotion_line,group_approval_manager,1,1,1,1 diff --git a/extra-addons/approvals/static/src/views/kanban/approvals_category_kanban.scss b/extra-addons/approvals/static/src/views/kanban/approvals_category_kanban.scss index 0be126336..e66859daf 100644 --- a/extra-addons/approvals/static/src/views/kanban/approvals_category_kanban.scss +++ b/extra-addons/approvals/static/src/views/kanban/approvals_category_kanban.scss @@ -1,52 +1,52 @@ -.o_approvals_category_actions_field, -.o_approvals_category_kanban_view { - .o_kanban_ungrouped { - padding: 0; +// .o_approvals_category_actions_field, +// .o_approvals_category_kanban_view { +// .o_kanban_ungrouped { +// padding: 0; - .o_kanban_record { - width: 30%; - margin: 0; +// .o_kanban_record { +// width: 30%; +// margin: 0; - &.o_kanban_ghost { - display: none; - } - } - } -} +// &.o_kanban_ghost { +// display: none; +// } +// } +// } +// } -.o_approvals_category_actions_field .o_kanban_ghost { - display: none; -} +// .o_approvals_category_actions_field .o_kanban_ghost { +// display: none; +// } -.o_approvals_category_kanban_view { - .o_kanban_grouped .row { - flex-direction: column !important; - gap: 0.5rem !important; +// .o_approvals_category_kanban_view { +// .o_kanban_grouped .row { +// flex-direction: column !important; +// gap: 0.5rem !important; - > * { - width: 100% !important; +// > * { +// width: 100% !important; - > * { - margin: 0 0.5rem !important; - } - } - } +// > * { +// margin: 0 0.5rem !important; +// } +// } +// } - .o_kanban_ungrouped .o_kanban_record .oe_kanban_global_click { - border-top: 0; - display: flex; - align-items: center; +// .o_kanban_ungrouped .o_kanban_record .oe_kanban_global_click { +// border-top: 0; +// display: flex; +// align-items: center; - .o_widget_web_ribbon { - align-self: flex-start; - } - } -} -.o_form_view .o_group .o_field_widget, .o_form_view .o_inner_group .o_field_widget { - width: 50%; -} -.o_approvals_category_error { - pre { - max-height: 25vh !important; - } -} +// .o_widget_web_ribbon { +// align-self: flex-start; +// } +// } +// } +// .o_form_view .o_group .o_field_widget, .o_form_view .o_inner_group .o_field_widget { +// width: 50%; +// } +// .o_approvals_category_error { +// pre { +// max-height: 25vh !important; +// } +// } diff --git a/extra-addons/approvals/views/approval_category_approver_views.xml b/extra-addons/approvals/views/approval_category_approver_views.xml index 9b17afa54..f1816c7b1 100644 --- a/extra-addons/approvals/views/approval_category_approver_views.xml +++ b/extra-addons/approvals/views/approval_category_approver_views.xml @@ -10,6 +10,7 @@ + diff --git a/extra-addons/approvals/views/approval_category_views.xml b/extra-addons/approvals/views/approval_category_views.xml index e5a2159f5..69cafa244 100644 --- a/extra-addons/approvals/views/approval_category_views.xml +++ b/extra-addons/approvals/views/approval_category_views.xml @@ -70,60 +70,47 @@ + - - - - + - - - - - - - - - -