diff --git a/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/controller/BuyerController.java b/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/controller/BuyerController.java index 399ba2e8..e62aae80 100644 --- a/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/controller/BuyerController.java +++ b/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/controller/BuyerController.java @@ -7,7 +7,6 @@ import com.dxhy.order.baseservice.annotation.SysLog; import com.dxhy.order.baseservice.config.BaseServiceConfig; import com.dxhy.order.baseservice.module.base.service.ExcelReadService; import com.dxhy.order.baseservice.module.buyer.model.BuyerEntity; -import com.dxhy.order.baseservice.module.buyer.model.BuyerEntityDetail; import com.dxhy.order.baseservice.module.buyer.model.BuyerImportExcel; import com.dxhy.order.baseservice.module.buyer.model.BuyerImportExcelEnum; import com.dxhy.order.baseservice.module.buyer.service.BuyerService; @@ -117,7 +116,10 @@ public class BuyerController { // 购方名称 带中文括号的转换成英文括号 buyerEntity.setPurchaseName(StringUtil.replaceStr(buyerEntity.getPurchaseName(), true)); - + String buyerCode = buyerEntity.getBuyerCode(); + if(StringUtils.isBlank(buyerCode)){ + return R.error("客户编码不能为空"); + } // 获取当前登录人id Long userId = userInfoService.getUser().getUserId(); String id = buyerEntity.getId(); diff --git a/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/service/impl/BuyerServiceImpl.java b/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/service/impl/BuyerServiceImpl.java index 3e770711..35607773 100644 --- a/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/service/impl/BuyerServiceImpl.java +++ b/order-management-base-service/src/main/java/com/dxhy/order/baseservice/module/buyer/service/impl/BuyerServiceImpl.java @@ -346,6 +346,19 @@ public class BuyerServiceImpl implements BuyerService { shList.add(buyerEntity.getXhfNsrsbh()); R r = new R(); + BuyerEntity queryBuyerEntity = new BuyerEntity(); + queryBuyerEntity.setBuyerCode(buyerEntity.getId()); + BuyerEntity entity = buyerMapper.selectBuyerByCodeOrNameAndNsrsbh("", buyerEntity.getBuyerCode(), null); + if(entity != null){ + if (StringUtils.isNotBlank(buyerEntity.getId())) { + if(!buyerEntity.getId().equals(entity.getId())){ + return r.put("message", "客户编码已存在").put(OrderManagementConstant.CODE, ConfigureConstant.STRING_9999); + } + }else { + return r.put("message", "客户编码已存在").put(OrderManagementConstant.CODE, ConfigureConstant.STRING_9999); + } + } + // if (ConfigureConstant.STRING_1.equals(buyerEntity.getIsEdit()) && StringUtils.isBlank(buyerEntity.getId())) { BuyerEntity existBuyer = isExistBuyer(buyerEntity); if (ObjectUtil.isNotNull(existBuyer)) { @@ -525,7 +538,6 @@ public class BuyerServiceImpl implements BuyerService { * @return */ private BuyerEntity isExistBuyer(BuyerEntity buyerEntity) { - BuyerEntity queryBuyerEntity = new BuyerEntity(); if (StringUtils.isNotBlank(buyerEntity.getId())) { queryBuyerEntity.setId(buyerEntity.getId()); diff --git a/order-management-base-service/src/main/resources/mybatis/mapper/BuyerMapper.xml b/order-management-base-service/src/main/resources/mybatis/mapper/BuyerMapper.xml index b15afb79..60d8bd64 100644 --- a/order-management-base-service/src/main/resources/mybatis/mapper/BuyerMapper.xml +++ b/order-management-base-service/src/main/resources/mybatis/mapper/BuyerMapper.xml @@ -906,9 +906,6 @@ FROM buyer_manage_info - - and xhf_nsrsbh = '' - and xhf_nsrsbh = diff --git a/order-management-consumer/src/main/java/com/dxhy/order/consumer/handle/YpyjTask.java b/order-management-consumer/src/main/java/com/dxhy/order/consumer/handle/YpyjTask.java index d6b7a0ec..0a207822 100644 --- a/order-management-consumer/src/main/java/com/dxhy/order/consumer/handle/YpyjTask.java +++ b/order-management-consumer/src/main/java/com/dxhy/order/consumer/handle/YpyjTask.java @@ -1,206 +1,205 @@ -package com.dxhy.order.consumer.handle;//package com.dxhy.order.consumer.handle; -// -//import cn.hutool.core.util.ObjectUtil; -//import cn.hutool.core.util.RandomUtil; -//import com.dxhy.order.baseservice.module.base.model.InvoiceWarningInfo; -//import com.dxhy.order.baseservice.module.base.service.YpWarningService; -//import com.dxhy.order.baseservice.module.thirdservice.itaxmsg.service.ItaxMsgService; -//import com.dxhy.order.baseservice.module.thirdservice.simsback.service.SimsBackService; -//import com.dxhy.order.constant.ConfigureConstant; -//import com.dxhy.order.constant.OrderInfoEnum; -//import com.dxhy.order.constant.RedisConstant; -//import com.dxhy.order.invoice.config.InvoiceConfig; -//import com.dxhy.order.invoice.module.invoice.service.EmailService; -//import com.dxhy.order.invoice.utils.HttpInvoiceRequestUtil; -//import com.dxhy.order.model.sk.sld.SldKcByFjhResponseExtend; -//import com.dxhy.order.model.sk.sld.SldKcRequest; -//import com.dxhy.order.model.sk.sld.SldKcmxByFjh; -//import com.dxhy.order.utils.CommonUtils; -//import com.dxhy.order.utils.JsonUtils; -//import com.dxhy.order.utils.NsrsbhUtils; -//import com.xxl.job.core.biz.model.ReturnT; -//import com.xxl.job.core.handler.IJobHandler; -//import com.xxl.job.core.handler.annotation.JobHandler; -//import lombok.extern.slf4j.Slf4j; -//import org.apache.commons.lang3.StringUtils; -//import org.slf4j.MDC; -//import org.slf4j.spi.MDCAdapter; -//import org.springframework.stereotype.Component; -// -//import javax.annotation.Resource; -//import java.math.BigDecimal; -//import java.util.ArrayList; -//import java.util.HashMap; -//import java.util.List; -//import java.util.Map; -//import java.util.stream.Collectors; -// -///** -// * todo 转为基础服务提供服务 -// * @Description 余票预警定时任务 -// * @Author xieyuanqiang -// * @Date 11:09 2018-09-19 -// */ -//@SuppressWarnings("AlibabaMethodTooLong") -//@Slf4j -//@Component -//@JobHandler(value = "/ypyjTask") -//public class YpyjTask extends IJobHandler { -// private static final String LOGGER_MSG = "(余票预警)"; -// @Resource -// private YpWarningService ypWarningService; -// @Resource -// private ItaxMsgService itaxMsgService; -// @Resource -// private EmailService emailService; -// @Resource -// private SimsBackService simsBackService; -// @Resource -// private InvoiceConfig invoiceConfig; -// -// @Override -// public ReturnT execute(String s) { -// try { -// -// //添加日志id -// MDCAdapter mdc = MDC.getMDCAdapter(); -// mdc.put("X-B3-TraceId", RandomUtil.randomString(25)); -// -// log.info("ypyjTask 余票预警 定时任务开始执行"); -// -// // 获取开票信息 -// InvoiceWarningInfo invoiceWarningInfo1 = new InvoiceWarningInfo(); -// invoiceWarningInfo1.setSfyj(ConfigureConstant.STRING_1); -// List data = ypWarningService.selectYpWarning(invoiceWarningInfo1, null, null); -// -// /** -// * 列出所有税号,查询税号对应的库存信息 -// */ -// List requestList = new ArrayList<>(); -// if (ObjectUtil.isNotEmpty(data)) { -// for (InvoiceWarningInfo invoiceWarningInfo : data) { -// requestList.add(invoiceWarningInfo.getXhfNsrsbh() + ConfigureConstant.STRING_UNDERLINE + invoiceWarningInfo.getSbbh() + ConfigureConstant.STRING_UNDERLINE + invoiceWarningInfo.getEntId()); -// } -// -// } -// requestList = requestList.stream().filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList()); -// Map sldKcByFjhResponseExtendMap = new HashMap<>(5); -// if (ObjectUtil.isNotEmpty(requestList)) { -// -// try { -// //遍历所有税号的库存信息 -// for (String request : requestList) { -// SldKcRequest kccxRequest = new SldKcRequest(); -// String terminalCode = simsBackService.getTerminalCode(request.split(ConfigureConstant.STRING_UNDERLINE)[0], request.split(ConfigureConstant.STRING_UNDERLINE)[2]); -// if (StringUtils.isBlank(terminalCode)) { -// log.warn("{}企业未配置税控设备,税号:{}", LOGGER_MSG, request.split(ConfigureConstant.STRING_UNDERLINE)[0]); -// continue; -// } -// /** -// * 方格相关去除 -// */ -// if (CommonUtils.judgeIsFgTerminalType(terminalCode)) { -// continue; -// } -// kccxRequest.setNsrsbh(request.split(ConfigureConstant.STRING_UNDERLINE)[0]); -// if (OrderInfoEnum.TAX_EQUIPMENT_NEWTAX.getKey().equals(terminalCode)) { -// kccxRequest.setJqbh(request.split(ConfigureConstant.STRING_UNDERLINE)[1]); -// } else { -// kccxRequest.setFjh(request.split(ConfigureConstant.STRING_UNDERLINE)[1]); -// } -// -// String kcxxUrl = invoiceConfig.configQuerykcxxByFjh(); -// if (CommonUtils.judgeNewInterface(terminalCode)) { -// kcxxUrl = invoiceConfig.configQueryTaxpayerStockInfo(); -// } -// SldKcByFjhResponseExtend sldKcByFjhResponseExtend = HttpInvoiceRequestUtil.queryKcxxByFjh(kcxxUrl, kccxRequest, terminalCode); -// sldKcByFjhResponseExtendMap.put(request, sldKcByFjhResponseExtend); -// } -// } catch (Exception e) { -// log.error("{}ypyjTask 余票预警 获取分机号异常 异常信息:{}", LOGGER_MSG, e); -// } -// -// log.info("{}调用开票系统查询税盘库存接口结果为:{}", LOGGER_MSG, JsonUtils.getInstance().toJsonString(sldKcByFjhResponseExtendMap)); -// } -// if (ObjectUtil.isNotEmpty(sldKcByFjhResponseExtendMap)) { -// for (InvoiceWarningInfo invoiceWarningInfo : data) { -// try { -// -// SldKcByFjhResponseExtend sldKcByFjhResponseExtend = sldKcByFjhResponseExtendMap.get(invoiceWarningInfo.getXhfNsrsbh() + ConfigureConstant.STRING_UNDERLINE + invoiceWarningInfo.getSbbh()); -// -// if (sldKcByFjhResponseExtend != null && ObjectUtil.isNotEmpty(sldKcByFjhResponseExtend.getKcmxes())) { -// List kcmxs = sldKcByFjhResponseExtend.getKcmxes(); -// Map map = new HashMap<>(10); -// if (ObjectUtil.isNotEmpty(kcmxs)) { -// for (SldKcmxByFjh k : kcmxs) { -// if (!"41".equals(k.getFpzlDm())) { -// if (map.containsKey(k.getFpzlDm())) { -// int x = map.get(k.getFpzlDm()) + Integer.parseInt(k.getFpfs()); -// map.put(k.getFpzlDm(), x); -// } else { -// map.put(k.getFpzlDm(), Integer.valueOf(k.getFpfs())); -// } -// } -// } -// log.info("{}调用库存接口返回结果为:{}", LOGGER_MSG, JsonUtils.getInstance().toJsonString(map)); -// map.forEach((fpzldm, fpfs) -> { -// if (StringUtils.equals(fpzldm, invoiceWarningInfo.getFpzlDm())) { -// int emailNum = Integer.parseInt(invoiceWarningInfo.getYjcs()); -// if (new BigDecimal(fpfs.toString()).compareTo(new BigDecimal(invoiceWarningInfo.getYjfs())) < 0) { -// -// log.info("开始预警 税盘号{} 发票类型{} 发票份数{} 预警份数{}", invoiceWarningInfo.getSbbh(), invoiceWarningInfo.getFpzlDm(), -// fpfs, invoiceWarningInfo.getYjfs()); -// String mc = CommonUtils.getFpzlDmMc(fpzldm); -// String message = ""; -// -// message = String.format(RedisConstant.ERROR_MESSAGE_INVOICE, invoiceWarningInfo.getXhfNsrsbh(), invoiceWarningInfo.getSbbh(), fpfs, mc, invoiceWarningInfo.getYjfs()) + "\n" + message; -// -// log.info("向i-tax系统推送消息开始了。。。"); -// if (emailNum < 1) { -// itaxMsgService.sessMessageToTax("余票预警", message, "2", -// invoiceWarningInfo.getUserId(), invoiceWarningInfo.getEntId()); -// } -// if (OrderInfoEnum.ORDER_WARNING_OPEN.getKey().equals(invoiceWarningInfo.getSfyj())) { -// -// log.info("邮件预警次数{}", emailNum); -// if (emailNum < 1) { -// emailService.sendInvoiceWarningInfoEmail(invoiceWarningInfo.getSbMc(), invoiceWarningInfo.getSfyj(), invoiceWarningInfo.getSbbh(), invoiceWarningInfo.getEMail(), fpfs.toString(), mc); -// emailNum = 1; -// } -// } -// -// } else { -// if (ConfigureConstant.INT_1 == emailNum) { -// emailNum = ConfigureConstant.INT_0; -// } -// } -// -// invoiceWarningInfo.setYjcs(String.valueOf(emailNum)); -// log.info("更新发票预警信息。。。"); -// int reslut = ypWarningService.updateYpWarnInfo(invoiceWarningInfo, NsrsbhUtils.transShListByNsrsbh(invoiceWarningInfo.getXhfNsrsbh())); -// log.info("更新发票预警信息结果 {}", reslut > 0); -// -// } -// }); -// } -// } else { -// log.info("ypyjTask 余票预警 调用开票系统查询税盘库存接口 结果为空"); -// } -// } catch (Exception e) { -// log.error("{}ypyjTask 余票预警 业务处理异常 异常信息:{}", LOGGER_MSG, e); -// -// } -// } -// } else { -// log.info("ypyjTask 余票预警 查询税盘号 结果为空"); -// } -// } catch (Exception e) { -// log.error("{}定时任务执行异常:{}", LOGGER_MSG, e); -// return FAIL; -// } -// return ReturnT.SUCCESS; -// -// -// } -// -//} +package com.dxhy.order.consumer.handle; + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.RandomUtil; +import com.dxhy.order.baseservice.config.BaseServiceConfig; +import com.dxhy.order.baseservice.module.base.model.InvoiceWarningInfo; +import com.dxhy.order.baseservice.module.base.service.YpWarningService; +import com.dxhy.order.baseservice.module.thirdservice.itaxmsg.service.ItaxMsgService; +import com.dxhy.order.baseservice.module.thirdservice.simsback.service.SimsBackService; +import com.dxhy.order.baseservice.utils.HttpInvoiceRequestUtil; +import com.dxhy.order.constant.ConfigureConstant; +import com.dxhy.order.constant.OrderInfoEnum; +import com.dxhy.order.constant.RedisConstant; +import com.dxhy.order.invoice.module.invoice.service.EmailService; +import com.dxhy.order.model.sk.sld.SldKcByFjhResponseExtend; +import com.dxhy.order.model.sk.sld.SldKcRequest; +import com.dxhy.order.model.sk.sld.SldKcmxByFjh; +import com.dxhy.order.utils.CommonUtils; +import com.dxhy.order.utils.JsonUtils; +import com.dxhy.order.utils.NsrsbhUtils; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.IJobHandler; +import com.xxl.job.core.handler.annotation.JobHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.MDC; +import org.slf4j.spi.MDCAdapter; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Description 余票预警定时任务 + * @Author xieyuanqiang + * @Date 11:09 2018-09-19 + */ +@SuppressWarnings("AlibabaMethodTooLong") +@Slf4j +@Component +@JobHandler(value = "/ypyjTask") +public class YpyjTask extends IJobHandler { + private static final String LOGGER_MSG = "(余票预警)"; + @Resource + private YpWarningService ypWarningService; + @Resource + private ItaxMsgService itaxMsgService; + @Resource + private EmailService emailService; + @Resource + private SimsBackService simsBackService; + @Resource + private BaseServiceConfig baseServiceConfig; + + @Override + public ReturnT execute(String s) { + try { + + //添加日志id + MDCAdapter mdc = MDC.getMDCAdapter(); + mdc.put("X-B3-TraceId", RandomUtil.randomString(25)); + + log.info("ypyjTask 余票预警 定时任务开始执行"); + + // 获取开票信息 + InvoiceWarningInfo invoiceWarningInfo1 = new InvoiceWarningInfo(); + invoiceWarningInfo1.setSfyj(ConfigureConstant.STRING_1); + List data = ypWarningService.selectYpWarning(invoiceWarningInfo1, null, null); + + /** + * 列出所有税号,查询税号对应的库存信息 + */ + List requestList = new ArrayList<>(); + if (ObjectUtil.isNotEmpty(data)) { + for (InvoiceWarningInfo invoiceWarningInfo : data) { + requestList.add(invoiceWarningInfo.getXhfNsrsbh() + ConfigureConstant.STRING_UNDERLINE + invoiceWarningInfo.getSbbh() + ConfigureConstant.STRING_UNDERLINE + invoiceWarningInfo.getEntId()); + } + + } + requestList = requestList.stream().filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList()); + Map sldKcByFjhResponseExtendMap = new HashMap<>(5); + if (ObjectUtil.isNotEmpty(requestList)) { + + try { + //遍历所有税号的库存信息 + for (String request : requestList) { + SldKcRequest kccxRequest = new SldKcRequest(); + String terminalCode = simsBackService.getTerminalCode(request.split(ConfigureConstant.STRING_UNDERLINE)[0], request.split(ConfigureConstant.STRING_UNDERLINE)[2]); + if (StringUtils.isBlank(terminalCode)) { + log.warn("{}企业未配置税控设备,税号:{}", LOGGER_MSG, request.split(ConfigureConstant.STRING_UNDERLINE)[0]); + continue; + } + /** + * 方格相关去除 + */ + if (CommonUtils.judgeIsFgTerminalType(terminalCode)) { + continue; + } + kccxRequest.setNsrsbh(request.split(ConfigureConstant.STRING_UNDERLINE)[0]); + if (OrderInfoEnum.TAX_EQUIPMENT_NEWTAX.getKey().equals(terminalCode)) { + kccxRequest.setJqbh(request.split(ConfigureConstant.STRING_UNDERLINE)[1]); + } else { + kccxRequest.setFjh(request.split(ConfigureConstant.STRING_UNDERLINE)[1]); + } + + String kcxxUrl = baseServiceConfig.configQuerykcxxByFjh(); + if (CommonUtils.judgeNewInterface(terminalCode)) { + kcxxUrl = baseServiceConfig.configQueryTaxpayerStockInfo(); + } + SldKcByFjhResponseExtend sldKcByFjhResponseExtend = HttpInvoiceRequestUtil.queryKcxxByFjh(kcxxUrl, kccxRequest, terminalCode); + sldKcByFjhResponseExtendMap.put(request, sldKcByFjhResponseExtend); + } + } catch (Exception e) { + log.error("{}ypyjTask 余票预警 获取分机号异常 异常信息:{}", LOGGER_MSG, e); + } + + log.info("{}调用开票系统查询税盘库存接口结果为:{}", LOGGER_MSG, JsonUtils.getInstance().toJsonString(sldKcByFjhResponseExtendMap)); + } + if (ObjectUtil.isNotEmpty(sldKcByFjhResponseExtendMap)) { + for (InvoiceWarningInfo invoiceWarningInfo : data) { + try { + + SldKcByFjhResponseExtend sldKcByFjhResponseExtend = sldKcByFjhResponseExtendMap.get(invoiceWarningInfo.getXhfNsrsbh() + ConfigureConstant.STRING_UNDERLINE + invoiceWarningInfo.getSbbh()); + + if (sldKcByFjhResponseExtend != null && ObjectUtil.isNotEmpty(sldKcByFjhResponseExtend.getKcmxes())) { + List kcmxs = sldKcByFjhResponseExtend.getKcmxes(); + Map map = new HashMap<>(10); + if (ObjectUtil.isNotEmpty(kcmxs)) { + for (SldKcmxByFjh k : kcmxs) { + if (!"41".equals(k.getFpzlDm())) { + if (map.containsKey(k.getFpzlDm())) { + int x = map.get(k.getFpzlDm()) + Integer.parseInt(k.getFpfs()); + map.put(k.getFpzlDm(), x); + } else { + map.put(k.getFpzlDm(), Integer.valueOf(k.getFpfs())); + } + } + } + log.info("{}调用库存接口返回结果为:{}", LOGGER_MSG, JsonUtils.getInstance().toJsonString(map)); + map.forEach((fpzldm, fpfs) -> { + if (StringUtils.equals(fpzldm, invoiceWarningInfo.getFpzlDm())) { + int emailNum = Integer.parseInt(invoiceWarningInfo.getYjcs()); + if (new BigDecimal(fpfs.toString()).compareTo(new BigDecimal(invoiceWarningInfo.getYjfs())) < 0) { + + log.info("开始预警 税盘号{} 发票类型{} 发票份数{} 预警份数{}", invoiceWarningInfo.getSbbh(), invoiceWarningInfo.getFpzlDm(), + fpfs, invoiceWarningInfo.getYjfs()); + String mc = CommonUtils.getFpzlDmMc(fpzldm); + String message = ""; + + message = String.format(RedisConstant.ERROR_MESSAGE_INVOICE, invoiceWarningInfo.getXhfNsrsbh(), invoiceWarningInfo.getSbbh(), fpfs, mc, invoiceWarningInfo.getYjfs()) + "\n" + message; + + log.info("向i-tax系统推送消息开始了。。。"); + if (emailNum < 1) { + itaxMsgService.sessMessageToTax("余票预警", message, "2", + invoiceWarningInfo.getUserId(), invoiceWarningInfo.getEntId()); + } + if (OrderInfoEnum.ORDER_WARNING_OPEN.getKey().equals(invoiceWarningInfo.getSfyj())) { + + log.info("邮件预警次数{}", emailNum); + if (emailNum < 1) { + emailService.sendInvoiceWarningInfoEmail(invoiceWarningInfo.getSbMc(), invoiceWarningInfo.getSfyj(), invoiceWarningInfo.getSbbh(), invoiceWarningInfo.getEMail(), fpfs.toString(), mc); + emailNum = 1; + } + } + + } else { + if (ConfigureConstant.INT_1 == emailNum) { + emailNum = ConfigureConstant.INT_0; + } + } + + invoiceWarningInfo.setYjcs(String.valueOf(emailNum)); + log.info("更新发票预警信息。。。"); + int reslut = ypWarningService.updateYpWarnInfo(invoiceWarningInfo, NsrsbhUtils.transShListByNsrsbh(invoiceWarningInfo.getXhfNsrsbh())); + log.info("更新发票预警信息结果 {}", reslut > 0); + + } + }); + } + } else { + log.info("ypyjTask 余票预警 调用开票系统查询税盘库存接口 结果为空"); + } + } catch (Exception e) { + log.error("{}ypyjTask 余票预警 业务处理异常 异常信息:{}", LOGGER_MSG, e); + + } + } + } else { + log.info("ypyjTask 余票预警 查询税盘号 结果为空"); + } + } catch (Exception e) { + log.error("{}定时任务执行异常:{}", LOGGER_MSG, e); + return FAIL; + } + return ReturnT.SUCCESS; + + + } + +}