优化记账模块,设计清算日期、结算日期、记账日期三个条件
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtl.java
index 85bac09..7c288bd 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TDebitCreditDtl.java
@@ -15,8 +15,8 @@
   @Column(name = "SEQNO", nullable = false, precision = 2)
   private Integer seqno;
 
-  @Column(name = "accdate", nullable = false, length = 8)
-  private String accdate;
+  @Column(name = "settledate", nullable = false, length = 8)
+  private String settleDate;
 
   @Column(name = "DRSUBJNO", length = 10)
   private String drsubjno; //借方科目
@@ -101,11 +101,11 @@
     this.summary = summary;
   }
 
-  public String getAccdate() {
-    return accdate;
+  public String getSettleDate() {
+    return settleDate;
   }
 
-  public void setAccdate(String accdate) {
-    this.accdate = accdate;
+  public void setSettleDate(String settleDate) {
+    this.settleDate = settleDate;
   }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java b/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
index d65da13..95a7b0f 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TShopdtl.java
@@ -1,5 +1,7 @@
 package com.supwisdom.dlpay.api.domain;
 
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+
 import javax.persistence.*;
 
 @Entity
@@ -45,6 +47,9 @@
   @Column(name = "TRANSDESC", length = 240)
   private String transdesc; //交易描述
 
+  @Column(name = "reverseflag", length = 10)
+  private String reverseFlag;
+
   @Column(name = "status", length = 20)
   private String status;
 
@@ -184,4 +189,12 @@
   public void setRemark(String remark) {
     this.remark = remark;
   }
+
+  public String getReverseFlag() {
+    return reverseFlag;
+  }
+
+  public void setReverseFlag(String reverseFlag) {
+    this.reverseFlag = reverseFlag;
+  }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java b/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
index a4969cb..fa3fc8d 100644
--- a/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
+++ b/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionMain.java
@@ -20,6 +20,12 @@
   @Column(name = "accdate", nullable = false, length = 8)
   private String accdate;
 
+  @Column(name = "checkable")
+  private Boolean checkable; // 是否需要清算的交易
+
+  @Column(name = "checkdate", length = 8)
+  private String checkDate;
+
   @Column(name = "person")
   private Boolean person = false;
 
@@ -51,7 +57,7 @@
   private Timestamp endTime;
 
   @Column(name = "reverse_flag", nullable = false, length = 10)
-  private String reverseFlag = "none";
+  private String reverseFlag = "none"; // 冲正标识, none - 未冲正, reverse - 被撤销, cancel - 被冲正
 
   @OneToOne(targetEntity = TPersondtl.class, fetch = LAZY, cascade = CascadeType.ALL)
   @JoinColumn(name = "refno", referencedColumnName = "refno")
@@ -206,6 +212,22 @@
     this.opertype = opertype;
   }
 
+  public String getCheckDate() {
+    return checkDate;
+  }
+
+  public void setCheckDate(String checkDate) {
+    this.checkDate = checkDate;
+  }
+
+  public Boolean getCheckable() {
+    return checkable;
+  }
+
+  public void setCheckable(Boolean checkable) {
+    this.checkable = checkable;
+  }
+
   public Double sumAmountByAccno(String accno, String subjno,
                                  int balanceFlag, String debitOrCredit) {
     Double debitSum = 0.0;
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
index 461f6dd..1b68789 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/consume_api_controller.kt
@@ -99,7 +99,7 @@
                 builder.addDebitCreditRecord(AccountProxy(person), AccountProxy(shop),
                         amount, feetypeConfig.summary)
                         .shop().also {
-                            it.amount += amount
+                            it.addAmount(amount)
                         }
             }
             else -> {
@@ -149,23 +149,18 @@
                 val shopacc = accountUtilServcie.readShopbyShopaccno(param.shopaccno)
 
                 val builder = TransactionBuilder().apply {
-                    transDate = param.transdate
-                    transTime = param.transtime
-                    paytype = TradeDict.PAYTYPE_BALANCE
-                    transCode = TradeCode.TRANSCODE_BALANCE_PAY
-                    payinfo = "账户余额消费"
-                    outId = shopacc.shopaccno
-                    outtradeno = param.billno
+                    setTransInfo(param.transdate, param.transtime, TradeCode.TRANSCODE_BALANCE_PAY, false)
+                    setOutTransInfo(shopacc.shopaccno, param.billno)
                     operator(param.shopaccno, TradeDict.OPERTYPE_SHOP)
-                }.person(account).apply {
+                    paytype = TradeDict.PAYTYPE_BALANCE
+                    payinfo = "账户余额消费"
                     description = "账户余额消费"
-                    amount = param.amount / 100.0
+                }.person(account).apply {
+                    setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT)
                     opposite = AccountProxy(shopacc)
-                    tradeOut()
                 }.and().shop(shopacc).apply {
-                    amount = param.amount / 100.0
+                    setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_IN)
                     opposite = AccountProxy(account)
-                    tradeIn()
                 }.and()
 
                 param.feelist?.forEach {
@@ -223,23 +218,18 @@
                 val shopacc = accountUtilServcie.readShopbyShopaccno(param.shopaccno)
                 val subject = accountUtilServcie.readSubject(Subject.SUBJNO_PAY_CITIZEN_CARD)
                 val transaction = TransactionBuilder().apply {
-                    transCode = TradeCode.TRANSCODE_CITIZENCARD_PAY
-                    transDate = param.transdate
-                    transTime = param.transtime
+                    setTransInfo(param.transdate, param.transtime, TradeCode.TRANSCODE_CITIZENCARD_PAY, true)
+                    setOutTransInfo(shopacc.shopaccno, param.billno)
+                    operator(param.shopaccno, TradeDict.OPERTYPE_SHOP)
                     paytype = TradeDict.PAYTYPE_CITIZEN_CARD
                     payinfo = "市民卡代扣消费"
                     description = "市民卡代扣消费"
-                    outId = shopacc.shopaccno
-                    outtradeno = param.billno
-                    operator(param.shopaccno, TradeDict.OPERTYPE_SHOP)
                 }.person(account).apply {
-                    amount = param.amount / 100.0
+                    setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_OUT)
                     opposite = AccountProxy(shopacc)
-                    tradeOut()
                 }.and().shop(shopacc).apply {
-                    amount = param.amount / 100.0
+                    setAmount(param.amount / 100.0, TradeDict.TRADE_FLAG_IN)
                     opposite = AccountProxy(account)
-                    tradeIn()
                 }.and().addDebitCreditRecord(AccountProxy(subject), AccountProxy(account),
                         param.amount / 100.0, "市民卡代扣消费")
                         .addDebitCreditRecord(AccountProxy(account), AccountProxy(shopacc),
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
index 1948116..a972d3f 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt
@@ -57,6 +57,7 @@
                 createTime = Timestamp(systemUtilService.sysdatetime.sysdate.time)
                 operid = builder.operId
                 opertype = builder.operType
+                reverseFlag = builder.tradeType
             }
 
             if (builder.hasPerson()) {
@@ -70,7 +71,7 @@
                     transdate = builder.transDate
                     transtime = builder.transTime
                     befbal = builder.person().person.availbal
-                    amount = if (builder.person().tradeFlag() == TradeDict.TRADE_FLAG_IN) {
+                    amount = if (builder.person().tradeFlag == TradeDict.TRADE_FLAG_IN) {
                         builder.person().amount
                     } else {
                         -builder.person().amount
@@ -78,11 +79,11 @@
                     paytype = builder.person().paytype
                     payinfo = builder.person().payinfo
                     transcode = builder.transCode
-                    tradeflag = builder.person().tradeFlag()
+                    tradeflag = builder.person().tradeFlag
                     transdesc = builder.person().description
                     oppositeAccNo = builder.person().opposite.getAccountNo()
                     oppositeAccName = builder.person().opposite.getAccountName()
-                    reverseFlag = builder.reverseFlag
+                    this.reverseFlag = TradeDict.REVERSE_FLAG_NONE
                     remark = builder.person().remark
                     this.status = status
                 }.also {
@@ -102,18 +103,19 @@
                     this.transDate = builder.transDate
                     this.transTime = builder.transTime
                     this.tradeCode = builder.transCode
-                    amount = if (builder.shop().tradeFlag() == TradeDict.TRADE_FLAG_IN) {
+                    amount = if (builder.shop().tradeFlag == TradeDict.TRADE_FLAG_IN) {
                         builder.shop().amount
                     } else {
                         -builder.shop().amount
                     }
-                    this.tradeflag = builder.shop().tradeFlag()
+                    this.tradeflag = builder.shop().tradeFlag
                     this.shopaccno = builder.shop().shopacc.shopaccno
                     this.shopname = builder.shop().shopacc.shopname
                     this.transdesc = builder.shop().description
                     this.oppositeAccNo = builder.shop().opposite.getAccountNo()
                     this.oppositeAccName = builder.shop().opposite.getAccountName()
                     this.remark = builder.shop().remark
+                    this.reverseFlag = TradeDict.REVERSE_FLAG_NONE
                     this.status = status
                 }.also {
                     // save shopdtl
@@ -144,7 +146,6 @@
             builder.getAllDetails().map { line ->
                 TDebitCreditDtl().apply {
                     this.refno = transaction.refno
-                    this.accdate = transaction.accdate
                     this.seqno = line.seqno
                     this.draccno = line.debit.getAccountNo()
                     this.drsubjno = line.debit.getSubjectNo()
@@ -159,7 +160,7 @@
 
 
             if (builder.hasPerson()) {
-                val dc = getDebitOrCredit(builder.person().tradeFlag())
+                val dc = getDebitOrCredit(builder.person().tradeFlag)
                 transaction.sumAmountByAccno(builder.person().person.accno,
                         Subject.SUBJNO_PERSONAL_DEPOSIT,
                         PERSON_BALANCE_FLAG, dc).also {
@@ -171,7 +172,7 @@
             }
 
             if (builder.hasShop()) {
-                val dc = getDebitOrCredit(builder.shop().tradeFlag())
+                val dc = getDebitOrCredit(builder.shop().tradeFlag)
                 transaction.sumAmountByAccno(builder.shop().shopacc.shopaccno,
                         Subject.SUBJNO_MACHANT_INCOME,
                         SHOP_BALANCE_FLAG, dc).also {
@@ -308,6 +309,46 @@
         }
         transaction.status = TradeDict.DTL_STATUS_SUCCESS
         transaction.accdate = systemUtilService.accdate
+        transactionOnSuccess(transaction, remark, false)
+
+        transaction.endTime = Timestamp(systemUtilService.sysdatetime.sysdate.time)
+        transactionMainDao.save(transaction)
+        return transaction
+    }
+
+    override fun reverse(originRefno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun reverseInit(originRefno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun reverseConfirm(refno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun reverseFail(refno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun cancel(originRefno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun cancelInit(originRefno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun cancelConfirm(refno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    override fun cancelFail(refno: String): TTransactionMain {
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+    }
+
+    private fun transactionOnSuccess(transaction: TTransactionMain, remark: String, overdraft: Boolean) {
         if (transaction.person) {
             // update account balance
             val amount = transaction.sumAmountByAccno(
@@ -315,7 +356,7 @@
                     PERSON_BALANCE_FLAG, "both")
             if (amount.compareTo(0.0) != 0) {
                 transaction.personDtl?.let {
-                    if (accountRepository.recalcAccountBalance(it, amount, false) != 1) {
+                    if (accountRepository.recalcAccountBalance(it, amount, overdraft) != 1) {
                         throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY,
                                 "个人账户交易冲突")
                     }
@@ -333,7 +374,7 @@
                     SHOP_BALANCE_FLAG, "both")
             if (amount.compareTo(0.0) != 0) {
                 transaction.shopDtl?.let {
-                    if (shopaccRepository.recalcShopBalance(it, it.amount, false) != 1) {
+                    if (shopaccRepository.recalcShopBalance(it, it.amount, overdraft) != 1) {
                         throw TransactionProcessException(TradeErrorCode.ACCOUNT_TRADE_BUSY,
                                 "商户账户交易冲突")
                     }
@@ -348,8 +389,24 @@
         if (transaction.subject) {
             // update subject balance
         }
+    }
 
+    override fun repair(refno: String, remark: String): TTransactionMain {
+        val transaction = transactionMainDao.findByRefnoForUpdate(refno)
+                ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS,
+                        "补帐交易流水<$refno>不存在")
+        val checkStatus = setOf(TradeDict.DTL_STATUS_FAIL, TradeDict.DTL_STATUS_CANCEL,
+                TradeDict.DTL_STATUS_WIP)
+
+        if (transaction.status !in checkStatus) {
+            throw TransactionCheckException(TradeErrorCode.TRANSDTL_STATUS_ERROR,
+                    "补帐交易<$refno>状态错误,status<${transaction.status}>")
+        }
+
+        transactionOnSuccess(transaction, remark, true)
+        transaction.checkDate = systemUtilService.accdate
         transaction.endTime = Timestamp(systemUtilService.sysdatetime.sysdate.time)
+
         transactionMainDao.save(transaction)
         return transaction
     }
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt b/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
index 4113740..f0acef4 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt
@@ -1,7 +1,6 @@
 package com.supwisdom.dlpay.api.service
 
 import com.supwisdom.dlpay.api.TransactionBuilder
-import com.supwisdom.dlpay.api.domain.TAccount
 import com.supwisdom.dlpay.api.domain.TTransactionMain
 import org.springframework.transaction.annotation.Propagation
 import org.springframework.transaction.annotation.Transactional
@@ -27,8 +26,35 @@
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
     fun success(refno: String, remark: String): TTransactionMain
-}
 
-interface PersonAccountService {
-    fun recalcBalance(account: TAccount, amount: Double)
-}
\ No newline at end of file
+    // 撤销接口冲正类接口
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+    fun reverse(originRefno: String): TTransactionMain
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+    fun reverseInit(originRefno: String): TTransactionMain
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+    fun reverseConfirm(refno: String): TTransactionMain
+
+    fun reverseFail(refno: String): TTransactionMain
+
+    // 冲正类接口
+    /**
+     * 冲正业务
+     */
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+    fun cancel(originRefno: String): TTransactionMain
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+    fun cancelInit(originRefno: String): TTransactionMain
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+    fun cancelConfirm(refno: String): TTransactionMain
+
+    fun cancelFail(refno: String): TTransactionMain
+
+    // 补帐接口
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = [Exception::class])
+    fun repair(refno: String, remark: String): TTransactionMain
+}
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
index 5d379fe..15a23d4 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/transaction_builder.kt
@@ -2,16 +2,14 @@
 
 import com.supwisdom.dlpay.api.domain.TAccount
 import com.supwisdom.dlpay.api.domain.TTransactionMain
-import com.supwisdom.dlpay.api.service.AccountUtilServcie
 import com.supwisdom.dlpay.api.service.TransactionService
 import com.supwisdom.dlpay.exception.TransactionCheckException
 import com.supwisdom.dlpay.framework.domain.TShopacc
 import com.supwisdom.dlpay.framework.domain.TSubject
-import com.supwisdom.dlpay.framework.util.Subject
 import com.supwisdom.dlpay.framework.util.TradeDict
 import com.supwisdom.dlpay.framework.util.TradeErrorCode
 
-open class SubTransactionBuilder(val parent: TransactionBuilder) {
+open class SubTransactionBuilder<T : SubTransactionBuilder<T>>(val parent: TransactionBuilder) {
     var paytype: String = ""
         get() {
             return if (field.isEmpty()) parent.paytype else field
@@ -42,38 +40,42 @@
         return parent
     }
 
-    private var balanceInOut: String = ""
+    // 收支方向, in / out
+    var tradeFlag: String = ""
+        private set
 
-    fun tradeIn(): SubTransactionBuilder {
-        this.balanceInOut = TradeDict.TRADE_FLAG_IN
+    var amount: Double = 0.0
+        private set
+
+    /**
+     * amount : 交易金额, 正向交易金额必须 >= 0, 冲正交易金额必须 <= 0
+     */
+    fun setAmount(amount: Double, inOut: String): SubTransactionBuilder<T> {
+        this.amount = amount
+        this.tradeFlag = inOut
         return this
     }
 
-    fun tradeOut(): SubTransactionBuilder {
-        this.balanceInOut = TradeDict.TRADE_FLAG_OUT
+    /**
+     * amount : 交易金额, 正向交易金额必须 >= 0, 冲正交易金额必须 <= 0
+     */
+    fun addAmount(amount: Double): SubTransactionBuilder<T> {
+        this.amount += amount
         return this
     }
 
-    fun tradeFlag(): String {
-        return this.balanceInOut
-    }
-
-
 }
 
 class PersonTranactionBuilder(parent: TransactionBuilder, val person: TAccount)
-    : SubTransactionBuilder(parent) {
-    var amount: Double = 0.0
+    : SubTransactionBuilder<PersonTranactionBuilder>(parent) {
 }
 
 class ShopTransactionBuilder(parent: TransactionBuilder, val shopacc: TShopacc)
-    : SubTransactionBuilder(parent) {
-    var amount: Double = 0.0
+    : SubTransactionBuilder<ShopTransactionBuilder>(parent) {
 }
 
 class SubjectTransactionBuilder(parent: TransactionBuilder, val subject: TSubject)
-    : SubTransactionBuilder(parent) {
-    var amount: Double = 0.0
+    : SubTransactionBuilder<SubjectTransactionBuilder>(parent) {
 }
 
 class AccountProxy<T>(private val accountObj: T) {
@@ -118,26 +120,59 @@
 
 // 在 constructor 中加入 service 接口
 class TransactionBuilder {
+    companion object {
+        private val VALID_REVERSEFLAG = setOf(TradeDict.REVERSE_FLAG_CANCEL,
+                TradeDict.REVERSE_FLAG_REVERSE,
+                TradeDict.REVERSE_FLAG_NONE)
+
+        private val VALID_OPERTYPE = setOf(TradeDict.OPERTYPE_OPER,
+                TradeDict.OPERTYPE_SHOP, TradeDict.OPERTYPE_PERSON)
+
+        private val VALID_TRADEFLAG = setOf(TradeDict.TRADE_FLAG_IN,
+                TradeDict.TRADE_FLAG_OUT)
+    }
+
     private lateinit var personBuilder: PersonTranactionBuilder
     private lateinit var shopBuilder: ShopTransactionBuilder
     private lateinit var subjectBuilder: SubjectTransactionBuilder
 
     private val debitCreditLines = mutableListOf<DebitCreditLine>()
 
+    // 以下是交易主表属性
     var transDate: String = ""
+        private set
     var transTime: String = ""
+        private set
     var transCode: Int = 0 //交易码,各明细流水统一
-    var refno: String = ""
-    var paytype: String = ""
-    var payinfo: String = ""
+        private set
+
+    // 是否需要清算的交易
+    var checkable: Boolean = false
+        private set
+
+    fun setTransInfo(date: String, time: String, code: Int, checkable: Boolean = false): TransactionBuilder {
+        this.transDate = date
+        this.transTime = time
+        this.transCode = code
+        this.checkable = checkable
+        return this
+    }
+
     var outtradeno: String = "" //第三方流水号
+        private set
     var outId: String = ""
-    var reverseFlag: String = "none"
-    var description: String = ""
-    var remark: String = ""
+        private set
+
+    fun setOutTransInfo(id: String, tradeno: String): TransactionBuilder {
+        this.outId = id
+        this.outtradeno = tradeno
+        return this
+    }
 
     var operId: String = ""
+        private set
     var operType: String = ""
+        private set
 
     fun operator(id: String, type: String): TransactionBuilder {
         this.operId = id
@@ -145,6 +180,26 @@
         return this
     }
 
+    var tradeType: String = "none"
+        private set
+
+    fun reverse(): TransactionBuilder {
+        this.tradeType = TradeDict.REVERSE_FLAG_REVERSE
+        return this
+    }
+
+    fun cancel(): TransactionBuilder {
+        this.tradeType = TradeDict.REVERSE_FLAG_CANCEL
+        return this
+    }
+
+
+    // 以下属性可以在子表中不同
+    var paytype: String = ""
+    var payinfo: String = ""
+    var description: String = ""
+    var remark: String = ""
+
     fun person(): PersonTranactionBuilder {
         return this.personBuilder
     }
@@ -210,6 +265,14 @@
         return debitCreditLines.toList()
     }
 
+    private fun checkAmount(amount: Double): Boolean {
+        return if (tradeType == TradeDict.REVERSE_FLAG_NONE) {
+            amount >= 0.0
+        } else {
+            amount <= 0.0
+        }
+    }
+
     fun preCheck() {
         if (outId.isNotEmpty() && outtradeno.isEmpty()) {
             throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
@@ -226,14 +289,27 @@
                     "交易码错误")
         }
 
+        if (tradeType !in VALID_REVERSEFLAG) {
+            throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+                    "冲正标志错误")
+        }
+
         if ((operId.isNotEmpty() || operType.isNotEmpty())
-                && operType !in setOf(TradeDict.OPERTYPE_OPER, TradeDict.OPERTYPE_PERSON, TradeDict.OPERTYPE_SHOP)) {
+                && operType !in VALID_OPERTYPE) {
             throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
                     "操作员类型错误")
         }
 
         if (hasPerson()) {
             person().also {
+                if (it.tradeFlag !in VALID_TRADEFLAG) {
+                    throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+                            "个人交易收支方向错误")
+                }
+                if (!checkAmount(it.amount)) {
+                    throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+                            "个人交易金额不正确")
+                }
                 if (!it.hasOpposite()) {
                     throw  TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
                             "个人交易对方账户未设置")
@@ -242,51 +318,23 @@
                     throw  TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
                             "个人交易信息未设置")
                 }
-                when (it.tradeFlag()) {
-                    TradeDict.TRADE_FLAG_IN -> {
-                        throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
-                                "不支持的交易")
-                    }
-                    TradeDict.TRADE_FLAG_OUT -> {
-                        if (reverseFlag != TradeDict.REVERSE_FLAG_NONE && it.amount > 0) {
-                            throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
-                                    "消费冲正交易,余额不能大于0")
-                        } else if (reverseFlag == TradeDict.REVERSE_FLAG_NONE && it.amount < 0) {
-                            throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
-                                    "消费交易,余额不能小于0")
-                        }
-                    }
-                    else -> {
-                        throw  TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
-                                "个人交易方向未设置")
-                    }
-                }
-
             }
         }
 
         if (hasShop()) {
             shop().also {
+                if (it.tradeFlag !in VALID_TRADEFLAG) {
+                    throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+                            "商户交易收支方向错误")
+                }
+                if (!checkAmount(it.amount)) {
+                    throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
+                            "商户交易金额不正确")
+                }
                 if (!it.hasOpposite()) {
                     throw  TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
                             "商户交易对方账户未设置")
                 }
-                when (it.tradeFlag()) {
-                    TradeDict.TRADE_FLAG_IN -> {
-                        if (it.amount < 0) {
-                            throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
-                                    "商户收入交易金额不能小于0")
-                        }
-                    }
-                    TradeDict.TRADE_FLAG_OUT -> {
-                        if (it.amount > 0) {
-                            throw TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
-                                    "商户支出交易金额不能小于0")
-                        }
-                    }
-                    else -> throw  TransactionCheckException(TradeErrorCode.INPUT_DATA_ERROR,
-                            "商户交易方向未设置")
-                }
             }
         }
     }
@@ -298,4 +346,12 @@
     fun wip(transactionService: TransactionService): TTransactionMain {
         return transactionService.wip(this)
     }
+
+    fun cancel(transactionService: TransactionService, originRefno: String): TTransactionMain {
+        TODO("not implement")
+    }
+
+    fun reverse(transactionService: TransactionService, originRefno: String, amount: Double): TTransactionMain {
+        TODO("not implement")
+    }
 }