OSDN Git Service

CSVデータ作成処理をリファクタリング
authorYOSHIDA Hiroki <hyoshida@appirits.com>
Wed, 15 May 2013 02:25:18 +0000 (11:25 +0900)
committerYOSHIDA Hiroki <hyoshida@appirits.com>
Wed, 15 May 2013 02:55:52 +0000 (11:55 +0900)
app/models/customer_search_form.rb
app/models/order.rb
app/models/product.rb
app/models/questionnaire.rb
config/initializers/add_csv_download/add_csv_download.rb
lib/totalizer.rb
spec/models/customer_search_form_spec.rb

index 78f2101..0098ec2 100644 (file)
@@ -28,69 +28,53 @@ class CustomerSearchForm < SearchForm
   validates_format_of :product_code, :with => /^[0-9A-Za-z]+$/, :allow_blank => true, :message => 'は半角英数字のみを入力してください。'\r
 \r
   def self.csv(params)\r
+    #customers = Customer.find_by_sql(get_sql_select(true) + get_sql_condition(@condition))\r
+    customers = Customer.find_by_sql(condition_for_csv(params))\r
+    return if customers.size.zero?\r
+    CSVUtil.make_csv_string(csv_rows(customers), csv_header)\r
+  end\r
+\r
+  private\r
+\r
+  def self.condition_for_csv(params)\r
     @condition = self.new(params[:condition] ||= [])\r
     sql_condition, conditions = get_sql_condition(@condition)\r
     sql = get_sql_select(true) + sql_condition\r
-    sqls = [sql]\r
-    conditions.each do |c|\r
-      sqls << c\r
-    end\r
-    #customers = Customer.find_by_sql(get_sql_select(true) + get_sql_condition(@condition))\r
-    customers = Customer.find_by_sql(sqls)\r
-    unless customers.size > 0\r
-      return false\r
-    end\r
+    [ sql ] + conditions\r
+  end\r
 \r
-    col_names = []\r
-    syms = Customer.get_symbols\r
-    field_names = Customer.field_names\r
-    syms.each do |sym|\r
-      col_names << field_names[sym]\r
-    end\r
-    str = CSV.generate("") do | writer |\r
-      writer << col_names\r
-      customers.each do |c|\r
-        arr = []\r
-        syms.each do |sym|\r
-          if sym == "sex".to_sym\r
-            if c.send(sym) == 1\r
-              arr << "男性"\r
-            else\r
-              arr << "女性"\r
-            end\r
-          elsif sym == "age".to_sym\r
-            #誕生日から年齢を割り出す\r
-            birthday = c.send("birthday".to_sym)\r
-            arr << self.get_age(birthday)\r
-          else\r
-            arr << c.send(sym)\r
-          end\r
-        end\r
-        writer << arr\r
-      end\r
+  def self.csv_header\r
+    Customer.get_symbols.map do |sym|\r
+      Customer.field_names[sym]\r
     end\r
   end\r
 \r
-  #誕生日から年齢を割り出すメソッド\r
-  def self.get_age(birthday)\r
-    unless birthday.blank?\r
-      today = Date.today\r
-      year = today.year.to_i - birthday.year.to_i\r
-      if today.month.to_i > birthday.month.to_i\r
-\r
-      elsif today.month.to_i < birthday.month.to_i\r
-        year = year - 1\r
-      elsif today.month.to_i == birthday.month.to_i\r
-        if today.day.to_i >= birthday.day.to_i\r
-\r
+  def self.csv_rows(customers)\r
+    customers.map do |customer|\r
+      Customer.get_symbols.map do |sym|\r
+        case sym\r
+        when :sex\r
+          sex_key = customer.send(sym)\r
+          System::SEX_NAMES[sex_key]\r
+        when :age\r
+          self.calculate_age_from(customer.birthday)\r
         else\r
-          year = year - 1\r
+          customer.send(sym)\r
         end\r
       end\r
-      return year\r
     end\r
   end\r
 \r
+  def self.calculate_age_from(birthday)\r
+    return if birthday.blank?\r
+    today = Date.today\r
+    day_diff   = today.day.to_i   - birthday.day.to_i\r
+    month_diff = today.month.to_i - birthday.month.to_i\r
+    year_diff  = today.year.to_i  - birthday.year.to_i\r
+    year_diff -= 1 if (month_diff < 0) || (month_diff == 0 && day_diff < 0)\r
+    year_diff\r
+  end\r
+\r
   def self.get_sql_select(for_csv=false)\r
     if for_csv\r
 <<-EOS\r
index 854df26..b3c55dc 100644 (file)
@@ -113,29 +113,38 @@ class Order < ActiveRecord::Base
   end
 
   def self.csv(search_list)
-    columns = OrderDelivery.csv_columns_name
     order_deliveries = OrderDelivery.find(:all,
                          :conditions => flatten_conditions(search_list),
                          :include => OrderDelivery::DEFAULT_INCLUDE,
                          :order => "order_deliveries.id desc")
-    str = CSV.generate("") do | writer |
-      writer<< columns.map{|name| OrderDelivery.set_field_names[name]}
-      order_deliveries and order_deliveries.each do | od |
-        writer << columns.map do | column |
-          if ![:order_code,:prefecture_name,:occupation_name,:sex_name,:payment_name,:deliv_pref_name,:delivery_trader_name,:delivery_time_name,:status_view,:ticket_code].include?(column) && OrderDelivery.columns_hash[column.to_s].type == :datetime
-            (od[column] + (60*60*9)).strftime("%Y-%m-%d %H:%M") if od[column]
-          else
-            od[column] || od.send(column)
-          end
+    csv_text = CSVUtil.make_csv_string(csv_rows(order_deliveries), csv_header)
+    [csv_text, csv_filename]
+  end
+
+  private
+
+  def self.csv_filename 
+    "order_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
+  end
+
+  def self.csv_header
+    columns.map{|name| OrderDelivery.set_field_names[name] }
+  end
+
+  def self.csv_rows(order_deliveries)
+    return if order_deliveries.blank?
+    order_deliveries.map do |od|
+      OrderDelivery.csv_columns_name.map do |column|
+        nodatetime_columns = [ :order_code, :prefecture_name, :occupation_name, :sex_name, :payment_name, :deliv_pref_name, :delivery_trader_name, :delivery_time_name, :status_view, :ticket_code ]
+        if nodatetime_columns.include?(column) || OrderDelivery.columns_hash[column.to_s].type != :datetime
+          od[column] || od.send(column)
+        else
+          (od[column] + 9.hours).strftime("%Y-%m-%d %H:%M") if od[column]
         end
       end
     end
-    filename = "order_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
-    [str, filename]
   end
 
-  private
-
   def generate_code
     id_code = ("%04d" % self.id).slice(-4..-1) # レコード ID の下 4 桁
     self.code = created_at.strftime("%Y%m%d%H%M") + id_code
@@ -145,5 +154,4 @@ class Order < ActiveRecord::Base
   def sum_deliveries message
     order_deliveries.map(&message).map(&:to_i).sum
   end
-
 end
index 4ec29d2..40f0915 100644 (file)
@@ -282,33 +282,12 @@ class Product < ActiveRecord::Base
   end
 
   def self.csv(search_list)
-    columns = csv_columns_name
     products = self.find(:all,
                          :conditions => flatten_conditions(search_list),
                          :include => DEFAULT_INCLUDE,
                          :order => "products.id")
-    str = CSV.generate("") do | writer |
-      writer<< columns.map{|name| set_field_names[name]}
-      products and products.each do | product |
-        writer << columns.map do | column |
-          if column.to_s == "permit"
-            if product[column]
-              "公開"
-            else
-              "非公開"
-            end
-          elsif column.to_s == "delivery_dates_label"
-            product.delivery_dates_label
-          elsif ![:small_resource_path,:medium_resource_path,:large_resource_path,:category_name,:delivery_dates_label,:supplier_name,:retailer_name].include?(column)&& Product.columns_hash[column.to_s].class == :datetime
-            (product[column] + (60*60*9)).strftime("%Y-%m-%d %H:%M") if product[column]
-          else
-            product[column] || product.send(column)
-          end
-        end
-      end
-    end
-    filename = "product_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
-    [str, filename]
+    csv_text = CSVUtil.make_csv_string(csv_rows(products), csv_header)
+    [csv_text, csv_filename]
   end
 
   def self.actual_count_list_csv(search_list)
@@ -316,20 +295,9 @@ class Product < ActiveRecord::Base
                                   :conditions => flatten_conditions(search_list),
                                   :joins => "LEFT JOIN products ON products.id = product_styles.product_id ",
                                   :order => "id")
-    title = ["商品名", "商品コード", "登録更新日", "実在個数"]
-    str = CSV.generate("") do | writer |
-      writer<< title
-      products and products.each do | product |
-        columns = []
-        columns  <<  product.product_name
-        columns  <<  product.code
-        columns  <<  product.updated_at
-        columns  <<  product.actual_count.to_i
-        writer << columns
-      end
-    end
-    filename = "actual_count_list_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
-    [str, filename]
+    rows = actual_count_list_csv_rows(products)
+    csv_text = CSVUtil.make_csv_string(rows, actual_count_list_csv_header)
+    [csv_text, actual_count_list_csv_filename]
   end
 
   def master_shop?
@@ -615,6 +583,55 @@ class Product < ActiveRecord::Base
     }
   end
 
+  def self.csv_header
+    csv_columns_name.map{|name| set_field_names[name] }
+  end
+
+  def self.csv_filename
+    "product_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
+  end
+
+  def self.csv_rows(products)
+    return if products.blank?
+    products.map do |product|
+      csv_columns_name.map do |column|
+        if column.to_s == "permit"
+          if product[column]
+            "公開"
+          else
+            "非公開"
+          end
+        elsif column.to_s == "delivery_dates_label"
+          product.delivery_dates_label
+        elsif ![:small_resource_path,:medium_resource_path,:large_resource_path,:category_name,:delivery_dates_label,:supplier_name,:retailer_name].include?(column)&& Product.columns_hash[column.to_s].class == :datetime
+          (product[column] + (60*60*9)).strftime("%Y-%m-%d %H:%M") if product[column]
+        else
+          product[column] || product.send(column)
+        end
+      end
+    end
+  end
+
+  def self.actual_count_list_csv_header
+    %w( 商品名 商品コード 登録更新日 実在個数 )
+  end
+
+  def self.actual_count_list_csv_filename
+    "actual_count_list_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
+  end
+
+  def self.actual_count_list_csv_rows(products)
+    return if products.blank?
+    products.map do |product|
+      [
+        product.product_name,
+        product.code,
+        product.updated_at,
+        product.actual_count.to_i
+      ]
+    end
+  end
+
   def self.id_change_to_i(ids)
     if ids.blank?
       ids = 0
index 530c905..43188f9 100644 (file)
@@ -68,18 +68,8 @@ class Questionnaire < ActiveRecord::Base
   end
 
   def self.csv(id, count)
-    questionnaire = self.find(id)
     header = get_csv_header(count)
-    str = CSV.generate("") do |writer|
-      writer << header
-      questionnaire.questionnaire_answers.each do | questionnaire_answer |
-        row = questionnaire_answer.export_row
-        questionnaire_answer.question_answers.each do |question_answer|
-          row.concat(question_answer.export_row)
-        end
-        writer << row
-      end
-    end
+    CSVUtil.make_csv_string(csv_rows(id), header)
   end
 
   private
@@ -108,4 +98,10 @@ class Questionnaire < ActiveRecord::Base
     header
   end
 
+  def self.csv_rows(id)
+    self.find(id).questionnaire_answers.map do |questionnaire_answer|
+      row = questionnaire_answer.export_row
+      row + questionnaire_answer.question_answers.map(&:export_row).flatten(1)
+    end
+  end
 end
index 99b183a..973729e 100644 (file)
@@ -16,17 +16,8 @@ module AddCSVDownload
     
     def csv(params)
       list_for_csv(params)
-      columns, titles = get_csv_settings((@model.nil? ? nil : @model.csv_columns_name))
-      str = CSV.generate("") do | writer |
-        writer << titles
-        @records and @records.each do | record |
-          writer << columns.map do | column |
-            record[column] || record.send(column)
-          end
-        end
-      end
-      filename = "#{csv_output_setting_name}#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"      
-      [str, filename]
+      csv_text = CSVUtil.make_csv_string(csv_rows, csv_header)
+      [csv_text, csv_filename]
     end
 
     private
@@ -149,15 +140,32 @@ module AddCSVDownload
         end
       end
     end    
-    
-    def get_csv_settings(columns=nil)
-      unless columns
-        columns = @model.columns.map(&:name)
-      end
-      titles = columns.map do | name |
+
+    def csv_columns
+      return if @model.nil?
+      columns = @model.csv_columns_name 
+      columns ||= @model.columns.map(&:name)
+      columns
+    end
+
+    def csv_header
+      return if @model.nil?
+      csv_columns.map do |name|
         @model.set_field_names[name]
       end
-      [columns, titles]
+    end
+
+    def csv_filename
+      "#{csv_output_setting_name}#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
+    end
+
+    def csv_rows
+      return if @records.blank?
+      @records.map do |record|
+        csv_columns.map do |column|
+          record[column] || record.send(column)
+        end
+      end
     end
   end
 
index 167732f..7562b84 100644 (file)
@@ -96,8 +96,12 @@ class Totalizer < TotalizerBase
     g
   end
 
-  def self.get_csv_settings(columns=nil)
-    [self.new.columns, self.new.labels.map{|c|c.sub("\n", '')}]
+  def self.csv_header
+    self.new.labels.map{|c| c.sub("\n", '') }
+  end
+
+  def self.csv_columns
+    self.new.columns
   end
 
   def self.csv_output_setting_name
index ee1993f..4040266 100644 (file)
@@ -111,20 +111,10 @@ describe CustomerSearchForm do
   end
   #fixturesデータをCSV形式に変換(比較用)
   def convert(customers)
-    datas = []
-    customers.each do |c|
-      arr = []
-      Customer.get_symbols.map do |sym|
-        if [:sex].include?(sym)
-          arr << (c.sex == System::MALE ? System::SEX_NAMES[System::MALE] : System::SEX_NAMES[System::FEMALE])
-        elsif [:age].include?(sym)
-          arr << (CustomerSearchForm.get_age(c.birthday).nil? ? "" : CustomerSearchForm.get_age(c.birthday).to_s)
-        else
-          arr << (c.send(sym).nil? ? "" : c.send(sym).to_s)
-        end
-      end
-      datas << arr.join(",").split(",")
+    rows = CustomerSearchForm.send :csv_rows, customers
+    rows.collect do |row|
+      # XXX: 下記行がどのような処理を意図しているか不明
+      row.join(",").split(",")
     end
-    datas
   end
 end