class Promotion < ApplicationRecord validates_presence_of :promo_code,:promo_start_date,:promo_end_date,:promo_start_hour,:promo_end_hour,:promo_type,:original_product,:min_qty has_many :promotion_products accepts_nested_attributes_for :promotion_products , :allow_destroy => true , update_only: true PROMO_TYPE1 = "Quantity" PROMO_TYPE2 = "Net_off" # 3000 => - 500 => 2500 [total] PROMO_TYPE3 = "Net_price" # 1800 => 1000 => 1000 PROMO_TYPE4 = "Percentage" def self.promo_activate(saleObj) current_day = Time.now.strftime("%Y-%m-%d") current_time = Time.now.strftime('%H:%M:%S') day = Date.today.wday promoList = is_between_promo_datetime(current_day,current_time) puts "promoList - " + promoList.size.to_s if promoList.size > 0 itemList = combine_item(saleObj) is_promo_day(promoList,day, itemList, saleObj.sale_id) end end def self.is_between_promo_datetime(current_day,current_time) #database is not local time promoList = Promotion.where("(Date_Format(promo_start_date, '%Y-%m-%d') <=? AND Date_Format(promo_end_date, '%Y-%m-%d') >=?) AND (promo_start_hour < ? AND promo_end_hour > ?)", current_day, current_day, current_time, current_time) return promoList end def self.combine_item(saleObj) # order_id = saleObj.sale_orders[0].order_id # itemList = OrderItem.where("order_id = ?", order_id).group(:item_instance_code).sum(:qty) itemList = [] saleObj.sale_orders.each do |so| itemList << OrderItem.where("order_id = ?",so.order_id).group(:item_instance_code).sum(:qty) end return itemList end def self.is_promo_day(promoList, day, orderitemList, sale_id) puts "Today date - " + day.to_s promoList.each do |promo| dayresult = promo.promo_day.include?(day.to_s) if dayresult orderitemList.each do |item| find_promo_item(promo, item, sale_id) end end end end def self.find_promo_item(promo, orderitem, sale_id) # item_code = OrderItem.find_by_item_instance_code(orderitem[0]).item_code orderitem.each do |odr_item| if promo.original_product.to_s == odr_item[0] if promo.min_qty.to_i > odr_item[1].to_i return false else check_promo_type(promo,odr_item, sale_id) end end end end def self.check_promo_type(promo, orderitem, sale_id) promo.promotion_products.each do |promo_product| if promo_product.item_code == orderitem[0] same = true else # return false, promo_product same = false end # same, promo_product = check_giveaway_product(promo, orderitem[0]) if promo.promo_type == Promotion::PROMO_TYPE1 if same give_promotion_same_product(orderitem[1], promo.min_qty, promo_product.min_qty, orderitem, sale_id,promo_product.item_code) else give_promotion_second_product(orderitem[1], promo.min_qty, promo_product.item_code, orderitem, sale_id) end elsif promo.promo_type == Promotion::PROMO_TYPE2 give_promotion_nett_off(same,promo_product,promo.min_qty, orderitem, sale_id) elsif promo.promo_type == Promotion::PROMO_TYPE3 give_promotion_nett_price(same,promo_product,promo.min_qty, orderitem, sale_id) elsif promo.promo_type == Promotion::PROMO_TYPE4 give_promotion_discount(same,promo_product,promo.min_qty, orderitem, sale_id) end end end def self.check_giveaway_product(promo, orderitem) # promo_pp = [] # flag = false # promo.promotion_products.each do |promo_product| # if promo_product.item_code == orderitem # # return true, promo_product # promo_pp.push(promo_product) # else # # return false, promo_product # end # end end def self.give_promotion_same_product(qty, promoqty, foc_min_qty, orderitem, sale_id,promo_product) puts " Order qty: " + qty.to_s + " / promoqty: " + promoqty.to_s + " / giveaway: " + foc_min_qty.to_s multiple = qty.to_i / promoqty.to_i # loop count charge_qty = 0 foc_qty = 0 if multiple > 0 multiple.times.each do |key| if qty > promoqty charge_qty += promoqty different = qty - promoqty qty = different if different == 0 foc_qty += foc_min_qty else foc_qty += foc_min_qty qty = qty - foc_min_qty end else charge_qty += qty end end if multiple == foc_qty charge_qty += qty end else charge_qty += qty end item = OrderItem.find_by_item_instance_code(orderitem[0]) if promo_product == OrderItem.find_by_item_instance_code(orderitem[0]).item_instance_code item = OrderItem.find_by_item_instance_code(orderitem[0]) else item = OrderItem.find_by_item_code(promo_product) end update_existing_item(foc_qty, item, sale_id, "promotion", item.price) puts "Charged - " + charge_qty.to_s puts "FOC - " + foc_qty.to_s end # AA - 10 # 3 # BB # orderList, #S34345 def self.give_promotion_second_product(orderitem_count, foc_min_qty, promo_product, orderitem, sale_id) puts "..... orderitem_count: " + orderitem_count.to_s + " / foc_min_qty: " + foc_min_qty.to_s + " /promo_product: " + promo_product + " orderitem: " + orderitem.to_s promotion_qty = orderitem_count.to_i / foc_min_qty.to_i # get foc item qty foc_qty = find_second_item_qty(sale_id, promo_product) if (foc_qty < promotion_qty) promotion_qty = foc_qty end item = OrderItem.find_by_item_instance_code(promo_product) update_existing_item(promotion_qty, item, sale_id, "promotion", item.price) end def self.update_existing_item(qty, item, sale_id, type, item_price) sale_item = SaleItem.new sale_item.product_code = item.item_code sale_item.product_name = item.item_name + "(promotion)" sale_item.product_alt_name = item.alt_name sale_item.account_id = item.account_id sale_item.remark = type sale_item.qty = qty * (-1) sale_item.unit_price = item_price # * (-1) sale_item.taxable_price = qty * item_price # * (-1) sale_item.price = qty * item_price * (-1) sale_item.is_taxable = 1 sale_item.sale_id = sale_id sale_item.save sale = Sale.find(sale_id) sale.compute_by_sale_items(sale.id, sale.sale_items, sale.total_discount) end def self.give_promotion_nett_off(same, promo_product, foc_min_qty, orderitem, sale_id) puts " same: " + same.to_s + " promo_product: " + promo_product.item_code.to_s + " foc_min_qty: " + foc_min_qty.to_s + " orderitem: " + orderitem.to_s if same foc_qty = orderitem[1].to_i / foc_min_qty item = OrderItem.find_by_item_instance_code(orderitem[0]) update_existing_item(foc_qty, item, sale_id, "promotion nett off", promo_product.net_off) else foc_qty = find_second_item_qty(sale_id, promo_product.item_code) item = OrderItem.find_by_item_instance_code(promo_product.item_code) update_existing_item(foc_qty, item, sale_id, "promotion nett off", promo_product.net_off) end end def self.give_promotion_nett_price(same, promo_product, foc_min_qty, orderitem, sale_id) puts " same: " + same.to_s + " promo_product: " + promo_product.item_code.to_s + " foc_min_qty: " + foc_min_qty.to_s + " orderitem: " + orderitem.to_s if same foc_qty = orderitem[1].to_i / foc_min_qty item = OrderItem.find_by_item_instance_code(orderitem[0]) # need to specify with menu item instance price = item.price.to_i - promo_product.net_price.to_i update_existing_item(foc_qty, item, sale_id, "promotion nett price", price) else foc_qty = find_second_item_qty(sale_id, promo_product.item_code) item = OrderItem.find_by_item_instance_code(promo_product.item_code) price = item.price - promo_product.net_price update_existing_item(foc_qty, item, sale_id, "promotion nett price", price) end end def self.give_promotion_discount(same, promo_product, foc_min_qty, orderitem, sale_id) puts " same: " + same.to_s + " promo_product: " + promo_product.item_code.to_s + " foc_min_qty: " + foc_min_qty.to_s + " orderitem: " + orderitem.to_s if same foc_qty = orderitem[1].to_i / foc_min_qty item = OrderItem.find_by_item_instance_code(orderitem[0]) # total = orderitem[1].to_i * item.price total = item.price price = calculate_discount(total, promo_product.percentage) update_existing_item(foc_qty, item, sale_id, "promotion discount", price) else foc_qty = find_second_item_qty(sale_id, promo_product.item_code) # give total qty is 1 #foc_qty = (foc_qty - foc_qty) + 1 item = OrderItem.find_by_item_instance_code(promo_product.item_code) # total = item.price * foc_qty total = item.price price = calculate_discount(total, promo_product.percentage) update_existing_item(foc_qty, item, sale_id, "promotion discount", price) end end def self.find_second_item_qty(sale_id, promo_item) saleObj = Sale.find_by_sale_id(sale_id) itemList = combine_item(saleObj) itemList.each do |item| item.each do |i| if i[0] == promo_item return i[1] end end end return 0 end def self.calculate_discount(total, discount) return (total.to_i * discount.to_i) / 100 end end