Commit Graph

156 Commits

Author SHA1 Message Date
roykho c73ce8ea04
Convert to using internal DI container 2021-04-16 12:23:40 -07:00
Claudio Sanches d6e3cf6de9 Update default GIT branch 2021-02-25 20:51:14 -03:00
Nestor Soriano 9ef18fea0e Change the calculate_refund_amount_from_line_items method
to return the calculated amount instead of setting it in the request.
2021-02-16 15:44:51 +01:00
Nestor Soriano fae00e2bdf Make the refunds creation REST API behave more as documented
- Allow the list of line items to be a non-associative array
  where each item is identified by an "id" field
- Same for taxes inside line items, specify amount to refund in
  a "refund_total" key as in the case of line items
- Allow "quantity" keys as synonyms of "qty"

Also calculate "amount" automatically if missing and when all the
line items and taxes have a valid "refund_total" key.
2021-02-11 09:51:13 +01:00
Nestor Soriano 2c957d2531 Merge branch 'master' into fix/25900-take-2 2021-01-29 10:00:51 +01:00
Fernando Marichal a3471b47d6 Fixed method adjust_download_permissions
This commit fixes the method "adjust_download_permissions" since we're getting an error if the received product id is not valid.
2021-01-27 13:25:06 -03:00
Claudio Sanches bf7fe82da4 Fixed woocommerce_activated_plugin docblock 2021-01-18 17:37:42 -03:00
Claudio Sanches e9abfa1669 Fixed docblock of new hooks of 5.0 2021-01-18 13:44:15 -03:00
Roy Ho 4c548951f4
Merge pull request #28521 from woocommerce/fix/26475
Create additional download permissions on product save if needed
2021-01-18 06:51:57 -08:00
Claudio Sanches d60ffa1e73
Merge pull request #28405 from szepeviktor/patch-5
Fix .gitignore
2021-01-15 11:19:37 -03:00
Nestor Soriano 8b0bd248d6 Attach hook for adjust_download_permissions from within init_hooks
The DownloadPermissionsAdjuster class hooks to adjust_download_permissions
from within its init method. However this method is executed only
if the class is resolved, otherwise the hooks doesn't get attached
and then the scheduled action is not serviced.

To solve this, the class is resolved from WooCommerce::init_hooks.
This requires a change in DownloadPermissionsAdjuster::init
to use wc_get_container()->get( LegacyProxy::class )->get_instance_of
instead of WC()->get_instance_of, since WC() can't be used from
WooCommerce::construct (which invokes init_hooks).
2021-01-14 11:40:11 +01:00
Nestor Soriano 2ec002defa Add unit tests for DownloadPermissionsAdjuster::adjust_download_permissions 2021-01-13 12:11:15 +01:00
Ilyas Foo 0e5596d1fc Transient and action passes plugin filename 2021-01-13 09:52:17 +08:00
Nestor Soriano 2d83db8b66 Add tests for DownloadPermissionsAdjuster::maybe_schedule_adjust_download_permissions
Also replace direct invocations of functions with usages of the
LegacyProxy whenever needed, and code style ajustments.
2021-01-12 12:07:38 +01:00
Nestor Soriano 10eb9f832e Remove one of the duplicate handlers for 'adjust_download_permissions' 2021-01-12 10:15:53 +01:00
Ilyas Foo 7f76d91b07 Delete transient before action to prevent race condition 2021-01-08 16:03:38 +08:00
Ilyas Foo d49783871a Update to signature compatible with activated_plugin hook 2021-01-01 12:24:04 +08:00
Ilyas Foo 0e590d1bdb Add transient and action for proxying WC plugin activation hook 2020-12-31 14:30:29 +08:00
Nestor Soriano f0b834d1ec Move the download permissions adjustment process to a scheduled action.
Also, move all the new code from the 'WC_Product_Data_Store_CPT' class
to a new separate 'DownloadPermissionsAdjuster' class.
2020-12-10 15:40:38 +01:00
Viktor Szépe 70e2a16c6f
Fix .gitignore 2020-11-25 06:48:13 +01:00
Christopher Allford c9f413d297 Created dummy `woocommerce/woocommerce-lib` package to contain dependencies
In order to avoid problems posed by potentially including the unconverted dependencies in the root autoloader, this package will hold all dependencies that require conflict avoidance.
2020-11-18 13:54:20 -08:00
Nestor Soriano 5509e2185c Add src/Internal/Vendor/League to source control. 2020-11-05 17:21:38 +01:00
Nestor Soriano 8bb0f196e6 Change the strategy for moving packages
Since the Mozart package requires PHP 7.2, and we need to support 7.0
and 7.1, the moving step has been removed from the composer install
stage. Instead, now it has to be triggered manually via
`composer run move-vendor-namespaces`, and the moved package must be
added to source control. See the updated src/Internal/Vendor/REAMDE.md
for details.
2020-11-05 17:19:14 +01:00
Nestor Soriano d620f1d232 Fix #25900 - image size customisation controls not shown
- Added the `ThemeSupport class`, with methods to add and get
  theme support options.
  - It also has a new `add_default_options` method that adds the
    options under a `_defaults` key.
- The `WC_Twenty_*` classes now use `ThemeSupport` instead of
  the `add_theme_support` function to define image and thumbnail sizes.
  - The values are defined as default options.
- The `WC_Shop_Customizer` class now uses `ThemeSupport` instead of
  `wc_get_theme_support` to check if image and thumbnail sizes UI
  should be rendered.
  - The check is made excluding default values.

With these changes the UI to change the image and thumbnail sizes
is hidden only if the options are added as non-defaults elsewhere.

Additional changes:

- The code of the `wc_get_theme_support` function is replaced with
  a simple call to `get_option` in `ThemeSupport`.
- Added the utility class `ArrayUtil`.
2020-11-04 13:01:53 +01:00
Nestor Soriano 96fce186e7 Use Mozart instead of a script to renamespace packages.
A custom fork of the coenjacobs/mozart package is now used to change
the namespace of the appropriate packages (only league/container
for now) instead of the previously used prefix-vendor-namespaces script.

The packages are now moved to the src/Internal/Vendor namespace instead
of being modified in-place in the vendor directory. The namespaces
are thus now prefixed with Automattic\WooCommerce\Internal\Vendor
(previously it was just Automattic\WooCommerce\Vendor).
2020-10-30 12:28:26 +01:00
Nestor Soriano 9aaee3dab9 Fix for compatibility of reflection function with PHP 7.0 2020-10-19 08:44:47 +02:00
Nestor Soriano 042e2cd0bb Fixes in the dependency injection engine for PHP 8 compatibility
- One dummy class used for tests had a 'final private' method, this
  is not allowed in PHP 8 and so the method is now just 'private'.

- The AbstractServiceProvider class was using
  ReflectionParameter::getClass. This is deprecated in PHP8 and thus
  that usage has been replaced with an utility method that uses
  the recommended replacement.
2020-10-16 11:31:26 +02:00
Néstor Soriano c15488d840
Merge pull request #27830 from woocommerce/php8/fix-round-function-with-non-numeric-argument 2020-10-09 08:01:44 +02:00
Nestor Soriano ac0641d02a Fix a couple of incompatibilities with NumberUtils::round
- Passing a string that represents a number but has spaces (e.g. ' 1 ')
  now works as expected (the number is properly interpreted)
- Passing the boolean true now returns 1, not 0
- Passing an object throws an error, instead of returning 0
2020-10-08 13:13:53 +02:00
Nestor Soriano b71f876cba Reintroduce the dependency injection related code.
After the League's Container package has been reintroduced, all the
code that implements the dependency injection mechanism in woocommerce
can be brought back as well.
2020-10-08 09:28:05 +02:00
Nestor Soriano 52eed70f04 Add a 'NumberUtil' class with a 'round' method.
There's a number of places in the WooCommerce codebase where the
built-in function 'round' is executed passing a non-numeric value
(not a number and not a string that can be parsed as a number),
for example round(''). In PHP 7 this yields a value of 0, but in
PHP 8 this throws an error.

This commit adds a 'NumberUtil' class with a static 'round' method,
this method checks if the passed value is numeric and if so it just
executes the built-in function, otherwise it returns 0. And all the
calls to 'round' in the codebase are replaced with 'NumberUtil::round'.
2020-10-01 11:08:51 +02:00
Nestor Soriano 4058371b07 Add a notice in readme about the DI being disabled 2020-08-19 11:31:02 +02:00
Christopher Allford 358db5dc3e Removed the internals of the Container pending package conflict resolution
Since reverting the PR at this point would be a mess I've gone ahead and removed the internals of the container. We should aim to keep the class since it's now part of our public API but it won't work as expected anymore. This is fine for now since we don't actually have anything in it!
2020-08-18 20:39:48 -07:00
Claudio Sanches 37291abc54 Added since tag in new filters introduced in 4.5 2020-08-17 18:01:41 -03:00
Claudio Sanches 3d0b38740b
Merge pull request #27285 from woocommerce/fix/make-typehints-specific-in-src
Removed the general `object` type hint from docblocks
2020-08-12 21:41:01 -03:00
Christopher Allford 7071c6dc0c
Merge pull request #27228 from woocommerce/feature/container-injection-change
Dependency Injection should use method injection instead of constructor injection
2020-08-12 12:41:48 -07:00
Peter Fabian ca33f6b218 Removed the general object type hint.
Since the methods actually expect the actual object type, it's probably better to include a narrower specification than overly general `object`.
2020-08-11 15:14:13 +02:00
Ron Rennick cbfe4bd595
Merge pull request #26166 from Chouby/reserve_stock_filter
Add filter for the query for reserved stock
2020-08-10 16:42:04 -03:00
Christopher Allford f6515f4b1a Removed unnecessary @package tags 2020-08-07 16:47:07 -07:00
Christopher Allford 12397aec0e Added `_with` suffix to `StringUtil` methods for clarity 2020-08-07 16:45:35 -07:00
Christopher Allford eb65252ba8 Merge branch 'master' into feature/container-injection-change 2020-08-07 14:35:44 -07:00
Christopher Allford 081f0d9133 Settled on an injection method of `init`
1. Since our code style dictates that these be `final` methods, we shouldn't be concerned about overlap.
2. There is precedent for `init` methods as requirements before using class instances.
2020-08-07 14:28:29 -07:00
Claudio Sanches 02cf0dfaed
Merge pull request #27239 from woocommerce/fix/package-tag
Fix usage of "package" tag in file headers
2020-08-07 13:37:24 -03:00
Néstor Soriano 459dd3fbf2
Merge pull request #27251 from woocommerce/fix/27226
Added woocommerce_order_item_quantity filter to ReserveStock::reserve_stock_for_order
2020-08-07 16:11:43 +02:00
Christopher Allford 154c812fc0 Renamed the `StringUtility` to `StringUtil` to make it easier to work with 2020-08-06 12:35:51 -07:00
Claudio Sanches 2d2e40c484 Applied woocommerce_order_item_quantity to ReserveStock 2020-08-06 14:15:50 -03:00
vedanshujain 1c162956ad Remove REST API package check as files are directly added. 2020-08-06 14:34:02 +05:30
Christopher Allford 39376abfd2 Added a requirement that `container_init` methods be marked `final` when registering using reflection 2020-08-05 22:34:00 -07:00
Christopher Allford ff6e30f1c1 Renamed `set_internal_dependencies` to `container_init` 2020-08-05 22:20:13 -07:00
Christopher Allford cbbfed4989 Replaced the rest of the constructor injection references 2020-08-05 21:28:06 -07:00
Claudio Sanches 3632714885 Removed package tag from src 2020-08-05 14:23:50 -03:00
Claudio Sanches a50552af75 Use only WooCommerce as package name 2020-08-05 14:11:20 -03:00
Christopher Allford d178c7ff01 Replaced constructor injection with method injection
Since we need to maintain backwards compatibility for class constructors we should settle on using method injection instead of constructor injection. I've replaced the `Definition` class we're using with one that doesn't support constructor arguments and added a check for auto_arg addition. Note that we don't check for method existence in the extended container. This is because reflection is unnecessarily expensive and we should avoid it if at all possible.
2020-08-04 20:37:28 -07:00
Christopher Allford 767fb048fc Fixed comments with incorrect namespaces 2020-08-03 14:00:14 -07:00
Christopher Allford 5e354c451c Removed the define for the `JETPACK_AUTOLOAD_DEV` constant
This is likely something that should be part of the `wp-config.php` for development environments of feature plugins as opposed to defined here.
2020-07-30 14:55:14 -07:00
Christopher Allford 08575b1661 Added JETPACK_AUTOLOAD_DEV flag to autoloader
Since Composer assigns dev versions to locally checked out repositories (most of the time) we need to set this flag. If we don't tell the autoloader we want to use dev versions then it will always prioritize the package classes over the plugin classes.
2020-07-27 09:40:55 +02:00
Christopher Allford 5afab2b03d Removed the temporary PSR-4 autoloader
This was added to get around a limitation in the Jetpack Autoloader 1.x branch. Since dependencies could not be used before `plugins_loaded` without throwing a notice we needed a custom autoloader to run before it in order to prevent the notice from showing.
2020-07-27 09:40:55 +02:00
Nestor Soriano e55ef052a2 Add documentation about the container and good coding practices.
- src/README.md largely expanded
- tests/README.md expanded
- includes/README.md added
- src/Internal/REAMDE.md added

src/README.md and includes/README.md have TODO placeholders to add
guidelines regarding to actions and filters.
2020-07-24 09:25:12 +02:00
Christopher Allford 811ac747e6 Added callable reflection to `add_with_auto_arguments`
This allows the dependencies of the callable function to be automatically resolved out of the container too!
2020-07-24 09:25:12 +02:00
Nestor Soriano 408295720c Fix LegacyProxy::get_instance_of for classesd having an `instance` method.
Pass the arguments as `...$args` instead of `$args`.
Also fix related unit test, and remove unnecessary `is_function`.
2020-07-24 09:25:12 +02:00
Nestor Soriano bd1e6a5db0 Add the ContainerException class, use it for dependency injection related errors. 2020-07-24 09:25:12 +02:00
Nestor Soriano 71462e33f3 Improevements on ExtendedContainer and LegacyProxy documentation.
Also, remove a not really needed `try` block in LegacyProxy::get_instance_of.
2020-07-24 09:25:11 +02:00
Nestor Soriano 65b5cbe692 Improve AbstractServiceProvider::add_with_auto_arguments
If a class name is passed as a concrete, check that the class
constructor is public if it exists. If another type of concrete is
passed, check that it's valid (a callback or an object).

Also update the autoloader to check if the class file exists,
otherwise class_exists fails if a namespaced class doesn't exist.
2020-07-24 09:25:11 +02:00
Christopher Allford 24f9738913 Reworked the temporary PSR4 autoloader to better support more namespaces
Since we want to avoid all of the jetpack-autoloader errors I've reworked the temporary autoloader to support defining the namespace it should load from.
2020-07-24 09:24:06 +02:00
Nestor Soriano 29cf161415 Small changes after review feedback:
- Method and class renames.
- Removed unnecessary autoloader registration.
- Add a unit test for classes with non-object type hints
  in constructor arguments.
2020-07-24 09:24:06 +02:00
Nestor Soriano 1684ce08b3 Removed annotations as we're not going to use them. 2020-07-24 09:24:06 +02:00
Nestor Soriano 4ec143532c Adjustments in the LegacyProxy class.
- `get_instance_of` accepts now arguments to be passed to the
  class constructor if necessary.
- `get_special_instance_of` method removed, instead, now if a method
  named `get_instance_of_<lowercased class name>` exists in the class,
  it is used to get the instance of the class.
- A couple more unit tests added.
2020-07-24 09:24:06 +02:00
Nestor Soriano 282d1dab86 DependencyManagement code folder moved inside an Internal folder. 2020-07-24 09:24:06 +02:00
Nestor Soriano 044a79d941 Added unit tests for `LegacyProxy` and `MockableLegacyProxy`.
Also:

- Added sutoloader for the `tests/tools` directory.
2020-07-24 09:24:04 +02:00
Nestor Soriano c9154d071c Add tests for `AbstractServiceProvider` and `ExtendedContainer`.
Also:

- Make the methods in `AbstractServiceProvider` protected.
- Add an autoloader for files in the `tests/php/src` directory.
- Fix a bug in the provisional (?) autoloader.
2020-07-24 09:23:05 +02:00
Nestor Soriano d55f7d10f8 Some small imrpovements in the dependency injection framework:
- camelCase methods changed to snake_case for consistency with WP.
- Added a check in `ExtendedContainer::get` that throws an informative
  exception if a non-namespaced class name is passed.
- `container->reset_resolved()` is called during unit testing bootstrap.
- Added some utility methods in `WC_Unit_Test_Case`.
2020-07-24 09:23:05 +02:00
Nestor Soriano ca9ed93b9a Added dependency injection infrastructure for unit tests:
- Added a new class `ExtendedContainer` that extends League's container.
  - `add` modified to reject classes not in the root Woo namespace.
  - Has two new methods, `replace` and `reset_resolved`.
  - It's used as the underlying container instead of League's one
    in `Container`, but the new methods are not exposed.
- At unit test bootstrap time the globally registered container is
  replaced with the extended one that `Container` stores
  (grabbed from private property using reflection).
- A new `MockableLegacyProxy` is added. It inherits from `LegacyProxy`
  and allows to mock functions, static methods and legacy classes.
  - The registeed `LegacyProxy` is replaced with the mockable version
    during unit test bootstrap.
- A PHPUnit hook is added to reset the mockable proxy to its initial
  state (so that nothing is mocked) before each test.
- `WC_Unit_Test_Case` gets helper methods to mock functions, static
  methods and classes without having to retrieve the proxy class.
2020-07-24 09:23:05 +02:00
Nestor Soriano 03bcf515c1 `DependencyManagement` and `Proxies` directories moved.
They have been moved out of the `Tools` directory to the root
`src` directory, `Tools` doesn't exist anymore.
2020-07-24 09:23:05 +02:00
Nestor Soriano b53fc512bf Some changes on the dependency injection engine based on feedback:
- `wc_get_container` declares a return type now.
- The autoloader now runs before `autoload_packages.php` is included.
- The autloader now excludes the namespaces for Admin, Blocs, Rest API.
- `private $container` in `Container` is now declared as being
  of type `\League\Container\Container`.
- The underlying container is registered with `share` instead of `add`.
- All methods in `AbstractServiceProvider` now allow passing a concrete.
- `AbstractServiceProvider::addWithAutoArguments` now checks if an
  argument has a default value, and registers the argument so that
  that value is supplied when constructing the object.
- `Proxies` class renamed to `ProxiesServiceProvider`.
- The methods to call code in `LegacyProxy` now use `call_user_func_array`.
2020-07-24 09:23:05 +02:00
Nestor Soriano 064ae558ab Changes in the overall organization of the dependency injection:
- The `Container` class now implements `Psr\Container\ContainerInterface`
  (and registers itself as such), holding a private instance of the
  real container. This way it's a read-only container from the point
  of view of plugins (which should use their own containers, but
  can still use this to get WooCommerce classes).
- All registrations are now done in the `Container` constructor via
  service providers.
- The container instance is now held in a global variable, set in
  `woocommerce.php`
- Added the `wc_get_container` function for old code.
- Added the `AbstractServiceProvider` class, which inherits with the
  corresponding League's class and adds some utility methods,
  most notably `add/shareWithAutoArguments`.
- Added the `ActionsProxy` and `LegacyProxy` classes, they are
  registered via a dedicated service provider.
- `WC_Queue_Interface` is no longer resolvable via the container
  (which is for classes inside `src` only).
- All the method names in the new classes have the format `fooBarFizz`
  to be PSR4 compliant, so the MethodNameInvalid error has been
  disabled in phpcs.xml for the `src` directory.
- Introduced the `@public` annotation for public API classes
  (classes that plugins can use and whose backwards compatibility
  we guarantee), applied to `ActionsProxy` and to `LegacyProxy` for now.
- Removed the hack for the autoloader as now it doesn't work anyway.
  For the changes in this branch to work, now WP_DEBUG must be false.
2020-07-24 09:23:01 +02:00
Nestor Soriano a7829525eb Changes in the dependency injection container:
- Renamed from `ObjectContainer` to `Container`.
- It now inherits from PHP League's `Container`.
- It has now a `defineAsSharedAutowired` method.
- Initialization moved to the `WooCommerce::init_container` method.
- The static method for object resolution is now `WooCommerce::get_instance_of`.
2020-07-24 09:20:24 +02:00
Nestor Soriano 281ec18158 Undo the registration of old singletons in the DI container.
The container will in principle be used only to register classes
in the `src` directory.

Also, CustomerProvider class removed.
2020-07-24 09:20:24 +02:00
Nestor Soriano 518c52b829 Move PSR4 autoloading from woocommerce.php to the Autoloader class 2020-07-24 09:20:24 +02:00
Nestor Soriano 312383ae47 First steps towards introducing a dependency injection framework.
- Add PHP League's Container package via Composer.
- Add an ObjectContainer class that encapsulates all the configuration
  and insulates the codebase from the concrete DI engine used.
- Add an improved ReflectionContainer class that will allow to
  register individual classes as singletons while autowiring.
- Use ObjectContainer to resolve the WooCommerce class, everything
  instantiated with "new" inside it, and all singletons that are
  usually obtained via WC() function.
- Introduce the CustomerProvider class.
- Introduce a service provider to resolve WC_Queue_Interface,
  this replaces the WC_Queue class.
- Mark as obsolete all the replaced "instance()" methods,
  and the entire WC_Queue class.
2020-07-24 09:20:21 +02:00
Vedanshu Jain a34835e489
Merge pull request #26932 from woocommerce/fix/25442
Show community forum link if wccom is not connected
2020-07-16 00:14:52 +05:30
vedanshujain aabf4bfe37 Add unit tests. 2020-07-15 15:27:34 +05:30
vedanshujain 4500e86198 Shorten class and method names to reduce redundancy in naming. 2020-07-15 15:20:18 +05:30
vedanshujain 1e68ce5dc9 Move function to src for better code architecture 2020-07-14 23:31:56 +05:30
Peter Fabian d54a2c3b2f Removed type hints.
Based on the design committee, we've decided not to use 'old' classes from the includes folder in new code in the 'src' directory. Thus removing those type hints, but leaving them in the docblock to not lose the information.
2020-07-06 15:36:33 +02:00
Claudio Sanches 2869867e35
Updated since tag 2020-06-24 13:08:08 -03:00
Frédéric Demarle 7c7e17dcd0 add filter woocommerce_query_for_reserved_stock
Remove previosuly proposed filter woocommerce_reserve_stock_for_products
2020-06-18 14:12:00 +02:00
Mike Jolley 00f1246553 Update reserved stock when a row already exists 2020-06-18 12:09:57 +01:00
vedanshujain d21cc596df Return early in release stock function if stock reservation is disabled. 2020-06-15 18:40:03 +05:30
vedanshujain 79e13edff0 This commit adds two changes for reserved stock functionality:
1. Use '0000-00-00 00:00:00' instead of CURRENT_TIMESTAMP as default value to support MySQL 5.6
2. Return early if DB version is less than 430 because then it would mean that required wc_reserved_stock table might not be present.
2020-06-05 19:20:06 +05:30
Vedanshu Jain b45373fe0c Revert "Revert "Introduce a `reserved stock` class and database table to prevent race conditions during checkout"" 2020-06-05 15:18:01 +05:30
Christopher Allford 1b2f5ab4ad Added handling to prevent namespace conflicts with included packages
The root namespace of Core is Automattic\WooCommerce, but both the blocks and wc-admin plugins exist in this namespace. In an effort to prevent possible conflicts, we should not allow for overlap in our repository. The rationale behind doing this as opposed to renaming our root namespace feels reasonable. In the case of Blocks, all of the tooling is already set up in their repository, so all blocks should go there anyway. In the case of WC-Admin, we shouldn't be refactoring admin classes, as that would duplicate work done to revamp them entirely.
2020-04-28 14:04:00 -07:00
Vedanshu Jain ee119e0a7e
Revert "Introduce a `reserved stock` class and database table to prevent race conditions during checkout" 2020-04-21 15:37:21 +05:30
Frédéric Demarle 2a70859888 Remove extra @since 2020-04-12 18:03:54 +02:00
Frédéric Demarle 9da21bc841 Add filter for products to reserve stock 2020-04-12 17:50:55 +02:00
Christopher Allford 09df1205de Updated the minimum PHP version to 7.0 2020-04-06 17:07:33 -07:00
Mike Jolley 0cce3c5c45 Missing abspath check 2020-04-03 16:16:20 +01:00
Mike Jolley f248902454 Update versions 2020-04-03 15:56:43 +01:00
Mike Jolley 107879950e Remove get_query_for_stock as it's part of data-store 2020-04-03 15:55:15 +01:00
Mike Jolley c983677a6f Implement stock functions 2020-04-03 15:55:15 +01:00
Mike Jolley d2d0967ac0 Introduce class to handle stock reservation 2020-04-03 15:55:14 +01:00