[MERGE] hr_expense: onboarding
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
{
|
||||
'name': 'Expense Tracker',
|
||||
'name': 'Expenses',
|
||||
'version': '2.0',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 95,
|
||||
|
||||
@@ -52,6 +52,12 @@
|
||||
<field name="description">Expense report paid</field>
|
||||
<field name="default" eval="False"/>
|
||||
</record>
|
||||
<record id="mt_expense_responsible" model="mail.message.subtype">
|
||||
<field name="name">Responsible</field>
|
||||
<field name="res_model">hr.expense.sheet</field>
|
||||
<field name="description">Changes of responsible</field>
|
||||
<field name="default" eval="True"/>
|
||||
</record>
|
||||
<!-- Department (Parent) related subtypes for messaging / Chatter -->
|
||||
<record id="mt_department_expense_confirmed" model="mail.message.subtype">
|
||||
<field name="name">Expenses To Approve</field>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import hr_employee
|
||||
from . import account_move_line
|
||||
from . import hr_department
|
||||
from . import hr_expense
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
class Employee(models.Model):
|
||||
_inherit = 'hr.employee'
|
||||
|
||||
expense_manager_id = fields.Many2one(
|
||||
'res.users', string='Expense Responsible',
|
||||
domain=lambda self: [('groups_id', 'in', self.env.ref('hr_expense.group_hr_expense_manager').id)],
|
||||
help="User responsible of expense approval. Should be Expense Manager.")
|
||||
@@ -29,13 +29,13 @@ class HrExpense(models.Model):
|
||||
def _default_account_id(self):
|
||||
return self.env['ir.property'].get('property_account_expense_categ_id', 'product.category')
|
||||
|
||||
name = fields.Char("Expense Description", readonly=True, required=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]})
|
||||
date = fields.Date("Expense Date", readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=fields.Date.context_today)
|
||||
employee_id = fields.Many2one('hr.employee', string="Employee", required=True, readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=_default_employee_id)
|
||||
product_id = fields.Many2one('product.product', string='Product', readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, domain=[('can_be_expensed', '=', True)], required=True)
|
||||
name = fields.Char('Description', readonly=True, required=True, states={'draft': [('readonly', False)], 'reported': [('readonly', False)], 'refused': [('readonly', False)]})
|
||||
date = fields.Date(readonly=True, states={'draft': [('readonly', False)], 'reported': [('readonly', False)], 'refused': [('readonly', False)]}, default=fields.Date.context_today, string="Date")
|
||||
employee_id = fields.Many2one('hr.employee', string="Employee", required=True, readonly=True, states={'draft': [('readonly', False)], 'reported': [('readonly', False)], 'refused': [('readonly', False)]}, default=_default_employee_id)
|
||||
product_id = fields.Many2one('product.product', string='Product', readonly=True, states={'draft': [('readonly', False)], 'reported': [('readonly', False)], 'refused': [('readonly', False)]}, domain=[('can_be_expensed', '=', True)], required=True)
|
||||
product_uom_id = fields.Many2one('product.uom', string='Unit of Measure', required=True, readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, default=_default_product_uom_id)
|
||||
unit_amount = fields.Float("Unit Price", readonly=True, required=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, digits=dp.get_precision('Product Price'))
|
||||
quantity = fields.Float(required=True, readonly=True, states={'draft': [('readonly', False)], 'refused': [('readonly', False)]}, digits=dp.get_precision('Product Unit of Measure'), default=1)
|
||||
unit_amount = fields.Float("Unit Price", readonly=True, required=True, states={'draft': [('readonly', False)], 'reported': [('readonly', False)], 'refused': [('readonly', False)]}, digits=dp.get_precision('Product Price'))
|
||||
quantity = fields.Float(required=True, readonly=True, states={'draft': [('readonly', False)], 'reported': [('readonly', False)], 'refused': [('readonly', False)]}, digits=dp.get_precision('Product Unit of Measure'), default=1)
|
||||
tax_ids = fields.Many2many('account.tax', 'expense_tax', 'expense_id', 'tax_id', string='Taxes', states={'done': [('readonly', True)], 'post': [('readonly', True)]})
|
||||
untaxed_amount = fields.Float("Subtotal", store=True, compute='_compute_amount', digits=dp.get_precision('Account'))
|
||||
total_amount = fields.Monetary("Total", compute='_compute_amount', store=True, currency_field='currency_id', digits=dp.get_precision('Account'))
|
||||
@@ -45,16 +45,17 @@ class HrExpense(models.Model):
|
||||
company_currency_id = fields.Many2one('res.currency', string="Report Company Currency", related='sheet_id.currency_id', store=True)
|
||||
analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account', states={'post': [('readonly', True)], 'done': [('readonly', True)]}, oldname='analytic_account')
|
||||
account_id = fields.Many2one('account.account', string='Account', states={'post': [('readonly', True)], 'done': [('readonly', True)]}, default=_default_account_id, help="An expense account is expected")
|
||||
description = fields.Text()
|
||||
description = fields.Text('Notes...', readonly=True, states={'draft': [('readonly', False)], 'reported': [('readonly', False)], 'refused': [('readonly', False)]})
|
||||
payment_mode = fields.Selection([
|
||||
("own_account", "Employee (to reimburse)"),
|
||||
("company_account", "Company")
|
||||
], default='own_account', states={'done': [('readonly', True)], 'post': [('readonly', True)], 'submitted': [('readonly', True)]}, string="Payment By")
|
||||
attachment_number = fields.Integer("Number of Attachments", compute='_compute_attachment_number')
|
||||
], default='own_account', states={'done': [('readonly', True)], 'post': [('readonly', True)], 'submitted': [('readonly', True)]}, string="Paid By")
|
||||
attachment_number = fields.Integer('Number of Attachments', compute='_compute_attachment_number')
|
||||
state = fields.Selection([
|
||||
('draft', 'To Submit'),
|
||||
('reported', 'Reported'),
|
||||
('done', 'Posted'),
|
||||
('reported', 'Submitted'),
|
||||
('approved', 'Approved'),
|
||||
('done', 'Paid'),
|
||||
('refused', 'Refused')
|
||||
], compute='_compute_state', string='Status', copy=False, index=True, readonly=True, store=True, help="Status of the expense.")
|
||||
sheet_id = fields.Many2one('hr.expense.sheet', string="Expense Report", readonly=True, copy=False)
|
||||
@@ -68,6 +69,8 @@ class HrExpense(models.Model):
|
||||
expense.state = "draft"
|
||||
elif expense.sheet_id.state == "cancel":
|
||||
expense.state = "refused"
|
||||
elif expense.sheet_id.state == "approve" or expense.sheet_id.state == "post":
|
||||
expense.state = "approved"
|
||||
elif not expense.sheet_id.account_move_id:
|
||||
expense.state = "reported"
|
||||
else:
|
||||
@@ -120,8 +123,8 @@ class HrExpense(models.Model):
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
for expense in self:
|
||||
if expense.state in ['done']:
|
||||
raise UserError(_('You cannot delete a posted expense.'))
|
||||
if expense.state in ['done', 'approved']:
|
||||
raise UserError(_('You cannot delete a posted or approved expense.'))
|
||||
return super(HrExpense, self).unlink()
|
||||
|
||||
@api.model
|
||||
@@ -161,6 +164,7 @@ class HrExpense(models.Model):
|
||||
if len(self.mapped('employee_id')) != 1:
|
||||
raise UserError(_("You cannot report expenses for different employees in the same report!"))
|
||||
return {
|
||||
'name': _('New Expense Report'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'hr.expense.sheet',
|
||||
@@ -470,8 +474,8 @@ class HrExpenseSheet(models.Model):
|
||||
], string='Status', index=True, readonly=True, track_visibility='onchange', copy=False, default='submit', required=True, help='Expense Report State')
|
||||
employee_id = fields.Many2one('hr.employee', string="Employee", required=True, readonly=True, states={'submit': [('readonly', False)]}, default=lambda self: self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1))
|
||||
address_id = fields.Many2one('res.partner', string="Employee Home Address")
|
||||
payment_mode = fields.Selection([("own_account", "Employee (to reimburse)"), ("company_account", "Company")], related='expense_line_ids.payment_mode', default='own_account', readonly=True, string="Payment By")
|
||||
responsible_id = fields.Many2one('res.users', 'Validation By', readonly=True, copy=False, states={'submit': [('readonly', False)]})
|
||||
payment_mode = fields.Selection([("own_account", "Employee (to reimburse)"), ("company_account", "Company")], related='expense_line_ids.payment_mode', default='own_account', readonly=True, string="Paid By")
|
||||
user_id = fields.Many2one('res.users', 'Manager', readonly=True, copy=False, states={'submit': [('readonly', False)]}, track_visibility='onchange', oldname='responsible_id')
|
||||
total_amount = fields.Monetary('Total Amount', currency_field='currency_id', compute='_compute_amount', store=True, digits=dp.get_precision('Account'))
|
||||
company_id = fields.Many2one('res.company', string='Company', readonly=True, states={'submit': [('readonly', False)]}, default=lambda self: self.env.user.company_id)
|
||||
currency_id = fields.Many2one('res.currency', string='Currency', readonly=True, states={'submit': [('readonly', False)]}, default=lambda self: self.env.user.company_id.currency_id)
|
||||
@@ -502,6 +506,7 @@ class HrExpenseSheet(models.Model):
|
||||
def _onchange_employee_id(self):
|
||||
self.address_id = self.employee_id.address_home_id
|
||||
self.department_id = self.employee_id.department_id
|
||||
self.user_id = self.employee_id.expense_manager_id
|
||||
|
||||
@api.multi
|
||||
@api.constrains('expense_line_ids')
|
||||
@@ -553,6 +558,8 @@ class HrExpenseSheet(models.Model):
|
||||
return 'hr_expense.mt_expense_refused'
|
||||
elif 'state' in init_values and self.state == 'done':
|
||||
return 'hr_expense.mt_expense_paid'
|
||||
elif 'user_id' in init_values:
|
||||
return 'hr_expense.mt_expense_responsible'
|
||||
return super(HrExpenseSheet, self)._track_subtype(init_values)
|
||||
|
||||
def _get_users_to_subscribe(self, employee=False):
|
||||
@@ -583,6 +590,10 @@ class HrExpenseSheet(models.Model):
|
||||
MailFollowers = self.env['mail.followers']
|
||||
for partner in users.mapped('partner_id'):
|
||||
values['message_follower_ids'] += MailFollowers._add_follower_command(self._name, [], {partner.id: None}, {})[0]
|
||||
|
||||
if values.get('user_id') and values.get('user_id') != employee.user_id.id:
|
||||
resp_partner = self.env['res.users'].browse(values['user_id'])
|
||||
values['message_follower_ids'] += MailFollowers._add_follower_command(self._name, [], {resp_partner.partner_id.id: None}, {})[0]
|
||||
|
||||
# --------------------------------------------
|
||||
# Actions
|
||||
@@ -633,7 +644,8 @@ class HrExpenseSheet(models.Model):
|
||||
def approve_expense_sheets(self):
|
||||
if not self.user_has_groups('hr_expense.group_hr_expense_user'):
|
||||
raise UserError(_("Only HR Officers can approve expenses"))
|
||||
self.write({'state': 'approve', 'responsible_id': self.env.user.id})
|
||||
responsible_id = self.user_id.id or self.env.user.id
|
||||
self.write({'state': 'approve', 'user_id': responsible_id})
|
||||
|
||||
@api.multi
|
||||
def paid_expense_sheets(self):
|
||||
|
||||
@@ -9,7 +9,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
expense_alias_prefix = fields.Char('Default Alias Name for Expenses')
|
||||
use_mailgateway = fields.Boolean(string='Let your employees record expenses by email',
|
||||
config_parameter='hr_expense.use_mailgateway')
|
||||
module_sale_management = fields.Boolean(string="Customer Billing")
|
||||
module_sale_expense = fields.Boolean(string="Customer Billing")
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
<div class="col-xs-2">
|
||||
<strong>Validated By:</strong>
|
||||
<p t-field="o.responsible_id"/>
|
||||
<p t-field="o.user_id"/>
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
<strong>Payment By:</strong>
|
||||
|
||||
@@ -13,22 +13,17 @@ tour.register('hr_expense_tour' ,
|
||||
[tour.STEPS.MENU_MORE,
|
||||
{
|
||||
trigger: '.o_app[data-menu-xmlid="hr_expense.menu_hr_expense_root"], .oe_menu_toggler[data-menu-xmlid="hr_expense.menu_hr_expense_root"]',
|
||||
content: _t("Go to the expense to attach a receipt."),
|
||||
content: _t("Want to manage your expenses? It starts here."),
|
||||
position: 'bottom',
|
||||
}, {
|
||||
trigger: '.o_list_button_add',
|
||||
extra_trigger: ".o_expense_tree",
|
||||
content: _t('<p>Click here to create your first expense and add it under here.</p>'),
|
||||
content: _t('<p>Let’s start by creating your first expense.</p>'),
|
||||
position: 'bottom'
|
||||
}, {
|
||||
trigger: ".o_required_modifier input",
|
||||
extra_trigger: ".o_expense_form",
|
||||
content: _t("Write the name of the product, or select an existing one."),
|
||||
position: "top",
|
||||
}, {
|
||||
trigger: '.o_form_button_save',
|
||||
extra_trigger: ".o_expense_form",
|
||||
content: _t("<p>Once your Expense is ready, you can save it.</p>"),
|
||||
extra_trigger: ".o_expense_sheet",
|
||||
content: _t("<p>Once your <b>Expense report</b> is ready, you can save it and wait for the approval from your manager.</p>"),
|
||||
position: 'bottom',
|
||||
}, {
|
||||
trigger: '.o_expense_form .o_chatter_button_new_message',
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="hr_employee_view_form_inherit_expense" model="ir.ui.view">
|
||||
<field name="name">hr.employee.view.form.expense</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='active_group']" position="before">
|
||||
<group string="Expenses" name="timesheet">
|
||||
<field name="expense_manager_id"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_expenses_tree" model="ir.ui.view">
|
||||
<field name="name">hr.expense.tree</field>
|
||||
<field name="model">hr.expense</field>
|
||||
@@ -21,26 +34,13 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_expense_form_view" model="ir.ui.view">
|
||||
<field name="name">hr.expense.form</field>
|
||||
<record id="hr_expense_view_form_without_header" model="ir.ui.view">
|
||||
<field name="name">hr.expense.view.form</field>
|
||||
<field name="model">hr.expense</field>
|
||||
<field eval="25" name="priority"/>
|
||||
<field eval="35" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Expenses" class="o_expense_form">
|
||||
<header invisible="context.get('expense_adding_line')">
|
||||
<button name="action_submit_expenses" states="draft" string="Submit to Manager" type="object" class="oe_highlight o_expense_submit"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,reported,done"/>
|
||||
<button name="action_view_sheet" type="object" string="View Report" class="oe_highlight" attrs="{'invisible': [('state', '=','draft')]}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" invisible="context.get('expense_adding_line')">
|
||||
<button name="action_get_attachment_view"
|
||||
class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
type="object">
|
||||
<field name="attachment_number" widget="statinfo" string="Documents"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1>
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
</group>
|
||||
<div>
|
||||
<field name="description" placeholder="Notes..."/>
|
||||
<field name="description" class="oe_inline" placeholder="Notes..."/>
|
||||
</div>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
@@ -87,6 +87,33 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_expense_view_form" model="ir.ui.view">
|
||||
<field name="name">hr.expense.view.form</field>
|
||||
<field name="model">hr.expense</field>
|
||||
<field name="inherit_id" ref="hr_expense.hr_expense_view_form_without_header"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/*" position="before">
|
||||
<header>
|
||||
<button name="action_submit_expenses" states="draft" string="Submit to Manager" type="object" class="oe_highlight"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,reported,approved,done,refused"/>
|
||||
<button name="action_view_sheet" type="object" string="View Report" class="oe_highlight" attrs="{'invisible': [('state', '=','draft')]}"/>
|
||||
</header>
|
||||
</xpath>
|
||||
<xpath expr="/form/sheet/*" position="before">
|
||||
<div class="oe_button_box">
|
||||
<button name="action_get_attachment_view"
|
||||
class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
type="object"
|
||||
attrs="{'invisible': [('attachment_number', '=', 0)]}">
|
||||
<field name="attachment_number" widget="statinfo" string="Documents" options="{'reload_on_button': true}"/>
|
||||
</button>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="hr_expense_kanban_view" model="ir.ui.view">
|
||||
<field name="name">hr.expense.kanban</field>
|
||||
<field name="model">hr.expense</field>
|
||||
@@ -112,8 +139,8 @@
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<span class="pull-right text-right">
|
||||
<field name="state" widget="label_selection" options="{'classes': {'draft': 'default', 'submit': 'default', 'cancel': 'danger', 'post': 'warning',
|
||||
'done': 'success'}}"/>
|
||||
<field name="state" widget="label_selection" options="{'classes': {'draft': 'default', 'reported': 'primary', 'refused': 'danger', 'done': 'warning',
|
||||
'approved': 'success'}}"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -160,9 +187,9 @@
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<separator />
|
||||
<filter domain="[('state', '=', 'draft')]" string="To Submit" name="to_report" help="New Expense"/>
|
||||
<filter domain="[('state', '=', 'reported')]" string="Reported" name="submitted" help="Confirmed Expenses"/>
|
||||
<filter domain="[('state', '!=', 'draft')]" string="Reported" name="submitted" help="Confirmed Expenses"/>
|
||||
<filter domain="[('state', '=', 'refused')]" string="Refused" name="refused" help="Refused Expenses"/>
|
||||
<filter domain="[('state', '!=', 'cancel')]" string="Not Refused" name="uncancelled" help="Actual expense sheets, not the refused ones"/>
|
||||
<filter domain="['|', ('state', '=', 'approved'), ('state', '=', 'done')]" string="Approved" name="approved" help="Actual expense sheets, not the refused ones"/>
|
||||
<separator />
|
||||
<filter string="My Team Expenses" name="my_team_expenses" domain="[('employee_id.parent_id.user_id', '=', uid)]" groups="hr_expense.group_hr_expense_manager" help="Expenses of Your Team Member"/>
|
||||
<filter string="My Expenses" name="my_expenses" domain="[('employee_id.user_id', '=', uid)]"/>
|
||||
@@ -196,7 +223,7 @@
|
||||
</record>
|
||||
|
||||
<record id="hr_expense_actions_my_unsubmitted" model="ir.actions.act_window">
|
||||
<field name="name">My Expenses to Submit</field>
|
||||
<field name="name">My Expenses</field>
|
||||
<field name="res_model">hr.expense</field>
|
||||
<field name="view_mode">tree,kanban,form,graph,pivot</field>
|
||||
<field name="search_view_id" ref="view_hr_expense_filter"/>
|
||||
@@ -347,7 +374,7 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,pivot</field>
|
||||
<field name="context">{
|
||||
'search_default_uncancelled': 1,
|
||||
'search_default_approved': 1,
|
||||
}
|
||||
</field>
|
||||
</record>
|
||||
@@ -387,7 +414,8 @@
|
||||
<button name="action_get_attachment_view"
|
||||
class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
type="object">
|
||||
type="object"
|
||||
attrs="{'invisible': [('attachment_number', '=', 0)]}">
|
||||
<field name="attachment_number" widget="statinfo" string="Documents"/>
|
||||
</button>
|
||||
</div>
|
||||
@@ -401,15 +429,15 @@
|
||||
<group>
|
||||
<field name="employee_id"/>
|
||||
<field name="payment_mode"/>
|
||||
<field name="responsible_id" invisible="1"/>
|
||||
<field name="user_id"/>
|
||||
<field name="address_id" invisible="1"/>
|
||||
<field name="department_id" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Expense Lines">
|
||||
<field name="expense_line_ids" nolabel="1" widget="many2many" domain="[('state', '=', 'draft')]" options="{'not_delete': True, 'reload_on_button': True, 'no_create': True}" context="{'expense_adding_line': True}">
|
||||
<page string="Expense">
|
||||
<field name="expense_line_ids" nolabel="1" widget="many2many" domain="[('state', '=', 'draft')]" options="{'reload_on_button': True}" context="{'form_view_ref' : 'hr_expense.hr_expense_view_form_without_header', 'expense_adding_line': True}">
|
||||
<tree decoration-danger="is_refused">
|
||||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
@@ -418,13 +446,12 @@
|
||||
<field name="message_unread" invisible="1"/>
|
||||
<field name="attachment_number" string=" "/>
|
||||
<button name="action_get_attachment_view" string="View Attachments" type="object" icon="fa-paperclip"/>
|
||||
<field name="tax_ids" widget="many2many_tags"/>
|
||||
<field name="tax_ids" widget="many2many_tags" groups="account.group_account_user"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="total_amount"/>
|
||||
<field name="company_currency_id" invisible="1"/>
|
||||
<field name="total_amount_company" groups="base.group_multi_currency"/>
|
||||
<field name="is_refused" invisible="True"/>
|
||||
<button name="%(hr_expense.hr_expense_refuse_wizard_action)d" states="reported, refused" string="Refuse" context="{'hr_expense_refuse_model':'hr.expense'}" type="action" groups="hr_expense.group_hr_expense_user, account.group_account_user" icon="fa-times" attrs="{'invisible': ['|', ('is_refused', '=', True),('state', 'in', ['done'])]}"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
@@ -722,7 +749,7 @@
|
||||
</record>
|
||||
|
||||
<record id="hr_expense_submit_action_server" model="ir.actions.server">
|
||||
<field name="name">Expense: Submit To Manager</field>
|
||||
<field name="name">Submit To Manager</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="model_id" ref="model_hr_expense"/>
|
||||
<field name="binding_model_id" ref="model_hr_expense"/>
|
||||
@@ -752,8 +779,6 @@ if records:
|
||||
|
||||
<menuitem id="menu_hr_expense_reports" name="Reporting" sequence="4" parent="menu_hr_expense_root" groups="hr_expense.group_hr_expense_manager"/>
|
||||
<menuitem id="menu_hr_expense_all_expenses" name="Expenses Analysis" sequence="0" parent="menu_hr_expense_reports" action="hr_expense_actions_all"/>
|
||||
<menuitem id="menu_hr_expense_sheet_all_all" name="Expenses Reports Analysis" sequence="4" parent="menu_hr_expense_reports"
|
||||
action="action_hr_expense_sheet_all_all" groups="hr_expense.group_hr_expense_manager"/>
|
||||
|
||||
<menuitem id="menu_hr_expense_configuration" name="Configuration" parent="menu_hr_expense_root"
|
||||
sequence="100"/>
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" title="This installs the Sales Management app.
|
||||
Expenses can be invoiced to customers from sales orders.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_sale_management"/>
|
||||
<field name="module_sale_expense"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_sale_management"/>
|
||||
<label for="module_sale_expense"/>
|
||||
<div class="text-muted">
|
||||
Sell services and invoice expenses to customer
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<record id="hr_expense_form_view_inherit_sale_expense" model="ir.ui.view">
|
||||
<field name="name">hr.expense.form.inherit.sale.expense</field>
|
||||
<field name="model">hr.expense</field>
|
||||
<field name="inherit_id" ref="hr_expense.hr_expense_form_view"/>
|
||||
<field name="inherit_id" ref="hr_expense.hr_expense_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='employee_id']" position="after">
|
||||
<field name="sale_order_id" context="{'sale_show_partner_name': True}"/>
|
||||
|
||||
Reference in New Issue
Block a user