-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow one sponsoring to target multiple teams #264
base: develop
Are you sure you want to change the base?
Conversation
@@ -89,41 +92,49 @@ class SponsoringController(private var sponsoringService: SponsoringService, | |||
@PreAuthorize("isAuthenticated()") | |||
@PostMapping("/event/{eventId}/team/{teamId}/sponsoring/") | |||
@ResponseStatus(CREATED) | |||
fun createSponsoring(@PathVariable teamId: Long, | |||
fun createSponsoring(@PathVariable eventId: Long, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For backwords compatibility, I'd personally like to keep this endpoint. It will accept a sponsoring be created for a single team.
We do have unit tests for it, so just adding a new endpoint in the first place should be the solution.
@@ -201,7 +201,12 @@ class Team : BasicEntity, Blockable { | |||
} | |||
|
|||
private fun Sponsoring.toEmailListing(): String { | |||
return "<b>Name</b> ${this.sponsor?.firstname} ${this.sponsor?.lastname} <b>Status</b> ${this.status} <b>Betrag pro km</b> ${this.amountPerKm.display()} <b>Limit</b> ${this.limit.display()} <b>Gereiste KM</b> ${this.team?.getCurrentDistance()} <b>Spendenversprechen</b> ${this.billableAmount().display()}" | |||
var result = "<b>Name</b> ${this.sponsor?.firstname} ${this.sponsor?.lastname} <b>Status</b> ${this.status} <b>Betrag pro km</b> ${this.amountPerKm.display()} <b>Limit</b> ${this.limit.display()} <b>Spendenversprechen</b> ${this.billableAmount().display()}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to check whether the visualization is correct this way.
We should also add a ticket for HTML encoding the content. Team names can include any HTML which is displayed here...
@@ -118,7 +118,9 @@ class SponsoringInvoice : Invoice { | |||
} | |||
|
|||
private fun Sponsoring.toEmailListing(): String { | |||
return "<b>Team-ID</b> ${this.team?.id} <b>Teamname</b> ${this.team?.name} <b>Status</b> ${this.status} <b>Betrag pro km</b> ${this.amountPerKm.display()} <b>Limit</b> ${this.limit.display()} <b>Gereiste KM</b> ${this.team?.getCurrentDistance()} <b>Spendenversprechen</b> ${this.billableAmount().display()}" | |||
// TODO: implement with teams |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm honestly not sure how this should be correctly implemented.
We need to check who this is sent to? The sponsor? Each team?
Based on this we either list all teams here (if sent to sponsor) or add a team to the function parameters and only show this team's name+id+distance+km+billable amount. And not all other teams they're not interested in.
where s.id is not null or c.id is not null | ||
left join i.sponsorings s | ||
where c.id is not null | ||
and exists (SELECT 1 FROM Sponsoring sp JOIN sp.teams t WHERE sp.id = s.id AND t.id = :teamId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This SQL query is kind of untested. It might also be better to use and s.id IN (SELECT sp.id FROM Sponsoring sp JOIN sp.teams t WHERE sp.id = s.id AND t.id = :teamId)
but my gut told me that exist
might be faster.
@ManyToOne | ||
var team: Team? = null | ||
@ManyToMany | ||
var teams: MutableSet<Team> = HashSet() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I chose a set for now. We might also want to use a list instead. I want to make sure that each team can only be once in there, so a Set felt better as a starting point.
|
||
@ManyToOne(cascade = [PERSIST]) | ||
private var unregisteredSponsor: UnregisteredSponsor? = null | ||
|
||
@ManyToOne | ||
private var registeredSponsor: Sponsor? = null | ||
|
||
@ManyToOne | ||
var event: Event? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is new because the event was initially read from the single team's event field. However, we theoretically might have 0 teams and thus still need to store the event relation somewhere.
@Suppress("UNUSED") //Used by Spring @PreAuthorize | ||
fun checkWithdrawPermissions(username: String): Boolean { | ||
return when { | ||
this.unregisteredSponsor != null -> this.team!!.isMember(username) | ||
this.unregisteredSponsor != null -> this.unregisteredSponsor!!.team?.isMember(username) == true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit unsure whether this is correct. Can the one who created the sponsoring (so unregistedSponsor.team
do this or any of the teams in the teams
collection? Ideally it's the same team anyway.
We need to check this.
@@ -141,8 +153,9 @@ class Sponsoring : BasicEntity, Billable { | |||
} | |||
|
|||
override fun billableAmount(): Money { | |||
|
|||
val distance: Double = team?.getCurrentDistance() ?: run { | |||
val distance: Double = if (teams.isNotEmpty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to implement the billing calculation across multiple teams here.
fun rejectSponsoring(sponsoring: Sponsoring): Sponsoring | ||
|
||
@PreAuthorize("#sponsoring.checkWithdrawPermissions(authentication.name)") | ||
fun withdrawSponsoring(sponsoring: Sponsoring): Sponsoring | ||
|
||
@PreAuthorize("#team.isMember(authentication.name)") | ||
fun createSponsoringWithOfflineSponsor(team: Team, amountPerKm: Money, limit: Money, unregisteredSponsor: UnregisteredSponsor): Sponsoring | ||
@PreAuthorize("#unregisteredSponsor.team.isMember(authentication.name)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to check how this behaves in the real world. Perhaps we might need to check isTeamMember
instead.
@@ -154,7 +154,8 @@ class SponsoringServiceImpl(private val sponsoringRepository: SponsoringReposito | |||
} | |||
|
|||
fun calculateAmount(sponsoring: Sponsoring): Money { | |||
val kilometers = teamService.getDistanceForTeam(sponsoring.team!!.id!!) | |||
// TODO: fix calculation | |||
val kilometers = sponsoring.teams.sumByDouble { it.getCurrentDistance() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check if we need to calculate this on a per team base.
var teamId: Long? = null | ||
|
||
var team: String? = null | ||
var teams: Map<Long, String>? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be adapted in the frontend.
var teamId: Long? = null | ||
|
||
var team: String? = null | ||
var teams: Map<Long, String>? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be adapted in the frontend.
@@ -37,19 +35,19 @@ class SponsoringView() { | |||
|
|||
var billableAmount: Double? = null | |||
|
|||
var teamDistance: Double? = null | |||
var teamsTotalDistance: Double? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure whether the total team distance is enough in here. If we need it on a per team base, we might need to extend the teams
map to not only include the name as the value but also each team's individual distance.
Work in progress