@startuml
title Class Diagram

class Cinema {
  +MEcrCinema()
  +MEendCinema()
  +MEcrCopyLocation()
  +MEcrOnlineTicket()
  +MEcrSeat()
  +MEcrShow()
  +MEcrTheatre()
  +MEcrTicket()
  +MEendAlternativeOffer()
  +MEendCopyLocation()
  +MEendOnlineTicket()
  +MEendSeat()
  +MEendShow()
  +MEendTheatre()
  +MEendTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +cancelShow()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +publish()
  +refund()
}

class Theatre {
  +MEcrTheatre()
  +MEendTheatre()
  +MEcrOnlineTicket()
  +MEcrSeat()
  +MEcrShow()
  +MEcrTicket()
  +MEendAlternativeOffer()
  +MEendOnlineTicket()
  +MEendSeat()
  +MEendShow()
  +MEendTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +cancelShow()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +publish()
  +refund()
}

class CopyLocation {
  +MEcrCopyLocation()
  +MEendCopyLocation()
  +MEcrOnlineTicket()
  +MEcrShow()
  +MEcrTicket()
  +MEendAlternativeOffer()
  +MEendOnlineTicket()
  +MEendShow()
  +MEendTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +cancelShow()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +publish()
  +refund()
}

class Copy {
  +MEcrCopy()
  +MEendCopy()
  +MEcrCopyLocation()
  +MEcrOnlineTicket()
  +MEcrShow()
  +MEcrTicket()
  +MEendAlternativeOffer()
  +MEendCopyLocation()
  +MEendOnlineTicket()
  +MEendShow()
  +MEendTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +cancelShow()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +publish()
  +refund()
}

class Movie {
  +MEcrMovie()
  +MEendMovie()
  +MEcrCopy()
  +MEcrCopyLocation()
  +MEcrOnlineTicket()
  +MEcrShow()
  +MEcrTicket()
  +MEendAlternativeOffer()
  +MEendCopy()
  +MEendCopyLocation()
  +MEendOnlineTicket()
  +MEendShow()
  +MEendTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +cancelShow()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +publish()
  +refund()
}

class Customer {
  +MEcrCustomer()
  +MEendCustomer()
  +MEcrOnlineTicket()
  +MEendAlternativeOffer()
  +MEendOnlineTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +refund()
}

class Seat {
  +MEcrSeat()
  +MEendSeat()
  +MEcrOnlineTicket()
  +MEcrTicket()
  +MEendAlternativeOffer()
  +MEendOnlineTicket()
  +MEendTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +refund()
}

class Show {
  +MEcrShow()
  +MEendShow()
  +cancelShow()
  +publish()
  +MEcrOnlineTicket()
  +MEcrTicket()
  +MEendAlternativeOffer()
  +MEendOnlineTicket()
  +MEendTicket()
  +accept()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +decline()
  +expire()
  +offer()
  +payReservedTicket()
  +refund()
}

class OnlineTicket {
  +MEcrSeatReservation()
  +MEendSeatReservation()
  +cancelReservationCustomer()
  +cancelReservationKinepolis()
  +payReservedTicket()
  +MEendAlternativeOffer()
  +accept()
  +decline()
  +expire()
  +offer()
  +refund()
}

class AlternativeOffer {
  +MEcrAlternativeOffer()
  +MEendAlternativeOffer()
  +accept()
  +decline()
  +expire()
  +refund()
  +offer()
}

class Ticket {
  +MEcrTicket()
  +MEendTicket()
}

' Structure of the cinemas
Cinema "1" -- "1..*" Theatre : has
Theatre "1" -- "1..*" Seat   : contains
Theatre "1" -- "0..*" Show   : schedules

' Movies, copies and locations
Movie "1" -- "0..*" Copy          : hasCopy
Cinema "1" -- "0..*" CopyLocation : has
Copy  "1" -- "0..*" CopyLocation  : locatedAt
CopyLocation  "1" -- "0..*" Show  : UsedFor


' Reservations and tickets for shows
Show        "1" -- "0..*" OnlineTicket : hasReservations
Show        "1" -- "0..*" Ticket       : hasTickets
Customer    "1" -- "0..*" OnlineTicket : buys
OnlineTicket "0..*" -- "1" Seat           : reservesSeat
Ticket       "0..*" -- "1" Seat           : assignedSeat

' Alternative offers when a show is cancelled
OnlineTicket    "1" -- "0..1" AlternativeOffer : mayLeadTo
AlternativeOffer "0..*" -- "1" Show               : alternativeShow
AlternativeOffer "0..1" -- "1" Seat         : alternativeSeat

@enduml

'===State Diagrams===

@startuml
title AlternativeOfferRole (AlternativeOffer)

[*] --> initial
state exists
ended --> [*]
state accepted
state declined
state refunded

initial --> exists : initialExists / offer
exists --> accepted : existsAccepted / accept
exists --> declined : existsDeclined / decline, expire
accepted --> ended : acceptedEnded / MEendAlternativeOffer
declined --> refunded : declinedRefunded / refund
refunded --> ended : refundedEnded / MEendAlternativeOffer
@enduml

@startuml
title ReservationRole (OnlineTicket)

[*] --> initial
state exists
ended --> [*]
state paid
state cancelledByCustomer
state cancelledByKinepolis
state alternativeOffered

initial --> exists : initialExists / MEcrSeatReservation
exists --> paid : existsPaid / payReservedTicket
exists --> cancelledByCustomer : existsCancelledByCustomer / cancelReservationCustomer
exists --> cancelledByKinepolis : existsCancelledByKinepolis / cancelReservationKinepolis
cancelledByKinepolis --> alternativeOffered : cancelledByKinepolisAlternativeOffered / offer
cancelledByCustomer --> ended : cancelledByCustomerEnded / MEendSeatReservation
alternativeOffered --> ended : alternativeOfferedEnded / MEendSeatReservation
paid --> ended : paidEnded / MEendSeatReservation
alternativeOffered --> alternativeOffered : alternativeOfferedAlternativeOffered / accept, decline, expire, MEendAlternativeOffer, refund
exists --> ended : existsEnded / MEendSeatReservation
@enduml

@startuml
title ShowRole (Show)

[*] --> initial
state exists
ended --> [*]
state published
cancelled --> [*]

initial --> exists : initialExists / MEcrShow
exists --> ended : existsEnded / MEendShow, cancelShow
exists --> published : existsPublished / publish
published --> cancelled : publishedCancelled / cancelShow
published --> ended : publishedEnded / MEendShow
published --> published : publishedPublished / publish, accept, cancelReservationKinepolis, cancelReservationCustomer, MEcrOnlineTicket, MEendOnlineTicket, MEcrTicket, MEendTicket, decline, MEendAlternativeOffer, expire, offer, payReservedTicket
@enduml