From de40d0d0eab74fa63a6d1f452e73c39e49bbf6bd Mon Sep 17 00:00:00 2001 From: yixian Date: Tue, 20 Mar 2018 20:17:26 +0800 Subject: [PATCH] manual settle request --- .../appclient/web/RetailAppController.java | 49 +++++-- .../payment/TaskManualSettleMapper.java | 31 ++++ .../mappers/payment/TransactionMapper.java | 2 + .../settlement/core/ManualSettleSupport.java | 16 +++ .../core/impls/ManualSettleSupportImpl.java | 81 +++++++++++ .../manage/settlement/package-info.java | 5 + .../mappers/payment/TransactionMapper.xml | 132 +++++++++++------- 7 files changed, 254 insertions(+), 62 deletions(-) create mode 100644 src/main/java/au/com/royalpay/payment/manage/mappers/payment/TaskManualSettleMapper.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/settlement/core/ManualSettleSupport.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/settlement/core/impls/ManualSettleSupportImpl.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/settlement/package-info.java diff --git a/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java b/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java index e6dea762c..4482b23ef 100644 --- a/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java +++ b/src/main/java/au/com/royalpay/payment/manage/appclient/web/RetailAppController.java @@ -11,6 +11,7 @@ import au.com.royalpay.payment.manage.bill.bean.QueryBillBean; import au.com.royalpay.payment.manage.bill.bean.QueryBillOrderBean; import au.com.royalpay.payment.manage.bill.core.BillOrderService; import au.com.royalpay.payment.manage.bill.core.BillService; +import au.com.royalpay.payment.manage.settlement.core.ManualSettleSupport; import au.com.royalpay.payment.manage.signin.beans.ChangePwdBean; import au.com.royalpay.payment.manage.signin.core.SignInStatusManager; import au.com.royalpay.payment.manage.system.core.ClientContractService; @@ -22,6 +23,7 @@ import au.com.royalpay.payment.tools.http.HttpUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.time.DateUtils; import org.springframework.validation.Errors; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; @@ -32,6 +34,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import java.math.BigDecimal; +import java.text.ParseException; +import java.util.Date; import java.util.List; import java.util.Map; @@ -58,6 +62,8 @@ public class RetailAppController { private AppActService appActService; @Resource private ClientContractService clientContractService; + @Resource + private ManualSettleSupport manualSettleSupport; @RequestMapping(value = "/token", method = RequestMethod.PUT) public void updateDevToken(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject token) { @@ -114,7 +120,7 @@ public class RetailAppController { @RequestMapping("/transaction_log/{clearing_detail_id}") public JSONObject getTransactionLogByClearingDetailId(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @PathVariable int clearing_detail_id, - @RequestParam(required = false) String timezone) { + @RequestParam(required = false) String timezone) { return retailAppService.getTransactionLogsByClearingDetailId(device, clearing_detail_id, timezone); } @@ -126,7 +132,7 @@ public class RetailAppController { @RequestMapping(value = "/notice/{noticeId}", method = RequestMethod.PUT) public void updateNoticePartnerHasRead(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @PathVariable String noticeId, - @RequestBody JSONObject account_param) { + @RequestBody JSONObject account_param) { if (!device.getString("account_id").equals(account_param.getString("account_id"))) { throw new ForbiddenException("You have no permission"); } @@ -147,7 +153,7 @@ public class RetailAppController { /* 我的页面begin */ @RequestMapping(value = "/partner_password/{account_id}", method = RequestMethod.PUT) public void changePassword(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @PathVariable String account_id, - @RequestBody @Valid ChangePwdBean change, Errors errors) { + @RequestBody @Valid ChangePwdBean change, Errors errors) { HttpUtils.handleValidErrors(errors); retailAppService.changeAccountPassword(device, change, account_id); } @@ -176,7 +182,7 @@ public class RetailAppController { /* 活动页面 begin */ @RequestMapping(value = "/activities", method = RequestMethod.GET) public JSONObject getActivities(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestParam(defaultValue = "activity_page") String type, - @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int limit) { + @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int limit) { return retailAppService.getActivities(device, type, page, limit); } @@ -220,7 +226,7 @@ public class RetailAppController { @RequestMapping(value = "/daily_transactions/date/{dateStr}", method = RequestMethod.GET) public JSONObject listDailyTransactions(@PathVariable String dateStr, @RequestParam(defaultValue = "Australia/Melbourne") String timezone, - @RequestParam(defaultValue = "false") boolean thisdevice, @ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { + @RequestParam(defaultValue = "false") boolean thisdevice, @ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { return retailAppService.listDailyTransactions(dateStr, timezone, thisdevice, device); } @@ -271,7 +277,7 @@ public class RetailAppController { @RequestMapping(value = "/cash_back/clean_info", method = RequestMethod.GET) public JSONObject getCashbackCleanInfo(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, - @RequestParam(value = "client_id", required = false) String client_id) { + @RequestParam(value = "client_id", required = false) String client_id) { if (client_id == null) { client_id = device.getString("client_id"); } @@ -287,7 +293,7 @@ public class RetailAppController { @RequestMapping(value = "/coupon/used", method = RequestMethod.GET) public JSONObject getCoupons(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestParam(value = "page", defaultValue = "1") int page, - @RequestParam(value = "limit", defaultValue = "10") int limit) { + @RequestParam(value = "limit", defaultValue = "10") int limit) { return retailAppService.getCoupons(device, page, limit); } @@ -339,15 +345,15 @@ public class RetailAppController { @RequestMapping(value = "/bills/orders/{bill_id}", method = RequestMethod.GET) public JSONObject getBillOrders(@PathVariable("bill_id") String bill_id, QueryBillOrderBean queryBillOrderBean, - @ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { + @ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { JSONObject result = billOrderService.query(bill_id, device.getIntValue("client_id"), queryBillOrderBean); result.put("analysis", billOrderService.analysis(bill_id, device.getIntValue("client_id"), queryBillOrderBean)); return result; } - @RequestMapping(value = "/acts",method = RequestMethod.GET) - public List getIndexAct(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device){ + @RequestMapping(value = "/acts", method = RequestMethod.GET) + public List getIndexAct(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { return appActService.listAppActs(); } @@ -373,12 +379,31 @@ public class RetailAppController { public JSONObject generateSourceAgreeFile(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { JSONObject file = clientContractService.getSourceAgreement(device.getIntValue("client_id")); JSONObject result = new JSONObject(); - result.put("file_url",file.getString("file_value")); + result.put("file_url", file.getString("file_value")); return result; } @RequestMapping(value = "/file/agree/confirm", method = RequestMethod.POST) public void confirmSourceAgreeFile(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { - clientContractService.confirmSourceAgreement(device.getIntValue("client_id"),device.getString("account_id"),"App"); + clientContractService.confirmSourceAgreement(device.getIntValue("client_id"), device.getString("account_id"), "App"); + } + + @RequestMapping(value = "/manual_settle", method = RequestMethod.GET) + public JSONObject getManualSettleStatus(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device) { + return manualSettleSupport.findCurrentSettle(device.getIntValue("client_id"), true); + } + + @RequestMapping(value = "/manual_settle", method = RequestMethod.PUT) + public JSONObject requestManualSettle(@ModelAttribute(CommonConsts.RETAIL_DEVICE) JSONObject device, @RequestBody JSONObject data) { + String settleToStr = data.getString("settle_to"); + if (settleToStr == null) { + throw new ParamInvalidException("settle_to", "error.payment.valid.param_missing"); + } + try { + Date setteTo = DateUtils.parseDate(settleToStr, "yyyy-MM-dd"); + return manualSettleSupport.requestManualSettle(setteTo, device.getString("account_id")); + } catch (ParseException e) { + throw new ParamInvalidException("settle_to", "error.payment.valid.invalid_time"); + } } } diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/payment/TaskManualSettleMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/payment/TaskManualSettleMapper.java new file mode 100644 index 000000000..735c80aea --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/payment/TaskManualSettleMapper.java @@ -0,0 +1,31 @@ +package au.com.royalpay.payment.manage.mappers.payment; + +import cn.yixblog.support.mybatis.autosql.annotations.AdvanceSelect; +import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper; +import cn.yixblog.support.mybatis.autosql.annotations.AutoSql; +import cn.yixblog.support.mybatis.autosql.annotations.SqlType; +import com.alibaba.fastjson.JSONObject; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * Create by yixian at 2018-03-20 18:05 + */ +@AutoMapper(tablename = "task_client_manual_settle", pkName = "task_id") +public interface TaskManualSettleMapper { + + @AutoSql(type = SqlType.SELECT) + @AdvanceSelect(addonWhereClause = "request_time>curdate()") + JSONObject findTodayTask(@Param("client_id") int clientId); + + @AutoSql(type = SqlType.SELECT) + @AdvanceSelect(addonWhereClause = "clearing_order is null") + List listActiveTasks(@Param("client_id") int clientId); + + @AutoSql(type = SqlType.INSERT) + void save(JSONObject task); + + @AutoSql(type = SqlType.UPDATE) + void update(JSONObject task); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.java index 97622c602..f6b91f73c 100644 --- a/src/main/java/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.java +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.java @@ -128,4 +128,6 @@ public interface TransactionMapper { List getClientRank(@Param("begin") Date begin, @Param("end") Date end); + List listClientUnsettleDataByDate(@Param("client_id") int clientId); + } diff --git a/src/main/java/au/com/royalpay/payment/manage/settlement/core/ManualSettleSupport.java b/src/main/java/au/com/royalpay/payment/manage/settlement/core/ManualSettleSupport.java new file mode 100644 index 000000000..5033a4028 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/settlement/core/ManualSettleSupport.java @@ -0,0 +1,16 @@ +package au.com.royalpay.payment.manage.settlement.core; + +import com.alibaba.fastjson.JSONObject; + +import java.util.Date; + +/** + * Create by yixian at 2018-03-20 17:42 + */ +public interface ManualSettleSupport { + + JSONObject requestManualSettle(Date settleTo, String accountId); + + JSONObject findCurrentSettle(int clientId, boolean includingUnsettleData); + +} diff --git a/src/main/java/au/com/royalpay/payment/manage/settlement/core/impls/ManualSettleSupportImpl.java b/src/main/java/au/com/royalpay/payment/manage/settlement/core/impls/ManualSettleSupportImpl.java new file mode 100644 index 000000000..1901358ad --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/settlement/core/impls/ManualSettleSupportImpl.java @@ -0,0 +1,81 @@ +package au.com.royalpay.payment.manage.settlement.core.impls; + +import au.com.royalpay.payment.manage.mappers.log.ClearingLogMapper; +import au.com.royalpay.payment.manage.mappers.payment.TaskManualSettleMapper; +import au.com.royalpay.payment.manage.mappers.payment.TransactionMapper; +import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper; +import au.com.royalpay.payment.manage.settlement.core.ManualSettleSupport; +import au.com.royalpay.payment.tools.exceptions.BadRequestException; +import au.com.royalpay.payment.tools.exceptions.ForbiddenException; +import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; + +/** + * Create by yixian at 2018-03-20 17:44 + */ +@Service +public class ManualSettleSupportImpl implements ManualSettleSupport { + + @Resource + private MerchantInfoProvider merchantInfoProvider; + @Resource + private TransactionMapper transactionMapper; + @Resource + private TaskManualSettleMapper taskManualSettleMapper; + @Resource + private ClearingLogMapper clearingLogMapper; + @Resource + private ClientAccountMapper clientAccountMapper; + + @Override + public JSONObject requestManualSettle(Date settleTo, String accountId) { + JSONObject account = clientAccountMapper.findById(accountId); + int clientId = account.getIntValue("client_id"); + JSONObject client = merchantInfoProvider.getClientInfo(clientId); + if (!client.getBooleanValue("manual_settle")) { + throw new ForbiddenException("Manual Settlement Not Enabled"); + } + if (DateUtils.isSameDay(new Date(), settleTo)) { + throw new BadRequestException("Cannot settle today's transactions"); + } + JSONObject currentTask = findCurrentSettle(clientId, false); + String taskId = currentTask.getString("task_id"); + currentTask.put("request_time", new Date()); + currentTask.put("client_id", clientId); + currentTask.put("applier_id", account.getString("account_id")); + currentTask.put("applier_name", account.getString("display_name")); + currentTask.put("settle_to", settleTo); + if (taskId != null) { + taskManualSettleMapper.update(currentTask); + } else { + taskManualSettleMapper.save(currentTask); + } + return currentTask; + } + + @Override + public JSONObject findCurrentSettle(int clientId, boolean includingUnsettleData) { + JSONObject todayTask = taskManualSettleMapper.findTodayTask(clientId); + if (todayTask != null) { + todayTask.put("settle_to", DateFormatUtils.format(todayTask.getDate("settle_to"), "yyyy-MM-dd")); + } else { + todayTask = new JSONObject(); + } + List settleLogs = clearingLogMapper.findByDate(new Date()); + //今天未清算则锁定 + todayTask.put("locked", settleLogs.isEmpty()); + if (includingUnsettleData) { + List unsettleReports = transactionMapper.listClientUnsettleDataByDate(clientId); + unsettleReports.parallelStream().forEach(report -> report.put("date_str", DateFormatUtils.format(report.getDate("trans_date"), "yyyy-MM-dd"))); + todayTask.put("unsettle", unsettleReports); + } + return todayTask; + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/settlement/package-info.java b/src/main/java/au/com/royalpay/payment/manage/settlement/package-info.java new file mode 100644 index 000000000..51ea13c08 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/settlement/package-info.java @@ -0,0 +1,5 @@ +/** + * 清算相关 + * Create by yixian at 2018-03-20 17:42 + */ +package au.com.royalpay.payment.manage.settlement; \ No newline at end of file diff --git a/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml b/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml index 18cd984c7..0ee0981d6 100644 --- a/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml +++ b/src/main/resources/au/com/royalpay/payment/manage/mappers/payment/TransactionMapper.xml @@ -31,20 +31,22 @@ and t.refund_id is NOT NULL and t.transaction_type='Debit' and t.refund_id is NULL - and o.channel=#{chan} + and + o.channel=#{chan} + @@ -172,12 +186,16 @@ and t.transaction_time < #{to} @@ -298,7 +317,8 @@ and c.client_moniker=#{client_moniker} and c.org_id = #{org_id} and c.org_id in - #{org_id} + #{org_id} + GROUP BY c.client_id order by total desc @@ -317,7 +337,8 @@ and c.client_moniker=#{client_moniker} and c.org_id = #{org_id} and c.org_id in - #{org_id} + #{org_id} + @@ -525,33 +546,33 @@ = t.transaction_time AND - r.rate_name = 'Wechat'), 1) wechat_rate_value, + r.rate_name = 'Wechat'), 1) wechat_rate_value, ifnull((SELECT min(r.rate_value) FROM sys_client_rates r WHERE r.client_id = t.client_id AND r.active_time <= t.transaction_time AND r.expiry_time >= t.transaction_time AND - r.rate_name = 'Alipay'), 1) alipay_rate_value, + r.rate_name = 'Alipay'), 1) alipay_rate_value, ifnull((SELECT min(r.rate_value) FROM sys_client_rates r WHERE r.client_id = t.client_id AND r.active_time <= t.transaction_time AND r.expiry_time >= t.transaction_time AND - r.rate_name = 'Bestpay'), 1) bestpay_rate_value, + r.rate_name = 'Bestpay'), 1) bestpay_rate_value, ifnull((SELECT min(r.rate_value) FROM sys_client_rates r WHERE r.client_id = t.client_id AND r.active_time <= t.transaction_time AND r.expiry_time >= t.transaction_time AND - r.rate_name = 'jd'), 1) jd_rate_value, + r.rate_name = 'jd'), 1) jd_rate_value, ifnull((SELECT min(r.rate_value) FROM sys_client_rates r WHERE r.client_id = t.client_id AND r.active_time <= t.transaction_time AND @@ -561,7 +582,7 @@ INNER JOIN sys_clients c ON c.client_id = t.client_id INNER JOIN sys_org so ON c.org_id = so.org_id AND so.is_valid = 1 AND so.type = 0 AND so.parent_org_id = #{parent_org_id} - WHERE year(t.transaction_time) = #{year} AND month(t.transaction_time) = #{month} AND t.channel != 'Settlement' + WHERE year(t.transaction_time) = #{year} AND month(t.transaction_time) = #{month} AND t.channel != 'Settlement' GROUP BY t.client_id, trade_date, channel ORDER BY c.org_id ASC, t.client_id ASC, trade_date ASC ]]> @@ -676,7 +697,8 @@ select sum(if(t.transaction_type='Credit',settle_amount,-settle_amount)) settle_amount , DATE_FORMAT(t.transaction_time,'%Y%m%d') weekend from pmt_transactions t - INNER JOIN log_clearing_detail d on d.clear_detail_id=t.clearing_order and DAYOFWEEK(d.report_date)>2 and clear_days = 1 + INNER JOIN log_clearing_detail d on d.clear_detail_id=t.clearing_order and DAYOFWEEK(d.report_date)>2 and + clear_days = 1 where (DAYOFWEEK(t.transaction_time)=1 or DAYOFWEEK(t.transaction_time) = 7) and t.transaction_time > #{begin} @@ -722,5 +744,15 @@ and t.clearing_order is not NULL group by client_id + \ No newline at end of file