Project Report updated
This commit is contained in:
parent
e7cbc694f8
commit
7e7b45c85d
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import models
|
||||
from . import wizard
|
||||
from . import report
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
{
|
||||
'name': 'Project Report',
|
||||
'summary': 'Projects Report',
|
||||
'description': "",
|
||||
'version': '1.0',
|
||||
'license': 'LGPL-3',
|
||||
'category': 'Services/Project',
|
||||
'author': "SunArc Technologies",
|
||||
'website': "http://www.sunarctechnologies.com",
|
||||
'depends': [
|
||||
'cor_custom'
|
||||
],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'views/project_view.xml',
|
||||
'wizard/project_create_expenses_views.xml',
|
||||
'report/project_budget_hrs_analysis_views.xml',
|
||||
'report/project_budget_amt_analysis_views.xml',
|
||||
],
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import project
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class Project(models.Model):
|
||||
_inherit = 'project.project'
|
||||
|
||||
budgeted_hours = fields.Float(string='Budgeted Hours')
|
||||
budgeted_revenue = fields.Float(string='Budgeted Revenue')
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import project_budget_hrs_analysis
|
||||
from . import project_budget_amt_analysis
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, tools
|
||||
|
||||
|
||||
class BudgetAmtAnalysis(models.Model):
|
||||
|
||||
_name = "project.budget.amt.report"
|
||||
_description = "Project budget amount analysis report"
|
||||
_order = 'project_id'
|
||||
_auto = False
|
||||
|
||||
#analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account', readonly=True)
|
||||
project_id = fields.Many2one('project.project', string='Project', readonly=True)
|
||||
partner_id = fields.Many2one('res.partner', string='Client', readonly=True)
|
||||
employee_id = fields.Many2one('hr.employee', string='Employee', readonly=True)
|
||||
budgeted_revenue = fields.Float("Budgeted Revenue", digits=(16, 2), readonly=True, group_operator="sum")
|
||||
actual_revenue = fields.Float("Actual Revenue", digits=(16, 2), readonly=True, group_operator="sum")
|
||||
|
||||
def init(self):
|
||||
'''Create the view'''
|
||||
tools.drop_view_if_exists(self._cr, self._table)
|
||||
self._cr.execute("""
|
||||
CREATE OR REPLACE VIEW %s AS (
|
||||
SELECT min(AAL.id) as id,
|
||||
PRO.id AS project_id,
|
||||
PRO.partner_id AS partner_id,
|
||||
AAL.employee_id AS employee_id,
|
||||
PRO.budgeted_hours AS budgeted_revenue,
|
||||
sum(AAL.amount) AS actual_revenue
|
||||
FROM project_project PRO
|
||||
LEFT JOIN account_analytic_account AA ON PRO.analytic_account_id = AA.id
|
||||
LEFT JOIN account_analytic_line AAL ON AAL.account_id = AA.id
|
||||
WHERE AAL.amount < 0.0 AND AAL.project_id IS NOT NULL AND PRO.active = 't' AND PRO.allow_timesheets = 't'
|
||||
group by Pro.id, PRO.partner_id, AAL.employee_id, Pro.budgeted_hours, AAL.unit_amount
|
||||
)""" % (self._table,))
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_budget_amt_report_view_pivot" model="ir.ui.view">
|
||||
<field name="name">project.budget.amt.report.pivot</field>
|
||||
<field name="model">project.budget.amt.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Budget Analysis" disable_linking="True" sample="1"> <!-- display_quantity="true" -->
|
||||
<field name="project_id" type="row"/>
|
||||
<field name="budgeted_revenue" type="measure"/>
|
||||
<field name="actual_revenue" type="measure"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_budget_amt_report_view_graph" model="ir.ui.view">
|
||||
<field name="name">project.budget.amt.report.graph</field>
|
||||
<field name="model">project.budget.amt.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Budget Analysis" type="bar" stacked="True" sample="1" disable_linking="1">
|
||||
<field name="budgeted_revenue" type="row"/>
|
||||
<field name="project_id" type="row"/>
|
||||
<field name="actual_revenue" type="measure"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="project_budget_amt_report_view_search" model="ir.ui.view">
|
||||
<field name="name">project.budget.amt.report.search</field>
|
||||
<field name="model">project.budget.amt.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Budget Analysis">
|
||||
<field name="project_id"/>
|
||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
||||
<field name="employee_id"/>
|
||||
<group expand="1" string="Group By">
|
||||
<filter string="Project" name="group_by_project" context="{'group_by':'project_id'}"/>
|
||||
<filter string="Customer" name="group_by_partner_id" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Consultant" name="group_by_employee_id" context="{'group_by':'employee_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_budget_amt_report_view_action" model="ir.actions.act_window">
|
||||
<field name="name">Projects Revenue Acutal Vs Budget</field>
|
||||
<field name="res_model">project.budget.amt.report</field>
|
||||
<field name="view_mode">pivot,graph</field>
|
||||
<field name="search_view_id" ref="project_budget_amt_report_view_search"/>
|
||||
<field name="context">{
|
||||
'group_by_no_leaf':1,
|
||||
'group_by':[],
|
||||
}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_project_budget_report_amt_analysis"
|
||||
parent="project.menu_project_report"
|
||||
action="project_budget_amt_report_view_action"
|
||||
name="Projects Revenue Acutal Vs Budget"
|
||||
sequence="50"/>
|
||||
|
||||
</odoo>
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, tools
|
||||
|
||||
|
||||
class BudgetHrsAnalysis(models.Model):
|
||||
|
||||
_name = "project.budget.hrs.report"
|
||||
_description = "Project budget hours analysis report"
|
||||
_order = 'project_id'
|
||||
_auto = False
|
||||
|
||||
#analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account', readonly=True)
|
||||
project_id = fields.Many2one('project.project', string='Project', readonly=True)
|
||||
partner_id = fields.Many2one('res.partner', string='Client', readonly=True)
|
||||
employee_id = fields.Many2one('hr.employee', string='Employee', readonly=True)
|
||||
budgeted_hours = fields.Float("Budgeted Hours", digits=(16, 2), readonly=True, group_operator="sum")
|
||||
actual_hours = fields.Float("Actual Hours", digits=(16, 2), readonly=True, group_operator="sum")
|
||||
|
||||
def init(self):
|
||||
'''Create the view'''
|
||||
tools.drop_view_if_exists(self._cr, self._table)
|
||||
self._cr.execute("""
|
||||
CREATE OR REPLACE VIEW %s AS (
|
||||
SELECT min(AAL.id) as id,
|
||||
PRO.id AS project_id,
|
||||
PRO.partner_id AS partner_id,
|
||||
AAL.employee_id AS employee_id,
|
||||
PRO.budgeted_hours AS budgeted_hours,
|
||||
sum(AAL.unit_amount) AS actual_hours
|
||||
FROM project_project PRO
|
||||
LEFT JOIN account_analytic_account AA ON PRO.analytic_account_id = AA.id
|
||||
LEFT JOIN account_analytic_line AAL ON AAL.account_id = AA.id
|
||||
WHERE AAL.amount < 0.0 AND AAL.project_id IS NOT NULL AND PRO.active = 't' AND PRO.allow_timesheets = 't'
|
||||
group by Pro.id, PRO.partner_id, AAL.employee_id, Pro.budgeted_hours, AAL.unit_amount
|
||||
)""" % (self._table,))
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_budget_hrs_report_view_pivot" model="ir.ui.view">
|
||||
<field name="name">project.budget.hrs.report.pivot</field>
|
||||
<field name="model">project.budget.hrs.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Budget Analysis" disable_linking="True" sample="1"> <!-- display_quantity="true" -->
|
||||
<field name="project_id" type="row"/>
|
||||
<field name="budgeted_hours" type="measure"/>
|
||||
<field name="actual_hours" type="measure"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_budget_hrs_report_view_graph" model="ir.ui.view">
|
||||
<field name="name">project.budget.hrs.report.graph</field>
|
||||
<field name="model">project.budget.hrs.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Budget Analysis" type="bar" stacked="True" sample="1" disable_linking="1">
|
||||
<field name="budgeted_hours" type="row"/>
|
||||
<field name="project_id" type="row"/>
|
||||
<field name="actual_hours" type="measure"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="project_budget_hrs_report_view_search" model="ir.ui.view">
|
||||
<field name="name">project.budget.hrs.report.search</field>
|
||||
<field name="model">project.budget.hrs.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Budget Analysis">
|
||||
<field name="project_id"/>
|
||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
||||
<field name="employee_id"/>
|
||||
<group expand="1" string="Group By">
|
||||
<filter string="Project" name="group_by_project" context="{'group_by':'project_id'}"/>
|
||||
<filter string="Customer" name="group_by_partner_id" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Consultant" name="group_by_employee_id" context="{'group_by':'employee_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_budget_hrs_report_view_action" model="ir.actions.act_window">
|
||||
<field name="name">Projects Hours Acutal Vs Budget</field>
|
||||
<!--<field name="name">Projects Revenue Acutal Vs Budget</field>-->
|
||||
<field name="res_model">project.budget.hrs.report</field>
|
||||
<field name="view_mode">pivot,graph</field>
|
||||
<field name="search_view_id" ref="project_budget_hrs_report_view_search"/>
|
||||
<field name="context">{
|
||||
'group_by_no_leaf':1,
|
||||
'group_by':[],
|
||||
}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_project_budget_report_hrs_analysis"
|
||||
parent="project.menu_project_report"
|
||||
action="project_budget_hrs_report_view_action"
|
||||
name="Projects Hours Acutal Vs Budget"
|
||||
sequence="50"/>
|
||||
|
||||
</odoo>
|
|
@ -0,0 +1,6 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_project_budget_hrs_report_manager,project.budget.hrs.report,model_project_budget_hrs_report,project.group_project_manager,1,1,1,1
|
||||
access_project_budget_amt_report_manager,project.budget.amt.report,model_project_budget_amt_report,project.group_project_manager,1,1,1,1
|
||||
access_project_create_expense_manager,access_project_create_expense_project_manager,model_project_create_expense,project.group_project_manager,1,1,1,1
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
|
||||
<record id="project_project_budget_inherit" model="ir.ui.view">
|
||||
<field name="name">Project Budget</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(project_report.project_project_action_multi_create_project_expense)d" icon="fa-usd"
|
||||
attrs="{'invisible': [('allow_billable','=',False)]}" string="Create Expense" widget="statinfo">
|
||||
</button>
|
||||
</div>
|
||||
<xpath expr="//field[@name='analytic_account_id']" position="after">
|
||||
<field name="budgeted_hours"/>
|
||||
<field name="budgeted_revenue"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
</odoo>
|
|
@ -0,0 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import project_create_expenses
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class ProjectCreateExpense(models.TransientModel):
|
||||
_name = 'project.create.expense'
|
||||
_description = "Create Expense from project"
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
result = super(ProjectCreateExpense, self).default_get(fields)
|
||||
active_model = self._context.get('active_model')
|
||||
if active_model != 'project.project':
|
||||
raise UserError(_('You can only apply this action from a project.'))
|
||||
active_id = self._context.get('active_id')
|
||||
if 'project_id' in fields and active_id:
|
||||
result['project_id'] = active_id
|
||||
if 'analytic_id' in fields and active_id:
|
||||
project = self.env['project.project'].browse(active_id)
|
||||
if not project.analytic_account_id:
|
||||
raise UserError(_("Please define Analytic Account."))
|
||||
result['analytic_id'] = project.analytic_account_id.id
|
||||
return result
|
||||
|
||||
project_id = fields.Many2one('project.project', "Project", required=True)
|
||||
analytic_id = fields.Many2one('account.analytic.account', "Analytic Account", required=True)
|
||||
description = fields.Char(string="Description", required=True)
|
||||
ispercentage = fields.Boolean(string="Is Percentage", default=False)
|
||||
#sale_order_id = fields.Many2one('sale.order', string="Sales Order", domain="['|', '|', ('partner_id', '=', partner_id), ('partner_id', 'child_of', commercial_partner_id), ('partner_id', 'parent_of', partner_id)]")
|
||||
expenses_from = fields.Selection([
|
||||
('invoiced', 'Invoiced'),
|
||||
('to_invoice', 'To Invoice')
|
||||
], "Expenses from", default='to_invoice')
|
||||
per_from_amt = fields.Float(string="Of", digits=(6, 2))
|
||||
percentage_rate = fields.Float(string="Percentage (%)")
|
||||
expenses_amt = fields.Float(string="Amount", digits=(6, 2), required=True)
|
||||
|
||||
@api.onchange('ispercentage', 'expenses_from', 'percentage_rate', 'per_from_amt')
|
||||
def onchange_ispercentage(self):
|
||||
expense_amount = 0
|
||||
active_id = self._context.get('active_id')
|
||||
if self.ispercentage and self.expenses_from:
|
||||
profit = dict.fromkeys(['invoiced', 'to_invoice'], 0.0)
|
||||
profitability_raw_data = self.env['project.profitability.report'].read_group([('project_id', '=', active_id)],
|
||||
['project_id', 'amount_untaxed_to_invoice', 'amount_untaxed_invoiced'], ['project_id'])
|
||||
print("profitability_raw_dataprofitability_raw_data", profitability_raw_data)
|
||||
for data in profitability_raw_data:
|
||||
profit['invoiced'] += data.get('amount_untaxed_invoiced', 0.0)
|
||||
profit['to_invoice'] += data.get('amount_untaxed_to_invoice', 0.0)
|
||||
if self.expenses_from == 'invoiced':
|
||||
self.per_from_amt = profit['invoiced']
|
||||
if self.expenses_from == 'to_invoice':
|
||||
self.per_from_amt = profit['to_invoice']
|
||||
if self.percentage_rate > 0.0 and self.per_from_amt > 0.0:
|
||||
expense_amount = self.per_from_amt * (self.percentage_rate / 100)
|
||||
self.expenses_amt = expense_amount
|
||||
|
||||
|
||||
def action_create_project_expense(self):
|
||||
""" Private implementation of generating the sales order """
|
||||
expenses_amt = self.expenses_amt
|
||||
if self.expenses_amt < 0:
|
||||
expenses_amt = self.expense_amount * -1
|
||||
if self.expenses_amt == 0:
|
||||
raise ValidationError(_("Amount shoud not be zero"))
|
||||
analytic = self.env['account.analytic.line'].create({
|
||||
'project_id': False,
|
||||
'partner_id': False,
|
||||
'account_id': self.project_id.analytic_account_id.id,
|
||||
'name': self.description,
|
||||
'date': fields.Date.context_today(self),
|
||||
'user_id': self.env.uid,
|
||||
'product_uom_id': False,
|
||||
#'amount': self.expenses_amt * -1,
|
||||
'amount': expenses_amt
|
||||
})
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("analytic.account_analytic_line_action")
|
||||
action['context'] = {'default_account_id': self.analytic_id.id}
|
||||
action['domain'] = [('account_id', '=', self.analytic_id.id)]
|
||||
return action
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_create_expense_view_form" model="ir.ui.view">
|
||||
<field name="name">project.create.expense.view.form</field>
|
||||
<field name="model">project.create.expense</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create Expense from Project">
|
||||
<group>
|
||||
<group>
|
||||
<field name="project_id" readonly="1"/>
|
||||
<field name="analytic_id" readonly="1"/>
|
||||
<!--<field name="sale_order_id" options="{'no_create_edit': True}" context="{'sale_show_partner_name': True}"/>-->
|
||||
<field name="description"/>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<field name="ispercentage"/>
|
||||
<field name="expenses_from" attrs="{'invisible':[('ispercentage','=',False)]}"/>
|
||||
<field name="per_from_amt" attrs="{'invisible':[('ispercentage','=',False)]}"/>
|
||||
<field name="percentage_rate" attrs="{'invisible':[('ispercentage','=',False)]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="expenses_amt"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Create Expense" type="object" name="action_create_project_expense" class="oe_highlight"/>
|
||||
<button string="Cancel" special="cancel" type="object" class="btn btn-secondary oe_inline"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_action_multi_create_project_expense" model="ir.actions.act_window">
|
||||
<field name="name">Create Expense</field>
|
||||
<field name="res_model">project.create.expense</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="project_create_expense_view_form"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
|
@ -0,0 +1,58 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class ProjectCreateExpenses(models.TransientModel):
|
||||
_name = 'project.create.expenses'
|
||||
_description = "Create Expenses from project"
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
result = super(ProjectCreateInvoice, self).default_get(fields)
|
||||
|
||||
active_model = self._context.get('active_model')
|
||||
if active_model != 'project.project':
|
||||
raise UserError(_('You can only apply this action from a project.'))
|
||||
|
||||
active_id = self._context.get('active_id')
|
||||
if 'project_id' in fields and active_id:
|
||||
result['project_id'] = active_id
|
||||
return result
|
||||
|
||||
project_id = fields.Many2one('project.project', "Project", help="Project to make billable", required=True)
|
||||
_candidate_orders = fields.Many2many('sale.order', compute='_compute_candidate_orders')
|
||||
sale_order_id = fields.Many2one(
|
||||
'sale.order', string="Choose the Sales Order to invoice", required=True,
|
||||
domain="[('id', 'in', _candidate_orders)]"
|
||||
)
|
||||
amount_to_invoice = fields.Monetary("Amount to invoice", compute='_compute_amount_to_invoice', currency_field='currency_id', help="Total amount to invoice on the sales order, including all items (services, storables, expenses, ...)")
|
||||
currency_id = fields.Many2one(related='sale_order_id.currency_id', readonly=True)
|
||||
|
||||
@api.depends('project_id.tasks.sale_line_id.order_id.invoice_status')
|
||||
def _compute_candidate_orders(self):
|
||||
for p in self:
|
||||
p._candidate_orders = p.project_id\
|
||||
.mapped('tasks.sale_line_id.order_id')\
|
||||
.filtered(lambda so: so.invoice_status == 'to invoice')
|
||||
|
||||
@api.depends('sale_order_id')
|
||||
def _compute_amount_to_invoice(self):
|
||||
for wizard in self:
|
||||
amount_untaxed = 0.0
|
||||
amount_tax = 0.0
|
||||
for line in wizard.sale_order_id.order_line.filtered(lambda sol: sol.invoice_status == 'to invoice'):
|
||||
amount_untaxed += line.price_reduce * line.qty_to_invoice
|
||||
amount_tax += line.price_tax
|
||||
wizard.amount_to_invoice = amount_untaxed + amount_tax
|
||||
|
||||
def action_create_invoice(self):
|
||||
if not self.sale_order_id and self.sale_order_id.invoice_status != 'to invoice':
|
||||
raise UserError(_("The selected Sales Order should contain something to invoice."))
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("sale.action_view_sale_advance_payment_inv")
|
||||
action['context'] = {
|
||||
'active_ids': self.sale_order_id.ids
|
||||
}
|
||||
return action
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_create_expense_view_form" model="ir.ui.view">
|
||||
<field name="name">project.create.expense.view.form</field>
|
||||
<field name="model">project.create.expense</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create Expense from Project">
|
||||
<group>
|
||||
<field name="project_id" readonly="1"/>
|
||||
<!--<field name="sale_order_id" options="{'no_create_edit': True}" context="{'sale_show_partner_name': True}"/>-->
|
||||
<field name="amount_to_invoice"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Create Expense" type="object" name="action_create_project_expense" class="oe_highlight"/>
|
||||
<button string="Cancel" special="cancel" type="object" class="btn btn-secondary oe_inline"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_action_multi_create_project_expense" model="ir.actions.act_window">
|
||||
<field name="name">Create Expense</field>
|
||||
<field name="res_model">project.create.expense</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="project_create_expense_view_form"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
Loading…
Reference in New Issue