@startuml

title DCD

hide class circle
hide empty member
/' Job classe per MansioneDiCucina '/
skinparam linetype polyline
/'Controller'/
class "CookalotAppManager" as ck
class "SheetManager" as sm{
  createSheet(event:Event)
  addActivity(kitchenJob)
  removeActivity(target: Activity)
  removeTask(target: Task)
  assignTask(activity: Activity,shift:Shift,time: float,quantity:float,cook:Cook,toBePrepared:boolean)
  orderActivity(activity: Activity,position: int)
  modifyTask(activity: Activity,task: Task,shift: Shift,time: float,quantity: float,cook:Cook,toBePrepared:boolean)
}
class "ShiftManager" as shm {
  getShiftTable(): List<Shift>
}
class "UserManager" as um{
  getCurrentUser(): User
}
class "KitchenJobManager" as kjm{
  createRecipe(name: String)
  selectKitchenJob(kitchenJob: KitchenJob)
  removeKitchenJob(): boolean
  editSimpleStep(simpleStep: SimpleStep, description: String, anticipation: boolean, repetitions: int)
  createPreparation(name: String)
  assignData(name: String, author: String, peopleNumber: int, quantity: int, tacc: int, tacv: int, tt: int, tuc: int, tuv: int)
  removeGenericStep(genericStep: GenericStep, parentGroup: GroupStep)
  addDependency(preparation: KitchenJob): boolean
  deleteDependency(preparation: Preparation)
  insertGroupStep(alternativeSteps: Boolean,repetition: int,fatherGroupStep: GroupStep)
  insertIngredient(ingredient: Ingredient, quantity: int, measureUnit: String): Dosage
  insertTag(tag: Tag): Tag
  removeTag(tag:Tag)
  publish()
}
class "MenùManager" as mm {
  createMenu( ): Menu
  createMenu(title: String): Menu
  chooseMenu(menu: Menu)
  copyMenu(menu: Menu): Menu
  deleteMenu(menu: Menu)
  defineSection(name: String): Section
  deleteSectionWithItems(sect:Section)
  deleteSection(sect:Section)
  changeSectionName(sect:Section, newname:String)
  moveSection(sect: Section,pos: int)
  moveItemInSection(sect: Section,item :MenuItem,pos : int)
  moveItemWithouSection(it:MenuItem,pos : int)
  getRecipeBook( ): RecipeBook
  insertItem(recipe: KitchenJob, section: Section, description: String): MenuItem
  assignItemToSection(it: MenuItem,sect: Section)
  changeItemDEscriptor(it: MenuItem,desc: String)
  deleteItem(it: MenuItem)
  publish( )
}
class "EventManager" as em{
  createEvent()
  selectEventModify(event:Event)
  selectEventLook(event:Event)
  assignData(date: Date,location: String,numberOfParticipants: int,serviceType: String,tipologyNote: String)
  assignChef(chef: User)
  assignRole(staff: User, roleText: String)
  demandStaff(staff: User)
  freeStaff(staff: User)
  modifyData(date: Date,location: String,numberOfParticipants: int,serviceType: String,tipologyNote: String)
  deleteEvent()
  closeEvent(note:String)
  setEventNote(note:String)
}
note left
  TODO: The selectEventLook method is useless...
  How can we handle this?
  How miss Picardi will design this in GUI?
end note

/'Interfaccie'/
interface "MenuEventReceiver" as mer{
  notifyMenuCreated(m: Menu)
  notifySectionAdded(m: Menu,s: Section)
  notifyItemAdded(m: Menu,s: Section,it: MenuItem)
  notifyMenuPublished(m: Menu)
  notifysectionRemuved(m:Menu,s: Section,itemsRemoved: boolean)
  notifySectionNameChanged(m:Menu,s: Section)
  notifySectionRearranged(m:Menu)
  notifyItemsRearrenged(m:Menu,s: Section)
  notifyItemsRearrengedInMenu(m:Menu)
  notifyItemMoved(m:Menu,oldS: Section,newS: Section,it: MenuItem)
  notifyItemDescriptionChanged(m:Menu,it: MenuItem)
  notifyItemDeleted(m:Menu,it: MenuItem)
  notifyMenuTitleChanged(m: Menu)
  
}
interface "Clonable" as c{
}
interface "SheetEventReceiver" as ser{
  notifyActivityRemoved(currentSheet:Sheet,target: Activity)
  notifyActivityRearrangeInSheet(currentSheet: Sheet)
  notifyModifiedTaskInSheet(currentSheet:Sheet,activity:Activity,task:Task)
  notifyAssignTask(currentSheet:Sheet,activity:Activity,task:Task)
  notifySheetCreated(sheet:Sheet)
  notifyActivityAdded(currentSheet:Sheet,activity:Activity)
  notifyTaskRemoved(currentSheet:Sheet,target:Task)
}
interface "EventReceiver" as er{
  notifyEventCreated(event:Event)
  notifyDataAssigned(currentEvent:Event)
  notifyChefAssigned(currentEvent:Event, chef:User)
  notifyDataModified(currentEvent:Event)
  notifyStaffDemanded(currentEvent:Event, assignment:Assignment)
  notifyEventRemoved(currentEvent:Event)
  notifyRoleAssignment(currentEvent:Event, assignment:Assignment)
  notifyReleasedStaff(currentEvent:Event, staff:User)
  notifycloseEvent(currentEvent:Event)
  notifySetEventNote(currentEvent:Event)
}
interface "KitchenJobReceiver" as kjr {
  notifyKitchenJobCreated(currentKitchenJob: KitchenJob)
  notifySimpleStepAdded(currentKitchenJob: KitchenJob, simpleStep: SimpleStep)
  notifySimpleStepEdited(currentKitchenJob: KitchenJob, simpleStep: SimpleStep)
  notifyGenericStepRemoved(currentKitchenJob: KitchenJob, genericStep: GenericStep, parentGroup: GroupStep)
  notifyDependencyAdded(currentKitchenJob: KitchenJob, preparation: KitchenJob)
  notifyTagAdded(currentKitchenJob: KitchenJob)
  notifyTagRemoved(currentKitchenJob: KitchenJob)
  notifyKitchenJobPublished(currentKitchenJob: KitchenJob)
  notifyDependencyRemoved(currentKitchenJob: KitchenJob, preparation: KitchenJob)
  notifyAssignedData(currentKitchenJob: KitchenJob)
  notifyKitchenJobRemoved(currentKitchenJob: KitchenJob)
  notifyGroupStepAdded(currentKitchenJob: KItchenJob,groupStep: GroupStep)
  notifyIngredientAdded(currentKitchebJob: KitchenJob)
}
/'Oggetti del dominio'/
class "Shift" as sh
class "Sheet" as  s {
  Sheet(event:Event)
  addActivity(kitchenJob: KitchenJob)
  removeActivity(target: Activity)
  removeTask(activity: Activity, target: Task)
  addTask(activity: Activity, shift:Shift, time: float, quantity:float, cook: Cook, toBePrepared: boolean)
  hasActivities(activity: Activity): boolean
}

abstract class "GenericStep" as gens {
  repetitions: int
}

class "SimpleStep" as sims {
  content: String
  anticipation: boolean

  SimpleStep(content: String, anticipation: boolean, repetitions: int)
}

class "GroupStep" as gros {
  alternativeSteps: boolean

  GroupStep(alternativeSteps: boolean, repetitions: int)
  addChildren(genericStep: GenericStep)
  removeChildren(genericStep: GenericStep)
  getChildrens(): List<GenericStep>
  contains(genericStep: GenericStep): boolean
}

class "Activity" as a{
  Activity(kitchenJob: KitchenJob)
  addTask(shift: Shift, time: float, quantity: float, cook: Cook, toBePrepared: boolean)
  hasTask(task: Task): boolean
  removeTask(target: Task)
  getTasks(): List<Task>
}
class "User" as u {
  isChef(): boolean
  isOrganiser(): boolean
  isCook(): boolean
  isStaff(): boolean
  isKitchen(): boolean
}
class "KitchenJob" as kj {
  name: String
  author: String
  peopleNumber: int
  quantity: int
  tacc: int
  tacv: int
  tt: int
  tuc: int
  tuv: int
  recipe: boolean
  published: boolean

  KitchenJob(name: String, staff: User, isRecipe: boolean)
  isDish(): boolean
  isPreparation(): boolean
  hasStep(step: GenericStep): boolean
  isInUse(): boolean
  addDependency(preparation: KitchenJob): boolean
  addTag(tag: Tag): Tag
  hasTag(tag: Tag): boolean
  deleteTag(tag:Tag)
  hasTagName(name): boolean
  hasDependency(preparation: KitchenJob): boolean
  removeDependency(preparation: KitchenJob)
  insertGroupStep(alternativeSteps: Boolean,repetition: int,fatherGroupStep: GroupStep)
  addIngredient(ingredient: Ingredient, quantity: int, measureUnit: String): Dosage
}
class "Ingredient" as ing {
  name: String

  Ingredient(name: String)
}
class "Dosage" as dos  {
  quantity: int
  measureUnit: String

  Dosage(quantity: int, measureUnit: String, ingredient: Ingredient)
}
class "Menù" as m  {
  title: String
  published: boolean
  inUse: boolean
  fingerFood: boolean
  requiresCook: boolean
  hotDishes: boolean
  requiresKitchen: boolean
  buffet: boolean
  Menu(owner: User)
  Menu(title: String)
  addSection(name: String): Section
  hasSection(sect: Section): boolean
  hasItem(item: MenuItem): boolean
  hasItemWithoutSection(item: MenuItem): boolean
  getSection(item: MenuItem)
  removeSection(sect: Section,removeItems: boolean)
  removeItem(it: MenuItem, sect: Section)
  addItem(recipe: KitchenJob, section: String, description: String): Item
  isOwner(user: User): boolean
}
class "MenùItem" as mi {
  description: String
  MenuItem(recipe: KitchenJob, description: String)
}
class "Section" as sec{
  name: String
  Section(name: String)
  orderActivity(activity: Activity, position: Integer)
  getItemCount(): number
  addItem(it: MenuItem): Item
  removeItem(it: MenuItem)
  moveItem(it: MenuItem, pos:int)
}
class "Task" as ts{
  quantity: float
  time: float
  toBePrepared: boolean
  Task(shift: Shift, time: float, quantity: float, cook: Cook, toBePrepared: boolean)

}
class "Event" as e{
  location: String
  date: Date
  numberOfParticipants: int
  serviceType: String
  tipologyNote: String
  annotation: String
  closed: boolean
  
  Event(organiser: User)
  setHandler(chef: User)
  addAssignment(assignment: Assigment)
  hasStaff(staff: User): boolean
}

class "Assignment" as asgn{
  description: String
  Assignment(staff: User)
}
class "Tag" as t{
  name: String
  
  Tag(name: String)
}

asgn ->"1" u:involvedUser
e ->"0..N" asgn:roles
ck ->"0..1" kjm:kitchenJobManager
ck ->"0..1" shm:shiftManager
ck -> "0..1" sm: sheetManager
ck -up->"0..1" um:userManager
ck -left->"0..1" mm:menuManager
sm -down->"0..1" s: currentSheet
s -down-> "0..N" a: activities
s --> "0..1" e: event
m -left->"1" u:owner
mm ->"0..1" m:currentMenu
mm -> "0..N" mer: receivers
m -down->"0..N" sec:sections
m ->"0..N" mi:itemsWithoutSection
sec ->"0..N" mi:items
mi -down->"1" kj:recipe
kjm -down->"0..N" kj:kitchenJobList
shm ->"0..N" sh:shifts
sm ->"0..N" ser:receivers
a -->"0..N" ts: tasks
ck ---> "0..1" em: eventManager
e ---> "0..1" u: handler
ts -> "0..1" sh
em -> "0..N" er:receivers
kjm -> "0..N" kjr:receivers
em -> "0..1" e: currentEvent
ts --> "0..1" u:cook
um -> "1" u:currentUser
e -> "0..1" m: menu
a -> "0..1" kj: kitchenJob
dos -> "1" ing: ingredient
kj -> "0..N" dos: ingredients

kjm --> "0..1" kj:currentKitchenJob
kj --> "1" u:owner
kj --> "0..N" kj:dependencies

sims -|> gens
gros - (sims, gens)
kj --> "1" gros:rootGroup
gros -> "0..N" gens:childrens
kj -> "0..N" t: tags

m ..|> c
s ..|> c
mi ..|> c
@enduml
