401 lines
23 KiB
XML
401 lines
23 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
|
|
<!--Request-->
|
|
|
|
<record id="approval_request_action" model="ir.actions.act_window">
|
|
<field name="name">My Requests</field>
|
|
<field name="res_model">approval.request</field>
|
|
<field name="view_mode">kanban,list,form</field>
|
|
<field name="domain">[('request_owner_id','=',uid)]</field>
|
|
<field name="help" type="html">
|
|
<p class="o_view_nocontent_smiling_face">
|
|
No Approvals Requests
|
|
</p>
|
|
<p>
|
|
Let's go to the <a type="action" class="text-primary" name="%(approvals.approval_category_action_new_request)d">new request</a> menu
|
|
</p>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="approval_request_action_to_review" model="ir.actions.act_window">
|
|
<field name="name">Approvals to Review</field>
|
|
<field name="res_model">approval.request</field>
|
|
<field name="view_mode">list,form,kanban</field>
|
|
<field name="domain">['&',('approver_ids.user_id','=',uid),('request_status','=','pending')]</field>
|
|
<field name="help" type="html">
|
|
<p class="o_view_nocontent_smiling_face">
|
|
No new approvals to review
|
|
</p>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="approval_request_action_all" model="ir.actions.act_window">
|
|
<field name="name">All Approvals</field>
|
|
<field name="res_model">approval.request</field>
|
|
<field name="view_mode">list,form,kanban</field>
|
|
<field name="help" type="html">
|
|
<p class="o_view_nocontent_smiling_face">
|
|
No Approvals
|
|
</p>
|
|
<p>
|
|
Let's go to the <a type="action" class="text-primary" name="%(approvals.approval_category_action_new_request)d">new request</a> menu
|
|
</p>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="approval_request_view_tree" model="ir.ui.view">
|
|
<field name="name">approval.request.view.list</field>
|
|
<field name="model">approval.request</field>
|
|
<field name="priority">10</field>
|
|
<field name="arch" type="xml">
|
|
<list sample="1" decoration-info="request_status == 'new'">
|
|
<field name="name"/>
|
|
<field name="request_owner_id" widget="many2one_avatar_user"/>
|
|
<field name="category_id"/>
|
|
<field name="date_start" string="Request Start" optional="show"/>
|
|
<field name="date_end" string="Request To" optional="show"/>
|
|
<field name="date_confirmed" string="Confirm Date" optional="hide"/>
|
|
<field name="location" string="Location" optional="hide"/>
|
|
<field name="activity_ids" widget="list_activity" optional="hide"/>
|
|
<field name="user_ids" string="Approvers" widget="many2many_avatar_user" optional="hide"/>
|
|
<field name="request_status" decoration-info="request_status == 'new'" decoration-warning="request_status == 'pending'" decoration-success="request_status == 'approved'" decoration-danger="request_status == 'refused'" widget="badge"/>
|
|
<field name="approval_properties"/>
|
|
<field name="company_id" readonly="True" optional="hide" groups="base.group_multi_company"/>
|
|
</list>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="approval_search_view_search" model="ir.ui.view">
|
|
<field name="name">approval.request.search</field>
|
|
<field name="model">approval.request</field>
|
|
<field name="priority">20</field>
|
|
<field name="arch" type="xml">
|
|
<search>
|
|
<field name="name"/>
|
|
<filter string="My Request" name="filter_my_request" domain="[('request_owner_id', '=', uid)]"/>
|
|
<filter string="My Approvals to Review" name="filter_approvals_to_review"
|
|
domain="[('approver_ids.user_id', '=', uid), ('request_status', '=', 'pending')]"/>
|
|
<separator/>
|
|
<filter string="Approved" name="filter_approved_requests" domain="[('request_status', '=', 'approved')]"/>
|
|
<filter string="Refused" name="filter_refused_requests" domain="[('request_status', '=', 'refused')]"/>
|
|
<separator/>
|
|
<filter string="Canceled" name="filter_canceled_requests" domain="[('request_status', '=', 'cancel')]"/>
|
|
<separator/>
|
|
<filter string="Archived" name="filter_archived_requests" domain="[('active', '=', False)]"/>
|
|
<filter invisible="1" string="Late Activities" name="activities_overdue"
|
|
domain="[('my_activity_date_deadline', '<', 'today')]"/>
|
|
<filter invisible="1" string="Today Activities" name="activities_today"
|
|
domain="[('my_activity_date_deadline', '=', 'today')]"/>
|
|
<filter invisible="1" string="Future Activities" name="activities_upcoming_all"
|
|
domain="[('my_activity_date_deadline', '>', 'today')]"/>
|
|
<group>
|
|
<filter string="Request Owner" name="groupby_request_owner"
|
|
context="{'group_by': 'request_owner_id'}"/>
|
|
<filter string="Category" name="groupby_category_id"
|
|
context="{'group_by': 'category_id'}"/>
|
|
<filter string="Request Status" name="groupby_request_status"
|
|
context="{'group_by': 'request_status'}"/>
|
|
</group>
|
|
</search>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="approval_request_view_form" model="ir.ui.view">
|
|
<field name="name">approval.request.view.form</field>
|
|
<field name="model">approval.request</field>
|
|
<field name="priority">10</field>
|
|
<field name="arch" type="xml">
|
|
<form string="Request">
|
|
<header>
|
|
<field name="user_status" invisible="1"/>
|
|
<field name="has_access_to_request" invisible="1"/>
|
|
<widget name="attach_document" string="Attach Document" action="message_post" highlight="1" invisible="(attachment_number >= 1 and request_owner_id == uid) or request_owner_id != uid"/>
|
|
<button name="action_confirm" string="Submit" type="object" invisible="attachment_number < 1 or not approver_ids or request_status != 'new'" class="btn-primary" data-hotkey="q"/>
|
|
<button name="action_confirm" string="Submit" type="object" invisible="attachment_number >= 1 or not approver_ids or request_status != 'new'" data-hotkey="q"/>
|
|
<button name="action_approve" string="Approve" type="object" invisible="(attachment_number < 1 and request_owner_id == uid) or request_status in ['approved', 'refused', 'cancel'] or user_status != 'pending'" class="btn-primary" data-hotkey="v"/>
|
|
<button name="action_approve" string="Approve" type="object" invisible="attachment_number >= 1 or request_owner_id != uid or request_status in ['approved', 'refused', 'cancel'] or user_status != 'pending'" class="btn-primary" data-hotkey="v"/>
|
|
<button name="action_refuse" string="Refuse" type="object" invisible="request_status in ['approved', 'refused', 'cancel'] or user_status != 'pending'" data-hotkey="z"/>
|
|
<button name="action_withdraw" string="Withdraw" type="object" invisible="request_status == 'new' or user_status in ['waiting', 'pending', 'cancel'] or not user_status" data-hotkey="y"/>
|
|
<button name="action_draft" string="Back To Draft" type="object" invisible="request_status != 'cancel' or not user_status and not has_access_to_request" data-hotkey="w"/>
|
|
<button name="action_cancel" string="Cancel" type="object" invisible="request_status in ['new', 'cancel'] or request_owner_id != uid" data-hotkey="x"/>
|
|
<widget name="attach_document" string="Attach Document" action="message_post" invisible="(attachment_number < 1 and request_owner_id == uid)"/>
|
|
<button string="Print" invisible="request_status != 'approved' or approval_type !='purchase'" type="action" name="%(action_report_approval_request)d"/>
|
|
<field name="request_status" widget="statusbar" statusbar_visible="new,pending,approved,refused" />
|
|
</header>
|
|
<sheet>
|
|
<field name="active" invisible="1"/>
|
|
<field name="has_date" invisible="1"/>
|
|
<field name="has_period" invisible="1"/>
|
|
<field name="has_quantity" invisible="1"/>
|
|
<field name="has_amount" invisible="1"/>
|
|
<field name="has_reference" invisible="1"/>
|
|
<field name="has_partner" invisible="1"/>
|
|
<field name="has_payment_method" invisible="1"/>
|
|
<field name="has_location" invisible="1"/>
|
|
<field name="has_product" invisible="1"/>
|
|
<field name="requirer_document" invisible="1"/>
|
|
<field name="approval_minimum" invisible="1"/>
|
|
<field name="approval_type" invisible="1"/>
|
|
<field name="change_request_owner" invisible="1"/>
|
|
<div class="o_not_full oe_button_box" name="button_box">
|
|
<button name="action_get_attachment_view"
|
|
class="oe_stat_button"
|
|
icon="fa-book"
|
|
type="object"
|
|
invisible="attachment_number == 0">
|
|
<field name="attachment_number" widget="statinfo" string="Documents" options="{'reload_on_button': true}"/>
|
|
</button>
|
|
</div>
|
|
<div class="oe_avatar">
|
|
<field name="category_image" widget="image" options="{'preview_image': 'category_image', 'size': [80, 80]}" class="bg-view" />
|
|
</div>
|
|
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
|
|
<div class="oe_title">
|
|
<label for="name"/>
|
|
<h1>
|
|
<field name="automated_sequence" invisible="1"/>
|
|
<field name="name" placeholder="E.g: Expenses Paris business trip"
|
|
required="not automated_sequence"
|
|
readonly="automated_sequence"/>
|
|
</h1>
|
|
</div>
|
|
<group>
|
|
<group name="request_main">
|
|
<field name="request_owner_id" readonly="not change_request_owner or request_status != 'new'" widget="many2one_avatar_user"/>
|
|
<field name="category_id" readonly="request_status != 'new'" force_save="1"/>
|
|
<field name="date_confirmed" groups="base.group_no_one" readonly="1"/>
|
|
<label for="date" string="Date" invisible="has_date == 'no'"/>
|
|
<div invisible="has_date == 'no'">
|
|
<div>
|
|
<field name="date" class="oe_inline" readonly="request_status != 'new'" required="has_date == 'required'"/>
|
|
</div>
|
|
</div>
|
|
<label for="date_start" string="Period" invisible="has_period == 'no'"/>
|
|
<div invisible="has_period == 'no'">
|
|
<div>
|
|
<label for="date_start" class="col-lg-2" string="From:"/>
|
|
<field name="date_start" class="oe_inline" readonly="request_status != 'new'" required="has_period == 'required'"/>
|
|
</div>
|
|
<div>
|
|
<label for="date_end" class="col-lg-2" string="to:"/>
|
|
<field name="date_end" class="oe_inline" readonly="request_status != 'new'" required="has_period == 'required'"/>
|
|
</div>
|
|
</div>
|
|
<field name="location" invisible="has_location == 'no'" readonly="request_status != 'new'" required="has_location == 'required'" placeholder="e.g. Brussels" />
|
|
<field name="partner_id" invisible="has_partner == 'no'" readonly="request_status != 'new'" required="has_partner == 'required'" context="{'category_id': ''}"/>
|
|
<field name="company_id" groups="base.group_multi_company"/>
|
|
</group>
|
|
<group name="request_details">
|
|
<field name="quantity" invisible="has_quantity == 'no' or has_product != 'no'" readonly="request_status != 'new'" required="has_quantity == 'required' and has_product == 'no'"/>
|
|
<field name="amount" invisible="has_amount == 'no'" readonly="request_status != 'new'" required="has_amount == 'required'"/>
|
|
<field name="reference" invisible="has_reference == 'no'" required="has_reference == 'required'"/>
|
|
<field name="company_id" invisible="1"/>
|
|
</group>
|
|
<field name="approval_properties" columns="2"/>
|
|
</group>
|
|
<notebook>
|
|
<page string="Products" name="products"
|
|
invisible="has_product == 'no'">
|
|
<field name="product_line_ids"
|
|
context="{'list_view_ref': 'approvals.approval_product_line_view_tree', 'kanban_view_ref': 'approvals.approval_product_kanban_mobile_view'}"
|
|
readonly="request_status != 'new'"/>
|
|
</page>
|
|
<page string="Description" name="description">
|
|
<field name="reason" readonly="request_status != 'new'"/>
|
|
</page>
|
|
<page string="Approver(s)" name="approvers">
|
|
<field name="approver_ids" mode="list,kanban" readonly="request_status != 'new' or change_request_owner == False">
|
|
<list editable="bottom" decoration-success="status=='approved'" decoration-warning="status in ['pending', 'waiting']" decoration-danger="status=='refused'" no_open="1">
|
|
<field name="existing_request_user_ids" column_invisible="True"/>
|
|
<field name="sequence" column_invisible="True"/>
|
|
<field name="can_edit" column_invisible="True"/>
|
|
<field name="can_edit_user_id" column_invisible="True"/>
|
|
<field name="user_id" string="Approver" widget="many2one_avatar_user" readonly="not can_edit_user_id or status != 'new'" force_save="1" />
|
|
<field name="required" readonly="not can_edit" force_save="1"/>
|
|
<field name="status"/>
|
|
<field name="company_id" column_invisible="True"/>
|
|
</list>
|
|
<kanban class="o_kanban_mobile">
|
|
<templates>
|
|
<t t-name="card" class="flex-row">
|
|
<field name="user_id"/>
|
|
<t t-if="record.status.raw_value">
|
|
<t t-set="classname" t-value="{'approved': 'text-bg-success', 'pending': 'text-bg-warning', 'refused': 'text-bg-danger'}[record.status.raw_value] || 'text-bg-light'"/>
|
|
<span t-attf-class="ms-auto rounded-pill {{ classname }}">
|
|
<field name="status"/>
|
|
</span>
|
|
</t>
|
|
</t>
|
|
</templates>
|
|
</kanban>
|
|
<form>
|
|
<group>
|
|
<field name="company_id" invisible="1"/>
|
|
<field name="existing_request_user_ids" invisible="1"/>
|
|
<field name="user_id"/>
|
|
</group>
|
|
</form>
|
|
</field>
|
|
</page>
|
|
</notebook>
|
|
</sheet>
|
|
<div class="o_attachment_preview"/>
|
|
<chatter/>
|
|
</form>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="approval_request_view_kanban" model="ir.ui.view">
|
|
<field name="name">approval.request.view.kanban</field>
|
|
<field name="model">approval.request</field>
|
|
<field name="arch" type="xml">
|
|
<kanban create="false" class="o_modules_kanban" default_group_by="request_status" default_order="create_date desc"
|
|
group_create="false" group_edit="false" group_delete="false" sample="1">
|
|
<field name="request_status"/>
|
|
<field name="user_status"/>
|
|
<field name="date_start"/>
|
|
<field name="date_end"/>
|
|
<templates>
|
|
<t t-name="card">
|
|
<div class="row g-2">
|
|
<div class="col-auto">
|
|
<field name="category_image" widget="image" options="{'preview_image': 'category_image', 'size': [64, 64]}"/>
|
|
</div>
|
|
<div class="col">
|
|
<field name="request_status"
|
|
widget="badge"
|
|
class="float-end"
|
|
decoration-info="request_status == 'new'"
|
|
decoration-warning="request_status == 'pending'"
|
|
decoration-success="request_status == 'approved'"
|
|
decoration-danger="request_status == 'refused'"/>
|
|
<field name="name" class="fw-bolder fs-3 pe-5 d-block text-wrap"/>
|
|
<field name="request_owner_id" widget="many2one_avatar_user" options="{'display_avatar_name': True}" class="o_approval_kanban_avatar fw-bold my-1"/>
|
|
<div class="text-muted">
|
|
<t t-if="record.date_start.raw_value" t-out="luxon.DateTime.fromISO(record.date_start.raw_value).toLocaleString({ month: 'short', day: 'numeric', year: 'numeric'})"/>
|
|
<t t-if="record.date_end.raw_value and record.date_start.raw_value != record.date_end.raw_value">
|
|
<span class="mx-1">-</span>
|
|
<t t-out="luxon.DateTime.fromISO(record.date_end.raw_value).toLocaleString({ month: 'short', day: 'numeric', year: 'numeric'})"/>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<footer class="o_kanban_footer">
|
|
<div class="d-flex align-items-center w-100">
|
|
<div class="d-flex gap-2 ms-auto">
|
|
<button t-if="record.user_status.raw_value == 'pending'" name="action_approve" type="object" class="btn btn-sm py-0">
|
|
<i class="fa fa-check text-success me-1"/>Approve
|
|
</button>
|
|
<button t-if="record.user_status.raw_value == 'pending'" name="action_refuse" type="object" class="btn btn-sm py-0">
|
|
<i class="fa fa-times text-danger me-1"/>Refuse
|
|
</button>
|
|
</div>
|
|
<field name="activity_ids" widget="kanban_activity"/>
|
|
</div>
|
|
</footer>
|
|
</t>
|
|
</templates>
|
|
</kanban>
|
|
</field>
|
|
</record>
|
|
|
|
<record id="model_approval_request_approve_admin" model="ir.actions.server">
|
|
<field name="name">Force Approval</field>
|
|
<field name="model_id" ref="approvals.model_approval_request"/>
|
|
<field name="binding_model_id" ref="approvals.model_approval_request"/>
|
|
<field name="group_ids" eval="[(4, ref('approvals.group_approval_user'))]"/>
|
|
<field name="binding_view_types">form,list</field>
|
|
<field name="state">code</field>
|
|
<field name="code">
|
|
if records:
|
|
records._action_force_approval()
|
|
</field>
|
|
</record>
|
|
|
|
<!--MenuItem-->
|
|
|
|
<menuitem
|
|
id="approvals_menu_root"
|
|
name="Approvals"
|
|
web_icon="approvals,static/description/icon.png"
|
|
action="approval_category_action_new_request"
|
|
sequence="255"/>
|
|
|
|
<menuitem
|
|
id="approvals_category_menu_new"
|
|
parent="approvals_menu_root"
|
|
name="Dashboard"
|
|
action="approval_category_action_new_request"
|
|
sequence="1"/>
|
|
|
|
<menuitem
|
|
id="approvals_approval_menu"
|
|
parent="approvals_menu_root"
|
|
name="My Approvals"
|
|
sequence="10"/>
|
|
|
|
<menuitem
|
|
id="approvals_request_menu_my"
|
|
parent="approvals_approval_menu"
|
|
name="My Requests"
|
|
action="approval_request_action"
|
|
sequence="20"/>
|
|
|
|
<menuitem
|
|
id="approvals_menu_manager"
|
|
parent="approvals_menu_root"
|
|
name="Manager"
|
|
sequence="20"/>
|
|
|
|
<menuitem
|
|
id="approvals_approval_menu_to_review"
|
|
parent="approvals_menu_manager"
|
|
name="Approvals to Review"
|
|
action="approval_request_action_to_review"
|
|
sequence="10"/>
|
|
|
|
<menuitem
|
|
id="approvals_approval_menu_all"
|
|
parent="approvals_menu_manager"
|
|
name="All Approvals"
|
|
action="approval_request_action_all"
|
|
sequence="20"/>
|
|
|
|
<menuitem
|
|
id="approvals_menu_config"
|
|
parent="approvals_menu_root"
|
|
name="Configuration"
|
|
groups="group_approval_manager"
|
|
sequence="40"/>
|
|
|
|
<menuitem
|
|
id="approvals_category_menu_config"
|
|
parent="approvals_menu_config"
|
|
name="Approval Categories"
|
|
action="approval_category_action"
|
|
groups="group_approval_manager"
|
|
sequence="10"/>
|
|
|
|
<menuitem
|
|
id="approvals_menu_product"
|
|
parent="approvals_menu_config"
|
|
name="Products"
|
|
sequence="30"/>
|
|
|
|
<menuitem
|
|
id="approvals_menu_product_template"
|
|
parent="approvals_menu_product"
|
|
name="Products"
|
|
action="product_template_action"
|
|
sequence="10"/>
|
|
|
|
<menuitem
|
|
id="approvals_menu_product_variant"
|
|
parent="approvals_menu_product"
|
|
name="Product Variants"
|
|
action="product_product_action"
|
|
groups="product.group_product_variant"
|
|
sequence="20"/>
|
|
</odoo>
|