class ShippingsController < CommLogistics::Base::Controller::SuperiorStock
  include Comm::Module::Controller::Logging
  include CommLogistics::Modules::Print::Controller
  include CommLogistics::Modules::Controller::ShowFilter
  include CommLogistics::Modules::Controller::ExtIndexFilter
  #include CommLogistics::Modules::PrintTruckingNotes
  
  def initialize
    @mcls = Shipping
    @pdf_cls = ShippingPdfOut
  end
  
#  def print_exception(pdfout) 
#    ##PDFでエラーがでたら、print_dateを1000-01-01に強制的にする。
#    if (params[:commit_print_date]==STR_TRUE || params[:with_date]==STR_TRUE) && pdfout
#      pdfout.make_sheet_json(params[:id_list].split(','), true)#error=true
#    end
#  end
  
  #== 指示書印刷
  def print_picking_sheet
    print_sheet(select_pdf_class)
  end
  
  def select_pdf_class
    pdf_class = nil
    if $PICKING_BREAK_PAGE_BY_LOCATION
      pdf_class = PickingPdfLocationBreak
    elsif $PICKING_SORT_BY_LOCATION
      pdf_class = PickingPdfLocationSort
    else
      pdf_class = PickingPdfOut
    end
    Rails.logger.info("Picking PDF Class : "+pdf_class.name.to_s)
    pdf_class
  end
  
  #送り状印刷
#  def print_trucking_notes
#    ActiveRecord::Base.transaction do
#      ars = Shipping.collect_trucking_records(params)
#      ng = get_notes_generator(params)
#      ng.output_csv(ars)
#      resp={:success=>true, :file_name=>ng.get_file_name, :tmp_file_name=>ng.get_tmp_path, :file_type=>ng.get_file_type}
#    end
#    respond_to do |format|
#      format.json { render :json => resp.to_json }
#    end
#  rescue Exception => e
#    Rails.logger.error(e.message + "\n" + e.backtrace.join("\n"))
#    resp={:success=>false, :message=>e.message}
#    respond_to do |format|
#      format.json { render :json => resp.to_json }
#    end
#  end
  
  # 出荷伝票
  class ShippingPdfOut < PdfBase
    #== PDF作成関連
    def initialize(params, mcls=nil)
      @print_rec_num_per_sheet = 6
      @params = params
      super
      
      unless @params[:with_date].blank?
        now = DateTime.now.to_s
        @mcls.transaction do
          @ids.each do |id|
            ar = @mcls.find(id)
            unless ar.update_attributes(:print_sheet_date => now)
              raise 'Time logging failed'
            end
          end
        end
        return true
      end
    rescue Exception => e
      Rails.logger.error(e)
      return false
    end
    
    ##２枚用の判定
    def check_two_sheet(ar)
      if ar.shipping_sheet_type_code == MCODE_SHIPPING_SHEET_2SHEET_STANDARD
        return true
      else
        return false
      end
    end
    
    #２枚目のページ数を定義するためにオーバーライド
    def set_print_rec_num_per_sheet(ar)
      if check_two_sheet(ar)
        @print_rec_num_per_sheet = 19
        @print_rec_num_per_sheet_second = 33
      else
        @print_rec_num_per_sheet = 6
      end
    end

    def make_sheet_add_on_page_end(ar, pdata, page)
      dd = {}
      dd.update(get_send_info(ar))
      dd.update(get_own_info(ar))
      dd['disp_id'] = pdata[page]['id'].to_s
      if pdata[page]['page_total'].to_i > 1
        dd['disp_id'] = [dd['disp_id'], '-', pdata[page]['page_num'].to_s].join('')
      end
      
      return dd
    end
    
    def get_send_info(ar)
      unless @send_info
        if Warehouse.is_own?(ar.warehouse_id)
          tar = Warehouse.find(ar.warehouse_id)
        else
          tar = Customer.find(ar.customer_id)
          tar1 = tar
          tar2 = Warehouse.find(ar.warehouse_id)
          if ar.shipment_customer_id
            tar3 = Customer.find(ar.shipment_customer_id)
          end
        end
        send_info_hash = get_address_info(tar)
        #配送先の設定がある場合は表示（得意先一次店名）に上書き
        if ar.shipment_customer_id
          s_customer_dn = Comm::Tool::DispName.get_id_disp_names('customer_id', [], MFIND_A, [ar.shipment_customer_id]).first['disp_name']
          title = Comm::Tool::DispName.get_code_disp_names('title_code', [], MFIND_V, [tar.title_code]).first['disp_name']
          send_info_hash['disp_name'] = s_customer_dn + ' ' + title
        end
        #着荷場所delivery(営業店止／配送センターなど)を調べて営業店止め以外（=運送業者なし）ならば表示
        if ar.delivery_id
          dar = Delivery.find(ar.delivery_id)
          if dar.trucking_id.blank?
            tmp_d_hash = {'delivery_id'=> ar.delivery_id}
            tmp_d_hash.add_disp_name({:disp_keys => @params[:print_disp_keys] || {}})
            send_info_hash['delivery_dn'] = tmp_d_hash['delivery_dn']
          end
        end
        @send_info = { 'send' => send_info_hash, 
                       :page_info => {:sheet_type => tar.respond_to?("shipping_sheet_type_code") ? tar.shipping_sheet_type_code : 1}}
        #宛名情報を購入者・届け先情報で上書き
        @send_info = overtype_send_info(ar,@send_info,'send',tar)
        #得意先情報
        if tar1
          @send_info['send_1'] = get_address_info(tar1)
          @send_info = overtype_send_info(ar,@send_info,'send_1',tar1)
        end
        #納品先情報
        if tar2
          @send_info['send_2'] = get_address_info(tar2)
          @send_info = overtype_send_info(ar,@send_info,'send_2',tar2)
        end
        #配送先情報
        if tar3
          @send_info['send_3'] = get_address_info(tar3)
          @send_info = overtype_send_info(ar,@send_info,'send_3',tar3)
        end
        ##２枚用の設定
        if check_two_sheet(ar)
          #2ページ目のフォーマット変更フラグをON
          @send_info[:page_info].store(:next_page,true)
        end
      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})}
      end
      return @own_info
    end
    
    def make_sheet_on_change_parent(ar, pdata, page)
      @send_info = nil
    end
    
    def make_sheet_add_for_detail(ar, detail_ar)
      pd = Product.find(detail_ar.product_id)
      pds = ProductSet.find(detail_ar.product_set_id)
      detail_hash = {}
      tmp_p_hash = {'product_set_id'=>pds.id, 'product_id'=>pd.id}
      tmp_p_hash.add_disp_name({:disp_keys => @params[:print_disp_keys] || {}})
      detail_hash['product_number'] = tmp_p_hash['product_dn']#pd.disp_name
      detail_hash['jan'] = pd.jan
      #空文字がある場合はnullに置き換えてcompactでnullを除く
      detail_hash['product_info1'] = tmp_p_hash['product_set_dn'] + " ／ " + tmp_p_hash['product_dn']#pds.disp_name + " ／ " + pd.disp_name
      detail_hash['product_info2'] = [pd.jan.blank? ?  nil : pd.jan, tmp_p_hash['product_dn']].compact.join(" ／ ")#[pd.jan.blank? ?  nil : pd.jan, pd.disp_name].compact.join(" ／ ")
      detail_hash['product_info3'] = [pd.product_name.blank? ?  nil : pd.product_name, tmp_p_hash['product_dn']].compact.join(" ／ ")#[pd.product_name.blank? ?  nil : pd.product_name, pd.disp_name].compact.join(" ／ ")
      detail_hash['product_info4'] = [pd.jan.blank? ?  nil : pd.jan, tmp_p_hash['product_set_dn'], tmp_p_hash['product_dn']].compact.join(" ／ ")#[pd.jan.blank? ?  nil : pd.jan, pds.disp_name, pd.disp_name].compact.join(" ／ ")
      detail_hash['product_info5'] = [pd.product_name.blank? ?  nil : pd.product_name, tmp_p_hash['product_set_dn'], tmp_p_hash['product_dn']].compact.join(" ／ ")#[pd.product_name.blank? ?  nil : pd.product_name, pds.disp_name, pd.disp_name].compact.join(" ／ ")
      if pds.price_unique_code == MCODE_PRICE_UNIQUE_PRODUCT_SET
        detail_hash['public_price'] = pds.public_price
      elsif pds.price_unique_code == MCODE_PRICE_UNIQUE_PRODUCT
        detail_hash['public_price'] = pd.public_price
      end
      return detail_hash
    end
    
    def make_sheet_add_for_main(ar)
      require 'config/site_config.rb'
      add = {}
      if $PRINT_USER_POSITION_NAME_FOR_SHEET
        if ar.user_position_id
          su = UserPosition.find(ar.user_position_id) 
          add['sales_user_name'] = su ? su.j_name : ''
        end
      else
        if ar.sales_user_id
          su = User.find(ar.sales_user_id) 
          add['sales_user_name'] = su ? su.j_name : ''
        end
      end
      add['shipping_note_with_customer_order_number'] = ar.shipping_note;
      unless ar.customer_order_number.blank?
        add['shipping_note_with_customer_order_number'] = '【注文番号：' + ar.customer_order_number + '】　'+ (add['shipping_note_with_customer_order_number'] || "");
      end
      #購入者情報が使われているとき情報補完を行う
      if ar.buyer_flag == MCODE_STOCK_FLAG_ON
        add = supplement_buyer_and_taker(ar,add)
      end
      return add
    end
  end
  
  #== 指示書(ピッキングリスト)出力
  class PickingPdfOut < PdfBase
    # 状態更新
    def post_update(is_success=true)
      id_list = @params[:id_list].split(',')
      id_list.each do |id|
        ar = Shipping.find(id)
        if is_success
          if ar.shipping_state_code == MCODE_SHIPPING_STATE_BEFORE_DIRECTION
            unless ar.update_attributes(:shipping_state_code => MCODE_SHIPPING_STATE_BEFORE_PICK)
              raise 'state logging failed'
            end
          end
        end
      end
    end
    
    def initialize(params, mcls=nil)
      @params = params
      @print_rec_num_per_sheet = 20
      @pdf_basename = 'picking'
      @update_time_column_symbol = :print_picking_date
      @cancel_auto_update_time = true
      super
      #削除済みの伝票が含まれていたらエラーを出力
      @ids.each do |id|
        ar = @mcls.find(id)
        error_array = []
        unless ar.invalid_flag_code==MCODE_FLAG_OFF
          error_array << id
        end
        unless error_array.blank?
          raise UserOperationError, LOEMJ0012 + LOEMD0021 + error_array.join(', ')
        end
      end
    end
    
    def make_filename
      return @pdf_basename
    end
    
    PICKING_PRINTED_OWN_MSG = '指示出力済伝票'
    PICKING_PRINTED_MSG = '■同一配送・配達先の指示 : '
    WDAYS = ["日", "月", "火", "水", "木", "金", "土"]
    def make_sheet_add_for_main(ar)
      require 'config/site_config.rb'
      add = {}
      #add['print_picking_date'] = ar.print_picking_date.blank? ? '' : ar.print_picking_date.strftime("%Y/%m/%d %H:%M:%S")
      ars = Shipping.picking_printed_own_search(ar)
      if ars.length > 0
        #ids = ars.collect{|ar| ar.id}
        add['picking_printed'] = PICKING_PRINTED_OWN_MSG
        add['picking_printed_1'] = PICKING_PRINTED_OWN_MSG
      end
      
      ars = Shipping.picking_printed_search(ar)
      if ars.length > 0
        ids = ars.collect{|one| one.id}
        msg = PICKING_PRINTED_MSG + ids.join(' , ')
        add['picking_printed'] = add['picking_printed'] ? add['picking_printed']+'  /  '+msg : msg
        add['picking_printed_2'] = msg
      end
      
      now = DateTime.now.to_s
      unless ar.update_attributes(@update_time_column_symbol => now)
        raise 'Time logging failed'
      end
      add['print_picking_date'] = ar.print_picking_date.strftime("%Y/%m/%d %H:%M:%S")
      
      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
          add['request_time'] = arranged_request_time
        else
          #4文字以外なら怖いので何もしない
          add['request_time'] = ar.request_time
        end
      end
      if ar.arrival_date
        str_day = ['(', WDAYS[ar.arrival_date.wday], ')'].join()
        add['arrival_date'] = ar.arrival_date.strftime("%m/%d") + str_day
      end
      if $PRINT_USER_POSITION_NAME_FOR_SHEET
        if ar.user_position_id
          su = UserPosition.find(ar.user_position_id) 
          add['sales_user_name'] = su ? su.j_name : ''
        end
      else
        if ar.sales_user_id
          su = User.find(ar.sales_user_id) 
          add['sales_user_name'] = su ? su.j_name : ''
        end
      end
      return add
    end
    
    def make_sheet_add_on_page_end(ar, pdata, page)
      require 'config/site_config.rb'
      #配送先が画面にあるので、配送先あるいは得意先を優先する
      if @params[:enable_shipment_customer]==STR_TRUE
        if pdata[page]['shipment_customer_id'].blank?
          pdata[page]['shipment_customer_id']=pdata[page]['customer_id']
          pdata[page]['shipment_customer_dn']=pdata[page]['customer_dn']
        end
      #配送先が画面にないときは、warehouse_dn or customer_dnを設定する。
      else
        if $PRIOR_CUSTOMER_FOR_SHIPMENT
          pdata[page]['shipment_customer_dn']=pdata[page]['customer_dn']
        else
          pdata[page]['shipment_customer_dn']=pdata[page]['warehouse_dn']
        end
      end
      if pdata[page]['delivery_id'].blank?
        pdata[page]['delivery_dn']=pdata[page]['shipment_customer_dn']
      end
      #顧客情報で上書き
      if pdata[page]['buyer_flag']==MCODE_FLAG_ON || pdata[page]['taker_flag']==MCODE_FLAG_ON
        tmp_name = pdata[page]['taker_flag']==MCODE_FLAG_ON ? (pdata[page]['taker_last_name'] + (pdata[page]['taker_first_name'] || "")) : (pdata[page]['buyer_last_name'] + (pdata[page]['buyer_first_name'] || ""))
        pdata[page]['shipment_customer_dn'] =  tmp_name
        pdata[page]['delivery_dn'] = tmp_name
        if pdata[page]['taker_flag']==MCODE_FLAG_ON
          tmp_address = '〒' + pdata[page]['taker_zip'] + ' ' + pdata[page]['taker_address_1'] + pdata[page]['taker_address_2'] + "\n" + 'TEL: ' + pdata[page]['taker_tel'] + ' / FAX: ' + pdata[page]['taker_fax']
        else
          tmp_address = '〒' + pdata[page]['buyer_zip'] + ' ' + pdata[page]['buyer_address_1'] + pdata[page]['buyer_address_2'] + "\n" + 'TEL: ' + pdata[page]['buyer_tel'] + ' / FAX: ' + pdata[page]['buyer_fax']
        end
          pdata[page]['note'] = pdata[page]['note'] + (pdata[page]['note'].blank? ? '' : "\n") + "配送先住所: " + tmp_address
      end
      return {}
    end
    
    # 製品群ID->製品IDでソート
    def get_arranged_child_details(ar)
      details = ar.child_details
      return details.sort{|a,b| (a.product_set_id <=> b.product_set_id)*2+(a.product_id <=> b.product_id)}
    end
  end
  # 指示書(ロケーションソート)
  class PickingPdfLocationSort < PickingPdfOut
    # 製品ロケーションNo->製品IDでソート
    def get_arranged_child_details(ar)
      details = ar.child_details
      return details.sort{|a,b| (a.location_number <=> b.location_number)*2+(a.product_id <=> b.product_id)}
    end    
  end
  # 指示書(ロケーション改ページ)
  class PickingPdfLocationBreak < PickingPdfLocationSort
    # 既存の処理にロケーション番号での改ページ処理を追加
    def set_details_to_pages(ar, pdata, details, detail_name, page)
      seq = 0
      print_rec_num_index =  @print_rec_num_per_sheet - 1
      previous_location = nil
      previous_page = nil
      details.each do |d|
        location_number = d.location_number
        if (previous_location and (previous_location != location_number)) and
           (previous_page and (previous_page == page))
          #ロケーションNoで改ページ
          page = on_change_pages_for_details(ar, pdata, page, previous_location)
          seq = 0
        end
        pdata[page][detail_name] ||= {}
        details_hash = d.only_hashfy
        details_hash.update(make_sheet_add_for_detail(ar, d))
        pdata[page][detail_name][seq] = add_disp_name_to_hash(details_hash)
        previous_page = page
        if seq == print_rec_num_index
          #子レコード数で改ページ
          page = on_change_pages_for_details(ar, pdata, page, location_number)
          seq = 0
        else
          seq += 1
        end
        previous_location = location_number
      end
      #子レコード数が半端な場合の改ページ
      unless seq == 0
        page = on_change_pages_for_details(ar, pdata, page, previous_location)
      end
      return page
    end
    def on_change_pages_for_details(ar, pdata, page, last_location_number)
      pdata[page].update(unique_make_sheet_add_on_page_end(ar, pdata, page, last_location_number))
      return page += 1
    end
    # ロケーション番号/総数を各ページに設定してから既存の改ページ処理をよぶ
    def unique_make_sheet_add_on_page_end(ar, pdata, page, last_location_number)
      pdata[page]['location_number'] = last_location_number
      pdata[page]['location_total_quantity'] = @location_total_quantity_counter[last_location_number]
      make_sheet_add_on_page_end(ar, pdata, page)
    end
    # ロケーションNoを考慮した総ページ数を求める
    def get_end_page_number(ar, details, page)
      line_number_counter = Hash.new(0)
      @location_total_quantity_counter = Hash.new(0)
      #行数を数えるついでにロケーション番号毎の総数も求めておく
      details.each do |d|
        line_number_counter[d.location_number] += 1
        @location_total_quantity_counter[d.location_number] += d.quantity
      end
      float_rec_num = @print_rec_num_per_sheet * 1.0
      add_num = 0
      line_number_counter.values.each{|v| add_num += (v / float_rec_num).ceil}
      # 0オリジンにするために1引く
      end_page = page + add_num - 1
      Rails.logger.debug("\nEND PAGE NUM : "+end_page.to_s)
      return end_page
    end    
  end
  
  ## 
  ##配送先でフィルタをかけるように修正
  ##
#  def find_all(calc_rows_flag = FLAG_OFF)
#    ss = ShippingSearch.new
#    return ss.search(calc_rows_flag, @mcls, @join_mcls, params, get_find_flag)
#  end
  ##配送先でフィルタをかける
  class ShippingSearch < Comm::Tool::SqlSearch
    def set_additional_where(str_where, params)
      trucking = params[:trucking_id]
      add_str_where(str_where, " trucking_id IN (#{trucking})")
    end
  end

end
