[IMP] stock: Update quantity on hand inventory adjustment

When the update quantity on hand is clicked on a product tracked by lot
or serial number or if the database is in multi location, the button
update quantity on hand will open an inventory adjustment to allow you
to add multiple lot/serial number and/or choose the lopcation in which
you are updateing quantities

TASK-30921
This commit is contained in:
dip-odoo
2018-06-28 10:42:28 +02:00
committed by Pierre Masereel
parent 15f3bbe594
commit a04d43faf2
5 changed files with 38 additions and 34 deletions
+27
View File
@@ -346,6 +346,9 @@ class Product(models.Model):
res['fields']['qty_available']['string'] = _('Produced Qty')
return res
def action_update_quantity_on_hand(self):
return self.product_tmpl_id.with_context({'default_product_id': self.id}).action_update_quantity_on_hand()
def action_view_routes(self):
return self.mapped('product_tmpl_id').action_view_routes()
@@ -527,6 +530,30 @@ class ProductTemplate(models.Model):
action['domain'] = [('id', 'in', routes.ids)]
return action
def action_update_quantity_on_hand(self):
default_product_id = self.env.context.get('default_product_id', self.product_variant_id.id)
if self.env.user.user_has_groups('stock.group_stock_multi_locations') or (self.env.user.user_has_groups('stock.group_production_lot') and self.tracking != 'none'):
product_ref_name = self.name + ' - ' + datetime.today().strftime('%m/%d/%y')
ctx = {'default_filter': 'product', 'default_product_id': default_product_id, 'default_name': product_ref_name}
return {
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.inventory',
'context': ctx,
}
else:
wiz = self.env['stock.change.product.qty'].create({'product_id': default_product_id})
return {
'name': _('Update quantity on hand'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'stock.change.product.qty',
'target': 'new',
'res_id': wiz.id,
'context': {'default_product_id': self.env.context.get('default_product_id')}
}
def action_open_quants(self):
products = self.mapped('product_variant_ids')
action = self.env.ref('stock.product_open_quants').read()[0]
+2
View File
@@ -136,6 +136,8 @@ class Inventory(models.Model):
self.category_id = False
if self.filter == 'product':
self.exhausted = True
if self.product_id:
return {'domain': {'product_id': [('product_tmpl_id', '=', self.product_id.product_tmpl_id.id)]}}
@api.onchange('location_id')
def onchange_location_id(self):
+4 -4
View File
@@ -151,7 +151,7 @@
<field name="arch" type="xml">
<sheet position="before">
<header>
<button name="%(action_view_change_product_quantity)d" string="Update Qty On Hand" type="action" attrs="{'invisible': [('type', '!=', 'product')]}"/>
<button name="action_update_quantity_on_hand" string="Update Qty On Hand" type="object" attrs="{'invisible': [('type', '!=', 'product')]}"/>
<button string="Replenish" type="action"
name="%(action_product_replenish)d"
context="{'default_product_id': id}"
@@ -171,8 +171,8 @@
<data>
<header position="inside">
<button string="Update Qty On Hand"
type="action"
name="%(action_view_change_product_quantity)d"
type="object"
name="action_update_quantity_on_hand"
attrs="{'invisible': [('type', '!=', 'product')]}"/>
<button string="Replenish" type="action"
name="%(action_product_replenish)d"
@@ -246,7 +246,7 @@
<field name="arch" type="xml">
<data>
<header position="inside" >
<button name="%(action_view_change_product_quantity)d" string="Update Qty On Hand" type="action" attrs="{'invisible': [('type', '!=', 'product')]}"/>
<button name="action_update_quantity_on_hand" string="Update Qty On Hand" type="object" attrs="{'invisible': [('type', '!=', 'product')]}"/>
<button string="Replenish" type="action"
name="%(action_product_replenish)d"
context="{'default_product_tmpl_id': id}"
@@ -18,16 +18,11 @@ class ProductChangeQuantity(models.TransientModel):
'New Quantity on Hand', default=1,
digits=dp.get_precision('Product Unit of Measure'), required=True,
help='This quantity is expressed in the Default Unit of Measure of the product.')
lot_id = fields.Many2one('stock.production.lot', 'Lot/Serial Number', domain="[('product_id','=',product_id)]")
location_id = fields.Many2one('stock.location', 'Location', required=True, domain="[('usage', '=', 'internal')]")
@api.model
def default_get(self, fields):
res = super(ProductChangeQuantity, self).default_get(fields)
if not res.get('product_id') and self.env.context.get('active_id') and self.env.context.get('active_model') == 'product.template' and self.env.context.get('active_id'):
res['product_id'] = self.env['product.product'].search([('product_tmpl_id', '=', self.env.context['active_id'])], limit=1).id
elif not res.get('product_id') and self.env.context.get('active_id') and self.env.context.get('active_model') == 'product.product' and self.env.context.get('active_id'):
res['product_id'] = self.env['product.product'].browse(self.env.context['active_id']).id
if 'location_id' in fields and not res.get('location_id'):
company_user = self.env.user.company_id
warehouse = self.env['stock.warehouse'].search([('company_id', '=', company_user.id)], limit=1)
@@ -48,7 +43,7 @@ class ProductChangeQuantity(models.TransientModel):
self.product_tmpl_id = self.onchange_product_id_dict(self.product_id.id)['product_tmpl_id']
def _action_start_line(self):
product = self.product_id.with_context(location=self.location_id.id, lot_id=self.lot_id.id)
product = self.product_id.with_context(location=self.location_id.id)
th_qty = product.qty_available
res = {
@@ -57,7 +52,6 @@ class ProductChangeQuantity(models.TransientModel):
'product_id': self.product_id.id,
'product_uom_id': self.product_id.uom_id.id,
'theoretical_qty': th_qty,
'prod_lot_id': self.lot_id.id,
}
return res
@@ -83,13 +77,10 @@ class ProductChangeQuantity(models.TransientModel):
""" Changes the Product Quantity by making a Physical Inventory. """
Inventory = self.env['stock.inventory']
for wizard in self:
product = wizard.product_id.with_context(location=wizard.location_id.id, lot_id=wizard.lot_id.id)
product = wizard.product_id.with_context(location=wizard.location_id.id)
line_data = wizard._action_start_line()
if wizard.product_id.id and wizard.lot_id.id:
inventory_filter = 'none'
elif wizard.product_id.id:
if wizard.product_id.id:
inventory_filter = 'product'
else:
inventory_filter = 'none'
@@ -98,7 +89,6 @@ class ProductChangeQuantity(models.TransientModel):
'filter': inventory_filter,
'product_id': wizard.product_id.id,
'location_id': wizard.location_id.id,
'lot_id': wizard.lot_id.id,
'line_ids': [(0, 0, line_data)],
})
inventory.action_done()
@@ -11,14 +11,10 @@
<field name="product_variant_count" invisible="1"/>
<field name="product_id" widget="selection"
domain="[('product_tmpl_id', '=', product_tmpl_id)]"
attrs="{'readonly': [('product_variant_count', '=', 1)]}"/>
attrs="{'readonly': [('product_variant_count', '=', 1)]}"
readonly="context.get('default_product_id')"/>
<field name="location_id" groups="stock.group_stock_multi_locations"/>
<field name="new_quantity"/>
<field name="lot_id" context="{'search_default_product_id':product_id,'default_product_id':product_id}" groups="stock.group_production_lot"/>
<p groups="stock.group_production_lot" class="oe_grey">
When you select a serial number (lot), the quantity is corrected with respect to
the quantity of that serial number (lot) and not to the total quantity of the product.
</p>
</group>
<footer>
<button name="change_product_qty" string="_Apply" type="object" class="btn-primary"/>
@@ -27,17 +23,6 @@
</form>
</field>
</record>
<record id="action_view_change_product_quantity" model="ir.actions.act_window">
<field name="name">Update Product Quantity</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.change.product.qty</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_change_product_quantity"/>
<field name="target">new</field>
</record>
</data>
</odoo>