Commit 94062b7c authored by neo.wang's avatar neo.wang

Merge branch 'neo_dev' into 'dev'

[patch] simple impl of data import for balance

See merge request root/atms!76
parents ac02e212 bb5bcd04
package pwc.taxtech.atms.constant;
public class DictionaryConstant {
public static final String WFSubmitReport = "WFSubmitReport"; //提交审核
public static final String WFReportApproval = "WFReportApproval"; //审核报表
public static final String WFCargoNameMatch = "WFCargoNameMatch";//货物匹配
public static final String WFDataProcess = "WFDataProcess"; //数据处理
public static final String WFDeclarationComplete = "WFDeclarationComplete"; //申报完成
public static final String WFAccountMap = "WFAccountMap"; //科目对应
public static final String WFImportErpData = "WFImportErpData"; //导入财务数据
public static final String WFImportBalanceTable = "WFImportBalanceTable"; //导入TB
public static final String WFImportIncomeInvoice = "WFImportIncomeInvoice"; //导入进项发票
public static final String WFImportInvoiceMap = "WFImportInvoiceMap"; //导入发票对应
public static final String WFImportVoucherMap = "WFImportVoucherMap"; //导入凭证对应
public static final String WFImportOutputInvoice = "WFImportOutputInvoice"; //导入销项发票
public static final String WFImportCustomInvoice = "WFImportCustomInvoice"; //导入海关清单
public static final String WFImportJournalEntry = "WFImportJournalEntry"; //导入序时账
public static final String WFImportAuditAdjust = "WFImportAuditAdjust"; //导入审计调整
public static final String WFViewFinancialReport = "WFViewFinancialReport"; //查看报表
}
package pwc.taxtech.atms.service.impl;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pwc.taxtech.atms.constant.enums.EnumServiceType;
import pwc.taxtech.atms.constant.enums.EnumTbImportType;
import pwc.taxtech.atms.constant.enums.EnumValidationType;
import pwc.taxtech.atms.constant.enums.ProjectImportDataType;
import pwc.taxtech.atms.constant.enums.ServiceType;
import pwc.taxtech.atms.constant.enums.VatImportType;
import pwc.taxtech.atms.dao.DataImportMapper;
import pwc.taxtech.atms.dao.EnterpriseAccountMapper;
import pwc.taxtech.atms.dao.ProjectMapper;
import pwc.taxtech.atms.dto.OperationResultDto;
import pwc.taxtech.atms.dto.taxadmin.DataImportedStatusDto;
import pwc.taxtech.atms.entitiy.EnterpriseAccount;
import pwc.taxtech.atms.entitiy.EnterpriseAccountExample;
import pwc.taxtech.atms.entitiy.Project;
import pwc.taxtech.atms.entitiy.ProjectExample;
import pwc.taxtech.atms.vat.dao.BalanceMapper;
import pwc.taxtech.atms.vat.dao.CompanyBalanceMapper;
import pwc.taxtech.atms.vat.dao.ValidationInfoMapper;
import pwc.taxtech.atms.vat.dao.VatEnterpriseAccountMapper;
import pwc.taxtech.atms.vat.dao.DataImportServiceMapper;
import pwc.taxtech.atms.vat.entity.Balance;
import pwc.taxtech.atms.vat.entity.CompanyBalance;
import pwc.taxtech.atms.vat.entity.CompanyBalanceExample;
import pwc.taxtech.atms.vat.entity.VatEnterpriseAccount;
import pwc.taxtech.atms.vat.entity.VatEnterpriseAccountExample;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
public class DataImportServiceImpl {
......@@ -40,6 +58,14 @@ public class DataImportServiceImpl {
@Autowired
private EnterpriseAccountMapper enterpriseAccountMapper;
@Autowired
private VatEnterpriseAccountMapper vatEnterpriseAccountMapper;
@Autowired
private ValidationInfoMapper validationInfoMapper;
@Autowired
private DataImportServiceMapper dataImportServiceMapper;
@Autowired
private BalanceMapper balanceMapper;
public OperationResultDto importTrialBalance(List<CompanyBalance> balanceList, Integer importType,
Integer serviceTypeId, String userID) {
......@@ -87,10 +113,352 @@ public class DataImportServiceImpl {
//先删除数据
clearTableData(period, BALANCE_TABLE);
mapper.deleteTbValidation(period, EnumValidationType.TrialBalance.getCode());
CompanyBalanceExample example = new CompanyBalanceExample();
example.createCriteria().andPeriodIdEqualTo(period);
List<CompanyBalance> companyBalanceList = companyBalanceMapper.selectByExample(example);
validationAcctCode(period, userID);
initBalance(companyBalanceList, period, serviceTypeId);
// calculateYearColumn();
// duplicatedValidation(period, userID);
// validationPeriodBal(period, userID);
// validationDebitCreditBalance(period, userID);
// validataionBegDebitAndBegCredit(period, userID);
// upAndDownValidation(period, userID);
//ToDo(add exception msg)
// ValidationInfoExample infoExample=new ValidationInfoExample();
// infoExample.createCriteria().andPeriodIdEqualTo(period).andImportTypeIdEqualTo(EnumValidationType.TrialBalance.getCode());
// List<ValidationInfo> infos =validationInfoMapper.selectByExample(infoExample);
// DictionaryExample dictionaryExample = new DictionaryExample();
// dictionaryExample.createCriteria().andDictKeyEqualTo(DictionaryConstant.WFImportBalanceTable);
}
return true;
}
private List<Balance> initBalance(List<CompanyBalance> companyBalanceList, int period, Integer serviceTypeId) {
List<Balance> addlist = new ArrayList<>();
List<VatEnterpriseAccount> vats = vatEnterpriseAccountMapper.selectByExample(null);
companyBalanceList.forEach(compbalance -> {
VatEnterpriseAccount directionDto = vats.stream().filter(m -> m.getAcctCode().equals(compbalance.getAcctCode()))
.findFirst().get();
if (directionDto != null) {
Integer direction = directionDto.getDirection();
Balance balanceDto = new Balance();
balanceDto.setBalanceId(UUID.randomUUID().toString());
balanceDto.setPeriodId(compbalance.getPeriodId());
balanceDto.setAcctCode(compbalance.getAcctCode());
balanceDto.setCustomerCode(compbalance.getCustomerCode());
balanceDto.setMonthId(compbalance.getMonthId());
balanceDto.setIsDummy(null);
//1.根据期初余额设置期初借方,期初贷方的值
if (compbalance.getBegBal() != null && compbalance.getEndBal() != null) {
balanceDto.setBegBal(compbalance.getBegBal());
balanceDto.setEndBal(compbalance.getEndBal());
if (direction == 1) {
balanceDto.setBegDebitBal(balanceDto.getBegBal());
balanceDto.setBegCreditBal(new BigDecimal(0));
balanceDto.setEndDebitBal(balanceDto.getEndBal());
balanceDto.setEndCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setBegCreditBal(balanceDto.getBegBal());
balanceDto.setBegDebitBal(new BigDecimal(0));
balanceDto.setEndDebitBal(new BigDecimal(0));
balanceDto.setEndCreditBal(balanceDto.getEndBal());
}
//判断是否选中了发生额
if (compbalance.getDebitBal() == null && compbalance.getCreditBal() == null) {
if (direction == 1) {
balanceDto.setDebitBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
balanceDto.setCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setDebitBal(new BigDecimal(0));
balanceDto.setCreditBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
}
} else {
balanceDto.setDebitBal(compbalance.getDebitBal());
balanceDto.setCreditBal(compbalance.getCreditBal());
}
}
//2.期末借方,期末贷方不为空
else if (compbalance.getBegBal() != null && compbalance.getEndDebitBal() != null && compbalance.getEndCreditBal() != null) {
balanceDto.setBegBal(compbalance.getBegBal());
balanceDto.setEndDebitBal(compbalance.getEndDebitBal());
balanceDto.setEndCreditBal(compbalance.getEndCreditBal());
balanceDto.setEndBal((balanceDto.getEndDebitBal().subtract(balanceDto.getEndCreditBal()))
.multiply(new BigDecimal(direction)));
if (direction == 1) {
balanceDto.setBegDebitBal(balanceDto.getBegBal());
balanceDto.setBegCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setBegCreditBal(balanceDto.getBegBal());
balanceDto.setBegDebitBal(new BigDecimal(0));
}
//判断是否选中了发生额
if (compbalance.getDebitBal() == null && compbalance.getCreditBal() == null) {
if (direction == 1) {
balanceDto.setDebitBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
balanceDto.setCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setDebitBal(new BigDecimal(0));
balanceDto.setCreditBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
}
} else {
balanceDto.setDebitBal(compbalance.getDebitBal());
balanceDto.setCreditBal(compbalance.getCreditBal());
}
}
//3.发生额不为空
else if (compbalance.getBegBal() != null && compbalance.getDebitBal() != null && compbalance.getCreditBal() != null) {
balanceDto.setBegBal(compbalance.getBegBal());
balanceDto.setDebitBal(compbalance.getDebitBal());
balanceDto.setCreditBal(compbalance.getCreditBal());
if (direction == 1) {
balanceDto.setBegDebitBal(balanceDto.getBegBal());
balanceDto.setBegCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setBegCreditBal(balanceDto.getBegBal());
balanceDto.setBegDebitBal(new BigDecimal(0));
}
if (compbalance.getEndBal() == null && compbalance.getEndDebitBal() == null && compbalance.getEndCreditBal() == null) {
balanceDto.setEndBal((balanceDto.getDebitBal().subtract(balanceDto.getCreditBal()))
.multiply(new BigDecimal(direction)).add(balanceDto.getBegBal()));
if (direction == 1) {
balanceDto.setEndDebitBal(balanceDto.getEndBal());
balanceDto.setEndCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setEndDebitBal(new BigDecimal(0));
balanceDto.setEndCreditBal(balanceDto.getEndBal());
}
} else if (compbalance.getEndBal() != null) {
balanceDto.setEndBal(compbalance.getEndBal());
if (direction == 1) {
balanceDto.setEndDebitBal(balanceDto.getEndBal());
balanceDto.setEndCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setEndDebitBal(new BigDecimal(0));
balanceDto.setEndCreditBal(balanceDto.getEndBal());
}
} else if (compbalance.getEndDebitBal() != null && compbalance.getEndCreditBal() != null) {
balanceDto.setEndDebitBal(compbalance.getEndDebitBal());
balanceDto.setEndCreditBal(compbalance.getEndCreditBal());
balanceDto.setEndBal((balanceDto.getEndDebitBal().subtract(balanceDto.getEndCreditBal())
.multiply(new BigDecimal(direction))));
}
}
//4.根据期初借方,期初贷方的值设置期初余额
else if (compbalance.getBegDebitBal() != null && compbalance.getBegCreditBal() != null && compbalance.getDebitBal() != null && compbalance.getCreditBal() != null) {
balanceDto.setBegDebitBal(compbalance.getBegDebitBal());
balanceDto.setBegCreditBal(compbalance.getBegCreditBal());
balanceDto.setDebitBal(compbalance.getDebitBal());
balanceDto.setCreditBal(compbalance.getCreditBal());
balanceDto.setBegBal((balanceDto.getBegDebitBal().subtract(balanceDto.getBegCreditBal()))
.multiply(new BigDecimal(direction)));
if (compbalance.getEndBal() == null && compbalance.getEndDebitBal() == null && compbalance.getEndCreditBal() == null) {
balanceDto.setEndBal((balanceDto.getDebitBal().subtract(balanceDto.getCreditBal()))
.multiply(new BigDecimal(direction)).add(balanceDto.getBegBal()));
if (direction == 1) {
balanceDto.setEndDebitBal(balanceDto.getEndBal());
balanceDto.setEndCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setEndDebitBal(new BigDecimal(0));
balanceDto.setEndCreditBal(balanceDto.getEndBal());
}
} else if (compbalance.getEndBal() != null) {
balanceDto.setEndBal(compbalance.getEndBal());
if (direction == 1) {
balanceDto.setEndDebitBal(balanceDto.getEndBal());
balanceDto.setEndCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setEndDebitBal(new BigDecimal(0));
balanceDto.setEndCreditBal(balanceDto.getEndBal());
}
} else if (compbalance.getEndDebitBal() != null && compbalance.getEndCreditBal() != null) {
balanceDto.setEndDebitBal(compbalance.getEndDebitBal());
balanceDto.setEndCreditBal(compbalance.getEndCreditBal());
balanceDto.setEndBal((balanceDto.getEndDebitBal().subtract(balanceDto.getEndCreditBal()))
.multiply(new BigDecimal(direction)));
}
}
//5.根据期初借方,期初贷方的值设置期初余额
else if (compbalance.getBegDebitBal() != null && compbalance.getBegCreditBal() != null && compbalance.getEndDebitBal() != null && compbalance.getEndCreditBal() != null) {
balanceDto.setBegDebitBal(compbalance.getBegDebitBal());
balanceDto.setBegCreditBal(compbalance.getBegCreditBal());
balanceDto.setEndDebitBal(compbalance.getEndDebitBal());
balanceDto.setEndCreditBal(compbalance.getEndCreditBal());
balanceDto.setBegBal((balanceDto.getBegDebitBal().subtract(balanceDto.getBegCreditBal()))
.multiply(new BigDecimal(direction)));
balanceDto.setEndBal((balanceDto.getEndDebitBal().subtract(balanceDto.getEndCreditBal()))
.multiply(new BigDecimal(direction)));
//判断是否选中了发生额
if (compbalance.getDebitBal() == null && compbalance.getCreditBal() == null) {
if (direction == 1) {
balanceDto.setDebitBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
balanceDto.setCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setDebitBal(new BigDecimal(0));
balanceDto.setCreditBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
}
} else {
balanceDto.setDebitBal(compbalance.getDebitBal());
balanceDto.setCreditBal(compbalance.getCreditBal());
}
}
//6.根据期初借方,期初贷方的值设置期初余额
else if (compbalance.getBegDebitBal() != null && compbalance.getBegCreditBal() != null && compbalance.getEndBal() != null) {
balanceDto.setBegDebitBal(compbalance.getBegDebitBal());
balanceDto.setBegCreditBal(compbalance.getBegCreditBal());
balanceDto.setEndBal(compbalance.getEndBal());
balanceDto.setBegBal((balanceDto.getBegDebitBal().subtract(balanceDto.getBegCreditBal()))
.multiply(new BigDecimal(direction)));
if (direction == 1) {
balanceDto.setEndDebitBal(balanceDto.getEndBal());
balanceDto.setEndCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setEndDebitBal(new BigDecimal(0));
balanceDto.setEndCreditBal(balanceDto.getEndBal());
}
//判断是否选中了发生额
if (compbalance.getDebitBal() == null && compbalance.getCreditBal() == null) {
if (direction == 1) {
balanceDto.setDebitBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
balanceDto.setCreditBal(new BigDecimal(0));
} else if (direction == -1) {
balanceDto.setDebitBal(new BigDecimal(0));
balanceDto.setCreditBal(balanceDto.getEndBal().subtract(balanceDto.getBegBal()));
}
} else {
balanceDto.setDebitBal(compbalance.getDebitBal());
balanceDto.setCreditBal(compbalance.getCreditBal());
}
}
addlist.add(balanceDto);
}
});
if (addlist.size() > 0) {
List<ImportBalanceCount> result = dataImportServiceMapper.resultBalance(period, VatImportType.AuditAdjust.getCode());
result.forEach(v -> {
BigDecimal value = (v.debit.subtract(v.credit)).multiply(new BigDecimal(v.direction));
List<Balance> items = addlist.stream().filter(p -> {
return p.getAcctCode().equals(v.acctCode) || v.acctCode.startsWith(p.getAcctCode());
}).collect(Collectors.toList());
if (items.size() > 0) {
items.forEach(item -> {
if (item != null) {
item.setDebitBal(item.getDebitNet().add(v.debit));
item.setCreditBal(item.getCreditBal().add(v.credit));
if (v.direction == 0) {
item.setEndDebitBal(item.getEndDebitBal().add(value));
} else {
item.setEndCreditBal(item.getEndCreditBal().add(value));
}
item.setEndBal(item.getEndBal().add(value));
}
});
if (!items.stream().anyMatch(p -> p.getAcctCode().equals(v.acctCode))) {
addList(addlist, v.acctCode, period, value, v);
}
} else {
VatEnterpriseAccountExample example = new VatEnterpriseAccountExample();
example.createCriteria().andAcctCodeLike(v.acctCode);
List<VatEnterpriseAccount> accts = vatEnterpriseAccountMapper.selectByExample(example);
if (accts.size() == 0) {
addList(addlist, v.acctCode, period, value, v);
} else {
accts.forEach(acct -> {
addList(addlist, acct.getAcctCode(), period, value, v);
});
if (!accts.stream().anyMatch(p -> p.getAcctCode().equals(v.acctCode))) {
addList(addlist, v.acctCode, period, value, v);
}
}
}
});
//插入账套中有CompanyBalance没有的数据
InsertCodeNotInBalance(addlist, period);
}
//VAT时立即批量插入到balance
if (serviceTypeId == EnumServiceType.VAT.getCode() && !addlist.isEmpty()) {//TODO(buil copy insert)
addlist.forEach(m -> balanceMapper.insert(m));
}
return addlist;
}
//EnterpriseAccount表中有,balance没有的科目,补全balance表科目
private void InsertCodeNotInBalance(List<Balance> addlist, int period) {
VatEnterpriseAccountExample example = new VatEnterpriseAccountExample();
List<String> accCode = new ArrayList<>();
addlist.forEach(m -> accCode.add(m.getAcctCode()));
example.createCriteria().andAcctCodeNotIn(accCode);
List<VatEnterpriseAccount> reult = vatEnterpriseAccountMapper.selectByExample(example);
Set<String> accts = new HashSet<>();
reult.forEach(m -> accts.add(m.getAcctCode()));
accts.forEach(m -> addList(addlist, m, period));
DealCodeNotInBalance(addlist,period);
}
//处理子科目导入,但父科目没导入的情况,需要计算父科目
private void DealCodeNotInBalance(List<Balance> addlist, int period) {//Todo(to be continue neo)
}
private void addList(List<Balance> addlist, String acctCode, int period, BigDecimal value, ImportBalanceCount v) {
Balance balance = new Balance();
balance.setBalanceId(UUID.randomUUID().toString());
balance.setPeriodId(period);
balance.setAcctCode(acctCode);
balance.setBegDebitBal(new BigDecimal(0));
balance.setBegCreditBal(new BigDecimal(0));
balance.setBegBal(new BigDecimal(0));
balance.setDebitBal(v.debit);
balance.setCreditBal(v.credit);
balance.setEndDebitBal(v.direction == 0 ? value : new BigDecimal(0));
balance.setEndCreditBal(v.direction == 0 ? new BigDecimal(0) : value);
balance.setEndBal(value);
addlist.add(balance);
}
private void addList(List<Balance> addlist, String acctCode, int period) {
Balance balance = new Balance();
balance.setBalanceId(UUID.randomUUID().toString());
balance.setPeriodId(period);
balance.setAcctCode(acctCode);
balance.setBegDebitBal(new BigDecimal(0));
balance.setBegCreditBal(new BigDecimal(0));
balance.setBegBal(new BigDecimal(0));
balance.setDebitBal(new BigDecimal(0));
balance.setCreditBal(new BigDecimal(0));
balance.setEndDebitBal(new BigDecimal(0));
balance.setEndCreditBal(new BigDecimal(0));
balance.setEndBal(new BigDecimal(0));
balance.setIsDummy(0);
balance.setMonthId(period);
balance.setCustomerCode("");
addlist.add(balance);
}
private void validationAcctCode(int period, String userID) {//(todo to be continue (neo)
}
private void synAccountFromTaxAdmin(int period, String userID) {
ProjectExample example = new ProjectExample();
example.createCriteria().andDbNameEqualTo(PROJECT_DB_NAME);
......@@ -103,11 +471,66 @@ public class DataImportServiceImpl {
EnterpriseAccountExample accountExample = new EnterpriseAccountExample();
accountExample.createCriteria().andEnterpriseAccountSetIDEqualTo(easId);
List<EnterpriseAccount> taxList = enterpriseAccountMapper.selectByExample(accountExample);
taxList.stream().sorted(Comparator.comparing(EnterpriseAccount::getUpdateTime));
List<VatEnterpriseAccount> proList = vatEnterpriseAccountMapper.selectByExample(null);
proList.stream().sorted(Comparator.comparing(VatEnterpriseAccount::getCreateTime));
if (taxList != null && !taxList.isEmpty()) {
if (proList == null || proList.isEmpty() || (!proList.isEmpty() && proList.get(FIRST_OR_DEFAULT)
.getCreateTime().before(taxList.get(FIRST_OR_DEFAULT).getUpdateTime()))) {
accountExample.createCriteria().andEnglishNameEqualTo(easId);
synAccountData(enterpriseAccountMapper.selectByExample(accountExample), period, userID);
}
}
}
}
}
private void synAccountData(List<EnterpriseAccount> importList, int period, String userID) {
importList.stream().forEach(m -> {
VatEnterpriseAccountExample vatEnterpriseAccountExample = new VatEnterpriseAccountExample();
vatEnterpriseAccountExample.createCriteria().andAcctCodeEqualTo(m.getCode());
List<VatEnterpriseAccount> result = vatEnterpriseAccountMapper.selectByExample(vatEnterpriseAccountExample);
if (result == null || result.isEmpty()) {
VatEnterpriseAccount account = new VatEnterpriseAccount();
account.setID(UUID.randomUUID().toString());
account.setAcctCode(m.getCode());
account.setName(StringUtil.isEmpty(m.getName()) ? m.getCode() : m.getName());
account.setParentCode(m.getParentCode());
account.setFullName(m.getFullName());
account.setAcctProp(m.getAcctProp());
account.setSubProp(m.getSubProp());
account.setAcctLevel(m.getAcctLevel());
account.setDirection(m.getDirection());
account.setIsLeaf(m.getIsLeaf());
account.setIsActive(m.getIsActive());
account.setEnglishName(m.getEnglishName());
account.setStdCode(m.getStdCode());
account.setEnterpriseAccountSetID(m.getEnterpriseAccountSetID());
account.setIsDummy(0);
account.setIsInVoucher(0);
account.setCreatorID(userID);
account.setUpdatorID(userID);
account.setCreateTime(new Date());
account.setUpdateTime(new Date());
vatEnterpriseAccountMapper.insert(account);
} else if (!StringUtil.isNotEmpty(m.getName())) {
result.forEach(n -> {
if (!n.getName().equals(m.getName())) {
n.setName(m.getName());
n.setIsDummy(0);
n.setUpdatorID(userID);
n.setUpdateTime(new Date());
vatEnterpriseAccountMapper.updateByPrimaryKeySelective(n);
}
});
}
});
}
private void clearTableData(int period, String companyBalanceTable) {
if (period > 0) {
mapper.deleteByNameAndPeriod(companyBalanceTable, period);
......@@ -115,4 +538,11 @@ public class DataImportServiceImpl {
mapper.truncateByName(companyBalanceTable);
}
}
public static class ImportBalanceCount {
public String acctCode;
public BigDecimal debit;
public BigDecimal credit;
public int direction;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment