Needs work
Project:
Commerce Stock
Version:
8.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
9 May 2019 at 11:49 UTC
Updated:
10 Jun 2021 at 12:58 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
olafkarsten commentedSounds like a legitimate feature. Hope you understand, that this is not on top of the list. Before we are finetuning the ux, we have to ship a stable release. Anyway, thanks for your input and please keep posting. We really appreciate your feedback.
Comment #3
daveianoThank you for your fast response!
I fully understand that there are other priorities for the beta release. Nevertheless, I can manage to get some time for implementing this, and by looking at the database structure I don't think this would be too difficult to implement (we have all necessary information in the
commerce_stock_location_leveltable).Any feedback on how this should be implemented is also very appreciated! And also if this makes sense now with the possible upcoming changes in mind?
Comment #4
olafkarsten commentedSounds great. We gladly accept patches, of course.
My Feedback:
At a first glance that looks like a easy task, but I doubt it is. This is a potentially expensive screen. We should implement some measures to prevent killing a website. Also, it doesn't seem to scale very well. You can easily have thousends of product variations. Even with 15 locations, that will end in a screen/report you can't work with, without any proper paging and filtering.
Is this really a report/screen we need? Or should we limit this for one product and its variations.
I would strictly decouple the parts where and how we get the data and how we present them. I guess the problem is, that we need variation specific data. In the stock related database records we only keep the purchasable entity id. So you need to fetch the SKU/Label or whatever you want to show from the variation.
Even if we refactor the datamodel, it should be possible to change the data fetching code without much hazzle.
Minor:
I don't see the why we need a total per row - how many product variations in that location.
Comment #5
daveianoThis is also a valid point. Perhaps the first step should be to provide a list for the Stock level Field Widget, which shows the stock for each location, not only the summed up stock level?
This whole data presenting layer should be implemented via views, shouldn't it? So we are talking about the views integration of the stock locations. After a quick search, I found some open tickets for views integration. So the first step should be to make progress with the views integration?
You are right, in most cases, the total per product should be important, not the total per location.
Comment #6
daveianoSo I got some time to look into these things: First thing I noticed, is that we should really implement these UX things with views to benefit from the flexibility provided by views.
First thing I did was to remove all the code from
modules/local_storage/commerce_stock_local.views.incand put it intomodules/local_storage/src/Entity/StockLocationViewsData.php. The docs say:(https://api.drupal.org/api/drupal/core%21modules%21views%21views.api.php...)
I then removed some parts of the old hook_views_data definition because of the Implementation of EntityViewsData, Drupal automatically catches the entity fields definitions. Then I added and corrected some relationships (just like in https://www.drupal.org/project/commerce_stock/issues/3027543).
With these changes, the duplicates of "Stock location" and "Commerce Stock location" disappeared from the "Create new view" form. I also created a relationship to the
commerce_stock_location_leveltable to access the stock level per location.I created two views (configs are attached):
I can imagine that we could add a configuration in the "stock_level" field widget to show these views in the form or display mode to give more information and flexibility?
The second question I got is: should we use the data from the
commerce_stock_location_leveltable to provide the level or should we calculate these values based on the transactions? I did not have enough time to look into the logic, but I assume it should be transaction-based, and thecommerce_stock_location_leveltable is just a cache table?Comment #7
daveianoComment #8
daveianoI extended the patch and changed the following in the StockLocationViewsData class:
From
to:
I added a new stock_location_level field formatter in the field submodule, which shows the stock from a specific location (you can configure which location, I also updated the schema). The new formatter also calculates the stock level transaction-based, it does not simply get the data from the database.
This way it is now possible to create a view like shown in the issue description:
Comment #9
daveianoAccidently changed issue description.
Comment #10
gge commentedHello,
I tried #8 but unfortunately there's a problem with
stock_location_level.If I try to use it in views, only the "Simple stock level formatter" works. When
Stock level formatter by locationis chosen, the following error is logged:AssertionError: Cannot load a NULL ID. în assert() (rândul 249 din /home/public_html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php) #0 /home/public_html/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(249): assert(false, 'Cannot load a N...') #1 /home/public_html/web/modules/contrib/commerce_stock/modules/field/src/Plugin/Field/FieldFormatter/StockLevelFormatterByLocation.php(96): Drupal\Core\Entity\EntityStorageBase->load(NULL) #2 /home/public_html/web/core/modules/views/src/Plugin/views/field/EntityField.php(519): Drupal\commerce_stock_field\Plugin\Field\FieldFormatter\StockLevelFormatterByLocation->settingsForm(Array, Object(Drupal\Core\Form\FormState)) #3 /home/public_html/web/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php(167): Drupal\views\Plugin\views\field\EntityField->buildOptionsForm(Array, Object(Drupal\Core\Form\FormState)) #4 [internal function]: Drupal\views_ui\Form\Ajax\ConfigHandler->buildForm(Array, Object(Drupal\Core\Form\FormState)) #5 /home/public_html/web/core/lib/Drupal/Core/Form/FormBuilder.php(519): call_user_func_array(Array, Array) #6 /home/public_html/web/core/lib/Drupal/Core/Form/FormBuilder.php(276): Drupal\Core\Form\FormBuilder->retrieveForm('views_ui_config...', Object(Drupal\Core\Form\FormState)) #7 /home/public_html/web/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php(214): Drupal\Core\Form\FormBuilder->buildForm('Drupal\\views_ui...', Object(Drupal\Core\Form\FormState)) #8 /home/public_html/web/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\views_ui\Form\Ajax\ViewsFormBase->Drupal\views_ui\Form\Ajax\{closure}() #9 /home/public_html/web/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php(216): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #10 /home/public_html/web/core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php(125): Drupal\views_ui\Form\Ajax\ViewsFormBase->ajaxFormWrapper('Drupal\\views_ui...', Object(Drupal\Core\Form\FormState)) #11 /home/public_html/web/core/modules/views_ui/src/Form/Ajax/ConfigHandler.php(39): Drupal\views_ui\Form\Ajax\ViewsFormBase->getForm(Object(Drupal\views_ui\ViewUI), 'page_1', 'ajax') #12 [internal function]: Drupal\views_ui\Form\Ajax\ConfigHandler->getForm(Object(Drupal\views_ui\ViewUI), 'page_1', 'ajax', 'field', 'field_stock_lev...') #13 /home/public_html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #14 /home/public_html/web/core/lib/Drupal/Core/Render/Renderer.php(582): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #15 /home/public_html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #16 /home/public_html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #17 /home/public_html/vendor/symfony/http-kernel/HttpKernel.php(151): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #18 /home/public_html/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #19 /home/public_html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #20 /home/public_html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #21 /home/public_html/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php(49): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #22 /home/public_html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Asm89\Stack\Cors->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23 /home/public_html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24 /home/public_html/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25 /home/public_html/web/core/lib/Drupal/Core/DrupalKernel.php(693): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26 /home/public_html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #27 {main}.Right now, this seems to be the only way to see the stock level per location but it doesn't work...
Thank you!
Comment #11
daveianoOk, you can try to add a view by doing the following:
This is my whole view:
Your error message looks like you forgot to configure your stock location in the field settings ("Location" autocomplete field in the first screenshot).
Let me know if this helps!
Comment #12
olafkarsten commentedComment #13
olafkarsten commentedThe patch is to big and tries to do to much. We should have split the issues. One for the views integration, on for field formatter stuff.
I think this is right for the stock location data. But I think we should keep the transaction data definition in the views.inc file. These are not entity related data. I'm not sure for the commerce_stock_location_level data. I'm okay with putting them in the StockLocationViewsData class i guess.
We calculate location stock levels per queueworker, so this data could be total valid or outdated, it depends on how often cron runs and how fast you are selling stuff. It's the responsibility of the user to adjust his system. So we can and should use the commerce_stock_location_level.
We need tests for all this, too.
- So lets split up the issues first. Remove the stock level field stuff from here and put it in own issue.
- Address the stuff above.
- Add tests.
Comment #14
guy_schneerson commentedHaven't properly reviewed this yet but just wanted to second olafkarsten. Currently the only way to get the stock level is using the API. The commerce_stock_location_level should not be used directly.
Comment #15
lukasss commented+1 for this
Comment #16
lukasss commentedI think this has long been in need of processing.
It is currently impossible to create a normal views with commerce_stock_location.
I see https://www.drupal.org/node/2433153
Maybe we need to remove the 'data_table' key from the annotation altogether?
Without it, I can create a view and all the entity fields are available to me.
What do you think?
Comment #17
daveiano@olafkarsten @guy_schneerson Thanks for the feedback.
What I noticed in the first place: Arent these completely different arguments?
and
So what to do?
@olafkarsten Ok, I also think the patch is too big. I will split this issue into several sub-issues and add them as a reference to this ticket, you should be notified about that!
Comment #18
daveianoAdded the first split-up issue as a reference
New Field Formatter for Stock level field - Stock Level by Location
Comment #19
daveianoOk I reviewed my old code. The remaining patch (see comment #8) is about exposing the
commerce_stock_location_leveldatabase table to views. The patch includes the views data defined incommerce_stock_local_views_data()for the table, and a viewfield to render stock level by location.But the question is if this data should even be exposed, in my understanding there are different opinions (see comment #17).
The only thing missing in the views data in my opinion is the relationship between the commerce_stock_transaction and the commerce_product_variation:
With this change, you can access the product variation data in a stock transaction view. See attached patch for the change.