Compare commits
13 Commits
14.0-impro
...
14.0-add-o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bfde2e346 | ||
|
|
de2e5f2121 | ||
|
|
42e014bcb1 | ||
|
|
e70e3b23cf | ||
|
|
50b4944c8b | ||
|
|
96bfda6e1b | ||
|
|
cfb58ed80f | ||
|
|
91e9c1fe33 | ||
|
|
dff4e47cf5 | ||
|
|
452cc399c5 | ||
|
|
f4c22501a7 | ||
|
|
9e8874eb4b | ||
|
|
fc6c0384ed |
@@ -5,6 +5,7 @@
|
|||||||
from odoo import api, fields, models
|
from odoo import api, fields, models
|
||||||
from odoo.tools import float_is_zero
|
from odoo.tools import float_is_zero
|
||||||
from odoo.tools.misc import format_date
|
from odoo.tools.misc import format_date
|
||||||
|
from odoo.osv import expression
|
||||||
|
|
||||||
|
|
||||||
class AccountMove(models.Model):
|
class AccountMove(models.Model):
|
||||||
@@ -49,11 +50,11 @@ class AccountMove(models.Model):
|
|||||||
def _compute_has_attachment(self):
|
def _compute_has_attachment(self):
|
||||||
iao = self.env['ir.attachment']
|
iao = self.env['ir.attachment']
|
||||||
for move in self:
|
for move in self:
|
||||||
if iao.search([
|
if iao.search_count([
|
||||||
('res_model', '=', 'account.move'),
|
('res_model', '=', 'account.move'),
|
||||||
('res_id', '=', move.id),
|
('res_id', '=', move.id),
|
||||||
('type', '=', 'binary'),
|
('type', '=', 'binary'),
|
||||||
('company_id', '=', move.company_id.id)], limit=1):
|
('company_id', '=', move.company_id.id)]):
|
||||||
move.has_attachment = True
|
move.has_attachment = True
|
||||||
else:
|
else:
|
||||||
move.has_attachment = False
|
move.has_attachment = False
|
||||||
@@ -157,6 +158,24 @@ class AccountMove(models.Model):
|
|||||||
for x in sales]
|
for x in sales]
|
||||||
inv.sale_dates = ", ".join(dates)
|
inv.sale_dates = ", ".join(dates)
|
||||||
|
|
||||||
|
# allow to manually create moves not only in general journals,
|
||||||
|
# but also in cash journal and check journals (= bank journals not linked to a bank account)
|
||||||
|
@api.depends('company_id', 'invoice_filter_type_domain')
|
||||||
|
def _compute_suitable_journal_ids(self):
|
||||||
|
for move in self:
|
||||||
|
if move.invoice_filter_type_domain:
|
||||||
|
super(AccountMove, move)._compute_suitable_journal_ids()
|
||||||
|
else:
|
||||||
|
company_id = move.company_id.id or self.env.company.id
|
||||||
|
domain = expression.AND([
|
||||||
|
[('company_id', '=', company_id)],
|
||||||
|
expression.OR([
|
||||||
|
[('type', 'in', ('general', 'cash'))],
|
||||||
|
[('type', '=', 'bank'), ('bank_account_id', '=', False)]
|
||||||
|
])
|
||||||
|
])
|
||||||
|
move.suitable_journal_ids = self.env['account.journal'].search(domain)
|
||||||
|
|
||||||
|
|
||||||
class AccountMoveLine(models.Model):
|
class AccountMoveLine(models.Model):
|
||||||
_inherit = 'account.move.line'
|
_inherit = 'account.move.line'
|
||||||
@@ -176,6 +195,8 @@ class AccountMoveLine(models.Model):
|
|||||||
matched_credit_ids = fields.One2many(string='Partial Reconcile Credit')
|
matched_credit_ids = fields.One2many(string='Partial Reconcile Credit')
|
||||||
reconcile_string = fields.Char(
|
reconcile_string = fields.Char(
|
||||||
compute='_compute_reconcile_string', string='Reconcile', store=True)
|
compute='_compute_reconcile_string', string='Reconcile', store=True)
|
||||||
|
# for optional display in tree view
|
||||||
|
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
|
||||||
|
|
||||||
def show_account_move_form(self):
|
def show_account_move_form(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
|
|||||||
@@ -30,6 +30,9 @@
|
|||||||
<field name="matching_number" optional="hide"/>
|
<field name="matching_number" optional="hide"/>
|
||||||
<field name="reconcile_string" optional="show"/>
|
<field name="reconcile_string" optional="show"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='product_id']" position="after">
|
||||||
|
<field name="product_barcode" optional="hide"/>
|
||||||
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
@@ -58,6 +61,36 @@
|
|||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="view_account_move_line_filter" model="ir.ui.view">
|
||||||
|
<field name="name">account_usability.account_move_line_search</field>
|
||||||
|
<field name="model">account.move.line</field>
|
||||||
|
<field name="inherit_id" ref="account.view_account_move_line_filter"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<filter name="unposted" position="before">
|
||||||
|
<filter name="current_year" string="Current Year" domain="[('date', '>=', (context_today().strftime('%Y-01-01'))), ('date', '<=', (context_today().strftime('%Y-12-31')))]"/>
|
||||||
|
<filter name="previous_year" string="Previous Year" domain="[('date', '>=', (context_today() + relativedelta(day=1, month=1, years=-1)).strftime('%Y-%m-%d')), ('date', '<=', (context_today() + relativedelta(day=31, month=12, years=-1)).strftime('%Y-%m-%d'))]"/>
|
||||||
|
<separator/>
|
||||||
|
</filter>
|
||||||
|
<field name="partner_id" position="after">
|
||||||
|
<field name="reconcile_string" />
|
||||||
|
<field name="debit" filter_domain="['|', ('debit', '=', self), ('credit', '=', self)]" string="Debit or Credit"/>
|
||||||
|
</field>
|
||||||
|
<filter name="unreconciled" position="before">
|
||||||
|
<filter name="reconciled" string="Fully Reconciled" domain="[('full_reconcile_id', '!=', False)]"/>
|
||||||
|
</filter>
|
||||||
|
<filter name="unreconciled" position="attributes">
|
||||||
|
<attribute name="string">Unreconciled or Partially Reconciled</attribute>
|
||||||
|
</filter>
|
||||||
|
<!--
|
||||||
|
<field name="name" position="attributes">
|
||||||
|
<attribute name="string">Name or Reference</attribute>
|
||||||
|
</field> -->
|
||||||
|
<field name="partner_id" position="attributes">
|
||||||
|
<attribute name="domain">['|', ('parent_id', '=', False), ('is_company', '=', True)]</attribute>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
<record id="account.action_move_journal_line" model="ir.actions.act_window">
|
<record id="account.action_move_journal_line" model="ir.actions.act_window">
|
||||||
<field name="context">{'default_move_type': 'entry', 'view_no_maturity': True}</field>
|
<field name="context">{'default_move_type': 'entry', 'view_no_maturity': True}</field>
|
||||||
<!-- Remove 'search_default_misc_filter': 1 -->
|
<!-- Remove 'search_default_misc_filter': 1 -->
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
'summary': 'Better usability in base module',
|
'summary': 'Better usability in base module',
|
||||||
'author': 'Akretion',
|
'author': 'Akretion',
|
||||||
'website': 'http://www.akretion.com',
|
'website': 'http://www.akretion.com',
|
||||||
'depends': ['base'],
|
'depends': ['base', 'contacts'],
|
||||||
'data': [
|
'data': [
|
||||||
'security/group.xml',
|
'security/group.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
|
|||||||
@@ -16,6 +16,19 @@
|
|||||||
<xpath expr="//field[@name='child_ids']/form//field[@name='title']" position="attributes">
|
<xpath expr="//field[@name='child_ids']/form//field[@name='title']" position="attributes">
|
||||||
<attribute name="attrs"></attribute>
|
<attribute name="attrs"></attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<!-- Show double VAT partner even when not in editable mode -->
|
||||||
|
<div attrs="{'invisible': [('same_vat_partner_id', '=', False)]}" position="attributes">
|
||||||
|
<attribute name="class">alert alert-warning</attribute>
|
||||||
|
</div>
|
||||||
|
<!-- Add a kanban button to open child partner -->
|
||||||
|
<xpath expr="//field[@name='child_ids']//kanban/templates/t/div" position="inside">
|
||||||
|
<div class="o_dropdown_kanban">
|
||||||
|
<a class="btn" role="button" title="Open"
|
||||||
|
t-att-href="'/web#id=' + record.id.raw_value + '&action=%(contacts.action_contacts)d' + '&menu_id=%(contacts.menu_contacts)d' + '&view_type=form&cids=1&model=res.partner'">
|
||||||
|
<span class="fa fa-external-link" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
|
|||||||
'views/product_pricelist_item.xml',
|
'views/product_pricelist_item.xml',
|
||||||
'views/product_template_view.xml',
|
'views/product_template_view.xml',
|
||||||
'views/product_product.xml',
|
'views/product_product.xml',
|
||||||
'views/product_category_view.xml',
|
|
||||||
],
|
],
|
||||||
'installable': True,
|
'installable': True,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,3 @@ from . import product_product
|
|||||||
from . import product_template
|
from . import product_template
|
||||||
from . import product_supplierinfo
|
from . import product_supplierinfo
|
||||||
from . import product_pricelist
|
from . import product_pricelist
|
||||||
from . import product_category
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Copyright 2022 Akretion (https://www.akretion.com).
|
|
||||||
# @author Sébastien BEAU <sebastien.beau@akretion.com>
|
|
||||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
||||||
|
|
||||||
from odoo import fields, models
|
|
||||||
|
|
||||||
|
|
||||||
class ProductCategory(models.Model):
|
|
||||||
_inherit = ['product.category', "mail.thread", "mail.activity.mixin"]
|
|
||||||
_name = 'product.category'
|
|
||||||
|
|
||||||
name = fields.Char(tracking=10)
|
|
||||||
parent_id = fields.Many2one(tracking=20)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<odoo>
|
|
||||||
|
|
||||||
<record id="product_category_form_view" model="ir.ui.view">
|
|
||||||
<field name="model">product.category</field>
|
|
||||||
<field name="inherit_id" ref="product.product_category_form_view" />
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
<sheet position="after">
|
|
||||||
<div class="oe_chatter">
|
|
||||||
<field name="message_follower_ids"/>
|
|
||||||
<field name="activity_ids"/>
|
|
||||||
<field name="message_ids"/>
|
|
||||||
</div>
|
|
||||||
</sheet>
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
|
|
||||||
</odoo>
|
|
||||||
|
|
||||||
@@ -71,3 +71,10 @@ class PurchaseOrder(models.Model):
|
|||||||
# {'subtotal': 8932.23},
|
# {'subtotal': 8932.23},
|
||||||
# ]
|
# ]
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
class PurchaseOrderLine(models.Model):
|
||||||
|
_inherit = 'purchase.order.line'
|
||||||
|
|
||||||
|
# for optional display in tree view
|
||||||
|
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
|
||||||
|
|||||||
@@ -34,6 +34,9 @@
|
|||||||
<xpath expr="//field[@name='order_line']/form//field[@name='analytic_tag_ids']" position="attributes">
|
<xpath expr="//field[@name='order_line']/form//field[@name='analytic_tag_ids']" position="attributes">
|
||||||
<attribute name="groups">analytic.group_analytic_tags</attribute>
|
<attribute name="groups">analytic.group_analytic_tags</attribute>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="after">
|
||||||
|
<field name="product_barcode" optional="hide"/>
|
||||||
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ class SaleOrder(models.Model):
|
|||||||
fiscal_position_id = fields.Many2one(tracking=True)
|
fiscal_position_id = fields.Many2one(tracking=True)
|
||||||
# for reports
|
# for reports
|
||||||
has_discount = fields.Boolean(compute='_compute_has_discount')
|
has_discount = fields.Boolean(compute='_compute_has_discount')
|
||||||
|
has_attachment = fields.Boolean(
|
||||||
|
compute='_compute_has_attachment',
|
||||||
|
search='_search_has_attachment')
|
||||||
|
|
||||||
@api.depends('order_line.discount')
|
@api.depends('order_line.discount')
|
||||||
def _compute_has_discount(self):
|
def _compute_has_discount(self):
|
||||||
@@ -34,6 +37,30 @@ class SaleOrder(models.Model):
|
|||||||
break
|
break
|
||||||
order.has_discount = has_discount
|
order.has_discount = has_discount
|
||||||
|
|
||||||
|
def _compute_has_attachment(self):
|
||||||
|
iao = self.env['ir.attachment']
|
||||||
|
for order in self:
|
||||||
|
if iao.search_count([
|
||||||
|
('res_model', '=', 'sale.order'),
|
||||||
|
('res_id', '=', order.id),
|
||||||
|
('type', '=', 'binary'),
|
||||||
|
('company_id', '=', order.company_id.id)]):
|
||||||
|
order.has_attachment = True
|
||||||
|
else:
|
||||||
|
order.has_attachment = False
|
||||||
|
|
||||||
|
def _search_has_attachment(self, operator, value):
|
||||||
|
att_order_ids = {}
|
||||||
|
if operator == '=':
|
||||||
|
search_res = self.env['ir.attachment'].search_read([
|
||||||
|
('res_model', '=', 'sale.order'),
|
||||||
|
('type', '=', 'binary'),
|
||||||
|
('res_id', '!=', False)], ['res_id'])
|
||||||
|
for att in search_res:
|
||||||
|
att_order_ids[att['res_id']] = True
|
||||||
|
res = [('id', value and 'in' or 'not in', list(att_order_ids))]
|
||||||
|
return res
|
||||||
|
|
||||||
# for report
|
# for report
|
||||||
def py3o_lines_layout(self):
|
def py3o_lines_layout(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
@@ -66,6 +93,10 @@ class SaleOrder(models.Model):
|
|||||||
class SaleOrderLine(models.Model):
|
class SaleOrderLine(models.Model):
|
||||||
_inherit = 'sale.order.line'
|
_inherit = 'sale.order.line'
|
||||||
|
|
||||||
|
# for optional display in tree view
|
||||||
|
product_barcode = fields.Char(
|
||||||
|
related='product_id.barcode', string="Product Barcode")
|
||||||
|
|
||||||
@api.onchange('product_uom', 'product_uom_qty')
|
@api.onchange('product_uom', 'product_uom_qty')
|
||||||
def product_uom_change(self):
|
def product_uom_change(self):
|
||||||
# When the user has manually set a custom price
|
# When the user has manually set a custom price
|
||||||
|
|||||||
@@ -26,6 +26,9 @@
|
|||||||
<field name="date_order" position="after">
|
<field name="date_order" position="after">
|
||||||
<field name="client_order_ref"/>
|
<field name="client_order_ref"/>
|
||||||
</field>
|
</field>
|
||||||
|
<xpath expr="//field[@name='order_line']/tree/field[@name='product_template_id']" position="after">
|
||||||
|
<field name="product_barcode" optional="hide"/>
|
||||||
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
@@ -62,6 +65,10 @@
|
|||||||
<filter name="order_month" position="after">
|
<filter name="order_month" position="after">
|
||||||
<filter string="State" name="state_groupby" context="{'group_by': 'state'}"/>
|
<filter string="State" name="state_groupby" context="{'group_by': 'state'}"/>
|
||||||
</filter>
|
</filter>
|
||||||
|
<filter name="activities_upcoming_all" position="after">
|
||||||
|
<separator/>
|
||||||
|
<filter name="no_attachment" string="Missing Attachment" domain="[('has_attachment', '=', False)]"/>
|
||||||
|
</filter>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Copyright 2019-2020 Akretion France (http://www.akretion.com)
|
# Copyright 2019-2021 Akretion France (http://www.akretion.com)
|
||||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
@@ -15,14 +15,13 @@ Stock Account Usability
|
|||||||
|
|
||||||
The usability enhancements include:
|
The usability enhancements include:
|
||||||
|
|
||||||
NONE
|
- show to_refund on stock.move form view
|
||||||
|
|
||||||
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
This module has been written by Alexis de Lattre from Akretion <alexis.delattre@akretion.com>.
|
||||||
""",
|
""",
|
||||||
'author': 'Akretion',
|
'author': 'Akretion',
|
||||||
'website': 'http://www.akretion.com',
|
'website': 'http://www.akretion.com',
|
||||||
'depends': ['stock_account'],
|
'depends': ['stock_account', 'stock_usability'],
|
||||||
'data': [
|
'data': ['views/stock_move.xml'],
|
||||||
],
|
'installable': True,
|
||||||
'installable': False,
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
stock_account_usability/views/stock_move.xml
Normal file
23
stock_account_usability/views/stock_move.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2021 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).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
|
||||||
|
<record id="view_move_form" model="ir.ui.view">
|
||||||
|
<field name="name">stock_account_usability.stock.move.form</field>
|
||||||
|
<field name="model">stock.move</field>
|
||||||
|
<field name="inherit_id" ref="stock_usability.view_move_form" />
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="price_unit" position="after">
|
||||||
|
<field name="to_refund" readonly="1"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
from . import stock_return_picking
|
|
||||||
from . import stock_quantity_history
|
|
||||||
@@ -1 +1,2 @@
|
|||||||
from . import models
|
from . import models
|
||||||
|
from .post_install import create_config_parameter_immediate_tranfer
|
||||||
|
|||||||
@@ -38,5 +38,6 @@ This module has been written by Alexis de Lattre from Akretion <alexis.delattre@
|
|||||||
'views/procurement_scheduler_log.xml',
|
'views/procurement_scheduler_log.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
],
|
],
|
||||||
|
'post_init_hook': 'create_config_parameter_immediate_tranfer',
|
||||||
'installable': True,
|
'installable': True,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ from . import stock_warehouse_orderpoint
|
|||||||
from . import stock_quant
|
from . import stock_quant
|
||||||
from . import procurement_group
|
from . import procurement_group
|
||||||
from . import procurement_scheduler_log
|
from . import procurement_scheduler_log
|
||||||
from . import product_template
|
from . import product
|
||||||
from . import res_partner
|
from . import res_partner
|
||||||
|
|||||||
31
stock_usability/models/product.py
Normal file
31
stock_usability/models/product.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Copyright 2016-2021 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 fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ProductTemplate(models.Model):
|
||||||
|
_inherit = 'product.template'
|
||||||
|
|
||||||
|
tracking = fields.Selection(tracking=True)
|
||||||
|
sale_delay = fields.Float(tracking=True)
|
||||||
|
# the 'stock' module adds 'product' in type...
|
||||||
|
# but forgets to make it the default
|
||||||
|
type = fields.Selection(default='product')
|
||||||
|
|
||||||
|
def action_view_stock_move(self):
|
||||||
|
action = self.env.ref('stock.stock_move_action').sudo().read()[0]
|
||||||
|
action['domain'] = [('product_id.product_tmpl_id', 'in', self.ids)]
|
||||||
|
action['context'] = {'search_default_done': True}
|
||||||
|
return action
|
||||||
|
|
||||||
|
|
||||||
|
class ProductProduct(models.Model):
|
||||||
|
_inherit = 'product.product'
|
||||||
|
|
||||||
|
def action_view_stock_move(self):
|
||||||
|
action = self.env.ref('stock.stock_move_action').sudo().read()[0]
|
||||||
|
action['domain'] = [('product_id', 'in', self.ids)]
|
||||||
|
action['context'] = {'search_default_done': True}
|
||||||
|
return action
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
# Copyright 2016-2020 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 fields, models
|
|
||||||
|
|
||||||
|
|
||||||
class ProductTemplate(models.Model):
|
|
||||||
_inherit = 'product.template'
|
|
||||||
|
|
||||||
tracking = fields.Selection(tracking=True)
|
|
||||||
sale_delay = fields.Float(tracking=True)
|
|
||||||
# the 'stock' module adds 'product' in type...
|
|
||||||
# but forgets to make it the default
|
|
||||||
type = fields.Selection(default='product')
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import models, _
|
from odoo import fields, models, _
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -12,6 +12,9 @@ logger = logging.getLogger(__name__)
|
|||||||
class StockMove(models.Model):
|
class StockMove(models.Model):
|
||||||
_inherit = 'stock.move'
|
_inherit = 'stock.move'
|
||||||
|
|
||||||
|
# for optional display in tree view
|
||||||
|
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
|
||||||
|
|
||||||
# def name_get(self):
|
# def name_get(self):
|
||||||
# '''name_get of stock_move is important for the reservation of the
|
# '''name_get of stock_move is important for the reservation of the
|
||||||
# quants: so want to add the name of the customer and the expected date
|
# quants: so want to add the name of the customer and the expected date
|
||||||
@@ -37,7 +40,7 @@ class StockMove(models.Model):
|
|||||||
picking = move.picking_id
|
picking = move.picking_id
|
||||||
if picking:
|
if picking:
|
||||||
product = move.product_id
|
product = move.product_id
|
||||||
picking.message_post(_(
|
picking.message_post(body=_(
|
||||||
"Product <a href=# data-oe-model=product.product "
|
"Product <a href=# data-oe-model=product.product "
|
||||||
"data-oe-id=%d>%s</a> qty %s %s <b>unreserved</b>")
|
"data-oe-id=%d>%s</a> qty %s %s <b>unreserved</b>")
|
||||||
% (product.id, product.display_name,
|
% (product.id, product.display_name,
|
||||||
@@ -49,6 +52,9 @@ class StockMove(models.Model):
|
|||||||
class StockMoveLine(models.Model):
|
class StockMoveLine(models.Model):
|
||||||
_inherit = 'stock.move.line'
|
_inherit = 'stock.move.line'
|
||||||
|
|
||||||
|
# for optional display in tree view
|
||||||
|
product_barcode = fields.Char(related='product_id.barcode', string="Product Barcode")
|
||||||
|
|
||||||
# TODO: I think it's not complete
|
# TODO: I think it's not complete
|
||||||
def button_do_unreserve(self):
|
def button_do_unreserve(self):
|
||||||
for moveline in self:
|
for moveline in self:
|
||||||
@@ -60,7 +66,7 @@ class StockMoveLine(models.Model):
|
|||||||
picking = moveline.move_id.picking_id
|
picking = moveline.move_id.picking_id
|
||||||
if picking:
|
if picking:
|
||||||
product = moveline.product_id
|
product = moveline.product_id
|
||||||
picking.message_post(_(
|
picking.message_post(body=_(
|
||||||
"Product <a href=# data-oe-model=product.product "
|
"Product <a href=# data-oe-model=product.product "
|
||||||
"data-oe-id=%d>%s</a> qty %s %s <b>unreserved</b>")
|
"data-oe-id=%d>%s</a> qty %s %s <b>unreserved</b>")
|
||||||
% (product.id, product.display_name,
|
% (product.id, product.display_name,
|
||||||
|
|||||||
26
stock_usability/post_install.py
Normal file
26
stock_usability/post_install.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Copyright 2021 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).
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from odoo import SUPERUSER_ID, api
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def create_config_parameter_immediate_tranfer(cr, registry):
|
||||||
|
with api.Environment.manage():
|
||||||
|
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||||
|
ico = env["ir.config_parameter"]
|
||||||
|
conf_param = ico.search([('key', '=', 'stock.no_default_immediate_tranfer')])
|
||||||
|
if not conf_param:
|
||||||
|
ico.create({
|
||||||
|
'key': 'stock.no_default_immediate_tranfer',
|
||||||
|
'value': 'True',
|
||||||
|
})
|
||||||
|
logger.info(
|
||||||
|
'ir.config_parameter stock.no_default_immediate_tranfer created')
|
||||||
|
else:
|
||||||
|
logger.info(
|
||||||
|
'ir.config_parameter stock.no_default_immediate_tranfer '
|
||||||
|
'already exists')
|
||||||
@@ -19,5 +19,38 @@
|
|||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record id="product_template_form_view_procurement_button" model="ir.ui.view">
|
||||||
|
<field name="name">stock_usability.product.template.form</field>
|
||||||
|
<field name="model">product.template</field>
|
||||||
|
<field name="inherit_id" ref="stock.product_template_form_view_procurement_button"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<button name="action_view_stock_move_lines" position="before">
|
||||||
|
<button string="Stock Moves"
|
||||||
|
type="object"
|
||||||
|
name= "action_view_stock_move"
|
||||||
|
attrs="{'invisible': [('type', 'not in', ('product', 'consu'))]}"
|
||||||
|
groups="stock.group_stock_user"
|
||||||
|
class="oe_stat_button" icon="fa-exchange"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="product_form_view_procurement_button" model="ir.ui.view">
|
||||||
|
<field name="name">stock_usability.product.product.form</field>
|
||||||
|
<field name="model">product.product</field>
|
||||||
|
<field name="inherit_id" ref="stock.product_form_view_procurement_button"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<button name="action_view_stock_move_lines" position="before">
|
||||||
|
<button string="Stock Moves"
|
||||||
|
type="object"
|
||||||
|
name= "action_view_stock_move"
|
||||||
|
attrs="{'invisible': [('type', 'not in', ('product', 'consu'))]}"
|
||||||
|
groups="stock.group_stock_user"
|
||||||
|
class="oe_stat_button" icon="fa-exchange"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -21,6 +21,9 @@
|
|||||||
<attribute name="decoration-info">product_qty > theoretical_qty</attribute>
|
<attribute name="decoration-info">product_qty > theoretical_qty</attribute>
|
||||||
<attribute name="decoration-danger">product_qty < theoretical_qty</attribute>
|
<attribute name="decoration-danger">product_qty < theoretical_qty</attribute>
|
||||||
</tree>
|
</tree>
|
||||||
|
<field name="location_id" position="attributes">
|
||||||
|
<attribute name="invisible">0</attribute>
|
||||||
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,9 @@
|
|||||||
states="partially_available,assigned"
|
states="partially_available,assigned"
|
||||||
icon="fa-ban"/>
|
icon="fa-ban"/>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="product_id" position="after">
|
||||||
|
<field name="product_barcode" optional="hide"/>
|
||||||
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
@@ -78,6 +81,20 @@
|
|||||||
states="partially_available,assigned"
|
states="partially_available,assigned"
|
||||||
icon="fa-ban"/>
|
icon="fa-ban"/>
|
||||||
</field>
|
</field>
|
||||||
|
<field name="product_id" position="after">
|
||||||
|
<field name="product_barcode" optional="hide"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- View embedded in picking -->
|
||||||
|
<record id="view_stock_move_line_detailed_operation_tree" model="ir.ui.view">
|
||||||
|
<field name="model">stock.move.line</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_stock_move_line_detailed_operation_tree" />
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="product_id" position="after">
|
||||||
|
<field name="product_barcode" optional="hide"/>
|
||||||
|
</field>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -30,9 +30,12 @@
|
|||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='location_id']" position="replace"/>
|
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='location_id']" position="replace"/>
|
||||||
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='location_dest_id']" position="replace"/>
|
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='location_dest_id']" position="replace"/>
|
||||||
|
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='name']" position="replace"/>
|
||||||
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='product_id']" position="after">
|
<xpath expr="//field[@name='move_ids_without_package']/tree/field[@name='product_id']" position="after">
|
||||||
<field name="location_id" groups="stock.group_stock_multi_locations"/>
|
<field name="product_barcode" optional="hide"/>
|
||||||
<field name="location_dest_id" groups="stock.group_stock_multi_locations"/>
|
<field name="name" optional="hide"/>
|
||||||
|
<field name="location_id" groups="stock.group_stock_multi_locations" optional="show"/>
|
||||||
|
<field name="location_dest_id" groups="stock.group_stock_multi_locations" optional="show"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='move_ids_without_package']/tree/button[@name='action_assign_serial']" position="after">
|
<xpath expr="//field[@name='move_ids_without_package']/tree/button[@name='action_assign_serial']" position="after">
|
||||||
<button type="object" name="button_do_unreserve" string="Unreserve"
|
<button type="object" name="button_do_unreserve" string="Unreserve"
|
||||||
@@ -40,15 +43,6 @@
|
|||||||
states="partially_available,assigned"
|
states="partially_available,assigned"
|
||||||
icon="fa-ban"/>
|
icon="fa-ban"/>
|
||||||
</xpath>
|
</xpath>
|
||||||
<!-- STOCK MOVE LINE -->
|
|
||||||
<!--
|
|
||||||
<xpath expr="//field[@name='move_line_ids_without_package']/tree/field[@name='location_id']" position="attributes">
|
|
||||||
<attribute name="attrs">{}</attribute>
|
|
||||||
</xpath>
|
|
||||||
<xpath expr="//field[@name='move_line_ids_without_package']/tree/field[@name='location_dest_id']" position="attributes">
|
|
||||||
<attribute name="attrs">{}</attribute>
|
|
||||||
</xpath>
|
|
||||||
-->
|
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user