longz
2026-07-29 45109a672b4946a059bac111d3a61a87e1886274
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
@@ -1,6 +1,8 @@
package com.ruoyi.chargingPile.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.account.api.model.TAppUser;
import com.ruoyi.chargingPile.api.dto.TAccountingStrategyDTO;
@@ -9,6 +11,7 @@
import com.ruoyi.chargingPile.api.query.TAccountingStrategyQuery;
import com.ruoyi.chargingPile.api.vo.TAccountingStrategyDetailVO;
import com.ruoyi.chargingPile.api.vo.TAccountingStrategyVO;
import com.ruoyi.chargingPile.service.IPartnerService;
import com.ruoyi.chargingPile.service.ISiteService;
import com.ruoyi.chargingPile.service.TAccountingStrategyDetailService;
import com.ruoyi.chargingPile.service.TAccountingStrategyService;
@@ -21,9 +24,13 @@
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.log.enums.OperatorType;
import com.ruoyi.common.security.annotation.Logical;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.integration.api.feignClient.ChengDuJianGuanClient;
import com.ruoyi.integration.api.feignClient.IntegrationClient;
import com.ruoyi.integration.api.feignClient.TCECClient;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.feignClient.SysUserClient;
import io.swagger.annotations.ApiOperation;
@@ -40,6 +47,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.ruoyi.common.core.context.SecurityContextHolder.getUserId;
@@ -62,11 +70,22 @@
    private TChargingPileService chargingPileService;
    @Autowired
    private ISiteService siteService;
    @Autowired
    @Resource
    private SysUserClient sysUserClient;
    
    @Resource
    private IPartnerService partnerService;
    @Resource
    private IntegrationClient integrationClient;
    @Resource
    private TCECClient tcecClient;
    @Resource
    private ChengDuJianGuanClient chengDuJianGuanClient;
    @Autowired
    private TokenService tokenService;
    @Autowired
@@ -78,19 +97,27 @@
    /**
     * 查询计费策略列表
     */
    @RequiresPermissions(value = {"/site/add", "/site/update", "/site/accounting_strategy", "/chargingPile/add_charging_gun", "/chargingPile/accountingStrategy",
            "/chargingGun/update", "/accountingStrategy"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-计费策略"},value = "查询计费策略分页列表")
    @PostMapping(value = "/pageList")
    public AjaxResult<PageInfo<TAccountingStrategyVO>> pageList(@RequestBody TAccountingStrategyQuery query) {
        SysUser sysUser = sysUserClient.getSysUser(SecurityUtils.getUserId()).getData();
        if (sysUser != null && Objects.equals(sysUser.getRoleType(), 2)) {
            query.setPartnerId(sysUser.getObjectId());
        }
        return AjaxResult.ok(accountingStrategyService.pageList(query));
    }
    /**
     * 查询计费策略明细列表
     */
    @RequiresPermissions(value = {"/billingTemplateAudit/info", "/site/accounting_strategy", "/chargingGun/select_rate", "/accountingStrategy",
            "/accountingStrategy/select", "/accountingStrategy/update"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-计费策略", "管理后台-站点管理", "管理后台-充电桩信息"},value = "查询计费策略明细列表")
    @GetMapping(value = "/queryAccountingStrategyDetailByStrategyId")
    public AjaxResult<List<TAccountingStrategyDetailVO>> queryAccountingStrategyDetailByStrategyId(@RequestParam("strategyId") Integer strategyId) {
        List<TAccountingStrategyDetailVO> list = accountingStrategyDetailService.queryAccountingStrategyDetailByStrategyId(strategyId);
        List<TAccountingStrategyDetailVO> list = accountingStrategyDetailService.queryMangementAccountingStrategyDetailByStrategyId(strategyId);
        list.forEach(detail -> {
            detail.setTotalPrice(detail.getElectrovalence().add(detail.getServiceCharge()));
        });
@@ -104,8 +131,14 @@
    @PostMapping(value = "/add")
    @Log(title = "【计费策略】添加计费策略", businessType = BusinessType.INSERT)
    public AjaxResult<Integer> add(@RequestBody TAccountingStrategyDTO dto) {
        String partnerCheck = fillAndCheckPartner(dto);
        if (partnerCheck != null) {
            return AjaxResult.error(partnerCheck);
        }
        if(null != dto.getSiteId()){
            dto.setAuditStatus(3);
        }else{
            dto.setAuditStatus(1);
        }
        Boolean flag = accountingStrategyDetailService.isStrategy24Hour(dto.getAccountingStrategyDetails());
        if(flag){
@@ -119,26 +152,32 @@
        Long userId = SecurityUtils.getLoginUser().getUserid();
        dto.setUserId(userId);
        accountingStrategyService.save(dto);
        // 添加明细
        dto.getAccountingStrategyDetails().forEach(detail -> detail.setAccountingStrategyId(dto.getId()));
        accountingStrategyDetailService.saveBatch(dto.getAccountingStrategyDetails());
        if(null != dto.getSiteId()){
            //下发硬件数据
            List<TChargingPile> list = chargingPileService.lambdaQuery().eq(TChargingPile::getSiteId, dto.getSiteId()).eq(TChargingPile::getDelFlag, 0).list();
            for (TChargingPile tChargingPile : list) {
                integrationClient.setupBillingModel1(tChargingPile.getCode());
                integrationClient.setupBillingModel1(tChargingPile.getCode(), JSON.toJSONString(dto.getAccountingStrategyDetails()));
                chengDuJianGuanClient.notificationStationFee(tChargingPile.getId());
            }
        }
        // 添加明细
        dto.getAccountingStrategyDetails().forEach(detail -> detail.setAccountingStrategyId(dto.getId()));
        accountingStrategyDetailService.saveBatch(dto.getAccountingStrategyDetails());
        return AjaxResult.ok(dto.getId());
    }
    /**
     * 修改计费策略
     */
    @RequiresPermissions(value = {"/accountingStrategy/update"}, logical = Logical.OR)
    @Log(title = "【计费策略】修改计费策略", businessType = BusinessType.UPDATE,operatorType = OperatorType.MANAGE)
    @ApiOperation(tags = {"后台-计费策略", "管理后台-站点管理"},value = "修改计费策略")
    @PostMapping(value = "/update")
    public AjaxResult<String> update(@RequestBody TAccountingStrategyDTO dto) {
        String partnerCheck = fillAndCheckPartner(dto);
        if (partnerCheck != null) {
            return AjaxResult.error(partnerCheck);
        }
        Boolean flag = accountingStrategyDetailService.isStrategy24Hour(dto.getAccountingStrategyDetails());
        if(flag){
            return AjaxResult.error("计费模板时间设置有误差");
@@ -148,63 +187,107 @@
        if(!flag1){
            return AjaxResult.error("同阶段费率值需一致");
        }
        TAccountingStrategy original = accountingStrategyService.getById(dto.getId());
        if (Objects.isNull(original)) {
            return AjaxResult.error("计费策略不存在");
        }
        if(Objects.isNull(dto.getDiscount())){
            accountingStrategyService.update(Wrappers.<TAccountingStrategy>lambdaUpdate().set(TAccountingStrategy::getDiscount, null).eq(TAccountingStrategy::getId, dto.getId()));
        }
        // 判断修改的计费策略是否为已通过
        // 历史审核通过的策略在替换旧策略后可能仍保留已删除策略的 parentId。
        // 这类正式策略再次编辑会被改为待审核子记录,并被计费策略列表过滤掉,先将其恢复为主策略。
        if (original.getParentId() != null && Objects.equals(original.getAuditStatus(), 3)
                && Objects.isNull(accountingStrategyService.getById(original.getParentId()))) {
            accountingStrategyService.update(Wrappers.<TAccountingStrategy>lambdaUpdate()
                    .set(TAccountingStrategy::getParentId, null)
                    .eq(TAccountingStrategy::getId, original.getId()));
            original.setParentId(null);
            dto.setParentId(null);
        }
        if (original.getParentId() != null) {
            dto.setParentId(original.getParentId());
            dto.setSiteId(original.getSiteId());
            dto.setUserId(SecurityUtils.getLoginUser().getUserid());
            dto.setAuditStatus(1);
            dto.setFirstRemark(null);
            dto.setTwoRemark(null);
            dto.setFirstAuditTime(null);
            dto.setTwoAuditTime(null);
            if (Objects.equals(original.getAuditStatus(), 4)) {
                dto.setId(null);
                accountingStrategyService.save(dto);
                saveStrategyDetails(dto.getId(), dto.getAccountingStrategyDetails());
            } else {
                dto.setId(original.getId());
                accountingStrategyService.updateById(dto);
                replaceStrategyDetails(dto.getId(), dto.getAccountingStrategyDetails());
            }
            return AjaxResult.success();
        }
        // 判断修改的计费策略是否为已通过或已驳回
        if(null != dto.getAuditStatus() && (dto.getAuditStatus() == 3 || dto.getAuditStatus() == 4)){
            // 查询是否有下级审核中的策略
            TAccountingStrategy children = accountingStrategyService.getOne(Wrappers.lambdaQuery(TAccountingStrategy.class)
                    .eq(TAccountingStrategy::getParentId, dto.getId())
                    .ne(TAccountingStrategy::getAuditStatus, Arrays.asList(3,4)));
                    .in(TAccountingStrategy::getAuditStatus, Arrays.asList(1,2,4))
                    .orderByDesc(TAccountingStrategy::getCreateTime)
                    .last("LIMIT 1"));
            if(Objects.nonNull(children)){
                // 删除计费策略明细信息
                accountingStrategyDetailService.remove(Wrappers.lambdaQuery(TAccountingStrategyDetail.class)
                        .eq(TAccountingStrategyDetail::getAccountingStrategyId, children.getId()));
                dto.setId(children.getId());
                dto.setParentId(children.getParentId());
                dto.setSiteId(children.getSiteId());
                dto.setUserId(SecurityUtils.getLoginUser().getUserid());
                dto.setAuditStatus(1);
                dto.setFirstRemark(null);
                dto.setTwoRemark(null);
                dto.setFirstAuditTime(null);
                dto.setTwoAuditTime(null);
                accountingStrategyService.updateById(dto);
                // 添加明细
                dto.getAccountingStrategyDetails().forEach(detail -> detail.setAccountingStrategyId(dto.getId()));
                accountingStrategyDetailService.saveBatch(dto.getAccountingStrategyDetails());
                replaceStrategyDetails(children.getId(), dto.getAccountingStrategyDetails());
            }else {
                Long userId = SecurityUtils.getLoginUser().getUserid();
                Integer parentId = dto.getId();
                dto.setUserId(userId);
                dto.setAuditStatus(1);
                dto.setParentId(dto.getId());
                dto.setParentId(parentId);
                dto.setId(null);
                accountingStrategyService.save(dto);
                // 添加明细
                List<TAccountingStrategyDetail> accountingStrategyDetails = dto.getAccountingStrategyDetails();
                accountingStrategyDetails.forEach(detail -> {
                    detail.setAccountingStrategyId(dto.getId());
                    detail.setId(null);
                });
                accountingStrategyDetailService.saveBatch(accountingStrategyDetails);
                saveStrategyDetails(dto.getId(), dto.getAccountingStrategyDetails());
            }
        }else {
            // 删除计费策略明细信息
            accountingStrategyDetailService.remove(Wrappers.lambdaQuery(TAccountingStrategyDetail.class)
                    .eq(TAccountingStrategyDetail::getAccountingStrategyId, dto.getId()));
            dto.setAuditStatus(1);
            accountingStrategyService.updateById(dto);
            // 添加明细
            dto.getAccountingStrategyDetails().forEach(detail -> detail.setAccountingStrategyId(dto.getId()));
            accountingStrategyDetailService.saveBatch(dto.getAccountingStrategyDetails());
            replaceStrategyDetails(dto.getId(), dto.getAccountingStrategyDetails());
        }
        if(null != dto.getSiteId()){
            //下发硬件数据
            List<TChargingPile> list = chargingPileService.lambdaQuery().eq(TChargingPile::getSiteId, dto.getSiteId()).eq(TChargingPile::getDelFlag, 0).list();
            for (TChargingPile tChargingPile : list) {
                integrationClient.setupBillingModel1(tChargingPile.getCode());
                integrationClient.setupBillingModel1(tChargingPile.getCode(), JSON.toJSONString(dto.getAccountingStrategyDetails()));
                chengDuJianGuanClient.notificationStationFee(tChargingPile.getId());
            }
        }
        return AjaxResult.success();
    }
    private void replaceStrategyDetails(Integer strategyId, List<TAccountingStrategyDetail> details) {
        accountingStrategyDetailService.remove(Wrappers.lambdaQuery(TAccountingStrategyDetail.class)
                .eq(TAccountingStrategyDetail::getAccountingStrategyId, strategyId));
        saveStrategyDetails(strategyId, details);
    }
    private void saveStrategyDetails(Integer strategyId, List<TAccountingStrategyDetail> details) {
        details.forEach(detail -> {
            detail.setAccountingStrategyId(strategyId);
            detail.setId(null);
        });
        accountingStrategyDetailService.saveBatch(details);
    }
    /**
     * 查看计费策略详情
     */
    @RequiresPermissions(value = {"/site/accounting_strategy", "/accountingStrategy/select", "/accountingStrategy/update"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-计费策略", "管理后台-站点管理"},value = "查看计费策略详情")
    @GetMapping(value = "/getDetailById")
    public AjaxResult<TAccountingStrategyVO> getDetailById(@RequestParam("id") Integer id) {
@@ -220,6 +303,7 @@
            String twoUserName = sysUserClient.getSysUser(accountingStrategy.getTwoUserId()).getData().getNickName();
            accountingStrategyVO.setTwoUserName(twoUserName);
        }
        fillPartnerName(accountingStrategyVO);
        return AjaxResult.ok(accountingStrategyVO);
    }
@@ -251,7 +335,7 @@
                accountingStrategyVO.setUserName(userName);
            }
            accountingStrategyVO.setAccountingStrategyDetailList(accountingStrategyDetailService.list(Wrappers.lambdaQuery(TAccountingStrategyDetail.class)
                    .eq(TAccountingStrategyDetail::getAccountingStrategyId, children.getId())));
                    .eq(TAccountingStrategyDetail::getAccountingStrategyId, children.getId()).eq(TAccountingStrategyDetail::getDelFlag, 0)));
        }else {
            TAccountingStrategy accountingStrategy = accountingStrategyService.getById(id);
            BeanUtils.copyProperties(accountingStrategy,accountingStrategyVO);
@@ -264,19 +348,46 @@
                String twoUserName = sysUserClient.getSysUser(accountingStrategy.getTwoUserId()).getData().getNickName();
                accountingStrategyVO.setTwoUserName(twoUserName);
            }
            if(null != children.getUserId()){
                String userName = sysUserClient.getSysUser(children.getUserId()).getData().getNickName();
            TAccountingStrategy accountingStrategy1 = accountingStrategyService.getById(id);
            if(null != accountingStrategy1.getUserId()){
                String userName = sysUserClient.getSysUser(accountingStrategy1.getUserId()).getData().getNickName();
                accountingStrategyVO.setUserName(userName);
            }
            accountingStrategyVO.setAccountingStrategyDetailList(accountingStrategyDetailService.list(Wrappers.lambdaQuery(TAccountingStrategyDetail.class)
                    .eq(TAccountingStrategyDetail::getAccountingStrategyId, id)));
                    .eq(TAccountingStrategyDetail::getAccountingStrategyId, id).eq(TAccountingStrategyDetail::getDelFlag, 0)));
        }
        fillPartnerName(accountingStrategyVO);
        return AjaxResult.ok(accountingStrategyVO);
    }
    private String fillAndCheckPartner(TAccountingStrategyDTO dto) {
        SysUser sysUser = sysUserClient.getSysUser(SecurityUtils.getUserId()).getData();
        if (sysUser != null && Objects.equals(sysUser.getRoleType(), 2)) {
            Integer objectId = sysUser.getObjectId();
            if (dto.getPartnerId() != null && !Objects.equals(dto.getPartnerId(), objectId)) {
                return "合作商账号只能选择自己的合作商";
            }
            dto.setPartnerId(objectId);
        }
        if (dto.getSiteId() == null && dto.getPartnerId() == null) {
            return "归属合作商不能为空";
        }
        return null;
    }
    private void fillPartnerName(TAccountingStrategyVO vo) {
        if (vo.getPartnerId() != null) {
            Partner partner = partnerService.getById(vo.getPartnerId());
            if (partner != null) {
                vo.setPartnerName(partner.getName());
            }
        }
    }
    /**
     * 删除计费策略
     */
    @RequiresPermissions(value = {"/accountingStrategy/del"}, logical = Logical.OR)
    @Log(title = "【计费策略】删除计费策略", businessType = BusinessType.DELETE,operatorType = OperatorType.MANAGE)
    @ApiOperation(tags = {"后台-计费策略"},value = "删除计费策略")
    @DeleteMapping(value = "/deleteById")
@@ -296,6 +407,7 @@
    /**
     * 批量删除计费策略
     */
    @RequiresPermissions(value = {"/accountingStrategy/del"}, logical = Logical.OR)
    @Log(title = "【计费策略】批量删除计费策略", businessType = BusinessType.DELETE,operatorType = OperatorType.MANAGE)
    @ApiOperation(tags = {"后台-计费策略"},value = "批量删除计费策略")
    @DeleteMapping(value = "/deleteByIds")
@@ -320,27 +432,32 @@
        List<TAccountingStrategyVO> list = accountingStrategyService.getPlatformAccountingStrategy();
        return AjaxResult.success(list);
    }
    @RequiresPermissions(value = {"/billingTemplateAudit"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-申请表单-计费模板审核"},value = "查询计费审核分页列表")
    @PostMapping(value = "/auth/pageList")
    public AjaxResult<PageInfo<TAccountingStrategyVO>> authPageList(@RequestBody TAccountingStrategyQuery query) {
        SysUser sysUser = sysUserClient.getSysUser(SecurityUtils.getUserId()).getData();
        if (sysUser != null && Objects.equals(sysUser.getRoleType(), 2)) {
            query.setPartnerId(sysUser.getObjectId());
        }
        return AjaxResult.ok(accountingStrategyService.pageList1(query));
    }
    
    @RequiresPermissions(value = {"/billingTemplateAudit/audit", "/billingTemplateAudit"}, logical = Logical.OR)
    @ApiOperation(tags = {"后台-申请表单-计费模板审核"},value = "审核")
    @PostMapping(value = "/auth/pass")
    @Log(title = "【计费模板审核】审核计费模板", businessType = BusinessType.OTHER,operatorType = OperatorType.MANAGE)
    public AjaxResult<PageInfo<TAccountingStrategyVO>> authPass(@RequestBody SteategyPassDto steategyPassDto) {
        TAccountingStrategy byId = accountingStrategyService.getById(steategyPassDto.getId());
        Long userId = SecurityUtils.getLoginUser().getUserid();
        if (byId.getAuditStatus()==1&&byId.getFirstUserId()!=userId){
        if (byId.getAuditStatus()==1 && !Objects.equals(byId.getFirstUserId(), userId)){
            return AjaxResult.error("您不是一级审核人员,无法审核");
        }
        if (byId.getAuditStatus()==2&&byId.getTwoUserId()!=userId){
        if (byId.getAuditStatus()==2 && !Objects.equals(byId.getTwoUserId(), userId)){
            return AjaxResult.error("您不是二级审核人员,无法审核");
        }
        if (steategyPassDto.getPass()==1){
@@ -357,17 +474,34 @@
                //如果parentId不为空,则将parentId对应的siteId改为现在的,并且将parenId对应的数据删除
                if (byId.getParentId()!=null) {
                    TAccountingStrategy one = accountingStrategyService.lambdaQuery().eq(TAccountingStrategy::getId, byId.getParentId()).one();
                    byId.setSiteId(one.getSiteId());
                    //将site表对应的模板id修改为新的这个
                    Site byId1 = siteService.getById(one.getSiteId());
                    byId1.setAccountingStrategyId(byId.getId());
                    siteService.updateById(byId1);
                    TAccountingStrategy one = accountingStrategyService.getById(byId.getParentId());
                    if (Objects.nonNull(one)) {
                        byId.setSiteId(one.getSiteId());
                        //将site表对应的模板id修改为新的这个
                        List<Site> list = siteService.lambdaQuery().eq(Site::getAccountingStrategyId, one.getId()).list();
                        if(!list.isEmpty()){
                            for (Site site : list) {
                                site.setAccountingStrategyId(byId.getId());
                            }
                            siteService.updateBatchById(list);
                            //推送三方平台
                            List<Integer> siteIds = list.stream().filter(s->1 == s.getIsOpenSynchronization()).map(Site::getId).collect(Collectors.toList());
                            if(!siteIds.isEmpty()){
                                tcecClient.notificationStationChange(siteIds);
                            }
                        }
                        accountingStrategyService.removeById(one.getId());
                    }
                    // 审核通过后当前记录已成为正式策略,不能继续保留旧策略的 parentId。
                    byId.setParentId(null);
                }
                //硬件
                List<TAccountingStrategyDetail> accountingStrategyDetails = accountingStrategyDetailService.list(new LambdaQueryWrapper<TAccountingStrategyDetail>()
                        .eq(TAccountingStrategyDetail::getAccountingStrategyId, byId.getId()).eq(TAccountingStrategyDetail::getDelFlag, 0));
                List<TChargingPile> list = chargingPileService.lambdaQuery().eq(TChargingPile::getSiteId, byId.getSiteId()).list();
                for (TChargingPile tChargingPile : list) {
                    integrationClient.setupBillingModel1(tChargingPile.getCode());
                    integrationClient.setupBillingModel1(tChargingPile.getCode(), JSON.toJSONString(accountingStrategyDetails));
                    chengDuJianGuanClient.notificationStationFee(tChargingPile.getId());
                }
            }
        }else {
@@ -421,7 +555,7 @@
        // 会员折扣
        BigDecimal discount = one1.getDiscount();
        List<TAccountingStrategyDetail> list = accountingStrategyDetailService.lambdaQuery().eq(TAccountingStrategyDetail::getAccountingStrategyId, one1.getId())
                .list();
                        .eq(TAccountingStrategyDetail::getDelFlag, 0).list();
        // 当前时间属于哪个计费策略
        LocalTime now = LocalTime.now();
        // 电价
@@ -441,25 +575,20 @@
                electronic = tAccountingStrategyDetail.getElectrovalence();
                // 非会员下的服务费
                BigDecimal multiply = beforeMoney.multiply(tAccountingStrategyDetail.getServiceCharge()).divide(electronic, 2, RoundingMode.HALF_UP);
                if (byId.getBusinessCategory() == 1){
                    // 直营才享受会员折扣
                    // 根据电价和预付金额 是否有会员折扣 计算最终服务费
                    if (split[1].equals("1")){
                        // 抵扣金额
                        BigDecimal multiply1 = multiply.multiply(discount);
                        if (multiply1.compareTo(discountMoney)>0){
                            multiply1 = discountMoney;
                        }
                        // 普通最终服务费
                        res = multiply.subtract(multiply1);
                res = multiply;
                // 根据电价和预付金额 是否有会员折扣 计算最终服务费
                if (split[1].equals("1")){
                    // 抵扣金额
                    BigDecimal multiply1 = multiply.multiply(discount);
                    if (multiply1.compareTo(discountMoney)>0){
                        multiply1 = discountMoney;
                    }
                    if (split[1].equals("2")){
                        // 内部会员折扣 最终服务费
                        res = discountInner.multiply(multiply);
                    }
                }else{
                    // 非直营
                    res = multiply;
                    // 普通最终服务费
                    res = multiply.subtract(multiply1);
                }
                if (split[1].equals("2")){
                    // 内部会员折扣 最终服务费
                    res = discountInner.multiply(multiply);
                }
                break;
            }