TransferUtils.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. package com.ydtech.modules.inv.utils;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.ydtech.exception.SystemException;
  4. import com.ydtech.modules.inv.model.*;
  5. import java.math.BigDecimal;
  6. import java.math.RoundingMode;
  7. import java.time.LocalDateTime;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.Map;
  11. /**
  12. * 转账工具类
  13. *
  14. * @author jianlong
  15. * @date 2024-01-10 14:10
  16. */
  17. public class TransferUtils {
  18. /**
  19. * 插入收入归属
  20. * @param entProfit
  21. * @param entAccount
  22. * @param entAccountCard
  23. * @param applyAmount
  24. * @return
  25. */
  26. public static List<InvAccountOp> invAccountEntOpList(JSONObject entProfit,InvAccount entAccount, InvAccountCard entAccountCard, String applyAmount){
  27. List<InvAccountOp> list = new ArrayList<>();
  28. if (entProfit != null) {
  29. for (Map.Entry<String, Object> entry : entProfit.entrySet()) {
  30. if (Integer.parseInt(entry.getValue().toString()) != 0) {
  31. InvAccountOp invAccountOp = new InvAccountOp();
  32. invAccountOp.setAccountId(entAccount.getAccountId());
  33. invAccountOp.setAccountName(entAccount.getAccountName());
  34. invAccountOp.setCardNum(entAccountCard.getBankCardNum());
  35. invAccountOp.setCardName(entAccountCard.getBankName());
  36. invAccountOp.setProfit(entry.getKey());
  37. invAccountOp.setMoney(new BigDecimal(entry.getValue().toString()).multiply(new BigDecimal(applyAmount)).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString());
  38. list.add(invAccountOp);
  39. }
  40. }
  41. }
  42. return list;
  43. }
  44. /**
  45. * 插入支出归属
  46. * @param outProfit
  47. * @param outAccount
  48. * @param outAccountCard
  49. * @param applyAmount
  50. * @return
  51. */
  52. public static List<InvAccountOp> invAccountOutOpList(JSONObject outProfit,InvAccount outAccount, InvAccountCard outAccountCard, String applyAmount){
  53. List<InvAccountOp> list = new ArrayList<>();
  54. for (Map.Entry<String, Object> entry : outProfit.entrySet()) {
  55. if (Integer.parseInt(entry.getValue().toString()) != 0) {
  56. InvAccountOp invAccountOp = new InvAccountOp();
  57. invAccountOp.setAccountId(outAccount.getAccountId());
  58. invAccountOp.setAccountName(outAccount.getAccountName());
  59. invAccountOp.setCardNum(outAccountCard.getBankCardNum());
  60. invAccountOp.setCardName(outAccountCard.getBankName());
  61. invAccountOp.setProfit(entry.getKey());
  62. invAccountOp.setMoney(new BigDecimal(String.valueOf(entry.getValue())).multiply(new BigDecimal(applyAmount)).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP).negate().toString());
  63. list.add(invAccountOp);
  64. }
  65. }
  66. return list;
  67. }
  68. /**
  69. * 转账成功后添加支出账户操作信息
  70. */
  71. public static InvAccountOperate insertOutAccountOperate(InvAccountExcel insAccountExcel) {
  72. //支出公司
  73. InvAccountOperate insAccountOperate = new InvAccountOperate();
  74. InvAccountOperate operate = operate(insAccountExcel, insAccountOperate);
  75. operate.setRevenueOutlay("1");
  76. JSONObject outProfit = insAccountExcel.getOutProfit();
  77. for (Map.Entry<String, Object> entry : outProfit.entrySet()) {
  78. outProfit.put(entry.getKey(), new BigDecimal(String.valueOf(entry.getValue())).negate().toString());
  79. }
  80. operate.setOutProfit(outProfit);
  81. operate.setCreateTime(LocalDateTime.now());
  82. operate.setRemark(insAccountExcel.getRemark());
  83. operate.setOutCardNum(insAccountExcel.getOutCardNum());
  84. return operate;
  85. }
  86. /**
  87. * 转账成功后添加收入账户操作信息
  88. */
  89. public static InvAccountOperate insertRevenueAccountOperate(InvAccountExcel insAccountExcel) {
  90. //支出公司
  91. InvAccountOperate insAccountOperate = new InvAccountOperate();
  92. InvAccountOperate operate = operate(insAccountExcel, insAccountOperate);
  93. operate.setRevenueOutlay("0");
  94. operate.setEntProfit(insAccountExcel.getEntProfit());
  95. operate.setCreateTime(LocalDateTime.now());
  96. operate.setRemark(insAccountExcel.getRemark());
  97. operate.setEnterCardNum(insAccountExcel.getEnterCardNum());
  98. return operate;
  99. }
  100. private static InvAccountOperate operate(InvAccountExcel invAccountExcel, InvAccountOperate invAccountOperate) {
  101. invAccountOperate.setApplicant(invAccountExcel.getApplicant());
  102. invAccountOperate.setApplySector(invAccountExcel.getApplySector());
  103. invAccountOperate.setApplyTime(invAccountExcel.getApplyTime());
  104. invAccountOperate.setCollectionMessage(invAccountExcel.getCollectionMessage());
  105. invAccountOperate.setFundFlow(invAccountExcel.getFundFlow());
  106. invAccountOperate.setFundUse(invAccountExcel.getFundUse());
  107. invAccountOperate.setPayMethod(invAccountExcel.getPayMethod());
  108. invAccountOperate.setCompany(invAccountExcel.getCompany());
  109. invAccountOperate.setApplyAmount(invAccountExcel.getApplyAmount());
  110. invAccountOperate.setBigApplyAmount(invAccountExcel.getBigApplyAmount());
  111. invAccountOperate.setFundFen(invAccountExcel.getFundFen());
  112. return invAccountOperate;
  113. }
  114. /**
  115. * 判断各余额是否足够
  116. *
  117. * @param outAccountCard
  118. * @param entAccountCard
  119. * @param ApplyAmount
  120. * @return
  121. */
  122. public static Boolean lenss(InvAccountCard outAccountCard, InvAccountCard entAccountCard, InvAccount outAccount, InvAccount entAccount, String ApplyAmount) {
  123. if (entAccountCard == null || entAccount == null) {
  124. throw new SystemException("收入卡或收入账户为空");
  125. }
  126. if (outAccountCard == null || outAccount == null) {
  127. throw new SystemException("转出卡或转出账户为空");
  128. }
  129. if (ApplyAmount == null) {
  130. throw new SystemException("金额为空");
  131. }
  132. if (outAccount.getOuterFlag().equals("0")) {
  133. //公户单日转账剩余
  134. BigDecimal pubDayLinesExcess = new BigDecimal(outAccountCard.getPubDayLinesExcess());
  135. //私户单日转账剩余
  136. BigDecimal priDayLinesExcess = new BigDecimal(outAccountCard.getPriDayLinesExcess());
  137. //公户年额度剩余
  138. BigDecimal pubYearExcess = new BigDecimal(outAccountCard.getPubYearExcess());
  139. //私户年额度剩余
  140. BigDecimal priYearExcess = new BigDecimal(outAccountCard.getPriYearExcess());
  141. //对公单笔限额
  142. BigDecimal pubSingleLines = new BigDecimal(outAccountCard.getPubSingleLines());
  143. //对私单笔限额
  144. BigDecimal priSingleLines = new BigDecimal(outAccountCard.getPriSingleLines());
  145. //单日转账笔数剩余
  146. long dayStrokeNumExcess = Long.parseLong(outAccountCard.getDayStrokeNumExcess());
  147. //申请金额
  148. BigDecimal invApplyAmount = new BigDecimal(ApplyAmount);
  149. //转出账户余额
  150. BigDecimal outAccountBalance = new BigDecimal(outAccountCard.getBalance());
  151. if (outAccountBalance.compareTo(invApplyAmount) < 0) {
  152. throw new SystemException("转出账户余额不足");
  153. }
  154. if (entAccountCard.getAccountQuality().equals("0")) {
  155. //收入账户为公户
  156. if (dayStrokeNumExcess <= 0) {
  157. throw new SystemException("公户单日转账笔数不足");
  158. }
  159. //判断单日转账金额是否超过
  160. if (pubDayLinesExcess.compareTo(BigDecimal.valueOf(0)) != 0 && pubDayLinesExcess.compareTo(invApplyAmount) < 0) {
  161. throw new SystemException("公户单日转账金额不足");
  162. }
  163. //判断年额度是否超过
  164. if (pubYearExcess.compareTo(BigDecimal.valueOf(0)) != 0 && pubYearExcess.compareTo(invApplyAmount) < 0) {
  165. throw new SystemException("公户年额度不足");
  166. }
  167. if (pubSingleLines.compareTo(invApplyAmount) < 0) {
  168. throw new SystemException("公户转账金额超出单笔限额");
  169. }
  170. } else {
  171. //收入账户为私户
  172. if (dayStrokeNumExcess <= 0) {
  173. throw new SystemException("私户单日转账笔数不足");
  174. }
  175. if (priDayLinesExcess.compareTo(BigDecimal.valueOf(0)) != 0 && priDayLinesExcess.compareTo(invApplyAmount) < 0) {
  176. throw new SystemException("私户单日转账金额不足");
  177. }
  178. if (priYearExcess.compareTo(BigDecimal.valueOf(0)) != 0 && priYearExcess.compareTo(invApplyAmount) < 0) {
  179. throw new SystemException("私户年额度不足");
  180. }
  181. if (priSingleLines.compareTo(invApplyAmount) > -1) {
  182. throw new SystemException("私户转账金额超出单笔限额");
  183. }
  184. }
  185. }
  186. return true;
  187. }
  188. /**
  189. * 判断归属是否分配完毕
  190. * @param outProfit
  191. * @param entProfit
  192. * @return
  193. */
  194. public static Boolean isProfitFull (JSONObject outProfit,JSONObject entProfit) {
  195. BigDecimal outAmount = new BigDecimal(0);
  196. BigDecimal entAmount = new BigDecimal(0);
  197. for (Map.Entry<String, Object> entry : outProfit.entrySet()) {
  198. outAmount = outAmount.add(new BigDecimal(entry.getValue().toString()));
  199. }
  200. for (Map.Entry<String, Object> entry : entProfit.entrySet()) {
  201. entAmount = entAmount.add(new BigDecimal(entry.getValue().toString()));
  202. }
  203. if (!String.valueOf(outAmount).equals("100")) {
  204. throw new SystemException("支出金额未完全分配");
  205. }
  206. if (!String.valueOf(entAmount).equals("100")) {
  207. throw new SystemException("收入金额未完全分配");
  208. }
  209. return true;
  210. }
  211. /**
  212. * 转给私户扣除余额方法
  213. */
  214. private static InvAccountCard priAccountUtils(InvAccountCard outAccountCard, String invAccountExcelApplyAmount) {
  215. String spend = outAccountCard.getSpend();
  216. String dayStrokeNumExcess = outAccountCard.getDayStrokeNumExcess();
  217. String priDayLinesExcess = outAccountCard.getPriDayLinesExcess();
  218. String priYearExcess = outAccountCard.getPriYearExcess();
  219. outAccountCard.setSpend(new BigDecimal(spend).add(new BigDecimal(invAccountExcelApplyAmount)).toString());
  220. outAccountCard.setBalance(new BigDecimal(outAccountCard.getBalance()).subtract(new BigDecimal(invAccountExcelApplyAmount)).toString());
  221. outAccountCard.setDayStrokeNumExcess(String.valueOf(Integer.parseInt(dayStrokeNumExcess) - 1));
  222. outAccountCard.setPriDayLinesExcess(new BigDecimal(priDayLinesExcess).subtract(new BigDecimal(invAccountExcelApplyAmount)).toString());
  223. outAccountCard.setPriYearExcess(new BigDecimal(priYearExcess).subtract(new BigDecimal(invAccountExcelApplyAmount)).toString());
  224. return outAccountCard;
  225. }
  226. /**
  227. * 转给公户扣除余额方法
  228. */
  229. private static InvAccountCard pubAccountUtils(InvAccountCard outAccountCard, String invAccountExcelApplyAmount) {
  230. String spend = outAccountCard.getSpend();
  231. String dayStrokeNumExcess = outAccountCard.getDayStrokeNumExcess();
  232. String pubDayLinesExcess = outAccountCard.getPubDayLinesExcess();
  233. String pubYearExcess = outAccountCard.getPubYearExcess();
  234. BigDecimal bigDecimal = new BigDecimal(invAccountExcelApplyAmount);
  235. //支出方减少余额
  236. outAccountCard.setSpend(new BigDecimal(spend).add(bigDecimal).toString());
  237. outAccountCard.setBalance(new BigDecimal(outAccountCard.getBalance()).subtract(bigDecimal).toString());
  238. //公户单日转账笔数减少
  239. outAccountCard.setDayStrokeNumExcess(String.valueOf(Integer.parseInt(dayStrokeNumExcess) - 1));
  240. //公户单日转账剩余减少
  241. outAccountCard.setPubDayLinesExcess(new BigDecimal(pubDayLinesExcess).subtract(bigDecimal).toString());
  242. //公户年额度减少
  243. outAccountCard.setPubYearExcess(new BigDecimal(pubYearExcess).subtract(bigDecimal).toString());
  244. return outAccountCard;
  245. }
  246. /**
  247. * 内部转内部方法
  248. */
  249. public static List<InvAccountCard> insideTransfer(InvAccountCard outAccountCard, InvAccount outAccount, InvAccountCard enterAccountCard, InvAccount enterAccount, String applyAmount) {
  250. List<InvAccountCard> list = new ArrayList<>();
  251. TransferUtils.lenss(outAccountCard, enterAccountCard, outAccount, enterAccount, applyAmount);
  252. if (enterAccountCard.getAccountQuality().equals("0")) {
  253. list.add(pubAccountUtils(outAccountCard, applyAmount));
  254. list.add(enterAccountUtils(enterAccountCard, applyAmount));
  255. return list;
  256. } else {
  257. //私户操作
  258. list.add(priAccountUtils(outAccountCard, applyAmount));
  259. list.add(enterAccountUtils(enterAccountCard, applyAmount));
  260. return list;
  261. }
  262. }
  263. /**
  264. * 内部转外部方法
  265. */
  266. public static List<InvAccountCard> enterDeTransfer(InvAccountCard outAccountCard, InvAccount outAccount, InvAccountCard enterAccountCard, InvAccount enterAccount, String applyAmount) {
  267. List<InvAccountCard> list = new ArrayList<>();
  268. TransferUtils.lenss(outAccountCard, enterAccountCard, outAccount, enterAccount, applyAmount);
  269. if (enterAccountCard.getAccountQuality().equals("0")) {
  270. //公户操作
  271. list.add(pubAccountUtils(outAccountCard, applyAmount));
  272. } else {
  273. //私户操作
  274. list.add(priAccountUtils(outAccountCard, applyAmount));
  275. }
  276. return list;
  277. }
  278. /**
  279. * 外部转内部方法
  280. */
  281. public static InvAccountCard outsideTransfer(InvAccountCard outAccountCard, InvAccount outAccount, InvAccountCard enterAccountCard, InvAccount enterAccount, String applyAmount) {
  282. TransferUtils.lenss(outAccountCard, enterAccountCard, outAccount, enterAccount, applyAmount);
  283. return enterAccountUtils(enterAccountCard, applyAmount);
  284. }
  285. /**
  286. * 收入方增加利润方法
  287. *
  288. * @return
  289. */
  290. private static InvAccountCard enterAccountUtils(InvAccountCard enterAccountCard, String invAccountExcelApplyAmount) {
  291. if (enterAccountCard.getBalance() != null && !enterAccountCard.getBalance().isEmpty()) {
  292. enterAccountCard.setBalance(new BigDecimal(enterAccountCard.getBalance()).add(new BigDecimal(invAccountExcelApplyAmount)).toString());
  293. }
  294. return enterAccountCard;
  295. }
  296. /**
  297. * 撤销发票方法
  298. */
  299. public static List<InvAccountCard> quashOutsideTransfer(InvAccountCard outAccountCard, InvAccountCard enterAccountCard, InvAccountIncoice invAccountIncoice) {
  300. if (enterAccountCard == null || invAccountIncoice == null) {
  301. throw new SystemException("账户为空");
  302. }
  303. BigDecimal applyAmount = new BigDecimal(invAccountIncoice.getInvoiceMoney());
  304. List<InvAccountCard> list = new ArrayList<>();
  305. list.add(enterAccountBreakUtils(enterAccountCard, applyAmount));
  306. list.add(outAccountBreakUtils(outAccountCard, applyAmount));
  307. return list;
  308. }
  309. /**
  310. * 收入方回滚利润方法
  311. *
  312. * @return
  313. */
  314. private static InvAccountCard enterAccountBreakUtils(InvAccountCard enterAccountCard, BigDecimal invAccountExcelApplyAmount) {
  315. enterAccountCard.setBalance(new BigDecimal(enterAccountCard.getBalance()).subtract(invAccountExcelApplyAmount).toString());
  316. return enterAccountCard;
  317. }
  318. /**
  319. * 支出方回滚利润方法
  320. *
  321. * @return
  322. */
  323. private static InvAccountCard outAccountBreakUtils(InvAccountCard enterAccountCard, BigDecimal invAccountExcelApplyAmount) {
  324. if (enterAccountCard.getBalance() != null && !enterAccountCard.getBalance().isEmpty()) {
  325. enterAccountCard.setBalance(new BigDecimal(enterAccountCard.getBalance()).add(invAccountExcelApplyAmount).toString());
  326. }
  327. return enterAccountCard;
  328. }
  329. }