11

カスタム金額でいくつかの品目をカートに追加する必要があります。コマース製品は価格 = 0 で保存され、私のモジュールは価格を計算して品目をカート/注文に追加しますが、プログラムで価格を設定する方法がわかりません。

Rules の使用について読みましたが、rules を呼び出さずに価格を設定/変更できるモジュールが必要です。

エンティティ ラッパーを試してみました。commerce_product_line_item_new() で作成された品目を変更しようとしましたが、品目がカートに入ると、常に元の製品価格 (私の場合は 0) になります。

広告申込情報の価格をプログラムで変更する方法

これまでの私のコードは次のようになります。

// For debugging, this function is called by hook_menu()
function mymodule_test($product_id)
{
    global $user;
    $user = user_load($user->uid);

    $order = commerce_cart_order_load($user->uid);
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);

    $product = commerce_product_load($product_id);

    $line_item = commerce_product_line_item_new(
            $product,
            1,
            0,
            array(
            ),
            'cover'
    );

    $line_item_wrapper = entity_metadata_wrapper("commerce_line_item", $line_item);

    $line_item_wrapper->commerce_unit_price->data = commerce_price_component_add(
            $line_item_wrapper->commerce_unit_price->value(),
            'base_price',
            array(
                            'amount' => 1234,
                            'currency_code' => 'EUR',
                            'data' => array(),
            ),
            TRUE
    );

    $insert_line_item = commerce_cart_product_add($user->uid, $line_item_wrapper->value(), FALSE);

    return 'done';
}

奇妙なことに、commerce/modules/line_item/commerce_line_item.rules.inc にある commerce_line_item_unit_price_amount() のコードを適合させようとしましたが、このテスト:

<?php
    global $user;
    $product = commerce_product_load(4); // my commerce product for test

    $line_item = commerce_product_line_item_new(
        $product,
        1,
        0,
        array(
        ),
        'cover' // I do have this line_items type
    );

    // manually set amount and component name
    $amount = 1234;
    $component_name = 'base_price'; // tryed with discount, nothing change

    $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
    $unit_price = commerce_price_wrapper_value($wrapper, 'commerce_unit_price', TRUE);

    // Calculate the updated amount and create a price array representing the
    // difference between it and the current amount.
    $current_amount = $unit_price['amount'];
    $updated_amount = commerce_round(COMMERCE_ROUND_HALF_UP, $amount);

    $difference = array(
        'amount' => $updated_amount - $current_amount, 
        'currency_code' => $unit_price['currency_code'], 
        'data' => array(),
    );

    // Set the amount of the unit price and add the difference as a component.
    $wrapper->commerce_unit_price->amount = $updated_amount;

    $wrapper->commerce_unit_price->data = commerce_price_component_add(
        $wrapper->commerce_unit_price->value(), 
        $component_name, 
        $difference, 
        TRUE
    );

    $insert_line_item = commerce_cart_product_add($user->uid, $line_item, FALSE);
?>

それでも失敗します。line_item はカートに入りますが、参照された製品の元の価格が表示されます。

何か案が?

4

5 に答える 5

19

ルールを使いたくなく、価格を直接変更したい人向け。これが私の解決策です:

// Alter the price in list and single product page.
function my_module_commerce_product_calculate_sell_price_line_item_alter($line_item){

    $price = 100; //1 dollar
    $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['amount'] = $price;

}

// Alter the price in cart & order.
function my_module_commerce_cart_line_item_refresh($line_item, $order_wrapper){

    $price = 100; //1 dollar
    $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['amount'] = $price;
    // Alter the base_price component.
    $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['data']['components']['0']['price']['amount'] = $price;

}
于 2014-01-28T01:23:46.160 に答える
6

ラインアイテムに保存された以前の値を無視して、新しい金額から合計を再計算する場合、探している関数は commerce_line_item_rebase_unit_price です。

新しい金額の値を設定し、そこから項目を実行して、項目と注文を保存します。

$line_item_wrapper->commerce_unit_price->amount = 13;

commerce_line_item_rebase_unit_price($line_item_wrapper->value());

commerce_line_item_save($line_item_wrapper->value());
于 2014-02-07T03:43:35.190 に答える
1

最近、Commerce で寄付フォームを実装する必要がありましたが、Commerce Express Checkoutモジュールはカスタム項目を処理しません。それは寄付であり、すべて (家を台無しにしようとしているのは誰ですか?) であるため、Express Checkout モジュールが提供する URL の 3 番目のパラメーターとして寄付額を渡すのが適切であると感じました。モジュールをハッキングする方法は次のとおりです。

ルーターに新しいエントリを追加しました。

$items['commerce-express-checkout/%/%/%'] = array(
      'title' => 'Express Checkout w/ extra argument',
      // 'page callback' => 'commerce_express_checkout_create_order',
      'page callback' => 'commerce_express_checkout_create_order_extra',
      'page arguments' => array(1, 2, 3),
      'access arguments' => array('access checkout'),
      'type' => MENU_CALLBACK,
  );

デフォルトのコールバックを複製して微調整し、「_extra」を追加しました。「データ」プロパティは、このような場合に備えて静的変数ストアのように見え、項目の寿命を持続することに注意してください。

function commerce_express_checkout_create_order_extra($product_id, $token, $amount) {

  if (drupal_hmac_base64($product_id, drupal_get_private_key().drupal_get_hash_salt()) == $token && is_numeric($amount)) {
    global $user;

    $product = commerce_product_load($product_id);

    $product->commerce_price['und'][0]['amount'] = (int)$amount;

    $order = ($user->uid) ? commerce_order_new($user->uid, 'checkout_checkout') : commerce_cart_order_new();

    commerce_order_save($order);

    $price = array('amount' => commerce_round(COMMERCE_ROUND_HALF_UP, $amount), 'currency_code' => commerce_default_currency());

    $line_item = commerce_product_line_item_new($product, 1, $order->order_id);
    $line_item->data = array('und' => array('0' => $price));
    commerce_line_item_save($line_item);

    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);

    $order_wrapper->commerce_line_items[] = $line_item;

    $order->data['type'] = 'commerce_express_checkout_order';

    commerce_order_save($order);

    drupal_goto('checkout/' . $order->order_id);

    return "";
  }

   return "";
}

以下は、単純に学習曲線が原因で最もトリッキーになった部分であり、一体何の関数を使用すればよいのかわからない:

/**                                                                             
 * Implements hook_commerce_cart_line_item_refresh().                           
 */                                                                             
function commerce_express_checkout_commerce_cart_line_item_refresh($line_item, $order_wrapper) { 
  if ($line_item->commerce_product['und'][0]['line_item_label'] == 'DONATE' || $line_item->commerce_product['und'][0]['product_id'] == '11') {
    $price = array('amount' => commerce_round(COMMERCE_ROUND_HALF_UP, $line_item->data['und'][0]['amount']), 'currency_code' => commerce_default_currency());
    $line_item->commerce_unit_price = array('und' => array('0' => $price));
    $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
    $line_item_wrapper->commerce_unit_price->data = commerce_price_component_add(
      $line_item_wrapper->commerce_unit_price->value(), 'base_price', $price, TRUE
    );
  }
}

カートが変更されるたびに、カートは更新され、カート内の製品をコード内プロトタイプに設定しようとします。私にとってもかなり非効率に思えますが、何かが欠けている可能性があります。

于 2013-07-23T22:09:55.673 に答える