[MOV] purchase_requisition: split models and views files

This commit simply move code into the right file.
The goal is here to fit the guidelines and prepare
the module for some changes. This will ease the
reading of module code.

Task-1851286

closes odoo/odoo#28795
This commit is contained in:
jem-odoo
2018-11-19 12:52:07 +00:00
parent 6f5748d288
commit 8fc246da31
10 changed files with 313 additions and 282 deletions
+4 -2
View File
@@ -11,12 +11,14 @@ Manage calls for tenders and blanket orders. Calls for tenders are used to get
competing offers from different vendors and select the best ones. Blanket orders
are agreements you have with vendors to benefit from a predetermined pricing.
""",
'depends' : ['purchase_stock'],
'depends': ['purchase_stock'],
'demo': ['data/purchase_requisition_demo.xml'],
'data': [
'security/purchase_tender.xml',
'security/purchase_requisition_security.xml',
'security/ir.model.access.csv',
'data/purchase_requisition_data.xml',
'views/product_views.xml',
'views/purchase_views.xml',
'views/purchase_requisition_views.xml',
'views/res_config_settings_views.xml',
'report/purchase_requisition_report.xml',
@@ -1,3 +1,6 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import purchase
from . import product
from . import purchase_requisition
from . import stock
@@ -0,0 +1,34 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
class SupplierInfo(models.Model):
_inherit = 'product.supplierinfo'
_order = 'sequence, purchase_requisition_id desc, min_qty desc, price'
purchase_requisition_id = fields.Many2one('purchase.requisition', related='purchase_requisition_line_id.requisition_id', string='Blanket order', readonly=False)
purchase_requisition_line_id = fields.Many2one('purchase.requisition.line')
class ProductProduct(models.Model):
_inherit = 'product.product'
def _prepare_sellers(self, params):
if params and params.get('order_id'):
return self.seller_ids.filtered(lambda s: not s.purchase_requisition_id or s.purchase_requisition_id == params['order_id'].requisition_id)
else:
return self.seller_ids
class ProductTemplate(models.Model):
_inherit = 'product.template'
purchase_requisition = fields.Selection(
[('rfq', 'Create a draft purchase order'),
('tenders', 'Propose a call for tenders')],
string='Procurement', default='rfq',
help="Create a draft purchase order: Based on your product configuration, the system will create a draft "
"purchase order.Propose a call for tender : If the 'purchase_requisition' module is installed and this option "
"is selected, the system will create a draft call for tender.")
@@ -0,0 +1,129 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
requisition_id = fields.Many2one('purchase.requisition', string='Purchase Agreement', copy=False)
is_quantity_copy = fields.Selection(related='requisition_id.is_quantity_copy', readonly=False)
@api.onchange('requisition_id')
def _onchange_requisition_id(self):
if not self.requisition_id:
return
requisition = self.requisition_id
if self.partner_id:
partner = self.partner_id
else:
partner = requisition.vendor_id
payment_term = partner.property_supplier_payment_term_id
FiscalPosition = self.env['account.fiscal.position']
fpos = FiscalPosition.get_fiscal_position(partner.id)
fpos = FiscalPosition.browse(fpos)
self.partner_id = partner.id
self.fiscal_position_id = fpos.id
self.payment_term_id = payment_term.id,
self.company_id = requisition.company_id.id
self.currency_id = requisition.currency_id.id
if not self.origin or requisition.name not in self.origin.split(', '):
if self.origin:
if requisition.name:
self.origin = self.origin + ', ' + requisition.name
else:
self.origin = requisition.name
self.notes = requisition.description
self.date_order = requisition.date_end or fields.Datetime.now()
self.picking_type_id = requisition.picking_type_id.id
if requisition.type_id.line_copy != 'copy':
return
# Create PO lines if necessary
order_lines = []
for line in requisition.line_ids:
# Compute name
product_lang = line.product_id.with_context({
'lang': partner.lang,
'partner_id': partner.id,
})
name = product_lang.display_name
if product_lang.description_purchase:
name += '\n' + product_lang.description_purchase
# Compute taxes
if fpos:
taxes_ids = fpos.map_tax(line.product_id.supplier_taxes_id.filtered(lambda tax: tax.company_id == requisition.company_id)).ids
else:
taxes_ids = line.product_id.supplier_taxes_id.filtered(lambda tax: tax.company_id == requisition.company_id).ids
# Compute quantity and price_unit
if line.product_uom_id != line.product_id.uom_po_id:
product_qty = line.product_uom_id._compute_quantity(line.product_qty, line.product_id.uom_po_id)
price_unit = line.product_uom_id._compute_price(line.price_unit, line.product_id.uom_po_id)
else:
product_qty = line.product_qty
price_unit = line.price_unit
if requisition.type_id.quantity_copy != 'copy':
product_qty = 0
# Create PO line
order_line_values = line._prepare_purchase_order_line(
name=name, product_qty=product_qty, price_unit=price_unit,
taxes_ids=taxes_ids)
order_lines.append((0, 0, order_line_values))
self.order_line = order_lines
@api.multi
def button_confirm(self):
res = super(PurchaseOrder, self).button_confirm()
for po in self:
if not po.requisition_id:
continue
if po.requisition_id.type_id.exclusive == 'exclusive':
others_po = po.requisition_id.mapped('purchase_ids').filtered(lambda r: r.id != po.id)
others_po.button_cancel()
po.requisition_id.action_done()
return res
@api.model
def create(self, vals):
purchase = super(PurchaseOrder, self).create(vals)
if purchase.requisition_id:
purchase.message_post_with_view('mail.message_origin_link',
values={'self': purchase, 'origin': purchase.requisition_id},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'))
return purchase
@api.multi
def write(self, vals):
result = super(PurchaseOrder, self).write(vals)
if vals.get('requisition_id'):
self.message_post_with_view('mail.message_origin_link',
values={'self': self, 'origin': self.requisition_id, 'edit': True},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'))
return result
class PurchaseOrderLine(models.Model):
_inherit = 'purchase.order.line'
@api.onchange('product_qty', 'product_uom')
def _onchange_quantity(self):
res = super(PurchaseOrderLine, self)._onchange_quantity()
if self.order_id.requisition_id:
for line in self.order_id.requisition_id.line_ids:
if line.product_id == self.product_id:
if line.product_uom_id != self.product_uom:
self.price_unit = line.product_uom_id._compute_price(
line.price_unit, self.product_uom)
else:
self.price_unit = line.price_unit
break
return res
@@ -180,13 +180,6 @@ class PurchaseRequisition(models.Model):
self.mapped('line_ids').unlink()
return super(PurchaseRequisition, self).unlink()
class SupplierInfo(models.Model):
_inherit = "product.supplierinfo"
_order = 'sequence, purchase_requisition_id desc, min_qty desc, price'
purchase_requisition_id = fields.Many2one('purchase.requisition', related='purchase_requisition_line_id.requisition_id', string='Blanket order', readonly=False)
purchase_requisition_line_id = fields.Many2one('purchase.requisition.line')
class PurchaseRequisitionLine(models.Model):
_name = "purchase.requisition.line"
@@ -290,217 +283,3 @@ class PurchaseRequisitionLine(models.Model):
'analytic_tag_ids': self.analytic_tag_ids.ids,
'move_dest_ids': self.move_dest_id and [(4, self.move_dest_id.id)] or []
}
class PurchaseOrder(models.Model):
_inherit = "purchase.order"
requisition_id = fields.Many2one('purchase.requisition', string='Purchase Agreement', copy=False)
is_quantity_copy = fields.Selection(related='requisition_id.is_quantity_copy', readonly=False)
@api.onchange('requisition_id')
def _onchange_requisition_id(self):
if not self.requisition_id:
return
requisition = self.requisition_id
if self.partner_id:
partner = self.partner_id
else:
partner = requisition.vendor_id
payment_term = partner.property_supplier_payment_term_id
FiscalPosition = self.env['account.fiscal.position']
fpos = FiscalPosition.get_fiscal_position(partner.id)
fpos = FiscalPosition.browse(fpos)
self.partner_id = partner.id
self.fiscal_position_id = fpos.id
self.payment_term_id = payment_term.id
self.company_id = requisition.company_id.id
self.currency_id = requisition.currency_id.id
if not self.origin or requisition.name not in self.origin.split(', '):
if self.origin:
if requisition.name:
self.origin = self.origin + ', ' + requisition.name
else:
self.origin = requisition.name
self.notes = requisition.description
self.date_order = requisition.date_end or fields.Datetime.now()
self.picking_type_id = requisition.picking_type_id.id
if requisition.type_id.line_copy != 'copy':
return
# Create PO lines if necessary
order_lines = []
for line in requisition.line_ids:
# Compute name
product_lang = line.product_id.with_context({
'lang': partner.lang,
'partner_id': partner.id,
})
name = product_lang.display_name
if product_lang.description_purchase:
name += '\n' + product_lang.description_purchase
# Compute taxes
if fpos:
taxes_ids = fpos.map_tax(line.product_id.supplier_taxes_id.filtered(lambda tax: tax.company_id == requisition.company_id)).ids
else:
taxes_ids = line.product_id.supplier_taxes_id.filtered(lambda tax: tax.company_id == requisition.company_id).ids
# Compute quantity and price_unit
if line.product_uom_id != line.product_id.uom_po_id:
product_qty = line.product_uom_id._compute_quantity(line.product_qty, line.product_id.uom_po_id)
price_unit = line.product_uom_id._compute_price(line.price_unit, line.product_id.uom_po_id)
else:
product_qty = line.product_qty
price_unit = line.price_unit
if requisition.type_id.quantity_copy != 'copy':
product_qty = 0
# Create PO line
order_line_values = line._prepare_purchase_order_line(
name=name, product_qty=product_qty, price_unit=price_unit,
taxes_ids=taxes_ids)
order_lines.append((0, 0, order_line_values))
self.order_line = order_lines
@api.multi
def button_confirm(self):
res = super(PurchaseOrder, self).button_confirm()
for po in self:
if not po.requisition_id:
continue
if po.requisition_id.type_id.exclusive == 'exclusive':
others_po = po.requisition_id.mapped('purchase_ids').filtered(lambda r: r.id != po.id)
others_po.button_cancel()
po.requisition_id.action_done()
return res
@api.model
def create(self, vals):
purchase = super(PurchaseOrder, self).create(vals)
if purchase.requisition_id:
purchase.message_post_with_view('mail.message_origin_link',
values={'self': purchase, 'origin': purchase.requisition_id},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'))
return purchase
@api.multi
def write(self, vals):
result = super(PurchaseOrder, self).write(vals)
if vals.get('requisition_id'):
self.message_post_with_view('mail.message_origin_link',
values={'self': self, 'origin': self.requisition_id, 'edit': True},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'))
return result
class PurchaseOrderLine(models.Model):
_inherit = "purchase.order.line"
@api.onchange('product_qty', 'product_uom')
def _onchange_quantity(self):
res = super(PurchaseOrderLine, self)._onchange_quantity()
if self.order_id.requisition_id:
for line in self.order_id.requisition_id.line_ids:
if line.product_id == self.product_id:
if line.product_uom_id != self.product_uom:
self.price_unit = line.product_uom_id._compute_price(
line.price_unit, self.product_uom)
else:
self.price_unit = line.price_unit
break
return res
class ProductProduct(models.Model):
_inherit = 'product.product'
def _prepare_sellers(self, params):
if params and params.get('order_id'):
return self.seller_ids.filtered(lambda s: not s.purchase_requisition_id or s.purchase_requisition_id == params['order_id'].requisition_id)
else:
return self.seller_ids
class ProductTemplate(models.Model):
_inherit = 'product.template'
purchase_requisition = fields.Selection(
[('rfq', 'Create a draft purchase order'),
('tenders', 'Propose a call for tenders')],
string='Procurement', default='rfq',
help="Create a draft purchase order: Based on your product configuration, the system will create a draft "
"purchase order.Propose a call for tender : If the 'purchase_requisition' module is installed and this option "
"is selected, the system will create a draft call for tender.")
class StockMove(models.Model):
_inherit = "stock.move"
requistion_line_ids = fields.One2many('purchase.requisition.line', 'move_dest_id')
class ProcurementGroup(models.Model):
_inherit = 'procurement.group'
@api.model
def _get_exceptions_domain(self):
return super(ProcurementGroup, self)._get_exceptions_domain() + [('requistion_line_ids', '=', False)]
class StockRule(models.Model):
_inherit = 'stock.rule'
@api.multi
def _run_buy(self, product_id, product_qty, product_uom, location_id, name, origin, values):
if product_id.purchase_requisition != 'tenders':
return super(StockRule, self)._run_buy(product_id, product_qty, product_uom, location_id, name, origin, values)
values = self.env['purchase.requisition']._prepare_tender_values(product_id, product_qty, product_uom, location_id, name, origin, values)
values['picking_type_id'] = self.picking_type_id.id
self.env['purchase.requisition'].create(values)
return True
def _prepare_purchase_order(self, product_id, product_qty, product_uom, origin, values, partner):
res = super(StockRule, self)._prepare_purchase_order(product_id, product_qty, product_uom, origin, values, partner)
res['partner_ref'] = values['supplier'].purchase_requisition_id.name
res['requisition_id'] = values['supplier'].purchase_requisition_id.id
if values['supplier'].purchase_requisition_id.currency_id:
res['currency_id'] = values['supplier'].purchase_requisition_id.currency_id.id
return res
def _make_po_get_domain(self, values, partner):
domain = super(StockRule, self)._make_po_get_domain(values, partner)
if 'supplier' in values and values['supplier'].purchase_requisition_id:
domain += (
('requisition_id', '=', values['supplier'].purchase_requisition_id.id),
)
return domain
class StockMove(models.Model):
_inherit = 'stock.move'
requisition_line_ids = fields.One2many('purchase.requisition.line', 'move_dest_id')
def _get_upstream_documents_and_responsibles(self, visited):
if self.requisition_line_ids:
return [(requisition_line.requisition_id, requisition_line.requisition_id.user_id, visited) for requisition_line in self.requisition_line_ids if requisition_line.state not in ('done', 'cancel')]
else:
return super(StockMove, self)._get_upstream_documents_and_responsibles(visited)
class Orderpoint(models.Model):
_inherit = "stock.warehouse.orderpoint"
def _quantity_in_progress(self):
res = super(Orderpoint, self)._quantity_in_progress()
for op in self:
for pr in self.env['purchase.requisition'].search([('state','=','draft'),('origin','=',op.name)]):
for prline in pr.line_ids.filtered(lambda l: l.product_id.id == op.product_id.id):
res[op.id] += prline.product_uom_id._compute_quantity(prline.product_qty, op.product_uom, round=False)
return res
@@ -0,0 +1,65 @@
# -*- encoding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class ProcurementGroup(models.Model):
_inherit = 'procurement.group'
@api.model
def _get_exceptions_domain(self):
return super(ProcurementGroup, self)._get_exceptions_domain() + [('requistion_line_ids', '=', False)]
class StockRule(models.Model):
_inherit = 'stock.rule'
@api.multi
def _run_buy(self, product_id, product_qty, product_uom, location_id, name, origin, values):
if product_id.purchase_requisition != 'tenders':
return super(StockRule, self)._run_buy(product_id, product_qty, product_uom, location_id, name, origin, values)
values = self.env['purchase.requisition']._prepare_tender_values(product_id, product_qty, product_uom, location_id, name, origin, values)
values['picking_type_id'] = self.picking_type_id.id
self.env['purchase.requisition'].create(values)
return True
def _prepare_purchase_order(self, product_id, product_qty, product_uom, origin, values, partner):
res = super(StockRule, self)._prepare_purchase_order(product_id, product_qty, product_uom, origin, values, partner)
res['partner_ref'] = values['supplier'].purchase_requisition_id.name
res['requisition_id'] = values['supplier'].purchase_requisition_id.id
if values['supplier'].purchase_requisition_id.currency_id:
res['currency_id'] = values['supplier'].purchase_requisition_id.currency_id.id
return res
def _make_po_get_domain(self, values, partner):
domain = super(StockRule, self)._make_po_get_domain(values, partner)
if 'supplier' in values and values['supplier'].purchase_requisition_id:
domain += (
('requisition_id', '=', values['supplier'].purchase_requisition_id.id),
)
return domain
class StockMove(models.Model):
_inherit = 'stock.move'
requisition_line_ids = fields.One2many('purchase.requisition.line', 'move_dest_id')
def _get_upstream_documents_and_responsibles(self, visited):
if self.requisition_line_ids:
return [(requisition_line.requisition_id, requisition_line.requisition_id.user_id, visited) for requisition_line in self.requisition_line_ids if requisition_line.state not in ('done', 'cancel')]
else:
return super(StockMove, self)._get_upstream_documents_and_responsibles(visited)
class Orderpoint(models.Model):
_inherit = "stock.warehouse.orderpoint"
def _quantity_in_progress(self):
res = super(Orderpoint, self)._quantity_in_progress()
for op in self:
for pr in self.env['purchase.requisition'].search([('state','=','draft'),('origin','=',op.name)]):
for prline in pr.line_ids.filtered(lambda l: l.product_id.id == op.product_id.id):
res[op.id] += prline.product_uom_id._compute_quantity(prline.product_qty, op.product_uom, round=False)
return res
@@ -0,0 +1,48 @@
<?xml version="1.0"?>
<odoo>
<record id="product_supplierinfo_tree_view_inherit" model="ir.ui.view">
<field name="name">product.template.product.form.inherit</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="product.product_supplierinfo_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='min_qty']" position="before">
<field name="purchase_requisition_id"/>
</xpath>
</field>
</record>
<record id="supplier_info_form_inherit" model="ir.ui.view">
<field name="name">product.supplierinfo.requisition.view</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="product.product_supplierinfo_form_view"/>
<field name="arch" type="xml">
<field name="product_code" position="after">
<field name="purchase_requisition_id"
attrs="{'invisible': [('purchase_requisition_id', '=', False)]}"/>
</field>
</field>
</record>
<record id="product_template_form_view_inherit" model="ir.ui.view">
<field name="name">product.template.form.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="purchase.view_product_supplier_inherit"/>
<field name="arch" type="xml">
<group name="bill" position="before">
<group string="Reordering" attrs="{'invisible': [('type', '=', 'service')]}">
<field name="purchase_requisition" widget="radio"/>
</group>
</group>
</field>
</record>
<act_window
id="act_res_partner_2_purchase_order"
name="Purchase orders"
domain="[('requisition_id', '=', active_id)]"
context="{'default_requisition_id': active_id}"
res_model="purchase.order"
src_model="purchase.requisition"/>
</odoo>
@@ -73,22 +73,6 @@
<!-- Purchase Orders -->
<record model="ir.ui.view" id="purchase_order_form_inherit">
<field name="name">purchase.order.form.inherit</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<field name="partner_id" position="replace">
<field name="is_quantity_copy" invisible="1"/>
<field name="partner_id" context="{'search_default_supplier':1, 'default_supplier':1, 'default_customer':0}" domain="[('supplier','=',True)]" attrs="{'readonly': ['|', ('is_quantity_copy', '=', 'none'), ('state', 'in', ['purchase', 'done', 'cancel'])]}" force_save="1"/>
</field>
<field name="partner_ref" position="after">
<field name="requisition_id"
domain="[('state', 'in', ('in_progress', 'open', 'ongoing')), ('vendor_id', 'in', (partner_id, False))]"/>
</field>
</field>
</record>
<record model="ir.ui.view" id="supplier_info_form_inherit">
<field name="name">product.supplierinfo.requisition.view</field>
<field name="model">product.supplierinfo</field>
@@ -102,17 +86,6 @@
</field>
</record>
<record model="ir.ui.view" id="purchase_order_search_inherit">
<field name="name">purchase.order.list.select.inherit</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.view_purchase_order_filter"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='approved']" position="after">
<filter string="Requisition" name="requisition" domain="[('requisition_id', '!=', False)]" help="Purchase Orders with requisition"/>
</xpath>
</field>
</record>
<record model="ir.actions.act_window" id="action_purchase_requisition_to_so">
<field name="name">Request for Quotation</field>
<field name="type">ir.actions.act_window</field>
@@ -330,37 +303,5 @@
parent="purchase.menu_procurement_management"
action="action_purchase_requisition"/>
<record model="ir.ui.view" id="product_template_form_view_inherit">
<field name="name">product.template.form.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="purchase.view_product_supplier_inherit"/>
<field name="arch" type="xml">
<group name="bill" position="before">
<group string="Reordering" attrs="{'invisible': [('type', '=', 'service')]}">
<field name="purchase_requisition" widget="radio"/>
</group>
</group>
</field>
</record>
<record model="ir.ui.view" id="product_supplierinfo_tree_view_inherit">
<field name="name">product.template.product.form.inherit</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="product.product_supplierinfo_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='min_qty']" position="before">
<field name="purchase_requisition_id"/>
</xpath>
</field>
</record>
<act_window
domain="[('requisition_id', '=', active_id)]"
context="{'default_requisition_id': active_id}"
id="act_res_partner_2_purchase_order"
name="Purchase orders"
res_model="purchase.order"
src_model="purchase.requisition"/>
</data>
</odoo>
@@ -0,0 +1,30 @@
<?xml version="1.0"?>
<odoo>
<record id="purchase_order_form_inherit" model="ir.ui.view">
<field name="name">purchase.order.form.inherit</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<field name="partner_id" position="replace">
<field name="is_quantity_copy" invisible="1"/>
<field name="partner_id" context="{'search_default_supplier':1, 'default_supplier':1, 'default_customer':0}" domain="[('supplier','=',True)]" attrs="{'readonly': ['|', ('is_quantity_copy', '=', 'none'), ('state', 'in', ['purchase', 'done', 'cancel'])]}" force_save="1"/>
</field>
<field name="partner_ref" position="after">
<field name="requisition_id" domain="[('state', 'in', ('in_progress', 'open', 'ongoing')), ('vendor_id', 'in', (partner_id, False))]"/>
</field>
</field>
</record>
<record id="purchase_order_search_inherit" model="ir.ui.view">
<field name="name">purchase.order.list.select.inherit</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.view_purchase_order_filter"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='approved']" position="after">
<filter string="Requisition" name="requisition" domain="[('requisition_id', '!=', False)]" help="Purchase Orders with requisition"/>
</xpath>
</field>
</record>
</odoo>