I'm getting the following when purchasing membership products which are handles using features:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'pid' cannot be null: INSERT INTO {ms_products_purchases} (oid, uid, sku, pid, expiration, status, start_date, current_payments, max_payments, bundle, data) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10); Array ( [:db_insert_placeholder_0] => 5 [:db_insert_placeholder_1] => 672 [:db_insert_placeholder_2] => multibuy_jobs [:db_insert_placeholder_3] => [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => completed [:db_insert_placeholder_6] => 1503411231 [:db_insert_placeholder_7] => 1 [:db_insert_placeholder_8] => 1 [:db_insert_placeholder_9] => ms_membership [:db_insert_placeholder_10] => a:0:{} ) in ms_products_insert_purchase() (line 567 of /var/www/ROOTFOLDER/sites/all/modules/contrib/moneysuite/ms_core/ms_products/ms_products.purchases.inc).

I think that this is only happening after running a deployment which reverts features. If I edit the plan and save and then purchase it then it appears to be ok. This is only when purchasing plans of type membership.

Comments

vaccinemedia created an issue.

vaccinemedia’s picture

Further digging has discovered that the function having problems is:

function ms_products_insert_purchase($oid, $uid, $sku, $expiration = 0, $status = 'active', $start_date = 0, $current_payments = 0, $max_payments = 0) {
  if (!$start_date) {
    $start_date = REQUEST_TIME;
  }
  $plan = ms_products_plan_load($sku);
  $id = db_insert('ms_products_purchases')
    ->fields(array(
      'oid' => $oid,
      'uid' => $uid,
      'sku' => $sku,
      'pid' => $plan->pid,
      'expiration' => $expiration,
      'status' => $status,
      'start_date' => $start_date,
      'current_payments' => $current_payments,
      'max_payments' => $max_payments,
      'bundle' => $plan->bundle,
      'data' => serialize(array()),
    ))
    ->execute();

  // Call hook_ms_products_api_purchase_insert().
  $purchase = ms_products_purchase_load($id);
  module_invoke_all('ms_products_api_purchase_insert', $purchase, $plan);
  return $purchase;
}

And here is the function being called to load the plan:

function ms_products_plan_load($sku) {
  ctools_include('export');
  $result = ctools_export_load_object('ms_products_plans', 'names', array($sku));

  if (isset($result[$sku]) AND $plan = $result[$sku]) {
    $plan->initialize();

    return $plan;
  }
  return FALSE;
}

When reverting all features, the ms_product_plans table in the database is being emptied for some reason and so the db lookup being performed here is bringing back nothing and this is in turn supplying NULL for the plan->pid

Is there another way of looking up these entries if they are handled by features and not currently in the DB?

Farreres’s picture

wow, I think I can't help because I don't understand the problem. It seems something related to features and handles. Are these things something standard or what?

vaccinemedia’s picture

@Farreres features is the main method used on Drupal 7 to handle deployments. You can add the products to a feature module deploy the feature module and enable it in order to deploy the product / functionality. Features can be overridden with the changes being stored in the database and if you revert the feature, the entries in the database are removed and Drupal uses the values in code instead. ms_products_plan_load($sku) is looking in the database and if the feature has been reverted, there are no entries in there and that's why it's failing.