class ManufacturesController < CommLogistics::Base::Controller::SuperiorOrder
  include Comm::Module::Controller::Logging
  include CommLogistics::Modules::Print::Controller
  include CommLogistics::Modules::Controller::ShowFilter
  include CommLogistics::Modules::Controller::ExtIndexFilter
  
  
  def initialize
    @mcls = Manufacture
    @pdf_cls = ManufacturePdfOut
  end
  
  def find_all_with_progress(flag)
    params[:session_user_id] = session[:user_id]
    ss = ManufactureSearch.new
    ss.table_alias = {'manufactures' => 't'}
    return ss.search(flag, Manufacture, [], params)
  end
  
  #mpdを追加するためにオーバーライド
  def ar_to_hr(ars)
    hrs = ars.ext_hashfy({:disp=>{:nil_str=>@disp_name_nil_str, :multiple_id_cols => @multiple_id_cols}})
    hrs.each do |hr|
      hr['manufacture_product_details'] = ManufactureProductDetail.child(hr['id']).find(:all, :select => "id, product_set_id, product_id, lot_number, serial_number, ubd, price, quantity").only_hashfy
    end
  end
  
  class ManufactureSearch < Comm::Tool::SqlSearch
    def get_columns_and_tables(tab, join_lists, params, str_vals)
      
      invalid_vals = (!params || params[:with_invalid]==STR_TRUE) ? '0,1' : '0'
      
      str_cols = ' * '
      str_tab =  " FROM (SELECT 
                           a.*,
                             IF(a.rels_total_quantity=0,
                                   a.rels_comp_total_quantity,
                                   100 * IFNULL(a.rels_comp_total_quantity, 0) / a.rels_total_quantity
                             ) AS progress
                         FROM manufactures AS a 
                         WHERE a.target_date BETWEEN \"#{params[:start_target_date]}\" AND \"#{params[:end_target_date]}\"
                           AND a.invalid_flag_code IN (#{invalid_vals})
                   ) AS t "
      return str_cols, str_tab, str_vals
    end
    #から実装
    def set_target_date_to_where(tab, params, str_where)
    end
  end
  
  # linkage 下記をかえす
  #  table_name : "orders", "purchases"など関連取引テーブルのテーブル名
  #  id : 関連取引テーブルのid。受注から発注を作ったなら、発注データのID
  #  state_code : 関連テーブルの状態のコード値
  #  invalid_flag_code : 無効フラグ
  #  sign_type_code : 赤黒（あれば）
  #  target_date : 関連取引データの処理日
  #  input_date : 関連取引データの入力日
  #  created_at : 関連取引データの作成日時
  #  updated_at : 関連取引データの更新日時
  #
  #関連進捗率の100％となる本数を計算
  def linkage
    rels = Manufacture.get_all_rels(params[:id])
    result = []
    
    rels.each do |rel|
      link = {'table_name' => rel.table_name, 'progress' => 0}
      if rel.record_id.to_i > 0
        class_name = rel.table_name.classify
        record = eval("#{class_name}.find(#{rel.record_id})").only_hashfy
        ['id', 
         'state_code',
         'invalid_flag_code',
         'sign_type_code',
         'target_date',
         'input_date',
         'created_at',
         'updated_at'].each do |val|
           link[val] = record[val] if record.include?(val)
        end
        #sale_type_codeとかshipping_type_codeとか
        link['trans_type_code'] = record[rel.table_name.singularize + '_type_code'] if record.include?(rel.table_name.singularize + '_type_code');
        #自身のテーブル名がsale_id, purchase_idとか赤黒伝票が有る取引処理この値が0より大きかったら赤黒伝票とわかる
        link['parent_id'] = record[rel.table_name.singularize + '_id'] if record.include?(rel.table_name.singularize + '_id');
        #組み立てでなおかつMCODE_PURCHASE_TYPE_PROCESS_UNLOAD
        if (rel.parent_trans_type_code.to_i==MCODE_MANUFACTURE_TYPE_COMPOSE && link['trans_type_code']==MCODE_PURCHASE_TYPE_PROCESS_UNLOAD) || 
           (rel.parent_trans_type_code.to_i==MCODE_MANUFACTURE_TYPE_DECOMPOSE && link['trans_type_code']==MCODE_PURCHASE_TYPE_DECOMPOSE_LOAD)
          process_total = rel.manufacture_product_total_quantity.to_f 
        else
          process_total = rel.stock_total_quantity.to_f 
        end
        # 各テーブルで固有の正規化
        eval("#{class_name}.linkage_standerdize(record, link)")
        if link['invalid_flag_code']==MCODE_FLAG_OFF
          link['total_quantity']=record['total_quantity']
          if link['state_code']==MCODE_STATUS2_COMP
            if process_total == 0
              link['progress'] = record['total_quantity']==0 ? 100 : 50
            else
              sign = (link['trans_type_code']==MCODE_PURCHASE_TYPE_PROCESS_UNLOAD || link['trans_type_code']==MCODE_PURCHASE_TYPE_DECOMPOSE_UNLOAD) ? -1: 1
              link['progress'] = ((record['total_quantity'].to_f * sign / process_total ) * 100).round()
            end
            link['comp_quantity']=record['total_quantity']
          end
        end
      end
      result << link
    end
    respond_to do |format|
      format.ext_json do
        render :json => result.to_ext_json('linkages', nil)
      end
    end
  end

  class ManufacturePdfOut < PdfBase
    require 'date'
    SHEET_TYPE_GENERAL = 1
    SHEET_TYPE_GENERAL_WITH_TOTAL = 2
    SHEET_TYPE_OMKK = 3
    
    def initialize(params, mcls=nil)
      @print_rec_num_per_sheet = 36
      @params = params
      super
    end
    
    #PDF生成
    def set_details_to_pages(ar, pdata, details, detail_name, page)
      sar = Supplier.find(ar.supplier_id)
      sheet_type = sar.order_sheet_type_code
      @currency_type = sar.currency_type_code
      
      case sheet_type.to_i
      when SHEET_TYPE_OMKK
        page = set_details_to_pages_omkk(ar, pdata, details, detail_name, page, sheet_type)
      when SHEET_TYPE_GENERAL
        page = set_details_to_pages_general(ar, pdata, details, detail_name, page, sheet_type)
      when SHEET_TYPE_GENERAL_WITH_TOTAL
        page = set_details_to_pages_general(ar, pdata, details, detail_name, page, sheet_type)
      else
        page = set_details_to_pages_general(ar, pdata, details, detail_name, page, sheet_type)
      end
      return page
    end
    
    # 標準テンプレート
    def set_details_to_pages_general(ar, pdata, details, detail_name, page, sheet_type=SHEET_TYPE_GENERAL)
      @print_rec_num_per_sheet = 10
      @print_rec_num_index = @print_rec_num_per_sheet - 1
      # ヘッダ情報
      tmp_main = ar.only_hashfy
      tmp_main['grand_total_price'] = ar.total_price.to_i + ar.total_duty.to_i
      main_hash = add_disp_name_to_hash(tmp_main)
      #請求書合計や消費税無しの場合は、消してくれといわれたので。
      if ar.duty_calc_type_code.to_i==MCODE_CALC_DUTY_REQ_TOTAL || ar.duty_calc_type_code.to_i==MCODE_CALC_DUTY_NON
        main_hash.update({'total_duty' => '-', 'grand_total_price'=> '-'})
      end
      main_hash.update({:page_info => {:sheet_type => sheet_type}})
      main_hash.update(get_send_info(ar).dup)
      main_hash.update(get_own_info(ar).dup)
      main_hash.update(add_disp_name_to_hash(make_sheet_add_for_main(ar)))
      
      seq, page_sum, accumulate_pages = 0, 0, 0
      page_org = page
      details.each do |d|
        pdata[page] ||= main_hash.dup
        pdata[page][detail_name] ||= {}
        detail_hash = d.only_hashfy
        pd = Product.find(d.product_id) #JANコードを取ってくる。
        detail_hash['jan'] = pd.jan
        tmp_total_price = d.price ? d.price * d.quantity : 0
        detail_hash['row_total_price'] = CommLogistics::Tools::CalcDuty.calc_decimal(tmp_total_price, {:duty_rate=>0, :fraction_method_code=>ar.price_fraction_method_code.to_i,:frac_digit_code=>1})
        pdata[page][detail_name][seq] = add_disp_name_to_hash(detail_hash)
        #page_sum += d['quantity']
        if seq == @print_rec_num_index
          #子レコード数で改ページ
          pdata[page]['page_num'] = page - page_org + 1
          #pdata[page]['page_sum'] = page_sum
          #accumulate_pages += page_sum
          #pdata[page]['accumulate_pages'] = accumulate_pages
          #枝番付きIDの準備
          pdata[page]['disp_id'] = pdata[page]['id'].to_s
          page_sum = 0
          seq = 0
          page += 1
        else
          seq += 1
        end
      end
      
      #子レコード数が半端な場合、改ページの処理
      unless seq == 0
        pdata[page]['page_num'] = page - page_org + 1
        #pdata[page]['page_sum'] = page_sum
        #accumulate_pages += page_sum
        #pdata[page]['accumulate_pages'] = accumulate_pages
        #枝番付きIDの準備
        pdata[page]['disp_id'] = pdata[page]['id'].to_s
        page += 1
      end
      
      #複数ページに及んだ場合は枝番をつける
      if page_org < (page - 1)
        cnt = 1
        for i in page_org..(page - 1)
          pdata[i]['disp_id'] = [pdata[i]['disp_id'], '-', cnt.to_s].join('')
          if i > 0
            @total_info_eraser ||= {'total_price'=>'-', 'total_duty'=>'-', 'grand_total_price'=>'-'}
            pdata[i].update(@total_info_eraser)
          end
          cnt += 1
        end
      end
      @send_info=nil
      return page
    end
    
    # OMKK向けテンプレート
    def set_details_to_pages_omkk(ar, pdata, details, detail_name, page, sheet_type=SHEET_TYPE_OMKK)
      @print_rec_num_per_sheet = 36
      @print_rec_num_index = @print_rec_num_per_sheet - 1
      
      Rails.logger.debug('set_details_to_pages sheet_type:'+sheet_type.to_s)
      #最初の扉ページ設定
      pdata[page] = {:page_info => {:sheet_type => sheet_type, :head_page => true}}
      parent_info_hash = add_disp_name_to_hash(ar.only_hashfy)
      parent_info_hash.update(add_disp_name_to_hash(make_sheet_add_for_main(ar)))
      pdata[page].update(parent_info_hash.dup)
      page += 1
      
      product_set_hash = {}
      #カテゴリごとに一旦まとめる
      details.each do |d|
        psid = d.product_set_id
        if product_set_hash[psid]
          product_set_hash[psid] << d
        else
          product_set_hash[psid] = [d]
        end
      end
      
      cnt, sum_quantity, sum_price = 0,0,0
      org_page_num = page
      keys = product_set_hash.keys.sort
      keys.each do |psid|
        Rails.logger.debug('set_details_to_pages psid:'+psid.inspect)
        @master_wide_info = {'product_set_id' => psid,
                             'product_set_dn' => ProductSet.find(psid).disp_name}
        details_ary = product_set_hash[psid]
        Rails.logger.debug('set_details_to_pages details_ary:'+details_ary.inspect)
        
        details_ary.each do |d|
          Rails.logger.debug('set_details_to_pages d:'+d.inspect)
          pdata[page] ||= @master_wide_info.dup
          pdata[page].update(parent_info_hash.dup)
          
          details_hash = d.only_hashfy
          details_hash.update(make_sheet_add_for_detail(nil, d))
          pdata[page][detail_name] ||= {}
          pdata[page][detail_name][cnt] = add_disp_name_to_hash(details_hash)
          
          sum_price += d.price ? d.price * d.quantity : 0
          sum_quantity += d.quantity
          
          if cnt == @print_rec_num_index
            pdata[page].update({:page_info => {:sheet_type => sheet_type},
                                               'page_num' => (page - org_page_num + 1)})
            page += 1
            cnt = 0
            pdata[page] ||= @master_wide_info.dup
            pdata[page].update(parent_info_hash.dup)
          else
            cnt += 1
          end
        end
        
        # ページがdetailでちょうど満タンになって終了している場合のページ情報設定
        if cnt == 0
          pdata[page] ||= @master_wide_info.dup
          pdata[page].update(parent_info_hash.dup)
        end
        
        # 製品型番による改ページ
        pdata[page].update({:page_info => {:sheet_type => sheet_type},
                                           'page_num' => (page - org_page_num + 1)})
        pdata[page][detail_name] ||= {}
        pdata[page][detail_name][cnt] = format_price({'product_dn'=>'TOTAL',
                                                      'quantity'=>sum_quantity,
                                                      'total_price'=>sum_price})
        cnt, sum_quantity, sum_price = 0,0,0
        page += 1
      end
      
      #総ページ数の設定(pageは1進んだ状態なのでその辺を考慮しつつ計算)
      total_page = (page - org_page_num)
      for i in org_page_num..(page-1)
        pdata[i].update({'page_total' => total_page})
      end
      @send_info=nil
      return page
    end
    
    def make_sheet_add_for_main(ar)
      main_add={}
      td = ar.target_date
      td = (td.is_a?(Date)) ? td : Date.new(ar.target_date)
      main_add['target_date_str'] = td.strftime("%B %d, %Y")
      main_add['target_month'] = td.strftime("%B %d")
      
      request_date_time=''
      if ar.arrival_date
        request_date_time = ar.arrival_date.strftime("%m月%d日 ")
      end
      if ar.request_time
        splitted = ar.request_time.split(//)
        if splitted.length == 4
          hour = splitted[0..1].join().to_i
          minute = splitted[2..3].join().to_i
          if minute == 0
            arranged_request_time = hour.to_s + '時'
          else
            arranged_request_time = hour.to_s + '時' + minute.to_s + '分'
          end
          request_date_time += arranged_request_time
        else
          #4文字以外なら怖いので何もしない
          request_date_time += ar.request_time
        end
      end
      main_add['request_date_time'] = request_date_time
      return main_add
    end
    
    def make_sheet_add_for_detail(ar, detail_ar)
      total_price = detail_ar.price ? detail_ar.price * detail_ar.quantity : nil
      pd = Product.find(detail_ar.product_id)
      spec = pd.spec2 + 'x' + pd.spec1 + 'mm' if pd.spec2 && pd.spec1
      detail_hash = {'total_price' => total_price, 'spec' => spec}
      return detail_hash
    end
    
    def get_send_info(ar)
      unless @send_info
        sar = Supplier.find(ar.supplier_id)
        @send_info = { 'send' => get_address_info(sar)}
      end
      return @send_info
    end
    
    def get_own_info(ar)
      unless @own_info
        oar = Supplier.find(OWN_SUPPLIER_ID)
        @own_info = { 'own' => get_address_info(oar, {:title=>false, :avoid_delivery_info=>true})}
        opts={:title=>false}
        if ar.delivery_id
          dar = Delivery.find(ar.delivery_id)
        elsif ar.shipment_customer_id
          dar = Customer.find(ar.shipment_customer_id)
        elsif ar.customer_id
          dar = Customer.find(ar.customer_id)
        elsif ar.warehouse_id
          dar = Warehouse.find(ar.warehouse_id)
          opts.update(:avoid_delivery_info=>true)
        else
          dar = Supplier.find(OWN_SUPPLIER_ID)
        end
        @own_info.update({'delivery' => get_address_info(dar, opts)})
      end
      return @own_info
    end
    
    #空override ページ数を動的に振るため独自で
    def make_all_pages_by_parent(ar, pdata, details, page)
      true
    end
  end
  
  def set_product_params
    manufacture_product_total_quantity = 0
    @details.each do |d|
      comp_product_set_info(d)
      comp_product_info(d)
      d['manufacture_product_details'].each do |md|
        comp_product_set_info(md)
        comp_product_info(md)
        md['parent_product_category_id']=d['product_category_id']
        md['parent_product_set_id']=d['product_set_id']
        md['parent_product_id']=d['product_id']
        md['parent_lot_number']=d['lot_number']
        md['parent_serial_number']=d['serial_number']
        md['parent_ubd']=d['ubd']
        manufacture_product_total_quantity += (md['quantity'].to_i * d['quantity'].to_i) if md['stock_flag_code']==MCODE_STOCK_FLAG_ON
      end
    end
    @table_params['manufacture_product_total_quantity']=manufacture_product_total_quantity
    @mcls.set_stock_and_rels_total_quantity(@table_params, @details)
  end

end
