`_action_done` could unlink a quant. This happens when moving a product from a
location to another one and makes null the quantity of this product in one of
theses locations. In this case, we unlink the quant because it is now useless
and could be confusing on reports based on quants.
The unwanted side effect is that unlinking a record will invalidate the cache. In
some pathologic cases, like making an inventory adjustment of 600 products
and reseting their quantity back to 0, the time of the operation is around 15
minutes. With this patch that tries to work carefully with the cache invalidation,
the same operations takes around 15 secondes.
This commit do not unlink quant anymore, instead it use a 'garbage
collector' on quants without quantity. The garbage collector is trigger
on the scheduler and when the user open the inventory view.
In the detailed operations view and in an immediate transfer:
- add a line
- select a random lot_id
- select a random product_id
- validate
The system won't raise while the combination of product_id/lot_id may
not make sense. We add a constraint to solve this isse.
Closes#25766
opw-1868453
Usecase to reproduce:
- Create a receipt for 1 dozen.
- Mark as todo
- Unlock and update initial demand to 3 dozen.
The reserved quantity on move line is 36 dozen.
It happens because reserved_availability and product_qty are
compare. However reserved_availability is in move UoM and product_qty
is in move's product UoM.
This commit clean the code in order to compare field that use the same
UoM.
Close#26504
- Create a product A tracked by S/N
- Get some stock of A
- Create a SO and sell 1 unit of A, confirm
- Go to the picking, validate
An error message forces the user to manually encode the 'Done'
quantities.
This step is not necessary, since the user will still get a message
notifying him that the reserved quantities will be used as done
quantities.
opw-1873180
From this commit onwards, Date fields will return datetime.date objects and Datetime fields will return datetime.datetime objects, this implies a number of things that are clearly explained both in the ORM API for master.
This commit also introduces a number of helper functions for dates and datetimes that are exposed in tools.date_utils and fields.Date[time], explained in the documentation as well.
Task-ID: 47189
PURPOSE
=======
1. Unified product demo data
2. Less demo: one per use case
3. Demo data for all models
Specification
=============
1. Refactor all the brol in the demo data
2. Adapt the tests to make them green, as some products are
renamed, removed, created in python instead of as demo data
...
- Create a product with -4.0 Units in stock
- Set the Buy and MTO routes, assign a vendor
- Create a SO for 25 Units
- A PO of 25 Units is created => validate and receive products
- Check availability on the picking linked to the SO
Nothing is reserved, while 21 Units could be reserved.
opw-1850688
Co-authored-by: Nicolas Martinelli <nim@odoo.com>
Steps to reproduce the bug:
- Create a stockable product P tracked by serial number with route BUY
- Create PO with 5 P and validate the PO
- On the picking, just set one serial number and create a backorder
- Go on the backorder
Bug:
8 lines were created:
- 4 lines with one reserved quantity
- 4 lines with no reserved quantity
Now only 4 lines with one reserved quantity are created.
opw:1847714
- Create a BOM for Product A, using Component B
1 Unit of a is built with 1 Unit of B
- Update on hand quantity for B to 3.0
- Create a MO for 5 Units of A
- Update the quantity to produce to 3.0
The button 'Check Availability' never disappears.
The core of the problem is that the move remains "Partially Available".
Indeed, if there is no product available (`available_quantity <= 0`),
the stock move is skipped and its availability status is not updated.
We slightly change the logic by first checking if we need any quantity.
If not, the move can be considered as assigned.
opw-1850499
The transfers are either 'planned' or 'immediate' but the process are sensibly the
same. This commit separate clearly the two possible pickings (with a new boolean field)
and simplify the view of immediate ones. This kind of transfer is pretty straightforward
so only the 'Done' column remains and the text stays written in black.
This commit remove force_assign method in every tests of point_of_sale, purchase, sale_mrp,
sale_stock, stock and stock_account . This method is not longer used since V11.
This commit is related to task ID 59417
In a situation where there's a negative quant next to a positive one,
they should be merged when the scheduler runs or when the user open its
inventory view. However, if in the meantime the user reserves and
unreserves, there may be some issues.
The system will only reserve on positive quant ;
the system will unreserve on the first encountered quant (even negative)
The issue is the second part of the early break condition:
float_is_zero(available_quantity, precision_rounding=rounding):
The issue here is `available_quantity`. In a reservation scenario, it
represents the maximum quantity we can reserve across quant. It is
useful so we do not lose time loopin over quants where nothing will be
available. In an unreserve scenario however, it represented the same
thing, which is wrong. In the case you reserved all the quantities,
`available_quantity` will be 0 we'll loop only on the first quant where
we won't do anything.
As the code doesn't check the success or failure of the unreserve, move
lines were unlinked while the reserved quantity on the quants were not
updated, resulting in the desynchronization of the move lines/ reserved
quantities.
This continues the work done at [1] to track down the "cannot unreserve
more than" errors.
[1] cce6030c0d
Do not try to keep the reservation when creating a backorder for two
reasons:
1) it doesn't make sense since the backordered move will only be
confirmed while it got some reserved move lines
2) with badly configured uom's rounding, it is possible that the
initial demand of the backorder is inferior to the now reserved
quantity
We also fix another "cannot unreserve more than available" cause that
could happen in the second case ; let's imagine in the second case that
the backordered quantity is 0.999, `_update_reserved_qty` will reserve
0.999 on the quants but do not create a move line as range (0, 0.999)
will not return anything.
We remove `test_split_1` as it tested a behavior we removed and add a
new test showing a new flow with what we fixed.
Please note that setting the rounding of unit to 1.0 would have
prevented all the issues here.
Followup of rev 383947646f
Let's say you have 6 units and you try to reserve a dozen while the
rounding of the dozen is 1.0. The previous commit correctly only allows
to reserve 12 units, and handle correctly forced quantities in other
compatible UOM, all that with extra moves/backoders.
But we missed an important issue: if now you have 12 units, you will
reserve them. If these 12 units are split across quants, i.e. some are
in another sublocations or are assigned a special lot_id, then we'll
again have rounding issue because the reservation was always expressed
in the move's uom while sometimes it is not possible to go back and
forth between the move uom and and the product's uom. In other word,
we'll reserve 12 times 0 dozen and get stuck at the next step.
This patch now only reserve a quantity if the quantity is expressible in
the rounding's UOM. If this quantity is split across multiple move
lines, we'll make the move line reserved in the UOM of the quants if
necessary. We also do not apply the rounding down -> halfup dance if
`_update_reserved_quantity` is called with the force argument set as
True (meaning, in an mto scenario). The change in
`_prepare_move_line_vals` will make the move lines in the uom of the
qants and everything should be good. With the last change, we need to
adapt the test added by the previous patch, else we won't be able to
make a chain of 2 move moving producst tracked by serial number if the
rounding of the dozen is set at 1.0.
opw-1835186
opw-1835946
There's a certain configuration of UOM that is not correctly handled in
the v11 stock:
- create a move with an UOM having an higher factor than the product's
UOM
- this higher UOM has a rounding of 1.0, meaning it doesn't allow
partial reservation
- use the product's uom in this move and enter quantities that aren't
expressible in the move's uom
A practical example is to set the rounding of dozen at 1.0, set the uom
of a product to units, create a move for a dozen and create a new move
line with 8 units.
The first issue is the `quantity_done` field, that uses an half-up
rounding on the `qty_done` field of each move line and sum them. When
applying this logic to the previous example, `quantity_done` field would
be 1.0, meaning we won't make a backorder for the missing 4 units. We
fix these issue by summing a non rounded qty_done and afterwards
rounding this value to the general products'UOM. This mean
`quantity_done` is technically not be expressible in the move's uom, but
keeping this value close to the reality will allow to handle the
backorders and extra moves correctly.
The second issue is that the backorder is always expressed in the move's
uom. In the previous example, this would mean creating a backorder of 0
dozen. In v10, an error was throwed, saying this operation is
impossible.
The `_prepare_move_split_vals` previously always received the quantity
of the backordered move in the uom of the original move. This is a
remnant of the v10 implementation where, if the quantity to backorder is
not expressible in the original move's UOM, an error was throwed. We now
pass the used uom via a context key to not update the method signature,
as it is probably legitimately overidden by custom modules. This way, in
the previous example, a backorder of 4 units is created.
The last issue is in `_action_assign`. Let's say you have 8 units in
stock and you want to reserve a dozen, the system will reserve 8 units
and then convert back 8 units in dozen, meaning a dozen was reserved.
This resulted in awkward situation where more items than available were
reserved, and the famous "cannot unreserve more than what's available in
stock" was throwed at almost each operation. To solve this, we convert
the not-yet reserved quantities back and forth in both uom. This
prevents partial reservation when not allowed, which is good. We had to
adapt some lines of `_action_assgn` that expected
`_update_reserved_quantity` always at least partially reserved the move.
It is now possible that it doesn't reserve anything.
We also normalize the quantity with a greater decimal precision when
deciding if we open the immediate transfer wizard or not (in the
original exemple, if you enter a single unit the immediate transfer
wizard would be openned because 0 was done in the UOM of the dozen). We
also prevent to enter `qty_done` on the move line if the value doesn't
honour the rounding of the UOM.
We introduce two tests, a simple `_action_assign` in MTS and a more
complete MTO scenario with backorders, extra moves and invalid qty_done.
opw-1835186
opw-1835946
This commit allows to define a putaway strategy by product. Before
this commit, it was only possible to define a putaway strategy by
category.
We add a second one2many on the model 'product.putaway': the original
(fixed_location_ids) is used for the putaway per category, the new one
(product_location_ids) is used for the putway per product.
The two one2many are displayed on the putaway strategy and a domain on
the fields is used to filter the records between them. Inline tree view
add a required on the product_id on the one2many per product and a
required on category_id on the one2many per category.
If a putaway strategy per product AND per category match for a product,
the putaway per product takes precedence
This task also reword some tooltips.
We add some testcases to display the behaviour
- when a putaway per product is applied
- the conflict between a putaway per product and category
- the fallback to the category when nothing is found on the product
Task 23495
PR #20143
In a situation where `_action_done` is called on a batch of move line
when one of them is forced and there isn't enough quantity available
to reserve it, a call to `_free_reservation` is made in order to not
have move lines reserved on quantity now unavailable.
The issue is that the method looks for move line to unlink by making a
search on move line having a quantity reserved. As the `_action_done`
method defer the update of the reserved quantity at the end of the
batch, `_free_reservation` could try to find and unreserve move lines
that were juste processed, resulting in a traceback because there isn't
enough stock to unreserved (because the move line was processed and thus
moved at the next location).
We fix this issue by explicitely passing the move lines to ignore.
Moves UoM models, test and data to a new addon in
order to be able to use uom without product.
A simple example is be to be able to use UoM for
timesheets.
This commit only move code, and adapt xml ids
without chaging any feature or functionnal
behavior.
Note: 'product' module now depends on new
'uom' module.
Before the patch, validating a picking where one of its move do not
have any quantity done nor quantity reserved resulted in the complete
validation of the said move. This doesn't make sense and does not do
what the help in the wizard indicate (process only *reserved* quantities).
We also use this patch to clarify what the tests on this workflow is
doing (test_immediate_validate_*). We completely replace the 3 as it was
testing the `force_assign` mechanism, which methods are still present in
v11 but unused. Instead this test is now testing the failing flow this
commit is fixing.
We thus adapt the `process` method of the immediate transfer to only
process the move lines (move line = reservation). We also fix a case
where nothing is reserved and nothing is done. In this case, the
backorder wizard should not opens but instead an UserError telling the
user to either cancel or process something. The testcase for this flow
is test_immediate_validate_7.
With these changes, the test `test_04_create_picking_update_saleorderline`
was failing because one of the items in the so lines was a stockable
product without stock. So before this patch, everything was processed,
now there's a backorder wizard. We complete the patch and duplicate it
with enough products in stock, so that the backorder wizard is not
needed.
opw-815056
opw-808126
- create a product comp1 tracked by lot
- make an inventory adjustment for comp1 ; 1 quant with lot1 and 1 quant
without lot
- create a bom for product finished1 composed by 1 comp1
- create a mo for 1 finished1, reserve it
- the mo reserved the quant with lot1
- produce finished 1
- unlock the mo
- change the component from lot1 to lot2 (that do not exist)
- the write on a move line will trigger a re-reservation that will
fallback on the quant without a lot (that's how untracked quant for
tracked products are handled)
- delete the move line, it'll unreserve with lot2 and fail
We fix the issue by applying the same logic of fallback on the untracked
quants in the unreserve of a move line.
We add a test for the unreserve of a move, as it simply unlink the move
lines.
opw-814914
Use case to reproduce:
- create a product A with serial number
- add 2 product A in stock
- create a delivery order with this 4 product
- Check Availability
- add 2 more product A in stock
- Check Availability
- in the first line the quantity is now 3
It happens because _update_reserved_quantity on stock move
try to add the quantity reserved on simililar move lines.
Howevever in serial case we don't want to have a move line
with a reserved quantity greater than 1.
to reproduce:
- have 4 units of product 1 in stock
- create a move for a dozen, reserve it
- try to scrap a single unit
- an exception "cannot reserve more than available" is raised
To reflect the change of reservation after scrapping the quantity, we
have to update the reserved quantity on the move line.
When updating the quantity on the move line, "quantity_split" is in the
quant uom, so it should be converted to the uom of the move line.
The condition in `_free_reservation` explicitely ignore move lines
having a done quantity. Let's imagine the scenrario where two stock
moves reserve all the quantity available and the user chose to process
all the quantity in a move while another user already set half the
quantity as reserved. In this case, we should keep the processed
quantity on the other move but correctly remove its reservation.
When the result packaged is changed on a move line, we should not change
the reservation of quants, because result_package is not related to
reservation, only package_id is used during the reservation.
We also changed the copy of move_line when we split a move line to put a
part of it in a package. By copying the move line and set the
product_uom_id in the default values of copy function, we mess the
reservation, because there is no quant reservation made for the move
line even if the move_line has a product_uom_qty. So we set the
product_uom_qty to 0 when copying the line, and then write the
product_uom_qty which will call the quant reservation
Fixes#20784
It is not possible to work directly on the operation tab
when the detailed operation tab is available. On detailed
operations page it is now impossible to add a new move line
when the picking is done and locked.
This commit add some condition in the view and add a check
in the move line creation. If the move line has a picking but
no move then we create it (mark as done directly)
When undoing the original move line, make sure to handle the packages
correctly (in the destination location, undo the result package, not the
source one.