No formal decision there, and the stdlib API seems like a PITA as it's
based around native strings, not bytes and not text.
* try to use cross-model API instead of random encode/decode
* unicode all the mail_template things
* formataddr *requires* a text tuple now
In P2, formataddr((False, False)) "worked" (generated "False
<False>"), in P3 it will fail and blow up.
* attachments are quite definitely bytes
* remove try_coerce_ascii because it's garbage
XMLRPC dumps returns text rather than bytes (for reasons unknown),
which does not suit Werkzeug's WSGI server, we need to encode the
body.
For simplicity and future-proofiness, return Werkzeug responses
instead, Werkzeug takes care of encoding text and passing bytes
through.
Otherwise when the subquery is somehow injected in the parent
query (didn't find where but...) it's b-prefixed and treated as a
binary rather than a sub-query somehow, which fails.
* IrValues.value should be a binary field, since pickle encodes
objects to bytes
* Which means the "action" string must be encoded before storage and
decoded before use
* Remove complete garbage mess of random encodings during XML
conversion, this probably still requires serious thinking and fixing
but it seems to run for now (yay)
* unichr -> pycompat (builtin removed from Python 3, ``chr`` has
become unicode-aware)
* Psycopg2 bytea values (binary fields) are returned as memoryviews in
P3 but buffers in P2
* Both bytes and (text) strings are conventionally iterable in
P3 (they have a __iter__ method), so fix up the exclusion pattern
for flatten
* remove references to basestring & unicode (use relevant pycompat
helpers)
* remove some str calls (either entirely or replaced by relevant
helper, either text or native)
* use better API to avoid unnecessary conversions
* remove some XML declarations in views
* StringIO removed from stdlib, replace with io
* try to correctly handle BytesIO/StringIO (one is for bytes the other
is for text)
* fix base64: Python 3 removed bytes-encoding and bytes-bytes
codecs (via #encode) so replace all calls to str.encode('base64'),
also b64encode is a bytes->bytes conversion so attempt to properly
handle that
issue #8530
So that was a fun one: mock.patch calls would regularly fail refusing
to find the addon in odoo.addon (e.g. essentially getattr(odoo.addon,
'account_budget' deep within the bowels of mock).
Turns out the answer is that our import hooks would not be used for
many imports: while in Python 2, sys.meta_path is empty and the
default finders are run after all meta_path finders fail as noted by
the documentation[0].
However when the import system was rewritten in Python 3.3[1]
meta_path was "despecialised" and the default finders were moved to
meta_path rather than be a hidden part of the import machinery[2]:
> sys.meta_path and sys.path_hooks now store all of the meta path
> finders and path entry hooks used by import. Previously the finders
> were implicit and hidden within the C code of import instead of
> being directly exposed.
The result of this change is that ``sys.meta_path.append`` means the
default finders should take priority and the custom ones should be
fallback. This is the exact opposite of what we want.
Fix issue by ``sys.meta_path.insert``-ing our finders at the start of
the path rather than appending them at the end. This should change
nothing in Python 2 but seems to fix the issue in P3.
[0]
https://docs.python.org/2/library/sys.html?highlight=meta_path#sys.meta_path
[1] https://docs.python.org/3/whatsnew/3.3.html#importlib
[2] https://docs.python.org/3/whatsnew/3.3.html#visible-changes
https://bugs.python.org/issue13936
That's a pretty sensible change, but it turns out we did have some
bits of resource which implicitly depended on the old behaviour.
In Python 2, hasattr swallows *any* exception raised during the
access. In Python 3, it only swallows AttributeError.
Accessing an attribute on an unbound threadlocal proxy raises
RuntimeError, while running test_ir_http_mimetype ``request`` is
unbound, in Python 2 ``hasattr`` would return ``False`` on an unbound
threadlocal, in Python 3 it lets ``RuntimeError`` pass through blowing
up the test.
Fix this by just checking if the threadlocal is bound by using it as a
boolean…
In Python 3 round:
* rounds half to even (banker's rounding) rather than up
* returns an int if not given a precision (or given a precision of
None)
* discards the negative sign when rounding to 0
Add a compatibility shim which implements P2 behaviour and at least
allows passing float_utils's tests.
Implementing float_round on top of Decimal was attempted but did not
work: although Decimal.quantize takes a non-integral
Decimal (e.g. ``d.quantize(D('0.001'))``) it only supports integral
powers of 10 and does not support quantizing to e.g. 0.05: while that
will not fail it will just use the exponent for quantization and 0.05
is thus equivalent to 0.01, which is not what we want if e.g. need to
round a value to 5 cents.
This is hinted at but maybe not clearly spelled out by the official
documentation:
> Return a value equal to the first operand after rounding
> and **having the exponent of** the second operand.
Also convert a bunch of hand-rolled currency rounding to just using
the round() method on res.currency.
Use case to reproduce the bug:
- Set multi location in settings
- Set warehouse's deliery method as pick/pack/ship
- Deliver a product to customer
- Process a return from customer to output.
- Create a return from output to pack ->
Unable to reserver product.
It happens because return moves where not linked together but have
the picking that created the return as origin.
Thus action_assign does not detect the return moves and can't
guess the real quantity available.
This commit add a behavior that will create links between
return move. It can be guess from parent move(the picking's move from which
the return is created) and its move dest/orig that have already
created other return. It also correct action assign because
the group by could retourn same line with return moves.
It add a test that check returns and links between them.
When deacreasing a quantity on a PO it will decrease the quantity
of an associated move. When the move's quantity reach 0, previously the
move was unlinked and aslo the picking if all moves inside were unlinked.
However the destination move(s) still exist with the quantity that has been
removed in the original move. It can confuse the end user which have a move without
origin.
This commit cancel the move/picking instead of unlink them. Thanks to this
the end user still have the link with the original moves and can guess from where
their destinations moves come from. It also remove the filter on PO in order
to display the canceled picking.
commit 0a960c08757a8ba5e1dc1dd36c17a35de8913975 introduced change about
reserved quantity that set it to 0 once the move is done.
This commit add views improvement. If the move lines are done
reserved quantity does not really matter and thus it is better
to not display it.
Modify the decorator on stock picking that change the font to red
if the quantity processed is greater than the reserved quantity.
This decorator does not trigger if the picking is in state done since
reserved quantity is always 0.
When validating a stock picking there were 2 different cases:
(1) If all qty are equal to 0 it will display a wizard asking
if the user want to set the quantity done to the reserved quantity
for all moves. If the user accept it will automatically perform the
moves after setting the quantity done.
(2) If the user set a quantity on a move, it will check if there is
a need for a back order. If yes it will display a wizard asking if
a back order is needed or not.
However the check if a back order was needed or not was never perform
in case 1. If the quantity reserved was lower than the initial demand
a back order was automatically created.
This commit add the step 2 in the procedure of step 1 (after setting the
quantity done).
The quantity reserved for move was never modified once the move
is done. It is a nonsense to have a reserved quantity for a done
move.
This commit add a constraint that ensure the quantity of
move line to be 0 if it is in state done. Also it add a write
on move_line's 'action_done' function that set the reserved quantity
to 0 for all move line processed.
It does not introduce any change on the stock move itself since the
reserved quantity is the sum of all its move lines's reserved quantity.
- When registering a payment token, validating it using a payment of a small amount (~1.50€) followed by a refund allows ensuring
that the payment method is valid (i.e. checksumming the card number simple ensure the number is valid but not that the card exists).
This commit introduces a generic approach that must be implemented for each acquirer that has tokenization support.
This commit also introduces a generic payment token registration/usage template that can be adapted according to one's need.
- Introducing a new payment form that handles payment, deletion and adding payment method (only for server2server for the moment).
- On /my/payment_method, changed strings 'Payment Acquirers' to 'Payment Methods' which is more clear.
- Stripe can now be used to pay subscriptions.
It happens because the function still use the old fields
utilized before refactoring introduced by commit b3180c8411
This commit adapt the function by using quantity instead of qty.
When deciding to prefetch records (getting records from the cache with
no value for the field being fetched), if the field was computed
`determine_value` would just get all records, not limited by the normal
prefetch limit; for large recordsets this would generate gigantic
prefetch lists for records we may not need at all.
Fix by applying the `PREFETCH_MAX` limit to records from the cache as is
done in `_prefetch_field`.
Complementarily, when traversing related fields the prefetch
environment would be lost and every record would get an empty prefetch
environment, so the values would ultimately be read one by one.
Example: select (search) 1000 product.product records, access a
related field (e.g. categ_id) in a loop, on the first iteration the
system would first read 1000 templates, then it would read each
categ_id individually, resulting in >1000 SQL queries rather than the
~2 we would expect.
Fixes#18511
A form view record may be saved even if the record is displayed in
readonly (e.g. when a button in the form view is clicked). When
this happened, if there were an html field with html_frame widget
in the form, it crashed (e.g. in Email Marketing > Mass Mailings >
open one > click on Test Mailing).