611 lines
28 KiB
Python
611 lines
28 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of flectra. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
import json
|
||
|
|
||
|
import flectra.addons.decimal_precision as dp
|
||
|
from flectra import api, fields, models, _
|
||
|
from flectra.exceptions import Warning, UserError
|
||
|
from flectra.tools.misc import formatLang
|
||
|
|
||
|
|
||
|
class SaleOrder(models.Model):
|
||
|
_inherit = "sale.order"
|
||
|
|
||
|
@api.depends('amount_total', 'currency_id')
|
||
|
def _get_amount_word(self):
|
||
|
for order in self:
|
||
|
if not order.currency_id:
|
||
|
return
|
||
|
order.amount_words = order.currency_id.amount_to_text(
|
||
|
order.discount)
|
||
|
|
||
|
@api.depends('order_line', 'partner_id', 'coupon_flag')
|
||
|
def _check_cart_rules(self):
|
||
|
for order in self:
|
||
|
if order.pricelist_id.pricelist_type == 'advance':
|
||
|
order._update_all()
|
||
|
cart_discount = 0.0
|
||
|
cart_discount_per = \
|
||
|
order.get_cart_rules_discount(order.get_values())
|
||
|
if order.pricelist_id.discount_policy == 'without_discount':
|
||
|
for line in order.order_line:
|
||
|
if line.get_line_percentage(cart_discount_per) < 100:
|
||
|
cart_discount += \
|
||
|
((line.price_unit * line.product_uom_qty
|
||
|
) * cart_discount_per) / 100
|
||
|
order.cart_discount = cart_discount
|
||
|
else:
|
||
|
for line in order.order_line:
|
||
|
line.set_line_amount(cart_discount_per)
|
||
|
|
||
|
@api.multi
|
||
|
def get_cart_discount(self, cart_rule_id, values):
|
||
|
cart_discount = cart_rule_id._get_cart_discount_amt(
|
||
|
self.pricelist_id, total=values.get('amount_untaxed'),
|
||
|
item_count=values.get('item_count'),
|
||
|
item_sum_count=values.get('item_sum_count'),
|
||
|
product_ids=values.get('product_ids'),
|
||
|
categ_ids=values.get('categ_ids'), order=self)
|
||
|
return cart_discount
|
||
|
|
||
|
@api.multi
|
||
|
def get_cart_rules_discount(self, values):
|
||
|
if not self.pricelist_id:
|
||
|
return 0.0
|
||
|
date = fields.Date.context_today(self)
|
||
|
self._cr.execute(
|
||
|
'SELECT rule.id '
|
||
|
'FROM cart_rule AS rule '
|
||
|
'WHERE (rule.pricelist_id = %s) '
|
||
|
'AND (rule.start_date IS NULL OR rule.start_date<=%s) '
|
||
|
'AND (rule.end_date IS NULL OR rule.end_date>=%s)'
|
||
|
'ORDER BY rule.sequence',
|
||
|
(self.pricelist_id.id, date, date))
|
||
|
item_ids = [x[0] for x in self._cr.fetchall()]
|
||
|
cart_rule_ids = self.env['cart.rule'].browse(item_ids)
|
||
|
if not cart_rule_ids:
|
||
|
return 0.0
|
||
|
final_dis_price = 0.0
|
||
|
one_dis_price = all_dis_price = 0.0
|
||
|
max_dis_price = []
|
||
|
min_dis_price = []
|
||
|
cart_discount = 0.0
|
||
|
for cart_rule_id in cart_rule_ids:
|
||
|
cart_discount = self.get_cart_discount(cart_rule_id, values)
|
||
|
if cart_rule_id.pricelist_id.apply_method == \
|
||
|
'first_matched_rule' and \
|
||
|
cart_discount > 0.0:
|
||
|
one_dis_price = cart_discount
|
||
|
break
|
||
|
elif cart_rule_id.pricelist_id.apply_method == 'all_matched_rules':
|
||
|
all_dis_price += cart_discount
|
||
|
elif cart_rule_id.pricelist_id.apply_method == \
|
||
|
'smallest_discount' and cart_discount:
|
||
|
min_dis_price.append(cart_discount)
|
||
|
else:
|
||
|
max_dis_price.append(cart_discount)
|
||
|
if one_dis_price > 0.0:
|
||
|
final_dis_price = one_dis_price
|
||
|
elif all_dis_price > 0.0:
|
||
|
final_dis_price = all_dis_price
|
||
|
elif min_dis_price:
|
||
|
final_dis_price = min(min_dis_price)
|
||
|
elif max_dis_price:
|
||
|
final_dis_price = max(max_dis_price)
|
||
|
return final_dis_price
|
||
|
|
||
|
@api.model
|
||
|
def _get_discount_vals(self):
|
||
|
payment_vals = []
|
||
|
price_list_discount = price_rule_discount = coupon_code_discount = 0.0
|
||
|
coupon_code_obj = self.env['coupon.code']
|
||
|
partner_id = self.partner_id
|
||
|
pricelist_id = self.pricelist_id
|
||
|
for line in self.order_line:
|
||
|
if not (line.product_id and line.product_uom and
|
||
|
partner_id and pricelist_id and
|
||
|
pricelist_id.discount_policy == 'without_discount' and
|
||
|
self.env.user.has_group(
|
||
|
'sale.group_discount_per_so_line')):
|
||
|
return
|
||
|
if pricelist_id.pricelist_type == 'basic':
|
||
|
price_list_discount = self.discount
|
||
|
else:
|
||
|
if line.product_uom_qty < 0 and line.coupon_code_id:
|
||
|
continue
|
||
|
if line.order_id.have_coupon_code and line.coupon_code_id:
|
||
|
coupon_code_discount += \
|
||
|
coupon_code_obj.get_coupon_discount(line, True)
|
||
|
if line.coupon_code_id and line.price_unit == 0:
|
||
|
continue
|
||
|
if pricelist_id.pricelist_type != 'basic':
|
||
|
price_rule_discount = (self.discount - coupon_code_discount
|
||
|
) - self.cart_discount
|
||
|
untaxed_amount = self.gross_amount - self.discount
|
||
|
payment_vals.append({
|
||
|
'gross_amount': formatLang(self.env, self.gross_amount, digits=2),
|
||
|
'price_list_discount':
|
||
|
formatLang(self.env, price_list_discount, digits=2),
|
||
|
'price_rule_discount':
|
||
|
formatLang(self.env, price_rule_discount, digits=2),
|
||
|
'cart_rule_discount':
|
||
|
formatLang(self.env, self.cart_discount, digits=2),
|
||
|
'coupon_code_discount':
|
||
|
formatLang(self.env, coupon_code_discount, digits=2),
|
||
|
'currency': self.pricelist_id.currency_id.symbol,
|
||
|
'untaxed_amount': formatLang(self.env, untaxed_amount, digits=2),
|
||
|
'position': self.pricelist_id.currency_id.position,
|
||
|
'amount_words': self.amount_words,
|
||
|
'discount': formatLang(self.env, self.discount, digits=2),
|
||
|
})
|
||
|
return payment_vals
|
||
|
|
||
|
@api.depends('discount')
|
||
|
def _get_discount_info_JSON(self):
|
||
|
for record in self:
|
||
|
info = {'title': _('Discount'), 'outstanding': False,
|
||
|
'content': record._get_discount_vals()}
|
||
|
record.discount_widget = json.dumps(info)
|
||
|
|
||
|
def _update_all(self):
|
||
|
for order in self:
|
||
|
amount_untaxed = amount_tax = item_count = item_sum_count = 0.0
|
||
|
product_ids = categ_ids = []
|
||
|
check_dup_product = []
|
||
|
for line in order.order_line:
|
||
|
amount_untaxed += line.price_subtotal
|
||
|
amount_tax += line.price_tax
|
||
|
item_sum_count += line.product_uom_qty
|
||
|
if line.product_id.id not in check_dup_product:
|
||
|
item_count += 1
|
||
|
check_dup_product.append(line.product_id.id)
|
||
|
product_ids.append(line.product_id.id)
|
||
|
categ_ids.append(line.product_id.categ_id.id)
|
||
|
return {
|
||
|
'amount_untaxed': amount_untaxed,
|
||
|
'amount_tax': amount_tax,
|
||
|
'item_sum_count': item_sum_count,
|
||
|
'item_count': item_count,
|
||
|
'product_ids': product_ids,
|
||
|
'categ_ids': categ_ids,
|
||
|
}
|
||
|
|
||
|
@api.multi
|
||
|
def get_values(self):
|
||
|
return self._update_all()
|
||
|
|
||
|
have_coupon_code = fields.Char('Have Coupon Code')
|
||
|
cart_discount = fields.Float(
|
||
|
compute='_check_cart_rules', string='Cart Discount')
|
||
|
coupon_flag = fields.Boolean('Check Coupon Apply')
|
||
|
amount_words = fields.Char(string="Discount Amount Words",
|
||
|
compute='_get_amount_word', store=True)
|
||
|
discount_widget = fields.Text(compute='_get_discount_info_JSON')
|
||
|
coupon_code_id = fields.Many2one('coupon.code', 'Coupon Ref')
|
||
|
|
||
|
@api.multi
|
||
|
def _get_percentage_coupon_discount(self, line, coupon_code_id,
|
||
|
onchange_context, cal_coupon,
|
||
|
discount_per, remove):
|
||
|
coupon_discount_amount = 0.0
|
||
|
total_price = (line.product_uom_qty * line.price_unit)
|
||
|
if self.coupon_flag and not onchange_context and line.coupon_code_id:
|
||
|
line.write({'check_coupon': False,
|
||
|
'discount': line.discount - discount_per,
|
||
|
'coupon_code_id': False,
|
||
|
'check_coupon': False})
|
||
|
elif not cal_coupon and not remove:
|
||
|
coupon_discount_amount = (total_price * discount_per) / 100
|
||
|
line.discount = line.discount + discount_per
|
||
|
line.coupon_code_id = coupon_code_id.id
|
||
|
line.check_coupon = True
|
||
|
else:
|
||
|
coupon_discount_amount = (total_price * discount_per) / 100
|
||
|
return coupon_discount_amount
|
||
|
|
||
|
@api.multi
|
||
|
def _get_fixed_coupon_discount(self, line, coupon_code_id,
|
||
|
onchange_context, cal_coupon, remove):
|
||
|
line_discount = 0.0
|
||
|
if not line.price_unit:
|
||
|
return 0.0
|
||
|
discount_amount = 0.0
|
||
|
if line.price_unit < coupon_code_id.discount_amount:
|
||
|
discount_amount = line.price_unit
|
||
|
if self.coupon_flag and not onchange_context and line.coupon_code_id:
|
||
|
if discount_amount:
|
||
|
line_discount = (line.price_unit * line.dummy_discount / 100
|
||
|
) - line.price_unit
|
||
|
line.write({'check_coupon': False,
|
||
|
'discount': line_discount / line.price_unit * 100,
|
||
|
'coupon_code_id': False})
|
||
|
else:
|
||
|
if line.dummy_discount:
|
||
|
line_discount = \
|
||
|
(line.price_unit * line.dummy_discount / 100
|
||
|
) - coupon_code_id.discount_amount
|
||
|
else:
|
||
|
line_discount = (line.price_unit * line.discount / 100
|
||
|
) - coupon_code_id.discount_amount
|
||
|
line.write({'check_coupon': False,
|
||
|
'discount': line_discount / line.price_unit * 100,
|
||
|
'coupon_code_id': False})
|
||
|
elif not cal_coupon and not remove:
|
||
|
if discount_amount:
|
||
|
line_discount = (line.price_unit * line.discount / 100
|
||
|
) + discount_amount
|
||
|
else:
|
||
|
line_discount = (line.price_unit * line.discount / 100
|
||
|
) + coupon_code_id.discount_amount
|
||
|
percent = line_discount / line.price_unit * 100
|
||
|
if percent > 100:
|
||
|
line.dummy_discount = percent
|
||
|
line.discount = 100
|
||
|
else:
|
||
|
line.discount = percent
|
||
|
line.coupon_code_id = coupon_code_id.id
|
||
|
line.check_coupon = True
|
||
|
return line.product_uom_qty * coupon_code_id.discount_amount
|
||
|
|
||
|
@api.multi
|
||
|
def _get_same_product_coupon_discount(self, line, coupon_code_id, remove):
|
||
|
qty = int((line.product_uom_qty / coupon_code_id.number_of_x_product)
|
||
|
) * coupon_code_id.number_of_y_product
|
||
|
if line.coupon_code_id and line.check_coupon:
|
||
|
line.write({'check_coupon': False, 'coupon_code_id': False})
|
||
|
elif self.coupon_flag and line.coupon_code_id and \
|
||
|
not line.check_coupon:
|
||
|
line.unlink()
|
||
|
elif line.product_uom_qty == coupon_code_id.number_of_x_product and \
|
||
|
not remove:
|
||
|
line.write({'check_coupon': True,
|
||
|
'coupon_code_id': coupon_code_id.id})
|
||
|
self.env['sale.order.line'].create(
|
||
|
{
|
||
|
'product_id': line.product_id.id,
|
||
|
'product_uom_qty': coupon_code_id.number_of_y_product,
|
||
|
'order_id': self.id,
|
||
|
'discount': 0.0,
|
||
|
'coupon_code_id': coupon_code_id.id,
|
||
|
'price_unit': 0.0
|
||
|
})
|
||
|
elif not self.coupon_flag and qty >= 1:
|
||
|
line.write({'check_coupon': True,
|
||
|
'coupon_code_id': coupon_code_id.id})
|
||
|
self.env['sale.order.line'].create(
|
||
|
{
|
||
|
'product_id': line.product_id.id,
|
||
|
'product_uom_qty': int(qty),
|
||
|
'order_id': self.id,
|
||
|
'discount': 0.0,
|
||
|
'coupon_code_id': coupon_code_id.id,
|
||
|
'price_unit': 0.0
|
||
|
})
|
||
|
|
||
|
@api.multi
|
||
|
def _get_other_product_coupon_discount(self, line, coupon_code_id):
|
||
|
qty = int((line.product_uom_qty / coupon_code_id.number_of_x_product)
|
||
|
) * coupon_code_id.number_of_y_product
|
||
|
if line.coupon_code_id and line.check_coupon:
|
||
|
line.write({'check_coupon': False, 'coupon_code_id': False})
|
||
|
return 0.0
|
||
|
elif self.coupon_flag and line.coupon_code_id \
|
||
|
and not line.check_coupon:
|
||
|
line.unlink()
|
||
|
return 0.0
|
||
|
elif not self.coupon_flag and qty >= 1:
|
||
|
line.write({'check_coupon': True,
|
||
|
'coupon_code_id': coupon_code_id.id})
|
||
|
return qty
|
||
|
return 0.0
|
||
|
|
||
|
@api.multi
|
||
|
def buy_x_get_percentage_coupon_discount(
|
||
|
self, line, coupon_code_id, onchange_context, cal_coupon, remove):
|
||
|
coupon_discount_amount = 0.0
|
||
|
total_price = (line.product_uom_qty * line.price_unit)
|
||
|
if self.coupon_flag and not onchange_context and line.coupon_code_id \
|
||
|
and line.product_uom_qty > coupon_code_id.number_of_x_product:
|
||
|
line.write({'check_coupon': False,
|
||
|
'discount':
|
||
|
line.discount - coupon_code_id.discount_amount,
|
||
|
'coupon_code_id': False,
|
||
|
'check_coupon': False})
|
||
|
elif not cal_coupon and not remove and line.product_uom_qty >= \
|
||
|
coupon_code_id.number_of_x_product:
|
||
|
coupon_discount_amount = \
|
||
|
(total_price * coupon_code_id.discount_amount) / 100
|
||
|
line.discount = line.discount + coupon_code_id.discount_amount
|
||
|
line.coupon_code_id = coupon_code_id.id
|
||
|
line.check_coupon = True
|
||
|
else:
|
||
|
coupon_discount_amount = \
|
||
|
(total_price * coupon_code_id.discount_amount) / 100
|
||
|
return coupon_discount_amount
|
||
|
|
||
|
@api.multi
|
||
|
def _check_Constraints(self):
|
||
|
self.get_values()
|
||
|
order_line = self.order_line
|
||
|
if not self.have_coupon_code:
|
||
|
raise UserError(_("Please enter the Coupon code!"))
|
||
|
if not order_line:
|
||
|
raise UserError(_("There is no sale order line!"))
|
||
|
if self.pricelist_id.pricelist_type != 'advance' or not \
|
||
|
self.pricelist_id.apply_coupon_code:
|
||
|
raise UserError(_("Coupon code does not apply to "
|
||
|
"sale order pricelist!"))
|
||
|
coupon_obj = self.env['coupon.code']
|
||
|
coupon_code_id = coupon_obj.get_coupon_records(
|
||
|
self.have_coupon_code, self.pricelist_id)
|
||
|
if not coupon_code_id:
|
||
|
raise UserError(_("Coupon code (%s) not found!"
|
||
|
) % (self.have_coupon_code))
|
||
|
if coupon_code_id.usage_limit > 0 \
|
||
|
and coupon_code_id.remaining_limit <= 0:
|
||
|
raise UserError(_("Coupon code (%s) Remaining Limit exceeds!"
|
||
|
) % (self.have_coupon_code))
|
||
|
if coupon_code_id.min_order_amount \
|
||
|
and self.amount_untaxed < coupon_code_id.min_order_amount \
|
||
|
and not self.env.context.get('remove', False):
|
||
|
raise UserError(_("Untaxed Amount (%s) must be greater than "
|
||
|
"Min Order Amount (%s) which required for "
|
||
|
"the apply coupon code!") % (
|
||
|
formatLang(self.env, self.amount_untaxed, digits=2),
|
||
|
formatLang(self.env, coupon_code_id.min_order_amount,
|
||
|
digits=2)))
|
||
|
if coupon_code_id.model_id:
|
||
|
check_coupon = coupon_obj.check_condition(
|
||
|
coupon_code_id, self.partner_id)
|
||
|
if check_coupon:
|
||
|
raise Warning(_("Coupon code (%s) condition criteria not "
|
||
|
"match!") % (self.have_coupon_code))
|
||
|
return coupon_code_id
|
||
|
|
||
|
@api.multi
|
||
|
def apply_coupon_code(self):
|
||
|
coupon_id = self._check_Constraints()
|
||
|
order_line = self.order_line
|
||
|
coupon_discount_amount = 0.0
|
||
|
have_coupon_code = self.have_coupon_code
|
||
|
coupon_flag = True
|
||
|
onchange_context = True
|
||
|
coupon_ref_id = coupon_id.id
|
||
|
remove = False
|
||
|
cal_coupon = False
|
||
|
if self.coupon_flag:
|
||
|
have_coupon_code = ''
|
||
|
coupon_flag = False
|
||
|
onchange_context = False
|
||
|
coupon_ref_id = False
|
||
|
remove = True
|
||
|
check_coupon = True
|
||
|
qty = 0.0
|
||
|
for line in order_line:
|
||
|
if coupon_id.apply_on == 'category' and not \
|
||
|
line.product_id.categ_id == coupon_id.categ_id:
|
||
|
continue
|
||
|
elif coupon_id.apply_on == 'product_template' and not \
|
||
|
line.product_id.product_tmpl_id == \
|
||
|
coupon_id.product_tmpl_id:
|
||
|
continue
|
||
|
elif coupon_id.apply_on == 'product' and not \
|
||
|
line.product_id == coupon_id.product_id:
|
||
|
continue
|
||
|
else:
|
||
|
if coupon_id.coupon_type == 'percent' or \
|
||
|
coupon_id.coupon_type == 'clubbed':
|
||
|
discount_per = coupon_id.discount_amount
|
||
|
if coupon_id.coupon_type == 'clubbed':
|
||
|
discount_per = coupon_id.flat_discount + \
|
||
|
coupon_id.extra_discount_percentage
|
||
|
coupon_discount_amount += \
|
||
|
self._get_percentage_coupon_discount(
|
||
|
line, coupon_id, onchange_context,
|
||
|
cal_coupon, discount_per, remove)
|
||
|
check_coupon = False
|
||
|
elif coupon_id.coupon_type == 'fixed_amount':
|
||
|
coupon_discount_amount += self._get_fixed_coupon_discount(
|
||
|
line, coupon_id, onchange_context, cal_coupon, remove)
|
||
|
check_coupon = False
|
||
|
elif coupon_id.coupon_type == 'buy_x_get_y' and \
|
||
|
coupon_id.number_of_x_product and \
|
||
|
coupon_id.number_of_y_product:
|
||
|
if line.product_uom_qty < \
|
||
|
coupon_id.number_of_x_product and not \
|
||
|
line.coupon_code_id and check_coupon:
|
||
|
check_coupon = True
|
||
|
continue
|
||
|
self._get_same_product_coupon_discount(
|
||
|
line, coupon_id, remove)
|
||
|
check_coupon = False
|
||
|
elif coupon_id.coupon_type == 'buy_x_get_y_other':
|
||
|
if line.product_uom_qty < \
|
||
|
coupon_id.number_of_x_product and not \
|
||
|
line.coupon_code_id and check_coupon:
|
||
|
check_coupon = True
|
||
|
continue
|
||
|
qty += self._get_other_product_coupon_discount(
|
||
|
line, coupon_id)
|
||
|
check_coupon = False
|
||
|
elif coupon_id.coupon_type == 'buy_x_get_percent':
|
||
|
if line.product_uom_qty < \
|
||
|
coupon_id.number_of_x_product and not \
|
||
|
line.coupon_code_id and check_coupon:
|
||
|
check_coupon = True
|
||
|
continue
|
||
|
coupon_discount_amount += \
|
||
|
self.buy_x_get_percentage_coupon_discount(
|
||
|
line, coupon_id, onchange_context,
|
||
|
cal_coupon, remove)
|
||
|
check_coupon = False
|
||
|
if check_coupon:
|
||
|
raise Warning(_("Coupon code (%s) condition criteria not match!"
|
||
|
) % (self.have_coupon_code))
|
||
|
if qty:
|
||
|
self.env['sale.order.line'].create({
|
||
|
'product_id': coupon_id.other_product_id.id,
|
||
|
'product_uom_qty': int(qty), 'order_id': self.id,
|
||
|
'coupon_code_id': coupon_id.id, 'price_unit': 0.0})
|
||
|
self.write({'have_coupon_code': have_coupon_code,
|
||
|
'coupon_flag': coupon_flag,
|
||
|
'coupon_code_id': coupon_ref_id})
|
||
|
|
||
|
|
||
|
class SaleOrderLine(models.Model):
|
||
|
_inherit = "sale.order.line"
|
||
|
|
||
|
coupon_code_id = fields.Many2one('coupon.code', 'Coupon Ref')
|
||
|
check_coupon = fields.Boolean('Apply Coupon')
|
||
|
dummy_discount = fields.Float(
|
||
|
string='Discount (%)',
|
||
|
digits=dp.get_precision('Discount'), default=0.0)
|
||
|
|
||
|
@api.multi
|
||
|
def get_line_percentage(self, percent):
|
||
|
self._onchange_discount()
|
||
|
discount = self.discount + percent
|
||
|
if discount > 100:
|
||
|
self.dummy_discount = discount
|
||
|
discount = 100
|
||
|
self.discount = discount
|
||
|
return discount
|
||
|
|
||
|
@api.multi
|
||
|
def set_line_amount(self, percent):
|
||
|
discount, product_price = self.get_rule_discount()
|
||
|
if product_price:
|
||
|
discount = product_price * (discount + percent) / 100
|
||
|
self.price_unit = product_price - discount
|
||
|
|
||
|
@api.multi
|
||
|
def get_total_coupon_code(self):
|
||
|
return self.env['coupon.code'].get_coupon_discount(self, False)
|
||
|
|
||
|
def _get_real_price_currency_flectra(self, product, uom,
|
||
|
pricelist_id, price_unit):
|
||
|
currency_id = pricelist_id.currency_id
|
||
|
product_currency = \
|
||
|
(product.company_id and product.company_id.currency_id
|
||
|
) or self.env.user.company_id.currency_id
|
||
|
if currency_id.id == product_currency.id:
|
||
|
cur_factor = 1.0
|
||
|
else:
|
||
|
cur_factor = currency_id._get_conversion_rate(
|
||
|
product_currency, currency_id)
|
||
|
product_uom = self.env.context.get('uom') or product.uom_id.id
|
||
|
if uom and uom.id != product_uom:
|
||
|
uom_factor = uom._compute_price(1.0, product.uom_id)
|
||
|
else:
|
||
|
uom_factor = 1.0
|
||
|
return price_unit * uom_factor * cur_factor, currency_id.id
|
||
|
|
||
|
@api.multi
|
||
|
def get_rule_discount(self):
|
||
|
date = fields.Date.context_today(self)
|
||
|
rules = self.env['price.rule'].get_rules(
|
||
|
self.order_id.pricelist_id, date)
|
||
|
max_dis_price = []
|
||
|
min_dis_price = []
|
||
|
discount_per = 0.0
|
||
|
apply_method = self.order_id.pricelist_id.apply_method
|
||
|
discount = 0.0
|
||
|
context_partner = dict(self.env.context,
|
||
|
partner_id=self.order_id.partner_id.id,
|
||
|
date=self.order_id.date_order)
|
||
|
pricelist_context = dict(context_partner, uom=self.product_uom.id)
|
||
|
product_price = 0.0
|
||
|
for rule in rules:
|
||
|
adv_price, adv_rule_id = \
|
||
|
self.order_id.pricelist_id.with_context(
|
||
|
pricelist_context).get_product_price_rule_flectra(
|
||
|
self.product_id, self.product_uom_qty,
|
||
|
self.order_id.partner_id, rule, self.price_unit)
|
||
|
rule_line_id = self.env['rule.line'].browse(adv_rule_id)
|
||
|
if not rule_line_id:
|
||
|
return discount, product_price
|
||
|
adv_new_price = 0.0
|
||
|
currency_id = False
|
||
|
if rule_line_id.rule_type == 'percent':
|
||
|
adv_new_price, currency_id = self.with_context(
|
||
|
context_partner)._get_real_price_currency(
|
||
|
self.product_id, False,
|
||
|
self.product_uom_qty,
|
||
|
self.product_uom,
|
||
|
self.order_id.pricelist_id.id)
|
||
|
else:
|
||
|
adv_new_price, currency_id = self.with_context(
|
||
|
context_partner)._get_real_price_currency_flectra(
|
||
|
self.product_id,
|
||
|
self.product_uom,
|
||
|
self.order_id.pricelist_id, self.price_unit)
|
||
|
if adv_new_price != 0:
|
||
|
if self.order_id.pricelist_id.currency_id.id != currency_id:
|
||
|
adv_new_price = self.env['res.currency'].browse(
|
||
|
currency_id).with_context(context_partner).compute(
|
||
|
adv_new_price, rule.pricelist_id.currency_id)
|
||
|
if not product_price:
|
||
|
product_price = adv_new_price
|
||
|
discount_per =\
|
||
|
(adv_new_price - adv_price) / adv_new_price * 100
|
||
|
if apply_method == 'first_matched_rule':
|
||
|
discount += discount_per
|
||
|
break
|
||
|
elif apply_method == 'all_matched_rules':
|
||
|
discount += discount_per
|
||
|
elif apply_method == 'smallest_discount' and adv_rule_id:
|
||
|
min_dis_price.append(discount_per)
|
||
|
else:
|
||
|
max_dis_price.append(discount_per)
|
||
|
if min_dis_price:
|
||
|
discount += min(min_dis_price)
|
||
|
if max_dis_price:
|
||
|
discount += max(max_dis_price)
|
||
|
return discount, product_price
|
||
|
|
||
|
# Overrides Function
|
||
|
@api.onchange('product_id', 'price_unit', 'product_uom',
|
||
|
'product_uom_qty', 'tax_id')
|
||
|
def _onchange_discount(self):
|
||
|
self.discount = 0.0
|
||
|
if not (self.product_id and self.product_uom and
|
||
|
self.order_id.partner_id and self.order_id.pricelist_id and
|
||
|
self.order_id.pricelist_id.discount_policy ==
|
||
|
'without_discount' and
|
||
|
self.env.user.has_group('sale.group_discount_per_so_line')):
|
||
|
return
|
||
|
discount = 0.0
|
||
|
context_partner = dict(self.env.context,
|
||
|
partner_id=self.order_id.partner_id.id,
|
||
|
date=self.order_id.date_order)
|
||
|
pricelist_context = dict(context_partner, uom=self.product_uom.id)
|
||
|
if self.order_id.pricelist_id.pricelist_type == 'basic':
|
||
|
price, rule_id = self.order_id.pricelist_id.with_context(
|
||
|
pricelist_context).get_product_price_rule(
|
||
|
self.product_id, self.product_uom_qty or 1.0,
|
||
|
self.order_id.partner_id)
|
||
|
new_list_price, currency_id = self.with_context(
|
||
|
context_partner)._get_real_price_currency(
|
||
|
self.product_id, rule_id, self.product_uom_qty,
|
||
|
self.product_uom, self.order_id.pricelist_id.id)
|
||
|
if new_list_price != 0:
|
||
|
if self.order_id.pricelist_id.currency_id.id != currency_id:
|
||
|
new_list_price = self.env['res.currency'].browse(
|
||
|
currency_id).with_context(context_partner).compute(
|
||
|
new_list_price, self.order_id.pricelist_id.currency_id)
|
||
|
discount = (new_list_price - price) / new_list_price * 100
|
||
|
if discount > 0:
|
||
|
self.discount = discount
|
||
|
else:
|
||
|
if self.coupon_code_id and (self._context.get(
|
||
|
'quantity', False) or self._context.get(
|
||
|
'price_unit', False) or self._context.get('tax', False)):
|
||
|
raise Warning(_('You can not change order line. '
|
||
|
'Please remove coupon code first!'))
|
||
|
discount, product_price = self.get_rule_discount()
|
||
|
if discount > 0:
|
||
|
self.discount = discount
|
||
|
if self.order_id.have_coupon_code and self.coupon_code_id:
|
||
|
self.get_total_coupon_code()
|