@startuml Gestire Compiti Cucina
skinparam Style strictuml
skinparam classAttributeIconSize 0
skinparam linetype polyline
skinparam linetype ortho
' skinparam Padding 8

title DCD

namespace KitchenTaskManagement {
    ' GRASP Controller
    class KitchenTaskManager{
        --<b>event sender methods</b>--
        +addReceiver(er: kitchenTaskReceiver)
        +removeReceiver(er: kitchenTaskReceiver)
        +notifySheetCreate(s: SummarySheet)
        +notifyTaskCreate(t: Task)
        +notifyAddExtraDuty(kd: KitchenDuty)
        +notifyDeleteExtraDuty(kd: KitchenDuty)
        --<b>operation methods</b>--
        + createSummarySheet(event: Event, service: Service)
        + editTask(task: Task, newAmount: int, newDuration: int)
        + sortTask(task: Task, position: int)
        + addExtraDuty(kd: KitchenDuty)
        + deleteExtraDuty(kd: KitchenDuty)
        + createJob(cook: Cook, task: Task, turn: Turn, amount: int, estimatedDuration: Duration)
        + deleteJob(task: Task, job: Job)
        + assignCook(job: Job, user: User)
    }

    class KitchenTaskReceiver{
        --
        +<i>updateSheetCreate(s: SummarySheet)</i>
        +<i>updateTaskCreate(t: Task)</i>
        +<i>updateAddExtraDuty(kd: KitchenDuty)</i>
        +<i>updateDeleteExtraDuty(kd: KitchenDuty)</i>
    }

    ' Compito
    class Task{
        - amount: int
        - estimatedDuration: Duration
        --
        + create(kitchenDuty: KitchenDuty)
        + editDetails(newAmount: int, newDuration: int)
        + addJob(cook: Cook, turn: Turn, amount: int, estimatedDuration: Duration)
        + deleteJob(job: Job)
    }

    ' Foglio Riepilogativo
    class SummarySheet {
        + create(menu: Menu)
        + addExtraDuty(kd: KitchenDuty)
        + deleteExtraDuty(kd: KitchenDuty)        
    }

    KitchenTaskManager --> "0..1" SummarySheet: currentSheet
    KitchenTaskManager -> "0..n" KitchenTaskReceiver: eventReceivers
    SummarySheet --> "1..n" Task: tasks
    SummarySheet --> "0..n" RecipeManagement.KitchenDuty: extraDuties
    Task -> "1..n" Job: jobs
    Task -left-> "0..1" RecipeManagement.KitchenDuty: optionalDuty


    ' Incarico
    class Job {
        - amount: int
        - estimatedDuration: Duration
        --
        + create(cook: Cook, turn: Turn, amount: int, estimatedDuration: Duration)
        + edit(user: User, amount: int, estimatedDuration: Duration)
    }

    Job --> "0..1"  UserManagement.User: cook
    Job --> "1" TurnManagement.Turn: turn
}

'prova

namespace TurnManagement {
    class Cook

    class Turn {
        - startDate: Date
        - endDate: Date
        - complete: boolean
        --
        + getDuration(): Duration
    }

    class TimeKeeper {
        - usedTime: Duration
    }

    TimeKeeper -> UserManagement.User: cook

    Turn -> "0..n" TimeKeeper: assignedCooks

    class TurnManager

    TurnManager -> "0..n" Turn: turns
}

namespace RecipeManagement {
    class KitchenDuty {
        - name: String
        - instructions: String
        - resultingAmount: int
        - constantConcreteActivityTime: Duration
        - variableConcreteActivityTime: Duration
        {abstract} List<KitchenDuty> getSubDuties()
    }
    KitchenDuty --> "1" UserManagement.User: author

    class Recipe {

    }

    class Preparation{

    }

    Recipe -left|> KitchenDuty
    Preparation -left|> KitchenDuty
    Recipe -up> "0..n" Preparation: subDuties
}

namespace EventManagement {
    class Service {
        + getMenu(): Menu
    }
    Service -up> "0..1" MenuManagement.Menu: menu

    class Event {
        - active: boolean
        --
        + isActive(): boolean
        + containsService(s:Service): boolean
    }
    Event -> "1..n" Service: "services"
    Event -left> "1" UserManagement.User: "assignedChef"

}

namespace UserManagement {
    class User {
        + isChef(): boolean
        + isCook(): boolean
    }

    class UserManager {
        --<b>event sender methods</b>--
        --<b>operation methods</b>--
        +getCurrentUser(): User
    }

    UserManager -> "0..1" User: currentUser
}

namespace MenuManagement {
    class Menu
    class Section
    class MenuItem

    Menu -left> "0..n" Section: sections
    Menu -> "0..n" MenuItem: freeItems
    Section -left> "0..n" MenuItem: sectionItems

    MenuItem -> RecipeManagement.Recipe: itemRecipe
}

namespace GeneralModule {
    UseCaseLogicException --|> Exception
    EventException --|> Exception


}

@enduml