Skip to content

Commit

Permalink
BAH-3852 | Validation pop up when confirming stock picking (#169)
Browse files Browse the repository at this point in the history
* BAH-3852 | Add. Model and view to show popup while doing stock moves

* BAH-3852 | Add. Security access to new model

* BAH-3852 | Refactor. Add subfolder for validation wizard in stock module

* BAH-3852 | Add. Handle display of validation pop up for stock receipt and internal transfer

* BAH-3852 | Refactor. Remove unused fields

* BAH-3852 | Refactor. Extract constants for picking codes
  • Loading branch information
mohan-13 authored May 21, 2024
1 parent cb90f2f commit 25d4256
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 9 deletions.
1 change: 1 addition & 0 deletions bahmni_stock/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from . import models
from . import report
from . import wizard
4 changes: 3 additions & 1 deletion bahmni_stock/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
'website': '',
'images': [],
'depends': ['stock', 'bahmni_product'],
'data': ['views/stock_production_lot_view.xml',
'data': ['security/ir.model.access.csv',
'views/stock_production_lot_view.xml',
'views/stock_picking_view.xml',
'views/account_invoice_line.xml',
'views/stock_pick_lot_view.xml',
'wizard/stock_picking_validate_wizard.xml',
],
'demo': [],
'qweb': [],
Expand Down
49 changes: 43 additions & 6 deletions bahmni_stock/models/stock_picking.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
# -*- coding: utf-8 -*-
from collections import namedtuple

from odoo import fields, models, api
from odoo import fields, models, api, _
from odoo.tools.float_utils import float_compare
from odoo.exceptions import UserError
from odoo.exceptions import UserError, ValidationError, AccessError, RedirectWarning

import logging

_logger = logging.getLogger(__name__)


class StockPicking(models.Model):
_inherit = 'stock.picking'
STOCK_PICKING_CODE_INTERNAL = 'internal'
STOCK_PICKING_CODE_INCOMING = 'incoming'
STOCK_PICKING_NAME_PURCHASE = 'Receipts'


def button_validate(self):
self.validate_batch_quantity_for_internal_transfer()
res = super(StockPicking, self).button_validate()
self.update_price_details_for_lots()
return res
if self._is_validation_needed():
return self.show_validation_screen()
else:
res = super(StockPicking, self).button_validate()
self.update_price_details_for_lots()
return res

def validate_batch_quantity_for_internal_transfer(self):
if self.picking_type_id and self.picking_type_id.code == 'internal':
if self.picking_type_id and self.picking_type_id.code == self.STOCK_PICKING_CODE_INTERNAL:
for line in self.move_line_ids:
if line.product_id.tracking != 'none':
stock_quant_lot = self.env['stock.quant'].search([
Expand All @@ -27,15 +38,41 @@ def validate_batch_quantity_for_internal_transfer(self):
raise UserError("Insufficient batch(%s) quantity for %s and available quantity is %s" \
%(line.lot_id.name, line.product_id.name, stock_quant_lot.quantity))

def show_validation_screen(self):
view_id = self.env.ref('bahmni_stock.stock_picking_validate_wizard_view').id
context = dict(self.env.context)
context.update({
'default_move_lines': [(6, 0, self.move_line_ids.filtered(lambda line: line.qty_done > 0).ids)],
'default_picking_id': self.id
})
return {
'name': _('Validate Stock Entries'),
'type': 'ir.actions.act_window',
'res_model': 'stock.picking.validate.wizard',
'view_mode': 'form',
'views': [(view_id, 'form')],
'view_id': view_id,
'target': 'new',
'context': context,
}
def update_price_details_for_lots(self):
if self.picking_type_id and self.picking_type_id.code == 'incoming' and self.picking_type_id.name == 'Receipts':
if self.picking_type_id and self.picking_type_id.code == self.STOCK_PICKING_CODE_INCOMING\
and self.picking_type_id.name == self.STOCK_PICKING_NAME_PURCHASE:
for line in self.move_line_ids:
if line.product_id.tracking != 'none':
line.lot_id.cost_price = line.cost_price
line.lot_id.sale_price = line.sale_price
line.lot_id.mrp = line.mrp
line.lot_id.expiration_date = line.expiration_date

def _is_validation_needed(self):
if self.env.context.get('validation_confirmed'):
return False
if self.picking_type_id.code in [self.STOCK_PICKING_CODE_INTERNAL, self.STOCK_PICKING_CODE_INCOMING]:
return True
return False


# this method is overridden to update cost_price, sale_price and mrp while lot is getting created
def _create_lots_for_picking(self):
Lot = self.env['stock.production.lot']
Expand Down
3 changes: 1 addition & 2 deletions bahmni_stock/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
stock_batch_future_forecast_user,Stock Batch Future Forecast Stock User,model_batch_stock_future_forecast,stock.group_stock_user,1,1,1,0
stock_report_prod_by_last_moved_user,Stock Report Products by Last Moved Stock User,model_prod_last_moved_report,stock.group_stock_user,1,1,1,0
access_stock_picking_validation,access_stock_picking_validation,model_stock_picking_validate_wizard,,1,1,1,1
1 change: 1 addition & 0 deletions bahmni_stock/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import stock_picking_validate_wizard
21 changes: 21 additions & 0 deletions bahmni_stock/wizard/stock_picking_validate_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from odoo import api, fields, models, _

import logging

_logger = logging.getLogger(__name__)


class StockPickingValidateWizard(models.TransientModel):
_name = 'stock.picking.validate.wizard'
_description = 'Validation Wizard for Stock Picking Operations'

move_lines = fields.Many2many('stock.move.line', readonly=True)
picking_id = fields.Many2one('stock.picking', 'Picking')
picking_code = fields.Selection(related='picking_id.picking_type_id.code', readonly=True)
source_location = fields.Many2one('stock.location', related='picking_id.location_id', string="Source Location",
readonly=True)
destination_location = fields.Many2one('stock.location', related='picking_id.location_dest_id',
string="Destination Location", readonly=True)

def btn_confirm(self):
return self.picking_id.with_context(validation_confirmed=True).button_validate()
54 changes: 54 additions & 0 deletions bahmni_stock/wizard/stock_picking_validate_wizard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="stock_picking_validate_wizard_view" model="ir.ui.view">
<field name="name">Validate Stock Picking</field>
<field name="model">stock.picking.validate.wizard</field>
<field name="arch" type="xml">
<form string="Validation">
<field name="picking_id" invisible="1"/>
<field name="picking_code" invisible="1"/>
<div class="row h3" attrs="{'invisible': [['picking_code', '!=', 'internal']]}">
<div class="col-sm">
<label for="source_location"/>
<field name="source_location"/>
</div>
<div class="col-sm">
<label for="destination_location"/>
<field name="destination_location"/>
</div>
</div>
<br/>
<field name="move_lines">
<tree string="Stock Move Lines">
<field name="product_id"/>
<field name="qty_done" string="Quantity"/>
<field name="balance" string="Balance Quantity"
attrs="{'column_invisible': [['parent.picking_code', '!=', 'internal']]}"/>
<field name="product_uom_id"/>
<field name="lot_id"
attrs="{'column_invisible': [['parent.picking_code', '!=', 'internal']]}"/>
<field name="lot_name" string="Lot/Serial Number"
attrs="{'column_invisible': [['parent.picking_code', '!=', 'incoming']]}"/>
<field name="expiration_date"
attrs="{'column_invisible': [['parent.picking_code', '!=', 'incoming']]}"/>/>
<field name="cost_price"
attrs="{'column_invisible': [['parent.picking_code', '!=', 'incoming']]}"/>
<field name="sale_price"
attrs="{'column_invisible': [['parent.picking_code', '!=', 'incoming']]}"/>
<field name="mrp" attrs="{'column_invisible': [['parent.picking_code', '!=', 'incoming']]}"/>
</tree>
</field>
<footer>
<button name="btn_confirm"
string="Confirm"
type="object"
data-hotkey="q"
class="btn-primary"/>
<button string="Discard"
class="btn-secondary"
special="cancel" data-hotkey="z"/>
</footer>
</form>
</field>
</record>
</odoo>

0 comments on commit 25d4256

Please sign in to comment.