Merge PR #1305 into 14.0

Signed-off-by rousseldenis
This commit is contained in:
OCA-git-bot
2022-04-29 07:17:29 +00:00
17 changed files with 281 additions and 0 deletions

View File

@@ -0,0 +1 @@
../../../../stock_exception

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)

View File

@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from . import models, wizard

View File

@@ -0,0 +1,20 @@
# Copyright 2021 Ecosoft Co., Ltd (https://ecosoft.co.th)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
{
"name": "Stock Exception",
"summary": "Custom exceptions on stock picking",
"version": "14.0.1.0.0",
"category": "Generic Modules/Warehouse Management",
"author": "Ecosoft, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/stock-logistics-warehouse",
"depends": ["stock", "base_exception"],
"license": "AGPL-3",
"data": [
"security/ir.model.access.csv",
"data/stock_exception_data.xml",
"wizard/stock_exception_confirm_view.xml",
"views/stock_view.xml",
],
"installable": True,
}

View File

@@ -0,0 +1,33 @@
<odoo noupdate="1">
<!-- Test Stock Exceptions Scheduler-->
<record model="ir.cron" forcecreate="True" id="ir_cron_test_stock_picking_except">
<field name="name">Stock: Test Draft Pickings Exception</field>
<field name="model_id" ref="stock.model_stock_picking" />
<field name="state">code</field>
<field name="code">model.test_all_draft_pickings()</field>
<field name="user_id" ref="base.user_root" />
<field name="interval_number">20</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False" />
<field name="active" eval="False" />
</record>
<record id="sp_excep_no_partner" model="exception.rule">
<field name="name">No Partner</field>
<field name="description">No Partner</field>
<field name="sequence">50</field>
<field name="model">stock.picking</field>
<field name="code">if not self.partner_id:
failed=True</field>
<field name="active" eval="False" />
</record>
<record id="sm_excep_product_uom_qty_check" model="exception.rule">
<field name="name">Demand Quantity not positive</field>
<field name="description">Demand quantity must be positive</field>
<field name="sequence">50</field>
<field name="model">stock.move</field>
<field name="code">if self.product_uom_qty &lt;= 0:
failed=True</field>
<field name="active" eval="False" />
</record>
</odoo>

View File

@@ -0,0 +1,5 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from . import exception_rule
from . import stock
from . import stock_move

View File

@@ -0,0 +1,17 @@
# Copyright 2021 Ecosoft Co., Ltd (https://ecosoft.co.th)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from odoo import fields, models
class ExceptionRule(models.Model):
_inherit = "exception.rule"
picking_ids = fields.Many2many(comodel_name="stock.picking", string="Pickings")
model = fields.Selection(
selection_add=[
("stock.picking", "Stock Picking"),
("stock.move", "Stock Move"),
],
ondelete={"stock.picking": "cascade", "stock.move": "cascade"},
)

View File

@@ -0,0 +1,49 @@
# Copyright 2021 Ecosoft Co., Ltd (https://ecosoft.co.th)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from odoo import api, models
class StockPicking(models.Model):
_inherit = ["stock.picking", "base.exception"]
_name = "stock.picking"
_order = "main_exception_id asc, priority desc, scheduled_date asc, id desc"
@api.model
def test_all_draft_pickings(self):
picking_set = self.search([("state", "=", "draft")])
picking_set.detect_exceptions()
return True
@api.model
def _reverse_field(self):
return "picking_ids"
def detect_exceptions(self):
all_exceptions = super().detect_exceptions()
moves = self.mapped("move_lines")
all_exceptions += moves.detect_exceptions()
return all_exceptions
@api.constrains("ignore_exception", "move_lines", "state")
def stock_check_exception(self):
pickings = self.filtered(
lambda s: s.state in ["waiting", "confirmed", "assigned"]
)
if pickings:
pickings._check_exception()
@api.onchange("move_lines")
def onchange_ignore_exception(self):
if self.state in ["waiting", "confirmed", "assigned"]:
self.ignore_exception = False
def action_confirm(self):
if self.detect_exceptions() and not self.ignore_exception:
return self._popup_exceptions()
return super().action_confirm()
@api.model
def _get_popup_action(self):
action = self.env.ref("stock_exception.action_stock_exception_confirm")
return action

View File

@@ -0,0 +1,24 @@
# Copyright 2021 Ecosoft Co., Ltd (https://ecosoft.co.th)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from odoo import api, fields, models
class StockMove(models.Model):
_inherit = ["stock.move", "base.exception.method"]
_name = "stock.move"
ignore_exception = fields.Boolean(
related="picking_id.ignore_exception", store=True, string="Ignore Exceptions"
)
def _get_main_records(self):
return self.mapped("picking_id")
@api.model
def _reverse_field(self):
return "picking_ids"
def _detect_exceptions(self, rule):
records = super()._detect_exceptions(rule)
return records.mapped("picking_id")

View File

@@ -0,0 +1 @@
* Tharathip Chaweewongphan <tharathipc@ecosoft.co.th>

View File

@@ -0,0 +1,6 @@
This module allows you attach several customizable exceptions to your
stock picking in a way that you can filter pickings by exceptions type and fix them.
This is especially useful in an scenario for mass stock picking import, because it's likely some pickings have
errors when you import them (like product not found in Odoo, wrong line
format etc.)

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_stock_exception_confirm,access_stock_exception_confirm,model_stock_exception_confirm,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_stock_exception_confirm access_stock_exception_confirm model_stock_exception_confirm base.group_user 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,82 @@
<odoo>
<record id="action_stock_test_tree" model="ir.actions.act_window">
<field name="name">Stock Exception Rules</field>
<field name="res_model">exception.rule</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="base_exception.view_exception_rule_tree" />
<field
name="domain"
>[('model', 'in', ['stock.picking', 'stock.move', 'stock.move.line'])]</field>
<field
name="context"
>{'active_test': False, 'default_model' : 'stock.picking'}</field>
</record>
<menuitem
action="action_stock_test_tree"
id="menu_stock_test"
parent="stock.menu_stock_config_settings"
/>
<record id="view_picking_form" model="ir.ui.view">
<field name="name">stock_exception.view_picking_form</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form" />
<field name="arch" type="xml">
<sheet position="before">
<div
class="alert alert-danger"
role="alert"
style="margin-bottom:0px;"
attrs="{'invisible': [('exceptions_summary','=',False)]}"
>
<p>
<strong
>There are exceptions blocking this stock picking:</strong>
</p>
<field name="exceptions_summary" />
<button
name="action_ignore_exceptions"
type="object"
class="btn-danger"
string="Ignore Exceptions"
help="Click here to be able to confirm this stock picking regardless of the exceptions."
groups="base_exception.group_exception_rule_manager"
/>
</div>
</sheet>
<xpath expr="//field[@name='date_deadline']/.." position="inside">
<field
name="ignore_exception"
states="waiting,confirmed,assigned"
groups='base_exception.group_exception_rule_manager'
/>
<field name="exception_ids" widget="many2many_tags" readonly="True" />
</xpath>
</field>
</record>
<record id="vpicktree" model="ir.ui.view">
<field name="name">stock_exception.vpicktree</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.vpicktree" />
<field name="arch" type="xml">
<field name="state" position="after">
<field name="main_exception_id" />
</field>
</field>
</record>
<record id="view_picking_internal_search" model="ir.ui.view">
<field name="name">stock_exception.view_picking_internal_search</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_internal_search" />
<field name="arch" type="xml">
<filter name="activities_exception" position="after">
<separator orientation="vertical" />
<filter
icon="fa-exclamation-circle"
name="tofix"
string="Blocked in Draft"
domain="[('main_exception_id','!=',False)]"
/>
</filter>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from . import stock_exception_confirm

View File

@@ -0,0 +1,19 @@
# Copyright 2021 Ecosoft Co., Ltd (https://ecosoft.co.th)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
from odoo import fields, models
class StockExceptionConfirm(models.TransientModel):
_name = "stock.exception.confirm"
_description = "Stock exception wizard"
_inherit = ["exception.rule.confirm"]
related_model_id = fields.Many2one("stock.picking", "Stock Picking")
def action_confirm(self):
self.ensure_one()
if self.ignore:
self.related_model_id.ignore_exception = True
self.related_model_id.action_confirm()
return super().action_confirm()

View File

@@ -0,0 +1,10 @@
<odoo>
<record id="action_stock_exception_confirm" model="ir.actions.act_window">
<field name="name">Outstanding exceptions to manage</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.exception.confirm</field>
<field name="view_mode">form</field>
<field name="view_id" ref="base_exception.view_exception_rule_confirm" />
<field name="target">new</field>
</record>
</odoo>