Files
odoo_source/addons/project_purchase/models/project.py
T
Xavier BOL (xbo) 2432b4a490 [IMP] project_purchase: allow user to add new purchase order
Before this commit, when the user is in the project update kanban view
and click on Purchase Order row shown in Project Profitability section
in the right side panel, the user cannot create or edit a purchase order
because the AA on each purchase order line is used to link those
purchase orders to the project.

This commit adds the project and also `project_update` key in the
context to use them keys to set the AA on new Purchase Order Line by
default.

task-2861207

closes odoo/odoo#95721

Related: odoo/enterprise#29304
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
2022-07-12 01:29:25 +02:00

143 lines
6.5 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from odoo import api, fields, models, _, _lt
from odoo.osv import expression
class Project(models.Model):
_inherit = "project.project"
purchase_orders_count = fields.Integer('# Purchase Orders', compute='_compute_purchase_orders_count', groups='purchase.group_purchase_user')
@api.depends('analytic_account_id')
def _compute_purchase_orders_count(self):
if not self.analytic_account_id:
self.purchase_orders_count = 0
return
purchase_orders_data = self.env['purchase.order.line']._read_group([
('account_analytic_id', 'in', self.analytic_account_id.ids)
], ['account_analytic_id', 'order_id:count_distinct'], ['account_analytic_id'])
mapped_data = dict([(data['account_analytic_id'][0], data['order_id']) for data in purchase_orders_data])
for project in self:
project.purchase_orders_count = mapped_data.get(project.analytic_account_id.id, 0)
# ----------------------------
# Actions
# ----------------------------
def action_open_project_purchase_orders(self):
purchase_orders = self.env['purchase.order'].search([
('order_line.account_analytic_id', '!=', False),
('order_line.account_analytic_id', 'in', self.analytic_account_id.ids)
])
action_window = {
'name': _('Purchase Orders'),
'type': 'ir.actions.act_window',
'res_model': 'purchase.order',
'views': [[False, 'tree'], [False, 'form']],
'domain': [('id', 'in', purchase_orders.ids)],
'context': {
'project_id': self.id,
}
}
if len(purchase_orders) == 1:
action_window['views'] = [[False, 'form']]
action_window['res_id'] = purchase_orders.id
return action_window
def action_profitability_items(self, section_name, domain=None, res_id=False):
if section_name == 'purchase_order':
action = {
'name': _('Purchase Order Items'),
'type': 'ir.actions.act_window',
'res_model': 'purchase.order.line',
'views': [[False, 'tree'], [False, 'form']],
'domain': domain,
'context': {
'create': False,
'edit': False,
},
}
if res_id:
action['res_id'] = res_id
if 'views' in action:
action['views'] = [
(view_id, view_type)
for view_id, view_type in action['views']
if view_type == 'form'
] or [False, 'form']
action['view_mode'] = 'form'
return action
return super().action_profitability_items(section_name, domain, res_id)
# ----------------------------
# Project Updates
# ----------------------------
def _get_stat_buttons(self):
buttons = super(Project, self)._get_stat_buttons()
if self.user_has_groups('purchase.group_purchase_user'):
buttons.append({
'icon': 'credit-card',
'text': _lt('Purchase Orders'),
'number': self.purchase_orders_count,
'action_type': 'object',
'action': 'action_open_project_purchase_orders',
'show': self.purchase_orders_count > 0,
'sequence': 36,
})
return buttons
def _get_profitability_aal_domain(self):
return expression.AND([
super()._get_profitability_aal_domain(),
['|', ('move_id', '=', False), ('move_id.purchase_line_id', '=', False)],
])
def _get_profitability_labels(self):
labels = super()._get_profitability_labels()
labels['purchase_order'] = _lt('Purchase Orders')
return labels
def _get_profitability_sequence_per_invoice_type(self):
sequence_per_invoice_type = super()._get_profitability_sequence_per_invoice_type()
sequence_per_invoice_type['purchase_order'] = 9
return sequence_per_invoice_type
def _get_profitability_items(self, with_action=True):
profitability_items = super()._get_profitability_items(with_action)
if self.analytic_account_id:
purchase_order_line_read = self.env['purchase.order.line'].sudo().search_read([
('account_analytic_id', 'in', self.analytic_account_id.ids),
('state', 'in', ['purchase', 'done']),
'|',
('qty_invoiced', '>', 0),
'|', ('qty_to_invoice', '>', 0), ('product_uom_qty', '>', 0),
], ['qty_invoiced', 'qty_to_invoice', 'product_uom_qty', 'price_unit'])
if purchase_order_line_read:
amount_invoiced = amount_to_invoice = 0.0
purchase_order_line_ids = []
for pol_read in purchase_order_line_read:
price_unit = pol_read['price_unit']
amount_invoiced -= price_unit * pol_read['qty_invoiced'] if pol_read['qty_invoiced'] > 0 else 0.0
if pol_read['qty_to_invoice'] > 0:
amount_to_invoice -= price_unit * pol_read['qty_to_invoice']
else:
amount_to_invoice -= price_unit * (pol_read['product_uom_qty'] - pol_read['qty_invoiced'])
purchase_order_line_ids.append(pol_read['id'])
costs = profitability_items['costs']
section_id = 'purchase_order'
purchase_order_costs = {'id': section_id, 'sequence': self._get_profitability_sequence_per_invoice_type()[section_id], 'billed': amount_invoiced, 'to_bill': amount_to_invoice}
if with_action and purchase_order_line_ids and self.user_has_groups('purchase.group_purchase_user'):
action = {'name': 'action_profitability_items', 'type': 'object', 'section': section_id, 'domain': json.dumps([('id', 'in', purchase_order_line_ids)])}
if len(purchase_order_line_ids) == 1:
action['res_id'] = purchase_order_line_ids[0]
purchase_order_costs['action'] = action
costs['data'].append(purchase_order_costs)
costs['total']['billed'] += amount_invoiced
costs['total']['to_bill'] += amount_to_invoice
return profitability_items