parent
615b9ddda0
commit
8321cfb724
@ -0,0 +1,93 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 18:38
|
||||
*/
|
||||
public class ATOBulkData {
|
||||
|
||||
private IntermediaryData intermediary;
|
||||
|
||||
public ATOBulkData(IntermediaryData intermediary) {
|
||||
this.intermediary = intermediary;
|
||||
}
|
||||
|
||||
public String outputBTTPS() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
intermediary.buildLine(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static class IntermediaryData implements ATOBulkLine {
|
||||
private final String identifier = "IDENTREGISTER";
|
||||
private final String version = "BTPSV001.0";
|
||||
private String abn;
|
||||
private Date createTime;
|
||||
private String fileReference;
|
||||
private String name;
|
||||
private ContactInfo contactInfo;
|
||||
private AddressInfo address;
|
||||
private List<ReportingPartyData> reportingParties = new ArrayList<>();
|
||||
|
||||
public IntermediaryData(String abn, String name, String fileReference) {
|
||||
this.abn = abn;
|
||||
this.fileReference = fileReference;
|
||||
this.name = name;
|
||||
this.createTime = new Date();
|
||||
}
|
||||
|
||||
public IntermediaryData setContactInfo(ContactInfo contactInfo) {
|
||||
this.contactInfo = contactInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IntermediaryData setAddress(AddressInfo address) {
|
||||
this.address = address;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder buildLine(StringBuilder builder) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
appendNParam(line, 1400, 4);
|
||||
appendAParam(line, identifier, 13);
|
||||
appendAParam(line, version, 10);
|
||||
appendAParam(line, abn, 11);
|
||||
appendDTParam(line, createTime, 28);
|
||||
appendAParam(line, fileReference, 16);
|
||||
appendAParam(line, name, 200);
|
||||
appendAParam(line, contactInfo.getContactName(), 40);
|
||||
appendNParam(line, contactInfo.getPhoneAreaCode(), 2);
|
||||
appendAParam(line, contactInfo.getPhoneNumber(), 15);
|
||||
appendAParam(line, address.getAddress(), 38 * 2);
|
||||
appendAParam(line, address.getSuburb(), 27);
|
||||
appendAParam(line, address.getState(), 3);
|
||||
appendNParam(line, address.getPostCode(), 4);
|
||||
appendAParam(line, address.getCountry(), 50);
|
||||
appendAParam(line, contactInfo.getEmail(), 76);
|
||||
appendFiller(line, 825);
|
||||
|
||||
builder.append(line);
|
||||
|
||||
for (ReportingPartyData partyData : reportingParties) {
|
||||
partyData.buildLine(builder);
|
||||
}
|
||||
|
||||
TotalDataRecord total = new TotalDataRecord()
|
||||
.setReportPartyCount(reportingParties.size())
|
||||
.setBusinessCount(reportingParties.stream().mapToInt(ReportingPartyData::businessCount).sum())
|
||||
.setTransactionsCount(reportingParties.stream().mapToInt(ReportingPartyData::transactionCount).sum());
|
||||
total.buildLine(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public void addReportingParty(ReportingPartyData reportingParty) {
|
||||
reportingParties.add(reportingParty);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
import com.github.stuxuhai.jpinyin.PinyinException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 21:11
|
||||
*/
|
||||
public interface ATOBulkLine {
|
||||
StringBuilder buildLine(StringBuilder builder);
|
||||
|
||||
default StringBuilder appendAParam(StringBuilder line, String content, int length) {
|
||||
content = content == null ? "" : StringUtils.trim(content);
|
||||
content = StringUtils.remove(StringUtils.remove(content, '\r'), '\n');
|
||||
int contentCharacterLength = content.getBytes().length;
|
||||
int contentLength = content.length();
|
||||
if (contentCharacterLength != contentLength) {
|
||||
try {
|
||||
content = CharacterUtils.convertToAlphaBet(content);
|
||||
} catch (PinyinException e) {
|
||||
e.printStackTrace();
|
||||
content = "";
|
||||
}
|
||||
}
|
||||
content = content.replace("?", " ");
|
||||
if (content.getBytes().length != content.length()) {
|
||||
content = "";
|
||||
}
|
||||
line.append(StringUtils.left(StringUtils.rightPad(content, length, " "), length));
|
||||
return line;
|
||||
}
|
||||
|
||||
default StringBuilder appendDParam(StringBuilder line, Date date, int len) {
|
||||
String dateStr = DateFormatUtils.format(date, "yyyyMMdd");
|
||||
return appendAParam(line, dateStr, len);
|
||||
}
|
||||
|
||||
default StringBuilder appendDTParam(StringBuilder line, Date date, int len) {
|
||||
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSZZ");
|
||||
String dateStr = formatter.print(new DateTime(date));
|
||||
return appendAParam(line, dateStr, len);
|
||||
}
|
||||
|
||||
default StringBuilder appendNParam(StringBuilder line, int num, int len) {
|
||||
line.append(StringUtils.right(StringUtils.leftPad(num + "", len, "0"), len));
|
||||
return line;
|
||||
}
|
||||
|
||||
default StringBuilder appendNParam(StringBuilder line, String num, int len) {
|
||||
num = num == null ? "" : StringUtils.trim(num);
|
||||
line.append(StringUtils.right(StringUtils.leftPad(num, len, "0"), len));
|
||||
return line;
|
||||
}
|
||||
|
||||
default StringBuilder appendNSParam(StringBuilder line, int num, int len) {
|
||||
line.append(StringUtils.right(StringUtils.leftPad(num + "", len, " "), len));
|
||||
return line;
|
||||
}
|
||||
|
||||
default StringBuilder appendFiller(StringBuilder line, int len) {
|
||||
line.append(StringUtils.repeat(" ", len)).append("\r\n");
|
||||
return line;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 21:17
|
||||
*/
|
||||
public class AddressInfo {
|
||||
private String address;
|
||||
private String suburb;
|
||||
private String state;
|
||||
private String postCode;
|
||||
private String country;
|
||||
|
||||
public AddressInfo(String address, String suburb, String state, String postCode, String country) {
|
||||
this.address = address;
|
||||
this.suburb = suburb;
|
||||
this.state = state;
|
||||
if (!postCode.matches("^\\d{4}$")) {
|
||||
postCode = "9999";
|
||||
country = "OTH";
|
||||
}
|
||||
this.postCode = postCode;
|
||||
if (country != null && country.length() != 3) {
|
||||
country = "OTH";
|
||||
}
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public String getSuburb() {
|
||||
return suburb;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getPostCode() {
|
||||
return postCode;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return "AUS".equals(country) ? "" : country;
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 21:21
|
||||
*/
|
||||
public class BusinessData implements ATOBulkLine {
|
||||
private final String identifier = "BIDR";
|
||||
private String customer;
|
||||
private Date paymentFacility;
|
||||
private String surName;
|
||||
private String firstName;
|
||||
private String secondName;
|
||||
private Date birth;
|
||||
private String abn;
|
||||
private String acn;
|
||||
private String registeredName;
|
||||
private String tradingName;
|
||||
private AddressInfo address;
|
||||
private AddressInfo postalAddress;
|
||||
private ContactInfo contactInfo;
|
||||
private String mchId;
|
||||
private String category;
|
||||
private String lodgment;
|
||||
|
||||
public BusinessData(Date paymentFacility, String abn, String acn, String registeredName, String tradingName, String mchId, String category, String lodgment) {
|
||||
this.paymentFacility = paymentFacility;
|
||||
if (abn != null) {
|
||||
abn = abn.replaceAll("\\D", "");
|
||||
if (abn.length() != 11) {
|
||||
abn = "";
|
||||
}
|
||||
}
|
||||
this.abn = abn;
|
||||
if (acn != null) {
|
||||
acn = acn.replaceAll("\\D", "");
|
||||
if (acn.length() != 9) {
|
||||
acn = "";
|
||||
}
|
||||
}
|
||||
this.acn = acn;
|
||||
this.registeredName = registeredName;
|
||||
this.tradingName = tradingName;
|
||||
this.mchId = mchId;
|
||||
this.customer = mchId;
|
||||
this.category = category;
|
||||
this.lodgment = lodgment;
|
||||
}
|
||||
|
||||
public BusinessData setAddress(AddressInfo address) {
|
||||
this.address = address;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BusinessData setPostalAddress(AddressInfo postalAddress) {
|
||||
this.postalAddress = postalAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BusinessData setContactInfo(ContactInfo contactInfo) {
|
||||
this.contactInfo = contactInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
private List<TransactionSummaryData> transactions = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public StringBuilder buildLine(StringBuilder builder) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
appendNParam(line, 1400, 4);
|
||||
appendAParam(line, identifier, 4);
|
||||
appendAParam(line, customer, 25);
|
||||
appendDParam(line, paymentFacility, 8);
|
||||
appendAParam(line, surName, 40);
|
||||
appendAParam(line, firstName, 40);
|
||||
appendAParam(line, secondName, 40);
|
||||
appendAParam(line, null, 8);
|
||||
appendNParam(line, abn, 11);
|
||||
appendNParam(line, acn, 9);
|
||||
appendAParam(line, registeredName, 200);
|
||||
appendAParam(line, tradingName, 200);
|
||||
appendAParam(line, address.getAddress(), 38 * 2);
|
||||
appendAParam(line, address.getSuburb(), 27);
|
||||
appendAParam(line, address.getState(), 3);
|
||||
appendNParam(line, address.getPostCode(), 4);
|
||||
appendAParam(line, address.getCountry(), 50);
|
||||
appendAParam(line, postalAddress.getAddress(), 38 * 2);
|
||||
appendAParam(line, postalAddress.getSuburb(), 27);
|
||||
appendAParam(line, postalAddress.getState(), 3);
|
||||
appendNParam(line, postalAddress.getPostCode(), 4);
|
||||
appendAParam(line, postalAddress.getCountry(), 50);
|
||||
appendAParam(line, contactInfo.getContactName(), 40);
|
||||
appendNParam(line, contactInfo.getPhoneAreaCode(), 2);
|
||||
appendAParam(line, contactInfo.getPhoneNumber(), 15);
|
||||
appendAParam(line, contactInfo.getEmail(), 76);
|
||||
appendAParam(line, mchId, 20);
|
||||
appendAParam(line, category, 100);
|
||||
appendAParam(line, lodgment, 1);
|
||||
appendFiller(line, 237);
|
||||
|
||||
builder.append(line);
|
||||
|
||||
for (TransactionSummaryData trans : transactions) {
|
||||
trans.buildLine(builder);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public int transactionCount() {
|
||||
return transactions.size();
|
||||
}
|
||||
|
||||
public void addTransaction(TransactionSummaryData transactionSummaryData) {
|
||||
//todo system account number
|
||||
transactionSummaryData.fillSystemInfo(mchId, "Merchant Acquiring System", mchId);
|
||||
transactions.add(transactionSummaryData);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
import com.github.stuxuhai.jpinyin.PinyinException;
|
||||
import com.github.stuxuhai.jpinyin.PinyinFormat;
|
||||
import com.github.stuxuhai.jpinyin.PinyinHelper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-09-06 9:03
|
||||
*/
|
||||
public class CharacterUtils {
|
||||
|
||||
public static String convertToAlphaBet(String source) throws PinyinException {
|
||||
return convertFullWidthToHalfWidth(convertToPinYin(source));
|
||||
}
|
||||
|
||||
public static String convertToPinYin(String source) throws PinyinException {
|
||||
return PinyinHelper.convertToPinyinString(source, "", PinyinFormat.WITHOUT_TONE).toUpperCase();
|
||||
}
|
||||
|
||||
public static String convertFullWidthToHalfWidth(String source) {
|
||||
if (StringUtils.isEmpty(source)) {
|
||||
return source;
|
||||
}
|
||||
|
||||
return source.chars().map(ch -> {
|
||||
if (ch == '\u3000') {
|
||||
return '\u0020';
|
||||
}
|
||||
if (isFullWidth((char) ch)) {
|
||||
return (char) (ch - 65248);
|
||||
}
|
||||
return (char) ch;
|
||||
}).filter(CharacterUtils::isHalfWidth)
|
||||
.mapToObj(chInt -> "" + (char) chInt).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
private static boolean isHalfWidth(int ch) {
|
||||
return ch >= 32 && ch <= 126;
|
||||
}
|
||||
|
||||
private static boolean isFullWidth(int ch) {
|
||||
if (ch == '\u3000') return true;
|
||||
|
||||
int i = ch - 65248;
|
||||
if (i < 32) return false;
|
||||
return isHalfWidth((char) i);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 21:19
|
||||
*/
|
||||
public class ContactInfo {
|
||||
private String contactName;
|
||||
private int phoneAreaCode;
|
||||
private String phoneNumber;
|
||||
private String email;
|
||||
|
||||
public ContactInfo(String contactName, String phoneNumber, String email) {
|
||||
this.contactName = contactName;
|
||||
if (isPhoneNumber(phoneNumber)) {
|
||||
phoneNumber = phoneNumber.replace(" ", "");
|
||||
String auPhoneNumber = formatAustralianPhoneNumber(phoneNumber);
|
||||
if (auPhoneNumber != null) {
|
||||
String subPhone = auPhoneNumber.substring(3);
|
||||
if (!subPhone.startsWith("1300") && !subPhone.startsWith("1800")) {
|
||||
this.phoneAreaCode = Integer.parseInt(subPhone.substring(0, 1));
|
||||
if (4 == phoneAreaCode) {
|
||||
this.phoneNumber = subPhone.substring(1, 3) + " " + subPhone.substring(3, 6) + " " + subPhone.substring(6);
|
||||
} else {
|
||||
this.phoneNumber = subPhone.substring(1, 5) + " " + subPhone.substring(5);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
this.phoneNumber = formatOtherPhoneNumber(phoneNumber);
|
||||
}
|
||||
}
|
||||
EmailValidator validator = new EmailValidator();
|
||||
this.email = validator.isValid(email, null) ? email : "";
|
||||
}
|
||||
|
||||
private boolean isPhoneNumber(String phoneNumber) {
|
||||
return phoneNumber.matches("^\\+?\\d+$");
|
||||
}
|
||||
|
||||
private String formatAustralianPhoneNumber(String phoneNumber) {
|
||||
if (phoneNumber.startsWith("+61") && phoneNumber.length() == 12) {
|
||||
return phoneNumber;
|
||||
}
|
||||
if (phoneNumber.startsWith("61") && phoneNumber.length() == 11) {
|
||||
return "+" + phoneNumber;
|
||||
}
|
||||
if (phoneNumber.startsWith("0") && phoneNumber.length() == 10) {
|
||||
return "+61" + phoneNumber.substring(1);
|
||||
}
|
||||
if (phoneNumber.length() == 9) {
|
||||
return "+61" + phoneNumber;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String formatOtherPhoneNumber(String phoneNumber) {
|
||||
String num = phoneNumber.replace(" ", "");
|
||||
if (num.startsWith("+")) {
|
||||
return num.replace("+", "");
|
||||
}
|
||||
if (num.startsWith("00")) {
|
||||
return num.substring(2);
|
||||
}
|
||||
if (num.startsWith("1") && num.length() == 11) {
|
||||
//中国手机号
|
||||
return "86" + num;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getContactName() {
|
||||
return contactName;
|
||||
}
|
||||
|
||||
public int getPhoneAreaCode() {
|
||||
return phoneAreaCode;
|
||||
}
|
||||
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 21:13
|
||||
*/
|
||||
public class ReportingPartyData implements ATOBulkLine {
|
||||
private final String identifier = "RPDR";
|
||||
private Date periodStart;
|
||||
private Date periodEnd;
|
||||
private String abn;
|
||||
private String branchNumber;
|
||||
private String registerName;
|
||||
private String tradingName;
|
||||
private AddressInfo address;
|
||||
private AddressInfo postalAddress;
|
||||
private ContactInfo contactInfo;
|
||||
private String softwareProductType;
|
||||
|
||||
private Map<Integer, BusinessData> businesses = new HashMap<>();
|
||||
|
||||
public ReportingPartyData(Date periodStart, Date periodEnd, String abn, String branchNumber, String registerName, String softwareProductType) {
|
||||
this.periodStart = DateUtils.truncate(periodStart, Calendar.DATE);
|
||||
this.periodEnd = DateUtils.truncate(periodEnd, Calendar.DATE);
|
||||
this.abn = abn;
|
||||
this.branchNumber = branchNumber;
|
||||
this.registerName = registerName;
|
||||
this.softwareProductType = softwareProductType;
|
||||
}
|
||||
|
||||
public ReportingPartyData setTradingName(String tradingName) {
|
||||
this.tradingName = tradingName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReportingPartyData setAddress(AddressInfo address) {
|
||||
this.address = address;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReportingPartyData setPostalAddress(AddressInfo postalAddress) {
|
||||
this.postalAddress = postalAddress;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReportingPartyData setContactInfo(ContactInfo contactInfo) {
|
||||
this.contactInfo = contactInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder buildLine(StringBuilder builder) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
appendNParam(line, 1400, 4);
|
||||
appendAParam(line, identifier, 4);
|
||||
appendDParam(line, periodStart, 8);
|
||||
appendDParam(line, periodEnd, 8);
|
||||
appendNParam(line, abn, 11);
|
||||
appendNParam(line, branchNumber, 3);
|
||||
appendAParam(line, registerName, 200);
|
||||
appendAParam(line, tradingName, 200);
|
||||
appendAParam(line, address.getAddress(), 38 * 2);
|
||||
appendAParam(line, address.getSuburb(), 27);
|
||||
appendAParam(line, address.getState(), 3);
|
||||
appendNParam(line, address.getPostCode(), 4);
|
||||
appendAParam(line, address.getCountry(), 50);
|
||||
appendAParam(line, postalAddress.getAddress(), 38 * 2);
|
||||
appendAParam(line, postalAddress.getSuburb(), 27);
|
||||
appendAParam(line, postalAddress.getState(), 3);
|
||||
appendNParam(line, postalAddress.getPostCode(), 4);
|
||||
appendAParam(line, postalAddress.getCountry(), 50);
|
||||
appendAParam(line, contactInfo.getContactName(), 40);
|
||||
appendNParam(line, contactInfo.getPhoneAreaCode(), 2);
|
||||
appendAParam(line, contactInfo.getPhoneNumber(), 15);
|
||||
appendAParam(line, contactInfo.getEmail(), 76);
|
||||
appendAParam(line, softwareProductType, 80);
|
||||
appendFiller(line, 429);
|
||||
|
||||
builder.append(line);
|
||||
businesses.values().stream()
|
||||
.filter(biz -> biz.transactionCount() > 0)
|
||||
.forEach(biz -> biz.buildLine(builder));
|
||||
return builder;
|
||||
}
|
||||
|
||||
public int businessCount() {
|
||||
return (int) businesses.values().stream().filter(biz -> biz.transactionCount() > 0).count();
|
||||
}
|
||||
|
||||
public int transactionCount() {
|
||||
return businesses.values().stream().mapToInt(BusinessData::transactionCount).sum();
|
||||
}
|
||||
|
||||
public BusinessData findBusiness(Integer clientId) {
|
||||
return businesses.get(clientId);
|
||||
}
|
||||
|
||||
public void addBusiness(Integer clientId, BusinessData biz) {
|
||||
businesses.put(clientId, biz);
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 21:35
|
||||
*/
|
||||
public class TotalDataRecord implements ATOBulkLine {
|
||||
private final String identifier = "FILE-TOTAL";
|
||||
private int reportPartyCount;
|
||||
private int businessCount;
|
||||
private int transactionsCount;
|
||||
|
||||
|
||||
public TotalDataRecord setReportPartyCount(int reportPartyCount) {
|
||||
this.reportPartyCount = reportPartyCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TotalDataRecord setBusinessCount(int businessCount) {
|
||||
this.businessCount = businessCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TotalDataRecord setTransactionsCount(int transactionsCount) {
|
||||
this.transactionsCount = transactionsCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder buildLine(StringBuilder builder) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
appendNParam(line, 1400, 4);
|
||||
appendAParam(line, identifier, 10);
|
||||
appendNParam(line, getRecords(), 10);
|
||||
appendNParam(line, reportPartyCount, 10);
|
||||
appendNParam(line, businessCount, 10);
|
||||
appendNParam(line, transactionsCount, 10);
|
||||
appendFiller(line, 1346);
|
||||
|
||||
builder.append(line);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private int getRecords() {
|
||||
return reportPartyCount + businessCount + transactionsCount + 2;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package au.com.royalpay.payment.manage.analysis.beans.ato;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-30 21:30
|
||||
*/
|
||||
public class TransactionSummaryData implements ATOBulkLine {
|
||||
private final String identifier = "TSDR";
|
||||
private String customer;
|
||||
private String description;
|
||||
private String accountNumber;
|
||||
private String settleAccountName;
|
||||
private String settleBSB;
|
||||
private String settleAccountNo;
|
||||
private Date periodStart;
|
||||
private Date periodEnd;
|
||||
private String currency = "AUD";
|
||||
private BigDecimal grossPayment;
|
||||
private int transactionCount;
|
||||
private BigDecimal totalRefund;
|
||||
private int refundCount;
|
||||
private BigDecimal cashoutAmount = BigDecimal.ZERO;
|
||||
private int cashoutCount = 0;
|
||||
private BigDecimal cashoutComponentAmount = BigDecimal.ZERO;
|
||||
|
||||
public TransactionSummaryData(JSONObject analysis, DateTime startOfMon, DateTime endOfMon) {
|
||||
settleAccountName = analysis.getString("account_name");
|
||||
settleBSB = analysis.getString("bsb_no");
|
||||
settleAccountNo = analysis.getString("account_no").replaceAll("\\D", "");
|
||||
periodStart = analysis.getDate("period_start");
|
||||
periodEnd = analysis.getDate("period_end");
|
||||
if (DateUtils.isSameDay(periodStart, periodEnd)) {
|
||||
if (DateUtils.isSameDay(periodStart, startOfMon.toDate())) {
|
||||
periodEnd = DateUtils.addDays(periodEnd, 1);
|
||||
} else {
|
||||
periodStart = DateUtils.addDays(periodStart, -1);
|
||||
}
|
||||
}
|
||||
grossPayment = analysis.getBigDecimal("gross_payment");
|
||||
transactionCount = analysis.getIntValue("pay_count");
|
||||
totalRefund = analysis.getBigDecimal("total_refund");
|
||||
refundCount = analysis.getIntValue("refund_count");
|
||||
}
|
||||
|
||||
public void fillSystemInfo(String customer, String systemDesc, String systemAccount) {
|
||||
this.customer = customer;
|
||||
this.description = systemDesc;
|
||||
this.accountNumber = systemAccount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBuilder buildLine(StringBuilder builder) {
|
||||
StringBuilder line = new StringBuilder();
|
||||
appendNParam(line, 1400, 4);
|
||||
appendAParam(line, identifier, 4);
|
||||
appendAParam(line, customer, 25);
|
||||
appendAParam(line, description, 40);
|
||||
appendAParam(line, accountNumber, 25);
|
||||
appendAParam(line, settleAccountName, 30);
|
||||
appendNParam(line, settleBSB, 6);
|
||||
appendNParam(line, settleAccountNo, 30);
|
||||
appendDParam(line, periodStart, 8);
|
||||
appendDParam(line, periodEnd, 8);
|
||||
appendAParam(line, currency, 3);
|
||||
appendNParam(line, grossPayment.intValue(), 13);
|
||||
appendNParam(line, transactionCount, 13);
|
||||
appendNParam(line, totalRefund.intValue(), 13);
|
||||
appendNParam(line, refundCount, 13);
|
||||
appendNParam(line, cashoutAmount.intValue(), 13);
|
||||
appendNParam(line, cashoutCount, 13);
|
||||
appendNParam(line, cashoutComponentAmount.intValue(), 20);
|
||||
appendFiller(line, 1119);
|
||||
builder.append(line);
|
||||
return builder;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package au.com.royalpay.payment.manage.analysis.core;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-31 1:22
|
||||
*/
|
||||
public interface ATOReportService {
|
||||
|
||||
String exportBTTPSFile(Date from, Date to);
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
package au.com.royalpay.payment.manage.analysis.core.impls;
|
||||
|
||||
import au.com.royalpay.payment.manage.analysis.beans.ato.*;
|
||||
import au.com.royalpay.payment.manage.analysis.core.ATOReportService;
|
||||
import au.com.royalpay.payment.manage.mappers.payment.TransactionMapper;
|
||||
import au.com.royalpay.payment.manage.mappers.system.ClientMapper;
|
||||
import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-31 1:23
|
||||
*/
|
||||
@Service
|
||||
public class ATOReportServiceImpl implements ATOReportService {
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
@Resource
|
||||
private TransactionMapper transactionMapper;
|
||||
@Resource
|
||||
private ClientMapper clientMapper;
|
||||
@Value("classpath:data/category/billbuddyindustry.json")
|
||||
private org.springframework.core.io.Resource industryResource;
|
||||
private Map<String, String> industryMap;
|
||||
|
||||
@PostConstruct
|
||||
public void loadIndustryConfiguration() throws IOException {
|
||||
industryMap = new HashMap<>();
|
||||
JSONArray config = JSON.parseArray(IOUtils.toString(industryResource.getInputStream(), Charsets.UTF_8));
|
||||
for (int i = 0; i < config.size(); i++) {
|
||||
JSONObject industry = config.getJSONObject(i);
|
||||
loadIndustry(industry, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadIndustry(JSONObject industry, String parentCategory) {
|
||||
JSONArray children = industry.getJSONArray("children");
|
||||
String category = industry.getString("category");
|
||||
String code = industry.getString("mccCode");
|
||||
if (category == null && parentCategory == null) {
|
||||
throw new ServerErrorException("Industry Have No Category Code:" + code);
|
||||
}
|
||||
category = category == null ? parentCategory : category;
|
||||
industryMap.put(code, category);
|
||||
if (children != null && !children.isEmpty()) {
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
JSONObject subIndustry = children.getJSONObject(i);
|
||||
loadIndustry(subIndustry, category);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String exportBTTPSFile(Date from, Date to) {
|
||||
String reference = "RPAY" + DateFormatUtils.format(new Date(), "yyyyMMddHHmm");
|
||||
String abn = "16601619685";
|
||||
String registerCompanyName = "Tunnel Show Pty Ltd";
|
||||
AddressInfo companyAddr = new AddressInfo("Level 11, 15 William St", "Melbourne", "VIC", "3000", "AUS");
|
||||
ContactInfo companyContact = new ContactInfo("Locky", "+61394488865", "info@royalpay.com.au");
|
||||
ATOBulkData.IntermediaryData intermediary = new ATOBulkData.IntermediaryData(abn, registerCompanyName, reference)
|
||||
.setAddress(companyAddr)
|
||||
.setContactInfo(companyContact);
|
||||
ATOBulkData data = new ATOBulkData(intermediary);
|
||||
|
||||
ReportingPartyData reportingParty = new ReportingPartyData(from, to, abn, "001", registerCompanyName, "INHOUSE Tunnel Show")
|
||||
.setAddress(companyAddr)
|
||||
.setPostalAddress(companyAddr)
|
||||
.setContactInfo(companyContact)
|
||||
.setTradingName("RoyalPay");
|
||||
intermediary.addReportingParty(reportingParty);
|
||||
|
||||
DateTime fromDateTime = new DateTime(from).withTimeAtStartOfDay();
|
||||
DateTime toDateTime = new DateTime(to).plusDays(1).withTimeAtStartOfDay();
|
||||
DateTime startOfMon = new DateTime(fromDateTime);
|
||||
DateTime endOfMon = new DateTime(fromDateTime.plusMonths(1).withDayOfMonth(1));
|
||||
while (endOfMon.isBefore(toDateTime)) {
|
||||
logger.debug("Exporting date range:" + startOfMon.toString("yyyy-MM-dd") + " ~ " + endOfMon.toString("yyyy-MM-dd"));
|
||||
loadMonthTransactions(reportingParty, startOfMon, endOfMon);
|
||||
startOfMon = new DateTime(endOfMon);
|
||||
endOfMon = new DateTime(endOfMon.plusMonths(1));
|
||||
}
|
||||
endOfMon = new DateTime(toDateTime);
|
||||
logger.debug("Exporting date range:" + startOfMon.toString("yyyy-MM-dd") + " ~ " + endOfMon.toString("yyyy-MM-dd"));
|
||||
loadMonthTransactions(reportingParty, startOfMon, endOfMon);
|
||||
logger.info("output BTTPS file");
|
||||
return data.outputBTTPS();
|
||||
}
|
||||
|
||||
private void loadMonthTransactions(ReportingPartyData reportingParty, DateTime startOfMon, DateTime endOfMon) {
|
||||
List<Integer> clients = clientMapper.listClientsWithTransactionsSettled(startOfMon.toDate(), endOfMon.toDate());
|
||||
clients.parallelStream().forEach(clientId -> loadClientMonthTransactions(reportingParty, clientId, startOfMon, endOfMon));
|
||||
}
|
||||
|
||||
private void loadClientMonthTransactions(ReportingPartyData reportingParty, Integer clientId, DateTime startOfMon, DateTime endOfMon) {
|
||||
BusinessData biz = reportingParty.findBusiness(clientId);
|
||||
logger.debug("Exporting date range for client[" + clientId + "]:" + startOfMon.toString("yyyy-MM-dd") + " ~ " + endOfMon.toString("yyyy-MM-dd"));
|
||||
if (biz == null) {
|
||||
JSONObject cli = clientMapper.findClientIgnoreInvalid(clientId);
|
||||
AddressInfo addr = new AddressInfo(cli.getString("address"), cli.getString("suburb"), cli.getString("state"), cli.getString("postcode"), cli.getString("country"));
|
||||
ContactInfo contact = new ContactInfo(cli.getString("contact_person"), cli.getString("contact_phone"), cli.getString("contact_email"));
|
||||
String industry = industryMap.getOrDefault(cli.getString("royalpayindustry"), cli.getString("royalpayindustry"));
|
||||
String clientMoniker = cli.getString("client_moniker");
|
||||
biz = new BusinessData(cli.getDate("create_time"), cli.getString("abn"), cli.getString("acn"),
|
||||
cli.getString("company_name"), cli.getString("short_name"), clientMoniker,
|
||||
industry, "O")
|
||||
.setAddress(addr)
|
||||
.setPostalAddress(addr)
|
||||
.setContactInfo(contact);
|
||||
reportingParty.addBusiness(clientId, biz);
|
||||
}
|
||||
List<JSONObject> analysisList = transactionMapper.analysisForATOReport(clientId, startOfMon.toDate(), endOfMon.toDate());
|
||||
for (JSONObject analysis : analysisList) {
|
||||
biz.addTransaction(new TransactionSummaryData(analysis, startOfMon, endOfMon));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,331 @@
|
||||
[
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "机票",
|
||||
"mccCode": "10001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "旅游行业",
|
||||
"mccCode": "10002"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "私人定制旅游",
|
||||
"mccCode": "10003"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "租车",
|
||||
"mccCode": "10004",
|
||||
"category": "RENTAL"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "巴士",
|
||||
"mccCode": "10005"
|
||||
}
|
||||
],
|
||||
"label": "旅游出行",
|
||||
"mccCode": "1",
|
||||
"category": "PROFRSSIONAL SERV"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "饭店",
|
||||
"mccCode": "20001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "奶茶店",
|
||||
"mccCode": "20002"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "烧烤",
|
||||
"mccCode": "20003"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "火锅",
|
||||
"mccCode": "20004"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "Coffee",
|
||||
"mccCode": "20005"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "酒吧",
|
||||
"mccCode": "20006"
|
||||
}
|
||||
],
|
||||
"label": "餐饮",
|
||||
"mccCode": "2",
|
||||
"category": "RETAIL"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "培训类",
|
||||
"mccCode": "30001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "移民留学",
|
||||
"mccCode": "30002"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "私人幼儿园",
|
||||
"mccCode": "30003"
|
||||
}
|
||||
],
|
||||
"label": "教育",
|
||||
"mccCode": "3",
|
||||
"category": "SCHOOLS & EDUCATION SERV"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "换汇",
|
||||
"mccCode": "40001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "房产",
|
||||
"mccCode": "40002"
|
||||
}
|
||||
],
|
||||
"label": "商务咨询",
|
||||
"mccCode": "4",
|
||||
"category": "FINANCE"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "公众号服务商",
|
||||
"mccCode": "50001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "各种媒体类宣传",
|
||||
"mccCode": "50002"
|
||||
}
|
||||
],
|
||||
"label": "传媒",
|
||||
"mccCode": "5",
|
||||
"category": "PROFESSIONAL SERV"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "美容院",
|
||||
"mccCode": "60001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "医疗美容",
|
||||
"mccCode": "60002"
|
||||
}
|
||||
],
|
||||
"label": "医美",
|
||||
"mccCode": "6",
|
||||
"category": "FITNESS"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"label": "超市",
|
||||
"mccCode": "70001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "服装店",
|
||||
"mccCode": "70002"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "鞋店",
|
||||
"mccCode": "70003"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "珠宝店",
|
||||
"mccCode": "70004"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "箱包",
|
||||
"mccCode": "70005"
|
||||
}
|
||||
],
|
||||
"label": "零售",
|
||||
"mccCode": "7",
|
||||
"category": "RETAIL"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "桌游吧",
|
||||
"mccCode": "80001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "演唱会",
|
||||
"mccCode": "80002",
|
||||
"category": "UTILITIES"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "马术训练",
|
||||
"mccCode": "80003",
|
||||
"category": "FITNESS"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "瑜伽",
|
||||
"mccCode": "80004",
|
||||
"category": "FITNESS"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "健身",
|
||||
"mccCode": "80005",
|
||||
"category": "FITNESS"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "社团",
|
||||
"mccCode": "80006"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "网吧",
|
||||
"mccCode": "80007",
|
||||
"category": "EQUIPMENT HIRE"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "KTV",
|
||||
"mccCode": "80008",
|
||||
"category": "EQUIPMENT HIRE"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "电影",
|
||||
"mccCode": "80009"
|
||||
}
|
||||
],
|
||||
"label": "休闲娱乐",
|
||||
"mccCode": "8",
|
||||
"category": "OTHER"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "摄影",
|
||||
"mccCode": "90001",
|
||||
"category": "PROFESSIONAL SERV"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "massage",
|
||||
"mccCode": "90002"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "通讯运营商",
|
||||
"mccCode": "90003",
|
||||
"category": "TELECOM"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "车行",
|
||||
"mccCode": "90004",
|
||||
"category": "TRADES & VOC"
|
||||
},
|
||||
{
|
||||
"children:": [],
|
||||
"label": "软件服务",
|
||||
"mccCode": "90005",
|
||||
"category": "PROFESSIONAL SERV"
|
||||
}
|
||||
],
|
||||
"label": "其他服务类",
|
||||
"mccCode": "9",
|
||||
"category": "OTHER"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "Hotel",
|
||||
"mccCode": "100001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "Motel",
|
||||
"mccCode": "100002"
|
||||
}
|
||||
],
|
||||
"label": "酒店",
|
||||
"mccCode": "10",
|
||||
"category": "RENTAL"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "代购",
|
||||
"mccCode": "110001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "物流(大宗出口贸易)",
|
||||
"mccCode": "110002"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "红酒出口",
|
||||
"mccCode": "110003"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "综合电商",
|
||||
"mccCode": "110004"
|
||||
}
|
||||
],
|
||||
"label": "出口贸易",
|
||||
"mccCode": "11",
|
||||
"category": "TRADES & VOC"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"children": [],
|
||||
"label": "建材",
|
||||
"mccCode": "120001"
|
||||
},
|
||||
{
|
||||
"children": [],
|
||||
"label": "家居",
|
||||
"mccCode": "120002"
|
||||
}
|
||||
],
|
||||
"label": "家居建材",
|
||||
"mccCode": "12",
|
||||
"category": "TRADES & VOC"
|
||||
}
|
||||
]
|
@ -0,0 +1,34 @@
|
||||
package au.com.royalpay.payment.manage.process.ato;
|
||||
|
||||
import au.com.royalpay.payment.manage.analysis.core.ATOReportService;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-31 14:40
|
||||
*/
|
||||
@SpringBootTest
|
||||
@ActiveProfiles({"proxy", "wechat"})
|
||||
@TestPropertySource(properties = {"spring.datasource.username=root", "spring.datasource.password=ZOIBhellor0yalpay"})
|
||||
@RunWith(SpringRunner.class)
|
||||
public class ExportATOReport {
|
||||
@Resource
|
||||
private ATOReportService atoReportService;
|
||||
|
||||
@Test
|
||||
public void export() throws IOException {
|
||||
String content = atoReportService.exportBTTPSFile(DateTime.parse("2017-07-01").toDate(), DateTime.parse("2017-07-31").toDate());
|
||||
FileUtils.write(new File("C:\\Users\\yixian\\Documents\\royalpay2017070120170731.bttps"), content, StandardCharsets.US_ASCII);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package au.com.royalpay.payment.manage.valid;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Create by yixian at 2018-08-31 15:27
|
||||
*/
|
||||
public class TestJodaFormat {
|
||||
@Test
|
||||
public void testFormat(){
|
||||
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSZZ");
|
||||
String dateStr = formatter.print(new DateTime(new Date()));
|
||||
System.out.println(dateStr);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue