You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
6.2 KiB
189 lines
6.2 KiB
//
|
|
// CashierDetailView.swift
|
|
// Padel Tournament
|
|
//
|
|
// Created by Razmig Sarkissian on 31/03/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct CashierDetailView: View {
|
|
var tournaments : [Tournament]
|
|
@State private var earnings: Double? = nil
|
|
@State private var paidCompletion: Double? = nil
|
|
|
|
init(tournaments: [Tournament]) {
|
|
self.tournaments = tournaments
|
|
}
|
|
|
|
init(tournament: Tournament) {
|
|
self.tournaments = [tournament]
|
|
}
|
|
|
|
var body: some View {
|
|
List {
|
|
if tournaments.count > 1 {
|
|
Section {
|
|
LabeledContent {
|
|
if let earnings {
|
|
Text(earnings.formatted(.currency(code: Locale.defaultCurrency()).precision(.fractionLength(0))))
|
|
} else {
|
|
ProgressView()
|
|
}
|
|
} label: {
|
|
Text("Encaissement")
|
|
if let paidCompletion {
|
|
Text(paidCompletion.formatted(.percent.precision(.fractionLength(0)))).foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
_tournamentsCashierDetailView(tournaments)
|
|
|
|
} header: {
|
|
Text("Bilan")
|
|
}
|
|
}
|
|
|
|
ForEach(tournaments) { tournament in
|
|
CashierSectionView(tournament: tournament, showTournamentTitle: tournaments.count > 1)
|
|
}
|
|
}
|
|
.headerProminence(.increased)
|
|
.onAppear {
|
|
Task {
|
|
if earnings == nil {
|
|
_getEarnings()
|
|
}
|
|
|
|
if paidCompletion == nil {
|
|
_getPaidCompletion()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private func _getEarnings() {
|
|
earnings = tournaments.map { $0.earnings() }.reduce(0,+)
|
|
}
|
|
|
|
private func _getPaidCompletion() {
|
|
let selectedPlayers = tournaments.flatMap { $0.selectedPlayers() }
|
|
if selectedPlayers.isEmpty {
|
|
paidCompletion = 0
|
|
} else {
|
|
paidCompletion = Double(selectedPlayers.filter { $0.hasPaid() }.count) / Double(selectedPlayers.count)
|
|
}
|
|
}
|
|
|
|
private func _tournamentsCashierDetailView(_ tournaments: [Tournament]) -> some View {
|
|
DisclosureGroup {
|
|
ForEach(PlayerPaymentType.allCases) { type in
|
|
PaymentTypeCashierRowView(tournaments: tournaments, type: type)
|
|
}
|
|
} label: {
|
|
Text("Voir le détail")
|
|
}
|
|
}
|
|
|
|
struct CashierSectionView: View {
|
|
let tournament: Tournament
|
|
let showTournamentTitle: Bool
|
|
@State private var earnings: Double? = nil
|
|
@State private var paidCompletion: Double? = nil
|
|
@State private var presence: Double? = nil
|
|
|
|
var body: some View {
|
|
Section {
|
|
LabeledContent {
|
|
if let earnings {
|
|
Text(earnings.formatted(.currency(code: Locale.defaultCurrency()).precision(.fractionLength(0))))
|
|
} else {
|
|
ProgressView()
|
|
}
|
|
} label: {
|
|
Text(tournament.isFree() ? "Présence" : "Encaissement")
|
|
if tournament.isFree() {
|
|
if let presence {
|
|
Text(presence.formatted(.percent.precision(.fractionLength(0)))).foregroundStyle(.secondary)
|
|
}
|
|
} else {
|
|
if let paidCompletion {
|
|
Text(paidCompletion.formatted(.percent.precision(.fractionLength(0)))).foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
}
|
|
CashierDetailDisclosureView(tournament: tournament)
|
|
} header: {
|
|
if showTournamentTitle {
|
|
Text(tournament.tournamentTitle())
|
|
}
|
|
}
|
|
.onAppear {
|
|
Task {
|
|
if earnings == nil {
|
|
earnings = tournament.earnings()
|
|
}
|
|
|
|
if paidCompletion == nil {
|
|
paidCompletion = tournament.paidCompletion()
|
|
}
|
|
|
|
if presence == nil {
|
|
presence = tournament.presenceStatus()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct PaymentTypeCashierRowView: View {
|
|
let tournaments: [Tournament]
|
|
let type: PlayerPaymentType
|
|
@State private var value: Double?
|
|
|
|
|
|
var body: some View {
|
|
LabeledContent {
|
|
if let value {
|
|
Text(value.formatted(.currency(code: Locale.defaultCurrency())))
|
|
} else {
|
|
ProgressView()
|
|
}
|
|
} label: {
|
|
Text(type.localizedLabel())
|
|
}
|
|
.onAppear {
|
|
Task {
|
|
if value == nil {
|
|
value = tournaments.compactMap({ $0.paidSelectedPlayers(type: type) }).reduce(0,+)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct CashierDetailDisclosureView: View {
|
|
let tournament: Tournament
|
|
|
|
var body: some View {
|
|
DisclosureGroup {
|
|
let selectedPlayers = tournament.selectedPlayers()
|
|
ForEach(PlayerPaymentType.allCases) { type in
|
|
let count = selectedPlayers.filter({ $0.paymentType == type }).count
|
|
if count > 0 {
|
|
LabeledContent {
|
|
if let entryFee = tournament.entryFee {
|
|
let sum = Double(count) * entryFee
|
|
Text(sum.formatted(.currency(code: Locale.defaultCurrency())))
|
|
}
|
|
} label: {
|
|
Text(type.localizedLabel())
|
|
Text(count.formatted())
|
|
}
|
|
}
|
|
}
|
|
} label: {
|
|
Text("Voir le détail")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|