Question

Our site imports customers from external data sources. Part of this import is creating a default billing address from external data if none exists.

I have followed advice from other questions, as wells as tutorials, all of which seem to say the same thing for creating/saving a default billing address. This seems to work at least partially.

// $c is the customer
$data_source  = array(
    'street'   => '',
    'city'     => '',
    'postcode' => '',
);

$a = $c->getPrimaryBillingAddress();

// Create a new default billing if none found
if (!$a)
{
  $a = Mage::getModel("customer/address");
  $a->setCustomerId($c->getId())
    ->setIsDefaultBilling('1')
    ->setSaveInAddressBook('1');
}

foreach ($data_source as $k => $d) $a->setData($k, $d);

$a->save();

After this code has been run, the address is visible on the customer's page in the backend and is marked as the default billing.

However, the following time data is fetched from our external source and the code is run, the address that was saved is not retrieved (getPrimaryBillingAddress returns false). This results in a new address being created every time this code is run.

The exception is when a customer has a default billing address set by magento. In this case, getPrimaryBillingAddress correctly finds the address and the address data is updated and saved.

How can I programatically create a default billing address in such a way that I can retrieve it with $customer->getPrimaryBillingAddress()?

UPDATE

After receiving a possible answer, I have adjusted to code to set customer's default_billing. The main problem persists with the changes.

$a = $c->getPrimaryBillingAddress();

// Create a new default billing if none found
if (!$a)
{
  $a = Mage::getModel("customer/address");
  $a->setCustomerId($c->getId())            // <-- variations of customer/customerID 
    ->setCustomer($c)                       //     don't seem to affect
    ->setIsDefaultBilling('1')
    ->setSaveInAddressBook('1')
    ->save();                               // <--- SAVE SO WE CAN ACCESS ID

  $c->addAddress($a)                        // <--|
    ->setDefaultBilling($a->getId())        // <--+ SAVE default_billing IN CUSTOMER
    ->save();                               // <--|

}

foreach ($data_source as $k => $d) $a->setData($k, $d);

$a->save();

// ---------------- SUBSEQUENT RUNS --------------

$c->getDefaultBilling();                    // null
$c->getPrimaryBillingAddress();             // false

References

Variations on this method for creating/setting a customer default address were found at these locations:

Was it helpful?

Solution

You need to set it the other way around. The default_billing for the customer.

$customerId = 1234; // Customer id
$data = array(); // Address data

$customer = Mage::getModel('customer/customer');

// Load customer
$customer->load($customerId);

// Get current address
$address = $customer->getPrimaryBillingAddress();

// Do we add a new address
$isNewAddress = false;
if (!$address) {
    $address = Mage::getModel('customer/address');

    $address->setCustomer($customer);
    $isNewAddress = true;
}

// Append data
$address->addData($data);
$address->save();

if ($isNewAddress) {
    // Add address to customer and save
    $customer->addAddress($address)
        ->setDefaultBilling($address->getId())
        ->save();
}

OTHER TIPS

I came across this exact problem. The tricky part is that there's nothing wrong with the code that you've shown - the problem lies in the omitted code before it (how you load $c).

Crucially you need to reload the customer model before $c->getPrimaryBillingAddress(). In my case it was because I was loading the product via a [collection]->getFirstItem() call - which presumably didn't load the address (I didn't delve all the way to the source of the problem once it was fixed). I fixed it by adding the the following code before the call to $c->getPrimaryBillingAddress() (your first line):

$c = Mage::getModel('customer/customer')->load($c->getId());

(as horribly pointless as it may seem).

Your situation would presumably be the same, but I can't be sure without seeing how $c was initially loaded.

Your problem is most likely long solved or circumvented now, but I thought this answer may be useful for others like me, who stumbled upon it with the same confusing symptoms. The struggle is that although all the answers online are correct code, they all implicitly rely on the customer model being loaded directly.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top