When I add a new node, the address field show it doubled, and the Add new item bellow the second one

It should show only 1 address, and the use would click the link to add the second address. No need to two address upstart.

Plus, when I edit a existing node, it always add an extra address. If it has 2 address, a 3rd will show up with a default country, if we save the node without deselect the country, it will pile up showing 3 address; the last one having only the country. If we edit again, a 4th country will be saved, and on and on.

CommentFileSizeAuthor
#6 multiple-address-disaster.jpg28.35 KBtgeller

Comments

afeijo’s picture

Title: doubled address with multiple » doubled address with Unlimited

I mixed unlimited for multiple in the title, sorry

grossmann’s picture

I can confirm this.
If you select country = - none - in the unwanted address it won't display. Because auf the default setting in the field configuration (a county has to be selected, none is not available) anytime you edit a node it will autopopulate the country and generate a new address.

damien tournoud’s picture

BarisW’s picture

circuscowboy’s picture

Version: 7.x-1.0-alpha3 » 7.x-1.x-dev
Category: bug » feature
Priority: Major » Normal
Status: Closed (duplicate) » Active

I am reopening this up because even with the latest dev and patches mentioned here the problem initially stated still exists. If you select unlimited 2 address fields appear. If I select unlimited for the link module one field shows up with an 'add another' button. Same for the media module.

The addressfield module shows 2 and add another. Address fields are long and even though I want the option to add a second most of the time there will only be one. It makes my form too long and more daunting.

I have changed this to feature request as it is not really a bug and the priority to normal but this module has a different workflow than other modules in the unlimited setting and it would be good to make it consistant.

tgeller’s picture

Priority: Normal » Major
StatusFileSize
new28.35 KB

This appears to still be an issue. I'm bumping it to major, as it quickly results in disasters like the one shown in the attached screen shot.

emptyvoid’s picture

Confirmed, this issue is still occurring.

For a better picture (if you have installed this module for integration with Drupal Commerce) the following modules are used together to manage addresses.

Address Field (this module)
http://drupal.org/project/addressfield

This of course the Drupal Commerce Modules:
Drupal Commerce
http://drupal.org/project/commerce

It is important to note that commerce has several sub-modules most notably the customer module. The module has business logic to managing addresses (address field is a dependency). Address instances are appended to the customer profile entity in methods located in the commerce_customer.module file.

I'm leveraging a community module that extends the basic integration between addressfield and commerce entitled:
Commerce Address Book
http://drupal.org/project/commerce_addressbook

This module extends the basic integration and provides more business rules that don't exist in the standard commerce_customer module. Most notably it adds a management interface for the customer with the ability to create, edit, and delete addresses outside of the order process.

I believe the issue that causes duplicates is located here:

commerce_addressbook/includes/commerce_addressbook.user.inc
Line 30:

/**
 * Page callback for editing a customer profile.
 */
function commerce_addressbook_profile_options_edit($account, $customer_profile) {
  // Add the breadcrumb for the form's location.
  commerce_addressbook_set_breadcrumb($account, $customer_profile->type);

  // If the profile is referenced by an order, make sure it gets duplicated.
  $profile = clone($customer_profile);
  if (!commerce_customer_profile_can_delete($customer_profile)) {
    $profile->previous_id = $profile->profile_id;
    unset($profile->profile_id);
    unset($profile->revision_id);
    $profile->is_new = TRUE;
  }
  module_load_include('inc', 'commerce_customer', 'includes/commerce_customer_profile.forms');
  return drupal_get_form('commerce_addressbook_customer_profile_form', $profile);
}

This method calls "commerce_customer_profile_can_delete($profile) which states:
commerce/modules/commerce_customer.module

Online 628:
// Return FALSE if the given profile does not have an ID; it need not be
// deleted, which is functionally equivalent to cannot be deleted as far as
// code depending on this function is concerned.

And a little later in the method
Online: 635
// If any module implementing hook_commerce_customer_profile_can_delete()
// returns FALSE the customer profile cannot be deleted. Return TRUE if none
// return FALSE.

So a quick search of my source code reveals the following places where modules influence if a profile can be deleted:

commerce/modules/commerce_order.module
Online: 458
function commerce_order_commerce_customer_profile_can_delete($profile)

The function comments say it all:


function commerce_order_commerce_customer_profile_can_delete($profile) {
  // Look for any non-cart order with a reference field targeting the profile.
  foreach (commerce_info_fields('commerce_customer_profile_reference') as $field_name => $field) {
    // Use EntityFieldQuery to look for orders referencing this customer profile
    // and do not allow the delete to occur if one exists.
    $query = new EntityFieldQuery();

    $query
      ->entityCondition('entity_type', 'commerce_order', '=')
      ->fieldCondition($field_name, 'profile_id', $profile->profile_id, '=')
      ->count();

    // Add a condition on the order status if there are cart order statuses.
    $statuses = array_keys(commerce_order_statuses(array('cart' => TRUE)));

    if (!empty($statuses)) {
      $query->propertyCondition('status', $statuses, 'NOT IN');
    }

    // If the profile includes an order context property, we know this was added
    // by the Order module as an order ID to skip in the deletion query.
    if (!empty($profile->entity_context['entity_id']) && $profile->entity_context['entity_type'] == 'commerce_order') {
      $query->propertyCondition('order_id', $profile->entity_context['entity_id'], '!=');
    }

    if ($query->execute() > 0) {
      return FALSE;
    }
  }

  return TRUE;
}

So, if an order in the past used the address then modifying the address for a current or future order will result in the system duplicating the address with the changed values. Old addresses are not deleted, period.

What I'm assuming is not working is that the "expired" addresses should be hidden from the user and only the "new" address revision should be visible.

Retracing back to ye old commerce_addressbook module the submission method is suppose to accomplish this.

commerce_addressbook/includes/commerce_addressbook.user.inc
Online: 45

/**
 * Submit handler for commerce_addressbook_customer_profile_form.
 */
function commerce_addressbook_customer_profile_form_submit($form, &$form_state) {
  $profile = $form_state['customer_profile'];

  // The profile has been edited and duplicated.
  // Disable the previous one to prevent it from showing up in listings.
  if (!empty($profile->previous_id)) {
    $old_profile = commerce_customer_profile_load($profile->previous_id);
    $old_profile->status = 0;
    commerce_customer_profile_save($old_profile);

    // If the old profile was the default, then we need to set the new one
    // as the default.
    $default_profile_id = commerce_addressbook_get_default_profile_id($profile->uid, $profile->type);
    if ($old_profile->profile_id == $default_profile_id) {
      commerce_addressbook_set_default_profile($profile);
    }
  }

  // Set the profile as default if it has just been added, and the user has no
  // other active profiles of this type.
  if (!empty($profile->_is_new)) {
    $query = new EntityFieldQuery;
    $query->entityCondition('entity_type', 'commerce_customer_profile')
          ->entityCondition('bundle', $profile->type)
          ->propertyCondition('uid', $profile->uid)
          ->propertyCondition('status', 1)
          ->count();
    $result = $query->execute();

    if ($result < 2) {
      commerce_addressbook_set_default_profile($profile);
    }
  }

  $form_state['redirect'] = 'user/' . $profile->uid . '/addressbook/' . $profile->type;
}

Online 52 of the method the current "target" profile has the status set to 0. Meaning it is disabled and should not be visible any longer. However it still appears both in the management indexes and during order checkout.

:(

Cross Posted at:

http://drupal.org/node/1940156

http://drupal.org/node/1185996

http://drupal.org/node/1794064#comment-7166112

tgeller’s picture

This is some very informative and thorough sleuthing. I wish I had the skills to mature it into a patch!

Thanks for doing so much legwork. I'm optimistic it'll help someone fix it.

tgeller’s picture

[Deleted - double post]

emptyvoid’s picture

Further discussion here, the:

General consensus from the Commerce Guys representatives is this behavior is by design. Although I'm getting a huge number of duplicates every time a user interacts with profiles. I also have automated routines that sync profiles some change values other are identical.

http://drupal.org/node/1940156#comment-7169264

guerno’s picture

Confirming this issue, would be nice to see a patch, I can't though, sorry!

johnv’s picture