I read in the plan for commerce kickstart 2 that you concidered stock levels but ran out of time.

The module http://drupal.org/project/commerce_stock seems to work ok.

It would be nice to be able to edit the stock quantities like the price is admin/commerce/products under the quick edit link.

How could I make the stock levels editable inline?

Thanks for any help

Comments

would love to know too!

Upvote, but extend this further to the "Disable Stock For this Product" option.

Project:Commerce Kickstart» Commerce Backoffice
Version:7.x-2.x-dev» 7.x-1.x-dev
Status:Active» Fixed

The quick edit form is provided by the Commerce Backoffice module.
There's no UI no manage that.
Here's the code that manage that part :

<?php
/**
* Form callback: Returns the form for modifying the product price and status.
*/
function commerce_backoffice_product_quick_edit_form($form, &$form_state, $product) {
 
$form_state['product'] = $product;
 
$price_array = $product->commerce_price[LANGUAGE_NONE][0];
 
$price = commerce_currency_amount_to_decimal($price_array['amount'], $price_array['currency_code']);
 
$wrapper = drupal_html_id('commerce-backoffice-product-quick-edit-form');
 
$form['#prefix'] = '<div class="container-inline" id="' . $wrapper . '">';
 
$form['#suffix'] = '</div>';
 
$form['price'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Price'),
   
'#title_display' => 'invisible',
   
'#default_value' => sprintf("%.2f", $price),
   
'#size' => 5,
  );
 
$form['status'] = array(
   
'#type' => 'select',
   
'#title' => t('Status'),
   
'#title_display' => 'invisible',
   
'#options' => array(0 => t('Disabled'), 1 => t('Active')),
   
'#default_value' => $product->status,
  );
 
$form['save'] = array(
   
'#type' => 'submit',
   
'#value' => t('Save'),
   
'#ajax' => array(
     
'callback' => 'commerce_backoffice_product_quick_edit_form_ajax',
     
'wrapper' => $wrapper,
    ),
  );
  if (!empty(
$form_state['product_saved'])) {
   
$form['save']['#suffix'] = t('Saved');
  }
  return
$form;
}
/**
* Ajax callback for commerce_backoffice_product_quick_edit_form.
*/
function commerce_backoffice_product_quick_edit_form_ajax($form, &$form_state) {
  return
$form;
}
/**
* Submit callback for commerce_backoffice_product_quick_edit_form.
*/
function commerce_backoffice_product_quick_edit_form_submit($form, &$form_state) {
 
$product = $form_state['product'];
 
$currency_code = $product->commerce_price[LANGUAGE_NONE][0]['currency_code'];
 
$product->commerce_price[LANGUAGE_NONE][0]['amount'] = commerce_currency_decimal_to_amount($form_state['values']['price'], $currency_code);
 
$product->status = $form_state['values']['status'];
 
commerce_product_save($product);
 
$form_state['rebuild'] = TRUE;
 
$form_state['product_saved'] = TRUE;
}
?>

If you want to alter that, you could alter the form add the fields you want and replace our submit callback.

Fair enough.

Status:Fixed» Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Status:Closed (fixed)» Active
StatusFileSize
new2.61 KB

Hi,

I'm trying to make a patch, but when i saved the value of stock and reload the page, only the first digit was saved. Eg. enter 423 => saved 4

My code snippet:

function commerce_backoffice_product_quick_edit_form($form, &$form_state, $product) {
(...)
  $stock = $product->commerce_stock['und'][0];
(...)
  $form['stock'] = array(
      '#type' => 'textfield',
      '#title' => t('Stock'),
      '#title_display' => 'invisible',
      '#default_value' => $stock,
      '#attributes' => array('title' => 'Estoque'),
      '#size' => 5,
   );
(...)

function commerce_backoffice_product_quick_edit_form_submit($form, &$form_state) {
(...)
  $product->commerce_stock['und'][0] = $form_state['values']['stock'];
(...)

At this moment, I don't run verification modules, etc.

Why only the one first digit is saved ?

Thanks!

StatusFileSize
new16.41 KB

Solved by correcting:

$stock = $product->commerce_stock['und'][0];

To:

$stock = $product->commerce_stock['und'][0]['value'];

Now, the value of the stock can changed here.

This is my first contribution to code, so my apologies to any failure. ;)

Thanks coyoterj for the inspiration but I think its better to use a alter function like jsacksick suggested.

This function you can use in a custom helper module

<?php

/**
* alter function for commerce_backoffice_product_quick_edit_form.
*/
function YOURMODULE_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){
 
$product = $form_state['product'] ;
 
$form['commerce_stock'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Stock'),
   
'#default_value' => $product->commerce_stock['und'][0]['value'],
   
'#size' => 5,
  );
$form['#submit'][] = 'YOURMODULE_commerce_backoffice_product_quick_edit_form_submit';
}
/**
* Submit callback for commerce_backoffice_product_quick_edit_form.
*/
function YOURMODULE_commerce_backoffice_product_quick_edit_form_submit($form, &$form_state) {
 
$product = $form_state['product'];
 
$currency_code = $product->commerce_price[LANGUAGE_NONE][0]['currency_code'];
 
$product->commerce_price[LANGUAGE_NONE][0]['amount'] = commerce_currency_decimal_to_amount($form_state['values']['price'], $currency_code);
 
$product->status = $form_state['values']['status'];
 
$product->commerce_stock[LANGUAGE_NONE][0]['value'] = $form_state['values']['commerce_stock'];
 
commerce_product_save($product);
 
$form_state['rebuild'] = TRUE;
 
$form_state['product_saved'] = TRUE;
}
?>

Hi rbosscher,

I knew it had to do, but did not know how. :)
Well... I put the code in my module, but not worked. The field "stock" does not appear in the form :(
Yes, I cleaned all caches. :)
Then, I will study your solution and post here if I find something.

Thanks!

Probably obvious, but just to be sure:

Make sure you replace YOURMODULE with your module name (its in there 3 times)
Make also sure your stock field has the machine name commerce_stock (Not sure this could be anything else but will not hurt to check)
Safe, clear caches, fingers crossed... :)

Yes, I replaced the name YOURMODULE.
Yes, the fields's name is the same. You can check in previous posts.
Does the problem is not here ?

$form['#submit'][] = 'YOURMODULE_commerce_backoffice_product_quick_edit_form_submit';

I say this because of ajax call:
'callback' => 'commerce_backoffice_product_quick_edit_form_ajax',

/**
* Ajax callback for commerce_backoffice_product_quick_edit_form.
*/
function commerce_backoffice_product_quick_edit_form_ajax($form, &$form_state) {
  return $form;
}

<?php
$form
['#submit'][] = 'YOURMODULE_commerce_backoffice_product_quick_edit_form_submit';
?>

Overwrites the default submit handler (commerce_backoffice_product_quick_edit_form_submit) with the new attached submit handler

<?php
function YOURMODULE_commerce_backoffice_product_quick_edit_form_submit($form, &$form_state) { .. }
?>

I Think I know what the problem is:

replace

<?php
function YOURMODULE_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){
?>

whit:

<?php
function YOURMODULE_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$form_id){  
?>

Hi rbosscher
Forgot a small detail ??
Or it was just a test with me ? :)

The problem is here:

function YOURMODULE_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){

Replace with:
1.
function YOURMODULE_form_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){

And

2.
$form['commerce_stock'] = array with $form['stock'] = array

3.
$product->commerce_stock[LANGUAGE_NONE][0]['value'] = $form_state['values']['commerce_stock']; with $product->commerce_stock[LANGUAGE_NONE][0]['value'] = $form_state['values']['stock'];

Yes! Now it works! :D

Thanks a lot, today I will update the module without fear :D

I put the full patch here:

https://gist.github.com/coyoterj/6247377

i am going to try this code, but i need it for two different forms, one for one worker that only can change stock and other for the director that can change price. for what i understand, this formula will affect both forms.. so should i use the same form and hide fields by permissions?
thanks for any tip ;)

thanks @rbosscher and @Icoyoterj for the documentation.
at the end i my client change his mind and workers will be able to change the price and i dont have to resolve that problem.

@Icoyoterj a minor correction, you should change in line 15 from

$form['#submit'][] = YOURMODULE_commerce_backoffice_product_quick_edit_form_submit';

to

$form['#submit'][] = 'YOURMODULE_commerce_backoffice_product_quick_edit_form_submit';

i used your code and i want that product state doesnt show in the quickedit form but i get a notice:

Notice: Undefined index: status in commerce_backoffice_product_quick_edit_form_submit() (line 375 of /home/ftp/xxx/profiles/commerce_kickstart/modules/contrib/commerce_backoffice/commerce_backoffice_product.module).

my module

<?php
 
/**
* alter function for commerce_backoffice_product_quick_edit_form.
*/
 
function MYMODULE_form_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){
 
$product = $form_state['product'] ;
 
$form['stock'] = array(
 
'#type' => 'textfield',
 
'#title' => t('Stock'),
 
'#title_display' => 'before',
 
'#default_value' => $product->commerce_stock['und'][0]['value'],
 
'#size' => 5,
  );
 
$form['price']['#title_display'] = 'before';
  unset(
$form['status']);
 
$form['#submit'][] = 'MYMODULE_commerce_backoffice_product_quick_edit_form_submit';
}
/**
* Submit callback for commerce_backoffice_product_quick_edit_form.
*/
function MYMODULE_commerce_backoffice_product_quick_edit_form_submit($form, &$form_state) {
 
$product = $form_state['product'];
 
$currency_code = $product->commerce_price[LANGUAGE_NONE][0]['currency_code'];
 
$product->commerce_price[LANGUAGE_NONE][0]['amount'] = commerce_currency_decimal_to_amount($form_state['values']['price'], $currency_code);
 
//here i removed the status field
  //$product->status = $form_state['values']['status'];
 
$product->commerce_stock[LANGUAGE_NONE][0]['value'] = $form_state['values']['stock'];
 
commerce_product_save($product);
 
$form_state['rebuild'] = TRUE;
 
$form_state['product_saved'] = TRUE;
}
?>

i will appreciate if you give to me any tip, since i am learning to work with forms in drupal :)

if you add above the line

<?php
   $form
['stock'] = array(
?>

the line:
<?php
unset($form['status']);
?>

You should get rid of the notice and the field.

@rbosscher thanks for your fast answer, i did it but i keep getting the notice (i truncate the cache tables on the db).

the code

<?php
function MYMODULE_form_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){
 
$product = $form_state['product'] ;
  unset(
$form['status']);
 
$form['stock'] = array(
 
'#type' => 'textfield',
 
'#title' => t('Stock'),
 
'#title_display' => 'before',
 
'#default_value' => $product->commerce_stock['und'][0]['value'],
 
'#size' => 5,
  );
 
$form['price']['#title_display'] = 'before';
 
$form['#submit'][] = 'MYMODULE_commerce_backoffice_product_quick_edit_form_submit';
}
?>

Can you tell me what the notice is and on which line it is and give the corresponding line?
Your previous posted notice is in the submit handler commerce_backoffice_product_quick_edit_form_submit
while your custom submit handler is: ocultar_vt_commerce_backoffice_product_quick_edit_form_submit

the notice always is

Notice: Undefined index: status in commerce_backoffice_product_quick_edit_form_submit() (line 375 of /home/ftp/xxx/profiles/commerce_kickstart/modules/contrib/commerce_backoffice/commerce_backoffice_product.module).

maybe i have to unset in the MYMODULE_commerce_backoffice_product_quick_edit_form_submit?

thanks

i found the solution. instead of

<?php
unset($form['status']);
?>

in
function MYMODULE_form_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){

i used

<?php
$form
['status']['#access'] = FALSE;
?>

and the warnings went away :)
i hope someone can use it!
thanks @rbosscher

Status:Active» Closed (fixed)

thanks @coyoterj for #14 and @candelas for the minor correction. code works great, and it's exactly what i needed!

Here's an updated example that doesn't use LANGUAGE NONE and includes validation

<?php
/**
* Implements hook_form_FORM_ID_alter().
*/
function MYMODULE_form_commerce_backoffice_product_quick_edit_form_alter(&$form, &$form_state, &$product){
 
$product = $form_state['product'];
 
$product_wrapper = entity_metadata_wrapper('commerce_product', $product);
 
$form['stock'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Stock'),
   
'#title_display' => 'before',
   
'#default_value' => !empty($product->commerce_stock) ? $product_wrapper->commerce_stock->value() : 0,
   
'#size' => 5,
  );
 
$form['price']['#title_display'] = 'before';
 
$form['#validate'][] = 'MYMODULE_commerce_backoffice_product_quick_edit_form_validate';
 
$form['#submit'][] = 'MYMODULE_commerce_backoffice_product_quick_edit_form_submit';
}
/**
* Validation callback to make sure stock is numeric.
*/
function MYMODULE_commerce_backoffice_product_quick_edit_form_validate($form, &$form_state) {
  if (!empty(
$form_state['values']['stock'])) {
    if (!
is_numeric($form_state['values']['stock'])) {
     
form_set_error('stock', t('Please enter a numeric stock value'));
    }
  }
}
/**
* Submit callback to update the product stock.
*/
function MYMODULE_commerce_backoffice_product_quick_edit_form_submit($form, $form_state) {
 
$product = $form_state['product'];
  if (!empty(
$product) && !empty($form_state['values']['stock'])) {
   
$product_wrapper = entity_metadata_wrapper('commerce_product', $product);
   
$product_wrapper->commerce_stock->set($form_state['values']['stock']);
   
commerce_product_save($product);
  }
}
?>

Thinking about this further.

We could do someting like:

<?php
//Load all fields form the product entity and attacht to form
field_attach_form('commerce_product', $product, $form, $form_state, NULL, array());
Delete fields that are unnecessary
unset($form['title_field']);
unset(
$form['field_images']);
unset(
$form['field_purchase_price']);
?>

Actually we could easely create a ui for the module so you can select wich fields to use in the quick edit form

I took the andyg5000 's code from comment 24 and wrapped a module around it.
Works great, does just what I need - Thanks Andy
I uploaded it to github, thinking it might save someone else a few minutes.

https://github.com/lanette/commerce_stock_quick_edit

This functionality is great, but I have problem with the code from @andyg5000

After enabling module, and clicking "quick edit", I have an AJAX ERROR:

AJAX HTTP.
HTTP Error: 200
...
StatusText: OK
ResponseText: Warning: strstr() expects parameter 1 to be string, object given in strstr() (line 88 of /....../sites/all/modules/commerce_wishlist/commerce_wishlist.module).

this line is pointing to this function:

<?php
/**
* Implements hook_form_alter().
*/
function commerce_wishlist_form_alter(&$form, &$form_state, $form_id) {
  if (
strstr($form_id, 'commerce_cart_add_to_cart_form')) {
    if (isset(
$form_state['build_info']['args'][0]->data['context']['view'])) {
      if (
$form_state['build_info']['args'][0]->data['context']['view']['view_name'] == 'wishlist') {
        return;
      }
    }
   
$form += commerce_wishlist_add_form();
  }
}
?>

help would be appreciated..

Same problem here as #27

When I got rid of commerce wishlist module, my error changed to:

Wystąpił błąd w AJAX HTTP.
Error HTTP: 200
Path: .../commerce_backoffice/variations/141
StatusText: OK
ResponseText: Warning: strpos() expects parameter 1 to be string, object given in strpos() (line 295 of .../sites/all/modules/views_bulk_operations/views_bulk_operations.module).

I was having the same issue reported in #29. The problem appears to have been caused by Views Bulk Operations not being enabled because the version of PHP running was lower than 5.29 which is required by VBO. Once PHP was upgrade and VBO was operational the issue went away.

in my case, VBO is enabled and my php ver is 5.5.3 (one server) and 5.3.16 on the other...

Issue summary:View changes

thx andyg5000 & lanetterm for the code

Yes it did save me some time :)