| @@ -25,7 +25,6 @@ CREATE TABLE `wx_energy_meter_user` ( | |||
| `meter_id` bigint(20) NOT NULL COMMENT '表ID', | |||
| PRIMARY KEY (`id`), | |||
| UNIQUE KEY `id_UNIQUE` (`id`), | |||
| UNIQUE KEY `T_U_T` (`tenant_id`,`user_id`,`user_type`) | |||
| ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='能耗表'; | |||
| CREATE TABLE `wx_energy_meter_reading` ( | |||
| @@ -2,6 +2,7 @@ package com.iformall.domain.po; | |||
| import com.baomidou.mybatisplus.annotation.TableField; | |||
| import com.baomidou.mybatisplus.annotation.TableName; | |||
| import com.iformall.common.IdWorker; | |||
| import com.iformall.domain.po.base.TenantEntity; | |||
| import com.iformall.enums.EnumBillDailyBuildWay; | |||
| import com.iformall.enums.EnumBillRentApplyStatus; | |||
| @@ -166,6 +167,8 @@ public class WxEnergyMeterReading extends TenantEntity { | |||
| private WxBillDaily generateBill(WxEnergyReadingCalcute calcute,WxMerchant merchant,MallUserInfo user,String needPay,String detail,String remark) { | |||
| WxBillDaily daily = new WxBillDaily(); | |||
| final IdWorker idWorker = IdWorker.get(); | |||
| daily.setId(idWorker.nextId()); | |||
| daily.updateTenantInfo(this); | |||
| daily.setMerchantId(merchant.getId()); | |||
| daily.setRentShopType(merchant.getType()); | |||
| @@ -200,12 +203,18 @@ public class WxEnergyMeterReading extends TenantEntity { | |||
| public WxBillDaily generateUserBill(WxEnergyReadingCalcute calcute,WxMerchant merchant,MallUserInfo user,WxEnergyMeter meter) { | |||
| BigDecimal dx = new BigDecimal(this.curNumber).subtract(new BigDecimal(this.preNumber)); | |||
| String needPay = new BigDecimal(this.price).multiply(dx).divide(new BigDecimal(meter.getRate())).setScale(2,RoundingMode.HALF_UP).toPlainString(); | |||
| String detail = "单价:"+this.price+",上次读数:"+this.preNumber+",本次读数:"+this.curNumber+",读数差:"+dx.toPlainString()+",表倍率:"+meter.getRate()+",费用:"+needPay; | |||
| return generateBill(calcute,merchant, user, needPay, detail, "抄表计算自动生成"); | |||
| BigDecimal needPay = new BigDecimal(this.price).multiply(dx).divide(new BigDecimal(meter.getRate())).setScale(2,RoundingMode.HALF_UP); | |||
| if (needPay.compareTo(new BigDecimal(0)) <= 0 ) { | |||
| return null; | |||
| } | |||
| String detail = "单价:"+this.price+",上次读数:"+this.preNumber+",本次读数:"+this.curNumber+",读数差:"+dx.toPlainString()+",表倍率:"+meter.getRate()+",费用:"+needPay.toPlainString(); | |||
| return generateBill(calcute,merchant, user, needPay.toPlainString(), detail, "抄表计算自动生成"); | |||
| } | |||
| public WxBillDaily generatePublicBill(WxEnergyReadingCalcute calcute,WxMerchant merchant,MallUserInfo user,String needPay) { | |||
| if (new BigDecimal(needPay).compareTo(new BigDecimal(0)) <= 0 ) { | |||
| return null; | |||
| } | |||
| String detail = "单价:"+this.price+",费用:"+needPay; | |||
| return generateBill(calcute,merchant, user, needPay, detail, "抄表计算自动生成公摊"); | |||
| } | |||
| @@ -2,7 +2,6 @@ package com.iformall.mapper; | |||
| import com.iformall.common.CommonMapper; | |||
| import com.iformall.domain.po.WxBillDaily; | |||
| import com.iformall.domain.po.WxBillRent; | |||
| import com.iformall.domain.vo.WxBillHotNotify; | |||
| import com.iformall.domain.vo.WxBillNotify; | |||
| import com.iformall.domain.vo.WxBillSum; | |||
| @@ -36,5 +35,9 @@ public interface WxBillDailyMapper extends CommonMapper<WxBillDaily, Long> { | |||
| WxBillDaily selectById(@Param("id")Long id,@Param("tenantId")String tenantId); | |||
| void deleteById(@Param("id")Long id,@Param("tenantId")String tenantId); | |||
| void insertBills(@Param("tenantId")String tenantId, @Param("list")List<WxBillDaily> resultList); | |||
| void deleteEnergyReadingBills(@Param("energyReadingCalcuteId")Long energyReadingCalcuteId,@Param("tenantId")String tenantId); | |||
| } | |||
| @@ -4,6 +4,7 @@ import com.iformall.common.CommonMapper; | |||
| import com.iformall.domain.po.WxMallFloor; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| public interface WxMallFloorMapper extends CommonMapper<WxMallFloor, String> { | |||
| @@ -16,4 +17,8 @@ public interface WxMallFloorMapper extends CommonMapper<WxMallFloor, String> { | |||
| List<WxMallFloor> findIdAndName(String tenantId); | |||
| List<Long> getBuildindIds(WxMallFloor wxMallFloor); | |||
| String getAllPublicAreaSum(WxMallFloor record); | |||
| Map<Long, String> getBuildingPublicAreaSum(WxMallFloor record); | |||
| } | |||
| @@ -85,5 +85,8 @@ public interface WxBillDailyService { | |||
| public void bad(WxBillPayDTO dto,MallUserInfo user); | |||
| public void stopMerchantBills(WxMerchant wxMerchant,MallUserInfo userInfo); | |||
| public void completeBill(EnumBillStatus status,WxMerchant wxMerchant,MallUserInfo user); | |||
| public void insertBills(TenantEntity tenantEntity,List<WxBillDaily> list); | |||
| public void deleteEnergyReadingBills(WxBillDaily wxBillDaily); | |||
| } | |||
| @@ -50,5 +50,10 @@ public interface WxMallFloorService { | |||
| Map<Long, String> getFloorMap(TenantEntity tenantInfo); | |||
| String getAllPublicAreaSum(WxMallFloor record); | |||
| Map<Long,String> getBuildingPublicAreaSum(WxMallFloor record); | |||
| Map<Long,String> getFloorPublicAreaSum(WxMallFloor record); | |||
| } | |||
| @@ -696,4 +696,14 @@ public class WxBillDailyServiceImpl extends WxBillBaseService implements WxBillD | |||
| } | |||
| @Override | |||
| public void insertBills(TenantEntity tenantEntity, List<WxBillDaily> list) { | |||
| wxBillDailyMapper.insertBills(tenantEntity.getTenantId(), list); | |||
| } | |||
| @Override | |||
| public void deleteEnergyReadingBills(WxBillDaily wxBillDaily) { | |||
| wxBillDailyMapper.deleteEnergyReadingBills(wxBillDaily.getEnergyReadingCalcuteId(), wxBillDaily.getTenantId());; | |||
| } | |||
| } | |||
| @@ -81,6 +81,10 @@ public class WxEnergyServiceImpl implements WxEnergyService { | |||
| @Autowired | |||
| WxShopService wxShopService; | |||
| @Lazy | |||
| @Autowired | |||
| WxBillDailyService wxBillDailyService; | |||
| @Override | |||
| public PageInfo<WxEnergyMeter> meterListAsPage(WxEnergyMeter record, Integer pageIndex, Integer pageSize) { | |||
| return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxEnergyMeterMapper.findList(record)); | |||
| @@ -532,7 +536,6 @@ public class WxEnergyServiceImpl implements WxEnergyService { | |||
| List<WxEnergyMeterReading> readingList = wxEnergyMeterReadingMapper.findList(reading); | |||
| if (null != readingList && readingList.size() > 0 ) { | |||
| WxShop sq = new WxShop(); | |||
| sq.updateTenantInfo(record); | |||
| Map<Long, WxMerchant> shopMerchantMap = wxMerchantService.getShopMerchantMap(sq); | |||
| @@ -542,40 +545,64 @@ public class WxEnergyServiceImpl implements WxEnergyService { | |||
| mq.updateTenantInfo(record); | |||
| mq.setIsDel(EnumYesOrNo.NO.getCode()); | |||
| Map<Long, WxEnergyMeter> meterMap = this.getMeterMap(mq); | |||
| if (null == meterMap) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"能源表未查询到。"); | |||
| } | |||
| WxEnergyFees fq = new WxEnergyFees(); | |||
| fq.updateTenantInfo(record); | |||
| fq.setIsDel(EnumYesOrNo.NO.getCode()); | |||
| fq.setId(record.getFeesId()); | |||
| WxEnergyFees fees = this.getFeesById(fq); | |||
| String publicTotalArea = "1"; | |||
| if (null == fees) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"科目未查询到。"); | |||
| } | |||
| String publicTotalArea = "0"; | |||
| String publicTotalMoney = "0"; | |||
| Map<Long,String> buildingMoney = null; | |||
| Map<Long,String> buildingFloorMoney = null; | |||
| Map<Long,String> buildingFloorArea = null; | |||
| if (fees.getPublicCalcute().intValue() == EnumEnergyPublicCalcuteRule.ALL.getCode().intValue()) { | |||
| //全部就查询所有公共表的费用 | |||
| reading.setIsPublic(EnumYesOrNo.YES.getCode()); | |||
| publicTotalMoney = wxEnergyMeterReadingMapper.findAllSumMoney(reading); | |||
| //公摊总面积 | |||
| WxEnergyMeterUser mu = new WxEnergyMeterUser(); | |||
| mu.updateTenantInfo(record); | |||
| List<WxEnergyMeterUser> mulist = wxEnergyMeterUserMapper.findList(mu); | |||
| if (null == mulist || mulist.size() <= 0 ) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"公摊总面积未配置。"); | |||
| } | |||
| publicTotalArea = mulist.get(0).getPublicArea(); | |||
| WxMallFloor mf = new WxMallFloor(); | |||
| mf.updateTenantInfo(record); | |||
| publicTotalArea = wxMallFloorService.getAllPublicAreaSum(mf); | |||
| if (StringUtils.isBlank(publicTotalArea)) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"公摊总面积未配置。"); | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼层可用面积未配置。"); | |||
| } | |||
| BigDecimal areaDecimal = new BigDecimal(publicTotalArea); | |||
| if (areaDecimal.compareTo(new BigDecimal(0)) <= 0 ) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼层可用面积未配置。"); | |||
| } | |||
| }else if (fees.getPublicCalcute().intValue() == EnumEnergyPublicCalcuteRule.BUILDING.getCode().intValue()) { | |||
| //如果是按楼栋计算,则要把每个楼栋的金额都要算出来 | |||
| buildingMoney = wxEnergyMeterReadingMapper.findBuildingSumMoney(reading); | |||
| reading.setIsPublic(EnumYesOrNo.YES.getCode()); | |||
| buildingFloorMoney = wxEnergyMeterReadingMapper.findBuildingSumMoney(reading); | |||
| //各楼座总面积 | |||
| WxMallFloor mf = new WxMallFloor(); | |||
| mf.updateTenantInfo(record); | |||
| buildingFloorArea = wxMallFloorService.getBuildingPublicAreaSum(mf); | |||
| if (null == buildingFloorArea) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼层可用面积未配置。"); | |||
| } | |||
| }else if (fees.getPublicCalcute().intValue() == EnumEnergyPublicCalcuteRule.FLOOR.getCode().intValue()) { | |||
| //查询各楼层的费用 | |||
| reading.setIsPublic(EnumYesOrNo.YES.getCode()); | |||
| buildingFloorMoney = wxEnergyMeterReadingMapper.findFloorSumMoney(reading); | |||
| //各楼层面积 | |||
| //各楼座总面积 | |||
| WxMallFloor mf = new WxMallFloor(); | |||
| mf.updateTenantInfo(record); | |||
| buildingFloorArea = wxMallFloorService.getFloorPublicAreaSum(mf); | |||
| if (null == buildingFloorArea) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼层可用面积未配置。"); | |||
| } | |||
| } | |||
| boolean allSuccess = true; | |||
| List<WxBillDaily> billList = new ArrayList<WxBillDaily>(); | |||
| for (int i = 0 ; i< readingList.size() ; i ++) { | |||
| WxEnergyMeterReading mr = readingList.get(i); | |||
| try { | |||
| @@ -584,39 +611,79 @@ public class WxEnergyServiceImpl implements WxEnergyService { | |||
| WxEnergyMeter meter = meterMap.get(mr.getMeterId()); | |||
| WxShop shop = shopMap.get(mr.getShopId()); | |||
| WxBillDaily userBill = mr.generateUserBill(record, merchant, user, meter); | |||
| if (null != userBill) { | |||
| billList.add(userBill); | |||
| } | |||
| /* | |||
| * 总表(分摊账单) | |||
| * 如果科目是根据总面积公摊,则根据总面积计算 | |||
| * 如果科目是根据楼栋公摊,则根据当前记录的楼栋面积计算 | |||
| * 如果科目是根据楼层公摊,则根据当前记录的楼层面积计算 | |||
| */ | |||
| WxBillDaily publicBill = null; | |||
| if (fees.getPublicCalcute().intValue() == EnumEnergyPublicCalcuteRule.ALL.getCode().intValue()) { | |||
| String needPay = new BigDecimal(publicTotalMoney).multiply(new BigDecimal(shop.getRentArea())).divide(new BigDecimal(publicTotalArea)).setScale(2,RoundingMode.HALF_UP).toPlainString(); | |||
| mr.generatePublicBill(record, merchant, user, needPay); | |||
| publicBill = mr.generatePublicBill(record, merchant, user, needPay); | |||
| }else if (fees.getPublicCalcute().intValue() == EnumEnergyPublicCalcuteRule.BUILDING.getCode().intValue()) { | |||
| String buildingArea = buildingFloorArea.get(mr.getBuildingId()); | |||
| if (StringUtils.isBlank(buildingArea) || new BigDecimal(buildingArea).compareTo(new BigDecimal(0)) <= 0 ) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼层可用面积未配置完全。"); | |||
| } | |||
| String buildingMoney = buildingFloorMoney.get(mr.getBuildingId()); | |||
| if (StringUtils.isBlank(buildingMoney) || new BigDecimal(buildingMoney).compareTo(new BigDecimal(0)) <= 0 ) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼栋总费用未获取到。"); | |||
| } | |||
| String needPay = new BigDecimal(buildingMoney).multiply(new BigDecimal(shop.getRentArea())).divide(new BigDecimal(buildingArea)).setScale(2,RoundingMode.HALF_UP).toPlainString(); | |||
| publicBill = mr.generatePublicBill(record, merchant, user, needPay); | |||
| }else if (fees.getPublicCalcute().intValue() == EnumEnergyPublicCalcuteRule.FLOOR.getCode().intValue()) { | |||
| String floorArea = buildingFloorArea.get(mr.getFloorId()); | |||
| if (StringUtils.isBlank(floorArea) || new BigDecimal(floorArea).compareTo(new BigDecimal(0)) <= 0 ) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼层可用面积未配置完全。"); | |||
| } | |||
| String floorMoney = buildingFloorMoney.get(mr.getFloorId()); | |||
| if (StringUtils.isBlank(floorMoney) || new BigDecimal(floorMoney).compareTo(new BigDecimal(0)) <= 0 ) { | |||
| throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"楼栋总费用未获取到。"); | |||
| } | |||
| String needPay = new BigDecimal(floorMoney).multiply(new BigDecimal(shop.getRentArea())).divide(new BigDecimal(floorArea)).setScale(2,RoundingMode.HALF_UP).toPlainString(); | |||
| publicBill = mr.generatePublicBill(record, merchant, user, needPay); | |||
| } | |||
| if (null != publicBill) { | |||
| billList.add(publicBill); | |||
| } | |||
| }catch(Exception e) { | |||
| logger.error("计算失败:"+mr.getId(),e); | |||
| allSuccess = false; | |||
| } | |||
| } | |||
| if (billList.size() > 0 ) { | |||
| try { | |||
| //先把之前的未付的账单全部删除掉,已支付的账单先不处理 | |||
| WxBillDaily delDaily = new WxBillDaily(); | |||
| delDaily.updateTenantInfo(record); | |||
| delDaily.setEnergyReadingCalcuteId(record.getId()); | |||
| wxBillDailyService.deleteEnergyReadingBills(delDaily); | |||
| wxBillDailyService.insertBills(record, billList); | |||
| }catch(Exception e) { | |||
| logger.error("insert bills error.",e); | |||
| allSuccess = false; | |||
| } | |||
| WxEnergyReadingCalcute c = new WxEnergyReadingCalcute(); | |||
| c.updateTenantInfo(record); | |||
| c.setId(record.getId()); | |||
| c.setIsCalcuted(EnumYesOrNo.YES.getCode()); | |||
| c.setUpdateTime(new Date()); | |||
| c.setUpdateBy(user.getId()); | |||
| c.setUpdateByName(user.getName()); | |||
| if (allSuccess) { | |||
| c.setCalcuteSuccess(EnumYesOrNo.YES.getCode()); | |||
| }else { | |||
| c.setCalcuteSuccess(EnumYesOrNo.NO.getCode()); | |||
| } | |||
| wxEnergyReadingCalcuteMapper.updateById(c); | |||
| } | |||
| WxEnergyReadingCalcute c = new WxEnergyReadingCalcute(); | |||
| c.updateTenantInfo(record); | |||
| c.setId(record.getId()); | |||
| c.setIsCalcuted(EnumYesOrNo.YES.getCode()); | |||
| c.setUpdateTime(new Date()); | |||
| c.setUpdateBy(user.getId()); | |||
| c.setUpdateByName(user.getName()); | |||
| if (allSuccess) { | |||
| c.setCalcuteSuccess(EnumYesOrNo.YES.getCode()); | |||
| }else { | |||
| c.setCalcuteSuccess(EnumYesOrNo.NO.getCode()); | |||
| } | |||
| wxEnergyReadingCalcuteMapper.updateById(c); | |||
| } | |||
| @@ -13,7 +13,9 @@ import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import java.math.BigDecimal; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.stream.Collectors; | |||
| @@ -85,5 +87,34 @@ public class WxMallFloorServiceImpl implements WxMallFloorService { | |||
| return maps; | |||
| } | |||
| @Override | |||
| public String getAllPublicAreaSum(WxMallFloor record) { | |||
| return wxMallFloorMapper.getAllPublicAreaSum(record); | |||
| } | |||
| @Override | |||
| public Map<Long, String> getBuildingPublicAreaSum(WxMallFloor record) { | |||
| return wxMallFloorMapper.getBuildingPublicAreaSum(record); | |||
| } | |||
| @Override | |||
| public Map<Long, String> getFloorPublicAreaSum(WxMallFloor record) { | |||
| List<WxMallFloor> list = wxMallFloorMapper.findList(record); | |||
| if (null != list) { | |||
| Map<Long,String> retMap = new HashMap<Long,String>(); | |||
| for (int i = 0 ; i < list.size() ; i++) { | |||
| WxMallFloor mf = list.get(i); | |||
| BigDecimal oa = mf.getOperatingArea(); | |||
| if (null == oa) { | |||
| retMap.put(mf.getId(), "0"); | |||
| }else { | |||
| retMap.put(mf.getId(), oa.toPlainString()); | |||
| } | |||
| } | |||
| return retMap; | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| @@ -256,6 +256,24 @@ | |||
| delete from wx_bill_daily where id = #{id} and tenant_id = #{tenantId} | |||
| </delete> | |||
| <insert id="insertBills" parameterType="HashMap"> | |||
| INSERT INTO wx_bill_daily (`id`,`tenant_id`,`parent_tenant_id`,`receive_pay`,`pay`,`receive_date`,`pay_date`,`createtime`,`expired_day`,`status`,`is_del`, | |||
| `merchant_id`,`user_id`,`shop_id`,`shop_name`,`updatetime`,`type`,`rent_shop_type`,`apply_status`,`pay_way`,`price_detail`, | |||
| `starttime`,`endtime`,`freeze`,`build_way`,`service_charge_pay`,`apply_pay_img`,`apply_update_time`,`remark`,`create_by`,`update_by`, | |||
| `create_by_name`,`update_by_name`,`energy_reading_calcuteId`,`energy_reading_id`) | |||
| VALUES | |||
| <foreach collection="list" item="item" index="index" separator=","> | |||
| ( | |||
| #{item.id},#{item.tenantId},#{item.parentTenantId},#{item.receivePay},#{item.pay},#{item.receiveDate},#{item.payDate},#{item.createtime},#{item.expiredDay},#{item.status},#{item.isDel}, | |||
| #{item.merchantId},#{item.userId},#{item.shopId},#{item.shopName},#{item.updatetime},#{item.type},#{item.rentShopType},#{item.applyStatus},#{item.payWay},#{item.priceDetail}, | |||
| #{item.starttime},#{item.endtime},#{item.freeze},#{item.buildWay},#{item.serviceChargePay},#{item.applyPayImg},#{item.applyUpdateTime},#{item.remark},#{item.createBy},#{item.updateBy}, | |||
| #{item.createByName},#{item.updateByName},#{item.energyReadingCalcuteId},#{item.energyReadingId} | |||
| ) | |||
| </foreach> | |||
| </insert> | |||
| <delete id = "deleteEnergyReadingBills" parameterType="HashMap"> | |||
| delete from wx_bill_daily where energy_reading_calcuteId = #{energyReadingCalcuteId} and tenant_id = #{tenantId} and status = 2 and pay <= 0 | |||
| </delete> | |||
| </mapper> | |||
| @@ -101,5 +101,18 @@ | |||
| from wx_mall_floor | |||
| <include refid="dynamicWhereConditions"/> | |||
| </select> | |||
| <select id="getAllPublicAreaSum" parameterType="com.iformall.domain.po.WxMallFloor" resultType="String"> | |||
| select sum((CAST(operating_area AS DECIMAL(20,4))) area | |||
| from wx_mall_floor | |||
| <include refid="dynamicWhereConditions"/> | |||
| </select> | |||
| <select id="getBuildingPublicAreaSum" parameterType="com.iformall.domain.po.WxMallFloor" resultType="HashMap"> | |||
| select building_id, sum((CAST(operating_area AS DECIMAL(20,4))) area | |||
| from wx_mall_floor | |||
| <include refid="dynamicWhereConditions"/> | |||
| group by building_id | |||
| </select> | |||
| </mapper> | |||