Skip to Content
Menu
This question has been flagged
4 Replies
10954 Views

Hello. I'm on Odoo 16. I have questions regarding internal transfers. 

For example, I have stock for oranges in Warehouse A. I would like to do an internal transfer of oranges from Warehouse A to warehouse B.

Today I would like to transfer 5 oranges from Warehouse A to warehouse B.

When I performed an internal transfer, there are a couple of things which I found confusing:

1) The internal transfer happens immediately. Immediately here means that the inventory levels for oranges were directly changed in both warehouse A and B after clicking on confirm. How do I create a 2-step internal transfer where:

- Staff in Warehouse A creates an internal transfer of 5 oranges to Warehouse B

- Once that is done, staff in Warehouse B will see that there is a receipt or transfer to process in the inventory overview under Warehouse B. 

- Staff in Warehouse B would then process them as they would normally do when purchasing from external vendors. Which is calculating the number of oranges that has arrived then validate the quantities

2) It seems like you are allowed to over-transfer (resulting in a negative inventory from the source location). How can I disallow this from happening? That means you can only transfer the amount of stock you actually have?  

Avatar
Discard

I have a couple questions:
- Do the warehouses share adress?
- What rules do you have in each warehouse (X step delivery?, X step recepcion?)

Hi,
"negative level" is caused because you are using immediate transfer -> which means you don't check product availability " you are sure they are there with this count.
So instead of that try to use planned transfer which will allow you to check availability of product in source destination

Hello,
I understood your problem. Yes you can get the acknowledgement from the receiver end. You have to extend the two to three points inside the internal transfer process. You can contact us for discussing in more details.

Thanks,
shivoham.odoo@gmail.com

Best Answer

In Odoo 16, you can create a 2-step internal transfer process by using the "Planned Transfer" functionality. With planned transfers, you can create a transfer order in Warehouse A and then process it as a receipt in Warehouse B.

To create a planned transfer, follow these steps:

Go to the "Inventory -> Operations -> Planned Transfers" menu.
Click on the "Create" button to create a new planned transfer order.
Select the source location (Warehouse A) and the destination location (Warehouse B).
Add the product that you want to transfer (oranges) and specify the quantity (5).
Save the planned transfer order.

Once the planned transfer order is saved, it will appear in the "Receipts to Process" section of the Warehouse B inventory overview. The staff in Warehouse B can then process the planned transfer order as they would normally do when receiving goods from an external vendor.

To disallow over-transferring, you can enable the "Allow negative quantities" option in the inventory settings. To do this, follow these steps:

Go to the "Inventory -> Configuration -> Settings" menu.
Scroll down to the "Inventory Valuation" section.
Deselect the "Allow negative quantities" option.
Save the changes.

With this setting enabled, you will not be able to confirm a transfer order if it results in a negative inventory balance in the source location.

Avatar
Discard
Best Answer

Here are a couple of concepts that might help in achieving the creation of receipt (2 step) for transfers

Firstly you would need to unarchive the location Inter warehouse transit location. This is to ensure transfer is happening in 2 steps to be able to track with 2 operations.

Couple of ways to create routes
1. Push rules - create a push rule
From transit location to WH-B/ stock 
This would create a receipt in WH-B when any product is moved to transit location 

To make a transfer, create internal transfer from WH-A to transit location on validation of this transfer a receipt operation would be created in WH-B

This is in line with your example of sending oranges from A to B. 
The limitation with this rule is that you wouldn’t be able to use the transit location to move products from WH B to A

2. Pull rule - Define a route using pull rules

Pull from Transit to WH-B

Pull from WH-A to Transit

Apply this to product or product categories.

To make a transfer create a replenishment in WH-B with this route, (order once). It should create 2 operations.
Limitation is that you would have to create replenishment by individual  product.

3. Another option could be to have one warehouse resupply the other.

================

Additional resources

The video below addresses a couple of business cases and details the steps to achieve them. It might help in applying and creating the routes (push/pull, triggers etc) specific to your business needs.
https://www.odoo.com/slides/slide/superstar-logistic-solution-1103?fullscreen=1

Hope this helps you in defining the use case specific to your needs.

Avatar
Discard
Best Answer

In Odoo, there are several ways to manage internal transfers between warehouses. The method you choose depends on the level of control and validation you need.

 

1. Immediate Transfer (Basic but Risky)

A simple way to transfer products between warehouses is by creating an Internal Transfer, where the source location belongs to Warehouse A and the destination location is Warehouse B.

Pros: Quick and straightforward.
Cons: Not realistic as it updates stock immediately, leading to potential physical discrepancies.


2. Transfer with Validation on Receipt

        i. ​Using an In-Transit Location

​To introduce validation, you can use an in-transit location:

        • Create an Internal Transfer from Warehouse A to In-Transit.
        • Then, create another transfer from In-Transit to Warehouse B.

Pros: Allows step-by-step tracking.
​​ Cons: Does not automatically create a receipt order for Warehouse B or include delivery/shipping details.

​Often, businesses require Warehouse B to automatically generate an order for the products they are waiting for. This method does not cover that scenario.

​ 

      ii.      ​Automated Replenishment

  ​Odoo can automatically generate internal transfer orders by setting up Replenishment Rules. This will create:

        • A Delivery Order in Warehouse A.
        • A Receipt Order in Warehouse B.

 

Pros: Fully automated transfer process.
​Cons: Requires proper routes and rules configuration and apply them to products.


    iii. ​Manual Replenishment Trigger

 

​Similar to automated replenishment, but instead of an automatic trigger, the user manually initiates the process by clicking the Replenish button under Inventory > Products.

Pros: More control over when the transfer happens.
​Cons: Requires manual action and also proper routes and rules configuration and apply them to products.

 

    iv.          ​Transfer Triggered by Delivery Order Validation (using Routes)

 

​This method works by setting up Routes so that when a Delivery Order is validated in Warehouse A, a Receipt Order is automatically created in Warehouse ​B.

 

Pros: Automates the process without manual intervention.
​Cons: This method has the limitations mentioned from Jaideep above and in order to surpass them you have to create a different in transit location for each ​different warehouse and assigned it to different route in order to cover all the different scenarios.

 

      v. ​Automated Transfer on Delivery (using Automated Actions)

 

​If you want to dynamically create a Receipt Order in Warehouse B without manually creating a delivery order first and avoiding the creation of ​unnecessary locations and routes, Automated Actions is the best way.

​Use Case:

​An operator in Warehouse A creates a Delivery Order without a predefined order and selects Warehouse B as the recipient. Instead of manually creating a ​receipt, an automated action triggers the creation of a Receipt Order in Warehouse B.

 

Implementation Steps:

      • Create an Automated Action that triggers “On Save”.
      • Update when the record is "Created On" in the Transfer model.
      • The action should apply when:
          • ​​Status is "Done".
          • Operation Type is "Delivery".
          • Source Document is not set (to prevent duplicate receipts for replenishments, as replenishments fill this with “Manual Replenishment”).

​In this automated action a code should be executed to see if the “Delivery Address” field belong to our company that owns Warehouse A and B. ​When this happens, Odoo automatically creates send the product(s) from this delivery to the “Physical location / Inter-Warehouse Transit” location but does ​not create the related receipt. So a code like the below should be implemented.


if record.picking_type_id.code == 'outgoing':
    # Identify the source and destination warehouses
    source_warehouse = record.picking_type_id.warehouse_id
    destination_warehouse = env['stock.warehouse'].search([
        ('partner_id', '=', record.partner_id.id)
    ], limit=1)

    if destination_warehouse and source_warehouse:
        source_partner = source_warehouse.partner_id
        procurement_group = record.group_id

        # Create the receipt picking without move lines
        new_receipt = env['stock.picking'].create({
            'picking_type_id': destination_warehouse.in_type_id.id,
            'location_id': record.location_dest_id.id,
            'location_dest_id': destination_warehouse.lot_stock_id.id,
            'origin': record.name,
            'partner_id': source_partner.id if source_partner else False,
            'user_id': False,
            'note': record.note if record.note else False,
            'group_id': procurement_group.id,
            'carrier_id': record.carrier_id.id if record.carrier_id else False,
            'carrier_tracking_ref': record.carrier_tracking_ref if record.carrier_tracking_ref else False,
            'weight': record.weight if record.weight else 0.0,
            'shipping_weight': record.shipping_weight if record.shipping_weight else 0.0,
        })

        # Create move lines for the new receipt
        move_line_vals = []
        for move in record.move_ids:
            for move_line in move.move_line_ids.filtered(lambda ml: ml.qty_done > 0):
                new_move = env['stock.move'].create({
                    'product_id': move_line.product_id.id,
                    'product_uom_qty': move_line.qty_done,
                    'product_uom': move_line.product_uom_id.id,
                    'name': move_line.product_id.name,
                    'location_id': record.location_dest_id.id,
                    'location_dest_id': destination_warehouse.lot_stock_id.id,
                    'picking_id': new_receipt.id,
                    'procure_method': 'make_to_stock',
                    'origin': record.name,
                    'group_id': procurement_group.id,
                })
                move_line_vals.append((0, 0, {
                    'move_id': new_move.id,
                    'product_id': move_line.product_id.id,
                    'quantity': move_line.qty_done,
                    'product_uom_id': move_line.product_uom_id.id,
                    'location_id': record.location_dest_id.id,
                    'location_dest_id': destination_warehouse.lot_stock_id.id,
                }))

        if move_line_vals:
            new_receipt.write({'move_line_ids': move_line_vals})

        # Set the receipt moves as "Assigned"
        new_receipt.move_ids.write({'state': 'assigned'})

        # Update the delivery origin to match procurement group
        record.write({
            'origin': 'Manual Operation',
            'group_id': procurement_group.id,
        })

        # Link moves from delivery to receipt
        for move in record.move_ids:
            matching_receipt_move = new_receipt.move_ids.filtered(lambda m: m.product_id == move.product_id)
            if matching_receipt_move:
                move.write({'move_dest_ids': [(4, matching_receipt_move.id)]})

        # Ensure Odoo recomputes "show_next_pickings"
        record._compute_show_next_pickings()

Avatar
Discard
Best Answer

Question 2 should not be able, I've just tested it and it did not allow me... I dont know how you did it... Any customs?

About question 1 I need more info to help you.

Avatar
Discard
Related Posts Replies Views Activity
1
Apr 25
201
2
Jan 24
1893
1
Jun 23
1523
1
Mar 22
2982
0
Apr 25
73