無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

[Ruby] 工なんとか管理にデータを一括登録するスクリプト

最近できた「工なんとか管理」にデータを一括登録するスクリプトです。戦略は以下。

  • 指定された月の登録済みデータを取得し、昼休みなどの規定のデータを登録します。
    • 休み以外の期間は、指定されたデフォルトのタスクで埋めます。
    • 退社時間が20:00以降の場合、30分の休憩をとります。
  • 退社時間のレコードがひとつだけ存在する日に挿入します。
    • レコードが1つもない(=退社時間がない日)は、休日とみなして登録を行いません。
    • レコードが2つ以上ある日は、すでに手動で入力済みとみなして登録を行いません。

利用例

template = Attendance::Template.new( "<ユーザー名>", "<パスワード>", "<社員番号>" )
template.set_task( "<プロジェクト名>", "<プロジェクトコード>", "<仕事の種類>" )
template.insert(2011,9)

前準備

# gem install httpclient 
# gem install json

コード

#!/bin/env ruby

require 'rubygems'
require 'fileutils'
require 'httpclient'
require 'json'
require 'date'

module Attendance

  class Attendance
    
    def initialize
      @records = []
    end
    def get_records_of( day )
      date_str = Utils.format_date(day)
      return records.select {|r|
        r["start_ymd"] ==  date_str
      }
    end
    def add_record( record )
      @records << record        
    end
    def to_json
      return {
        "tasks" => @records
      }.to_json
    end
    def self.create_from_json( json )
      attendance = Attendance.new
      JSON.parse(json)["tasks"].each {|task|
        attendance.add_record( task )
      }
      return attendance
    end
    
    attr_reader :day
    attr_reader :records
    
  end
  
  class AttendanceService
    
    def initialize( user, pass )
      @user = user
      @pass = pass
      @client = HTTPClient.new
      @client.set_cookie_store('./cookie.dat')
    end
    def get( year, month )
      return Attendance.create_from_json(
        @client.get_content(export_url_for( year, month )))
    end
    def put( attendance )
      temp_file = "./tmp.json"
      open(temp_file, "w") {|f|
        f << attendance.to_json
      }
      begin
        open(temp_file) {|f|
          result = JSON.parse(@client.post_content(import_url, {
            "import_file" => f,
            "oformat" => "json",
            "login" => @user,
            "password" => @pass
          }))
          if ( result["status"]["status"] == "Error" )
            raise result["status"]["message"]
          end
        }
      ensure
        FileUtils.rm_rf temp_file
      end
    end
  private
    def host
      return "http://<ChangeIt>:5555"
    end
    def export_url_for( year, month )
      start_day = Date.new( year, month, 1 )
      end_day   = Date.new( year, month+1, -1 )
      return "#{host}/webapi/v100/export.json?from=" \
            + "#{Utils.format_date(start_day)}&to=#{Utils.format_date(end_day)}" \
            + "&password=#{@pass}&login=#{@user}"
    end
    def import_url
      return "#{host}/webapi/v100/import"
    end
  end
  
  class Utils
    def self.format_date( date )
      return date.strftime("%Y-%m-%d")
    end
  end
  
  class Time
    
    def initialize( h, m=0 )
      @h = h
      @m = m
    end
    def <=>(that)
      return @h <=> that.h if (@h <=> that.h) != 0
      return @m <=> that.m
    end
    def <(that)
      return (self <=> that) < 0
    end
    def >(that)
      return (self <=> that) > 0
    end
    def to_s
      return (@h > 10 ? @h.to_s : "0" + @h.to_s) + ":" \
            + (@m > 10 ? @m.to_s : "0" + @m.to_s)
    end
    def self.from( string )
      steps = string.split(":")
      return Time.new( steps[0].to_i, steps[1].to_i )
    end
    attr_reader :h
    attr_reader :m
  end
  
  class Template
    
    def initialize( user, pass, emp_no )
      @service = AttendanceService.new( user, pass )
      @emp_no = emp_no
    end
    
    def set_task( task_name, task_code, kind )
      @task_name = task_name
      @task_code = task_code
      @kind = kind
    end
    
    def insert( year, month )
      @attendance = @service.get( year, month )
      start_day = Date.new(year, month,1)
      end_day   = Date.new(year, month+1,-1)
      start_day.upto(end_day){|date|
        create_records_for( date, @attendance.get_records_of(date))
      }
      do_insert
    end
    
    def insert_to( year, month, day )
      @attendance = @service.get( year, month )
      date = Date.new(year, month,day)
      create_records_for( date, @attendance.get_records_of(date))
      do_insert
    end
    
  private
  
    def do_insert
      @service.put( @attendance )
    end
  
    def create_records_for( day, registerd_records_of_day )
      return if registerd_records_of_day.length != 1
      insert_am_work(day)
      insert_lunch(day)
      
      quitting_time = quitting_time( registerd_records_of_day ) 
      if quitting_time > Time.new(20,0)
        insert_dinner_and_pm_work( day,quitting_time )
      else
        insert_pm_work(day,quitting_time)
      end
    end
    def insert_am_work(day)
      @attendance.add_record({
        "end_hm"=>"11:45", 
        "task_name"=>@task_name,
        "kind"=>@kind,
        "sect_code"=>"F4AL1500C0", 
        "details"=>"", 
        "emp_no"=>@emp_no, 
        "start_hm"=>"09:00", 
        "task_kind"=>"", 
        "start_ymd"=>Utils.format_date(day), 
        "task_code"=>@task_code
      })
    end
    def insert_lunch(day)
      @attendance.add_record({
        "end_hm"=>"12:45", 
        "task_name"=>"休憩・外出",
        "kind"=>"com999", 
        "sect_code"=>"F4AL1500C0", 
        "details"=>"", 
        "emp_no"=>@emp_no, 
        "start_hm"=>"11:45", 
        "task_kind"=>"", 
        "start_ymd"=>Utils.format_date(day), 
        "task_code"=>"ZZK"
      })
    end
    def insert_pm_work(day,quitting_time)
      @attendance.add_record({
        "end_hm"=>quitting_time.to_s, 
        "task_name"=>@task_name,
        "kind"=>@kind,
        "sect_code"=>"F4AL1500C0", 
        "details"=>"", 
        "emp_no"=>@emp_no, 
        "start_hm"=>"12:45", 
        "task_kind"=>"", 
        "start_ymd"=>Utils.format_date(day), 
        "task_code"=>@task_code
      })
    end
    def insert_dinner_and_pm_work(day,quitting_time)
      @attendance.add_record({
        "end_hm"=>"17:30",
        "task_name"=>@task_name,
        "kind"=>@kind,
        "sect_code"=>"F4AL1500C0", 
        "details"=>"",
        "emp_no"=>@emp_no,
        "start_hm"=>"12:45", 
        "task_kind"=>"", 
        "start_ymd"=>Utils.format_date(day), 
        "task_code"=>@task_code
      })
      @attendance.add_record({
        "end_hm"=>"18:00", 
        "task_name"=>"休憩・外出",
        "kind"=>"com999", 
        "sect_code"=>"F4AL1500C0", 
        "details"=>"", 
        "emp_no"=>@emp_no, 
        "start_hm"=>"17:30", 
        "task_kind"=>"", 
        "start_ymd"=>Utils.format_date(day), 
        "task_code"=>"ZZK"
      })
      @attendance.add_record({
        "end_hm"=>quitting_time.to_s, 
        "kind"=>@kind,
        "task_name"=>@task_name,
        "sect_code"=>"F4AL1500C0", 
        "details"=>"", 
        "emp_no"=>@emp_no, 
        "start_hm"=>"18:00", 
        "task_kind"=>"", 
        "start_ymd"=>Utils.format_date(day), 
        "task_code"=>@task_code
      })
    end
    def quitting_time(registerd_records_of_day)
      return Time.from( registerd_records_of_day.find {|r|
        r["task_code"] == "ZZL"
      }["start_hm"])
    end
  end

end