/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
Cyclos is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Cyclos is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package nl.strohalm.cyclos.services.accounts.guarantees;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import nl.strohalm.cyclos.access.AdminMemberPermission;
import nl.strohalm.cyclos.access.MemberPermission;
import nl.strohalm.cyclos.access.OperatorPermission;
import nl.strohalm.cyclos.entities.Relationship;
import nl.strohalm.cyclos.entities.accounts.guarantees.PaymentObligation;
import nl.strohalm.cyclos.entities.accounts.guarantees.PaymentObligation.Status;
import nl.strohalm.cyclos.entities.accounts.guarantees.PaymentObligationQuery;
import nl.strohalm.cyclos.entities.members.Element;
import nl.strohalm.cyclos.entities.members.Member;
import nl.strohalm.cyclos.exceptions.PermissionDeniedException;
import nl.strohalm.cyclos.services.BaseServiceSecurity;
import nl.strohalm.cyclos.utils.RelationshipHelper;
import nl.strohalm.cyclos.utils.access.LoggedUser;
import nl.strohalm.cyclos.utils.access.PermissionHelper;
import org.apache.commons.collections.CollectionUtils;
public class PaymentObligationServiceSecurity extends BaseServiceSecurity implements PaymentObligationService {
private PaymentObligationServiceLocal paymentObligationService;
private GuaranteeServiceLocal guaranteeService;
@Override
public boolean canChangeStatus(final PaymentObligation paymentObligation, final PaymentObligation.Status newStatus) {
checkHasUser();
return paymentObligationService.canChangeStatus(paymentObligation, newStatus);
}
@Override
public boolean canDelete(final PaymentObligation paymentObligation) {
checkHasUser();
return paymentObligationService.canDelete(paymentObligation);
}
@Override
public PaymentObligation changeStatus(final Long paymentObligationId, final PaymentObligation.Status newStatus) {
PaymentObligation paymentObligation = paymentObligationService.load(paymentObligationId, PaymentObligation.Relationships.BUYER);
switch (newStatus) {
case REJECTED:
permissionService.permission(paymentObligation.getSeller())
.member(MemberPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS)
.operator(OperatorPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS)
.check();
break;
default:
permissionService.permission(paymentObligation.getBuyer())
.member(MemberPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS)
.operator(OperatorPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS)
.check();
}
return paymentObligationService.changeStatus(paymentObligationId, newStatus);
}
@Override
public Long[] checkPaymentObligationPeriod(final PaymentObligationPackDTO dto) {
if (!guaranteeService.isSeller()) {
throw new PermissionDeniedException();
}
// ensure each PO
List<PaymentObligation> paymentObligations = paymentObligationService.loadOrderedByExpiration(dto.getPaymentObligations());
if (CollectionUtils.isNotEmpty(paymentObligations)) {
for (PaymentObligation po : paymentObligations) {
if (!LoggedUser.element().equals(po.getSeller())) {
throw new PermissionDeniedException();
}
}
}
return paymentObligationService.checkPaymentObligationPeriod(dto);
}
@Override
public PaymentObligation.Status[] getStatusToFilter() {
if (!guaranteeService.isBuyer() && !guaranteeService.isSeller() && !hasPermission(AdminMemberPermission.GUARANTEES_VIEW_PAYMENT_OBLIGATIONS)) {
throw new PermissionDeniedException();
}
return paymentObligationService.getStatusToFilter();
}
@Override
public PaymentObligation load(final Long id, final Relationship... fetch) {
PaymentObligation po = paymentObligationService.load(id, fetch);
po = fetchService.fetch(po, RelationshipHelper.nested(PaymentObligation.Relationships.BUYER, Element.Relationships.GROUP), RelationshipHelper.nested(PaymentObligation.Relationships.SELLER, Element.Relationships.GROUP));
// if the logged user can issue certifications to the payment obligation's buyer group
// then is an issuer that can view the payment obligation
boolean hasPermission = permissionService.permission()
.memberFor(MemberPermission.GUARANTEES_ISSUE_CERTIFICATIONS, po.getBuyer().getMemberGroup())
.operatorFor(OperatorPermission.GUARANTEES_ISSUE_CERTIFICATIONS, MemberPermission.GUARANTEES_ISSUE_CERTIFICATIONS, po.getBuyer().getMemberGroup())
.hasPermission();
if (hasPermission) {
return po;
}
boolean manages = permissionService.manages(po.getSeller()) || permissionService.manages(po.getBuyer());
if (!manages) {
throw new PermissionDeniedException();
} else {
permissionService.permission()
.admin(AdminMemberPermission.GUARANTEES_VIEW_PAYMENT_OBLIGATIONS)
.member(MemberPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS, MemberPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS)
.operator(OperatorPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS, OperatorPermission.GUARANTEES_SELL_WITH_PAYMENT_OBLIGATIONS)
.check();
}
return po;
}
@Override
public int remove(final Long paymentObligationId) {
PaymentObligation paymentObligation = paymentObligationService.load(paymentObligationId);
if (canDelete(paymentObligation)) {
return paymentObligationService.remove(paymentObligationId);
} else {
throw new PermissionDeniedException();
}
}
@Override
public PaymentObligation save(final PaymentObligation paymentObligation, final boolean validateBeforeSave) {
Member seller = fetchService.fetch(paymentObligation.getSeller(), Element.Relationships.GROUP);
permissionService.permission(paymentObligation.getBuyer())
.memberFor(MemberPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS, seller.getGroup())
.operatorFor(OperatorPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS, MemberPermission.GUARANTEES_BUY_WITH_PAYMENT_OBLIGATIONS, paymentObligation.getSeller().getGroup())
.check();
// Only can modify an obligation payment with REGISTERED status and the status can only be set to REGISTERED.
// Transient payment obligation status is ensured afterwards.
if (!paymentObligation.isTransient()) {
PaymentObligation savedPO = paymentObligationService.load(paymentObligation.getId());
PermissionHelper.checkEquals(Status.REGISTERED, savedPO.getStatus());
PermissionHelper.checkEquals(Status.REGISTERED, paymentObligation.getStatus());
}
// the security must ignore the validate parameter and set true!
return paymentObligationService.save(paymentObligation, true);
}
@Override
public List<PaymentObligation> search(PaymentObligationQuery queryParameters) {
final boolean isSeller = guaranteeService.isSeller();
final boolean isBuyer = guaranteeService.isBuyer();
final boolean adminCanView = hasPermission(AdminMemberPermission.GUARANTEES_VIEW_PAYMENT_OBLIGATIONS);
if (!isBuyer && !isSeller && !adminCanView) {
throw new PermissionDeniedException();
}
if (isBuyer && isSeller) {
queryParameters.setLoggedMember((Member) LoggedUser.accountOwner());
} else if (isBuyer) {
queryParameters.setBuyer((Member) LoggedUser.accountOwner());
} else if (isSeller) {
queryParameters.setSeller((Member) LoggedUser.accountOwner());
final List<PaymentObligation.Status> sellerStatusToFilter = Arrays.asList(paymentObligationService.getSellerStatusToFilter());
if (sellerStatusToFilter.isEmpty()) {
return Collections.emptyList();
} else if (CollectionUtils.isEmpty(queryParameters.getStatusList())) {
queryParameters = (PaymentObligationQuery) queryParameters.clone();
queryParameters.setStatusList(sellerStatusToFilter);
} else { // check valid status selection
for (final PaymentObligation.Status st : queryParameters.getStatusList()) {
if (!sellerStatusToFilter.contains(st)) {
throw new IllegalArgumentException("Payment Obligation status not allowed to filter by: " + st);
}
}
}
} else { // admin can view
queryParameters.setManagedMemberGroups(permissionService.getManagedMemberGroups());
}
return paymentObligationService.search(queryParameters);
}
public void setGuaranteeServiceLocal(final GuaranteeServiceLocal guaranteeService) {
this.guaranteeService = guaranteeService;
}
public void setPaymentObligationServiceLocal(final PaymentObligationServiceLocal paymentObligationService) {
this.paymentObligationService = paymentObligationService;
}
@Override
public void validate(final PaymentObligation paymentObligation) {
paymentObligationService.validate(paymentObligation);
}
}