FundManagerOrderServiceImpl.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. package com.goafanti.order.service.impl;
  2. import java.io.UnsupportedEncodingException;
  3. import java.math.BigDecimal;
  4. import java.util.Calendar;
  5. import java.util.Date;
  6. import java.util.HashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.UUID;
  10. import javax.mail.MessagingException;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Service;
  15. import com.goafanti.admin.bo.AdminListBo;
  16. import com.goafanti.common.bo.EmailBo;
  17. import com.goafanti.common.dao.AdminMapper;
  18. import com.goafanti.common.dao.NoticeMapper;
  19. import com.goafanti.common.dao.TOrderBackMapper;
  20. import com.goafanti.common.dao.TOrderBillNewMapper;
  21. import com.goafanti.common.dao.TOrderBonusMapper;
  22. import com.goafanti.common.dao.TOrderLogMapper;
  23. import com.goafanti.common.dao.TOrderMonthReportMapper;
  24. import com.goafanti.common.dao.TOrderNewMapper;
  25. import com.goafanti.common.dao.TOrderRefundMapper;
  26. import com.goafanti.common.dao.TOrderTaskMapper;
  27. import com.goafanti.common.enums.NoticeStatus;
  28. import com.goafanti.common.enums.OrderLogProcess;
  29. import com.goafanti.common.model.Notice;
  30. import com.goafanti.common.model.TOrderBack;
  31. import com.goafanti.common.model.TOrderBillNew;
  32. import com.goafanti.common.model.TOrderBonus;
  33. import com.goafanti.common.model.TOrderLog;
  34. import com.goafanti.common.model.TOrderMonthReport;
  35. import com.goafanti.common.model.TOrderNew;
  36. import com.goafanti.common.model.TOrderRefund;
  37. import com.goafanti.common.model.TOrderTask;
  38. import com.goafanti.common.utils.LoggerUtils;
  39. import com.goafanti.common.utils.SendEmailUtil;
  40. import com.goafanti.common.utils.StringUtils;
  41. import com.goafanti.core.mybatis.BaseMybatisDao;
  42. import com.goafanti.core.mybatis.JDBCIdGenerator;
  43. import com.goafanti.core.mybatis.page.Pagination;
  44. import com.goafanti.core.shiro.token.TokenManager;
  45. import com.goafanti.order.bo.OrderListBo;
  46. import com.goafanti.order.bo.TOrderNewBo;
  47. import com.goafanti.order.enums.ApprovalNewState;
  48. import com.goafanti.order.enums.BonusSubject;
  49. import com.goafanti.order.enums.LiquidationNewState;
  50. import com.goafanti.order.enums.OrderNewState;
  51. import com.goafanti.order.enums.ProcessStatus;
  52. import com.goafanti.order.enums.refundState;
  53. import com.goafanti.order.service.FundManageOrderService;
  54. import com.goafanti.order.service.OrderNewService;
  55. @Service
  56. public class FundManagerOrderServiceImpl extends BaseMybatisDao<TOrderNewMapper> implements FundManageOrderService {
  57. @Autowired
  58. private TOrderNewMapper tOrderNewMapper;
  59. @Autowired
  60. private AdminMapper adminMapper;
  61. @Autowired
  62. private TOrderBillNewMapper billNewMapper;
  63. @Autowired
  64. private TOrderBackMapper backMapper;
  65. @Autowired
  66. private TOrderRefundMapper refundMapper;
  67. @Autowired
  68. private TOrderBonusMapper bonusMapper;
  69. @Autowired
  70. private TOrderMonthReportMapper monthReportMapper;
  71. @Autowired
  72. private TOrderTaskMapper taskMapper;
  73. @Autowired
  74. private TOrderLogMapper tOrderLogMapper;
  75. @Autowired
  76. JDBCIdGenerator idGenerator;
  77. @Autowired
  78. NoticeMapper noticeMapper;
  79. Logger logger = LoggerFactory.getLogger(FundManagerOrderServiceImpl.class);
  80. @SuppressWarnings("unchecked")
  81. @Override
  82. public Pagination<OrderListBo> allUnassignedOrder(OrderListBo order, Integer pageNo,
  83. Integer pageSize) {
  84. Map<String, Object> params = new HashMap<String, Object>();
  85. params.put("o", order);
  86. Pagination<OrderListBo> data = (Pagination<OrderListBo>)findPage("getAllUnassignedListOrder", "getAllUnassignedCountOrder", params, pageNo, pageSize);
  87. return data;
  88. }
  89. @Override
  90. public Integer updateDistributionFinance(String orderNo, String financeId, Integer approval) {
  91. // 先判断订单id和财务专员是否存在或者能够使用
  92. //判断是不是特批的数据
  93. if(approval != ApprovalNewState.TG.getCode() && approval != ApprovalNewState.FTP.getCode()){//特批未通过 2 0
  94. return -1;
  95. }
  96. TOrderNew onew = new TOrderNew();
  97. TOrderNew torder=tOrderNewMapper.selectByPrimaryKey(orderNo);
  98. onew.setOrderNo(orderNo);
  99. onew.setDeleteSign(0);//正常
  100. onew.setApproval(approval);//特批状态
  101. if(approval == ApprovalNewState.FTP.getCode()){
  102. onew.setProcessStatus(ProcessStatus.YPCWGLY.getCode());//已派财务管理员
  103. }
  104. onew.setOrderStatus(OrderNewState.QDSHTG.getCode());//营销管理员审核通过
  105. int idCount = tOrderNewMapper.getCountByIdAndStatus(onew);
  106. int fidCount = adminMapper.getCountById(financeId);
  107. Integer r = null;
  108. if(idCount == 1 && fidCount == 1){
  109. //修改订单流程状态
  110. TOrderNew record = new TOrderNew();
  111. record.setOrderNo(orderNo);
  112. record.setFinanceId(financeId);
  113. if(torder.getProcessStatus()<ProcessStatus.YPZXSGLY.getCode()) {
  114. record.setProcessStatus(ProcessStatus.YPCWZY.getCode());
  115. }
  116. addOrderLog(orderNo, OrderLogProcess.CWPD.getCode());
  117. r = tOrderNewMapper.updateByPrimaryKeySelective(record);
  118. }else{
  119. //返回错误标志 提示订单编号或者财务专员选择错误
  120. r = -2;
  121. }
  122. return r;
  123. }
  124. public void addOrderLog(String orderNo, Integer code) {
  125. TOrderLog tl=new TOrderLog();
  126. tl.setOrderNo(orderNo);
  127. tl.setProcess(code);
  128. tl.setAid(TokenManager.getAdminId());
  129. tOrderLogMapper.insertSelective(tl);
  130. }
  131. @SuppressWarnings("unchecked")
  132. @Override
  133. public Pagination<OrderListBo> financeList(OrderListBo order,
  134. Integer pageNo, Integer pageSize) {
  135. Map<String, Object> params = new HashMap<String, Object>();
  136. params.put("o", order);
  137. Pagination<OrderListBo> data = (Pagination<OrderListBo>)findPage("financeList", "financeCount", params, pageNo, pageSize);
  138. return data;
  139. }
  140. @Override
  141. public Integer updateReject(TOrderBack back) {
  142. // 是否已经收款
  143. BigDecimal bd = billNewMapper.getAmountByOid(back.getOrderNo());
  144. if(bd.compareTo(new BigDecimal(0.0)) == 1){
  145. return 0;//已经收款不能驳回
  146. }
  147. TOrderNewBo b = tOrderNewMapper.getSaleIdByOno(back.getOrderNo());//订单和订单负责人相关信息
  148. if(null == b || StringUtils.isBlank(b.getSalesmanId())){
  149. return -1;
  150. }
  151. //否 可以处理驳回
  152. //修改订单状态
  153. TOrderNew orderNew = new TOrderNew();
  154. orderNew.setOrderNo(back.getOrderNo());
  155. orderNew.setOrderStatus(OrderNewState.YBH.getCode());
  156. int c = tOrderNewMapper.updateByPrimaryKeySelective(orderNew);
  157. //新增驳回数据
  158. if(c>0){
  159. back.setBackStatus(0);
  160. back.setInitiate(TokenManager.getAdminId());//发起人
  161. back.setAccept(b.getSalesmanId()); //查看该订单的负责人
  162. addOrderLog(back.getOrderNo(), OrderLogProcess.BH.getCode());
  163. c = backMapper.insertSelective(back);
  164. //发送站内消息
  165. addNotic(back.getOrderNo(),NoticeStatus.ORDER_BACK.getCode(),b.getSalesmanId());
  166. if(StringUtils.isNotBlank(b.getEmail())){ //邮箱不为空发送邮件
  167. AdminListBo a = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
  168. //发送驳回邮件
  169. String content = "<div>客户名称: "+ b.getUserName() +"</div><div>订单编号: " + back.getOrderNo() + "</div>";
  170. EmailBo bo = new EmailBo("订单驳回", b.getEmail(), b.getSalesmanName(), a.getDepartmentName(), a.getName(), content);
  171. try {
  172. SendEmailUtil.getInstance().send(bo);
  173. } catch (UnsupportedEncodingException e) {
  174. e.printStackTrace();
  175. } catch (MessagingException e) {
  176. e.printStackTrace();
  177. }
  178. }
  179. }
  180. return c;
  181. }
  182. @Override
  183. public Integer addReceiptsFlow(TOrderBillNew billNew, String contractNo) {
  184. //判断有没有要加入的金额有没有超过总金额
  185. BigDecimal bill = billNewMapper.getAmountByOid(billNew.getOrderNo());
  186. //获得的单个订单金额数据(首付金额和总金额)
  187. TOrderNew o = tOrderNewMapper.selectByPrimaryKey(billNew.getOrderNo());
  188. if(null == o){
  189. return -2;
  190. }
  191. BigDecimal bd = bill.add(billNew.getTransactionAmount().abs());
  192. //奖金信息
  193. TOrderBonus bonus = new TOrderBonus();
  194. bonus.setId(UUID.randomUUID().toString());
  195. bonus.setOrderNo(billNew.getOrderNo());
  196. bonus.setGrantBy(TokenManager.getAdminId());
  197. int lstaus = 0;//如果订单流水小于首付 lstaus 0
  198. // 0 相等
  199. // -1 小于
  200. // 1 大于
  201. if(bd.compareTo(o.getTotalAmount()) == 1){//如果订单流水总额大于总金额 return -1
  202. return -1;//超过不能添加
  203. }else if(bd.compareTo(o.getTotalAmount()) == 0){//付完款//如果订单流水等于于总金额 lstaus 2
  204. lstaus = 2;
  205. bonus.setBonusSubject(BonusSubject.WK.getCode());//12
  206. //发放给技术员如果付完款所有参与这个项目任务的人都会有结算奖
  207. //获得所有的任务负责人
  208. List<TOrderTask> l = taskMapper.getReceiverByOid(billNew.getOrderNo());
  209. // 取消没有技术员不能支付全款
  210. // if(null == l || l.size() == 0){
  211. // return -3;//没有给将任务分给咨询师(技术员)
  212. // }
  213. for (TOrderTask tOrderTask : l) {
  214. if(null != tOrderTask &&null != tOrderTask.getTaskReceiver()){
  215. bonus.setTaskId(tOrderTask.getId());//任务id
  216. bonus.setGrantTarget(tOrderTask.getTaskReceiver());
  217. bonus.setGrantType(1);
  218. int c = bonusMapper.checkByOnoAndSub(bonus);
  219. //不存在就设置
  220. if(c==0){
  221. bonus.setId(UUID.randomUUID().toString());
  222. bonusMapper.insertSelective(bonus);
  223. }
  224. }
  225. }
  226. addOrderLog(billNew.getOrderNo(), OrderLogProcess.CWQK.getCode());
  227. }else if(bd.compareTo(o.getTotalAmount()) == -1){//如果订单流水小于总金额
  228. if(bd.compareTo(o.getFirstAmount()) == 0 || bd.compareTo(o.getFirstAmount()) == 1){//首付完成
  229. //查看首付奖是否存在
  230. TOrderBonus b = new TOrderBonus();
  231. b.setOrderNo(billNew.getOrderNo());
  232. b.setBonusSubject(11);
  233. b.setGrantType(0);
  234. b.setGrantTarget(o.getSalesmanId());
  235. int c = bonusMapper.checkByOnoAndSub(b);
  236. //不存在就设置
  237. if(c==0){
  238. bonus.setBonusSubject(BonusSubject.SF.getCode());//11
  239. }
  240. lstaus = 1;
  241. addOrderLog(billNew.getOrderNo(), OrderLogProcess.CWSF.getCode());
  242. }
  243. }
  244. //否则新增流水信息
  245. billNew.setBillNo(UUID.randomUUID().toString().replaceAll("-", ""));
  246. billNew.setCreater(TokenManager.getAdminId());
  247. int result = billNewMapper.insertSelective(billNew);
  248. //修改订单结算金额和结算状态
  249. //如果已经首付并且流程状态是没有派给咨询师的修改流程状态为4
  250. TOrderNew orderNew = new TOrderNew();
  251. orderNew.setOrderNo(billNew.getOrderNo());
  252. orderNew.setContractNo(contractNo);
  253. //这里的已收金额是以前收的所有金额加上本次收的金额
  254. orderNew.setSettlementAmount(billNew.getTransactionAmount().add(o.getSettlementAmount()));
  255. orderNew.setLiquidationStatus(lstaus);
  256. if((lstaus == LiquidationNewState.WAIT_PAY_LAST_BALANCE.getCode()
  257. || lstaus == LiquidationNewState.ALREADY_PAY.getCode())
  258. && o.getProcessStatus() < ProcessStatus.YPZXSGLY.getCode()){
  259. //流程状态是3,结算是付款的话
  260. orderNew.setProcessStatus(ProcessStatus.YPZXSGLY.getCode());//4
  261. }
  262. if(result > 0){
  263. result = tOrderNewMapper.updateByPrimaryKeySelective(orderNew);
  264. //如果达到奖金发放要求新增奖金信息
  265. if(null != bonus.getBonusSubject()){
  266. bonus.setId(UUID.randomUUID().toString());
  267. bonus.setGrantTarget(o.getSalesmanId());
  268. //设置发放人类型
  269. bonus.setGrantType(0);
  270. bonusMapper.insertSelective(bonus);
  271. }
  272. }
  273. return result;
  274. }
  275. @Override
  276. public Integer updateChangeRefund(TOrderRefund refund) {
  277. //查看当前退单状态
  278. TOrderRefund d = refundMapper.selectByPrimaryKey(refund.getId());
  279. if(d.getRefundStatus() != refundState.DSH.getCode()){
  280. return -1;
  281. }
  282. //如果审核通过给咨询师和营销员发起退单通知
  283. if(refund.getRefundStatus() == refundState.SHTG.getCode()){
  284. //修改订单状态
  285. TOrderNewBo o = tOrderNewMapper.agreeEmailData(refund.getId());
  286. TOrderNew record = new TOrderNew();
  287. record.setOrderNo(o.getOrderNo());
  288. record.setOrderStatus(OrderNewState.YTD.getCode());//7
  289. record.setProofCount(0.0f);//订单单量为0
  290. tOrderNewMapper.updateByPrimaryKeySelective(record);
  291. //更新统计表
  292. updateCount(o.getOrderNo());
  293. //新增奖金信息表数据
  294. TOrderBonus bonus = new TOrderBonus();
  295. bonus.setId(UUID.randomUUID().toString());
  296. bonus.setOrderNo(o.getOrderNo());
  297. bonus.setGrantBy(TokenManager.getAdminId());
  298. bonus.setGrantTarget(o.getSalesmanId());
  299. bonus.setBonusSubject(BonusSubject.TK.getCode());//16
  300. bonusMapper.insertSelective(bonus);
  301. //退单邮件发送需要的数据
  302. AdminListBo a = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
  303. String content = "<div>退单编号: "+ refund.getId() +"</div><div>客户名称: " + o.getUserName() + "</div>";
  304. content += "<div>订单编号: "+ o.getOrderNo() +"</div>";
  305. if(StringUtils.isNotBlank(o.getEmail())){
  306. EmailBo emailBo = new EmailBo("同意退单", o.getEmail(), o.getSalesmanName(), a.getDepartmentName(), a.getName(), content);
  307. try {
  308. SendEmailUtil.getInstance().send(emailBo);
  309. } catch (UnsupportedEncodingException e) {
  310. e.printStackTrace();
  311. } catch (MessagingException e) {
  312. e.printStackTrace();
  313. }
  314. }
  315. //发送站内消息
  316. addNotic(o.getOrderNo(),NoticeStatus.ORDER_REFUND.getCode(),o.getSalesmanId());//给营销员
  317. //根据订单编号获得所有的技术员
  318. List<TOrderTask> l = taskMapper.getReceiverByOid(o.getOrderNo());
  319. for (TOrderTask tOrderTask : l) {
  320. if(null != tOrderTask && null != tOrderTask.getTaskReceiver()){
  321. addNotic(o.getOrderNo(),NoticeStatus.ORDER_REFUND.getCode(),tOrderTask.getTaskReceiver());//给技术员
  322. //发邮件给技术员
  323. if(StringUtils.isNotBlank(tOrderTask.getEmail())){
  324. EmailBo emailBo = new EmailBo("同意退单", tOrderTask.getEmail(), tOrderTask.getName(), a.getDepartmentName(), a.getName(), content);
  325. try {
  326. SendEmailUtil.getInstance().send(emailBo);
  327. } catch (UnsupportedEncodingException e) {
  328. e.printStackTrace();
  329. } catch (MessagingException e) {
  330. e.printStackTrace();
  331. }
  332. }
  333. }
  334. }
  335. }else{//审核拒绝
  336. //给营销员发通知和邮件
  337. TOrderNewBo o = tOrderNewMapper.agreeEmailData(refund.getId());
  338. addNotic(o.getOrderNo(),NoticeStatus.ORDER_REFUND_REFUSE.getCode(),o.getSalesmanId());//给营销员
  339. AdminListBo a = adminMapper.getDeptNameByAid(TokenManager.getAdminId());
  340. String content = "<div>退单编号: "+ refund.getId() +"</div><div>客户名称: " + o.getUserName() + "</div>";
  341. content += "<div>订单编号: "+ o.getOrderNo() +"</div>";
  342. String email = o.getEmail();
  343. if(StringUtils.isNotBlank(email)){
  344. email = email.substring(0, email.indexOf(","));
  345. String sale = o.getSalesmanName();
  346. sale = sale.substring(0,sale.indexOf(","));
  347. if(email.matches("[\\w\\.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+")){//email格式校验
  348. EmailBo emailBo = new EmailBo("拒绝退单",email, sale, a.getDepartmentName(), a.getName(), content);
  349. try {
  350. SendEmailUtil.getInstance().send(emailBo);
  351. } catch (UnsupportedEncodingException e) {
  352. e.printStackTrace();
  353. } catch (MessagingException e) {
  354. e.printStackTrace();
  355. }
  356. }
  357. }
  358. }
  359. //修改退单审核状态
  360. return refundMapper.updateRefundById(refund);
  361. }
  362. @Override
  363. public Integer addRefundFlow(TOrderBillNew billNew) {
  364. // 查看收款总金额流水
  365. BigDecimal bd = billNewMapper.getAmountByOid(billNew.getOrderNo());
  366. billNew.setTransactionAmount(billNew.getTransactionAmount().abs());//绝对值
  367. int lstaus = 3;
  368. //如果小于要退的金额 return -1
  369. //如果等于要退的金额 lstatus 4
  370. //如果大于 要退的金额 lstatus 3
  371. if(bd.compareTo(billNew.getTransactionAmount()) == -1){
  372. return -1;
  373. }else if(bd.compareTo(billNew.getTransactionAmount()) == 0){
  374. lstaus = 4;
  375. }
  376. //新增退款流水
  377. billNew.setBillNo(UUID.randomUUID().toString().replaceAll("-", ""));
  378. //System.out.println("*****************"+billNew.getBillNo());
  379. billNew.setCreater(TokenManager.getAdminId());
  380. billNew.setTransactionAmount(billNew.getTransactionAmount().negate());// 取负数
  381. int result = billNewMapper.insertSelective(billNew);
  382. //修改订单数据结算状态和结算金额
  383. TOrderNew orderNew = new TOrderNew();
  384. orderNew.setOrderNo(billNew.getOrderNo());
  385. TOrderNew o = tOrderNewMapper.selectByPrimaryKey(billNew.getOrderNo());
  386. //这里修改退款金额数据之前退的金额加上本次退的金额
  387. orderNew.setRefundAmount(billNew.getTransactionAmount().add(o.getRefundAmount()));
  388. orderNew.setLiquidationStatus(lstaus);
  389. if(lstaus == 4){//如果款项全部退完就更改订单状态,这里不一定待商榷
  390. addOrderLog(billNew.getOrderNo(), OrderLogProcess.WCTD.getCode());
  391. //orderNew.setProcessStatus(6);
  392. }
  393. if(result > 0){
  394. result = tOrderNewMapper.updateByPrimaryKeySelective(orderNew);
  395. }
  396. return result;
  397. }
  398. @Override
  399. public TOrderBillNew selectOneRefundFlow(String BillNo) {
  400. return billNewMapper.getOneRefundFlow(BillNo);
  401. }
  402. @Override
  403. public List<TOrderBillNew> selectOneOrderAllRefundFlow(String orderNo) {
  404. return billNewMapper.getOneOrderAllRefundFlow(orderNo);
  405. }
  406. @Override
  407. public Integer updateProofreading(TOrderNew orderNew) {
  408. // 创建人
  409. orderNew.setProofAid(TokenManager.getAdminId());
  410. //校对状态
  411. orderNew.setProofStatus(1);
  412. //校对时间
  413. orderNew.setProofTime(new Date());
  414. tOrderNewMapper.updateByPrimaryKeySelective(orderNew);
  415. updateCount(orderNew.getOrderNo());
  416. return 0;
  417. }
  418. public void addNotic(String orderNo,Integer type,String aid) {
  419. String id=TokenManager.getAdminId()==null?"1":TokenManager.getAdminId();
  420. AdminListBo a = adminMapper.getDeptNameByAid(id);
  421. String str=NoticeStatus.getValueByCode(type)+": 订单编号 -"+orderNo+", 操作人:"+a.getDepartmentName()+"-"+a.getName()+"。";
  422. Notice n =new Notice();
  423. n.setId(UUID.randomUUID().toString());
  424. n.setAid(aid);//通知人
  425. n.setNoticeType(type);
  426. n.setContent(str);
  427. n.setReaded(0);//未读
  428. noticeMapper.insertSelective(n);
  429. }
  430. private void updateCount(String orderNo){
  431. //获得订单数据
  432. TOrderNew new1 = tOrderNewMapper.selectByPrimaryKey(orderNo);
  433. Calendar cal = Calendar.getInstance();
  434. cal.setTime(new1.getSignTime());
  435. int sy = cal.get(Calendar.YEAR);
  436. int sm = cal.get(Calendar.MONTH);
  437. Integer month = sy*100+(sm+1);
  438. //重新校对月统计
  439. int c = monthReportMapper.updateByMonth(month);
  440. LoggerUtils.debug(logger, "更新订单统计【%s】条。", c);
  441. }
  442. @Override
  443. public int updateContractNo(TOrderNew orderNew) {
  444. return tOrderNewMapper.updateByPrimaryKeySelective(orderNew);
  445. }
  446. }