package crmdna.payment2;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.cmd.Query;
import crmdna.client.Client;
import crmdna.common.Utils;
import crmdna.common.api.APIException;
import crmdna.common.api.APIResponse.Status;
import crmdna.sequence.Sequence;
import crmdna.sequence.Sequence.SequenceType;
import crmdna.user.User;
import crmdna.user.User.ClientLevelPrivilege;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static crmdna.common.AssertUtils.ensure;
import static crmdna.common.AssertUtils.ensureNotNull;
import static crmdna.common.OfyService.ofy;
public class Payment {
public static PaymentProp recordPayment(String client, PaymentProp paymentProp, Set<String> tags,
String login) {
Client.ensureValid(client);
User.ensureValidUser(client, login);
ensureNotNull(paymentProp, "paymentProp is null");
ensure(paymentProp.amount != 0, "Amount is 0");
ensureNotNull(paymentProp.currency, "Currency is null");
ensureNotNull(paymentProp.transactionId, "Transaction id is null");
ensureNotNull(paymentProp.paymentType, "Payment type is null");
if ((paymentProp.paymentType == PaymentType.CASH)
|| (paymentProp.paymentType == PaymentType.CHEQUE)) {
ensureNotNull(paymentProp.collectedBy, "Collected by is null");
Utils.ensureValidEmail(paymentProp.collectedBy);
}
if (paymentProp.paymentType == PaymentType.CHEQUE) {
ensureNotNull(paymentProp.chequeNo, "Cheque no should be specified");
ensureNotNull(paymentProp.bank, "Bank should be specified");
}
// TODO: cash and online cannot have chequeNo and bank
if (!paymentProp.collectedBy.equals(login)) {
User.ensureClientLevelPrivilege(client, login, ClientLevelPrivilege.UPDATE_PAYMENT);
}
PaymentEntity entity = new PaymentEntity();
entity.paymentId = Sequence.getNext(client, SequenceType.PAYMENT);
entity.amount = paymentProp.amount;
entity.currency = paymentProp.currency;
entity.paymentType = paymentProp.paymentType;
entity.bank = paymentProp.bank;
entity.chequeNo = paymentProp.chequeNo;
entity.collectedBy = paymentProp.collectedBy;
entity.currency = paymentProp.currency;
entity.ms = paymentProp.date.getTime();
entity.tags = tags;
ofy(client).save().entity(entity).now();
return entity.toProp();
}
public static List<PaymentEntity> query(String client, PaymentQueryCondition qc, String login) {
Client.ensureValid(client);
User.ensureValidUser(client, login);
ensureNotNull(qc, "query condition is null");
Query<PaymentEntity> q = ofy(client).load().type(PaymentEntity.class);
if (qc.currency != null)
q = q.filter("currency", qc.currency);
if (qc.transactionId != null)
q = q.filter("transactionId", qc.transactionId);
if (qc.paymentType != null)
q = q.filter("paymentType", qc.paymentType);
if (qc.chequeNo != null)
q = q.filter("chequeNo", qc.chequeNo);
if (qc.collectedBy != null)
q = q.filter("collectedBy", qc.collectedBy);
if (qc.startDate != null)
q = q.filter("ms >", qc.startDate.getTime());
if (qc.endDate != null)
q = q.filter("ms <", qc.endDate.getTime());
if ((qc.tags != null) && !qc.tags.isEmpty()) {
for (String tag : qc.tags) {
q = q.filter("tags", tag);
}
}
q = q.order("-ms");
List<Key<PaymentEntity>> keys = q.keys().list();
final int MAX_ENTITIES = 5000;
if (keys.size() > MAX_ENTITIES)
throw new APIException("Query condition returns more than 5000 entities")
.status(Status.ERROR_OVERFLOW);
Map<Key<PaymentEntity>, PaymentEntity> map = ofy(client).load().keys(keys);
List<PaymentEntity> entities = new ArrayList<>();
for (Key<PaymentEntity> key : keys) {
entities.add(map.get(key));
}
return entities;
}
public enum PaymentType {
CASH, CHEQUE, ONLINE
}
}