Drupal Commerce Issue Queue

Allow admin to discount line item price

Mon, 11/09/2015 - 08:15

I've been searching for a clear answer for hours and yet to find one. If the answer to the below is already out there somewhere, just point me to it... :)


I have a client who'd like to give certain users an arbitrary discount to a class. In these situations an admin will create the registration (using the Registration module) which will automatically create a cart with this class as a line item. I'm having trouble figuring out what process to use to (from the user's perspective) correct the price for the course in cart.

My understanding is that there's no way to modify the price for the line item directly. Assuming this is correct (if this isn't please let me know!), my research indicates I'll need to add a line item to the order that will (from the user's perspective) reduce the price to where they want it.

What should this line item be? A discount? A coupon? Something else? And, whatever the right "thing" is, how does it get applied?

I've tried installing commerce_discount and have set up a discount, but I cannot for the life of me figure out how to apply it to an order. I've read through the info on this page --> https://drupalcommerce.org/user-guide/discounts-and-coupons, but assuming the answer I'm looking for is in there, I'm not finding it.

Any direction / thoughts / help on this will be much appreciated.


Categories: Issue Queues

Add IP Address to payment transaction fields

Sat, 11/07/2015 - 16:14

Today we got a dispute from our credit card processor about a fraudulent payment; after doing some investigation, I couldn't find any *real* evidence of wrongdoing, because the IP address recorded in the {commerce_order} table matches with the IP used in previous (valid) orders.

However, I noticed that somehow, two payment transactions had been entered for a single order (using Commerce Stripe). I'm not quite sure how at the moment, but this brought me to another realization: the IP address of the person creating the transaction is not saved anywhere in the transaction data. It's included as part of the Order process, but there's the rub: it only records the IP address in the commerce_order_revision table during a save() event. Unfortunately, though, this data is only accessible from the db, and is nowhere to be found in an order's Payment tab.

It would be better from a customer support/administration side if we included the originating IP address that submitted the transaction. This would better protect store admins from fraud and would just make a better UX for non-technical administrators.

I'd suggest including a new field in the commerce_payment_transaction table schema, and then adding a write function to the controller to record the IP in that field whenever a transaction is created.


Categories: Issue Queues

Display the amount of the order on the block cart

Fri, 11/06/2015 - 13:04


do you know how to display the amount of the basket next to the number of elements?
As this page http://demo.commerceguys.com/cart

 * Returns the title of the shopping cart menu item with an item count.
function commerce_cart_menu_item_title() {
  global $user;

  // Default to a static title.
  $title = t('Shopping cart');

  // If the user actually has a cart order...
  if ($order = commerce_cart_order_load($user->uid)) {
    // Count the number of product line items on the order.
    $wrapper = entity_metadata_wrapper('commerce_order', $order);
    $quantity = commerce_line_items_quantity($wrapper->commerce_line_items, commerce_product_line_item_types());

    // If there are more than 0 product line items on the order...
    if ($quantity > 0) {
      // Use the dynamic menu item title.
      $title = format_plural($quantity, 'Shopping cart (1 item)', 'Shopping cart (@count items)');

  return $title;

thank you in advance

Categories: Issue Queues

Convert amount total for order in page checkout doesn’t work properly

Fri, 11/06/2015 - 11:24


I don't know if this problem come from commerce module or from my own code, So I have the following information about the problem:

GIVEN: order in the cart page
WHEN: Change the currency(I use module Multicurrency) then click on button checkout
THEN: an problem occurred, The page checkout opened and the line items converted to the current currency whereas amount total of order doesn’t converted.

2-More details
After debugging the code in the function commerce_cart_order_refresh($order)
This function refresh the line items in case exist changing in their currency or amount or comment and that by invoke rules_invoke_event('commerce_product_calculate_sell_price', $cloned_line_item);
So after refreshed all line items it compare if exist difference between old line_item(that come from order) and the refreshed line_item.
If exist changes it save the order with refreshed line_item else do nothing.

So the problem occurred because it doesn’t exist difference between the old line_item and
refreshed line_item always the both have the current currency with converted amount, thus the order doesn’t update.

Please help. Thanks in advance.

Categories: Issue Queues

Create a views argument plugin for filtering by active store

Fri, 11/06/2015 - 08:59

Just like there's a default argument plugin for the current user, there should be one for the active store.
It would allow a view of products to be filtered by the active store, for example.

Categories: Issue Queues

Prevent commerce_checkout_complete() to be fired more than once for the same order

Thu, 11/05/2015 - 07:27

We're having a lot of discussions about problems with calling "commerce_checkout_complete" in the UI and (remove) payment providers...

In my current case for example the payment provider SOFORTÜBERWEISUNG calls the payment entered APIs before the checkout is complete (). In other cases, e.g. for PayPal other problems occur and especially the case that the order completition should be independent of UI. This is for example important if the user should never go back to the checkout complete page or only under special circumstances (which might then trigger commerce_checkout_complete more than once).

All in all I see the problem that commerce_checkout_complete() might be triggered more than once for an order currently and we don't have a clean way to prevent that.

This is a big logical problem because you can't always ensure that the call always happens once while there is only one logical "order completition" from my point of view.

So my suggestion would be to encapsulate the rules_invoke_all('commerce_checkout_complete', $order);

 * Completes the checkout process for the given order.
function commerce_checkout_complete($order) {
  rules_invoke_all('commerce_checkout_complete', $order);
in an if statement which only executes this call if it was not called before.

commerce_payment.module, Line 447 does something similar here using a data attribute:

 * Implements hook_commerce_payment_transaction_insert().
 * When a new payment transaction is inserted that is already completed, check
 * the order balance and invoke a Rules event if the order is paid in full.
function commerce_payment_commerce_payment_transaction_insert($transaction) {
  // If the inserted transaction was marked as a success and placed against a
  // valid order...
  if ($transaction->status == COMMERCE_PAYMENT_STATUS_SUCCESS &&
    $order = commerce_order_load($transaction->order_id)) {
    // Then check to make sure the event hasn't been invoked for this order.
    if (empty($order->data['commerce_payment_order_paid_in_full_invoked'])) {
      // Check the order balance and invoke the event.
      $balance = commerce_payment_order_balance($order);

      if (!empty($balance) && $balance['amount'] <= 0) {
        // Invoke the event including a hook of the same name.
        rules_invoke_all('commerce_payment_order_paid_in_full', $order, $transaction);

        // Update the order's data array to indicate this just happened.
        $order->data['commerce_payment_order_paid_in_full_invoked'] = TRUE;

        // Save the updated order.

What do you think about that or could you at least add a hook to add a way to prevent the rules call here?

Categories: Issue Queues

commerce_entity_access incorrect access logic

Wed, 11/04/2015 - 16:55

If the fourth parameter to commerce_entity_access is not passed in, or passed in as null, then incorrect access logic occurs.

The related issue, in ctools_entity_from_field_context, has existed for about two years, so while this is certainly an improper invocation by the caller, it is not isolated.

If the fourth parameter is not passed in, the entity_get_info() call is made with an argument of null. This returns an array of arrays, rather than a singular array into $entity_info.

This renders all of the checks against $entity_info invalid, since the code assumes that the $entity_info is for a singular entity, rather than an array of entity_info(s) keyed by entity_type.

This does two things:
1) It always returns false for 'create', 'update', and 'delete' operations, when it possibly should be true. (It could also incorrectly return true, if another module implements hook_commerce_entity_access and also has issues with $entity_access being null)

2) Because of inverse logic for the 'view' operation, it always returns true.

Categories: Issue Queues

Checkout Order Total Displays Wrong Amount

Mon, 11/02/2015 - 15:08

Website caters to UK & US. They can purchase the same products but they have different price points as well as different currencies. The UK orders work fine. When a US customer tries to make an order the shopping cart is fine; line items and total are correct. When going to check out, the line items are correct, but the Order Total reflects the numerical value of a UK price with a dollar sign.

Categories: Issue Queues

Add #disabled for bundle form id elements

Mon, 11/02/2015 - 09:29

This is a followup to #2591829: Modernize bundle forms (like ProductTypeForm). The commit 0e675b7e5e49ddeafeb7b67975129a1f402e2238 wrongly changed the isNew() calls to isLocked(). Let's change them back.

Categories: Issue Queues

Add tests for the attribute settings form

Mon, 11/02/2015 - 08:13

The product module adds attribute settings to list_string and entity_reference field settings.
This got broken by D8 when the entity_reference module was deprecated, and fixed recently in https://github.com/commerceguys/commerce/commit/908a0b29a26bdacb691c5517...
Meanwhile, the tests were green. So, we need to add test coverage to ensure that doesn't repeat.

Categories: Issue Queues

Research copying product data into the line item

Mon, 11/02/2015 - 05:17

This has been a topic of many conversations at sprints and drupalcons, this issue is intended to document it.

Line items need to be self sufficient. After an order has been placed, the data is set in stone, and can't change. Viewing the order or the invoice 1 day and 10 days after the purchase must show the same data. This is only possible if only the order / line item data is shown. Pulling in product, variation, attribute (taxonomy term) data creates a problem, because that data can change. The "Blue" attribute might be renamed to "Light blue", the product title might change, etc.

Commerce 1.x protects against this by storing the line item title and price, initially populated from a product. The product title can include the attributes, they aren't shown elsewhere. Looking at Amazon and Apple Store, they take the same approach. See the attached screenshots.

For 2.x we've also explored alternatives:
1) Use revisions - The line item stores a reference to an exact variation revision, so the data never changes.
This doesn't work for the same reason revisions themselves don't work - they're limited to a single entity. We'd need to revision the product, the variations, the attributes. Just revisioning the variations wouldn't save us from an attribute rename, for example.

2) Serialize important variation fields on the line item (attributes, etc).
This is problematic for several reasons.
First, only simple values could be stored (since we'd call getString() on each field).
Second, since the data is serialized, we have no way to tell Drupal what's inside.
This means not having the data available in views, rules, tokens, etc.

3) Map variation fields to line item fields.
This is what the Erpal team did. They create matching line item fields for the product fields they want to persist (for example, the attributes).
They then configure the mapping, so that the system knows which fields to copy where.
This gets around the main problems of #2, at the expense of additional complexity (ensuring two sets of fields, maintaining the mapping)

I discussed the various approaches with pcambra. The final conclusion was to continue doing what 1.x did, since it provides good enough UX, and is a pattern seen on major ecommerce sites. Furthermore, the line item title only needs to be shown on complete orders / invoices, the cart can still render the variation and get something more complex.

Meanwhile, #3 can be developed in contrib. It would be a welcome addition to the ecosystem.
Our variation types now have a matching line item type, making it easy to extend the variation type entity and form to hold the mapping settings.

Categories: Issue Queues

Rework line item title handling

Mon, 11/02/2015 - 04:13

This worked correctly in 1.x, but we haven't ported it properly to 2.x yet.

When a variation (or any other purchasable entity) is added to an order, its title should be copied into the line item.
This protects the line item from any label changes (on the product, variation, or the attributes) that might happen after the order has been placed.

The title field should have the maxlength set to a value bigger than 255 (let's go with 512), just in case there are many attributes.

Categories: Issue Queues

Rework the variation label

Mon, 11/02/2015 - 04:01

Right now the variation label is the sku. The sku is not meant to be user friendly, it's a machine name.
A variation is always identified by its attributes. So we should construct a label from that. "Small, Blue"
If there are no attributes, that means there's always only one variation. We can call it "Default".

We have this data on the entity already, so we don't need to store it in a property, we can create it on the fly.
This helps us avoid the problem of the label getting out of date if the attribute gets renamed or gets a new translation.

Categories: Issue Queues

Replace the injected entity manager

Mon, 11/02/2015 - 03:17

The entity manager has been split into 11 different services: https://www.drupal.org/node/2549139

We'll want to replace the entity manager (injected into our forms, services) with the more appropriate replacement(s). In most cases that will be the EntityTypeManager, since we only call getStorage() on it.

Categories: Issue Queues

Redirect users to 403 instead 404 in case of access denied

Fri, 10/30/2015 - 08:33


I know the normal behaviour of Drupal Commerce is to display a 404 page is the user doesn't have access to the checkout page but we need to display a 403 in our case.

So here is the corresponding patch.

Categories: Issue Queues

Redirect users to 403 instead 404 in case of access denied

Fri, 10/30/2015 - 07:16


I know the normal behaviour of Drupal Commerce is to display a 404 page is the user doesn't have access to the checkout page but we need to display a 403 in our case.

So here is the corresponding patch.

Categories: Issue Queues

commerce_product_handler_field_product_link does not use entity_uri()

Thu, 10/29/2015 - 07:58

commerce_product_handler_field_product_link does not use entity_uri(), but constructs entity URLs itself, completely bypassing any other module's abilities to alter the URL.

Proposed resolution

Make the Views field handler use entity_uri() instead of constructing URls itself.

Remaining tasks


User interface changes

No changes, but additions. The field now extends Views' URL field base class, rather than the generic field base classes.

API changes


Data model changes
Categories: Issue Queues

Clarify order language behavior

Wed, 10/28/2015 - 07:15

Orders and line items are not multilingual, they exist in only one language at a time.
At the same time, products, discounts, shipping rates are multilingual.

To guard against data changes, the $line_item->title receives the product title when the product is added to cart.
So this means that the line item ends up with a specific translation (FR if the site/product was viewed in french, for example).

$order->langcode holds the order language. Selected on the order add form, or created by the CartProvider.
This language is used when copying any multilingual data. Once an order is completed in french, the line items stay in french.

Does that make sense? It's potentially weird if the customer views the site in a different language the next time, but the line items stay in the old language, but I don't see a way around that if we want to keep the line item title copying (and we do, cause EU laws require invoices and orders to be unchanged after they are placed).

Categories: Issue Queues

Consider renaming line items to (order) items

Wed, 10/28/2015 - 07:10

In 1.x line items held both the purchased products and non-product adjustments such as discounts and shipping.
In 2.x we're separating the two: line items hold only products. Adjustments will hold discounts, shipping, fees.

I've been reading Silverstone's data modelling book, and he has a chapter about orders, and he also argues for separating line items and adjustments.
However, he has an argument for dropping the "line" part of the name:

Many models will portray orders having "order line items." The reason that this model does not call them "order line items" is that this term connotes physical lines on an order form. The physical lines on an order form often encompass many other things aside from the items that have been ordered. For instance, there may be notes to records adjustments, taxes, estimated freight costs, explanations, and other descriptive detail for the order. Rather than portray the entity as capturing each of the documented lines on an order form, the ORDER ITEM entity represents a major information need for the order, namely the items or products that have been ordered."

This would mean the following changes:
entity_type: commerce_line_item -> commerce_order_item
entity class: LineItem -> OrderItem
reference field: $order->line_items -> $order->items.

Is this a change we want to make? I don't care much, but I thought it was worth discussing.
A different naming might signal better that the underlying assumptions have changed.

Categories: Issue Queues