Odoo Help

0
3 Answers
0
jithesh
5/17/18, 1:44 AM

here we design a .py  code to implement custom picking

the user can automattically select stock location and shelf and row the product stocked its not completed it is use-ful to you


import logging
from datetime import timedelta
from functools import partial

import psycopg2
from collections import namedtuple
import json
import time
import ast
from odoo.tools.float_utils import float_compare
from odoo import api, fields, models, tools, _
from odoo.tools import float_is_zero
from odoo.exceptions import UserError
from odoo.http import request
import odoo.addons.decimal_precision as dp
from collections import OrderedDict

_logger = logging.getLogger(__name__)

class PosOrderLine(models.Model):
    _inherit = "pos.order.line"

    dict_value= fields.Char()


class PosOrder(models.Model):
    _inherit = "pos.order"


    def create_picking(self):
        """Create a picking for each order and validate it."""
        Picking = self.env['stock.picking']
        Move = self.env['stock.move']
        StockWarehouse = self.env['stock.warehouse']
        for order in self:
            print "order %s" % order.picking_type_id.id
            address = order.partner_id.address_get(['delivery']) or {}
            picking_type = order.picking_type_id
            print "picking_type %s" % picking_type
            return_pick_type = order.picking_type_id.return_picking_type_id or order.picking_type_id
            order_picking = Picking
            return_picking = Picking
            moves = Move
            location_id = order.location_id.id
            print "====================================%s" % order.location_id.name
            if order.partner_id:
                destination_id = order.partner_id.property_stock_customer.id
            else:
                if (not picking_type) or (not picking_type.default_location_dest_id):
                    customerloc, supplierloc = StockWarehouse._get_partner_locations()
                    destination_id = customerloc.id
                else:
                    destination_id = picking_type.default_location_dest_id.id
            if picking_type:
                print "picking_type"
                message = _(
                    "This transfer has been created from the point of sale session: <a href=# data-oe-model=pos.order data-oe-id=%d>%s</a>") % (
                          order.id, order.name)

                picking_vals = {
                    'origin': order.name,
                    'partner_id': address.get('delivery', False),
                    'date_done': order.date_order,
                    'picking_type_id': picking_type.id,
                    'company_id': order.company_id.id,
                    'move_type': 'direct',
                    'note': order.note or "",
                    'location_id': location_id,
                    'location_dest_id': destination_id,
                }
                print(picking_vals)
                pos_qty = any([x.qty >= 0 for x in order.lines])
                print "pos_qty %s" % pos_qty
                if pos_qty:
                    print "entered into pos_qty"
                    order_picking = Picking.create(picking_vals)
                    order_picking.message_post(body=message)
                neg_qty = any([x.qty < 0 for x in order.lines])
                if neg_qty:
                    return_vals = picking_vals.copy()
                    return_vals.update({
                        'location_id': destination_id,
                        'location_dest_id': return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id,
                        'picking_type_id': return_pick_type.id
                    })
                    return_picking = Picking.create(return_vals)
                    return_picking.message_post(body=message)

            for line in order.lines.filtered(lambda l: l.product_id.type in ['product', 'consu']):
                    print "--------------- dic_value-------------%s" %line.dict_value

                    if line.x_location:
                        if line.dict_value:
                            locations = ast.literal_eval(line.dict_value)
                            line_qty = line.qty

                            loc_id = self.env['stock.location'].search([('name', '=', line.x_location)])
                            print "loc id == %s" % loc_id
                            moves |= Move.create({
                                'name': line.name,
                                'product_uom': line.product_id.uom_id.id,
                                'picking_id': order_picking.id if line.qty >= 0 else return_picking.id,
                                'picking_type_id': picking_type.id if line.qty >= 0 else return_pick_type.id,
                                'product_id': line.product_id.id,
                                'product_uom_qty': abs(float(locations[line.x_location])),
                                'state': 'draft',
                                'location_id': loc_id.id,
                                'location_dest_id': destination_id if line.qty >= 0 else return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id,
                            })
                            line_qty -= float(locations[line.x_location])

                            if line_qty > 0:
                                for loc, qty in locations.iteritems():
                                    print "==============LINE QTY================%s"%line_qty
                                    print "==============QTY=====================%s"%qty

                                    if loc != line.x_location and float(qty)>0 and line_qty > 0:
                                        if float(qty) >= line_qty:
                                            # line_qty = float(qty) - line_qty
                                            print "qty diff =%s"%line_qty
                                            loc_id = self.env['stock.location'].search([('name', '=', loc)])
                                            moves |= Move.create({
                                                'name': line.name,
                                                'product_uom': line.product_id.uom_id.id,
                                                'picking_id': order_picking.id if line.qty >= 0 else return_picking.id,
                                                'picking_type_id': picking_type.id if line.qty >= 0 else return_pick_type.id,
                                                'product_id': line.product_id.id,
                                                'product_uom_qty': line_qty,
                                                'state': 'draft',
                                                'location_id': loc_id.id,
                                                'location_dest_id': destination_id if line.qty >= 0 else return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id,
                                            })

                                            print "executed move create"
                                            break
                                        else:
                                            print "ENETERD ELSE"
                                            line_qty = abs(float(qty)-line_qty)
                                            loc_id = self.env['stock.location'].search([('name', '=', loc)])
                                            moves |= Move.create({
                                                'name': line.name,
                                                'product_uom': line.product_id.uom_id.id,
                                                'picking_id': order_picking.id if line.qty >= 0 else return_picking.id,
                                                'picking_type_id': picking_type.id if line.qty >= 0 else return_pick_type.id,
                                                'product_id': line.product_id.id,
                                                'product_uom_qty': float(qty),
                                                'state': 'draft',
                                                'location_id': loc_id.id,
                                                'location_dest_id': destination_id if line.qty >= 0 else return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id,
                                            })
                        else:
                                loc_id = self.env['stock.location'].search([('name', '=', line.x_location)])
                                print "loc id == %s" % loc_id
                                moves |= Move.create({
                                    'name': line.name,
                                    'product_uom': line.product_id.uom_id.id,
                                    'picking_id': order_picking.id if line.qty >= 0 else return_picking.id,
                                    'picking_type_id': picking_type.id if line.qty >= 0 else return_pick_type.id,
                                    'product_id': line.product_id.id,
                                    'product_uom_qty': abs(line.qty),
                                    'state': 'draft',
                                    'location_id': loc_id.id,
                                    'location_dest_id': destination_id if line.qty >= 0 else return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id,
                                })

                    else:
                        moves |= Move.create({
                            'name': line.name,
                            'product_uom': line.product_id.uom_id.id,
                            'picking_id': order_picking.id if line.qty >= 0 else return_picking.id,
                            'picking_type_id': picking_type.id if line.qty >= 0 else return_pick_type.id,
                            'product_id': line.product_id.id,
                            'product_uom_qty': abs(line.qty),
                            'state': 'draft',
                            'location_id': location_id if line.qty >= 0 else destination_id,
                            'location_dest_id': destination_id if line.qty >= 0 else return_pick_type != picking_type and return_pick_type.default_location_dest_id.id or location_id,
                        })





            print "=========================== order picking is =%s" % order_picking.id
            # prefer associating the regular order picking, not the return
            order.write({'picking_id': order_picking.id or return_picking.id})

            if return_picking:
                order._force_picking_done(return_picking)
            if order_picking:
                print("1")
                order_picking.action_confirm()
                print("2")
                order_picking.force_assign()
                # order_picking.do_new_transfer()
                print("before")
                order.set_pack_operation_lot()
                print("after")
                order_picking.action_done()

            # when the pos.config has no picking_type_id set only the moves will be created
            if moves and not return_picking and not order_picking:
                moves.action_confirm()
                moves.force_assign()
                moves.filtered(lambda m: m.product_id.tracking == 'none').action_done()

        return True


class StockPick(models.Model):
    _inherit = 'stock.picking'

    def _prepare_pack_ops(self, quants, forced_qties):
        """ Prepare pack_operations, returns a list of dict to give at create """
        # TDE CLEANME: oh dear ...
        valid_quants = quants.filtered(lambda quant: quant.qty > 0)
        _Mapping = namedtuple('Mapping', ('product', 'package', 'owner', 'location', 'location_dst_id'))

        all_products = valid_quants.mapped('product_id') | self.env['product.product'].browse(
            p.id for p in forced_qties.keys()) | self.move_lines.mapped('product_id')
        computed_putaway_locations = dict(
            (product, self.location_dest_id.get_putaway_strategy(product) or self.location_dest_id.id) for product in
            all_products)

        product_to_uom = dict((product.id, product.uom_id) for product in all_products)
        picking_moves = self.move_lines.filtered(lambda move: move.state not in ('done', 'cancel'))
        for move in picking_moves:
            # If we encounter an UoM that is smaller than the default UoM or the one already chosen, use the new one instead.
            if move.product_uom != product_to_uom[move.product_id.id] and move.product_uom.factor > product_to_uom[
                move.product_id.id].factor:
                product_to_uom[move.product_id.id] = move.product_uom
        # if len(picking_moves.mapped('location_id')) > 1:
        #     raise UserError(_('The source location must be the same for all the moves of the picking.'))
        # if len(picking_moves.mapped('location_dest_id')) > 1:
        #     raise UserError(_('The destination location must be the same for all the moves of the picking.'))

        pack_operation_values = []
        # find the packages we can move as a whole, create pack operations and mark related quants as done
        top_lvl_packages = valid_quants._get_top_level_packages(computed_putaway_locations)
        for pack in top_lvl_packages:
            pack_quants = pack.get_content()
            pack_operation_values.append({
                'picking_id': self.id,
                'package_id': pack.id,
                'product_qty': 1.0,
                'location_id': pack.location_id.id,
                'location_dest_id': computed_putaway_locations[pack_quants[0].product_id],
                'owner_id': pack.owner_id.id,
            })
            valid_quants -= pack_quants

        # Go through all remaining reserved quants and group by product, package, owner, source location and dest location
        # Lots will go into pack operation lot object
        qtys_grouped = {}
        lots_grouped = {}
        for quant in valid_quants:
            key = _Mapping(quant.product_id, quant.package_id, quant.owner_id, quant.location_id,
                           computed_putaway_locations[quant.product_id])
            qtys_grouped.setdefault(key, 0.0)
            qtys_grouped[key] += quant.qty
            if quant.product_id.tracking != 'none' and quant.lot_id:
                lots_grouped.setdefault(key, dict()).setdefault(quant.lot_id.id, 0.0)
                lots_grouped[key][quant.lot_id.id] += quant.qty
        # Do the same for the forced quantities (in cases of force_assign or incomming shipment for example)
        for product, qty in forced_qties.items():
            if qty <= 0.0:
                continue
            key = _Mapping(product, self.env['stock.quant.package'], self.owner_id, self.location_id,
                           computed_putaway_locations[product])
            qtys_grouped.setdefault(key, 0.0)
            qtys_grouped[key] += qty

        # Create the necessary operations for the grouped quants and remaining qtys
        Uom = self.env['product.uom']
        product_id_to_vals = {}  # use it to create operations using the same order as the picking stock moves
        for mapping, qty in qtys_grouped.items():
            uom = product_to_uom[mapping.product.id]
            val_dict = {
                'picking_id': self.id,
                'product_qty': mapping.product.uom_id._compute_quantity(qty, uom),
                'product_id': mapping.product.id,
                'package_id': mapping.package.id,
                'owner_id': mapping.owner.id,
                'location_id': mapping.location.id,
                'location_dest_id': mapping.location_dst_id,
                'product_uom_id': uom.id,
                'pack_lot_ids': [
                    (0, 0, {'lot_id': lot, 'qty': 0.0, 'qty_todo': lots_grouped[mapping][lot]})
                    for lot in lots_grouped.get(mapping, {}).keys()],
            }
            product_id_to_vals.setdefault(mapping.product.id, list()).append(val_dict)

        for move in self.move_lines.filtered(lambda move: move.state not in ('done', 'cancel')):
            print(move.product_uom_qty)
            values = product_id_to_vals.pop(move.product_id.id, [])
            values[0]['location_id'] = move.location_id.id
            pack_operation_values += values
            print("pac ops vals %s"%pack_operation_values)
        return pack_operation_values



    @api.multi
    def do_prepare_partial(self):
        # TDE CLEANME: oh dear ...
        PackOperation = self.env['stock.pack.operation']

        # get list of existing operations and delete them
        existing_packages = PackOperation.search([('picking_id', 'in', self.ids)])  # TDE FIXME: o2m / m2o ?
        if existing_packages:
            existing_packages.unlink()
        for picking in self:
            forced_qties = {}  # Quantity remaining after calculating reserved quants
            picking_quants = self.env['stock.quant']
            # Calculate packages, reserved quants, qtys of this picking's moves
            for move in picking.move_lines:
                value = {}
                if move.state not in ('assigned', 'confirmed', 'waiting'):
                    continue
                move_quants = move.reserved_quant_ids
                picking_quants += move_quants
                forced_qty = (move.state == 'assigned') and move.product_qty - sum([x.qty for x in move_quants]) or 0
                # if we used force_assign() on the move, or if the move is incoming, forced_qty > 0
                if float_compare(forced_qty, 0, precision_rounding=move.product_id.uom_id.rounding) > 0:
                    if forced_qties.get(move.product_id):
                        value['fresh_record'] = False
                        value['location_dest_id']=move.location_dest_id.id
                        value['product_id'] = move.product_id.id
                        value['product_qty'] = forced_qty
                        value['product_uom_id'] = move.product_uom.id
                        value['location_id'] = move.location_id.id
                        value['picking_id'] = move.picking_id.id
                        PackOperation.create(value)
                        # print("inside11")
                        # forced_qties[move.product_id] += forced_qty
                    else:
                        # forced_qties[move.product_id] = forced_qty
                        value['fresh_record'] = False
                        value['location_dest_id']=move.location_dest_id.id
                        value['product_id'] = move.product_id.id
                        value['product_qty'] = forced_qty
                        value['product_uom_id'] = move.product_uom.id
                        value['location_id'] = move.location_id.id
                        value['picking_id'] = move.picking_id.id
                        PackOperation.create(value)
            # for vals in picking._prepare_pack_ops(picking_quants, forced_qties):
            #     vals['fresh_record'] = False
            #     PackOperation.create(vals)
        # recompute the remaining quantities all at once
        self.do_recompute_remaining_quantities()
        self.write({'recompute_pack_op': False})


0
Simone
4/16/18, 10:46 AM

I have the usual problem do you have any help? 

Sorry my English!

Ask a Question
Writer
Keep Informed
1 follower(s)
About This Community

This platform is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.

Register
Odoo Training Center

Access to our E-learning platform and experience all Odoo Apps through learning videos, exercises and Quizz.

Test it now