Scala练习:OpenHouse题目 Timesheet

package sanguo.timesheet

import helpers._

abstract class Project(val name: String, val rate: Int)
case class BillableProject(override val name: String) extends Project(name, 1)
case class SIPProject(override val name: String) extends Project(name, 0)
case class Holiday() extends Project("休假", 0)

class Level(val chargePerHour: Int)
object Level {
    def apply(chargePerHour: Int) = new Level(chargePerHour)
}

class Consultant(val name: String, val level: Level) {
    def chargePerHour = level.chargePerHour
}
object Consultant {
    def apply(name: String, level: Level) = new Consultant(name, level)
}

class TimeSheetItem(
    val consultant: Consultant,
    val project: Project,
    mon: Int, tue: Int, wed: Int, thu: Int, fri: Int) {
    def working_hours = mon + tue + wed + thu + fri
    def charge = consultant.chargePerHour * project.rate * working_hours
}

object TimeSheetItem {
    def apply(c: Consultant, p: Project, mon: Int, tue: Int, wed: Int, thu: Int, fri: Int) = new TimeSheetItem(c, p, mon, tue, wed, thu, fri)
}

class Timesheet(val items: Set[TimeSheetItem]) {
    private var consultants = Set.empty[Consultant]
    private var projects = Set.empty[Project]
    items foreach { item =>
        consultants += item.consultant
        projects += item.project
    }

    private val sum_hours = (total: Int, item: TimeSheetItem) => total + item.working_hours
    private val sum_charges = (total: Int, item: TimeSheetItem) => total + item.charge

    def total_hours(_filter: (TimeSheetItem => Boolean)): Int = {
        (0 /: (items filter _filter)) { sum_hours }
    }

    def total_charge(_filter: (TimeSheetItem => Boolean)): Int = {
        (0 /: (items filter _filter)) { sum_charges }
    }

    def print_report = {
        projects foreach { p =>
            p match {
                case BillableProject(name) => {
                    println("项目名称:" + name)
                    println("咨询师\t工作时间\t应收费用")
                    var hours_all = 0
                    var charge_all = 0
                    consultants foreach { c =>
                        val filter = c at p
                        val hours = total_hours(filter)
                        val charge = total_charge(filter)
                        if (hours > 0) println(c.name + "\t" + hours + "\t" + charge)
                        hours_all += hours
                        charge_all += charge
                    }
                    println("总计:\t" + hours_all + "\t" + charge_all)
                }
                case Holiday() => {
                    println("休假情况:")
                    println("咨询师\t时间")
                    var hours_all = 0
                    consultants foreach { c =>
                        val filter = c at p
                        val hours = total_hours(filter)
                        if (hours > 0) println(c.name + "\t" + hours)
                    }
                    println("总计:\t" + hours_all)
                }
                case SIPProject(name) => {
                    println("项目名称:" + name + " - 公益项目")
                    println("咨询师\t工作时间")
                    var hours_all = 0
                    consultants foreach { c =>
                        val filter = c at p
                        val hours_of_cons = total_hours(filter)
                        hours_all += hours_of_cons
                        if (hours_of_cons > 0) println(c.name + "\t" + hours_of_cons)
                    }
                    println("总计:\t" + hours_all)
                }
            }
            println("-------------------------------------------------")
        }
    }
}

object helpers {
    implicit def consultant2Helper(consultant: Consultant): Consultant2TimesheetItem = new Consultant2TimesheetItem(consultant)
    implicit def helper(name: String): String2Consultant = new String2Consultant(name)
}

class Consultant2TimesheetItem(consultant: Consultant) {
    def at(project: Project): (TimeSheetItem => Boolean) = {
        item: TimeSheetItem => item.consultant == consultant && item.project == project
    }
}
class String2Consultant(name: String) {
    def level(_level: Level) = {
        Consultant(name, _level)
    }
}

object Timesheet extends App {
    val junior = Level(chargePerHour = 1000)
    val senior = Level(chargePerHour = 2000)
    
    val 张飞 = "张飞" level junior
    val 关羽 = "关羽" level junior
    val 刘备 = "刘备" level senior
    val 赵云 = "赵云" level junior

    val 火烧赤壁 = BillableProject("火烧赤壁")
    val 七擒孟获 = BillableProject("七擒孟获")
    val 都江堰 = SIPProject("都江堰")
    val 休假 = Holiday()
    
    import sanguo.timesheet.{TimeSheetItem => Item}
    val timesheet = new Timesheet(
        Set(
            Item(张飞, 火烧赤壁, 8, 0, 0, 8, 4),
            Item(张飞, 七擒孟获, 0, 8, 8, 0, 0),
            Item(张飞, 休假, 0, 8, 8, 0, 0),
            Item(关羽, 都江堰, 8, 8, 8, 0, 0),
            Item(关羽, 火烧赤壁, 8, 8, 8, 0, 0),
            Item(刘备, 七擒孟获, 8, 8, 0, 8, 8),
            Item(刘备, 都江堰, 0, 0, 8, 0, 0),
            Item(赵云, 休假, 8, 8, 8, 8, 8)))
    timesheet print_report
}
 

你可能感兴趣的:(scala,OpenHouse,CodeSample)