class CommLogistics::Base::Model::ReceivablePayable < CommLogistics::Base::Model::Superior
  include CommLogistics::Modules::ReceivableUtil
  
  self.abstract_class = true
  attr_accessor :target_key
  attr_accessor :acnt_target_id
  
  named_scope :all_search, lambda {|target_id, date, target_key| {
    :conditions => ["#{target_key}_id = ? AND cutoff_date = ?", target_id, date.to_s]
  }}
  
  named_scope :target_charge, lambda {|target_id, date| {
    :conditions => ["#{@target_key}_id = ? AND  cutoff_date >= ?", target_id, date.to_s],
    :order => 'cutoff_date DESC'
  }}
  
  named_scope :target_month_is, lambda {|date| {
    :conditions => ["DATE_FORMAT(cutoff_date, '%Y-%m') LIKE ?", date.strftime("%Y-%m")]
  }}
  
  def self.pre_search(target_id, date)
    result = find(:first,
                  :conditions => ["#{@target_key}_id = ? AND cutoff_date < ?", target_id, date],
                  :order => "cutoff_date DESC")
    return result
  end
  
  def self.next_search(target_id, date)
    result = find(:first,
                  :conditions => ["#{@target_key}_id = ? AND cutoff_date > ?", target_id, date],
                  :order => "cutoff_date ASC")
    return result
  end
  
  def init(params, target_key)
    eval("self.#{target_key}_id = #{params[:target_id]}")
    eval("self.#{target_key}_group_id = #{params[:target_group_id].blank? ? 'nil' : params[:target_group_id]}")
    self.cutoff_date        = params[:cutoff_date] #make_paramsメソッド内で、@cutoff_dateからparams[:cutoff_date]にコピーされている。
    self.total_price        = 0
    self.total_duty         = 0
    self.total_payment      = 0
    self.total_carry        = 0
    self.total_carry_duty   = 0
    self.trade_sheet_cnt    = 0
    pre = self.class.pre_search(params[:target_id], params[:cutoff_date])
    if pre
      self.pre_total = pre.total
      self.total     = pre.total
    else
      self.pre_total = 0
      self.total     = 0
    end
  end 
  
  def update_total
    self.total = self.pre_total + self.total_price + self.total_duty - self.total_payment + self.total_carry + self.total_carry_duty
  end
  
  def this_total
    return self.total_price + self.total_duty + self.total_carry + self.total_carry_duty
  end
  
  def this_total_without_duty
    return self.total_price + self.total_carry
  end
  
  def add_total(acnt_type, calc_type, ar, req_total_duty_calc_weight)
    # total値の加算/減算
    sign = (calc_type == CALC_ADD) ? 1 : -1
    case acnt_type
    when MCODE_DEAL_TYPE_DEAL
      self.total_price   += ar.total_price * sign
      # 税計算が請求合計の場合は上書きする
      if req_total_duty_calc_weight
        #self.total_duty = self.total_price * req_total_duty_calc_weight
        self.total_duty = CommLogistics::Tools::CalcDuty.calc_decimal_duty(self.total_price, req_total_duty_calc_weight)
        logger.debug("rp req duty :"+self.total_duty.to_s)
      else
        self.total_duty += ar.total_duty * sign
        logger.debug("rp normal duty :"+self.total_duty.to_s)
      end
      result = update_info
    when MCODE_DEAL_TYPE_PAYMENT
      self.total_payment += ar.total_amount * sign
    when MCODE_DEAL_TYPE_CARRY
      self.total_carry += ar.total_carry * sign
      self.total_carry_duty += ar.total_carry_duty * sign
      logger.debug("carry normal total_carry_duty :"+self.total_carry_duty.to_s)
      result = update_info
    end
    update_total
    
    # 次のレコードのtotalを繰り越す
    result = update_next_record
    
    return result
  end

  def update_next_record
    result = true
    nxt = eval("self.class.next_search(#{@target_key}_id, cutoff_date)")
    if nxt
      nxt.pre_total = total
      nxt.update_total
      nxt.target_key = @target_key
      ret = nxt.save
      if ret
        nxt.update_next_record
      else
       result = false
      end
    end
    
    return result
  end
  
  def update_records(payment_class, group_id, need_encachement=true)
    require 'config/site_config'
    #payments = payment_class.group_is(group_id) #customer_group_payments/supplier_group_paymentsはクビにしたので。
    payments = payment_class.get_payments(@acnt_target_id)
    unless self.cutoff_date.blank?
      $PAYMENTS_BY_GROUP ||= false
      if $PAYMENTS_BY_GROUP && !group_id.blank? #グループの合計金額を条件とするかどうか
        total = self.class.group_total(group_id, self.cutoff_date, @acnt_target_id) + self.this_total
        total_without_duty = self.class.group_total_without_duty(group_id, self.cutoff_date, @acnt_target_id) + self.this_total_without_duty
      else
        total = self.this_total
        total_without_duty = self.this_total_without_duty
      end
      
      logger.debug("update_records payments:"+payments.inspect)
      logger.debug("update_records group_total:"+total.inspect)
      logger.debug("update_records group_total_without_duty:"+total_without_duty.inspect)
      logger.debug("update_records this total:"+self.this_total.inspect)
      logger.debug("update_records this total without duty:"+self.this_total_without_duty.inspect)
      logger.debug("update_records @acnt_target_id:"+@acnt_target_id.inspect)
      #payment = get_match_payment(payments, group_total+self.this_total)
      if payments.blank?
        payment = {}
      else
        payment = get_match_payment(payments, total, total_without_duty)
      end
      #支払方法が設定されていない場合も考慮する
      if payment.blank?
        payment[:payment_type_code] = nil
        payment_date = nil
        encachement_date = nil if need_encachement
      else
        payment_date, encachement_date = get_receivable_dates(payment, self.cutoff_date, need_encachement)
      end
      
      # payment_type_code, payment_date, encachement_date
      self.payment_type_code = payment[:payment_type_code]
      self.payment_date = payment_date
      self.encachement_date = encachement_date if need_encachement
      # update same group
      if $PAYMENTS_BY_GROUP && !group_id.blank?
        members = self.class.group_members(group_id, self.cutoff_date)
        if members
          members.delete(self)
          members.each do |mb|
            mb.payment_type_code = payment[:payment_type_code]
            mb.payment_date = payment_date
            mb.encachement_date = encachement_date if need_encachement
            mb.save
          end
        end
      end
    end
    return true
  end
end
