256 lines
13 KiB
Java
256 lines
13 KiB
Java
package fr.titionfire.ffsaf.domain.service;
|
|
|
|
import fr.titionfire.ffsaf.data.model.LicenceModel;
|
|
import fr.titionfire.ffsaf.data.model.LogModel;
|
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
|
import fr.titionfire.ffsaf.data.repository.CombRepository;
|
|
import fr.titionfire.ffsaf.data.repository.LicenceRepository;
|
|
import fr.titionfire.ffsaf.data.repository.SequenceRepository;
|
|
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
|
import fr.titionfire.ffsaf.rest.from.LicenceForm;
|
|
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
|
import fr.titionfire.ffsaf.utils.SequenceType;
|
|
import fr.titionfire.ffsaf.utils.Utils;
|
|
import io.quarkus.hibernate.reactive.panache.Panache;
|
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
|
import io.smallrye.mutiny.Uni;
|
|
import io.smallrye.mutiny.unchecked.Unchecked;
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
import org.hibernate.reactive.mutiny.Mutiny;
|
|
import org.jboss.logging.Logger;
|
|
|
|
import java.util.List;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
|
|
@WithSession
|
|
@ApplicationScoped
|
|
public class LicenceService {
|
|
private static final Logger LOGGER = Logger.getLogger(LicenceService.class);
|
|
|
|
@Inject
|
|
LicenceRepository repository;
|
|
|
|
@Inject
|
|
CombRepository combRepository;
|
|
|
|
@Inject
|
|
SequenceRepository sequenceRepository;
|
|
|
|
@Inject
|
|
KeycloakService keycloakService;
|
|
|
|
@Inject
|
|
LoggerService ls;
|
|
|
|
@Inject
|
|
CheckoutService checkoutService;
|
|
|
|
public Uni<List<LicenceModel>> getLicence(long id, Consumer<MembreModel> checkPerm) {
|
|
return combRepository.findById(id).invoke(checkPerm)
|
|
.chain(combRepository -> Mutiny.fetch(combRepository.getLicences()));
|
|
}
|
|
|
|
public Uni<List<LicenceModel>> getCurrentSaisonLicence(SecurityCtx securityCtx) {
|
|
if (securityCtx == null || securityCtx.getSubject() == null)
|
|
return repository.find("saison = ?1", Utils.getSaison()).list();
|
|
|
|
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult().map(MembreModel::getClub)
|
|
.chain(clubModel -> combRepository.find("club = ?1", clubModel).list())
|
|
.chain(membres -> repository.find("saison = ?1 AND membre IN ?2", Utils.getSaison(), membres).list());
|
|
}
|
|
|
|
public Uni<?> valideLicences(List<Long> ids) {
|
|
Uni<String> uni = Uni.createFrom().nullItem();
|
|
|
|
for (Long id : ids) {
|
|
uni = uni.chain(__ -> repository.find("membre.id = ?1 AND saison = ?2", id, Utils.getSaison()).firstResult()
|
|
.chain(model -> {
|
|
if (!model.isValidate())
|
|
ls.logUpdate("validation de la licence", model);
|
|
return validateLicences(model);
|
|
}))
|
|
.map(__ -> "OK");
|
|
}
|
|
return uni.call(__ -> ls.append());
|
|
}
|
|
|
|
protected Uni<LicenceModel> validateLicences(LicenceModel model) {
|
|
model.setValidate(true);
|
|
return Panache.withTransaction(() -> repository.persist(model)
|
|
.call(m -> Mutiny.fetch(m.getMembre())
|
|
.call(genLicenceNumberAndAccountIfNeed())
|
|
));
|
|
}
|
|
|
|
public Uni<?> validePaymentLicences(List<Long> ids) {
|
|
Uni<String> uni = Uni.createFrom().nullItem();
|
|
|
|
for (Long id : ids) {
|
|
uni = uni.chain(__ -> repository.find("membre.id = ?1 AND saison = ?2", id, Utils.getSaison()).firstResult()
|
|
.chain(model -> {
|
|
if (!model.isPay())
|
|
ls.logUpdate("payment (admin) de la licence", model);
|
|
return validatePayLicences(model);
|
|
}))
|
|
.map(__ -> "OK");
|
|
}
|
|
return uni.call(__ -> ls.append());
|
|
}
|
|
|
|
protected Uni<LicenceModel> validatePayLicences(LicenceModel model) {
|
|
model.setPay(true);
|
|
return Panache.withTransaction(() -> repository.persist(model));
|
|
}
|
|
|
|
public Uni<LicenceModel> setLicence(long id, LicenceForm form) {
|
|
if (form.getId() == -1) {
|
|
return combRepository.findById(id).chain(membreModel -> {
|
|
LicenceModel model = new LicenceModel();
|
|
model.setMembre(membreModel);
|
|
model.setClub_id((membreModel.getClub() == null) ? null : membreModel.getClub().getId());
|
|
model.setSaison(form.getSaison());
|
|
model.setCertificate(form.getCertificate());
|
|
model.setValidate(form.isValidate());
|
|
model.setPay(form.isPay());
|
|
return Panache.withTransaction(() -> repository.persist(model)
|
|
.call(m -> m.isValidate() ? Uni.createFrom().item(membreModel)
|
|
.call(genLicenceNumberAndAccountIfNeed())
|
|
: Uni.createFrom().nullItem()
|
|
))
|
|
.call(licenceModel -> ls.logA(LogModel.ActionType.ADD, membreModel.getObjectName(),
|
|
licenceModel));
|
|
});
|
|
} else {
|
|
return repository.findById(form.getId()).chain(model -> {
|
|
ls.logChange("Certificate", model.getCertificate(), form.getCertificate(), model);
|
|
ls.logChange("Validate", model.isValidate(), form.isValidate(), model);
|
|
ls.logChange("Pay", model.isPay(), form.isPay(), model);
|
|
model.setCertificate(form.getCertificate());
|
|
model.setValidate(form.isValidate());
|
|
model.setPay(form.isPay());
|
|
return Panache.withTransaction(() -> repository.persist(model)
|
|
.call(m -> m.isValidate() ? Mutiny.fetch(m.getMembre())
|
|
.call(genLicenceNumberAndAccountIfNeed())
|
|
: Uni.createFrom().nullItem()
|
|
))
|
|
.call(__ -> ls.append());
|
|
});
|
|
}
|
|
}
|
|
|
|
private Function<MembreModel, Uni<?>> genLicenceNumberAndAccountIfNeed() {
|
|
return membreModel -> ((membreModel.getLicence() == null || membreModel.getLicence() <= 0) ?
|
|
sequenceRepository.getNextValueInTransaction(SequenceType.Licence)
|
|
.invoke(i -> membreModel.setLicence(Math.toIntExact(i)))
|
|
.chain(() -> combRepository.persist(membreModel))
|
|
: Uni.createFrom().nullItem())
|
|
.call(__ -> (membreModel.getUserId() == null) ?
|
|
keycloakService.initCompte(membreModel.getId()).onFailure()
|
|
.invoke(t -> LOGGER.infof("Failed to init account: %s", t.getMessage())).onFailure()
|
|
.recoverWithNull()
|
|
: Uni.createFrom().nullItem());
|
|
}
|
|
|
|
public Uni<String> payLicences(List<Long> ids, Consumer<MembreModel> checkPerm, SecurityCtx securityCtx) {
|
|
return repository.list("membre.id IN ?1 AND saison = ?2 AND pay = FALSE", ids, Utils.getSaison())
|
|
.invoke(Unchecked.consumer(models -> {
|
|
if (models.size() != ids.size())
|
|
throw new DBadRequestException("Erreur lors de la sélection des membres");
|
|
}))
|
|
.call(models -> {
|
|
Uni<?> uni = Uni.createFrom().nullItem();
|
|
for (LicenceModel model : models)
|
|
uni = uni.chain(__ -> Mutiny.fetch(model.getMembre()).invoke(checkPerm));
|
|
return uni;
|
|
})
|
|
.chain(models -> checkoutService.create(models.stream().map(LicenceModel::getId).toList(),
|
|
securityCtx));
|
|
}
|
|
|
|
public Uni<?> deleteLicence(long id) {
|
|
return repository.findById(id)
|
|
.call(__ -> checkoutService.canDeleteLicence(id)
|
|
.invoke(Unchecked.consumer(b -> {
|
|
if (!b) throw new DBadRequestException(
|
|
"Impossible de supprimer une licence pour laquelle un paiement est en cours");
|
|
})))
|
|
.call(model -> ls.logADelete(model))
|
|
.chain(model -> Panache.withTransaction(() -> repository.delete(model)));
|
|
}
|
|
|
|
public Uni<LicenceModel> askLicence(long id, LicenceForm form, Consumer<MembreModel> checkPerm) {
|
|
return combRepository.findById(id).invoke(checkPerm).chain(membreModel -> {
|
|
if (form.getId() == -1) {
|
|
return repository.find("saison = ?1 AND membre = ?2", Utils.getSaison(), membreModel).count()
|
|
.invoke(Unchecked.consumer(count -> {
|
|
if (count > 0)
|
|
throw new DBadRequestException("Licence déjà demandée");
|
|
})).chain(__ -> combRepository.findById(id).chain(membreModel2 -> {
|
|
LicenceModel model = new LicenceModel();
|
|
model.setClub_id((membreModel2.getClub() == null) ? null : membreModel2.getClub().getId());
|
|
model.setMembre(membreModel2);
|
|
model.setSaison(Utils.getSaison());
|
|
model.setCertificate(form.getCertificate());
|
|
model.setValidate(false);
|
|
return Panache.withTransaction(() -> repository.persist(model));
|
|
}))
|
|
.call(licenceModel -> ls.logA(LogModel.ActionType.ADD, membreModel.getObjectName(),
|
|
licenceModel));
|
|
} else {
|
|
return repository.findById(form.getId()).chain(model -> {
|
|
ls.logChange("Certificate", model.getCertificate(), form.getCertificate(), model);
|
|
model.setCertificate(form.getCertificate());
|
|
return Panache.withTransaction(() -> repository.persist(model))
|
|
.call(__ -> ls.append());
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
public Uni<?> deleteAskLicence(long id, Consumer<MembreModel> checkPerm) {
|
|
return repository.findById(id)
|
|
.call(licenceModel -> Mutiny.fetch(licenceModel.getMembre()).invoke(checkPerm))
|
|
.call(__ -> checkoutService.canDeleteLicence(id)
|
|
.invoke(Unchecked.consumer(b -> {
|
|
if (!b) throw new DBadRequestException(
|
|
"Impossible de supprimer une licence pour laquelle un paiement est en cours");
|
|
})))
|
|
.invoke(Unchecked.consumer(licenceModel -> {
|
|
if (licenceModel.isValidate())
|
|
throw new DBadRequestException("Impossible de supprimer une licence déjà validée");
|
|
if (licenceModel.isPay())
|
|
throw new DBadRequestException("Impossible de supprimer une licence déjà payée");
|
|
}))
|
|
.call(model -> ls.logADelete(model))
|
|
.chain(__ -> Panache.withTransaction(() -> repository.deleteById(id)));
|
|
}
|
|
|
|
public Uni<?> setImport(int licence, int saison, boolean valid) {
|
|
return combRepository.find("licence = ?1", licence).firstResult()
|
|
.chain(membreModel ->
|
|
repository.find("saison = ?1 AND membre = ?2", saison, membreModel).firstResult()
|
|
.chain(licenceModel -> {
|
|
if (licenceModel != null) {
|
|
if (licenceModel.getClub_id() == null)
|
|
licenceModel.setClub_id(
|
|
(membreModel.getClub() == null) ? null : membreModel.getClub()
|
|
.getId());
|
|
licenceModel.setValidate(valid);
|
|
return Panache.withTransaction(() -> repository.persist(licenceModel));
|
|
} else {
|
|
LicenceModel model = new LicenceModel();
|
|
model.setClub_id(
|
|
(membreModel.getClub() == null) ? null : membreModel.getClub().getId());
|
|
model.setMembre(membreModel);
|
|
model.setSaison(saison);
|
|
model.setCertificate("¤");
|
|
model.setValidate(valid);
|
|
return Panache.withTransaction(() -> repository.persist(model));
|
|
}
|
|
}))
|
|
.map(__ -> "OK");
|
|
}
|
|
}
|