Steps to reproduce the bug:
- Connect with the company A
- Create a consumable product “P1”
- Create a receipt transfer with this product
- confirm the transfer
- Come back to the product form
- limiter le produit que a la “Company B”
Problem:
no user error triggered
Go to inventory > operation > transfer: a Traceback is triggered
Before this commit, there is no verification while changing a product's
company for consumable. That can lead to an issue where some operations
cannot be done because of access errors. To avoid that, this commit
prevents to change the product's company if some move lines for this
product exist in another company.
opw-3300559
closesodoo/odoo#120983
X-original-commit: a6666de7f492f9f94abc23a080134dd473d0dddc
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
Before, when the user pastes a list of tracking numbers into the move
line's `lot_name` field (through the move's detailed view), a lot is
created for each line, creating a move line for each new lot, or
assigning each lot to an existing line with no lot.
With this commit, it will also take `qty_done` and `expiration_date` (if
`product_expiry` is installed) from the pasted list if it's relevant.
Each data should be separate either by a semicolon, either by a tab, and
the first data should always be the lot name.
Valid examples for lots and quantities:
lot-01;22
lot-02 12
Valid examples for lots, expiration date and quantities:
lot-03;8;01-02-2005
lot-04 2005/02/01 12-20
The only valid separation characters for the date are the space (" "),
the dash ("-") and the slash ("/"). Examples of valid dates:
20-02-24 20-Feb-2024
20 02 24 20 Feb 2024
20/02/24 20/Feb/2024
If any of the extra values can't be converted into either a quantity or
a date, the whole line will be used as the tracking number.
Also, if dates are pasted but the product doesn't use any expiration
date, the date's part will be ignored.
task-3171866
closesodoo/odoo#115401
Signed-off-by: Tiffany Chang <tic@odoo.com>
Steps to reproduce:
- activate `group_stock_reception_report` in settings
- activate `auto_show_reception_report` for the "Receipts" operation type
- create a receipt w/ any product + confirm
- create a return w/any product + confirm
- select both the receipt + return in the (Operations > Transfers) list
view > action > Validate
Expected result: both pickings are validated
Actual result: stacktrace due to expected singleton ValueError
enterprise PR : https://github.com/odoo/enterprise/pull/37518
task-3204596
closesodoo/odoo#120190
X-original-commit: b2ac4b2f30e15c4b8a50628798b2fc39d7d43331
Related: odoo/enterprise#40570
Signed-off-by: Tiffany Chang <tic@odoo.com>
Steps to reproduce:
- Enable multi-warehouses (i.e. have a company with 2 warehouses:
warehouse_1 and warehouse_2)
- Set warehouse_2's view_location to a location within warehouse_1
- Check the warehouse_id of a location within warehouse_2
Expected result:
warehouse_id = warehouse_2
Actual result:
warehouse_id = warehouse_1
The issue with this is each warehouse may be configured with their
own routes/rules, therefore a product within warehouse_2 may not
follow the warehouse_2 routes/rules. Note that a nested warehouse
situation like this may occur with warehouses located in different
countries, but products from both warehouses are sold in the same
ecommerce store and `website_warehouse_id` only allows 1
warehouse to be assigned to it
closesodoo/odoo#119181
X-original-commit: 83613b56cadf1a12331db9d4d41ab688d68768e9
Signed-off-by: Tiffany Chang <tic@odoo.com>
To reproduce the issue:
1. In Settings, enable:
- Multi-Step Routes
- Storage Categories
- Packages
2. Create a Storage Category SC:
- Allow New Product: same
- Max Weight: 100 kg
- Capacity by Package:
- 2 x Pallet
3. Create two locations L1, L2:
- Parent: WH/Stock
- Type: Internal
- Storage Category: SC
4. Create a putaway rule:
- When in: WH/Stock
- Package type: Pallet
- Store to: WH/Stock
- Having Category: SC
5. Edit the warehouse:
- Incoming Shipments: 2 steps
6. Create a product P:
- Type: Storable
- Weight: 1 kg
7. Update L1:
- There is 1 x P in a pallet
8. Create a planned receipt R:
- To: WH/Input
- Operations:
- 2 x P
9. Mark R as Todo
10. Create two packages:
- 1 x P in PK01 (! PK01 must be a Pallet)
- 1 x P in PK02 (! PK02 must be a Pallet)
11. Validate R
12. Open the related internal transfer T
Error: Both packages are redirected to L2 but one of them should be
redirected to L1
When checking L1, we ensure that the policy 'all same products' is
respected. To do so, we compare the products of the quants of L1
with the given product. Here is the issue: when moving a package, we
don't provide any `product` value to the methods used in the putaway
rules process.
Note: There was also another issue with the 'all same products'
policy. Suppose L1 is empty, and we move a pallet with two different
products, the move line is redirected to L1, which breaks the 'all
same products' condition.
OPW-3204924
closesodoo/odoo#118708
X-original-commit: 3a6d82de77e0ab477b3f22985f6d41995e25f652
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
Since https://github.com/odoo/odoo/pull/104062, the location and
scrap location id fields on a scrap order are no longer editable
(even while still in draft).
To reproduce:
- Enable storage locations in settings
- Create a new scrap order
Bug: The source and draft location are readonly.
This fix restores the intended behaviour to make these fields editable
while in draft state and adds a test to confirm this behaviour.
Task: 3266655
Community PR: https://github.com/odoo/odoo/pull/117931closesodoo/odoo#118177
X-original-commit: 1dcc9ade1793a562e5df20336241d2a025c5e14c
Signed-off-by: Tiffany Chang <tic@odoo.com>
An error appears when we try to change the product in transfer line via
product/search
steps to reproduce the error :
1- create 2 products : Test 1 (UoM is Cm) and Test 2 (Uom is g)
2- create a delivery order and add Test 1
3- UoM error due to the UoM not being updated at the time of change
The error was happening because when updating the product directly in
the line section , the stock_move item already has a UoM and the if
statement makes it impossible to change it , so the error appears.
opw-3231298
closesodoo/odoo#117504
X-original-commit: ece3dea8c1ab43a854a57513cc317e8618010542
Signed-off-by: Adrien Widart <awt@odoo.com>
Signed-off-by: Mahdi Cheikh Rouhou (macr) <macr@odoo.com>
Steps to reproduce the bug:
- Create a Storable product “C1” tracked by Lot:
- Update the Qty to 10
- Create a Storable product “P1”:
- Add a BoM:
- add 1 unit of “C1” as component
- Enable 3 steps for the manufacturing operation in warehouse settings
- Create a Mo to produce 1 unit of “P1”:
- Confirm the MO
- Click on related transfer:
- Select the “Pick component”
- check that the qty is reserved correctly
- Try to validate it without setting Qty done
- The immediate transfer is triggered, validate it
Problem:
The backorder's wizard triggers when it shouldn't
To know if we should create a backorder, we check if the qty reserved
is equal to the qty done, and as the qty done was not set correctly
during the validation of the immediate transfer, the two quantities
are not identical, therefore the widget is trigger:
https://github.com/odoo/odoo/blob/15.0/addons/stock/models/stock_picking.py#L1128-L1132
opw-3240264
closesodoo/odoo#117706
X-original-commit: dd44e1f69dfd217fafa9c2ec5da8b211b2ff3513
Signed-off-by: Steve Van Essche <svs@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
Before this commit, if there is a demand for quantities and they are
available but reserved in transit (not yet in a stock location) they are
shown as not available.
To reproduce:
1) Have 2/3 step incoming shipments in warehouse
2) Purchase a quantity to create the incoming transfer
3) Validate the first step so that quantity is now in Input location
4) Create a MO with the component with quantity only in Input location
5) Go to forecast report of component, the quantity is shown not available.
closesodoo/odoo#117372
X-original-commit: 39ff1feae9f44b64ee3fff6ccee837ac4922ad1e
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Ahmed Khalaf <ahkh@odoo.com>
Community PR: https://github.com/odoo/odoo/pull/91187
## Proposed feature and relevance
Add a new retrieval strategy for gathering products: "Least packages".
The goal of this strategy is to select specific product quantities from stock by using as few packages as possible, to allow for efficient logistics operations and avoid unnecessary opening/unpacking of packages.
This strategy will behave as follows:
- In case a negative qty is requested this strategy will behave as a FIFO strategy.
- Otherwise, the strategy will determine a combination using the least amount of packages that sum to the requested quantity, and adapt the provided domain to select only the quantities in these packages. This way no packages need to be opened to select the requested quantity.
- In case an exact matching of current packages to get the requested quantity is not possible, a selection of packages is made where the largest packages are selected one by one until the requested quantity is reached, or until no more quantities are available. For this approach, one package needs to be unpacked as it will not be used completely. The final selected package that will be unpacked will be the smallest one possible, to try to unpack smaller packages over bigger packages.
- In case the search for a minimal matching of packages results in an out-of-memory situation, the strategy will fall back to a FIFO strategy.
- Loose items (not tied to a package) are considered as single-item packages for the purposes of package selection.
- **NOTE:** To force the selection strategy to "clean up" certain packages that have previously been opened, it is recommended to unpack these packages into single items, as they will then be consumed to "fill up" requested quantities in later retrievals.
## Changes to allow more complex strategies
To allow for the integration of this new strategy the structure of `_gather()` needed to be adapted to allow a removal strategy to provide not only the SQL `ORDER BY` string but also adapt the domain used to retrieve the requested quantities.
This change is reflected in the method signature of `_get_removal_strategy_domain_order()`.
## How the strategy works
The strategy does one extra query of the database, to determine the different packages and their respective quantities (using the provided domain).
Loose items (that do not belong to a package) are added as single-item packages to also consider them.
For minimal exact package selection, an A* algorithm is used with 2 performance modifications:
- Using the information that the packages are sorted by size (large -> small).
- Using the information that the generated subtree for a specific package of size x is the same as all other packages of size x at a specific node.
By using the A* algorithm, as soon as a matching packaging selection is found, it is ensured to be optimal and other combinations do not need to be considered.
In case the A* algorithm runs out of memory the provided domain is just returned, which equates to a FIFO strategy.
In case the A* algorithm does not find an exact matching of packages for the requested quantity, a selection is made using the least amount of packages, unpacking the smallest possible package (or until no more quantities are available, in which case effectively all quantities in the domain are returned).
## Used heuristic
The heuristic used for the A* algorithm exploits the knowledge that our packages to select from are ordered by the highest to the lowest quantity (on the database side, SQL `ORDER BY`).
It assumes the "best case scenario" as an estimate for the amount of packages remaining, which is if we were to "match" the required quantity using fractional multiples of the next biggest package size.
***Example**:
Remaining quantity to select: 27
Remaining package sizes to select from: [10, 10, 5, 5, 5, 1, 1, 1]
Heuristic for choosing package with qty 10 as next package: 27/10 = 2.7
Heuristic for choosing package with qty 5 as next package: 27/5 = 5.4
Heuristic for choosing package with qty 1 as next package: 27/1 = 27*
This way the heuristic is always a "best case" (fractional) for the amount of packages that still need to be selected.
As required by the A* algorithm this also results in an underestimation as the fractional result is not possible, and it is not certain that there are still enough packages of this size that can actually be selected, but favours larger packages to make the search converge more quickly.
## Performance
### CPU
Two test cases were run to evaluate the performance.
***Total nr of pkg**: The total amount of different packages generated during data generation
**Qty to select**: The total quantity that needs to be selected
**Selected nr of pkg**: The amount of packages that was ultimately selected by the algorithm
**Data generation time**: The time required to generate all packages
**Assignment time**: The total time to run `_action_assign()` for the move
**A\* time**: The time to run the `_run_least_packages_removal_strategy_astar()` method*
#### First test case
This scenario simulates a case with a large quantity to select from a large amount of packages, but of relatively homogenous size.
Generate 30 different package sizes between 2 and 1000. For each package size, generate 100 to 250 packages each. Also add 100 to 250 "loose items".
The quantity to select is chosen between 1 and 50000.
| RESULTS | RUN 1 | RUN 2 | RUN 3 | RUN 4 | RUN 5 | AVG |
|--------------------------|----------|-----------|------------|-----------|----------|------------|
| Total nr of pkg | 5298 | 5772 | 5855 | 5533 | 5179 | 5527.4 |
| Qty to select | 10319 | 20762 | 44422 | 39306 | 1783 | 23318.4 |
| Selected nr of pkg | 11 | 22 | 48 | 41 | 3 | 25 |
| Data generation time (s) | 64.59124 | 92.916682 | 133.673384 | 82.711438 | 85.54542 | 91.8876328 |
| Assignment time (s) | 4.060216 | 11.212937 | 4.763776 | 8.60248 | 3.461941 | 6.42027 |
| A* time (s) | 0.28 | 6.88 | 0.21 | 3.96 | 0.03 | 2.272 |
#### Second test case
This scenario generates a large amount of small packages of different sizes.
Generate 250 different package sizes between 2 and 10. For each package size, generate 5 to 15 packages each. Also add 5 to 15 "loose items".
The quantity to select is chosen between 1 and 10000.
| RESULTS | RUN 1 | RUN 2 | RUN 3 | RUN 4 | RUN 5 | AVG |
|--------------------------|-----------|-----------|-----------|-----------|----------|------------|
| Total nr of pkg | 2485 | 2406 | 2491 | 2555 | 2542 | 2495.8 |
| Amount to assign | 27 | 4029 | 3966 | 3049 | 1833 | 2580.8 |
| Selected nr of pkg | 3 | 411 | 411 | 306 | 184 | 263 |
| Data generation time (s) | 18.502933 | 18.692048 | 19.969955 | 19.169106 | 19.16439 | 19.0996864 |
| Assignment time (s) | 1.35635 | 7.958852 | 8.470518 | 6.300406 | 3.895457 | 5.5963166 |
| A* time (s) | 0.01 | 0.07 | 0.77 | 0.56 | 0.31 | 0.344 |
### Memory
In cases with large amounts of different-sized packages (200+ different sizes and 200+ packages required to get an exact match) the memory performance of the A* strategy might become problematic.
When lots of packages have the same size (which would be considered typical in cases where there are large amounts of packages) the specific modifications to the A* algorithm ensure that the strategy still delivers good memory performance for this use case as the tree size can be significantly reduced, even with large quantities.
### IO
This strategy only requires one extra SQL query to fetch the different quantities and their respective packages.
## Limitations
No tests for this strategy were done for non-integer quantities. In these cases the performance of the A* algorithm might not be satisfactory and another approach might be preferred.
More research could be done for specific use cases where packaged quantities are non-integer values.
closesodoo/odoo#91187
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Some users were updating their access rights to allow for direct
deletion of quants. This could lead to the infamous:
"It is not possible to unreserve more products of %s than you have in stock."
error since directly deleting a quant bypasses the flows of correctly
unreserving the amounts you are deleting. Therefore we now restrict
the unlinking to:
- when in sudo mode, since the automatic unlinking of zero quants always
occurs in sudo mode.
- stock manager when unlink access right = True. Normally we would allow
any user with the unlink access to do it, but since we are using the
existing `_apply_inventory` to ensure that reserved qtys of the
quant are correctly unreserved before the unlinking, only stock
managers will correctly do this unreservation.
It is expected that some custom code may break due to this restriction,
but if custom code is directly unlinking quants without a sudo or with a
non-stock manager, then the code in these cases probably need to be
fixed anyways since this will cause inconsistent db data and lead to
the error above.
X-original-commit: d1602e7ddefd59cafa1ce0a5522a53c987135858
Part-of: odoo/odoo#115613
A lot of issue with "It is not possible to unreserve more products of ... than you have in stock".
It's the result of a desynchronisation between
`stock.move.line`.`reserved_qty` and `stock.quant`.`reserved_quantity` fields.
It should never happens in theory. However we already faced it a lot due
to bugs/custom code/server actions... It's not trivial to fix because
the issue come from data corruption. So it is hard to spot the different
main issues.
In order to avoid it, this commit try to modify the structure of stock
module. Before the operations was made in this order:
- The `stock.move` checks the quantity available on `stock.quant`
- The `stock.move` write the quantity reserved on the `stock.quant` and
save it in a variable
- The `stock.move` create a `stock.move.line` with the quanity reserved.
The main issue is that a `stock.move.line` could be easily created with
a reserved quantity while the `stock.quant` are not update nor checked.
After this commit the operations will be:
- The `stock.move` checks the quantity available
- The `stock.move` dispatch the available quantity among the `stock.move.line`
based on create or write calls.
- The `stock.move.line` reserve the quantity on `stock.quant`
- If the quantity is bigger than available, we write the max available on
`stock.move.line`
The idea is to respect the different layers
`stock.move` <-> `stock.move.line` <-> `stock.quant`.
Avoid the interactions bewteen `stock.move` and `stock.quant`
This behavior is already well managed in other use cases.
E.g. the real quantity itself, `_do_unreserve` of `stock.move`,...
opw - a lot
Part-of: odoo/odoo#115328
How to reproduce:
- Create a tracked product;
- In the receipt picking type form view, for the lot and serial numbers,
uncheck "Create New" and "Use Existing ones";
- Create a planned receipt for some of this tracked product;
- Confirm and validate the receipt:
It opens the "Immediate Transfer" wizard;
- Apply the immediate transfer:
-> It asks if you want to create a backorder.
Since the picking type doesn't use new or existing LN/SN, it accepts to
be confirmed even if some move lines for tracked product have no
tracking numbers.
The issue was, when a `stock.move` sets its done quantity to its
reserved quantity, if its product is tracked, it doesn't change its done
quantity if it has no tracking number, regardless the picking type's
configuration.
OPW-3186155
closesodoo/odoo#115234
X-original-commit: 89567288e9c134f1262e8ba8b5fc65f730a239cf
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
This commit allows the user to choose which quants to reserve from stock
and the quantity to reserve from each quant, making reservation much more
flexible from the picking form.
In addition, the `reserved_uom_qty` of stock.move.line
is now editable in views to allow for users to change the qty reserved
by existing move lines. When editing the reserved qty, if quantity is not available,
it will reserve only what is available..
closesodoo/odoo#106006
Taskid: 3090913
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
The test returns an error if today is within 365 days before the next 29th February: datetime.date(2024, 3, 1) != datetime.date(2024, 2, 29)
closesodoo/odoo#114053
X-original-commit: 880c0a76ac6333cbc9a8e89c865eb6caf309e0e3
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Diez Stéphane (snd) <snd@odoo.com>
Issue:
Since PR #80434, for versions 15.2 onward stock.move.line changed the
product_qty field to reserved_qty. When doing this change, the compute and
inverse function definitions were changed, but the inverse method on the field
was never corrected. This means that if something tries to write to reserved_qty
a traceback will occur:
AttributeError: 'stock.move.line' object has no attribute '_set_product_qty'
To recreate this error, make a write call on stock.move.line to reserved_qty
and you will get the traceback instead of the UserError.
Solution:
Change the field's definition to the correct function name (_set_reserved_qty)
leads to the proper UserError instead of a traceback.
opw-3204213
closesodoo/odoo#113812
X-original-commit: 5ac0568af2909864a2231309fa3e72397a581957
Signed-off-by: Tiffany Chang <tic@odoo.com>
In `_check_backorder`, changes the condition so it checks if the qty
done is enough compared to the actual reserved quantity (instead of the
demand).
Also, removes an unused bloack of code and makes minor visual changes.
task-3076044
Part-of: odoo/odoo#109511
To reproduce the issue:
(Use demo data)
1. In Settings, enable "Multi Locations"
2. Create a storable and tracked-by-lot product P
3. Create an immediate receipt R
4. Add a line for 1 x P and save
5. Open the wizard 'Detailed Operations' and add a line:
- 1 x P, lot 123, to WH/Stock/Shelf 1
6. Save
7. Open the wizard again
Error: The destination location of the line is now WH/Stock
When creating the SML, because we write on its done quantity, we
will automatically write the same on the new done quantity of the SM
on the demand of that SM. Doing so, it will trigger the assign
process:
https://github.com/odoo/odoo/blob/57ac92fc4c14bf305ffd9ef98212cc80013345f5/addons/stock/models/stock_move.py#L599-L602
(And it will therefore lead to the putaway rules feature)
Once the above issue is fixed, there will be another one. When
marking the SML as done, if it's needed, we assign it a lot. However,
writing on such a field will trigger the reservation process:
https://github.com/odoo/odoo/blob/c9fdd4f2ac2d8afb18cb0dd126bb0b88c54f374e/addons/stock/models/stock_move_line.py#L330-L333
And it will lead, again, to the putaway rules feature
OPW-3086704
closesodoo/odoo#112322
X-original-commit: a3f6cefbbe81bafc0780a95729b8f9150afef817
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
Refactoring of report_stock_forecasted to owl
Since it wasn't really a report (no print action),
it changed from a report to a client action.
Task: 2885757
See Upgrade : odoo/upgrade#3926
See Enterprise : odoo/enterprise#32116closesodoo/odoo#101247
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Before this commit, there is no verification while changing a product's
company. That can lead to issue where some operations cannot be done
because of access errors.
To avoid that, this commit prevents to change the product's company if
some quants for this product exist in another company's location.
How to reproduce:
- Have at least two different companies (let say CompA and CompB);
- Create a new product who belong to no company;
- For this product, add quantity on hand in a CompA location;
- Now, change the product's company for the CompB;
- While selected only the CompA, go into the Inventory Adjustments and
try to create a new inventory adjustment for the CompA location with
this product's quant -> Access Error.
opw-3095984
closesodoo/odoo#110810
X-original-commit: 46987e13f35dc140869c58f6c5a09d9c542c3ae5
Signed-off-by: Tiffany Chang <tic@odoo.com>
Signed-off-by: Steve Van Essche <svs@odoo.com>
Small copy/paste error during odoo/odoo#95332 made it so
`line.picking_id.location_id` was used when assigning `location_dest_id`
of a directly created `move.line` in a picking. Usually this would not
be noticeable due to `default_location_dest_id` in the views ensuring
the correct value, but move lines created directly will be incorrect.
In addition to adding this case to existing test, the test has also been
updated to use non-default locations to ensure no other default values
are causing the result to be correct when it may not be under other
circumstances.
Issue noticed during master refactoring to remove location_id /
location_dest_id fields from views when multi-location is not active.
closesodoo/odoo#110672
X-original-commit: 74bfa154dde72ce792428521aea128408965dcc1
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Signed-off-by: Tiffany Chang <tic@odoo.com>
The `product.product` method `_get_rules_from_location` can call itself
in case `_get_rule` returns a rule using the "Trigger Another Rule"
supply method. But if this rule cannot trigger any other rules,
`_get_rules_from_location` will continue to call itself endlessly until
it reach the recursion's limit, causing a traceback.
How to reproduce:
- In Inventory Configuration, enable "Multi-Step Routes";
- In Configuration > Rules, create a new rule with the following config:
- Action: Pull & Push
- Operation Type: Internal Transfers
- Source Location: same location than the Destination Location
- Supply Method: Trigger Another Rule
- Route: Receive
- Insure the created rule is the only one used by its route;
- Insure there is at least one product who needs to be ressuplied;
- Click on Operation > Ressuply --> traceback.
opw-3068546
closesodoo/odoo#110446
X-original-commit: 511eebf7de4b751b776e7b2d1b1d15a08c53171b
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Steps to reproduce:
- create a storable product with serial_number tracking
- create an confirm a PO that porduct
- recieve the product
- add serial_numbers to the list view and enter a number
- validate the reciept
- an error pops up (You need to supply a Lot/Serial Number for product)
Bug:
entering a serial_number creates a new stock_move_line with qty_done
while also setting qty_done of the already exising line
Fix:
If a stock move line already exists to reserve the product
use the existing line instead of creating a new one
opw-3060668
closesodoo/odoo#110407
X-original-commit: f1541c62b099ab40c295c60e86094232f5c51a2c
Signed-off-by: Steve Van Essche <svs@odoo.com>
Signed-off-by: Walid Hanniche (waha) <waha@odoo.com>
When applying the putaway rules, if we redirect a package (with a
specific type), we don't check the category of the package products.
To reproduce the issue:
1. In Settings, enable
- Packages
- Multi-Step Routes
- Storage Categories
2. Edit the warehouse:
- Receipt: 2 steps
3. Create three categories C1, C2, C3
- Parent: All
4. Create three locations L1, L2, L3
- Parent: WH/Stock
5. For each location Lx, create a putaway rules PRx:
- From: WH/Stock
- Category: Cx
- To: Lx
6. Create a product P
- Type: Storable
- Category: C2
7. Create a planned receipt R with 1 x P
8. Mark it as todo, set the done quantity and put it in pack
9. Set a type on the package
10. Mark R as done
11. Open the associated internal transfer
Error: the destination location of the package is not L2 -> an
incorrect putaway rule has been applied
When we try to apply the PR on the SML "input to stock", because
this is a package with a type, we don't provide the list of the
products. Therefore, we have no idea about the product category.
This is a shame in case of a package that contains some products of
the same category. We should be able to apply the putaway rules
related to that category.
Moreover, this commit also fixes two other issues explained in [1]
and [2]. The FW of these commits have been stopped for the current
one because they didn't fix the above use case. Moreover, this commit
simplifies/clarifies the filtering and sorting of all putaway rules
[1] 03e47b165e7f6c59b41509d9229e8e2074aa3f34
[2] e0098eb281d886797a888a6f8fac474bbacb1b09
OPW-3098452
X-original-commit: c99523bc3a4a5a335f1928cf9bb53bb8483b492e
Part-of: odoo/odoo#109669
Steps to reproduce :
- Create two products
- Create a planned internal transfer with one of each product from Stock
-> Location A
- Hit "Mark as todo"
- Hit "Put in pack"
- Validate the picking
- Create an new planned internal transfer, with the same products and
quantities, but from Location A -> Location B
- Remove the destination package for one product.
- This will remove the destination package for all products in the same
package.
When unlinking a package level, it will unlink all moves and move_lines
at the same time. Problem is that if a single move_line is updated in a
picking where multiple move_lines are in the same package, it will
unlink it for all the move_lines instead.
closesodoo/odoo#107448
X-original-commit: 9dcbc420f50ece3356dff57cbdc467c7893ff2c2
Signed-off-by: Tiffany Chang <tic@odoo.com>
Commit 168cbe66bee7824bdf389de5c6c680342e27bc6d removes fields
with the 'groups' attribute from views when the user is not part
of the groups.
This is the case of product_uom_id in stock_scrap_form_view2,
but the field is mandatory for scrap creation,
therefore we use the unit of measure of the scrapped product
when not provided (as this is the case when uom are not checked).
Task: 2985735
Part-of: odoo/odoo#104062
Issue:
At anypoint we should be able to call the method "_set_lot_ids" from stock.move on moves that are already done and the quantities should not change.
This is not the case for lots that get their quantity changes to 1 as if the product was tracked by serial number.
This commit should be seen a a complement to the commit: https://github.com/odoo/odoo/pull/79565
Fix:
Check the product is tracked by SN before trying to change the quantities to 1.
Related ticket: 2689724
closesodoo/odoo#91769
X-original-commit: b56f96d6d63435d629f0a8137a038dacaf0782fe
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Steps to reproduce:
- Create a product and complete a sales order.
- Then try to change the product type.
- The following message is shown:
"You cannot change the products type because it is already used in sales orders."
However, we can close the message and save.
Problem:
If some sales were already made, it should not be possible to change the product type.
There is a warning message on the onchange but it's not blocking.
This causes inconsistencies between the quantities and value shown in the quants and in the valuation layers.
Solution:
Raise an user error when trying to save the changes.
opw-3000886
closesodoo/odoo#105496
X-original-commit: 1b468ad100960cbd6940a24fbfaeeae4f01994de
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
Suppose a product P with an available quantity equal to 1. Suppose a
user writes on an existing SML for that product and sets the reserved
quantity to 2. When writing on such a field, `StockMoveLine.write` tries
to reserve the same quantity on the quants. If it fails (which would be
the case here because there is only one P available), the reserved
quantity of the SML is reset to 0 (and so does the reserved quantity of
the quant).
https://github.com/odoo/odoo/blob/b8423ba218e0736593c3329d7438ca09112a735f/addons/stock/models/stock_move_line.py#L301-L313
However, there is an issue: the incorrect reserved quantity is still in
`vals`. As a result, later on in the method, this incorrect value is
written on the SML:
https://github.com/odoo/odoo/blob/b8423ba218e0736593c3329d7438ca09112a735f/addons/stock/models/stock_move_line.py#L362
This creates an inconsistency: a SML affirms that 2 x P are reserved
while the reserved quantity of the quant is 0. Moreover, when marking
the SML as done, it will lead to a "unreserve more than..." issue.
OPW-2936689
closesodoo/odoo#100858
X-original-commit: 2ea52bbcdbc2beaac916fa5f127ffc0ab2650708
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
Purpose of the task is to be able to click on inventory adjustment
history and do a reverse adjustment by using `Revert Inventory` action.
`Revert Inventory` action is available in Inventory Adjustments > History
and Product Moves > select some lines > actions dropdown. This
method creates a new move that reverts the quantity (including negative
values) with prefix `[reverted]`.
TaskID - 2859490
closesodoo/odoo#95720
Signed-off-by: Tiffany Chang <tic@odoo.com>
In some cases, when putting in pack, it will lead to a "unreserve more
than reserved" error
To reproduce the issue:
1. In Settings, enable "Packages"
2. Create a storable product P
3. Update the on-hand quantity: 0.4 x P
4. Create and mark as todo a planned delivery order DO
- Operations: 0.4 x P
5. In the detailed operations, set the done quantity to 0.3
6. Put in Pack
7. Open the detailed operations
- Error: There is a line with 0.11 x P reserved instead of 0.10. The
total reserved quantity is therefore 0.41 which is not possible.
Moreover, the available quantity of the related quant is 0.29 which does
not make sense
8. Set the done quantity to 0.1
9. Put in Pack
10. Validate
Error: a User Error is displayed "It is not possible to unreserve more
products of ... than you have in stock." The user is now stuck, he can
neither process the picking nor unreserve it.
On step 6, when putting in pack, we split the SML into two ones. To do
so, we also split the reserved quantity:
https://github.com/odoo/odoo/blob/fcc74186330c8df37cfac08455bd7bba44d4656b/addons/stock/models/stock_picking.py#L1384-L1388
However, because of a floating point issue, we have:
`0.4 - 0.3 = 0.10000000000000003`
Therefore, since we use the rounding method `UP`, we have:
```py
ml.product_uom_qty == 0.4
quantity_left_todo == 0.11
done_to_keep == 0.3
```
And we then use these values to update the reserved quantity on each
SML:
https://github.com/odoo/odoo/blob/fcc74186330c8df37cfac08455bd7bba44d4656b/addons/stock/models/stock_picking.py#L1391-L1398
When writing on that field, we also try to update the quants:
https://github.com/odoo/odoo/blob/55921e32baa1b4b226bd43edf20e93619e411905/addons/stock/models/stock_move_line.py#L378-L383
(As shown, if an error is raised, we ignore it)
After the reservation of `quantity_left_todo`, there are 0.29 x P left.
Therefore, when trying to reserve `done_to_keep`, it will raise an
error:
https://github.com/odoo/odoo/blob/b5d16141dc48d4379452ea40e167f3b00f956c20/addons/stock/models/stock_quant.py#L679-L680
But as shown above, the error will be ignored. This explains the
inconsistency between the reserved quantity on the SMLs and on the
quant.
On step 10, when validating the picking, we try to unreserve all SMLs:
https://github.com/odoo/odoo/blob/55921e32baa1b4b226bd43edf20e93619e411905/addons/stock/models/stock_move_line.py#L570-L572
So we will try to unreserve more than actually reserved on the quant.
That's the reason why an error will be displayed.
OPW-2942054
closesodoo/odoo#98521
X-original-commit: 4f593706ee6d1b3ddf0f1c9c90c86df2977459d9
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
When creating a receipt with products tracked by lot or serial number,
empty move lines are automatically created when the receipt is validated
Steps to reproduce:
1. Install Inventory
2. Go to Inventory > Configuration > Warehouse Management > Operations
Types
3. Open Receipts and enable 'Show Detailed Operations' and 'Pre-fill
Detailed Operations'
4. Go to Overview > Receipts and create a new receipt, in Detailed
Operations add product 'Cable Management Box' with any serial number
and a quantity of 1
5. Validate the receipt, a new line is added in Detailed Operations with
quantity 0
Solution:
When we create a stock move line and we need to create a lot, we create
the lot with the context key `do_not_unreserve`
Problem:
When we create and write the lot on stock move lines, we detect that the
`product_uom_qty` is not set. Because we are in an immediate transfer,
we will try and assign it the `quantity_done`.
https://github.com/odoo/odoo/blob/7fec535f3d84d15899aea5e61b51947f260d9697/addons/stock/models/stock_move_line.py#L467-L469
By writing the `product_uom_qty` on the stock move, we will try to
unreserve and reserve again the stock move (if `do_not_unreserve` is not
in the context)
https://github.com/odoo/odoo/blob/ba3bb9b701a382c4052ddb57392baeee32625937/addons/stock/models/stock_move.py#L569-L576
This will then create the undesired empty move lines (that are supposed
to be the 'Pre-filled Detailed Operations') in _action_assign
https://github.com/odoo/odoo/blob/3e8a45fce0af0aa5792f0aea978d4ab78ab50a40/addons/stock/models/stock_move.py#L1586
opw-2897875
closesodoo/odoo#95983
Signed-off-by: Tiffany Chang <tic@odoo.com>
* commons & setup refactoring:
* convert setUp to setUpClass
* move setups where needed (stock/mrp commons or specific test
classes)
* create test data in batch (faster, less sql queries & batched
operations)
* move most tests post-install to allow runbot splits
* by default, run tests without mail logic
* by default, run tests in a consistent environment (fixed currency
imposed in the BaseCommon)
* refactor existing tests to use new commons data (while trying to keep
diff reduced)
* add dedicated test file to test the common data
* use mute_logger to reduce useless test logs (less spam to scroll in
logs, less data on runbot builds, ...)
Part-of: odoo/odoo#96791
this commit will allow users to setup replenish locations and replenish
them directly if they have negative forecast
instead of checking forecast qty per warehouse,
this adds the abiltiy to replenish to any internal stock location,
marked as replenish location, instead of just the warehouse location
Task Id: 2796757
closesodoo/odoo#93633
Related: odoo/upgrade#3626
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
The render API was confusing as mixing the access to the report and
the rendering env.
The ambiguity was present for code such as
`report.sudo()._render(record_ids)` where it was not clear if the
`sudo()` is needed to access to `report` or to `record_ids`. For low
priviledge users (such as portal or public), it was common to use
`report.with_user(SUPERUSER_ID)._render(record_ids)`.
This PR changes the render methods signature to be `api.model`. The
`report_ref` can be:
- ir.actions.report external id
- ir.actions.report id
- ir.actions.report recod
- `report_name` value
This will allow to call the report methods with any user and no longer
need to use `with_user(1)` to render reports as public user.
Task-id 2670865
closesodoo/odoo#91341
Related: odoo/upgrade#3650
Related: odoo/enterprise#27323
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
When canceling a transfer, all its moves and move lines having qty done
(if any) are canceled as well. But this doesn't happen on package levels
having such move lines with qty done filled, the state was set to
'confirmed' while all its move lines are 'cancel', which was not
consistent.
closesodoo/odoo#96764
X-original-commit: d9b16c3732c7e935c21a0396bb01ed4f19456827
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
When receiving more than expected, we try to redirect the SM thanks to
the putaway rules. This can lead to undesirable behaviors.
To reproduce the issue:
1. In Settings, enable 'Storage Locations'
2. Create a storable product P
3. Edit the operation type "Receipt":
- Show Detailed Operations: True
4. Create and confirm a planned receipt for 1 x P
5. In the Detailed Operations:
- Set the done quantity to 3
- Set the destination location to Shelf 1
6. Validate the receipt
Error: The destination location of the SML has changed: Stock. It should
still be Shelf 1
When validating the SM, because the done quantity is more than the
demand, an exra-move is created. During such a process, the extra move
is confirmed and assigned, so it leads to the destination redirection
thanks to the putaway rules (that's the reason why the destination Stock
will be selected and defined on the SML).
In such situation, we should not try to apply the putaway rules.
OPW-2900283
closesodoo/odoo#96124
X-original-commit: 0183298293192538a801f52262c047ea34a1b76a
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This follows revision
odoo/odoo@9925c8fbaf
On creation of an orderpoint,
if warehouse and location are not specified,
set default warehouse and location
if warehouse is specified but not location,
set default location according to the warehouse chosen
(and not the location of the default warehouse, as formerly)
if location is specified, but not location,
set default warehouse according to the location chosen
(and not the default warehouse, as formerly)
if warehouse and location are specified,
let them, do not overwrite them.
closesodoo/odoo#95851
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
In the web client, in a real use case, it's not possible
to write on fields which are invisible,
as it's not possible to write on fields which are readonly.
This is a first step in the goal to change the behavior
of the `groups=` attribute in the back-end views,
to remove them for the view instead of making them invisible.
This is mainly to reduce the diff of the revision that will introduce
the mentioned above behavior change.
As nodes with `groups=` will be removed from the view
when the user doesn't have the group, it's no longer possible
to set a value on a field having a `groups=` the user doesn't have
in the `Form` test class, as the field will no longer be at all in the
view.
However, these unit tests shouldn't have been able to set values
on invisible fields in the first place.
This revision therefore aims to correct the unit tests setting value
on fields which were invisible because the user executing the
test was not part of the required group(s) for these fields
to be visible in the view.
closesodoo/odoo#94337
Related: odoo/enterprise#28936
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Convert the onchange on `picking_type_id` to a compute field
This allows to create a `stock.picking` record without
the need to specify the locations during the creation nor calling the onchange
method. The locations defaults from the picking type locations.
This way, if the database is not configured to use multi locations,
the users do not have the specify the UOM to use.
For instance during an XMLRPC call to create a picking.
closesodoo/odoo#95423
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This allows to create a stock.package_level record without
the need to set the `location_dest_id` during the `create` call.
For instance, this makes easier to create a package level
using XMLRPC when you do not use multiple locations.
closesodoo/odoo#95361
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This allows to create a stock.warehouse.orderpoint record without
the need to call the onchanges to set the warehouse and location
or to set it manually during the `create` call.
For instance, this makes easier to create orderpoints
using XMLRPC when you do not use multiple locations.
closesodoo/odoo#95352
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This allows to create a stock.move record without
the need to call the onchanges to set the uom
or to set it manually during the `create` call.
This allows to create a stock.move.line record
without the need to call the onchanges to set the uom and locations
or to set it manually during the `create` call.
For instance, this makes easier to create stock moves
using XMLRPC when you do not use multiple UOMs or multiple locations.
closesodoo/odoo#95332
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
In picking type, we introduce a new setting ask-always-never setting for
creating backorder. When a backorder is needed, the behaviour will be
different according to this setting:
- ask: popup a wizard to ask if a backorder is needed
- always: generate backorder automatically
- never: no backorder
The main reasoning behind this change is that there are some scenarios
in which operators always create backorders (e.g. by validating the
transfer after scanning a pallet and setting quantities). Hence, always
asking if the user (operator) wants to create a backorder can be confusing.
task-2648993
Part-of: odoo/odoo#83462
- Install stock
- Go to Inventory > Configuration > Settings and enable "Lots" and "Storage Locations"
- Create a Product tracked By Lots (i.e. Product X)
- Go to Inventory > Operations > Inventory Adjustments
- Create an Inventory Adjustment for Product X:
Product | Location | Lot/SN | Real Quantity
-------------------------------------------------------------
Product X | WH/Stock | LOT 01 | 20
Product X | WH/Stock | | 10
- Validate Inventory
- Go to Inventory > Operations > Transfers and create one:
* Source Location: WH/Stock
* Destination Location: WH/Stock/Shelf1
* Operation Type: Internal Transfers
* Operations:
[Product: Product X, Initial Demand: 25]
- Save Transfer, Mark As Todo and Check availability
- Click on list icon of Operation line for Product X to display Detailed Operations
- 20 units of LOT 01 and 5 units without lot have been reserved
- Set LOT 01 for the 5 reserved units without lot and confirm
- Open Detailed Operations again
- There are now 20 units of LOT 01 and 5 units of LOT 01
- Remove the row with 5 units and confirm
- Check availability and open Detailed Operation
- There is now only a row with 25 reserved units of LOT 01
- Unreserve
The following errror is raised:
"It is not possible to unreserve more products of P than you have in stock."
It happens because the system is not able to manage quants with lots and
wihtout lots at the same time. When modifying the move line to 25
reserved units. It's composed of 20 quants with lot and 5 quants without
lot. And when unreserving it will check if there is a quants with 25
units with the lot and if it's not found 25 units without lot. But never
25 units of quants with lots and without lots.
opw-2419444
Close#64497closesodoo/odoo#66029closesodoo/odoo#93141
X-original-commit: 83d55d8ed8b8b5a5232e3cdfc09abf5285f18ed7
Signed-off-by: Arnold Moyaux <amoyaux@users.noreply.github.com>
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
When moving some products between two warehouses thanks to an internal
transfer, the forecasted inventory becomes incorrect
To reproduce the issue:
1. In Settings, enable "Multi-Warehouses"
2. Let WH01 be the existing warehouse. Create a second one WH02
3. Create a storable product P
4. Update the quantity of P:
- 3 in WH01/Stock
5. Create a planned and internal transfer T:
- Source: WH01/Stock
- Destination: WH02/Stock
- Ignore the warning
- Operations:
- 1 x P
6. Mark T as todo
7. Open the Forecasted Inventory:
- Filters:
- Forecasted Stock
- Product: P
- Group By: Warehouse
Error: The report is incorrect, it says there are 3 P in WH01 and 0 in
WH02 (should be 2 and 1). It becomes worst if T is done (the quantities
in the past become incorrect)
We should be able to move a product between two warehouses thanks to an
internal transfer (so the warning of the step 5 should be removed).
Moreover, the `report.stock.quantity` should consider that use case.
When processing a stock move, the SQL view translates it as an in-move
or out-move for a specific warehouse. For instance, if the SM comes from
a warehouse and goes to a location without any warehouse (e.g., customer
location), the SM is considered as an out-move. But here is the issue:
in case of an inter-warehouse SM, both source and destination have a
defined warehouse.
Therefore, we need to:
- Duplicate the inter-warehouses SM (so we have one in and one out)
- Fake the values (no destination warehouse for the out move, no source
warehouse for the in move)
Also, before duplicating all SM, we filter out some useless SM:
- Draft and cancelled ones
- SM done more than 3 months ago (because the report only works for [-3
months; +3 months])
Considering some tests:
(SM are confirmed. Each test has been repeated 5 times to get an
average)
| | |
|:-------------------------------------:|:--------:|
| 5000 SM, 0% inter-wh, without the fix | ~715 ms |
| 5000 SM, 0% inter-wh, with the fix | ~710 ms |
| Impact | 0.99x |
| | |
| 6666 SM, 0% inter-wh, without the fix | ~911 ms |
| 5000 SM, 33% inter-wh, with the fix | ~999 ms |
| Impact | 1.10x |
| | |
| 7500 SM, 0% inter-wh, without the fix | ~1004 ms |
| 5000 SM, 50% inter-wh, with the fix | ~1097 ms |
| Impact | 1.09x |
The impact is not that significant
OPW-2752017
task-2822157
closesodoo/odoo#91772
X-original-commit: b1efc0243bbf886bbef42a32587f4a818fa34e64
Signed-off-by: Arnold Moyaux <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>