/*
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.setup;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import nl.strohalm.cyclos.entities.access.Channel;
import nl.strohalm.cyclos.entities.accounts.AccountLock;
import nl.strohalm.cyclos.entities.accounts.AccountType;
import nl.strohalm.cyclos.entities.accounts.Currency;
import nl.strohalm.cyclos.entities.accounts.MemberAccountType;
import nl.strohalm.cyclos.entities.accounts.MemberGroupAccountSettings;
import nl.strohalm.cyclos.entities.accounts.SystemAccount;
import nl.strohalm.cyclos.entities.accounts.SystemAccountType;
import nl.strohalm.cyclos.entities.accounts.fees.account.AccountFee;
import nl.strohalm.cyclos.entities.accounts.fees.account.AccountFee.InvoiceMode;
import nl.strohalm.cyclos.entities.accounts.fees.account.AccountFee.PaymentDirection;
import nl.strohalm.cyclos.entities.accounts.fees.transaction.BrokerCommission;
import nl.strohalm.cyclos.entities.accounts.fees.transaction.BrokerCommission.When;
import nl.strohalm.cyclos.entities.accounts.fees.transaction.BrokerCommission.WhichBroker;
import nl.strohalm.cyclos.entities.accounts.fees.transaction.SimpleTransactionFee;
import nl.strohalm.cyclos.entities.accounts.fees.transaction.TransactionFee.Subject;
import nl.strohalm.cyclos.entities.accounts.loans.Loan;
import nl.strohalm.cyclos.entities.accounts.loans.LoanParameters;
import nl.strohalm.cyclos.entities.accounts.transactions.PaymentFilter;
import nl.strohalm.cyclos.entities.accounts.transactions.TransferType;
import nl.strohalm.cyclos.entities.accounts.transactions.TransferType.Context;
import nl.strohalm.cyclos.entities.ads.AdCategory;
import nl.strohalm.cyclos.entities.customization.fields.CustomField;
import nl.strohalm.cyclos.entities.customization.fields.CustomFieldPossibleValue;
import nl.strohalm.cyclos.entities.customization.fields.MemberCustomField;
import nl.strohalm.cyclos.entities.customization.fields.MemberCustomField.Indexing;
import nl.strohalm.cyclos.entities.customization.fields.MemberRecordCustomField;
import nl.strohalm.cyclos.entities.customization.fields.PaymentCustomField;
import nl.strohalm.cyclos.entities.customization.fields.Validation;
import nl.strohalm.cyclos.entities.groups.AdminGroup;
import nl.strohalm.cyclos.entities.groups.BrokerGroup;
import nl.strohalm.cyclos.entities.groups.Group;
import nl.strohalm.cyclos.entities.groups.MemberGroup;
import nl.strohalm.cyclos.entities.members.Reference.Level;
import nl.strohalm.cyclos.entities.members.messages.MessageCategory;
import nl.strohalm.cyclos.entities.members.records.MemberRecordType;
import nl.strohalm.cyclos.utils.Amount;
import nl.strohalm.cyclos.utils.TimePeriod;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
/**
* Creates a set of default account related data, as well as other default data. These are the generated account types:
* <ol>
* <li>Debit account</li>
* <li>Community account</li>
* <li>Voucher account</li>
* <li>Organization account</li>
* <li>Member account</li>
* </ol>
* These are the generated transfer types: <li>Debit to community</li> <li>Voucher creation</li> <li>Debit to organization</li> <li>Community to debit
* </li> <li>Community to voucher</li> <li>Community to organization</li> <li>Voucher destruction</li> <li>Voucher to community</li> <li>Voucher to
* organization</li> <li>Organization to debit</li> <li>Organization to community</li> <li>Organization to voucher</li> <li>Trade transfer</li> <li>
* Debit to member</li> <li>Community to member</li> <li>Voucher cashing</li> <li>Organization to member</li> <li>Member to community</li> <li>Voucher
* buying</li> <li>Member to organization</li> <li>Loan repayment</li> <li>Loan</li> <li>Initial credit</li> <li>Money conversion</li> <li>Transaction
* tax payment</li> <li>Broker commission payment</li> <li>Contribution payment</li> <li>Liquidity tax payment</li> <li>Trade transfer from mobile</li>
* <li>External trade transfer</li> </ol>
* @author luis
*/
public class CreateInitialData implements Runnable {
private final ResourceBundle bundle;
private Currency units;
private SystemAccountType community;
private SystemAccountType debit;
private MemberAccountType member;
private SystemAccountType organization;
private final Session session;
private final Map<String, AccountType> systemTypes;
private SystemAccountType voucher;
private TransferType trade;
private TransferType mobileTrade;
private TransferType externalTrade;
private TransferType liquidityTaxPayment;
private TransferType contributionPayment;
private TransferType transactionTaxPayment;
private TransferType brokerCommissionPayment;
private TransferType initialCredit;
private TransferType loan;
private TransferType loanRepayment;
private TransferType moneyConversion;
private Collection<TransferType> systemToSystem;
private Collection<TransferType> systemToMember;
private Collection<TransferType> memberToSystem;
private Collection<TransferType> memberVoucher;
private Collection<TransferType> memberDebit;
private Collection<TransferType> memberCommunity;
private Collection<TransferType> memberOrganization;
private Collection<TransferType> debitCommunity;
private Collection<TransferType> debitOrganization;
private Collection<TransferType> debitVoucher;
private Collection<TransferType> organizationVaucher;
private Collection<TransferType> organizationCommunity;
private Collection<TransferType> communityVaucher;
private AdminGroup systemAdmins;
private AdminGroup accountAdmins;
private MemberGroup fullMembers;
private MemberGroup inactiveMembers;
private MemberGroup demoMembers;
private BrokerGroup fullBrokers;
private Collection<AdminGroup> enabledAdminGroups;
private Collection<MemberGroup> enabledMemberGroups;
public CreateInitialData(final Setup setup) {
session = setup.getSession();
bundle = setup.getBundle();
systemTypes = new LinkedHashMap<String, AccountType>();
}
/**
* CreateInitialData Create an initial database
*/
@Override
public void run() {
Setup.out.println(bundle.getString("initial-data.start"));
session.clear();
systemAdmins = (AdminGroup) session.createCriteria(AdminGroup.class).add(Restrictions.eq("name", bundle.getString("group.system-admins.name"))).uniqueResult();
accountAdmins = (AdminGroup) session.createCriteria(AdminGroup.class).add(Restrictions.eq("name", bundle.getString("group.account-admins.name"))).uniqueResult();
fullMembers = (MemberGroup) session.createCriteria(MemberGroup.class).add(Restrictions.eq("name", bundle.getString("group.full-members.name"))).uniqueResult();
inactiveMembers = (MemberGroup) session.createCriteria(MemberGroup.class).add(Restrictions.eq("name", bundle.getString("group.inactive-members.name"))).uniqueResult();
fullBrokers = (BrokerGroup) session.createCriteria(BrokerGroup.class).add(Restrictions.eq("name", bundle.getString("group.full-brokers.name"))).uniqueResult();
enabledAdminGroups = Arrays.asList(systemAdmins, accountAdmins);
enabledMemberGroups = Arrays.asList(fullMembers, fullBrokers);
createCurrencies();
createSystemAccountTypes();
createMemberAccountTypes();
createSystemAccounts();
createTransferTypes();
createFees();
createAccountFees();
createPaymentFilters();
createMemberAccountSettings();
createExampleAdCategory();
createExampleMessageCategory();
createCustomFields();
createRemarks();
session.flush();
Setup.out.println(bundle.getString("initial-data.end"));
}
private void addPossibleValues(final CustomField field, final String... keys) {
for (final String key : keys) {
final CustomFieldPossibleValue pv = new CustomFieldPossibleValue();
pv.setField(field);
pv.setValue(bundle.getString(key));
session.save(pv);
}
}
private void associateTransferTypeToGroups(final TransferType transferType, final Collection<MemberGroup> memberGroups) {
for (final MemberGroup memberGroup : memberGroups) {
memberGroup.getTransferTypes().add(transferType);
}
}
private void createAccountFees() {
final AccountFee contribution = new AccountFee();
contribution.setName(bundle.getString("tax.contribution.name"));
contribution.setDescription(bundle.getString("tax.contribution.description"));
contribution.setAccountType(member);
contribution.setChargeMode(AccountFee.ChargeMode.FIXED);
contribution.setPaymentDirection(PaymentDirection.TO_SYSTEM);
contribution.setAmount(new BigDecimal(5));
contribution.setRunMode(AccountFee.RunMode.SCHEDULED);
contribution.setRecurrence(new TimePeriod(1, TimePeriod.Field.MONTHS));
contribution.setEnabled(false);
contribution.setDay((byte) 1);
contribution.setHour((byte) 3);
contribution.setInvoiceMode(InvoiceMode.NOT_ENOUGH_CREDITS);
contribution.setTransferType(contributionPayment);
contribution.setGroups(new HashSet<MemberGroup>(enabledMemberGroups));
session.save(contribution);
final AccountFee liquidity = new AccountFee();
liquidity.setName(bundle.getString("tax.liquidity.name"));
liquidity.setDescription(bundle.getString("tax.liquidity.description"));
liquidity.setAccountType(member);
liquidity.setChargeMode(AccountFee.ChargeMode.VOLUME_PERCENTAGE);
liquidity.setPaymentDirection(PaymentDirection.TO_SYSTEM);
liquidity.setAmount(new BigDecimal(1));
liquidity.setRunMode(AccountFee.RunMode.SCHEDULED);
liquidity.setRecurrence(new TimePeriod(1, TimePeriod.Field.MONTHS));
liquidity.setEnabled(false);
liquidity.setDay((byte) 1);
liquidity.setHour((byte) 1);
liquidity.setInvoiceMode(InvoiceMode.NEVER);
liquidity.setTransferType(liquidityTaxPayment);
liquidity.setGroups(new HashSet<MemberGroup>(enabledMemberGroups));
session.save(liquidity);
}
private void createCurrencies() {
units = new Currency();
units.setName("Units");
units.setPattern("#amount# units");
units.setSymbol("units");
session.save(units);
}
private void createCustomFields() {
final Collection<MemberGroup> memberGroups = Arrays.asList(fullMembers, demoMembers, inactiveMembers, fullBrokers);
// Birthday
final MemberCustomField birthday = new MemberCustomField();
birthday.setName(bundle.getString("field.birthday"));
birthday.setInternalName("birthday");
birthday.setControl(CustomField.Control.TEXT);
birthday.setSize(CustomField.Size.SMALL);
birthday.setType(CustomField.Type.DATE);
birthday.setMemberCanHide(true);
birthday.setOrder(0);
birthday.setIndexing(Indexing.NONE);
birthday.setShowInPrint(true);
birthday.setGroups(new ArrayList<MemberGroup>(memberGroups));
session.save(birthday);
// Gender
final MemberCustomField gender = new MemberCustomField();
gender.setName(bundle.getString("field.gender"));
gender.setInternalName("gender");
gender.setControl(CustomField.Control.RADIO);
gender.setSize(CustomField.Size.LARGE);
gender.setType(CustomField.Type.ENUMERATED);
gender.setMemberCanHide(true);
gender.setOrder(1);
gender.setShowInPrint(true);
gender.setGroups(new ArrayList<MemberGroup>(memberGroups));
gender.setIndexing(Indexing.NONE);
session.save(gender);
addPossibleValues(gender, "field.gender.male", "field.gender.female");
// Address
final MemberCustomField address = new MemberCustomField();
address.setName(bundle.getString("field.address"));
address.setInternalName("address");
address.setControl(CustomField.Control.TEXT);
address.setSize(CustomField.Size.LARGE);
address.setType(CustomField.Type.STRING);
address.setMemberCanHide(true);
address.setOrder(2);
address.setIndexing(Indexing.MEMBERS_AND_ADS);
address.setGroups(new ArrayList<MemberGroup>(memberGroups));
session.save(address);
// Postal code
final MemberCustomField postalCode = new MemberCustomField();
postalCode.setName(bundle.getString("field.postalCode"));
postalCode.setInternalName("postalCode");
postalCode.setControl(CustomField.Control.TEXT);
postalCode.setSize(CustomField.Size.LARGE);
postalCode.setType(CustomField.Type.STRING);
postalCode.setMemberCanHide(true);
postalCode.setOrder(3);
postalCode.setIndexing(Indexing.NONE);
postalCode.setGroups(new ArrayList<MemberGroup>(memberGroups));
session.save(postalCode);
// City
final MemberCustomField city = new MemberCustomField();
city.setName(bundle.getString("field.city"));
city.setInternalName("city");
city.setControl(CustomField.Control.TEXT);
city.setSize(CustomField.Size.LARGE);
city.setType(CustomField.Type.STRING);
city.setMemberCanHide(true);
city.setOrder(4);
city.setIndexing(Indexing.MEMBERS_AND_ADS);
city.setGroups(new ArrayList<MemberGroup>(memberGroups));
session.save(city);
// Area
final MemberCustomField area = new MemberCustomField();
area.setName(bundle.getString("field.area"));
area.setInternalName("area");
area.setControl(CustomField.Control.SELECT);
area.setType(CustomField.Type.ENUMERATED);
area.setMemberCanHide(true);
area.setOrder(5);
area.setGroups(new ArrayList<MemberGroup>(memberGroups));
area.setIndexing(Indexing.MEMBERS_AND_ADS);
session.save(area);
addPossibleValues(area, "area.name");
// Phone
final MemberCustomField phone = new MemberCustomField();
phone.setName(bundle.getString("field.phone"));
phone.setInternalName("phone");
phone.setControl(CustomField.Control.TEXT);
phone.setSize(CustomField.Size.LARGE);
phone.setType(CustomField.Type.STRING);
phone.setMemberCanHide(true);
phone.setOrder(6);
phone.setIndexing(Indexing.NONE);
phone.setGroups(new ArrayList<MemberGroup>(memberGroups));
session.save(phone);
// Mobile phone
final MemberCustomField mobilePhone = new MemberCustomField();
mobilePhone.setName(bundle.getString("field.mobilePhone"));
mobilePhone.setInternalName("mobilePhone");
mobilePhone.setControl(CustomField.Control.TEXT);
mobilePhone.setSize(CustomField.Size.LARGE);
mobilePhone.setType(CustomField.Type.STRING);
mobilePhone.setMemberCanHide(true);
mobilePhone.setOrder(7);
mobilePhone.setIndexing(Indexing.NONE);
mobilePhone.setGroups(new ArrayList<MemberGroup>(memberGroups));
mobilePhone.setValidation(new Validation(false, true));
session.save(mobilePhone);
// Fax
final MemberCustomField fax = new MemberCustomField();
fax.setName(bundle.getString("field.fax"));
fax.setInternalName("fax");
fax.setControl(CustomField.Control.TEXT);
fax.setSize(CustomField.Size.LARGE);
fax.setType(CustomField.Type.STRING);
fax.setMemberCanHide(true);
fax.setOrder(8);
fax.setIndexing(Indexing.NONE);
fax.setGroups(new ArrayList<MemberGroup>(memberGroups));
session.save(fax);
// URL
final MemberCustomField url = new MemberCustomField();
url.setName(bundle.getString("field.url"));
url.setInternalName("url");
url.setControl(CustomField.Control.TEXT);
url.setSize(CustomField.Size.LARGE);
url.setType(CustomField.Type.URL);
url.setMemberCanHide(true);
url.setOrder(9);
url.setIndexing(Indexing.NONE);
url.setGroups(new ArrayList<MemberGroup>(memberGroups));
session.save(url);
// Loan identifier
final PaymentCustomField loanIdentifier = new PaymentCustomField();
loanIdentifier.setTransferType(loan);
loanIdentifier.setName(bundle.getString("field.loanIdentifier"));
loanIdentifier.setInternalName("identifier");
loanIdentifier.setControl(CustomField.Control.TEXT);
loanIdentifier.setSize(CustomField.Size.SMALL);
loanIdentifier.setType(CustomField.Type.STRING);
loanIdentifier.setSearchAccess(PaymentCustomField.Access.FROM_ACCOUNT);
loanIdentifier.setOrder(0);
session.save(loanIdentifier);
}
/**
* Create some example category
*/
private void createExampleAdCategory() {
final AdCategory category = new AdCategory();
category.setActive(true);
category.setName(bundle.getString("ad-category.name"));
session.save(category);
}
/**
* Create some message categories
*/
private void createExampleMessageCategory() {
final List<MessageCategory> allCategories = new ArrayList<MessageCategory>();
final MessageCategory support = new MessageCategory();
support.setName(bundle.getString("message-category.support.name"));
session.save(support);
allCategories.add(support);
final MessageCategory administration = new MessageCategory();
administration.setName(bundle.getString("message-category.administration.name"));
session.save(administration);
allCategories.add(administration);
final MessageCategory loanRequest = new MessageCategory();
loanRequest.setName(bundle.getString("message-category.loan-request.name"));
session.save(loanRequest);
allCategories.add(loanRequest);
systemAdmins.setMessageCategories(new ArrayList<MessageCategory>(allCategories));
accountAdmins.setMessageCategories(new ArrayList<MessageCategory>(allCategories));
fullMembers.setMessageCategories(new ArrayList<MessageCategory>(allCategories));
fullBrokers.setMessageCategories(new ArrayList<MessageCategory>(allCategories));
}
private void createFees() {
final SimpleTransactionFee transactionTax = new SimpleTransactionFee();
transactionTax.setName(bundle.getString("fee.transaction-tax.name"));
transactionTax.setDescription(bundle.getString("fee.transaction-tax.description"));
transactionTax.setOriginalTransferType(trade);
transactionTax.setGeneratedTransferType(transactionTaxPayment);
transactionTax.setAmount(Amount.fixed(new BigDecimal(5)));
transactionTax.setEnabled(false);
transactionTax.setPayer(Subject.SOURCE);
transactionTax.setReceiver(Subject.SYSTEM);
session.save(transactionTax);
final BrokerCommission brokerCommission = new BrokerCommission();
brokerCommission.setName(bundle.getString("fee.broker-commission.name"));
brokerCommission.setDescription(bundle.getString("fee.broker-commission.description"));
brokerCommission.setOriginalTransferType(trade);
brokerCommission.setGeneratedTransferType(brokerCommissionPayment);
brokerCommission.setAmount(Amount.percentage(new BigDecimal(2.5F)));
brokerCommission.setEnabled(false);
brokerCommission.setPayer(Subject.SYSTEM);
brokerCommission.setWhichBroker(WhichBroker.SOURCE);
brokerCommission.setWhen(When.COUNT);
brokerCommission.setCount(20);
session.save(brokerCommission);
}
private void createMemberAccountSettings() {
MemberGroupAccountSettings mgas = new MemberGroupAccountSettings();
for (final MemberGroup group : enabledMemberGroups) {
mgas = new MemberGroupAccountSettings();
mgas.setAccountType(member);
mgas.setDefault(true);
mgas.setDefaultCreditLimit(BigDecimal.ZERO);
mgas.setGroup(group);
mgas.setInitialCreditTransferType(initialCredit);
mgas.setInitialCredit(BigDecimal.ZERO);
mgas.setLowUnits(new BigDecimal(20));
mgas.setLowUnitsMessage(bundle.getString("account.member.low-units"));
session.save(mgas);
}
}
private void createMemberAccountTypes() {
member = new MemberAccountType();
member.setCurrency(units);
member.setName(bundle.getString("account.member.name"));
member.setDescription(bundle.getString("account.member.description"));
session.save(member);
}
@SuppressWarnings("unchecked")
private void createPaymentFilter(final AccountType accountType, final String key, final Object... arguments) {
final PaymentFilter filter = new PaymentFilter();
filter.setAccountType(accountType);
final String name = bundle.getString("payment-filter." + key);
filter.setName(name);
filter.setDescription(name);
filter.setShowInAccountHistory(true);
filter.setShowInReports(true);
final Collection<TransferType> transferTypes = new HashSet<TransferType>();
for (Object object : arguments) {
if (object instanceof TransferType) {
transferTypes.add((TransferType) object);
} else if (object instanceof Collection) {
transferTypes.addAll((Collection<TransferType>) object);
} else {
throw new IllegalArgumentException("Invalid argument passed to createPaymentFilter: " + object);
}
}
filter.setTransferTypes(transferTypes);
final Collection<Group> groups = new HashSet<Group>();
if (accountType instanceof SystemAccountType) {
groups.addAll(enabledAdminGroups);
} else {
groups.addAll(enabledMemberGroups);
}
filter.setGroups(groups);
session.save(filter);
}
private void createPaymentFilters() {
createPaymentFilter(member, "member-payments", trade, mobileTrade, externalTrade);
createPaymentFilter(member, "member-loans", loan, loanRepayment);
createPaymentFilter(member, "member-fees", liquidityTaxPayment, contributionPayment, transactionTaxPayment);
createPaymentFilter(member, "member-commission", brokerCommissionPayment);
createPaymentFilter(member, "member-voucher", memberVoucher);
createPaymentFilter(member, "member-system", memberToSystem);
createPaymentFilter(debit, "debit-community", debitCommunity);
createPaymentFilter(debit, "debit-voucher", debitVoucher);
createPaymentFilter(debit, "debit-organization", debitOrganization);
createPaymentFilter(debit, "debit-member", memberDebit);
createPaymentFilter(community, "community-voucher", communityVaucher);
createPaymentFilter(community, "community-debit", debitCommunity);
createPaymentFilter(community, "community-organization", organizationCommunity);
createPaymentFilter(community, "community-contribution", contributionPayment);
createPaymentFilter(community, "community-liquidity", liquidityTaxPayment);
createPaymentFilter(community, "community-broker", brokerCommissionPayment);
createPaymentFilter(community, "community-loan", loan, loanRepayment);
createPaymentFilter(community, "community-member", memberCommunity);
createPaymentFilter(voucher, "voucher-debit", debitVoucher);
createPaymentFilter(voucher, "voucher-community", communityVaucher);
createPaymentFilter(voucher, "voucher-organization", organizationVaucher);
createPaymentFilter(voucher, "voucher-member", memberVoucher);
createPaymentFilter(organization, "organization-debit", debitOrganization);
createPaymentFilter(organization, "organization-community", organizationCommunity);
createPaymentFilter(organization, "organization-voucher", organizationVaucher);
createPaymentFilter(organization, "organization-member", memberOrganization);
}
@SuppressWarnings("unchecked")
private MemberRecordType createRemarks() {
final Collection<Group> allGroups = session.createCriteria(Group.class).list();
// Create member record type "remarks"
final MemberRecordType memberRecordType = new MemberRecordType();
memberRecordType.setName(bundle.getString("remarks.name"));
memberRecordType.setLabel(bundle.getString("remarks.label"));
memberRecordType.setDescription(bundle.getString("remarks.description"));
memberRecordType.setGroups(allGroups);
memberRecordType.setViewableByAdminGroups(enabledAdminGroups);
memberRecordType.setViewableByBrokerGroups(Collections.singletonList(fullBrokers));
memberRecordType.setLayout(MemberRecordType.Layout.FLAT);
memberRecordType.setShowMenuItem(true);
session.save(memberRecordType);
// Add permissions to administrators groups (system and account) and full brokers group
systemAdmins.getViewAdminRecordTypes().add(memberRecordType);
systemAdmins.getCreateAdminRecordTypes().add(memberRecordType);
systemAdmins.getViewMemberRecordTypes().add(memberRecordType);
systemAdmins.getCreateMemberRecordTypes().add(memberRecordType);
accountAdmins.getViewMemberRecordTypes().add(memberRecordType);
accountAdmins.getCreateMemberRecordTypes().add(memberRecordType);
fullBrokers.getBrokerMemberRecordTypes().add(memberRecordType);
fullBrokers.getBrokerCreateMemberRecordTypes().add(memberRecordType);
// Create custom field "comments" for the type "remarks"
final MemberRecordCustomField commentsField = new MemberRecordCustomField();
commentsField.setName(bundle.getString("remarks.comments"));
commentsField.setInternalName(bundle.getString("remarks.comments.internalName"));
commentsField.setDescription(bundle.getString("remarks.comments.description"));
commentsField.setType(CustomField.Type.STRING);
commentsField.setControl(CustomField.Control.TEXTAREA);
commentsField.setSize(CustomField.Size.FULL);
commentsField.setShowInList(true);
commentsField.setValidation(new Validation(true));
commentsField.setOrder(0);
commentsField.setMemberRecordType(memberRecordType);
commentsField.setBrokerAccess(MemberRecordCustomField.Access.EDITABLE);
session.save(commentsField);
return memberRecordType;
}
private SystemAccount createSystemAccount(final SystemAccountType type) {
// Save the account
final SystemAccount account = new SystemAccount();
account.setCreditLimit(type.getCreditLimit());
account.setCreationDate(Calendar.getInstance());
account.setType(type);
account.setOwnerName(type.getName());
session.save(account);
// Save the account lock
session.save(new AccountLock(account));
type.setAccount(account);
return account;
}
private void createSystemAccounts() {
createSystemAccount(debit);
createSystemAccount(community);
createSystemAccount(voucher);
createSystemAccount(organization);
}
@SuppressWarnings("unchecked")
private void createSystemAccountTypes() {
debit = new SystemAccountType();
debit.setCreditLimit(null);
debit.setName(bundle.getString("account.debit.name"));
debit.setDescription(bundle.getString("account.debit.description"));
debit.setCurrency(units);
session.save(debit);
systemTypes.put("debit", debit);
community = new SystemAccountType();
community.setCurrency(units);
community.setName(bundle.getString("account.community.name"));
community.setDescription(bundle.getString("account.community.description"));
community.setCreditLimit(BigDecimal.ZERO);
session.save(community);
systemTypes.put("community", community);
voucher = new SystemAccountType();
voucher.setCurrency(units);
voucher.setName(bundle.getString("account.voucher.name"));
voucher.setDescription(bundle.getString("account.voucher.description"));
voucher.setCreditLimit(BigDecimal.ZERO);
session.save(voucher);
systemTypes.put("voucher", voucher);
organization = new SystemAccountType();
organization.setCurrency(units);
organization.setName(bundle.getString("account.organization.name"));
organization.setDescription(bundle.getString("account.organization.description"));
organization.setCreditLimit(BigDecimal.ZERO);
session.save(organization);
systemTypes.put("organization", organization);
// Allow the adminstrator group to view all system account types
final List<SystemAccountType> allSystemAccountTypes = session.createCriteria(SystemAccountType.class).list();
systemAdmins.setViewInformationOf(new ArrayList<SystemAccountType>(allSystemAccountTypes));
accountAdmins.setViewInformationOf(new ArrayList<SystemAccountType>(allSystemAccountTypes));
}
private void createTransferTypes() {
final Channel web = (Channel) session.createCriteria(Channel.class).add(Restrictions.eq("internalName", Channel.WEB)).uniqueResult();
memberDebit = new ArrayList<TransferType>();
memberCommunity = new ArrayList<TransferType>();
memberOrganization = new ArrayList<TransferType>();
memberVoucher = new ArrayList<TransferType>();
debitCommunity = new ArrayList<TransferType>();
debitOrganization = new ArrayList<TransferType>();
debitVoucher = new ArrayList<TransferType>();
organizationVaucher = new ArrayList<TransferType>();
organizationCommunity = new ArrayList<TransferType>();
communityVaucher = new ArrayList<TransferType>();
// Insert all combinations of from-to between system accounts
systemToSystem = new ArrayList<TransferType>();
for (final Map.Entry<String, AccountType> fromEntry : systemTypes.entrySet()) {
final String fromName = fromEntry.getKey();
final AccountType from = fromEntry.getValue();
for (final Map.Entry<String, AccountType> toEntry : systemTypes.entrySet()) {
final String toName = toEntry.getKey();
final AccountType to = toEntry.getValue();
if (from.equals(to)) {
// Ignore the same from and to
continue;
}
final TransferType tt = new TransferType();
tt.setName(bundle.getString("transfer-type." + fromName + "-" + toName + ".name"));
tt.setDescription(bundle.getString("transfer-type." + fromName + "-" + toName + ".description"));
tt.getContext().setSelfPayment(true);
tt.setFrom(from);
tt.setTo(to);
session.save(tt);
systemAdmins.getTransferTypes().add(tt);
systemToSystem.add(tt);
if ((from == debit && to == community) || (from == community && to == debit)) {
debitCommunity.add(tt);
} else if ((from == debit && to == voucher) || (from == voucher && to == debit)) {
debitVoucher.add(tt);
} else if ((from == debit && to == organization) || (from == organization && to == debit)) {
debitOrganization.add(tt);
} else if ((from == organization && to == voucher) || (from == voucher && to == organization)) {
organizationVaucher.add(tt);
} else if ((from == organization && to == community) || (from == community && to == organization)) {
organizationCommunity.add(tt);
} else if ((from == community && to == voucher) || (from == voucher && to == community)) {
communityVaucher.add(tt);
}
}
}
// Insert the trade transfer
trade = new TransferType();
trade.setName(bundle.getString("transfer-type.trade.name"));
trade.setDescription(bundle.getString("transfer-type.trade.description"));
trade.getContext().setPayment(true);
trade.setFrom(member);
trade.setTo(member);
trade.setMaxAmountPerDay(new BigDecimal(1000));
trade.setChannels(Collections.singletonList(web));
trade.setAllowsScheduledPayments(true);
setFeedbackParameters(trade);
session.save(trade);
associateTransferTypeToGroups(trade, enabledMemberGroups);
// Insert all combinations of from:system / to:member
systemToMember = new ArrayList<TransferType>();
for (final Map.Entry<String, AccountType> entry : systemTypes.entrySet()) {
final String name = entry.getKey();
final AccountType from = entry.getValue();
final TransferType tt = new TransferType();
tt.setName(bundle.getString("transfer-type." + name + "-member.name"));
tt.setDescription(bundle.getString("transfer-type." + name + "-member.description"));
tt.getContext().setPayment(true);
tt.setFrom(from);
tt.setTo(member);
tt.setChannels(Collections.singletonList(web));
session.save(tt);
systemAdmins.getTransferTypes().add(tt);
systemToMember.add(tt);
if (from == debit) {
memberDebit.add(tt);
} else if (from == community) {
memberCommunity.add(tt);
} else if (from == organization) {
memberOrganization.add(tt);
} else if (from == voucher) {
memberVoucher.add(tt);
}
}
// Insert types from member to voucher, community and organization (no direct payment to debit)
final Map<String, AccountType> toSystem = new LinkedHashMap<String, AccountType>(systemTypes);
toSystem.remove("debit");
memberToSystem = new ArrayList<TransferType>();
for (final Map.Entry<String, AccountType> entry : toSystem.entrySet()) {
final String name = entry.getKey();
final AccountType to = entry.getValue();
final TransferType tt = new TransferType();
tt.setName(bundle.getString("transfer-type.member-" + name + ".name"));
tt.setDescription(bundle.getString("transfer-type.member-" + name + ".description"));
tt.getContext().setPayment(true);
tt.setFrom(member);
tt.setTo(to);
tt.setChannels(Collections.singletonList(web));
session.save(tt);
associateTransferTypeToGroups(tt, enabledMemberGroups);
memberToSystem.add(tt);
if (to == community) {
memberCommunity.add(tt);
} else if (to == organization) {
memberOrganization.add(tt);
} else if (to == voucher) {
memberVoucher.add(tt);
}
}
// Insert the loan repayment and grant
loanRepayment = new TransferType();
loanRepayment.setName(bundle.getString("transfer-type.loan-repayment.name"));
loanRepayment.setDescription(bundle.getString("transfer-type.loan-repayment.description"));
loanRepayment.setFrom(member);
loanRepayment.setTo(debit);
session.save(loanRepayment);
loan = new TransferType();
loan.setName(bundle.getString("transfer-type.loan.name"));
loan.setDescription(bundle.getString("transfer-type.loan.description"));
loan.setFrom(debit);
loan.setTo(member);
loan.setContext(Context.payment());
final LoanParameters loanParameters = new LoanParameters();
loan.setLoan(loanParameters);
loanParameters.setType(Loan.Type.SINGLE_PAYMENT);
loanParameters.setRepaymentType(loanRepayment);
loanParameters.setRepaymentDays(30);
session.save(loan);
systemAdmins.getTransferTypes().add(loan);
memberDebit.add(loan);
// Add the initial credit
initialCredit = new TransferType();
initialCredit.setName(bundle.getString("transfer-type.initial-credit.name"));
initialCredit.setDescription(bundle.getString("transfer-type.initial-credit.description"));
initialCredit.setFrom(debit);
initialCredit.setTo(member);
session.save(initialCredit);
memberDebit.add(initialCredit);
// Add the money conversion
moneyConversion = new TransferType();
moneyConversion.setName(bundle.getString("transfer-type.money-conversion.name"));
moneyConversion.setDescription(bundle.getString("transfer-type.money-conversion.description"));
moneyConversion.setFrom(debit);
moneyConversion.setTo(member);
moneyConversion.getContext().setPayment(true);
session.save(moneyConversion);
systemAdmins.getTransferTypes().add(moneyConversion);
// Add the transaction tax payment
transactionTaxPayment = new TransferType();
transactionTaxPayment.setName(bundle.getString("transfer-type.transaction-tax-payment.name"));
transactionTaxPayment.setDescription(bundle.getString("transfer-type.transaction-tax-payment.description"));
transactionTaxPayment.setFrom(member);
transactionTaxPayment.setTo(community);
session.save(transactionTaxPayment);
// Add the broker commission payment
brokerCommissionPayment = new TransferType();
brokerCommissionPayment.setName(bundle.getString("transfer-type.broker-commission-payment.name"));
brokerCommissionPayment.setDescription(bundle.getString("transfer-type.broker-commission-payment.description"));
brokerCommissionPayment.setFrom(community);
brokerCommissionPayment.setTo(member);
session.save(brokerCommissionPayment);
// Insert the contribution payment
contributionPayment = new TransferType();
contributionPayment.setName(bundle.getString("transfer-type.contribution-payment.name"));
contributionPayment.setDescription(bundle.getString("transfer-type.contribution-payment.description"));
contributionPayment.setFrom(member);
contributionPayment.setTo(community);
session.save(contributionPayment);
// Insert the liquidity tax payment
liquidityTaxPayment = new TransferType();
liquidityTaxPayment.setName(bundle.getString("transfer-type.liquidity-tax-payment.name"));
liquidityTaxPayment.setDescription(bundle.getString("transfer-type.liquidity-tax-payment.description"));
liquidityTaxPayment.setFrom(member);
liquidityTaxPayment.setTo(community);
session.save(liquidityTaxPayment);
// Get mobile channels
final Channel restChannel = (Channel) session.createCriteria(Channel.class).add(Restrictions.eq("internalName", Channel.REST)).uniqueResult();
final Channel wap2Channel = (Channel) session.createCriteria(Channel.class).add(Restrictions.eq("internalName", Channel.WAP2)).uniqueResult();
final Channel wap1Channel = (Channel) session.createCriteria(Channel.class).add(Restrictions.eq("internalName", Channel.WAP1)).uniqueResult();
final List<Channel> mobileChannels = new ArrayList<Channel>();
mobileChannels.add(restChannel);
mobileChannels.add(wap2Channel);
mobileChannels.add(wap1Channel);
// Add the mobile trade transfer
mobileTrade = new TransferType();
mobileTrade.setName(bundle.getString("transfer-type.mobile-trade.name"));
mobileTrade.setDescription(bundle.getString("transfer-type.mobile-trade.description"));
mobileTrade.setFrom(member);
mobileTrade.setTo(member);
mobileTrade.getContext().setPayment(true);
mobileTrade.setChannels(mobileChannels);
mobileTrade.setMaxAmountPerDay(new BigDecimal(500));
mobileTrade.setGroups(new HashSet<Group>(enabledMemberGroups));
setFeedbackParameters(mobileTrade);
session.save(mobileTrade);
associateTransferTypeToGroups(mobileTrade, enabledMemberGroups);
// Add the external trade transfer
final Channel poswebChannel = (Channel) session.createCriteria(Channel.class).add(Restrictions.eq("internalName", Channel.POSWEB)).uniqueResult();
final Channel webshopChannel = (Channel) session.createCriteria(Channel.class).add(Restrictions.eq("internalName", Channel.WEBSHOP)).uniqueResult();
final List<Channel> externalTradeTransferChannels = Arrays.asList(webshopChannel, poswebChannel);
externalTrade = new TransferType();
externalTrade.setName(bundle.getString("transfer-type.external-trade.name"));
externalTrade.setDescription(bundle.getString("transfer-type.external-trade.description"));
externalTrade.setFrom(member);
externalTrade.setTo(member);
externalTrade.setChannels(externalTradeTransferChannels);
externalTrade.getContext().setPayment(true);
externalTrade.setMaxAmountPerDay(new BigDecimal(500));
externalTrade.setGroups(new HashSet<Group>(enabledMemberGroups));
session.save(externalTrade);
associateTransferTypeToGroups(externalTrade, enabledMemberGroups);
}
private void setFeedbackParameters(final TransferType transferType) {
transferType.setRequiresFeedback(true);
transferType.setDefaultFeedbackComments(bundle.getString("transfer-type.feedback.default-comments"));
transferType.setDefaultFeedbackLevel(Level.NEUTRAL);
transferType.setFeedbackEnabledSince(Calendar.getInstance());
transferType.setFeedbackExpirationTime(new TimePeriod(2, TimePeriod.Field.WEEKS));
transferType.setFeedbackReplyExpirationTime(new TimePeriod(2, TimePeriod.Field.WEEKS));
}
}