Odoo Help


[Sale Promotion] Buy 1 get 1 Feature is not working for same Product .How to solve?

on 4/23/15, 10:52 PM 445 views

In Existing openerp Sale Promotion Module Buy 1 get 1 is not working for same product 

eg.If I have 2 product A,B

if i set in sales Rule

  buy 2 product of A then how to set 1 product of A give as a bonus .(This is not working)

but if I set in sales Rule if I buy Product A ,product B gone as Bonusc(This is Working ),How to change below code-------

def action_prod_x_get_y(self, cursor, user,

action, order, context=None):

print "inside^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ action_prod_x_get_y"


'Buy X get Y free:[Only for integers]'

@param cursor: Database Cursor

@param user: ID of User

@param action: Action to be taken on sale order

@param order: sale order

@param context: Context(no direct use).

Note: The function is too long because if it is split then there

will a lot of arguments to be passed from one function to

another. This might cause the function to get slow and

hamper the coding standards.


order_line_obj = self.pool.get('sale.order.line')

product_obj = self.pool.get('product.product')

vals = prod_qty = {}

#Get Product

product_x_code, product_y_code = [eval(code) \

for code in action.product_code.split(",")]

product_id = product_obj.search(cursor, user,

[('default_code', '=', product_x_code)],


if not product_id:

raise Exception("No product with the code for Y")

if len(product_id) > 1:

raise Exception("Many products with same code")

#get Quantity

qty_x, qty_y = [eval(arg) \

for arg in action.arguments.split(",")]

#Build a dictionary of product_code to quantity

for order_line in order.order_line:

if order_line.product_id:

product_code = order_line.product_id.default_code

prod_qty[product_code] = prod_qty.get(

product_code, 0.00

) + order_line.product_uom_qty

#Total number of free units of y to give






tot_free_y = int(int(prod_qty.get(product_x_code, 0) / qty_x) * qty_y)



#If y is already in the cart discount it?

qty_y_in_cart = prod_qty.get(product_y_code, 0)

existing_order_line_ids = order_line_obj.search(cursor, user,


('order_id', '=', order.id),


'=', product_y_code)




if existing_order_line_ids:

update_order_line = order_line_obj.browse(cursor, user,



#Update that line

#The replace is required because on secondary update

#the name may be repeated

if tot_free_y:

line_name = "%s (%s)" % (


'(%s)' % action.promotion.name,




if qty_y_in_cart <= tot_free_y:

#Quantity in cart is less then increase to total free

order_line_obj.write(cursor, user, update_order_line.id,



'product_uom_qty': tot_free_y,

'discount': 100,

}, context)


#If the order has come for 5 and only 3 are free

#then convert paid order to 2 units and rest free

order_line_obj.write(cursor, user, update_order_line.id,


'product_uom_qty': qty_y_in_cart - tot_free_y,

}, context)

self.create_y_line(cursor, user, action,






#delete the other lines


if existing_order_line_ids:

order_line_obj.unlink(cursor, user,

existing_order_line_ids, context)

return True


#Dont create line if quantity is not there

if not tot_free_y:

return True

return self.create_y_line(cursor, user, action,

order, tot_free_y, product_id, context)

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

About This Community

This platform is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.


Odoo Training Center

Access to our E-learning platform and experience all Odoo Apps through learning videos, exercises and Quizz.

Test it now

Question tools

1 follower(s)


Asked: 4/23/15, 10:52 PM
Seen: 445 times
Last updated: 4/24/15, 1:04 AM