@startuml
skinparam classAttributeIconSize 0




class Store {

    - Integer ID
    - String name
    - String address
    - String email
    - String phoneNumber
    - State state
    - District district
    - City city
    - String designation


}
class StoreRepository {
    - List<Store> stores
    + createStore(id, name, address, email, phoneNumber, state, district, city)
    + validateStore(store)
    + addStore(store)
    + getStores()
    + getStoreByDesignation(designation)
    - storeDesignationExists(designation)
}

class State {
    - List<District> districts
    - String Name
    + getDistrictsOfState()
    - getDistrictFromDistrictName(districtName))

}

class StateRepository {
    - List<State> states
    - getStates()
    - getStatesFromStatename(stateName)

}

class District {
    - List<City> cities
    - String Name
    + getCitiesOfDistrict()
    + getCityByName(cityName)
}



class City {
    - String Name

}


class RegisterStoreController {
    + RegisterStoreController(StoreRepository, StateRepository)
    + getStates()
    + createStore(id, name, address, email, phoneNumber, state, district, city)
    - getDistrictsOfState(stateName)
    - getCitiesOfDistrict(districtName)
    - getCityByName(cityName)

}

class RegisterStoreUI {
}

class Repositories {
    - Repositories()
    + getInstance() : Repositories
    + getTypeOfPropertyRepository()
    + getStateRepository()
    + getStoreRepository()
    + getTypeOfBusinessRepository()
    + getTypeOfBusiness()
    + getTypeOfProperty()
    + getStores()
    + getUserRepository()
    + getAgents(Agency)
    + getPropertyRepository()
    + getPropertyByLocation(location)
    + addDuration(duration, property)
    + getRoleRepository()
    + getEmployeeRepository()
}

class PropertyRepository {
    + getPropertyByLocation(location)
    + getPropertyByTypebusinessTypepropertyNumberrooms(typebusiness, typeproperty, numberrooms)
    -addProperty(property)
    -validateProperty(property)
}

class UserRepository {
    + getUserByEmail(email)
    + setRoleToUser(role, user)
}

class Employee {
    -Integer passportNum
    -Integer taxNum
    -Integer address
    -Integer contact
    -String role

    + Employee(citizenCardNum,taxNum,address,contact)
    - getRole(citizenCardNum)
    +getRequiredFields()
    +setStore(store)
}

class User {
    -String name
    -String email
    -String password

    + User(name, email, password)
    + createWithRandomPassword(name, email)
    + setRole(role)
}

class Agent {
}

class Properties {
    + sortedProperties(option)
}

class Property {
    -Double price
    -Integer area
    -String location
    -Integer distanceFromCity

    +Property(price, area, location, distanceFromCity, photographs)
    +CreateHouse(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment, sunExposure, inhabitableLoft, basement)
    +CreateApartment(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment)
    +CreateLand(price, area, location, distanceFromCity, photographs, typeOfProperty)
    +Building()
    +Land()
    +BusinessType()
    +PropertyType()
    +Photograph()
}

class Land {
    +CreateLand(price, area, location, distanceFromCity, photographs, typeOfProperty)

}

class Building{
    -Integer numBedrooms
    -Integer numBathrooms
    -Integer numParking
    -Boolean centralHeating
    -Boolean airConditioning
    -ArrayList<String> availableEquipment

    +Building (numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, availableEquipment)
    +CreateHouse(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment, sunExposure, inhabitableLoft, basement)
    +CreateApartment(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment)

}

class House {
    -Boolean sunExposure
    -Boolean inhabitableLoft
    -Boolean basement

    +CreateHouse(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment, sunExposure, inhabitableLoft, basement)
}

class Apartment {
    +CreateApartment(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment)
}

class CreatePropertyUI {
}

class CreatePropertyController {
    +CreatePropertyController(propertyRepository)
    +CreateHouse(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment, sunExposure, inhabitableLoft, basement)
    +CreateApartment(price, area, location, distanceFromCity, photographs, typeOfProperty\n,numBedrooms, numBathrooms, numParking, centralHeating, airConditioning, \navailableEquipment)
    +CreateLand(price, area, location, distanceFromCity, photographs, typeOfProperty)
    -getEmployeeFromSession()
}

class ApplicationSession
{
    + static getInstance()
    + getCurrentSession()
}

class UserSession
{
    + getUserEmail()
}

class TypeOfPropertyRepository {
    + getTypeOfProperty()
}

class PropertyType {
    - String name

    + PropertyType(name)
}

class TypeOfBusinessRepository {
    + getTypeOfProperty()
}

class BusinessType {
    - String name

    + BusinessType(name)
}

class Owner {

}

class CreateEmployeeUI {
}

class CreateEmployeeController{
    +CreateEmployeeController()
    +getStores()
    +setStore(designation)
    -saveStore(store)
    +setRoles(roleNames)
    -addToRoles(role)
    -getStore()
    -getRoles()
    +createEmployee(name, passportNumber,\n taxNumber, address, email, contact)
}

class RoleRepository{
 + getRoles()
 + getRoleByName(name)
 - roleWithNameExists(name)
}

class Role{
    - String name
}

class EmployeeRepository{
    +getEmployeeRequiredData()
    +createEmployee(name, passportNumber, taxNumber, address, email, contact)
    -validateNewEmployee()
    +setStoreToEmployee(store, employee)
}

class Address{
    +create(address)
}

class ListPropertiesUI {
}

class ListPropertiesController {
    +ListPropertiesController()
    +getAllTypeProperty()
    +getAllTypeBusiness()
    -getPropertyByTypebusinessTypepropertyNumberrooms(typebusiness, typeproperty, numberrooms, option)
}

note bottom of TypeOfPropertyRepository
    - used for displaying
    the Property type list
end note

note bottom of TypeOfBusinessRepository
    - used for displaying
    the Business type list
end note

note right of ListPropertiesController
    - typebusiness and typeproperty
    are retrieved from selected data
end note

RegisterStoreUI .> RegisterStoreController

RegisterStoreController .> Repositories : repositories


RegisterStoreController ..> StoreRepository : StoreRepository
RegisterStoreController ..> StateRepository : StateRepository

Repositories --> "1" StoreRepository
Repositories --> "1" StateRepository


StoreRepository "1" --> "*" Store
StateRepository "1" --> "*" State
State "1" --> "*" District
District "1" --> "*" City


RegisterStoreController ..> "1" Store : Store
RegisterStoreController ..> "1" District : District
RegisterStoreController ..> "1" State : State


Repositories -> Repositories : instance
Repositories --> "1" UserRepository : userRepository
Repositories --> "1" PropertyRepository : propertyRepository

ApplicationSession -> ApplicationSession : instance
ApplicationSession --> "1" UserSession : userSession
CreatePropertyController ..> ApplicationSession
CreatePropertyController ..> UserSession


CreatePropertyUI .> CreatePropertyController

CreatePropertyController .> Repositories : repositories

UserRepository --> "*" User
PropertyRepository --> "*" Property

Employee "1" --> "1" Agent : is

Property "1" --> "1" Building : is
Building "1" --> "1" House : is
Building "1" --> "1" Apartment : is

Property "1" --> "1" Land : is

CreatePropertyController ..> TypeOfPropertyRepository : TypeOfPropertyRepository
Repositories -> "1" TypeOfPropertyRepository

TypeOfPropertyRepository "1" --> "*" PropertyType : PropertyType

Property "*" --> "1" PropertyType : PropertyType
Repositories -> "1" TypeOfBusinessRepository
CreatePropertyController ..> TypeOfBusinessRepository : TypeOfBusinessRepository

Property "*" --> "1" BusinessType : BusinessType
TypeOfBusinessRepository "1" --> "*" BusinessType : BusinessType

Property --> Owner : createdBy

Store --> "*" Employee : employs
Store --> "*" Property : has

User <|-- Employee
User <|-- Owner

Repositories ----> "1" RoleRepository : roleRepository
Repositories ----> "1" EmployeeRepository : employeeRepository

CreateEmployeeUI .> CreateEmployeeController
CreateEmployeeController .-> Repositories

RoleRepository --> "*" Role

EmployeeRepository --> "*" Employee

Employee "1"  ---> "1" Address: has

User "1"  ---> "0..*" Role: has

ListPropertiesUI .> ListPropertiesController

ListPropertiesController .> Repositories : repositories
ListPropertiesController ..> PropertyRepository : PropertyRepository
PropertyRepository -> "*"Properties: properties

Properties "1"-> "*" Property : properties
@enduml