Comments

pcambra’s picture

Status: Active » Fixed
Issue tags: +Fix coupon type condition for fixed amount redeem rule

Oops, that was a typo I pushed, the coupon type is called commerce_coupon_fixed

Fixed now, many thanks for testing all this.

roam2345’s picture

Status: Fixed » Needs work

still does not work.....

its fine if the page is not reloaded, add a coupon then reload that page again... gets zero'ed.

mrfelton’s picture

Seeing the same problem.

pcambra’s picture

Status: Needs work » Postponed (maintainer needs more info)

Strange, I can't reproduce this, could you make sure you've got the rules related to the fixed amount reverted and the cache cleared?

Are these the steps to reproduce it?

  • Add something to the cart
  • Add a fixed coupon, the qty is ok
  • Refresh the page, qty is 0
mrfelton’s picture

Title: Grant Amount changes... » Grant Amount not applied
Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new4.81 KB

So,
many hours later...

In our setup (where the commerce_coupon rules are in their default state) fixed price discounts simply did not get applied at all. The attached patch fixes the issue, although I have some questions about the specific of the implementation. The biggest question is wether we should really be using hook_commerce_cart_line_item_refresh() or hook_commerce_cart_order_refresh to handle the updating. I suspect the ater, although we only managed to get it working use the line item refresh hook. In order to make this work, we needed to use a simple static cache to ensure that each coupon would only be applied to the order once.

In any case it works in a very similar way as the percent based discounts, and we looks to be working well for us even with our own custom coupon block that enables coupons to be applied on the cart form as opposed to the checkout page.

pcambra’s picture

Status: Needs review » Needs work

I don't really think this is the solution to it.

hook_commerce_cart_line_item_refresh is invoked once for each line item of a cart state order, so there's no point of looping all, that would be something you do in hook_commerce_cart_order_refresh.

Then calls like these wouldn't be needed.
$commerce_coupon_fixed_amount_applied_coupons = &drupal_static(__FUNCTION__);

I don't really see a change in the roots of the code here, basically on hook_commerce_cart_line_item_refresh, checks if the line item type is a coupon (that only works for fixed amount coupons) and if so, it applies it.
What you do change is the coupon log update, that is completely removed, and that's the piece of code that is failing for you as I've understood.
With your code, if there's a change in the coupon, log is never updated.

roam2345’s picture

@pcambra the current function checks that the line item is of the type "commerce_coupon" which never is TRUE in its current incarnation, and the refresh never happens to the cart. All though this needs work it does update the coupon fixed coupon amounts.

Also have noticed that commerce_coupon_code is used for the component name.
$price_component_name = $coupon->type . '_' . $coupon_wrapper->commerce_coupon_code->value();
There is no clean up of that code that may have white space, etc.. not sure if this gonna cause issues?

roam2345’s picture

Attached is a reroll that updates the log as well.

pcambra’s picture

I'd say that the patch wouldn't apply as it seems is taken from the 1...

the current function checks that the line item is of the type "commerce_coupon" which never is TRUE in its current incarnation

I don't see why this is not true, the line item type is always "commerce_coupon" for coupons.

Also have noticed that commerce_coupon_code is used for the component name.
$price_component_name = $coupon->type . '_' . $coupon_wrapper->commerce_coupon_code->value();
There is no clean up of that code that may have white space, etc.. not sure if this gonna cause issues?

That's probably true, we could use the coupon id, but probably we're going to need a coupon label at some point, I'm open to discussion about this.

roam2345’s picture

But when you put a dsm() on $cloned_line_item and $coupon to look at their types.... they are always the line items never the coupons?

mrfelton’s picture

Agreed, the line item that gets passed in to $cloned_line_item is never a commerce_coupon type. Hense why previously the code did absolutely nothing.

pcambra’s picture

Status: Needs work » Postponed (maintainer needs more info)

Marking as needs more info as I'm not being able to reproduce this at all, line item type for producs is normally "product", for shipping items is going to be "shipping" and for coupons of fixed amount, "commerce_coupon", you may get "coupon" in older -devs from commerce coupon "core", but definitely not "line item" type line items.

I'm probably getting just pieces of the debug you're doing, I'm going to need much more information to be able to track and fix (if needed) this.

pcambra’s picture

A copy of that dsm result would be a good start.

roam2345’s picture

StatusFileSize
new314.03 KB

Here is a dsm result.

roam2345’s picture

That's probably true, we could use the coupon id, but probably we're going to need a coupon label at some point, I'm open to discussion about this.

Not sure what other modules use to build there machine names is there no generic function that deals with that for us?

mrfelton’s picture

Status: Postponed (maintainer needs more info) » Active

@pcambra It seems that the rule that adds the coupon line item to the cart isn't firing correctly on our site - so there is never a commerce_coupon line item type, which would explain the behavior we are seeing. See this screenshot that shows the broken rule: http://cl.ly/1R2D1U1b3J0e0O0J181S

It seems to be failing because it can't find a coupon_reference field. I see that there is a new field type called Coupon Reference, but have no idea what its for, what entity it needs to go on, what is supposed to reference what. Clearly I'm missing some fundamental aspect of how this module is suposed to be used! I'm also confused as to how the % based coupons work, but the fixed price ones dont. I don't have coupon_reference fields on either of the coupon types (fixed or pct), or on any of my products.

pcambra’s picture

Category: bug » support

Ok, this is starting to make sense, I think we're looking at the wrong place then.

The field coupon reference is created in the line item type coupon, you can see your line item types at admin/commerce/config/line-items. You should see there the coupon type that should have more or less this look: https://skitch.com/pcambra/8w84u/coupon-commerce-kickstart
If you haven't got this, you've got a problem with your commerce coupon install, as this structure is created on install by commerce_coupon_configure_line_item that commerce invokes when creating the line item type.

roam2345’s picture

pcambra’s picture

I think we've got the problem, not sure how to reproduce though, as if you install from scratch commerce kickstart + commerce coupons "suite", you get the right fields (it'd be useful if you could try that).

What I've would do is to invoke commerce_coupon_configure_line_item manually (be careful with this, I'd do it in a sandbox first) and then you're going to update your ongoing carts (not sure if you're live yet) to get the proper information in the line item.

pcambra’s picture

By the way, just commited a machine name feature in both coupon, fixed and pct modules

roam2345’s picture

So I have run commerce_coupon_configure_line_item in a sandbox that ran and added a commerce_coupon_reference to the coupon line item entity. But once I now add a fixed coupon to the cart I get this wonderful ditty.

EntityMetadataWrapperException: Unable to get the data property data as the parent data structure is not set. in EntityStructureWrapper->getPropertyValue() (line 442 of /Users/jucallme/Sites/systemseed/ks_profile/new/build/profiles/ks/modules/contrib/entity/includes/entity.wrapper.inc).

running this get me the site back.. but as soon as i add a coupon again it fries.

DELETE co.*, cor.*, fdcli.*, frcli.*, fdcot.*, frcot.*, fdccb.*, frccb.*, cli.*,fdcp.*,fdcup.*,fdct.*,fdcdp.*, frcp.*, frcup.*, frct.*, frcdp.*
FROM 
commerce_order co LEFT JOIN commerce_order_revision cor ON (co.order_id = cor.order_id)
LEFT JOIN field_data_commerce_line_items fdcli ON (co.order_id = fdcli.entity_id)
LEFT JOIN field_revision_commerce_line_items frcli ON (co.order_id = frcli.entity_id)
LEFT JOIN field_data_commerce_order_total fdcot ON (co.order_id = fdcot.entity_id)
LEFT JOIN field_revision_commerce_order_total frcot ON (co.order_id = frcot.entity_id)
LEFT JOIN field_data_commerce_customer_billing fdccb ON (co.order_id = fdccb.entity_id)
LEFT JOIN field_revision_commerce_customer_billing frccb ON (co.order_id = frccb.entity_id)
LEFT JOIN commerce_line_item cli ON (co.order_id = cli.order_id)
LEFT JOIN field_data_commerce_product fdcp ON (fdcp.entity_id = cli.line_item_id)
LEFT JOIN field_data_commerce_unit_price fdcup ON (fdcup.entity_id = cli.line_item_id)
LEFT JOIN field_data_commerce_total fdct ON (fdct.entity_id = cli.line_item_id)
LEFT JOIN field_data_commerce_display_path fdcdp ON (fdcdp.entity_id = cli.line_item_id)
LEFT JOIN field_revision_commerce_product frcp ON (frcp.entity_id = cli.line_item_id)
LEFT JOIN field_revision_commerce_unit_price frcup ON (frcup.entity_id = cli.line_item_id)
LEFT JOIN field_revision_commerce_total frct ON (frct.entity_id = cli.line_item_id)
LEFT JOIN field_revision_commerce_display_path frcdp ON (frcdp.entity_id = cli.line_item_id)
WHERE co.status = 'cart' OR co.status = 'checkout_checkout';
pcambra’s picture

That's normally being called when getting the property value of an entity, see:
http://drupalcontrib.org/api/drupal/contributions%21entity%21includes%21...

Wondering if we're using "data" property at all in coupons. I'm thinking that's an heritage copy-paste from orders entity type since the beginning. Need to review that.

I think it's better to run the configure line item thing without any coupon in any cart for avoiding issues like this.

Need to work in the uninstall issues as you're probably in need of a reinstall of the coupon suite due those structural issues. Anyways, the configure line item on install has been there from moment 0 I'd say, so it's a really odd problem.

davidwhthomas’s picture

I had a similar issue when updating to the latest dev versions, I lost the 'commerce_coupon_reference' and other fields on the coupon line item type, resulting in errors creating that line item for fixed amount coupons.

I used an update hook to ensure the fields were set again on the coupon line item type.

After that, I could use the fixed amount coupon type normally.

Quite lengthy update code to ensure the line item fields were all set, but it worked.

Update code currently is:

/**
 * Ensure line item fields set on coupon line item type
 */
function EXAMPLE_update_7031(){
  
  // COUPON REFERENCE FIELD
  // Delete field if exists first
  $field = field_info_field('commerce_coupon_reference');
  if($field){
    field_delete_field('commerce_coupon_reference');
  }
  field_cache_clear();
  $entity_type = 'commerce_line_item';
  $bundle = 'commerce_coupon';
  // Look for or add the specified coupon code reference field
  $field_name = 'commerce_coupon_reference';
  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle);

  if (empty($field)) {
    drupal_set_message(t("Creating field %name on %entity", array("%name" => $field_name, '%entity' => $entity)));
    $field = array(
      'field_name' => $field_name,
      'type' => 'commerce_coupon_reference',
      'cardinality' => 1,
      'entity_types' => array($entity_type),
      'translatable' => FALSE,
      'locked' => TRUE,
      'settings' => array(),
    );
    $field = field_create_field($field);
  }
  if (empty($instance)) {
    drupal_set_message(t("Creating field instance for %name on %bundle", array("%name" => $field_name, '%bundle' => $bundle)));
    $instance = array(
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => t('Coupon'),
      'required' => FALSE,
      'settings' => array(),
      'display' => array(),
    );
    field_create_instance($instance);
  }
  field_cache_clear();

  // UNIT PRICE FIELD
  // Look for or add the specified coupon code unit price field
  $entity_type = 'commerce_line_item';
  $bundle = 'commerce_coupon';
  $field_name = 'commerce_unit_price';
  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle);

  if (empty($field)) {
    drupal_set_message(t("Creating field %name on %entity", array("%name" => $field_name, '%entity' => $entity)));
    $field = array(
      'field_name' => $field_name,
      'type' => 'commerce_price',
      'cardinality' => 1,
      'entity_types' => array($entity_type),
      'translatable' => FALSE,
      'locked' => TRUE,
      'settings' => array(),
    );
    $field = field_create_field($field);
  }
  if (empty($instance)) {
    drupal_set_message(t("Creating field instance for %name on %bundle", array("%name" => $field_name, '%bundle' => $bundle)));
    $instance_data = array(
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => t('Unit price'),
      'required' => FALSE,
      'settings' => array(),
      // Because this widget is locked, we need it to use the full price widget
      // since the currency option can't be adjusted at the moment.
      'widget' => array(
        'type' => 'commerce_price_full',
        'weight' => $weight,
        'settings' => array(
          'currency_code' => 'default',
        ),
      ),
      'default_value' => array(
        array(
          'amount' => 0,
          'currency_code' => commerce_default_currency(),
          'data' => array(
            'components' => array(),
          ),
        ),
      ),
      'display' => array(),
    );
    field_create_instance($instance_data);
  }
  field_cache_clear();

  // TOTAL FIELD
  // Look for or add the specified coupon code total price field
  $entity_type = 'commerce_line_item';
  $bundle = 'commerce_coupon';
  $field_name = 'commerce_total';
  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle);

  if (empty($field)) {
    drupal_set_message(t("Creating field %name on %entity", array("%name" => $field_name, '%entity' => $entity)));
    $field = array(
      'field_name' => $field_name,
      'type' => 'commerce_price',
      'cardinality' => 1,
      'entity_types' => array($entity_type),
      'translatable' => FALSE,
      'locked' => TRUE,
      'settings' => array(),
    );
    $field = field_create_field($field);
    field_cache_clear();
  }
  if (empty($instance)) {
    drupal_set_message(t("Creating field instance for %name on %bundle", array("%name" => $field_name, '%bundle' => $bundle)));
    $instance_data = array(
      'field_name' => $field_name,
      'entity_type' => $entity_type,
      'bundle' => $bundle,
      'label' => t('Total'),
      'required' => FALSE,
      'settings' => array(),
      // Because this widget is locked, we need it to use the full price widget
      // since the currency option can't be adjusted at the moment.
      'widget' => array(
        'type' => 'commerce_price_full',
        'weight' => $weight,
        'settings' => array(
          'currency_code' => 'default',
        ),
      ),
      'default_value' => array(
        array(
          'amount' => 0,
          'currency_code' => commerce_default_currency(),
          'data' => array(
            'components' => array(),
          ),
        ),
      ),
      'display' => array(),
    );
    field_create_instance($instance_data);
  }

  field_cache_clear();

}

HTH,

DT

P.S @pcambra, thanks for your hard work on this project, I like the direction it's taking. cheers.

pcambra’s picture

Status: Active » Fixed

Closing this, please open new issues with specific problems, bear in mind that we have now an issue to track update problems to beta5

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