#
#= 表示名一覧取得 コントローラー
# Authors:: Sumiyo Yamamoto
# Copyright:: Copyright (C) OrbusNeich Medical K.K.  2010.
#--
# date        name                   note
# 2010.10.29  Sumiyo Yamamoto        新規作成
#-------------------------------------------------------------------------------
#++
class DispNamesController < Comm::BaseController::DispName
  include CommLogistics::Const::Code
  include Comm::Const::MasterCode
  include CommLogistics::Modules::StockSearch
  #include Comm::Const::DispNameLists

protected
  #== データ取得
  #-----------------------------------------------------------------#++
  def get_disp_names
    super
    case params[:mode]
    when 'product'
      product_search
    when 'price_product'
      price_product_search
    when 'product_custom'
      product_custom_search
    when 'lot_number'
      @disp_names = stock_search('lot_number', params)
      # serial_numberによって分割しているレコードのマージ
      if params[:no_merge]!=STR_TRUE
        tmp = []
        dist_keys = [
          'warehouse_id',
          'customer_id',
          'supplier_id',
          'product_id',
          'lot_number',
          'location_number',
          'ubd',
          'stock_type_code'
        ]
        @disp_names.each do |r|
          idx = tmp.search_val(r, dist_keys)
          if idx
            tmp[idx]['existing_quantity']  += r['existing_quantity']
            tmp[idx]['available_quantity'] += r['available_quantity']
          else
            tmp.push(r)
          end
        end
        @disp_names = tmp
      end
    when 'serial_number'
      @disp_names = stock_search('serial_number', params)
    when 'customer'
      customer_search
    when 'supplier'
      supplier_search
    when 'receivings_charge'
      charge_search(Receivable)
    when 'payings_charge'
      charge_search(Payable)
    when 'customer_warehouse'
      customer_warehouse_search
    when 'inventory_date'
      inventory_date_search
    end
    return
  end
  #特殊な製品型番一覧のモード
  def product_custom_search
    @disp_names = Product.find_by_sql(["select
                                          p.id,
                                          p.invalid_flag_code AS ivf,
                                          p.disp_name,
                                          p.product_set_id,
                                          p.product_name
                                        from master_app_production.products as p where p.invalid_flag_code=? ", MCODE_FLAG_OFF]).only_hashfy;
    return
  end
  #== データ取得：製品(→未使用)
  #-----------------------------------------------------------------#++
  def product_search
    require 'config/site_config'
    one_month = $MONTH_VALIDITY_PERIOD ? ' 30 * ' : ''
    #RESERVE(予備)は含めない。
    w_ids = Warehouse.set(MFIND_V).asign('own_flag_code', Comm::Const::MasterCode::MCODE_OWN_ON).all.extract('id')
    #w_ids = Warehouse.own_ids
    if params[:product_set_id].blank?
      p_ids = ProductSet.set(MFIND_V).all.extract('id')
    else
      p_ids = [params[:product_set_id]]
    end
  
    unless w_ids.blank?
      if params[:own_supplier_flag]==STR_TRUE 
        supplier_consition = ''
      else
        if params[:supplier_ids].blank?
          return []
        end
        supplier_condition = " AND (p.supplier_id IN (#{params[:supplier_ids]}) OR p.supplier_id IS NULL)" 
      end
      
      if params[:only_existing_product]==STR_TRUE
        only_existing_product_condition = " AND IFNULL(s.stock_quantity,0) > 0 "
      end
      if $PRODUCT_NO_FILTER_BY_SUPPLIER || params[:supplier_id].blank?
        supplier_filter = ""
      else
        supplier_filter = " AND s.supplier_id=#{params[:supplier_id]} "
      end
      
      @disp_names = Stock.find_by_sql(["select 
                                          p.id, 
                                          p.unit_code, 
                                          p.invalid_flag_code AS ivf, 
                                          p.product_name, 
                                          p.product_set_id, 
                                          p.disp_name, 
                                          IFNULL(s.stock_quantity,0)-IFNULL(ss.shipping_quantity,0) as quantity,
                                          IFNULL(s.short_stock_quantity,0)-IFNULL(ss.short_shipping_quantity,0) as short_quantity 
                                  from master_app_production.products as p  
                                  left join ( 
                                      select product_id,
                                             sum(existing_quantity) as stock_quantity,
                                             sum(IF(ubd < ADDDATE('#{params[:target_date]}', INTERVAL #{one_month} p.shipment_validity_period DAY) , existing_quantity, 0 )) AS short_stock_quantity
                                          from stocks as s
                                          left join master_app_production.products as p ON s.product_id=p.id
                                          where s.product_set_id IN (?) #{supplier_filter} AND s.warehouse_id IN (?) AND s.existing_quantity > 0 group by s.product_id
                                  ) as s on p.id=s.product_id 
                                  left join (
                                      select 
                                        product_id, 
                                        sum(sd.quantity) as shipping_quantity,
                                        sum(IF(sd.ubd < ADDDATE('#{params[:target_date]}', INTERVAL #{one_month} p.shipment_validity_period DAY) , sd.quantity, 0 )) AS short_shipping_quantity 
                                      from shippings as s 
                                          right join shipping_details as sd on s.id=sd.shipping_id 
                                          left join master_app_production.products as p on sd.product_id=p.id
                                          where s.invalid_flag_code=? and shipping_state_code NOT IN (?) and sd.product_set_id IN (?) AND own_warehouse_id IN (?) group by sd.product_id
                                  ) as ss on p.id=ss.product_id where product_set_id IN (?) #{supplier_condition} #{only_existing_product_condition}",
                             p_ids, w_ids, MCODE_FLAG_OFF, [ MCODE_SHIPPING_STATE_WAIT, MCODE_SHIPPING_STATE_COMP, MCODE_SHIPPING_STATE_BO], p_ids, w_ids, p_ids]).only_hashfy
    end
    return
  end
  #== データ取得：製品（価格設定用）(→未使用)
  #-----------------------------------------------------------------#++
#  def price_product_search
#    id = params[:id]
#    if !(id.blank?) && (ProductSet.find(id).price_unique_code == MCODE_PRICE_UNIQUE_PRODUCT)
#      product_search
#    else
#      add_list(LIST_ALL)
#    end
#    return
#  end

  #== データ取得：得意先(→未使用)
  #-----------------------------------------------------------------#++
#  def customer_search
#    warehouses = Warehouse.dlist(@req_cols).all.only_hashfy
#    rels = WarehousesCustomer.selekt(['warehouse_id', 'customer_id']).all.only_hashfy
#    @disp_names = Customer.dlist(@req_cols).all.only_hashfy
#    @disp_names.each do |r|
#      ids = (rels.select{|x| x['customer_id'] == r['id'] }).extract('warehouse_id')
#      tmps = []
#      ids.each do |id|
#        ret = warehouses.get_by_search_val(id, 'id')
#        if ret
#          tmps.push(ret)
#        end
#      end
#      r['warehouses'] = tmps
#    end
#    return
#  end

  #== データ取得：仕入先
  #-----------------------------------------------------------------#++
#  def supplier_search
#    warehouse_id = params[:warehouse_id]
#    if warehouse_id.blank?
#      @col_name = 'supplier_id'
#      normal_search
#    else
#      # 仕入先ID取得
#      ids = InvoicePrice.selekt('supplier_id').sassign('warehouse_id', warehouse_id).sassign('customer_id', params[:customer_id]).product_is(params[:product_set_id], params[:product_id]).all.extract('supplier_id')
#      
#      # 自社追加
#      if params[:include_own]=='show' || params[:include_own]=='search'
#        ids.push(OWN_SUPPLIER_ID)
#      end
#      # 仕入先disp_name取得
#      @disp_names = Supplier.dlist(@req_cols).passign('id', ids).all.only_hashfy if ids.length > 0
#      # 自社倉庫の在庫情報を添付する。
#      if params[:include_own]=='search' && @disp_names.length > 0
#        w_ids = Warehouse.dlist.asign('own_flag_code', Comm::Const::MasterCode::MCODE_OWN_ON).all.extract('id')
#        ar = Stock.own.has_quantity.passign('warehouse_id', w_ids).sassign('product_id', params[:product_id]).all.only_hashfy if w_ids.length > 0
#        @disp_names.each do |r|
#          r['stock']=ar if r['id']==OWN_SUPPLIER_ID
#        end
#      end
#      
#    end
#    
#    return
#  end

  #== データ取得：売掛・買掛
  #-----------------------------------------------------------------#++
  def charge_search(cls = nil)
    unless params[:id].blank?
      cols = ['id', 'cutoff_date', 'total', 'total_price', 'total_duty', 'total_carry', 'total_carry_duty', 'payment_date']
      cols.push(params[:trade_with]);
      period = Date.today.years_ago(2)
      @disp_names = cls.selekt(cols).target_charge(params[:id], period).all.only_hashfy
      
      # 対象フラグ設定
      @disp_names.each do |r|
        r['target'] = false
      end
      #一番入金処理日に近い支払日を選択する。差が等しい場合は古い方を選択
      if params[:trans_date]
        trans_arr = Date.parse(params[:trans_date])
        date_diff = 1000 #2年前からの売掛が対象なので、日数的には最大で730日になるはず、余裕を見て1000とする。
        target_index = nil
        @disp_names.each_with_index do |r, i|
          unless r['payment_date'].blank?
            tmp_diff = (r['payment_date'] - trans_arr).to_i.abs
            if tmp_diff <= date_diff
              target_index = i
              date_diff = tmp_diff
            end
          end
        end
        @disp_names[target_index]['target']=true unless target_index.blank?
      end
    end
    return
  end
  #==特定の得意先に紐付けされている納品先のみを抽出
  def customer_warehouse_search
    #, :conditions => [" own_flag_code IN (?) OR id IN (#{wids.join(',')})", [Comm::Const::MasterCode::MCODE_OWN_ON, Comm::Const::MasterCode::MCODE_OWN_RESERVE] ]
    cids = CustomersUser.vcustomers(session[:user_id])
    unless cids.blank?
      wids = WarehousesCustomer.find(:all, :select => "warehouse_id", :group => 'warehouse_id', :conditions => [" customer_id IN (#{cids.join(',')}) "]).map {|r| r.warehouse_id }
      unless wids.blank?
        select = (['id', 'disp_name', "(invalid_flag_code OR IF( ( own_flag_code IN (#{Comm::Const::MasterCode::MCODE_OWN_ON},#{Comm::Const::MasterCode::MCODE_OWN_RESERVE}) OR id IN (#{wids.join(',')})) , #{MCODE_FLAG_OFF},#{MCODE_FLAG_ON})) as ivf"] + @req_cols).join(',')
        @disp_names = Warehouse.find(:all, :select => select, :order => 'disp_sort').only_hashfy
        return 
      end
    end
    select = (['id', 'disp_name', "(invalid_flag_code OR IF( ( own_flag_code IN (#{Comm::Const::MasterCode::MCODE_OWN_ON},#{Comm::Const::MasterCode::MCODE_OWN_RESERVE}) ) , #{MCODE_FLAG_OFF},#{MCODE_FLAG_ON})) as ivf"] + @req_cols).join(',')
    @disp_names = Warehouse.find(:all, :select => select, :order => 'disp_sort').only_hashfy
    return
  end
  #== 棚卸原票
  def inventory_date_search
     dates = Inventory.inventory_dates
     @disp_names = []
     dates.each_with_index{|date,idx| @disp_names << {'id'=>idx, 'disp_name'=>date.to_s}}
     return
  end
end
