@startuml
'Attribute syntax: <visibility> <name> : <type> <multiplicity> = <default>
'Method syntax: <visibility> <name (parameter-list)> : <return-type> - For simplicity the type of the parameter-list is not specified

skinparam classAttributeIconSize 0
'skinparam classBackgroundColor transparent
skinparam linetype polyline

title US003 - As Administrator, I want to change the profile of a user account
' Controllers ----------------------------------------------------------------------------------------------------------
class ChangeProfileController {
    -profileService : ProfileService

    +ChangeProfileController ()
    +accountList () : String
    +profileList () : String
    +changeProfile (accountID, profileID) : boolean
}

' Services -------------------------------------------------------------------------------------------------------------
class ProfileService {
    -profiles : ProfileContainer

    +ProfileService ()
    +createProfile (id, name) : boolean
    +profileList ()
}

class AccountService {
    -accounts : AccountContainer

    +AccountService ()
    +createAccount (name, email, phoneNumber, photo) : boolean
    +changeProfile (accountID, profileID) : boolean
    +accountList () : String
    +accountsAndStatusList () : accountsListDTO
}

' Collections ----------------------------------------------------------------------------------------------------------
class ProfileContainer {
    -profiles : Profile [1..*] = [Admin]

    +ProfileContainer()
    +createProfile (id, name) : boolean
}

class AccountContainer {
    -accounts : Account [1..*]

    +AccountContainer ()
    +createAccount (name, email, phoneNumber, photo) : boolean
    +accountList () : String
    +searchAccount (accountID : int) : boolean
    +changeProfile (accountID, profileID) : boolean
    +accountsAndStatusList () : String
    +generateAccountsDTO () : AccountDTO [1..*]
}

' Entities ----------------------------------------------------------------------------------------------------------------
class Profile {
    -id: int
    -name : String

    +Profile (int id, String name)
    +generateDTO () : ProfileDTO
    +equals (Profile) : boolean
}

class Account {
    -id: int
    -name : String
    -email : String
    -phoneNumber : int
    -photo : Image
    -profileID : int = 2
    -isActive : boolean = true

    +Account (name, email, phoneNumber, photo)
    +generateDTO () : AccountDTO
    +hasID (accountID : int) : boolean
    +changeProfile (profile) : boolean
    +isActive () : boolean
    +inactivate () : boolean
    +activate () : boolean
    +equals (object : Account) : boolean
}

' Assembler ------------------------------------------------------------------------------------------------------------
class AccountListAssembler {
    -accountListDTO : AccountListDTO

    +AccountListAssembler ()
    +createDTO (accounts : Accounts) : boolean
    +getAccountsAndStatus () : String
    +getAccountList () : String
}

class ProfileListAssembler {
    -profileListDTO : ProfileListDTO

    +ProfileListAssembler()
    +createProfilesDTO (profiles : Profiles) : boolean
    +getListOfProfiles () : String
}

' DTO ------------------------------------------------------------------------------------------------------------------
class AccountDTO {
    -id: int
    -name : String
    -email : String
    -status : boolean
    -profile : int

    +AccountDTO (name, email, status)
    +getID () : id
    +getName () : String
    +getEmail () : String
    +getStatus () : String
    +getProfile () : int
}

class ProfileDTO {
    -id: int
    -name : String

    +ProfileDTO (id, name)
    +getID () : id
    +getName () : String
    +getEmail () : String
    +getStatus () : String
}

class AccountListDTO {
    -accountsMap : HashMap

    +AccountListDTO ()
    +addData (accountID, namesAndEmails) : boolean
    +serializeListOfAccontsAndStatus () : String
    +serializeAccountList () : String
}

class ProfileListDTO {
    -profilesMap : HashMap

    +ProfileListDTO ()
    +addData (profileID, profileName) : boolean
    +serializeListOfProfiles () : String
}

' Associations and dependencies ----------------------------------------------------------------------------------------

' Controller Layer
ChangeProfileController --> ProfileService : profileService
ChangeProfileController --> AccountService : accountService

' Service Layer
AccountService --> AccountContainer : accounts
ProfileService --> ProfileContainer : profiles

' Collections Layer
ProfileContainer "1" *--> "*" Profile : profiles
AccountContainer "1" *--> "*" Account : accounts

' DTO Layer
AccountService .l.> AccountListAssembler
AccountListAssembler ..> AccountContainer
AccountListAssembler ..> AccountDTO
AccountListAssembler --> AccountListDTO : accountListDTO
Account ..> AccountDTO

ProfileService .l.> ProfileListAssembler
ProfileListAssembler ..> ProfileContainer
ProfileListAssembler --> ProfileListDTO : profileListDTO
ProfileListAssembler ..> ProfileDTO
Profile ..> ProfileDTO

' Notes ----------------------------------------------------------------------------------------------------------------
note right of Account::profileID
    Admin = 0, Manager = 1, User = 2
endnote

@enduml
