
#Description
#total_revenue = sum of all sub-total from sales table
#total_discounts = sum of all discount (overall) from sales tables
#total_taxes = sum of all taxes from sales table (Service + Goverment Tax (commercial_taxes))
#grand_total = total_revenue - total_discounts + total_taxes
#nett_sales = grand_total - commercial_taxes
#cash_sales = cash payment total revenue
#credit_sales = credit payment total revenue
#others_sales = [Sum of each of other payment type --- mpu, jcb, visa,master, rebate, vochure]
#commercial_taxes = Total Goverment tax due
#cash_in = Payment receive
#Cash_out = Payment issues for misc payments

class ShiftSale < ApplicationRecord
  belongs_to :cashier_terminal
  belongs_to :employee, :foreign_key => 'employee_id'

  def self.current_shift
    # today_date = DateTime.now.strftime("%Y-%m-%d")
    shift = ShiftSale.where("shift_started_at is not null and shift_closed_at is null").first
    return shift
  end

  def self.current_open_shift(current_user)
    #if current_user
      #find open shift where is open today and is not closed and login by current cashier
      #DATE(shift_started_at)=? and 
      today_date = DateTime.now.strftime("%Y-%m-%d")
      shift = ShiftSale.where("shift_started_at is not null and shift_closed_at is null and employee_id = #{current_user}").take
      return shift
    #end
  end

  def self.sync_shift_sale_records(shift_sales)
    if !shift_sales.nil?
      shift_sales.each do |ss|
        # status = nil
        shift_sale = nil

        # if ShiftSale.exists?(ss['id'])
        shift_sale = ShiftSale.find_by_id(ss['id'])
          # status = 'updated'
        if shift_sale.nil?
          shift_sale = ShiftSale.new
          # status = 'created'     
        end

        shift_sale.id = ss['id']
        shift_sale.cashier_terminal_id = ss['cashier_terminal_id']
        shift_sale.shift_started_at = ss['shift_started_at']
        shift_sale.shift_closed_at = ss['shift_closed_at']
        shift_sale.employee_id = ss['employee_id']
        shift_sale.opening_balance = ss['opening_balance']
        shift_sale.closing_balance = ss['closing_balance']
        shift_sale.total_revenue = ss['total_revenue']
        shift_sale.total_discounts = ss['total_discounts']
        shift_sale.total_taxes = ss['total_taxes']
        shift_sale.grand_total = ss['grand_total']
        shift_sale.nett_sales = ss['nett_sales']
        shift_sale.cash_sales = ss['cash_sales']
        shift_sale.credit_sales = ss['credit_sales']
        shift_sale.other_sales = ss['other_sales']
        shift_sale.commercial_taxes = ss['commercial_taxes']
        shift_sale.cash_in = ss['cash_in']
        shift_sale.cash_out = ss['cash_out']
        shift_sale.dining_count = ss['dining_count']
        shift_sale.takeaway_count = ss['takeaway_count']
        shift_sale.member_count = ss['member_count']
        shift_sale.total_rounding = ss['total_rounding']
        shift_sale.total_receipt = ss['total_receipt']
        shift_sale.total_void = ss['total_void']
        shift_sale.save

      end
      Rails.logger.debug "....... Shift Sale sync completed ......"
    end
  end

  def create(opening_balance,cashier_terminal, current_user)
    self.cashier_terminal_id = cashier_terminal
    self.shift_started_at = DateTime.now
    self.employee_id = current_user.id
    self.opening_balance = opening_balance
    self.other_sales = 0
    self.save
  end

  def update(sale)
    saleobj = Sale.find_by_sale_id(sale)
    cash = saleobj.get_cash_amount
    credit = saleobj.get_credit_amount
    other_sales = saleobj.get_other_amount
    tax = saleobj.get_commerical_tax
    self.total_revenue = self.total_revenue.to_f + saleobj.total_amount.to_f
    self.total_discounts = self.total_discounts + saleobj.total_discount
    self.total_taxes = self.total_taxes + saleobj.total_tax
    self.grand_total = self.grand_total + saleobj.grand_total
    self.cash_sales = self.cash_sales.to_f + cash.to_f
    self.credit_sales = self.credit_sales.to_f + credit.to_f
    self.other_sales = self.other_sales.to_f + other_sales.to_f
    self.nett_sales = self.nett_sales + (saleobj.total_amount.to_f - saleobj.total_discount)  #self.grand_total.to_f -  self.commercial_taxes
    self.commercial_taxes = self.commercial_taxes.to_f + tax.to_f
    self.total_rounding = self.total_rounding + saleobj.rounding_adjustment
    self.total_receipt = self.total_receipt + 1
    if saleobj.customer.customer_type == "Dinein"
      self.dining_count = self.dining_count + 1
    else
      self.takeaway_count = self.takeaway_count + 1
    end
    self.save
  end

  # Calculate by type and update
  def calculate(sale, type)
    saleobj = Sale.find_by_sale_id(sale)
    cash = saleobj.get_cash_amount
    credit = saleobj.get_credit_amount
    other_sales = saleobj.get_other_amount
    tax = saleobj.get_commerical_tax
    
    if type == "void"
      self.total_revenue = self.total_revenue.to_f - saleobj.total_amount.to_f
      self.total_discounts = self.total_discounts - saleobj.total_discount
      self.total_taxes = self.total_taxes - saleobj.total_tax
      self.grand_total = self.grand_total - saleobj.grand_total
      self.cash_sales = self.cash_sales.to_f - cash.to_f
      self.credit_sales = self.credit_sales.to_f - credit.to_f
      self.other_sales = self.other_sales.to_f - other_sales.to_f
      self.nett_sales = self.nett_sales - (saleobj.total_amount.to_f - saleobj.total_discount)  #self.grand_total.to_i -  self.commercial_taxes
      self.commercial_taxes = self.commercial_taxes.to_f - tax.to_f
      self.total_rounding = self.total_rounding - saleobj.rounding_adjustment
      self.total_void = self.total_void + saleobj.grand_total
      if saleobj.customer.customer_type == "Dinein"
        self.dining_count = self.dining_count - 1
      else
        self.takeaway_count = self.takeaway_count - 1
      end

     
      self.save
    end
  end

  def get_closing_balance(shift)
     shiftobj = ShiftSale.find(shift)
     closing_balance = shiftobj.grand_total + shiftobj.cash_in - shiftobj.cash_out + shiftobj.total_cash
     return closing_balance
  end

  def self.get_by_shift_other_payment(shift)
        
    other_payment = Sale.select("sale_payments.payment_method as name,
                        SUM(case when (sale_payments.payment_method='mpu') then (sale_payments.payment_amount) else 0 end) as mpu_amount, 
                        SUM(case when (sale_payments.payment_method='visa') then (sale_payments.payment_amount) else 0 end) as visa_amount, 
                        SUM(case when (sale_payments.payment_method='master') then (sale_payments.payment_amount) else 0 end) as master_amount, 
                        SUM(case when (sale_payments.payment_method='jcb') then (sale_payments.payment_amount) else 0 end) as jcb_amount,
                        SUM(case when (sale_payments.payment_method='unionpay') then (sale_payments.payment_amount) else 0 end) as unionpay_amount,
                        SUM(case when (sale_payments.payment_method='alipay') then (sale_payments.payment_amount) else 0 end) as alipay_amount,
                        SUM(case when (sale_payments.payment_method='KBZPay') then (sale_payments.payment_amount) else 0 end) as kbzpay_amount,
                        SUM(case when (sale_payments.payment_method='dinga') then (sale_payments.payment_amount) else 0 end) as dinga_amount,
                        SUM(case when (sale_payments.payment_method='giftvoucher') then (sale_payments.payment_amount) else 0 end) as giftvoucher_amount,
                        SUM(case when (sale_payments.payment_method='JunctionPay') then (sale_payments.payment_amount) else 0 end) as junctionpay_amount,
                        SUM(case when (sale_payments.payment_method='foc') then (sale_payments.payment_amount) else 0 end) as foc_amount, 
                        SUM(case when (sale_payments.payment_method='paymal') then (sale_payments.payment_amount) else 0 end) as paymal_amount, 
                        SUM(case when (sale_payments.payment_method='paypar') then (sale_payments.payment_amount) else 0 end) as paypar_amount")
                .joins("join sale_payments on sale_payments.sale_id = sales.sale_id")
                .where("sales.shift_sale_id =? and sale_status = 'completed' and sale_payments.payment_amount != 0 ", shift.id)
  end

  def self.calculate_total_price_by_accounts(shift,type)
      query = Sale.select("acc.title as account_name," + 
                          "SUM(case when (acc.id=i.account_id) then (i.price) else 0 end) as total_price")
      
      query = query.joins("JOIN sale_items i ON i.sale_id = sales.sale_id "+
                          "JOIN accounts acc ON acc.id = i.account_id" + 
                          " JOIN shift_sales sh ON sh.`id` = sales.shift_sale_id")
      if type == 'discount'
        query = query.where("sales.shift_sale_id =? and sale_status = 'completed' and i.remark = 'Discount'", shift.id)
                .group("acc.title").order("acc.id")
      else
        query = query.where("sales.shift_sale_id =? and sale_status = 'completed'", shift.id)
                .group("acc.title").order("acc.id")
      end
  end

  def self.get_total_member_discount(shift)
      query = Sale.select("SUM(sales.total_discount) as member_discount")
              .where("shift_sale_id =? and sale_status = 'completed' and discount_type = 'member_discount'", shift.id)
     
  end  

  def self.get_total_dinein(shift) 
      query = Sale.select("sum(sales.grand_total) as total_dinein_amount")
          .joins("JOIN customers as c ON c.customer_id = sales.customer_id")
          .where('shift_sale_id =? and sales.sale_status = "completed" and c.customer_type = "Dinein" and c.membership_id is null',shift.id)
          .first()
  end  

  def self.get_total_takeway(shift) 
      query = Sale.select("sum(sales.grand_total) as total_takeway_amount")
          .joins("JOIN customers as c ON c.customer_id = sales.customer_id")
          .where('shift_sale_id =? and sales.sale_status = "completed" and c.customer_type = "Takeaway" and c.membership_id is null',shift.id)
          .first()
  end

  # def self.get_total_other_charges_for_sale_item_report(from, to)
  #   query = SaleItem.select("sum(sale_items.qty * sale_items.unit_price) as total_other_charges_amount")
  #                   .joins("JOIN sales as s ON s.sale_id = sale_items.sale_id")
  #                   .joins("JOIN shift_sales ss ON ss.id = s.shift_sale_id")
  #                   .where('s.sale_status = "completed" and sale_items.product_code = "Other Charges" and sale_items.item_instance_code is null and s.receipt_date between ? and ?',from, to)
  # end

  def self.get_total_other_charges(shift) 
      query = SaleItem.select("sum(sale_items.qty * sale_items.unit_price) as total_other_charges_amount")
          .joins("JOIN sales as s ON s.sale_id = sale_items.sale_id")
          .where('shift_sale_id =? and s.sale_status = "completed" and sale_items.product_code = "Other Charges" and sale_items.item_instance_code is null',shift.id)
          .first()
  end 

  def self.search(filter,from,to)
    if filter.blank?
        keyword = ''
    else
        keyword = "booking_id LIKE ? OR checkin_by LIKE ? OR booking_status LIKE? OR checkout_by LIKE? OR sale_id ='#{filter}'","%#{filter}%","%#{filter}%","%#{filter}%","%#{filter}%"
    end

    if from.present? && to.present?
       booking = ShiftSale.where("DATE_FORMAT(created_at,'%d-%m-%Y') >= ?" + " AND DATE_FORMAT(created_at,'%d-%m-%Y') <= ? and NOT booking_status = 'void' ", from,to)
       query = booking.where(keyword)
    else
        where("booking_id LIKE ? OR checkin_by LIKE ? OR booking_status LIKE? OR checkout_by LIKE? OR sale_id ='#{filter}'","%#{filter}%","%#{filter}%","%#{filter}%","%#{filter}%")
    end

  end

  def self.get_shift_sales_with_credit_payment(shift_id)
    query = SalePayment.select("(CASE WHEN (SUM(sale_payments.payment_amount) + SUM(sale_payments.outstanding_amount)) > 0 THEN (SUM(sale_payments.payment_amount) + SUM(sale_payments.outstanding_amount)) ELSE 0 END) as total_credit_payments")
            .joins(" JOIN sale_audits sa ON SUBSTRING_INDEX(sa.remark,'||',1)=sale_payments.sale_payment_id")
            .where("SUBSTRING_INDEX(SUBSTRING_INDEX(sa.remark,'||',-1),' -> ',1) = #{shift_id}")
            .first()
  end

end
