@startuml

title US011 Sequence Diagram

autonumber
actor "agent" as A

activate A

participant ":PurchaseOrdersUI" as UI
participant ":PurchaseOrdersController" as CTRL

participant ":Repositories" as REPO
participant "repositories :Repositories" as repo

participant ":PropertyRepository" as propertyREPO
participant "propertyRepo :PropertyRepository" as propertyrepo

participant ":PurchaseOrdersRepository" as poREPO
participant "purchaseOrderRepo :PurchaseOrdersRepository" as porepo

participant " <Service>\nSorting " as sortSERVICE

participant "chosenPurchaseOrder : PurchaseOrder" as cpo
participant "purchaseOrder : PurchaseOrder" as po

participant "EmailSender" as ES

participant ":purchaseOrderList\n List<PurchaseOrder> purchaseOrderList" as purchaseOrderList



A -> UI : Asks to list all purchase orders
activate UI

UI -> CTRL** : create()


UI -> CTRL: getAllPurchaseOrders()
activate CTRL
CTRL -> REPO : getInstance()
activate REPO
REPO --> CTRL : repositories
deactivate REPO
CTRL -> repo : getPropertiesRepository()
activate repo
repo --> CTRL : propertiesRepository
deactivate repo
CTRL -> propertyrepo: getListedProperties()
activate propertyrepo
propertyrepo --> CTRL : listedProperties
deactivate propertyrepo
CTRL --> sortSERVICE ** : create()
CTRL -> sortSERVICE : sortPropertiesByDate(listedProperties)
activate sortSERVICE
sortSERVICE --> CTRL : sortedListedProperties
deactivate sortSERVICE
CTRL -> REPO : getPurchaseOrdersRepository()
activate REPO
REPO --> CTRL : purchaseOrdersRepository
deactivate REPO
loop for each property in listedProperties
CTRL -> porepo : getListOfPendingOrdersByProperty(property)
activate porepo
porepo --> CTRL : listOfPendingOrders
deactivate porepo
CTRL -> sortSERVICE : sortByAmount(listOfPendingOrders)
activate sortSERVICE
sortSERVICE --> CTRL : sortedListOfPendingOrders
deactivate sortSERVICE
end loop
CTRL --> UI :sortedListOfPendingOrders
deactivate CTRL
UI --> A : presents a sorted list of properties with the corresponding pending orders\n and asks the agent to choose one
deactivate UI
alt if sortedListOfPendingOrders is not empty
A -> UI : Selects one
activate UI
UI --> A: Presents the property and it`s order details and asks agent to accept or decline it
deactivate UI

alt if accepted

A -> UI: accepts the order
activate UI
UI -> CTRL : acceptPurchaseOrder(chosenPurchaseOrder)
activate CTRL
CTRL -> cpo : changeToAccepted()
activate cpo
deactivate cpo
CTRL -> cpo : getBuyerEmail()
activate cpo
cpo --> CTRL: email
deactivate cpo
CTRL -> porepo : removeOrderFromList(chosenPurchaseOrder)
activate porepo
deactivate porepo

CTRL -> ES ** : create
CTRL -> ES : notifyBuyerOfSuccess(email)
activate ES
deactivate ES
CTRL -> porepo : getListOfPendingOrdersByProperty(propertyOfTheChosenPurchaseOrder)
activate porepo
porepo --> CTRL : listOfPendingOrders
deactivate porepo
loop for each purchaseOrder in listOfPendingOrders
CTRL -> po: changeToDeclined()
activate po
deactivate po
CTRL -> cpo : getBuyerEmail()
activate cpo
cpo --> CTRL: email
deactivate cpo
CTRL -> ES : notifyBuyerOfFailure(email)
activate ES
deactivate ES
CTRL -> porepo : removeOrderFromList(purchaseOrder)
activate porepo
deactivate porepo
end loop
CTRL --> UI : confirms success of operation
deactivate CTRL
UI --> A : confirms success of operation


deactivate UI




else if declined
A -> UI: declines the order
activate UI
UI -> CTRL : declinePurchaseOrder(chosenPurchaseOrder)
activate CTRL
CTRL -> po: changeToDeclined()
activate po
deactivate po
CTRL -> cpo : getBuyerEmail()
activate cpo
cpo --> CTRL: email
deactivate cpo
CTRL -> ES : notifyBuyerOfFailure(email)
activate ES
deactivate ES
CTRL -> porepo : removeOrderFromList(purchaseOrder)
activate porepo
deactivate porepo
CTRL --> UI : confirms success of operation
deactivate CTRL
UI --> A : confirms success of operation


deactivate UI

end

end

@enduml