2012-11-21 28 views
11

我必須在自己的購物車中添加一些自定義金額的訂單項。 商業產品保存的價格= 0,我的模塊計算價格並將訂單項添加到購物車/訂單,但我不明白如何以編程方式設置價格。Drupal Commerce Line Items:改變價格?

我已閱讀使用規則,但我需要我的模塊能夠設置/更改價格,,而無需調用規則。我嘗試改變使用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'; 
} 

奇怪的是,我tryed適應commerce_line_item_unit_price_amount()在商業/模塊/ LINE_ITEM/commerce_line_item.rules.inc發現的代碼,但是這測試:

<?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進入購物車,但與參考產品的原始價格。

有什麼想法?

+0

你不保存您的包裝......這可能是問題(即'$ line_item_wrapper->保存();') – Clive

+0

@Clive我想我也嘗試過,但讓我再試一次,以防萬一 – Strae

+0

哦,你還需要保存'$ order_wrapper'(當我做某事的時候,類似幾個月回來) – Clive

回答

18

對於那些不想使用規則並希望直接改變價格的人。這裏是我的解決方案:

// 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; 

} 
+0

你好,上面的'hook'沒有從我的模塊中觸發。嘗試單一產品頁面'鉤子'。我正在使用DC Kickstart。 – james

+0

你有任何其他地方設置價格? 你可以嘗試在鉤子kpr($ line_item)看看它是什麼樣子。 –

4

我今天整天都在努力解決這個問題,並最終找出了改變訂單項價格的正確途徑。問題是,即使您成功將訂單項價格更改爲自定義值,在下一頁上刷新購物車將重置行項目以匹配原始產品價格。詳情請看commerce_cart_order_refresh()函數。每次在頁面上加載訂單/購物車時都會執行此功能,並且無法繞過它。

事實證明,更改訂單項價格的正確方法是使用規則或實現hook_commerce_cart_line_item_refresh()函數。無論哪種方式,Drupal Commerce都需要能夠在每次購物車/訂單加載時應用更改邏輯。

我最終在行項目中創建了一個自定義字段,其中存儲了我想要的自定義價格值。然後,我使用定價規則在購物車刷新時將定製價格值複製到產品價格值。

以下博客文章對此很有幫助。它向您展示瞭如何將自定義字段添加到訂單項類型,以及如何設置定價規則以將自定義金額複製到單價。

http://commerceguys.com/blog/using-custom-line-items-provide-donation-feature-drupal-commerce

+1

感謝分享! Drupal Commerce功能強大且靈活,但我仍然不明白爲什麼價格變動以嚴格的方式與規則相關。 – Strae

+0

你能發佈最終代碼嗎? – MSD

+0

@MichaelStevens我發佈了一個實現這個函數的例子。 – mpoplin

1

最近,我不得不實施在商務部捐贈的形式,但Commerce Express Checkout模塊不處理自定義行項目。既然這是一個捐款,所有人(誰在試圖搞砸這個房子?),我認爲將捐贈金額作爲Express Checkout模塊提供的URL中的第三個參數傳遞是合適的。下面是我如何着手黑客模塊:

我添加了一個新條目到路由器:

$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」給它。請注意,對於像這樣的場合,「data」屬性似乎是一個靜態變量存儲區,並且會持續該訂單項的生命週期。

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 
    ); 
    } 
} 

每一個時間的車被修改,它刷新並嘗試將購物車中的產品設置爲代碼原型。對我來說這似乎相當低效,但我可能會錯過一些東西。

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()); 
+2

在我看來,這是最好的答案。我確信有些情況下Drupal Commerce的複雜定價系統非常有幫助,但在我遇到的使用案例中,我只想設置當時的價格**,而且我不想實現另一個鉤子(從而使我的代碼更難以理解)。 – jaskho

0

這篇文章我指出了正確的方向通過編程方式改變一個Drupal商務線項目使用hook_commerce_cart_line_item_refersh()。但是,這裏的一些答案要麼是完全錯誤的,要麼是效率低下,馬虎。

這將是在Drupal商務部修改訂單類型正確有效的解決方案:

/* 
* implements hook_commerce_cart_line_item_refresh() 
* 
*/ 

function MYMODULE_commerce_cart_line_item_refresh($line_item, $order_wrapper){ 

    $line_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item); 

    $new_price = 100; //I use a function to calculate the value of $new_price 

    if(!empty($new_price)){ 
     $line_wrapper->commerce_unit_price->amount->set($new_price); 
     $line_wrapper->save(); 
    } 
}