package org.killbill.billing.jaxrs.resources;
import java.util.List;
import java.util.UUID;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.jaxrs.json.AccountJson;
import org.killbill.billing.jaxrs.json.PaymentMethodJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.payment.api.InvoicePaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PaymentMethod;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
import org.killbill.billing.util.api.TagUserApi;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.clock.Clock;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
public abstract class ComboPaymentResource extends JaxRsResourceBase {
@Inject
public ComboPaymentResource(final JaxrsUriBuilder uriBuilder,
final TagUserApi tagUserApi,
final CustomFieldUserApi customFieldUserApi,
final AuditUserApi auditUserApi,
final AccountUserApi accountUserApi,
final PaymentApi paymentApi,
final InvoicePaymentApi invoicePaymentApi,
final Clock clock,
final Context context) {
super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, paymentApi, invoicePaymentApi, null, clock, context);
}
protected Account getOrCreateAccount(final AccountJson accountJson, final CallContext callContext) throws AccountApiException {
if (accountJson.getAccountId() != null) {
return accountUserApi.getAccountById(accountJson.getAccountId(), callContext);
}
if (accountJson.getExternalKey() != null) {
try {
return accountUserApi.getAccountByKey(accountJson.getExternalKey(), callContext);
} catch (final AccountApiException ignore) {
}
}
return accountUserApi.createAccount(accountJson.toAccount(null), callContext);
}
protected UUID getOrCreatePaymentMethod(final Account account, @Nullable final PaymentMethodJson paymentMethodJson, final Iterable<PluginProperty> pluginProperties, final CallContext callContext) throws PaymentApiException {
if (paymentMethodJson == null || paymentMethodJson.getPluginName() == null) {
return null;
}
final List<PaymentMethod> accountPaymentMethods = paymentApi.getAccountPaymentMethods(account.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
if (paymentMethodJson.getPaymentMethodId() != null) {
final UUID match = paymentMethodJson.getPaymentMethodId();
if (Iterables.any(accountPaymentMethods, new Predicate<PaymentMethod>() {
@Override
public boolean apply(final PaymentMethod input) {
return input.getId().equals(match);
}
})) {
return match;
}
throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, match);
}
if (paymentMethodJson.getExternalKey() != null) {
final PaymentMethod match = Iterables.tryFind(accountPaymentMethods, new Predicate<PaymentMethod>() {
@Override
public boolean apply(final PaymentMethod input) {
return input.getExternalKey().equals(paymentMethodJson.getExternalKey());
}
}).orNull();
if (match != null) {
return match.getId();
}
}
final boolean isDefault = accountPaymentMethods.isEmpty();
final PaymentMethod paymentData = paymentMethodJson.toPaymentMethod(account.getId());
return paymentApi.addPaymentMethod(account, paymentMethodJson.getExternalKey(), paymentMethodJson.getPluginName(), isDefault,
paymentData.getPluginDetail(), pluginProperties, callContext);
}
}