PayFeeCmd.java 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. package com.java110.fee.cmd.fee;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.java110.core.annotation.Java110Cmd;
  5. import com.java110.core.annotation.Java110Transactional;
  6. import com.java110.core.context.ICmdDataFlowContext;
  7. import com.java110.core.event.cmd.Cmd;
  8. import com.java110.core.event.cmd.CmdEvent;
  9. import com.java110.core.factory.GenerateCodeFactory;
  10. import com.java110.core.factory.Java110TransactionalFactory;
  11. import com.java110.core.log.LoggerFactory;
  12. import com.java110.core.smo.IComputeFeeSMO;
  13. import com.java110.dto.account.AccountDto;
  14. import com.java110.dto.accountDetail.AccountDetailDto;
  15. import com.java110.dto.fee.FeeAttrDto;
  16. import com.java110.dto.fee.FeeConfigDto;
  17. import com.java110.dto.fee.FeeDto;
  18. import com.java110.dto.feeReceipt.FeeReceiptDetailDto;
  19. import com.java110.dto.owner.OwnerCarDto;
  20. import com.java110.dto.parking.ParkingSpaceDto;
  21. import com.java110.dto.repair.RepairDto;
  22. import com.java110.dto.repair.RepairUserDto;
  23. import com.java110.dto.user.UserDto;
  24. import com.java110.intf.acct.IAccountDetailInnerServiceSMO;
  25. import com.java110.intf.acct.IAccountInnerServiceSMO;
  26. import com.java110.intf.acct.ICouponUserDetailV1InnerServiceSMO;
  27. import com.java110.intf.acct.ICouponUserV1InnerServiceSMO;
  28. import com.java110.intf.community.*;
  29. import com.java110.intf.fee.*;
  30. import com.java110.intf.fee.IFeeAccountDetailServiceSMO;
  31. import com.java110.intf.user.IOwnerCarInnerServiceSMO;
  32. import com.java110.intf.user.IUserV1InnerServiceSMO;
  33. import com.java110.po.accountDetail.AccountDetailPo;
  34. import com.java110.po.applyRoomDiscount.ApplyRoomDiscountPo;
  35. import com.java110.po.car.OwnerCarPo;
  36. import com.java110.po.fee.PayFeeDetailPo;
  37. import com.java110.po.fee.PayFeePo;
  38. import com.java110.po.feeAccountDetail.FeeAccountDetailPo;
  39. import com.java110.po.owner.RepairPoolPo;
  40. import com.java110.po.owner.RepairUserPo;
  41. import com.java110.po.payFeeDetailDiscount.PayFeeDetailDiscountPo;
  42. import com.java110.utils.cache.CommonCache;
  43. import com.java110.utils.constant.FeeFlagTypeConstant;
  44. import com.java110.utils.constant.ResponseConstant;
  45. import com.java110.utils.exception.CmdException;
  46. import com.java110.utils.exception.ListenerExecuteException;
  47. import com.java110.utils.lock.DistributedLock;
  48. import com.java110.utils.util.Assert;
  49. import com.java110.utils.util.BeanConvertUtil;
  50. import com.java110.utils.util.DateUtil;
  51. import com.java110.utils.util.StringUtil;
  52. import com.java110.vo.ResultVo;
  53. import org.slf4j.Logger;
  54. import org.springframework.beans.factory.annotation.Autowired;
  55. import java.math.BigDecimal;
  56. import java.text.ParseException;
  57. import java.text.SimpleDateFormat;
  58. import java.util.*;
  59. /**
  60. * 前台 现金或者转账收费 缴费处理类
  61. * <p>
  62. * 假如 缴费 后要处理一些逻辑建议用databus
  63. * 这个类已经很复杂 ,最好不要加新逻辑
  64. */
  65. @Java110Cmd(serviceCode = "fee.payFee")
  66. public class PayFeeCmd extends Cmd {
  67. private static Logger logger = LoggerFactory.getLogger(PayFeeCmd.class);
  68. @Autowired
  69. private IPayFeeV1InnerServiceSMO payFeeV1InnerServiceSMOImpl;
  70. @Autowired
  71. private IPayFeeDetailV1InnerServiceSMO payFeeDetailNewV1InnerServiceSMOImpl;
  72. @Autowired
  73. private IFeeInnerServiceSMO feeInnerServiceSMOImpl;
  74. @Autowired
  75. private IFeeAttrInnerServiceSMO feeAttrInnerServiceSMOImpl;
  76. @Autowired
  77. private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
  78. @Autowired
  79. private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl;
  80. @Autowired
  81. private IOwnerCarInnerServiceSMO ownerCarInnerServiceSMOImpl;
  82. @Autowired
  83. private IFeeReceiptDetailInnerServiceSMO feeReceiptDetailInnerServiceSMOImpl;
  84. @Autowired
  85. private IRepairUserInnerServiceSMO repairUserInnerServiceSMO;
  86. @Autowired
  87. private IRepairInnerServiceSMO repairInnerServiceSMO;
  88. @Autowired
  89. private IApplyRoomDiscountInnerServiceSMO applyRoomDiscountInnerServiceSMOImpl;
  90. @Autowired
  91. private IParkingSpaceInnerServiceSMO parkingSpaceInnerServiceSMOImpl;
  92. @Autowired
  93. private IAccountDetailInnerServiceSMO accountDetailInnerServiceSMOImpl;
  94. @Autowired
  95. private IAccountInnerServiceSMO accountInnerServiceSMOImpl;
  96. @Autowired
  97. private IComputeFeeSMO computeFeeSMOImpl;
  98. @Autowired
  99. private IPayFeeDetailDiscountNewV1InnerServiceSMO payFeeDetailDiscountNewV1InnerServiceSMOImpl;
  100. @Autowired
  101. private IRepairPoolV1InnerServiceSMO repairPoolNewV1InnerServiceSMOImpl;
  102. @Autowired
  103. private IRepairUserV1InnerServiceSMO repairUserNewV1InnerServiceSMOImpl;
  104. @Autowired
  105. private ICouponUserV1InnerServiceSMO couponUserV1InnerServiceSMOImpl;
  106. @Autowired
  107. private ICouponUserDetailV1InnerServiceSMO couponUserDetailV1InnerServiceSMOImpl;
  108. @Autowired
  109. private IOwnerCarNewV1InnerServiceSMO ownerCarNewV1InnerServiceSMOImpl;
  110. @Autowired
  111. private IFeeAccountDetailServiceSMO feeAccountDetailServiceSMOImpl;
  112. @Autowired
  113. private IUserV1InnerServiceSMO userV1InnerServiceSMOImpl;
  114. @Override
  115. public void validate(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject reqJson) throws CmdException {
  116. Assert.jsonObjectHaveKey(reqJson, "communityId", "请求报文中未包含communityId节点");
  117. Assert.jsonObjectHaveKey(reqJson, "cycles", "请求报文中未包含cycles节点");
  118. Assert.jsonObjectHaveKey(reqJson, "receivedAmount", "请求报文中未包含receivedAmount节点");
  119. Assert.jsonObjectHaveKey(reqJson, "feeId", "请求报文中未包含feeId节点");
  120. Assert.hasLength(reqJson.getString("communityId"), "小区ID不能为空");
  121. Assert.hasLength(reqJson.getString("cycles"), "周期不能为空");
  122. Assert.hasLength(reqJson.getString("receivedAmount"), "实收金额不能为空");
  123. Assert.hasLength(reqJson.getString("feeId"), "费用ID不能为空");
  124. //判断是否 费用状态为缴费结束
  125. FeeDto feeDto = new FeeDto();
  126. feeDto.setFeeId(reqJson.getString("feeId"));
  127. feeDto.setCommunityId(reqJson.getString("communityId"));
  128. List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
  129. Assert.listOnlyOne(feeDtos, "传入费用ID错误");
  130. feeDto = feeDtos.get(0);
  131. if (FeeDto.STATE_FINISH.equals(feeDto.getState())) {
  132. throw new IllegalArgumentException("收费已经结束,不能再缴费");
  133. }
  134. Date endTime = feeDto.getEndTime();
  135. FeeConfigDto feeConfigDto = new FeeConfigDto();
  136. feeConfigDto.setConfigId(feeDto.getConfigId());
  137. feeConfigDto.setCommunityId(reqJson.getString("communityId"));
  138. List<FeeConfigDto> feeConfigDtos = feeConfigInnerServiceSMOImpl.queryFeeConfigs(feeConfigDto);
  139. if (feeConfigDtos == null || feeConfigDtos.size() != 1) {
  140. throw new IllegalArgumentException("费用项不存在");
  141. }
  142. //一次性费用 和间接性费用
  143. Date maxEndTime = feeDtos.get(0).getDeadlineTime();
  144. //周期性费用
  145. if (maxEndTime == null || FeeDto.FEE_FLAG_CYCLE.equals(feeConfigDtos.get(0).getFeeFlag())) {
  146. maxEndTime = DateUtil.getDateFromStringA(feeConfigDtos.get(0).getEndTime());
  147. }
  148. if (maxEndTime != null && endTime != null && !FeeDto.FEE_FLAG_ONCE.equals(feeConfigDtos.get(0).getFeeFlag())) {
  149. Date newDate = DateUtil.stepMonth(endTime, reqJson.getDouble("cycles").intValue());
  150. if (newDate.getTime() > maxEndTime.getTime()) {
  151. throw new IllegalArgumentException("缴费周期超过 缴费结束时间,请用按结束时间方式缴费");
  152. }
  153. }
  154. String selectUserAccount = reqJson.getString("selectUserAccount");
  155. JSONArray params = JSONArray.parseArray(selectUserAccount);
  156. for (int paramIndex = 0; paramIndex < params.size(); paramIndex++) {
  157. JSONObject param = params.getJSONObject(paramIndex);
  158. String maximumNumber = param.getString("maximumNumber");
  159. }
  160. }
  161. @Override
  162. @Java110Transactional
  163. public void doCmd(CmdEvent event, ICmdDataFlowContext cmdDataFlowContext, JSONObject paramObj) throws CmdException {
  164. logger.debug("paramObj : {}", paramObj);
  165. String userId = cmdDataFlowContext.getReqHeaders().get("user-id");
  166. UserDto userDto = new UserDto();
  167. userDto.setUserId(userId);
  168. List<UserDto> userDtos = userV1InnerServiceSMOImpl.queryUsers(userDto);
  169. Assert.listOnlyOne(userDtos, "用户未登录");
  170. PayFeePo payFeePo = null;
  171. String requestId = DistributedLock.getLockUUID();
  172. String key = this.getClass().getSimpleName() + paramObj.get("feeId");
  173. try {
  174. DistributedLock.waitGetDistributedLock(key, requestId);
  175. JSONObject feeDetail = addFeeDetail(paramObj);
  176. feeDetail.put("payableAmount", feeDetail.getString("receivableAmount"));
  177. JSONObject fee = modifyFee(paramObj);
  178. payFeePo = BeanConvertUtil.covertBean(fee, PayFeePo.class);
  179. PayFeeDetailPo payFeeDetailPo = BeanConvertUtil.covertBean(feeDetail, PayFeeDetailPo.class);
  180. payFeeDetailPo.setReceivableAmount(feeDetail.getString("totalFeePrice"));
  181. //判断是否有赠送规则
  182. hasDiscount(paramObj, payFeePo, payFeeDetailPo);
  183. // todo 处理用户账户
  184. dealUserAccount(paramObj, payFeeDetailPo);
  185. String oId = Java110TransactionalFactory.getOId();
  186. if (StringUtil.isEmpty(oId)) {
  187. oId = payFeeDetailPo.getDetailId();
  188. }
  189. payFeeDetailPo.setPayOrderId(oId);
  190. payFeeDetailPo.setCashierId(userDtos.get(0).getUserId());
  191. payFeeDetailPo.setCashierName(userDtos.get(0).getName());
  192. int flag = payFeeDetailNewV1InnerServiceSMOImpl.savePayFeeDetailNew(payFeeDetailPo);
  193. if (flag < 1) {
  194. throw new CmdException("缴费失败");
  195. }
  196. flag = payFeeV1InnerServiceSMOImpl.updatePayFee(payFeePo);
  197. if (flag < 1) {
  198. throw new CmdException("缴费失败");
  199. }
  200. } catch (ParseException e) {
  201. e.printStackTrace();
  202. } finally {
  203. DistributedLock.releaseDistributedLock(requestId, key);
  204. }
  205. //账户处理
  206. dealAccount(paramObj);
  207. //折扣管理
  208. if (paramObj.containsKey("selectDiscount")) {
  209. JSONObject discountBusiness = null;
  210. JSONArray selectDiscounts = paramObj.getJSONArray("selectDiscount");
  211. for (int discountIndex = 0; discountIndex < selectDiscounts.size(); discountIndex++) {
  212. JSONObject param = selectDiscounts.getJSONObject(discountIndex);
  213. addPayFeeDetailDiscount(paramObj, param);
  214. }
  215. }
  216. //为停车费单独处理
  217. updateCarEndTime(paramObj);
  218. //处理报修单
  219. doDealRepairOrder(paramObj);
  220. //修改折扣申请状态,空置房折扣只能用一次
  221. String selectDiscount = paramObj.getString("selectDiscount");
  222. JSONArray params = JSONArray.parseArray(selectDiscount);
  223. for (int index = 0; index < params.size(); index++) {
  224. JSONObject param = params.getJSONObject(index);
  225. if (!StringUtil.isEmpty(param.getString("ardId"))) {
  226. ApplyRoomDiscountPo applyRoomDiscountPo = new ApplyRoomDiscountPo();
  227. //空置房优惠不可用
  228. applyRoomDiscountPo.setInUse("1");
  229. applyRoomDiscountPo.setArdId(param.getString("ardId"));
  230. applyRoomDiscountInnerServiceSMOImpl.updateApplyRoomDiscount(applyRoomDiscountPo);
  231. }
  232. }
  233. //根据明细ID 查询收据信息
  234. FeeReceiptDetailDto feeReceiptDetailDto = new FeeReceiptDetailDto();
  235. feeReceiptDetailDto.setDetailId(paramObj.getString("detailId"));
  236. cmdDataFlowContext.setResponseEntity(ResultVo.createResponseEntity(feeReceiptDetailDto));
  237. }
  238. private void dealUserAccount(JSONObject paramObj, PayFeeDetailPo payFeeDetailPo) {
  239. //判断选择的账号
  240. JSONArray jsonArray = paramObj.getJSONArray("selectUserAccount");
  241. if (jsonArray == null || jsonArray.size() < 1) {
  242. return;
  243. }
  244. BigDecimal integralSum = new BigDecimal(0);
  245. BigDecimal cashSum = new BigDecimal(0);
  246. for (int columnIndex = 0; columnIndex < jsonArray.size(); columnIndex++) {
  247. JSONObject param = jsonArray.getJSONObject(columnIndex);
  248. //账户金额
  249. BigDecimal amount = new BigDecimal(param.getString("amount"));
  250. if (AccountDto.ACCT_TYPE_INTEGRAL.equals(param.getString("acctType"))) { //积分账户
  251. //获取最大抵扣积分
  252. BigDecimal maximumNumber = new BigDecimal(param.getString("maximumNumber"));
  253. //获取积分抵扣
  254. BigDecimal deductionProportion = new BigDecimal(param.getString("deductionProportion"));
  255. int flag = amount.compareTo(maximumNumber);
  256. BigDecimal redepositAmount = new BigDecimal("0.00");
  257. if (flag == 1) { //账户积分大于最大使用积分,就用最大使用积分抵扣
  258. redepositAmount = maximumNumber;
  259. }
  260. if (flag > -1) { //账户积分大于等于最大使用积分,就用最大使用积分抵扣
  261. redepositAmount = maximumNumber;
  262. }
  263. if (flag == -1) { //账户积分小于最大使用积分,就用账户积分抵扣
  264. redepositAmount = amount;
  265. }
  266. if (flag < 1) { //账户积分小于等于最大使用积分,就用账户积分抵扣
  267. redepositAmount = amount;
  268. }
  269. if (flag == 0) { //账户积分等于最大使用积分
  270. redepositAmount = amount;
  271. }
  272. //计算积分换算的金额
  273. BigDecimal divide = redepositAmount.divide(deductionProportion);
  274. BigDecimal receivedAmount = new BigDecimal(payFeeDetailPo.getReceivedAmount());
  275. //计算实付金额
  276. int flag2 = divide.compareTo(receivedAmount);
  277. BigDecimal subtract = new BigDecimal("0.00");
  278. //生成抵扣明细记录
  279. if (flag2 == -1) { //积分换算金额小于实付金额
  280. subtract = receivedAmount.subtract(divide);
  281. } else if (flag < 1) { //积分换算金额小于等于实付金额
  282. subtract = receivedAmount.subtract(divide);
  283. }
  284. integralSum = integralSum.add(subtract);
  285. payFeeDetailPo.setReceivedAmount(subtract.toString());
  286. } else if (AccountDto.ACCT_TYPE_CASH.equals(param.getString("acctType"))) { //现金账户
  287. //实收金额
  288. BigDecimal receivedAmount = new BigDecimal(payFeeDetailPo.getReceivedAmount());
  289. int flag = amount.compareTo(receivedAmount);
  290. BigDecimal redepositAmount = new BigDecimal(0.00);
  291. if (flag == 1) { //现金账户大于实收金额,就用实收金额
  292. redepositAmount = receivedAmount;
  293. }
  294. if (flag > -1) { //现金账户大于等于实收金额,就用实收金额
  295. redepositAmount = receivedAmount;
  296. }
  297. if (flag == -1) { //现金账户小于实收金额,就用现金账户
  298. redepositAmount = amount;
  299. }
  300. if (flag < 1) { //现金账户小于等于实收金额,就用现金账户
  301. redepositAmount = amount;
  302. }
  303. if (flag == 0) { //现金账户等于实收金额
  304. redepositAmount = amount;
  305. }
  306. cashSum = cashSum.add(redepositAmount);
  307. }
  308. // todo 如果积分大于0
  309. if (integralSum.doubleValue() > 0) {
  310. FeeAccountDetailPo feeAccountDetailPo = new FeeAccountDetailPo();
  311. feeAccountDetailPo.setFadId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_fadId));
  312. feeAccountDetailPo.setDetailId(payFeeDetailPo.getDetailId());
  313. feeAccountDetailPo.setCommunityId(payFeeDetailPo.getCommunityId());
  314. feeAccountDetailPo.setAmount(integralSum.doubleValue() + "");
  315. feeAccountDetailPo.setState("1003"); //1001 无抵扣 1002 现金账户抵扣 1003 积分账户抵扣 1004 优惠券抵扣
  316. feeAccountDetailServiceSMOImpl.saveFeeAccountDetail(feeAccountDetailPo);
  317. }
  318. if (cashSum.doubleValue() > 0) {
  319. //生成抵扣明细记录
  320. FeeAccountDetailPo feeAccountDetailPo = new FeeAccountDetailPo();
  321. feeAccountDetailPo.setFadId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_fadId));
  322. feeAccountDetailPo.setDetailId(payFeeDetailPo.getDetailId());
  323. feeAccountDetailPo.setCommunityId(payFeeDetailPo.getCommunityId());
  324. feeAccountDetailPo.setState("1002"); //1001 无抵扣 1002 现金账户抵扣 1003 积分账户抵扣 1004 优惠券抵扣
  325. feeAccountDetailPo.setAmount(cashSum.doubleValue() + ""); //现金抵扣金额
  326. feeAccountDetailServiceSMOImpl.saveFeeAccountDetail(feeAccountDetailPo);
  327. BigDecimal receivedAmountDec = new BigDecimal(payFeeDetailPo.getReceivedAmount());
  328. receivedAmountDec = receivedAmountDec.subtract(cashSum);
  329. payFeeDetailPo.setReceivedAmount(receivedAmountDec.doubleValue() + "");
  330. }
  331. }
  332. }
  333. /**
  334. * 改造赠送逻辑 if 嵌套有点多 优化
  335. *
  336. * @param paramObj
  337. * @param payFeePo
  338. * @param payFeeDetailPo
  339. * @throws ParseException
  340. */
  341. private void hasDiscount(JSONObject paramObj, PayFeePo payFeePo, PayFeeDetailPo payFeeDetailPo) throws ParseException {
  342. if (!paramObj.containsKey("selectDiscount")) {
  343. return;
  344. }
  345. JSONArray selectDiscount = paramObj.getJSONArray("selectDiscount");
  346. if (selectDiscount == null || selectDiscount.size() < 1) {
  347. return;
  348. }
  349. for (int index = 0; index < selectDiscount.size(); index++) {
  350. JSONObject paramJson = selectDiscount.getJSONObject(index);
  351. if (!"102020008".equals(paramJson.getString("ruleId"))) { //赠送规则
  352. continue;
  353. }
  354. JSONArray feeDiscountSpecs = paramJson.getJSONArray("feeDiscountSpecs");
  355. if (feeDiscountSpecs == null || feeDiscountSpecs.size() < 1) {
  356. continue;
  357. }
  358. for (int specIndex = 0; specIndex < feeDiscountSpecs.size(); specIndex++) {
  359. JSONObject paramIn = feeDiscountSpecs.getJSONObject(specIndex);
  360. if (!"89002020980015".equals(paramIn.getString("specId"))) { //赠送月份
  361. continue;
  362. }
  363. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  364. String specValue = paramIn.getString("specValue");
  365. //获取费用结束时间(也就是下次费用开始时间)
  366. Date endTime = df.parse(payFeeDetailPo.getEndTime());
  367. Calendar cal = Calendar.getInstance();
  368. cal.setTime(endTime);
  369. cal.add(Calendar.MONTH, Integer.parseInt(specValue));
  370. payFeeDetailPo.setEndTime(df.format(cal.getTime()));
  371. payFeePo.setEndTime(df.format(cal.getTime()));
  372. }
  373. }
  374. }
  375. /**
  376. * 处理报修单
  377. *
  378. * @param paramObj
  379. */
  380. private void doDealRepairOrder(JSONObject paramObj) {
  381. int flag;//判断是否有派单属性ID
  382. FeeAttrDto feeAttrDto = new FeeAttrDto();
  383. feeAttrDto.setCommunityId(paramObj.getString("communityId"));
  384. feeAttrDto.setFeeId(paramObj.getString("feeId"));
  385. feeAttrDto.setSpecCd(FeeAttrDto.SPEC_CD_REPAIR);
  386. List<FeeAttrDto> feeAttrDtos = feeAttrInnerServiceSMOImpl.queryFeeAttrs(feeAttrDto);
  387. //修改 派单状态
  388. if (feeAttrDtos != null && feeAttrDtos.size() > 0) {
  389. RepairDto repairDto = new RepairDto();
  390. repairDto.setRepairId(feeAttrDtos.get(0).getValue());
  391. //查询报修记录
  392. List<RepairDto> repairDtos = repairInnerServiceSMO.queryRepairs(repairDto);
  393. Assert.listOnlyOne(repairDtos, "报修信息错误!");
  394. //获取报修渠道
  395. String repairChannel = repairDtos.get(0).getRepairChannel();
  396. RepairPoolPo repairPoolPo = new RepairPoolPo();
  397. repairPoolPo.setRepairId(feeAttrDtos.get(0).getValue());
  398. repairPoolPo.setCommunityId(paramObj.getString("communityId"));
  399. if (repairChannel.equals("Z")) { //如果是业主自主报修,状态就变成待评价
  400. repairPoolPo.setState(RepairDto.STATE_APPRAISE);
  401. } else { //如果是员工代客报修或电话报修,状态就变成待回访
  402. repairPoolPo.setState(RepairDto.STATE_RETURN_VISIT);
  403. }
  404. flag = repairPoolNewV1InnerServiceSMOImpl.updateRepairPoolNew(repairPoolPo);
  405. if (flag < 1) {
  406. throw new CmdException("更新微信派单池信息失败");
  407. }
  408. repairDto = new RepairDto();
  409. repairDto.setRepairId(feeAttrDtos.get(0).getValue());
  410. //查询报修记录
  411. repairDtos = repairInnerServiceSMO.queryRepairs(repairDto);
  412. Assert.listOnlyOne(repairDtos, "报修信息错误!");
  413. //获取报修渠道
  414. repairChannel = repairDtos.get(0).getRepairChannel();
  415. RepairUserDto repairUserDto = new RepairUserDto();
  416. repairUserDto.setRepairId(feeAttrDtos.get(0).getValue());
  417. repairUserDto.setState(RepairUserDto.STATE_PAY_FEE);
  418. //查询待支付状态的记录
  419. List<RepairUserDto> repairUserDtoList = repairUserInnerServiceSMO.queryRepairUsers(repairUserDto);
  420. Assert.listOnlyOne(repairUserDtoList, "信息错误!");
  421. RepairUserPo repairUserPo = new RepairUserPo();
  422. repairUserPo.setRuId(repairUserDtoList.get(0).getRuId());
  423. if ("Z".equals(repairChannel)) { //如果业主是自主报修,状态就变成已支付,并新增一条待评价状态
  424. repairUserPo.setState(RepairUserDto.STATE_FINISH_PAY_FEE);
  425. //如果是待评价状态,就更新结束时间
  426. repairUserPo.setEndTime(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
  427. repairUserPo.setContext("已支付" + paramObj.getString("feePrice") + "元");
  428. //新增待评价状态
  429. RepairUserPo repairUser = new RepairUserPo();
  430. repairUser.setRuId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_ruId));
  431. repairUser.setStartTime(repairUserPo.getEndTime());
  432. repairUser.setState(RepairUserDto.STATE_EVALUATE);
  433. repairUser.setContext("待评价");
  434. repairUser.setCommunityId(paramObj.getString("communityId"));
  435. repairUser.setCreateTime(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
  436. repairUser.setRepairId(repairUserDtoList.get(0).getRepairId());
  437. repairUser.setStaffId(repairUserDtoList.get(0).getStaffId());
  438. repairUser.setStaffName(repairUserDtoList.get(0).getStaffName());
  439. repairUser.setPreStaffId(repairUserDtoList.get(0).getStaffId());
  440. repairUser.setPreStaffName(repairUserDtoList.get(0).getStaffName());
  441. repairUser.setPreRuId(repairUserDtoList.get(0).getRuId());
  442. repairUser.setRepairEvent("auditUser");
  443. flag = repairUserNewV1InnerServiceSMOImpl.saveRepairUserNew(repairUser);
  444. if (flag < 1) {
  445. throw new CmdException("更新微信派单池信息失败");
  446. }
  447. } else { //如果是员工代客报修或电话报修,状态就变成已支付
  448. repairUserPo.setState(RepairUserDto.STATE_FINISH_PAY_FEE);
  449. //如果是已支付状态,就更新结束时间
  450. repairUserPo.setEndTime(DateUtil.getNow(DateUtil.DATE_FORMATE_STRING_A));
  451. repairUserPo.setContext("已支付" + paramObj.getString("feePrice") + "元");
  452. }
  453. flag = repairUserNewV1InnerServiceSMOImpl.updateRepairUserNew(repairUserPo);
  454. if (flag < 1) {
  455. throw new CmdException("更新微信派单池信息失败");
  456. }
  457. }
  458. }
  459. /**
  460. * 处理停车费
  461. *
  462. * @param paramObj
  463. */
  464. private void updateCarEndTime(JSONObject paramObj) {
  465. int flag;
  466. FeeDto feeDto = new FeeDto();
  467. feeDto.setFeeId(paramObj.getString("feeId"));
  468. feeDto.setCommunityId(paramObj.getString("communityId"));
  469. List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
  470. if (feeDtos == null || feeDtos.size() < 1) {
  471. return;
  472. }
  473. if (!FeeDto.PAYER_OBJ_TYPE_CAR.equals(feeDtos.get(0).getPayerObjType())) {
  474. return;
  475. }
  476. Date feeEndTime = feeDtos.get(0).getEndTime();
  477. OwnerCarDto ownerCarDto = new OwnerCarDto();
  478. ownerCarDto.setCommunityId(paramObj.getString("communityId"));
  479. ownerCarDto.setCarId(feeDtos.get(0).getPayerObjId());
  480. ownerCarDto.setCarTypeCd("1001"); //业主车辆
  481. List<OwnerCarDto> ownerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
  482. if (ownerCarDtos == null || ownerCarDtos.size() < 1) {
  483. return;
  484. }
  485. //获取车位id
  486. String psId = ownerCarDtos.get(0).getPsId();
  487. //获取车辆状态(1001 正常状态,2002 欠费状态 3003 车位释放)
  488. boolean sonMotherParking = false;
  489. String num = "";
  490. String carState = ownerCarDtos.get(0).getState();
  491. if (!StringUtil.isEmpty(psId) && "3003".equals(carState)) {
  492. ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
  493. parkingSpaceDto.setPsId(psId);
  494. List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
  495. Assert.listOnlyOne(parkingSpaceDtos, "查询车位信息错误!");
  496. //获取车位状态(出售 S,出租 H ,空闲 F)
  497. String state = parkingSpaceDtos.get(0).getState();
  498. if (!StringUtil.isEmpty(state) && !state.equals("F")) {
  499. throw new IllegalArgumentException("车位已被使用,不能再缴费!");
  500. }
  501. if (ParkingSpaceDto.TYPE_CD_SON_MOTHER.equals(parkingSpaceDtos.get(0).getTypeCd())
  502. && !parkingSpaceDtos.get(0).getTypeCd().contains(ParkingSpaceDto.NUM_MOTHER)
  503. ) {
  504. sonMotherParking = true;
  505. num = parkingSpaceDtos.get(0).getNum();
  506. }
  507. }
  508. // todo 字母车位,子车位缴费 母车位延期
  509. if (sonMotherParking) {
  510. queryMotherOwnerCars(num, ownerCarDtos, psId);
  511. }
  512. Calendar endTimeCalendar = null;
  513. //车位费用续租
  514. for (OwnerCarDto tmpOwnerCarDto : ownerCarDtos) {
  515. //后付费 或者信用期车辆 加一个月
  516. if (FeeConfigDto.PAYMENT_CD_AFTER.equals(feeDtos.get(0).getPaymentCd())
  517. || OwnerCarDto.CAR_TYPE_CREDIT.equals(tmpOwnerCarDto.getCarType())) {
  518. endTimeCalendar = Calendar.getInstance();
  519. endTimeCalendar.setTime(feeEndTime);
  520. endTimeCalendar.add(Calendar.MONTH, 1);
  521. feeEndTime = endTimeCalendar.getTime();
  522. }
  523. if (tmpOwnerCarDto.getEndTime().getTime() >= feeEndTime.getTime()) {
  524. continue;
  525. }
  526. OwnerCarPo ownerCarPo = new OwnerCarPo();
  527. ownerCarPo.setMemberId(tmpOwnerCarDto.getMemberId());
  528. ownerCarPo.setEndTime(DateUtil.getFormatTimeString(feeEndTime, DateUtil.DATE_FORMATE_STRING_A));
  529. flag = ownerCarNewV1InnerServiceSMOImpl.updateOwnerCarNew(ownerCarPo);
  530. if (flag < 1) {
  531. throw new CmdException("缴费失败");
  532. }
  533. }
  534. }
  535. /**
  536. * 子母车位延期 母车位也需要延期
  537. *
  538. * @param num
  539. * @param ownerCarDtos
  540. */
  541. private void queryMotherOwnerCars(String num, List<OwnerCarDto> ownerCarDtos, String paId) {
  542. String sonMotherSwitch = CommonCache.getValue("SON_MOTHER_PARKING_AUTO_FEE");
  543. if (!"ON".equals(sonMotherSwitch)) {
  544. return;
  545. }
  546. ParkingSpaceDto parkingSpaceDto = new ParkingSpaceDto();
  547. parkingSpaceDto.setNum(num + ParkingSpaceDto.NUM_MOTHER);
  548. parkingSpaceDto.setPaId(paId);
  549. List<ParkingSpaceDto> parkingSpaceDtos = parkingSpaceInnerServiceSMOImpl.queryParkingSpaces(parkingSpaceDto);
  550. Assert.listOnlyOne(parkingSpaceDtos, "查询车位信息错误!");
  551. OwnerCarDto ownerCarDto = new OwnerCarDto();
  552. ownerCarDto.setCommunityId(parkingSpaceDtos.get(0).getCommunityId());
  553. ownerCarDto.setPsId(parkingSpaceDtos.get(0).getPsId());
  554. ownerCarDto.setCarTypeCd("1001"); //业主车辆
  555. List<OwnerCarDto> tmpOwnerCarDtos = ownerCarInnerServiceSMOImpl.queryOwnerCars(ownerCarDto);
  556. if (ownerCarDtos == null) {
  557. ownerCarDtos = new ArrayList<>();
  558. }
  559. ownerCarDtos.addAll(tmpOwnerCarDtos);
  560. }
  561. /**
  562. * 添加小区信息
  563. *
  564. * @param paramInJson 接口调用放传入入参
  565. * @return 订单服务能够接受的报文
  566. */
  567. public void addPayFeeDetailDiscount(JSONObject paramInJson, JSONObject discountJson) {
  568. JSONObject businessFee = new JSONObject();
  569. businessFee.put("detailDiscountId", GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_detailDiscountId));
  570. businessFee.put("discountPrice", discountJson.getString("discountPrice"));
  571. businessFee.put("discountId", discountJson.getString("discountId"));
  572. businessFee.put("detailId", paramInJson.getString("detailId"));
  573. businessFee.put("communityId", paramInJson.getString("communityId"));
  574. businessFee.put("feeId", paramInJson.getString("feeId"));
  575. PayFeeDetailDiscountPo payFeeDetailDiscount = BeanConvertUtil.covertBean(businessFee, PayFeeDetailDiscountPo.class);
  576. //businessFee.putAll(feeMap);
  577. int fage = payFeeDetailDiscountNewV1InnerServiceSMOImpl.savePayFeeDetailDiscountNew(payFeeDetailDiscount);
  578. if (fage < 1) {
  579. throw new CmdException("更新费用信息失败");
  580. }
  581. }
  582. /**
  583. * 添加费用明细信息
  584. *
  585. * @param paramInJson 接口调用放传入入参
  586. * @return 订单服务能够接受的报文
  587. */
  588. public JSONObject addFeeDetail(JSONObject paramInJson) {
  589. JSONObject businessFeeDetail = new JSONObject();
  590. businessFeeDetail.putAll(paramInJson);
  591. businessFeeDetail.put("detailId", GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_detailId));
  592. paramInJson.put("detailId", businessFeeDetail.getString("detailId"));
  593. //支付方式
  594. businessFeeDetail.put("primeRate", paramInJson.getString("primeRate"));
  595. //计算 应收金额
  596. FeeDto feeDto = new FeeDto();
  597. feeDto.setFeeId(paramInJson.getString("feeId"));
  598. feeDto.setCommunityId(paramInJson.getString("communityId"));
  599. List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
  600. if (feeDtos == null || feeDtos.size() != 1) {
  601. throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "查询费用信息失败,未查到数据或查到多条数据");
  602. }
  603. if (!businessFeeDetail.containsKey("state") || StringUtil.isEmpty(businessFeeDetail.getString("state"))) {
  604. businessFeeDetail.put("state", "1400");
  605. }
  606. feeDto = feeDtos.get(0);
  607. businessFeeDetail.put("startTime", DateUtil.getFormatTimeString(feeDto.getEndTime(), DateUtil.DATE_FORMATE_STRING_A));
  608. int hours = 0;
  609. Date targetEndTime = null;
  610. BigDecimal cycles = null;
  611. Map feePriceAll = computeFeeSMOImpl.getFeePrice(feeDto);
  612. BigDecimal feePrice = new BigDecimal(feePriceAll.get("feePrice").toString());
  613. if ("-101".equals(paramInJson.getString("cycles"))) {
  614. Date endTime = feeDto.getEndTime();
  615. Calendar endCalender = Calendar.getInstance();
  616. endCalender.setTime(endTime);
  617. BigDecimal receivedAmount = new BigDecimal(Double.parseDouble(paramInJson.getString("receivedAmount")));
  618. cycles = receivedAmount.divide(feePrice, 4, BigDecimal.ROUND_HALF_EVEN);
  619. endCalender = getTargetEndTime(endCalender, cycles.doubleValue());
  620. targetEndTime = endCalender.getTime();
  621. paramInJson.put("tmpCycles", cycles.doubleValue());
  622. businessFeeDetail.put("cycles", cycles.doubleValue());
  623. //处理 可能还存在 实收手工减免的情况
  624. if (paramInJson.containsKey("receivableAmount") && !StringUtil.isEmpty(paramInJson.getString("receivableAmount"))) {
  625. businessFeeDetail.put("receivableAmount", paramInJson.getString("receivableAmount"));
  626. } else {
  627. businessFeeDetail.put("receivableAmount", receivedAmount.doubleValue());
  628. }
  629. } else if ("-103".equals(paramInJson.getString("cycles"))) { //这里按缴费结束时间缴费
  630. String custEndTime = paramInJson.getString("custEndTime");
  631. Date endDates = DateUtil.getDateFromStringB(custEndTime);
  632. Calendar c = Calendar.getInstance();
  633. c.setTime(endDates);
  634. c.add(Calendar.DAY_OF_MONTH, 1);
  635. endDates = c.getTime();//这是明天
  636. targetEndTime = endDates;
  637. BigDecimal receivedAmount1 = new BigDecimal(Double.parseDouble(paramInJson.getString("receivedAmount")));
  638. cycles = receivedAmount1.divide(feePrice, 4, BigDecimal.ROUND_HALF_EVEN);
  639. paramInJson.put("tmpCycles", cycles.doubleValue());
  640. businessFeeDetail.put("cycles", cycles.doubleValue());
  641. BigDecimal receivedAmount = new BigDecimal(Double.parseDouble(paramInJson.getString("receivedAmount")));
  642. //处理 可能还存在 实收手工减免的情况
  643. if (paramInJson.containsKey("receivableAmount") && !StringUtil.isEmpty(paramInJson.getString("receivableAmount"))) {
  644. businessFeeDetail.put("receivableAmount", paramInJson.getString("receivableAmount"));
  645. } else {
  646. businessFeeDetail.put("receivableAmount", receivedAmount.doubleValue());
  647. }
  648. } else {
  649. targetEndTime = computeFeeSMOImpl.getFeeEndTimeByCycles(feeDto, paramInJson.getString("cycles"));//根据缴费周期计算 结束时间
  650. cycles = new BigDecimal(Double.parseDouble(paramInJson.getString("cycles")));
  651. double tmpReceivableAmount = cycles.multiply(feePrice).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue();
  652. businessFeeDetail.put("receivableAmount", tmpReceivableAmount);
  653. //出租递增问题处理
  654. if (FeeConfigDto.COMPUTING_FORMULA_RANT_RATE.equals(feeDto.getComputingFormula())) {
  655. computeFeeSMOImpl.dealRentRateCycle(feeDto, cycles.doubleValue());
  656. if (feeDto.getOweFee() > 0) {
  657. businessFeeDetail.put("receivableAmount", feeDto.getAmountOwed());
  658. }
  659. }
  660. }
  661. businessFeeDetail.put("endTime", DateUtil.getFormatTimeString(targetEndTime, DateUtil.DATE_FORMATE_STRING_A));
  662. paramInJson.put("feeInfo", feeDto);
  663. return businessFeeDetail;
  664. }
  665. public JSONObject modifyFee(JSONObject paramInJson) {
  666. JSONObject businessFee = new JSONObject();
  667. FeeDto feeInfo = (FeeDto) paramInJson.get("feeInfo");
  668. Date endTime = feeInfo.getEndTime();
  669. Calendar endCalender = Calendar.getInstance();
  670. endCalender.setTime(endTime);
  671. int hours = 0;
  672. //-101自定义金额 -102自定义周期 -103 自定义结束时间
  673. if ("-101".equals(paramInJson.getString("cycles"))) {
  674. endCalender = getTargetEndTime(endCalender, Double.parseDouble(paramInJson.getString("tmpCycles")));
  675. } else if ("-103".equals(paramInJson.getString("cycles"))) {
  676. String custEndTime = paramInJson.getString("custEndTime");
  677. Date endDates = DateUtil.getDateFromStringB(custEndTime);
  678. Calendar c = Calendar.getInstance();
  679. c.setTime(endDates);
  680. c.add(Calendar.DAY_OF_MONTH, 1);
  681. endDates = c.getTime();//这是明天
  682. endCalender.setTime(endDates);
  683. } else {
  684. endCalender.add(Calendar.MONTH, Integer.parseInt(paramInJson.getString("cycles")));
  685. }
  686. if (FeeDto.FEE_FLAG_ONCE.equals(feeInfo.getFeeFlag())) {
  687. if (feeInfo.getDeadlineTime() != null) {
  688. endCalender.setTime(feeInfo.getDeadlineTime());
  689. } else if (!StringUtil.isEmpty(feeInfo.getCurDegrees())) {
  690. endCalender.setTime(feeInfo.getCurReadingTime());
  691. } else if (feeInfo.getImportFeeEndTime() == null) {
  692. endCalender.setTime(feeInfo.getConfigEndTime());
  693. } else {
  694. endCalender.setTime(feeInfo.getImportFeeEndTime());
  695. }
  696. //businessFee.put("state",FeeDto.STATE_FINISH);
  697. feeInfo.setState(FeeDto.STATE_FINISH);
  698. }
  699. feeInfo.setEndTime(endCalender.getTime());
  700. Date maxEndTime = feeInfo.getDeadlineTime();
  701. if (FeeDto.FEE_FLAG_CYCLE.equals(feeInfo.getFeeFlag())) {
  702. maxEndTime = feeInfo.getConfigEndTime();
  703. }
  704. if (FeeDto.FEE_FLAG_CYCLE_ONCE.equals(feeInfo.getFeeFlag())) {
  705. maxEndTime = feeInfo.getMaxEndTime();
  706. }
  707. //如果间歇性费用没有设置结束时间 则取费用项的
  708. if (maxEndTime == null) {
  709. maxEndTime = feeInfo.getConfigEndTime();
  710. }
  711. //判断 结束时间 是否大于 费用项 结束时间,这里 容错一下,如果 费用结束时间大于 费用项结束时间 30天 走报错 属于多缴费
  712. if (maxEndTime != null) {
  713. if (feeInfo.getEndTime().getTime() - maxEndTime.getTime() > 30 * 24 * 60 * 60 * 1000L) {
  714. throw new IllegalArgumentException("缴费超过了 费用项结束时间");
  715. }
  716. }
  717. Map feeMap = BeanConvertUtil.beanCovertMap(feeInfo);
  718. feeMap.put("startTime", DateUtil.getFormatTimeString(feeInfo.getStartTime(), DateUtil.DATE_FORMATE_STRING_A));
  719. feeMap.put("endTime", DateUtil.getFormatTimeString(feeInfo.getEndTime(), DateUtil.DATE_FORMATE_STRING_A));
  720. feeMap.put("cycles", paramInJson.getString("cycles"));
  721. feeMap.put("configEndTime", feeInfo.getConfigEndTime());
  722. businessFee.putAll(feeMap);
  723. //为停车费单独处理
  724. paramInJson.put("carFeeEndTime", feeInfo.getEndTime());
  725. paramInJson.put("carPayerObjType", feeInfo.getPayerObjType());
  726. paramInJson.put("carPayerObjId", feeInfo.getPayerObjId());
  727. // 周期性收费、缴费后,到期日期在费用项终止日期后,则设置缴费状态结束,设置结束日期为费用项终止日期
  728. if (!FeeFlagTypeConstant.ONETIME.equals(feeInfo.getFeeFlag())) {
  729. //这里 容错五天时间
  730. Calendar calendar = Calendar.getInstance();
  731. calendar.setTime(maxEndTime);
  732. calendar.add(Calendar.DAY_OF_MONTH, -5);
  733. maxEndTime = calendar.getTime();
  734. if (feeInfo.getEndTime().after(maxEndTime)) {
  735. businessFee.put("state", FeeDto.STATE_FINISH);
  736. businessFee.put("endTime", maxEndTime);
  737. }
  738. }
  739. return businessFee;
  740. }
  741. public void dealAccount(JSONObject paramObj) {
  742. //判断选择的账号
  743. JSONArray jsonArray = paramObj.getJSONArray("selectUserAccount");
  744. if (jsonArray == null || jsonArray.size() < 1) {
  745. return;
  746. }
  747. List<AccountDto> accountDtos = new ArrayList<>();
  748. for (int columnIndex = 0; columnIndex < jsonArray.size(); columnIndex++) {
  749. //应收款 totalFeePrice
  750. BigDecimal totalFeePrice = new BigDecimal(paramObj.getString("totalFeePrice")); //应收款
  751. //实收款 receivedAmount
  752. BigDecimal receivedAmount = new BigDecimal(paramObj.getString("receivedAmount")); //实收款(扣款金额)
  753. BigDecimal redepositAmount = new BigDecimal("0.00");//抵扣金额
  754. JSONObject param = jsonArray.getJSONObject(columnIndex);
  755. if (!StringUtil.isEmpty(param.getString("acctType")) && param.getString("acctType").equals("2004")) { //积分账户
  756. //获取抵扣比例
  757. BigDecimal deductionProportion = new BigDecimal(param.getString("deductionProportion"));
  758. //计算实收款所扣的积分
  759. BigDecimal multiply = receivedAmount.multiply(deductionProportion);
  760. receivedAmount = multiply;
  761. }
  762. //账户金额
  763. BigDecimal amount = new BigDecimal(param.getString("amount"));
  764. int flag = amount.compareTo(receivedAmount);
  765. if (flag == -1) { //账户金额小于实收款
  766. redepositAmount = amount;//抵扣金额
  767. } else {
  768. redepositAmount = receivedAmount;//抵扣金额
  769. }
  770. if ("2004".equals(param.getString("acctType"))) {
  771. //获取最大抵扣积分
  772. BigDecimal maximumNumber = new BigDecimal(param.getString("maximumNumber"));
  773. //获取积分抵扣
  774. BigDecimal deductionProportion = new BigDecimal(param.getString("deductionProportion"));
  775. int flag2 = amount.compareTo(maximumNumber);
  776. if (flag2 == 1) { //账户积分大于最大使用积分,就用最大使用积分抵扣
  777. int flag3 = maximumNumber.compareTo(receivedAmount);
  778. if (flag3 == 1) { //如果最大使用积分大于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  779. redepositAmount = receivedAmount;
  780. } else if (flag3 > -1) {//如果最大使用积分大于等于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  781. redepositAmount = receivedAmount;
  782. } else {
  783. redepositAmount = maximumNumber;
  784. }
  785. }
  786. if (flag2 > -1) { //账户积分大于等于最大使用积分,就用最大使用积分抵扣
  787. int flag3 = maximumNumber.compareTo(receivedAmount);
  788. if (flag3 == 1) { //如果最大使用积分大于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  789. redepositAmount = receivedAmount;
  790. } else if (flag3 > -1) {//如果最大使用积分大于等于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  791. redepositAmount = receivedAmount;
  792. } else {
  793. redepositAmount = maximumNumber;
  794. }
  795. }
  796. if (flag2 == -1) { //账户积分小于最大使用积分,就用账户积分抵扣
  797. int flag3 = amount.compareTo(receivedAmount);
  798. if (flag3 == 1) { //如果积分账户大于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  799. redepositAmount = receivedAmount;
  800. } else if (flag3 > -1) {//如果积分账户大于等于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  801. redepositAmount = receivedAmount;
  802. } else {
  803. redepositAmount = amount;
  804. }
  805. }
  806. if (flag2 < 1) { //账户积分小于等于最大使用积分,就用账户积分抵扣
  807. int flag3 = amount.compareTo(receivedAmount);
  808. if (flag3 == 1) { //如果积分账户大于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  809. redepositAmount = receivedAmount;
  810. } else if (flag3 > -1) {//如果积分账户大于等于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  811. redepositAmount = receivedAmount;
  812. } else {
  813. redepositAmount = amount;
  814. }
  815. }
  816. if (flag2 == 0) { //账户积分等于最大使用积分
  817. int flag3 = amount.compareTo(receivedAmount);
  818. if (flag3 == 1) { //如果积分账户大于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  819. redepositAmount = receivedAmount;
  820. } else if (flag3 > -1) {//如果积分账户大于等于实收金额抵扣积分,就把实收金额抵扣积分赋值给抵扣积分
  821. redepositAmount = receivedAmount;
  822. } else {
  823. redepositAmount = amount;
  824. }
  825. }
  826. //计算积分换算的金额
  827. BigDecimal divide = redepositAmount.divide(deductionProportion);
  828. BigDecimal divide1 = receivedAmount.divide(deductionProportion);
  829. //计算还需支付的金额
  830. BigDecimal subtract = divide1.subtract(divide);
  831. paramObj.put("receivedAmount", subtract);
  832. }
  833. String acctId = param.getString("acctId");
  834. if (StringUtil.isEmpty(acctId)) {
  835. throw new IllegalArgumentException("账户id为空!");
  836. }
  837. AccountDto accountDto = new AccountDto();
  838. accountDto.setAcctId(acctId);
  839. //查询账户金额
  840. accountDtos = accountInnerServiceSMOImpl.queryAccounts(accountDto);
  841. Assert.listOnlyOne(accountDtos, "查询账户金额错误!");
  842. if (accountDtos != null && accountDtos.size() > 0) {
  843. AccountDto accountDto1 = accountDtos.get(0);
  844. BigDecimal accountDto1Amount = new BigDecimal(accountDto1.getAmount());
  845. if (accountDto1Amount.compareTo(redepositAmount) == -1) {
  846. throw new UnsupportedOperationException("账户金额抵扣不足,请您确认账户金额!");
  847. }
  848. }
  849. AccountDetailPo accountDetailPo = new AccountDetailPo();
  850. accountDetailPo.setDetailId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_detailId));
  851. int flag1 = redepositAmount.compareTo(BigDecimal.ZERO);
  852. if (flag1 == 1) {
  853. accountDetailPo.setAmount(redepositAmount + "");
  854. accountDetailPo.setDetailType(AccountDetailDto.DETAIL_TYPE_OUT);
  855. accountDetailPo.setRemark("前台缴费扣款");
  856. }
  857. accountDetailPo.setOrderId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_orderId));
  858. accountDetailPo.setObjType(accountDtos.get(0).getObjType());
  859. accountDetailPo.setObjId(accountDtos.get(0).getObjId());
  860. accountDetailPo.setAcctId(accountDtos.get(0).getAcctId());
  861. accountDetailPo.setRelAcctId(GenerateCodeFactory.getGeneratorId(GenerateCodeFactory.CODE_PREFIX_detailId));
  862. flag = accountInnerServiceSMOImpl.withholdAccount(accountDetailPo);
  863. if (flag < 1) {
  864. throw new CmdException("扣款失败");
  865. }
  866. }
  867. }
  868. private static Calendar getTargetEndTime(Calendar endCalender, Double cycles) {
  869. if (StringUtil.isInteger(cycles.toString())) {
  870. endCalender.add(Calendar.MONTH, new Double(cycles).intValue());
  871. return endCalender;
  872. }
  873. if (cycles >= 1) {
  874. endCalender.add(Calendar.MONTH, new Double(Math.floor(cycles)).intValue());
  875. cycles = cycles - Math.floor(cycles);
  876. }
  877. int futureDay = endCalender.getActualMaximum(Calendar.DAY_OF_MONTH);
  878. int hours = new Double(cycles * futureDay * 24).intValue();
  879. endCalender.add(Calendar.HOUR, hours);
  880. return endCalender;
  881. }
  882. }