コマースチェックアウト-ユーザーが配送オプションを選択した後のカートペインの更新(ajax)


7

私は1ページのチェックアウトに取り組んでおり、ユーザーが配送オプションを選択している間、カートレビューペインを配送価格で更新しようとしています

配送オプションが保存されたときにカートのレビューフォームを更新するために、配送オプションに#ajax情報を添付しました。

チェックアウト時のコマース配送ajaxコールバックの変更

if($form_id == 'commerce_checkout_form_checkout') {
  $form['commerce_shipping']['shipping_service']['#ajax']['callback'] = 'mshop_shipping_pane_service_details_refresh';
}

Ajaxコールバック

function mshop_shipping_pane_service_details_refresh($form, $form_state) {
  // Update shipping form
  $commands[] = ajax_command_replace('#' . $form['commerce_shipping']['service_details']['#id'], render($form['commerce_shipping']['service_details']));

  // Update checkout cart review
  list($view_id, $display_id) = explode('|', variable_get('commerce_cart_contents_pane_view', 'commerce_cart_summary|default'));
  $commands[] = ajax_command_replace('.view-mshop-cart-shopping-cart-summary', commerce_embed_view($view_id, $display_id, array(arg(1))));

  return array('#type' => 'ajax', '#commands' => $commands);
}

問題: AJAXは機能しており、更新されたカートレビュービューは更新されていますが、配送オプションが適用されていません。

私の推測では、フォームは更新されるだけで送信されないため、注文は保存されません。したがって、カートレビューのビューは注文に基づいており、配送オプションは注文にまだ保存されていないため、カートレビューに正しい配送情報が表示されません。

回避策はありますか?

編集:

milkovskyのコメントのおかげで、注文に適用される配送料で注文を保存できました。次に、カートレビュービューが正しく表示され、更新されたカートレートが適用されます。

/**
 * Ajax callback: Returns the shipping details form elements that match the
 * currently selected shipping service.
 */
function mshop_shipping_pane_service_details_refresh($form, &$form_state, $checkout_pane, $order) {

  // Get order from form
  list($order, $checkout_pane) = $form_state['build_info']['args'];

  // Load up to date order
  $order = commerce_order_load($order->order_id);

  // Get selected 
  $service_name = $form['commerce_shipping']['shipping_service']['#default_value'];

  commerce_shipping_service_rate_order($service_name, $order);

  // Delete any existing shipping line items from the order.
  commerce_shipping_delete_shipping_line_items($order, TRUE);

  // Extract the unit price from the calculated rate.
  $rate_line_item = $order->shipping_rates[$service_name];
  $rate_line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $rate_line_item);
  $unit_price = $rate_line_item_wrapper->commerce_unit_price->value();

  // Create a new shipping line item with the calculated rate from the form.
  $line_item = commerce_shipping_line_item_new($service_name, $unit_price, $order->order_id, $rate_line_item->data, $rate_line_item->type);

  // Save and add the line item to the order.
  $new_line_item = commerce_shipping_add_shipping_line_item($line_item, $order, TRUE);
  commerce_order_save($order);


  // Update shipping form
  $commands[] = ajax_command_replace('#' . $form['commerce_shipping']['service_details']['#id'], render($form['commerce_shipping']['service_details']));


  // Update checkout cart review
  list($view_id, $display_id) = explode('|', variable_get('commerce_cart_contents_pane_view', 'commerce_cart_summary|default'));
  $commands[] = ajax_command_replace('.view-mshop-cart-shopping-cart-summary', commerce_embed_view($view_id, $display_id, array($order->order_id)));

  $commands[] = ajax_command_after('.main form', theme('status_messages'));

  // $commands[] = ajax_command_after('.'.$form['#attributes']['class'][1].':eq(0)',theme('status_messages'));
  return array('#type' => 'ajax', '#commands' => $commands);
}

既存のコールバックをオーバーライドしないかどうかを確認します$form['commerce_shipping']['shipping_service']['#ajax']['callback'] = ...
milkovsky

私はそれを動作させることができません-コードは if($form_id == 'commerce_checkout_form_checkout') { $form['commerce_shipping']['shipping_service']['#ajax']['callback'] = 'mshop_shipping_pane_service_details_refresh'; } 実装していますhook_form_alterか、それとも特別なコマースフックですか?
ダルマズ2015

はい、基本的なhook_form_alter()を実装しています。私の側では、それはDrupal Commerceの最新バージョンで動作します。コールバックは実行されましたか?
E. de Saint Chamas、2015

回答:


4

あなたが正しいです。配送料は、フォームを送信した後にのみ適用されます([次へ]をクリックします)。

送信すると、適用されたすべての配送ルール(または均一料金)が適用され、注文は新しいラインアイテムで保存されます(配送はカスタムラインアイテムタイプを介して実装されます)。

計算はcommerce_shipping_pane_checkout_form_submit()で実行されます

したがって、カートが更新される前に、この関数(またはその一部)をajaxコールバックで実行してみることができます。

フラットレートモジュールを使用している場合に送料を適用する方法の例を次に示し ます


1
おかげで、2番目のソリューションは魅力的に機能します。チェックアウトプロセスの途中で注文をロードして保存する必要がない最初のソリューションを選択しましたが、commerce_shipping_pane_checkout_form_submit()を正しく実装できませんでした。この関数ではアクセスできない2つの変数が必要です。私の投稿をソリューションで更新します。
E. de Saint Chamas、2015年

1
壮大な答えと編集!Thx-
ミシェル

それで、UIを通じてこれを強制する方法はありますか?
nizz0k 2017年

2

まず、このソリューションを投稿していただきありがとうございます。

AJAX応答から次の500エラーが発生しました: "EntityMetadataWrapperException:Missing data values。in EntityMetadataWrapper-> value()。

$ 100を超える注文で送料無料を提供したかったので、commerce_order_totalモジュール(https://www.drupal.org/sandbox/joshmiller/2718047)を有効にして、配送方法を選択するときにエラーを強調表示しました。

デバッグの結果、commerce_order_save()行が含まれている場合にのみ発生していたことがわかりました。

チェックアウトペインをすべて同じページに表示するように設定し、レビューペインを無効にしたため、この行をIFステートメントで囲みました。

//get checkout panes
$panes = commerce_checkout_panes();

//check if the Review pane is enabled
if ($panes['checkout_review']['enabled']){
  //review is enabled
  commerce_order_save($order);
}

コメント/改善が奨励されます!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.