Add module purchase_stock_usability
Port purchase_usability to v12
This commit is contained in:
56
.gitignore
vendored
Normal file
56
.gitignore
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
bin/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Pycharm
|
||||
.idea
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Rope
|
||||
.ropeproject
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# Backup files
|
||||
*~
|
||||
*.swp
|
||||
@@ -17,32 +17,3 @@ class BaseLanguageInstall(models.TransientModel):
|
||||
_inherit = 'base.language.install'
|
||||
|
||||
overwrite = fields.Boolean(default=True)
|
||||
|
||||
|
||||
class BaseUsabilityInstalled(models.AbstractModel):
|
||||
_name = "base.usability.installed"
|
||||
_description = "technical flag to see if base_usability module is installed"
|
||||
|
||||
|
||||
formatLang_original = misc.formatLang
|
||||
|
||||
def formatLang(self, value, digits=None, grouping=True, monetary=False,
|
||||
dp=False, currency_obj=False, int_no_digits=True):
|
||||
with api.Environment.manage():
|
||||
env = api.Environment(self.cr, self.uid, {})
|
||||
if (
|
||||
'base.usability.installed' in env and
|
||||
int_no_digits and
|
||||
not monetary and
|
||||
isinstance(value, float) and
|
||||
dp):
|
||||
prec = env['decimal.precision'].precision_get(dp)
|
||||
if not float_compare(value, int(value), precision_digits=prec):
|
||||
digits = 0
|
||||
dp = False
|
||||
res = formatLang_original(
|
||||
self, value, digits=digits, grouping=grouping, monetary=monetary,
|
||||
dp=dp, currency_obj=currency_obj)
|
||||
return res
|
||||
|
||||
misc.formatLang = formatLang
|
||||
|
||||
1
purchase_stock_usability/__init__.py
Normal file
1
purchase_stock_usability/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import purchase
|
||||
29
purchase_stock_usability/__manifest__.py
Normal file
29
purchase_stock_usability/__manifest__.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright (C) 2014-2019 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
'name': 'Purchase Stock Usability',
|
||||
'version': '12.0.1.0.0',
|
||||
'category': 'Purchases',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Usability improvements on purchase_stock module',
|
||||
'description': """
|
||||
Purchase Stock Usability
|
||||
========================
|
||||
|
||||
Several usability improvements on the official purchase_stock module:
|
||||
|
||||
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
|
||||
""",
|
||||
'author': 'Akretion',
|
||||
'website': 'http://www.akretion.com',
|
||||
'depends': [
|
||||
'purchase_stock',
|
||||
'purchase_usability',
|
||||
],
|
||||
'data': [
|
||||
'stock_view.xml',
|
||||
],
|
||||
'installable': True,
|
||||
}
|
||||
27
purchase_stock_usability/purchase.py
Normal file
27
purchase_stock_usability/purchase.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2015-2019 Akretion France (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class PurchaseOrder(models.Model):
|
||||
_inherit = 'purchase.order'
|
||||
|
||||
picking_type_id = fields.Many2one(track_visibility='onchange')
|
||||
incoterm_id = fields.Many2one(track_visibility='onchange')
|
||||
|
||||
# inherit compute method of the field delivery_partner_id
|
||||
# defined in purchase_usability
|
||||
@api.depends('dest_address_id', 'picking_type_id')
|
||||
def _compute_delivery_partner_id(self):
|
||||
for o in self:
|
||||
delivery_partner_id = False
|
||||
if o.dest_address_id:
|
||||
delivery_partner_id = o.dest_address_id
|
||||
elif (
|
||||
o.picking_type_id.warehouse_id and
|
||||
o.picking_type_id.warehouse_id.partner_id):
|
||||
delivery_partner_id = o.picking_type_id.warehouse_id.partner_id
|
||||
o.delivery_partner_id = delivery_partner_id
|
||||
22
purchase_stock_usability/stock_view.xml
Normal file
22
purchase_stock_usability/stock_view.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2017-2019 Akretion (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_picking_form" model="ir.ui.view">
|
||||
<field name="name">purchase_usability.stock.picking.form</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="origin" position="after">
|
||||
<field name="purchase_id" attrs="{'invisible': [('picking_type_code', '!=', 'incoming')]}"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</odoo>
|
||||
@@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import purchase
|
||||
from . import product
|
||||
from . import partner
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014-2017 Akretion (http://www.akretion.com)
|
||||
# Copyright (C) 2014-2019 Akretion (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
'name': 'Purchase Usability',
|
||||
'version': '10.0.0.1.0',
|
||||
'category': 'Purchase Management',
|
||||
'version': '12.0.1.0.0',
|
||||
'category': 'Purchases',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'Show invoices and receptions on PO',
|
||||
'summary': 'Usability improvements on purchase module',
|
||||
'description': """
|
||||
Purchase Usability Extension
|
||||
============================
|
||||
Purchase Usability
|
||||
==================
|
||||
|
||||
Display Invoices and Incoming Shipments on Purchase Order form view (in dedicated tabs).
|
||||
Several usability improvements on the official purchase module:
|
||||
|
||||
Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
|
||||
""",
|
||||
@@ -22,7 +21,6 @@ Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for
|
||||
'depends': ['purchase'],
|
||||
'data': [
|
||||
'purchase_view.xml',
|
||||
'stock_view.xml',
|
||||
],
|
||||
'active': False,
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
@@ -1,30 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2017 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
# Copyright 2017-2019 Akretion France
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
purchase_warn = fields.Selection(track_visibility='onchange')
|
||||
|
||||
# Fix an access right issue when accessing partner form without being
|
||||
# a member of the purchase/User group
|
||||
@api.multi
|
||||
def _purchase_invoice_count(self):
|
||||
poo = self.env['purchase.order']
|
||||
aio = self.env['account.invoice']
|
||||
for partner in self:
|
||||
try:
|
||||
partner.purchase_order_count = poo.search_count(
|
||||
[('partner_id', 'child_of', partner.id)])
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
partner.supplier_invoice_count = aio.search_count([
|
||||
('partner_id', 'child_of', partner.id),
|
||||
('type', '=', 'in_invoice')])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||
# Copyright 2016-2019 Akretion France
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# © 2015-2016 Akretion (http://www.akretion.com)
|
||||
# Copyright 2015-2019 Akretion France (http://www.akretion.com)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
@@ -10,45 +10,22 @@ from odoo.tools.misc import formatLang
|
||||
class PurchaseOrder(models.Model):
|
||||
_inherit = 'purchase.order'
|
||||
|
||||
picking_type_id = fields.Many2one(track_visibility='onchange')
|
||||
dest_address_id = fields.Many2one(track_visibility='onchange')
|
||||
currency_id = fields.Many2one(track_visibility='onchange')
|
||||
payment_term_id = fields.Many2one(track_visibility='onchange')
|
||||
fiscal_position_id = fields.Many2one(track_visibility='onchange')
|
||||
incoterm_id = fields.Many2one(track_visibility='onchange')
|
||||
partner_ref = fields.Char(track_visibility='onchange')
|
||||
# field 'partner_id': native value for track_visibility='always'
|
||||
partner_id = fields.Many2one(track_visibility='onchange')
|
||||
# for report
|
||||
# the field 'delivery_partner_id' is used in report
|
||||
# the compute method of that field is inherited in purchase_stock_usability
|
||||
delivery_partner_id = fields.Many2one(
|
||||
'res.partner', compute='_compute_delivery_partner_id', readonly=True)
|
||||
|
||||
@api.multi
|
||||
@api.depends('dest_address_id', 'picking_type_id')
|
||||
@api.depends('dest_address_id')
|
||||
def _compute_delivery_partner_id(self):
|
||||
for o in self:
|
||||
delivery_partner_id = False
|
||||
if o.dest_address_id:
|
||||
delivery_partner_id = o.dest_address_id
|
||||
elif (
|
||||
o.picking_type_id.warehouse_id and
|
||||
o.picking_type_id.warehouse_id.partner_id):
|
||||
delivery_partner_id = o.picking_type_id.warehouse_id.partner_id
|
||||
o.delivery_partner_id = delivery_partner_id
|
||||
|
||||
@api.multi
|
||||
def button_confirm(self):
|
||||
'''Reload view upon order confirmation to display the 3 qty cols'''
|
||||
res = super(PurchaseOrder, self).button_confirm()
|
||||
if len(self) == 1:
|
||||
res = self.env['ir.actions.act_window'].for_xml_id(
|
||||
'purchase', 'purchase_form_action')
|
||||
res.update({
|
||||
'view_mode': 'form,tree,kanban,pivot,graph,calendar',
|
||||
'res_id': self.id,
|
||||
'views': False,
|
||||
})
|
||||
return res
|
||||
for order in self:
|
||||
order.delivery_partner_id = order.dest_address_id
|
||||
|
||||
def print_order(self):
|
||||
action = self.env['report'].get_action(
|
||||
@@ -63,17 +40,8 @@ class PurchaseOrder(models.Model):
|
||||
for po in self:
|
||||
name = po.name
|
||||
if po.partner_ref:
|
||||
name += ' ('+po.partner_ref+')'
|
||||
if po.amount_untaxed:
|
||||
name += ' (' + po.partner_ref + ')'
|
||||
if self.env.context.get('show_total_amount') and po.amount_total:
|
||||
name += ': ' + formatLang(self.env, po.amount_untaxed, currency_obj=po.currency_id)
|
||||
result.append((po.id, name))
|
||||
return result
|
||||
|
||||
|
||||
class StockPicking(models.Model):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
# Field added to have a clickable link from picking to PO
|
||||
purchase_id = fields.Many2one(
|
||||
related='move_lines.purchase_line_id.order_id', readonly=True,
|
||||
string='Purchase Order')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
© 2014-2016 Akretion (http://www.akretion.com/)
|
||||
Copyright 2014-2019 Akretion (http://www.akretion.com/)
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
@@ -14,7 +14,7 @@
|
||||
<field name="inherit_id" ref="purchase.purchase_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<button name="action_rfq_send" states="purchase" position="after">
|
||||
<button name="print_order" states="purchase" string="Print Order" type="object" groups="base.group_user"/>
|
||||
<button name="print_order" states="purchase" string="Print Order" type="object"/>
|
||||
</button>
|
||||
<field name="fiscal_position_id" position="attributes">
|
||||
<attribute name="widget">selection</attribute>
|
||||
@@ -38,9 +38,6 @@
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="state" position="after">
|
||||
<field name="is_shipped" invisible="not context.get('show_purchase', False)"/>
|
||||
</field>
|
||||
<!-- the 'origin' field can be very long ; it can list a lot of MO or OP!
|
||||
I think limiting the size of the field would not be the best option,
|
||||
because the info it carries can be interesting. So we just remove it from
|
||||
@@ -56,11 +53,6 @@
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.view_purchase_order_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter name="not_invoiced" position="before">
|
||||
<filter name="shipped" string="Fully Received" domain="[('is_shipped', '=', True)]"/>
|
||||
<filter name="not_shipped" string="Not Fully Received" domain="[('is_shipped', '=', False)]"/>
|
||||
<separator/>
|
||||
</filter>
|
||||
<field name="name" position="attributes">
|
||||
<attribute name="string">Reference or Origin</attribute>
|
||||
<attribute name="filter_domain">['|', ('name', 'ilike', self), ('origin', 'ilike', self)]</attribute>
|
||||
@@ -105,18 +97,7 @@
|
||||
|
||||
<!-- Do not show cancelled quotations by default in "Requests for Quotation" -->
|
||||
<record id="purchase.purchase_rfq" model="ir.actions.act_window">
|
||||
<field name="context">{'search_default_draft': 1, 'search_default_todo': 1}</field>
|
||||
</record>
|
||||
|
||||
<record id="purchase_order_line_form2" model="ir.ui.view">
|
||||
<field name="name">usability.purchase.order.line.form</field>
|
||||
<field name="model">purchase.order.line</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_line_form2"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="order_id" position="attributes">
|
||||
<attribute name="context">{'show_purchase': True}</attribute>
|
||||
</field>
|
||||
</field>
|
||||
<field name="context">{'search_default_draft': 1}</field>
|
||||
</record>
|
||||
|
||||
<record id="purchase_order_line_tree" model="ir.ui.view">
|
||||
@@ -180,42 +161,5 @@
|
||||
|
||||
<!-- The menu entry should be added in customer-specific module -->
|
||||
|
||||
<!-- in v10, the cart button is present on the product.template form view
|
||||
but not on the product.product form view
|
||||
In v8, it was present on both, so I put the cart button on the product.product form view too -->
|
||||
<record id="action_purchase_line_product_product_tree" model="ir.actions.act_window">
|
||||
<field name="name">Purchase Order Lines</field>
|
||||
<field name="res_model">purchase.order.line</field>
|
||||
<field name="view_id" ref="purchase_order_line_tree"/>
|
||||
<field name="domain">[('product_id','in',active_ids), ('state', 'in', ['purchase', 'done'])]</field>
|
||||
<field name="context">{}</field>
|
||||
</record>
|
||||
|
||||
<record id="view_product_normal_purchase_buttons_from" model="ir.ui.view">
|
||||
<field name="name">product.product.purchase.button.inherit</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="groups_id" eval="[(4, ref('purchase.group_purchase_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_inline oe_stat_button"
|
||||
name="%(action_purchase_line_product_product_tree)d"
|
||||
type="action" icon="fa-shopping-cart">
|
||||
<field string="Purchases" name="purchase_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_product_supplier_inherit" model="ir.ui.view">
|
||||
<field name="name">purchase_usability.product.template.form</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="purchase.view_product_supplier_inherit"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="purchase_method" position="attributes">
|
||||
<attribute name="groups"></attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user