feature: send customized settle file

master
Yixian 3 years ago
parent 08beabca15
commit a641ac3ad1

@ -60,6 +60,8 @@ public interface CleanService {
void getCustomizedSettleABA(int logId, HttpServletResponse response); void getCustomizedSettleABA(int logId, HttpServletResponse response);
JSONObject sendCustomizedSettleMail(List<Integer> logIds);
void getSettlementFilesForBatch(String batchId, HttpServletResponse resp) throws IOException; void getSettlementFilesForBatch(String batchId, HttpServletResponse resp) throws IOException;
List<JSONObject> getCleanLogs(ClearingLogQuery query, JSONObject manager); List<JSONObject> getCleanLogs(ClearingLogQuery query, JSONObject manager);

@ -683,6 +683,18 @@ public class CleanServiceImpl implements CleanService, ManagerTodoNoticeProvider
if (log == null) { if (log == null) {
throw new NotFoundException("Settle log not found"); throw new NotFoundException("Settle log not found");
} }
ABAFile file = buildCustomizedABAFile(log);
response.setContentType("application/octet-stream;");
response.addHeader("Content-Disposition", "attachment; filename=" + file.filename());
try (OutputStream ous = response.getOutputStream()) {
ous.write(file.output(1));
ous.flush();
} catch (IOException e) {
throw new ServerErrorException("Output failed", e);
}
}
private ABAFile buildCustomizedABAFile(JSONObject log) {
String bank = log.getString("settle_bank"); String bank = log.getString("settle_bank");
BalanceGroup group = BalanceGroup.valueOf(log.getString("balance_group")); BalanceGroup group = BalanceGroup.valueOf(log.getString("balance_group"));
JSONObject settle = new JSONObject(); JSONObject settle = new JSONObject();
@ -694,15 +706,64 @@ public class CleanServiceImpl implements CleanService, ManagerTodoNoticeProvider
settle.put("account_name", log.getString("account_name")); settle.put("account_name", log.getString("account_name"));
settle.put("client_moniker", log.getString("client_moniker")); settle.put("client_moniker", log.getString("client_moniker"));
ABAFile file = generateSettleAbaFile(bank, group, new Date(), Collections.singletonList(settle)); ABAFile file = generateSettleAbaFile(bank, group, new Date(), Collections.singletonList(settle));
response.setContentType("application/octet-stream;"); String filename = String.format("[%s]Manual_Settle_%s_%s.aba", log.getIntValue("log_id"), log.getString("client_moniker"), DateTime.now().toString("yyyyMMdd"));
String filename = String.format("[%s]Manual_Settle_%s_%s.aba", logId, log.getString("client_moniker"), DateTime.now().toString("yyyyMMdd")); file.setFilename(filename);
response.addHeader("Content-Disposition", "attachment; filename=" + filename); return file;
try (OutputStream ous = response.getOutputStream()) { }
ous.write(file.output(1));
ous.flush(); @Override
} catch (IOException e) { public JSONObject sendCustomizedSettleMail(List<Integer> logIds) {
throw new ServerErrorException("Output failed", e); JSONObject result = new JSONObject();
try {
Date date = DateTime.now().withTimeAtStartOfDay().toDate();
String title = (PlatformEnvironment.getEnv().isDebug() ? "[TEST]" : "") + "Royalpay Manual Settlement Files " + DateFormatUtils.format(date, "yyyyMMdd");
List<JSONObject> customizedLogs = logIds.stream().map(customizedSettleLogMapper::find)
.filter(Objects::nonNull)
.collect(Collectors.toList());
List<ABAFile> abaFileList = customizedLogs.stream().map(this::buildCustomizedABAFile).collect(Collectors.toList());
List<JSONObject> attachList = abaFileList.stream()
.map(aba -> new JSONObject(Map.of("name", aba.filename(),
"content", Base64.encodeBase64String(aba.output(0)))))
.collect(Collectors.toList());
Context ctx = new Context();
ctx.setVariable("date", DateFormatUtils.format(date, "dd-MM-yyyy"));
ctx.setVariable("abaFiles", abaFileList);
BigDecimal total = abaFileList.stream().map(ABAFile::getTotalSettleAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
ctx.setVariable("totalAmount", total.setScale(2, RoundingMode.DOWN).toPlainString());
final String content = thymeleaf.process("mail/settlement_mail", ctx);
// 测试用地址
JSONObject config = sysConfigManager.getSysConfig();
String mailId = mailService.sendEmail(title, config.getString("settle_mail_to"), config.getString("settle_mail_cc"), content, attachList);
JSONObject settleMailRecord = new JSONObject();
settleMailRecord.put("send_date", new Date());
settleMailRecord.put("clearing_date", date);
settleMailRecord.put("email_id", mailId);
if (StringUtils.isEmpty(mailId)) {
result.put("result", 1);
result.put("msg", "System error");
settleMailRecord.put("mail_status", 0);
settleMailRecord.put("notice_status", 0);
logSettleMailMapper.save(settleMailRecord);
return result;
} else {
settleMailRecord.put("mail_status", 1);
settleMailRecord.put("notice_status", 0);
logSettleMailMapper.save(settleMailRecord);
} }
String detailDescription = customizedLogs.stream()
.map(log -> String.format("[%s]%s-%s", log.getString("log_id"),
log.getString("client_moniker"), log.getBigDecimal("amount")))
.collect(Collectors.joining(","));
sendTaskFinishMessages(ManagerRole.FINANCIAL_STAFF, "人工清算文件已发送清算方:" + detailDescription, "发送清算通知");
} catch (URISyntaxException | IOException e) {
logger.error("调用服务发送邮件时错误", e);
throw new ServerErrorException("IOError", e);
}
result.put("result", 0);
result.put("msg", "已发送");
return result;
} }
@Override @Override

@ -182,6 +182,12 @@ public class SettlementDevController {
cleanService.getCustomizedSettleABA(logId, response); cleanService.getCustomizedSettleABA(logId, response);
} }
@PostMapping("/customized_settle/sending_mail")
public JSONObject sendCustomizedSettleFile(@RequestBody JSONObject param){
List<Integer> ids = param.getJSONArray("ids").toJavaList(Integer.class);
return cleanService.sendCustomizedSettleMail(ids);
}
@GetMapping("/settle_batches/{batchId}/settle_files") @GetMapping("/settle_batches/{batchId}/settle_files")
public void getSettlementFilesForBatch(@PathVariable String batchId, HttpServletResponse resp) throws IOException { public void getSettlementFilesForBatch(@PathVariable String batchId, HttpServletResponse resp) throws IOException {
cleanService.getSettlementFilesForBatch(batchId, resp); cleanService.getSettlementFilesForBatch(batchId, resp);

@ -13,6 +13,7 @@ import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Optional;
public class ABAFile { public class ABAFile {
private final String baseLine = StringUtils.repeat(" ", 120); private final String baseLine = StringUtils.repeat(" ", 120);
@ -21,6 +22,7 @@ public class ABAFile {
private List<SettleMerchantInfo> settlements; private List<SettleMerchantInfo> settlements;
private BigDecimal totalSettleAmount; private BigDecimal totalSettleAmount;
private Date operateTime; private Date operateTime;
private String filename;
private String remark; private String remark;
public ABAFile(ABAConfig.ABABase base, Date settleDate) { public ABAFile(ABAConfig.ABABase base, Date settleDate) {
@ -138,8 +140,13 @@ public class ABAFile {
return operateTime; return operateTime;
} }
public ABAFile setFilename(String filename) {
this.filename = filename;
return this;
}
public String filename() { public String filename() {
return "Merchant_Settlement_Info_" + bank() + "_" + getOperateTimeString() + ".aba"; return Optional.ofNullable(filename).orElse("Merchant_Settlement_Info_" + bank() + "_" + getOperateTimeString() + ".aba");
} }
private class SettleMerchantInfo { private class SettleMerchantInfo {

@ -388,8 +388,21 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func
} }
}]); }]);
app.controller('customizedDialogCtrl', ['$scope', 'customizedLogs', function ($scope, customizedLogs) { app.controller('customizedDialogCtrl', ['$scope', '$http', 'commonDialog', 'customizedLogs', function ($scope, $http, commonDialog, customizedLogs) {
$scope.customizedLogs = customizedLogs.data $scope.customizedLogs = customizedLogs.data
$scope.sendMail = function () {
let selected = $scope.customizedLogs.filter(log => log.selected).map(log => log.log_id)
if (!selected.length) {
commonDialog.alert({type: 'error', title: 'Not Selected', content: 'No file selected to send'})
return
}
$http.post('/sys/settlement/customized_settle/sending_mail', {ids: selected}).then(function (resp) {
$scope.$dismiss()
commonDialog.alert({type: 'success', title: 'Success', content: resp.data.msg})
}, function (resp) {
commonDialog.alert({type: 'error', title: 'Send Email Failed', content: resp.data.message})
})
}
}]) }])
app.controller('settlementTransactionsCtrl', ['$scope', '$stateParams', 'detail', function ($scope, $stateParams, detail) { app.controller('settlementTransactionsCtrl', ['$scope', '$stateParams', 'detail', function ($scope, $stateParams, detail) {
$scope.ctrl = {channel: null}; $scope.ctrl = {channel: null};

@ -1,5 +1,6 @@
<div class="modal-header">Manual Settlements</div> <div class="modal-header">Manual Settlements</div>
<div class="modal-body"> <div class="modal-body">
<div class="alert alert-info">Click on row to choose file</div>
<table class="table table-striped table-bordered table-hover" ng-if="customizedLogs.length"> <table class="table table-striped table-bordered table-hover" ng-if="customizedLogs.length">
<thead> <thead>
<tr> <tr>
@ -9,8 +10,8 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="log in customizedLogs"> <tr ng-repeat="log in customizedLogs" ng-class="{'success':log.selected}">
<td ng-bind="log.client_moniker"></td> <td ng-bind="log.client_moniker" class="text-blue" title="Click to choose" style="cursor: pointer" ng-click="log.selected=!log.selected"></td>
<td ng-bind="log.amount|currency:''"></td> <td ng-bind="log.amount|currency:''"></td>
<td> <td>
<a title="Download" ng-href="{{log.aba_file}}" target="_blank"><i class="fa fa-download"></i></a> <a title="Download" ng-href="{{log.aba_file}}" target="_blank"><i class="fa fa-download"></i></a>
@ -23,5 +24,6 @@
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button class="btn btn-danger" ng-click="$dismiss()">OK</button> <button class="btn btn-success" ng-click="sendMail()">Send Email</button>
<button class="btn btn-danger" ng-click="$dismiss()">Close</button>
</div> </div>
Loading…
Cancel
Save