gt:                                 adjusted += detail.getAdjBalanceAmount();
context: package com.abm.mainet.bill.service;
  
  import java.lang.reflect.Method;
  import java.math.BigDecimal;
  import java.time.LocalDate;
  import java.time.ZoneId;
  import java.util.ArrayList;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Locale;
  import java.util.Map;
  
  import javax.annotation.Resource;
  
  import org.apache.commons.lang.StringUtils;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.MessageSource;
  import org.springframework.core.task.TaskExecutor;
  import org.springframework.http.HttpStatus;
  import org.springframework.http.ResponseEntity;
  import org.springframework.stereotype.Service;
  import org.springframework.transaction.annotation.Transactional;
  import org.springframework.util.ClassUtils;
  import org.springframework.util.ReflectionUtils;
  
  import com.abm.mainet.bill.repository.AdjustmentBillDetailMappingRepository;
  import com.abm.mainet.cfc.challan.dao.IChallanDAO;
  import com.abm.mainet.cfc.challan.domain.AdjustmentBillDetailMappingEntity;
  import com.abm.mainet.cfc.challan.domain.AdjustmentMasterEntity;
  import com.abm.mainet.cfc.challan.service.IChallanService;
  import com.abm.mainet.common.audit.service.AuditService;
  import com.abm.mainet.common.constant.MainetConstants;
  import com.abm.mainet.common.constant.PrefixConstants;
  import com.abm.mainet.common.constant.ServiceEndpoints;
  import com.abm.mainet.common.domain.Department;
  import com.abm.mainet.common.domain.Organisation;
  import com.abm.mainet.common.domain.TbTaxMasEntity;
  import com.abm.mainet.common.exception.FrameworkException;
  import com.abm.mainet.common.integration.acccount.dto.VoucherPostDTO;
  import com.abm.mainet.common.integration.acccount.dto.VoucherPostDetailDTO;
  import com.abm.mainet.common.integration.dto.BillTaxDTO;
  import com.abm.mainet.common.integration.dto.TbBillDet;
  import com.abm.mainet.common.integration.dto.TbBillMas;
  import com.abm.mainet.common.master.dto.TbLocationMas;
  import com.abm.mainet.common.master.dto.TbTaxMas;
  import com.abm.mainet.common.master.service.DepartmentService;
  import com.abm.mainet.common.master.service.TbTaxMasService;
  import com.abm.mainet.common.service.ILocationMasService;
  import com.abm.mainet.common.utility.ApplicationContextProvider;
  import com.abm.mainet.common.utility.ApplicationSession;
  import com.abm.mainet.common.utility.CommonMasterUtility;
  import com.abm.mainet.common.utility.LookUp;
  import com.abm.mainet.common.utility.RestClient;
  import com.abm.mainet.common.utility.Utility;
  import com.abm.mainet.common.utility.UtilityService;
  import com.google.common.util.concurrent.AtomicDouble;
  
  @Service
  public class BillMasterCommonServiceImpl implements BillMasterCommonService {
  
      private static final Logger LOGGER = LoggerFactory.getLogger(BillMasterCommonServiceImpl.class);
  
      @Resource
      private IChallanDAO iChallanDAO;
  
      @Autowired
      private TbTaxMasService tbTaxMasService;
  
      @Autowired
      private DepartmentService departmentService;
  
      @Resource
      private AuditService auditService;
  
      @Autowired
      private MessageSource messageSource;
  
      @Resource
      private IChallanService iChallanService;
  
      @Resource
      private ILocationMasService iLocationMasService;
  
      @Autowired
      private TaskExecutor taskExecutor;
  
      @Autowired
      private AdjustmentEntryService adjustmentEntryService;
  
      @Resource
      private AdjustmentBillDetailMappingRepository adjustmentBillDetailMappingRepository;
  
      private final String constantNO = MainetConstants.Common_Constant.NO;
      private final String constantYES = MainetConstants.Common_Constant.YES;
  
      /*
       * (non-Javadoc)
       * @see com.abm.mainetservice.water.service.TbWtBillMasService# calculateInterestAndArrears(java.util.LinkedList)
       */
      @Override
      public void calculateInterestAndArrears(final List<TbBillMas> listBill) {
          final Organisation org = new Organisation();
          org.setOrgid(listBill.get(0).getOrgid());
  
          TbBillMas lastBillMas = null;
          List<TbBillMas> previousBillMass = null;
          for (final TbBillMas currBillMas : listBill) {
              if (previousBillMass == null) {
                  previousBillMass = new ArrayList<>();
              }
              previousBillMass.add(currBillMas);
              double amount = 0d;
              if ((previousBillMass != null) && !previousBillMass.isEmpty()) {
                  for (final TbBillMas prevBillMas : previousBillMass) {
                      if (UtilityService.compareDateField(prevBillMas.getBmDuedate(),
                              currBillMas.getBmBilldt())) {
                          amount += prevBillMas.getBmTotalBalAmount();
                          currBillMas.setBmTotalArrearsWithoutInt(amount);
                      }
                  }
              }
              if ((currBillMas.getBmTotalArrearsWithoutInt() == 0d) || (lastBillMas == null)) {
                  currBillMas.setBmToatlInt(0d);
              } else {
  
                  final Calendar startCalendar = Calendar.getInstance();
                  startCalendar.setTime(currBillMas.getBmBilldt());
  
                  final Calendar startCalendar1 = Calendar.getInstance();
                  startCalendar1.setTime(lastBillMas.getBmBilldt());
  
                  final Calendar endCalendar = Calendar.getInstance();
                  endCalendar.setTime(lastBillMas.getBmDuedate());
  
                  final int diffYear = startCalendar.get(Calendar.YEAR)
                          - endCalendar.get(Calendar.YEAR);
                  final int diffMonth = ((diffYear * 12)
                          + startCalendar.get(Calendar.MONTH))
                          - endCalendar.get(Calendar.MONTH);
  
                  final int diffYear1 = endCalendar.get(Calendar.YEAR)
                          - startCalendar1.get(Calendar.YEAR);
                  final int diffMonth1 = ((diffYear1 * 12)
                          + endCalendar.get(Calendar.MONTH))
                          - startCalendar1.get(Calendar.MONTH);
                  currBillMas.setBmToatlInt(Math.round((currBillMas.getBmTotalArrearsWithoutInt()
                          * diffMonth * currBillMas.getBmIntValue())
                          + (lastBillMas
                                  .getBmTotalArrearsWithoutInt()
                                  * diffMonth1 * lastBillMas
                                          .getBmIntValue())));
                  if (!isLastDayOfMonth(lastBillMas.getBmDuedate())) {
                      currBillMas.setBmToatlInt((lastBillMas.getBmTotalBalAmount() * lastBillMas.getBmIntValue()) +
                              currBillMas.getBmToatlInt());
                  }
              }
              if (lastBillMas != null) {
                  currBillMas.setBmTotalCumIntArrears(
                          lastBillMas.getBmTotalCumIntArrears()
                                  + currBillMas.getBmToatlInt());
              } else {
                  currBillMas.setBmTotalCumIntArrears(
                          currBillMas.getBmToatlInt());
              }
  
              currBillMas.setBmTotalArrears(Math.round(
                      currBillMas.getBmTotalCumIntArrears()
                              + currBillMas.getBmTotalArrearsWithoutInt()));
              if (constantYES.equals(currBillMas.getBmPaidFlag())) {
                  if (UtilityService.compareDateField(lastBillMas.getBmDuedate(),
                          currBillMas.getBmBilldt())) {
                      currBillMas.setBmTotalOutstanding(
                              currBillMas.getBmTotalArrears());
                  } else {
                      currBillMas.setBmTotalOutstanding(
                              currBillMas.getBmTotalArrears()
                                      + lastBillMas.getBmTotalBalAmount());
                  }
              } else {
                  currBillMas.setBmTotalOutstanding(
                          currBillMas.getBmTotalArrears()
                                  + currBillMas.getBmTotalBalAmount());
              }
              if ((currBillMas.getTbWtBillDet() != null) && !currBillMas.getTbWtBillDet().isEmpty() && (lastBillMas != null)) {
                  for (final TbBillDet det : currBillMas.getTbWtBillDet()) {
                      for (final TbBillDet lastDet : lastBillMas.getTbWtBillDet()) {
                          if (det.getTaxId().equals(lastDet.getTaxId())) {
                              final String taxCode = CommonMasterUtility.getHierarchicalLookUp(det.getTaxCategory(), org)
                                      .getLookUpCode();
                              if (!taxCode.equals(PrefixConstants.TAX_CATEGORY.ADVANCE)
                                      && !taxCode.equals(PrefixConstants.TAX_CATEGORY.REBATE)) {
                                  det.setBdPrvBalArramt(lastDet.getBdCurBalTaxamt() + lastDet.getBdPrvBalArramt());
                              }
                          }
                      }
                  }
              }
              lastBillMas = currBillMas;
          }
      }
  
      private boolean isLastDayOfMonth(final Date bmDuedate) {
          final Calendar calendar = Calendar.getInstance();
          calendar.setTime(bmDuedate);
          final boolean isLastDay = calendar.get(Calendar.DATE) == calendar.getActualMaximum(Calendar.DATE);
          return isLastDay;
      }
  
      /*
       * (non-Javadoc)
       * @see com.abm.mainetservice.water.service.TbWtBillMasService#processBillNewData (java.util.LinkedList)
       */
      @Override
      public void processBillNewData(final List<TbBillMas> billMasData,
              final String ccnNumber) {
  
          final ApplicationSession appSession = ApplicationSession.getInstance();
          if ((billMasData != null) && !billMasData.isEmpty()) {
              final TbBillMas billMasLast = billMasData.get(billMasData.size() - 1);
              final TbBillMas billMas = new TbBillMas();
  
              billMas.setBmNo(billMasLast.getBmNo());
              billMas.setCsIdn(billMasLast.getCsIdn());
              billMas.setBmYear((long) Utility.getCurrentYear());
  
              billMas.setBmRemarks(appSession.getMessage("bill.lbl.payment"));
              billMas.setBmFromdt(billMasLast.getBmFromdt());
              billMas.setBmTodt(billMasLast.getBmTodt());
              final LocalDate date = LocalDate.now();
              final Date duedate = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
              billMas.setBmDuedate(duedate);
              billMas.setBmBilldt(duedate);
              billMas.setBmTotalAmount(0d);
              billMas.setBmTotalBalAmount(0d);
              billMas.setBmIntValue(billMasLast.getBmIntValue());
              billMas.setBmPaidFlag(constantYES);
              billMas.setUserId(billMasLast.getUserId());
              billMas.setOrgid(billMasLast.getOrgid());
              billMas.setLmoddate(new Date());
              billMas.setLangId(billMasLast.getLangId());
              billMas.setLgIpMac(billMasLast.getLgIpMac());
  
              billMasData.add(billMas);
  
              calculateInterestAndArrears(billMasData);
  
          }
  
      }
  
      /*
       * (non-Javadoc)
       * @see com.abm.mainetservice.water.service.TbWtBillMasService#updateBillData (java.util.LinkedList, double)
       */
      @Override
      public Map<Long, Double> updateBillData(final List<TbBillMas> listBill,
              Double paidAmount, Map<Long, Double> details, Map<Long, Long> billDetails, final Organisation org) {
          final int size = listBill.size();
          final LocalDate date = LocalDate.now();
          final Date duedate = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
          if (details == null) {
              details = new HashMap<>(0);
          }
          if (billDetails == null) {
              billDetails = new HashMap<>(0);
          }
  
          final double amount = paidAmount;
          double detAmount = amount;
          TbBillMas lastBillMas = null;
          List<TbBillMas> previousBillMass = null;
          List<TbBillDet> tbWtBillDet = null;
          for (final TbBillMas bill : listBill) {
              boolean rebate = false;
              if (UtilityService.compareDate(duedate, bill.getBmDuedate())) {
                  if ((bill.getBmTotalAmount() == bill.getBmTotalBalAmount()) && (bill.getBmToatlRebate() > 0d)) {
                      final double totalAmountPayable = amount + bill.getBmToatlRebate();
                      if (totalAmountPayable >= bill.getBmTotalOutstanding()) {
                          paidAmount += bill.getBmToatlRebate();
                          detAmount += bill.getBmToatlRebate();
                          rebate = true;
                      }
                  }
              }
              if (previousBillMass == null) {
                  previousBillMass = new ArrayList<>();
              }
              if ((bill.getBmToatlInt() > 0d) && (paidAmount > 0d)) {
  
                  paidAmount = paidAmount - bill.getBmToatlInt();
                  if (paidAmount < 0d) {
                      bill.setBmToatlInt(Math.abs(paidAmount));
                  } else {
                      bill.setBmToatlInt(0);
                  }
                  if (lastBillMas == null) {
                      bill.setBmTotalCumIntArrears(bill.getBmToatlInt());
                  } else {
                      bill.setBmTotalCumIntArrears(lastBillMas
                              .getBmTotalCumIntArrears() + bill.getBmToatlInt());
                  }
              }
  
              if ((bill.getBmTotalBalAmount() > 0d)
                      && (paidAmount > 0d)) {
                  paidAmount = paidAmount - bill.getBmTotalBalAmount();
                  if (paidAmount < 0d) {
                      bill.setBmTotalBalAmount(Math.abs(paidAmount));
                  } else {
                      bill.setBmTotalBalAmount(0);
                  }
  
              }
              double amountint = 0d;
              previousBillMass.add(bill);
              if ((previousBillMass != null) && !previousBillMass.isEmpty()) {
                  for (final TbBillMas tbWtBillMas : previousBillMass) {
  
                      if (UtilityService.compareDate(
                              tbWtBillMas.getBmDuedate(), bill.getBmBilldt())) {
                          amountint += tbWtBillMas.getBmTotalBalAmount();
                          bill.setBmTotalArrearsWithoutInt(amountint);
                      }
                  }
              }
              bill.setBmTotalArrears(bill.getBmTotalArrearsWithoutInt()
                      + bill.getBmTotalCumIntArrears());
              bill.setBmTotalOutstanding(bill.getBmTotalArrears()
                      + bill.getBmTotalBalAmount());
  
              if (bill.getBmTotalOutstanding() == 0d) {
                  bill.setBmPaidFlag(constantYES);
              }
              tbWtBillDet = new ArrayList<>(0);
              if ((bill.getTbWtBillDet() != null)
                      && !bill.getTbWtBillDet().isEmpty()) {
                  for (final TbBillDet det : bill.getTbWtBillDet()) {
                      final String taxCode = CommonMasterUtility.getHierarchicalLookUp(det.getTaxCategory(), org).getLookUpCode();
                      if (!taxCode.equals(PrefixConstants.TAX_CATEGORY.ADVANCE)) {
                          if (taxCode.equals(PrefixConstants.TAX_CATEGORY.REBATE) && rebate) {
                              details.put(det.getTaxId(), bill.getBmToatlRebate());
                              billDetails.put(det.getTaxId(), det.getBdBilldetid());
                              continue;
                          }
                          Double value = details.get(det.getTaxId());
                          if (detAmount > 0d) {
                              if (det.getBdCurBalTaxamt() > 0d) {
                                  detAmount = detAmount - det.getBdCurBalTaxamt();
                                  if (value != null) {
                                      if (detAmount >= 0d) {
                                          value += (det.getBdCurBalTaxamt());
                                          det.setBdCurBalTaxamt(0);
                                      } else {
                                          value += (det.getBdCurBalTaxamt() - Math.abs(detAmount));
                                          det.setBdCurBalTaxamt(Math.abs(detAmount));
                                      }
                                      details.put(det.getTaxId(), value);
                                  } else {
                                      if (detAmount >= 0d) {
                                          details.put(det.getTaxId(), det.getBdCurBalTaxamt());
                                          det.setBdCurBalTaxamt(0);
                                      } else {
                                          details.put(det.getTaxId(), (det.getBdCurBalTaxamt() - Math.abs(detAmount)));
                                          det.setBdCurBalTaxamt(Math.abs(detAmount));
                                      }
                                  }
                                  if (billDetails != null) {
                                      billDetails.put(det.getTaxId(), det.getBdBilldetid());
                                  }
                              }
                          }
                          if ((lastBillMas != null) && (lastBillMas.getTbWtBillDet() != null)) {
                              for (final TbBillDet lastdet : lastBillMas.getTbWtBillDet()) {
                                  if (det.getTaxId().equals(lastdet.getTaxId())) {
                                      det.setBdPrvBalArramt(lastdet.getBdCurBalTaxamt() + lastdet.getBdPrvBalArramt());
                                  }
                              }
                          }
                          tbWtBillDet.add(det);
                      }
                  }
              }
              bill.setTbWtBillDet(tbWtBillDet);
              lastBillMas = bill;
          }
          listBill.get(size - 1).setBmLastRcptamt(amount);
          listBill.get(size - 1).setBmLastRcptdt(new Date());
          listBill.get(size - 1).setExcessAmount(paidAmount);
          return details;
      }
  
      /**
       * @param taxMas2
       * @param waterDTO
       * @param taxCalMap
       * @param tax
       * @param taxCategory1
       */
      @Override
      public void setTaxCalculationMap(final TbTaxMas taxMas2, final Long csIdn,
              final Map<Long, List<BillTaxDTO>> taxCalMap, final double tax, final String taxCategory1) {
          BillTaxDTO dto = null;
          List<BillTaxDTO> dtoMapList = taxCalMap.get(csIdn);
          if (dtoMapList == null) {
              dtoMapList = new ArrayList<>(0);
              dto = new BillTaxDTO();
              dto.setTax(tax);
              dto.setTaxCategoryCodeValue(taxCategory1);
              dto.setTaxId(taxMas2.getTaxId());
              dto.setTaxSequence(taxMas2.getCollSeq());
              dto.setTaxCategory(taxMas2.getTaxCategory1());
              dto.setTaxSubCategory(taxMas2.getTaxCategory2());
              dto.setTaxCategoryCodeValue(taxCategory1);
              dtoMapList.add(dto);
          } else {
              boolean found = false;
              for (final BillTaxDTO taxdata : dtoMapList) {
                  if (taxdata.getTaxId().equals(taxMas2.getTaxId())) {
                      found = true;
                      if (taxdata.getTax() != null) {
                          taxdata.setTax(taxdata.getTax() + tax);
                      } else {
                          taxdata.setTax(tax);
                      }
                  }
              }
              if (!found) {
                  dto = new BillTaxDTO();
                  dto.setTax(tax);
                  dto.setTaxCategoryCodeValue(taxCategory1);
                  dto.setTaxId(taxMas2.getTaxId());
                  dto.setTaxSequence(taxMas2.getCollSeq());
                  dto.setTaxCategory(taxMas2.getTaxCategory1());
                  dto.setTaxSubCategory(taxMas2.getTaxCategory2());
                  dtoMapList.add(dto);
              }
          }
          taxCalMap.put(csIdn, dtoMapList);
      }
  
      /**
       * @param orgnisation
       * @param langId
       * @param empId
       * @param penaltytaxDto
       * @param billDet
       */
      @Override
      public void setBillDetails(final Organisation orgnisation, final int langId,
              final Long empId, final BillTaxDTO penaltytaxDto, final TbBillDet billDet) {
          billDet.setTaxId(penaltytaxDto.getTaxId());
          billDet.setTaxCategory(penaltytaxDto.getTaxCategory());
          billDet.setTaxSubCategory(penaltytaxDto.getTaxSubCategory());
          billDet.setCollSeq(penaltytaxDto.getTaxSequence());
          billDet.setOrgid(orgnisation.getOrgid());
          billDet.setUserId(empId);
          billDet.setLmoddate(new Date());
          billDet.setLangId(langId);
          billDet.setLgIpMac(Utility.getMacAddress());
      }
  
      /*
       * (non-Javadoc)
       * @see com.abm.mainetservice.water.service.TbWtBillMasService#getAdvanceTaxId(long)
       */
      @Override
      public Long getAdvanceTaxId(final long orgid, final String module, final Long depmtId) {
          Long taxId = null;
          Long deptId = null;
          final Organisation organisation = new Organisation();
          organisation.setOrgid(orgid);
          final List<LookUp> taxCategory = CommonMasterUtility.getLevelData(PrefixConstants.LookUpPrefix.TAC,
                  MainetConstants.NUMBERS.ONE,
                  organisation);
          Long advanceId = null;
          if ((taxCategory != null) && !taxCategory.isEmpty()) {
              for (final LookUp lookupid : taxCategory) {
                  if (lookupid.getLookUpCode().equals(PrefixConstants.TAX_CATEGORY.ADVANCE)) {
                      advanceId = lookupid.getLookUpId();
                      break;
                  }
              }
          }
          if (module != null) {
              deptId = departmentService.getDepartmentIdByDeptCode(
                      module, MainetConstants.STATUS.ACTIVE);
          } else {
              deptId = depmtId;
          }
          final LookUp chargeApplicableAt = CommonMasterUtility.getValueFromPrefixLookUp(
                  PrefixConstants.NewWaterServiceConstants.BILL,
                  PrefixConstants.NewWaterServiceConstants.CAA, organisation);
          final List<TbTaxMasEntity> taxMas = tbTaxMasService.getTaxMasterByTaxCategoryId(deptId, advanceId, orgid,
                  chargeApplicableAt.getLookUpId());
          if ((taxMas != null) && !taxMas.isEmpty()) {
              taxId = taxMas.get(0).getTaxId();
          }
          return taxId;
      }
  
      @Override
      public void doVoucherPosting(final List<Long> uniqueId, final Organisation orgId,
              final String deptShortName, final String finYearId, final Long empId) {
          taskExecutor.execute(() -> accountVoucherPosting(uniqueId, orgId, deptShortName, finYearId,
                  empId));
      }
  
      /**
       * @param csIdn
       * @param orgId
       * @param deptShortName
       * @param finYearId
       * @param empId
       */
      private void accountVoucherPosting(final List<Long> uniqueId,
              final Organisation orgId, final String deptShortName,
              final String finYearId, final Long empId) {
          VoucherPostDTO accountPosting = null;
          VoucherPostDetailDTO voucherDetail = null;
          Map<Long, TbBillMas> bills = null;
          String activeFlag = null;
          final LookUp aaountActive = CommonMasterUtility.getValueFromPrefixLookUp(MainetConstants.FlagL,
                  MainetConstants.BUG_HEAD_OPENING_BALANCE_MASTER.SLI_PREFIX_VALUE, orgId);
          if (aaountActive != null) {
              activeFlag = aaountActive.getDefaultVal();
          }
          final List<Long> billIds = new ArrayList<>(0);
          if (PrefixConstants.IsLookUp.STATUS.YES.equals(activeFlag)) {
              final LookUp tdpPrefix = CommonMasterUtility.getValueFromPrefixLookUp(MainetConstants.BILL_MASTER_COMMON.DMD_VALUE,
                      MainetConstants.BILL_MASTER_COMMON.ACCOUNT_TEMPLATE_FOR_PREFIX, orgId);
              final Department dept = departmentService.getDepartment(deptShortName, MainetConstants.STATUS.ACTIVE);
              bills = getBillMasterListByPrimaryKey(uniqueId, orgId.getOrgid(), deptShortName);
              if ((bills != null) && !bills.isEmpty()) {
                  for (final Long primaryKey : uniqueId) {
                      final TbBillMas billMas = bills.get(primaryKey);
                      if (billMas != null) {
                          String referenceNo = null;
                          accountPosting = new VoucherPostDTO();
                          accountPosting.setVoucherDetails(new ArrayList<VoucherPostDetailDTO>(0));
                          if (tdpPrefix != null) {
                              accountPosting.setVoucherSubTypeId(tdpPrefix.getLookUpId());
                          }
                          accountPosting.setVoucherDate(new Date());
                          accountPosting.setDepartmentId(dept.getDpDeptid());
                          referenceNo = billMas.getBmNo();
                          accountPosting.setVoucherReferenceNo(referenceNo);
                          accountPosting.setNarration(dept.getDpDeptdesc()
                                  + ApplicationSession.getInstance().getMessage("bill.lbl.taxes") + referenceNo);
                          accountPosting.setPayerOrPayee(deptShortName);
                          accountPosting.setEntryType(MainetConstants.BILL_MASTER_COMMON.ENTRY_TYPE);
                          final Long emplocationId = iLocationMasService.fetchEmployeeLocation(empId, orgId.getOrgid());
                          if (emplocationId != null) {
                              final TbLocationMas locMas = iLocationMasService.findById(emplocationId);
                              if ((locMas.getLocRevenueWZMappingDto() != null) && !locMas.getLocRevenueWZMappingDto().isEmpty()) {
                                  final Long locationId = locMas.getLocRevenueWZMappingDto().get(0).getCodIdRevLevel1();
                                  accountPosting.setFieldId(locationId);
                              }
                          }
                          accountPosting.setOrgId(orgId.getOrgid());
                          accountPosting.setCreatedBy(empId);
                          accountPosting.setCreatedDate(new Date());
                          accountPosting.setLangId(MainetConstants.ENGLISH);
                          accountPosting.setLgIpMac(Utility.getMacAddress());
                          for (final TbBillDet billDet : billMas.getTbWtBillDet()) {
                              final String taxCategory = CommonMasterUtility
                                      .getNonHierarchicalLookUpObject(billDet.getTaxCategory(), orgId).getLookUpCode();
                              if (!PrefixConstants.TAX_CATEGORY.ADVANCE.equals(taxCategory)) {
                                  voucherDetail = new VoucherPostDetailDTO();
                                  voucherDetail.setVoucherAmount(new BigDecimal(billDet.getBdCurTaxamt()));
                                  final Long budgetCodeId = tbTaxMasService.fetchBudgetCodeIdForReceiptDet(orgId.getOrgid(),
                                          billDet.getTaxId(), MainetConstants.STATUS.ACTIVE);
                                  voucherDetail.setBudgetCodeId(budgetCodeId);
                                  accountPosting.getVoucherDetails().add(voucherDetail);
                              }
                          }
                          final ResponseEntity<?> response = RestClient.callRestTemplateClient(accountPosting,
                                  ServiceEndpoints.ACCOUNT_POSTING);
                          if ((response != null) && (response.getStatusCode() == HttpStatus.OK)) {
                              billIds.add(billMas.getBmIdno());
                              LOGGER.info(ApplicationSession.getInstance().getMessage("account.voucher.posting.successmsg"));
                          } else {
                              LOGGER.error(ApplicationSession.getInstance().getMessage("account.voucher.posting.failmsg")
                                      + (response != null ? response.getBody() : ""));
                          }
                      }
                  }
                  if ((billIds != null) && !billIds.isEmpty()) {
                      updateAccountPostingFlag(billIds, constantYES, deptShortName);
                  }
              }
          }
      }
  
      private boolean updateAccountPostingFlag(final List<Long> billIds, final String flag, final String deptShortName) {
          boolean result = false;
          try {
              Class<?> clazz = null;
              Object dynamicServiceInstance = null;
              String serviceClassName = null;
              final ApplicationSession appSession = ApplicationSession.getInstance();
              serviceClassName = messageSource.getMessage(
                      appSession.getMessage("bill.lbl.Bills") + deptShortName, new Object[] {},
                      StringUtils.EMPTY, Locale.ENGLISH);
              clazz = ClassUtils.forName(serviceClassName,
                      ApplicationContextProvider.getApplicationContext()
                              .getClassLoader());
              dynamicServiceInstance = ApplicationContextProvider
                      .getApplicationContext().getAutowireCapableBeanFactory()
                      .autowire(clazz, 4, false);
              final Method method = ReflectionUtils.findMethod(clazz,
                      "updateAccountPostingFlag", new Class[] { List.class,
                              String.class });
              result = (boolean) ReflectionUtils.invokeMethod(method,
                      dynamicServiceInstance, new Object[] { billIds, flag });
          } catch (LinkageError | Exception e) {
              throw new FrameworkException("Exception in fetching bills for account posting for department :" + deptShortName, e);
          }
          return result;
  
      }
  
      @SuppressWarnings("unchecked")
      private Map<Long, TbBillMas> getBillMasterListByPrimaryKey(final List<Long> csIdnBill, final long orgid,
              final String deptShortName) {
          Map<Long, TbBillMas> result = null;
          try {
              Class<?> clazz = null;
              Object dynamicServiceInstance = null;
              String serviceClassName = null;
              serviceClassName = messageSource.getMessage(
                      "Bill." + deptShortName, new Object[] {},
                      StringUtils.EMPTY, Locale.ENGLISH);
              clazz = ClassUtils.forName(serviceClassName,
                      ApplicationContextProvider.getApplicationContext()
                              .getClassLoader());
              dynamicServiceInstance = ApplicationContextProvider
                      .getApplicationContext().getAutowireCapableBeanFactory()
                      .autowire(clazz, 4, false);
              final Method method = ReflectionUtils.findMethod(clazz,
                      "fetchListOfBillsByPrimaryKey", new Class[] { List.class, Long.class });
              result = (Map<Long, TbBillMas>) ReflectionUtils.invokeMethod(method,
                      dynamicServiceInstance, new Object[] { csIdnBill, orgid });
          } catch (LinkageError | Exception e) {
              throw new FrameworkException("Exception in fetching bills for account posting for department :" + deptShortName, e);
          }
          return result;
      }
  
      @Override
      @Transactional(readOnly = true)
      public TbTaxMasEntity getInterestTax(final Long orgid, final String deptShortName) {
          final Organisation organisation = new Organisation();
          organisation.setOrgid(orgid);
          final List<LookUp> taxCategory = CommonMasterUtility.getLevelData(PrefixConstants.LookUpPrefix.TAC,
                  MainetConstants.NUMBERS.ONE,
                  organisation);
          Long interestTax = null;
          if ((taxCategory != null) && !taxCategory.isEmpty()) {
              for (final LookUp lookupid : taxCategory) {
                  if (lookupid.getLookUpCode().equals(PrefixConstants.TAX_CATEGORY.PENALTY)) {
                      interestTax = lookupid.getLookUpId();
                      break;
                  }
              }
          }
          final Long deptId = departmentService.getDepartmentIdByDeptCode(
                  deptShortName, MainetConstants.STATUS.ACTIVE);
          final LookUp chargeApplicableAt = CommonMasterUtility.getValueFromPrefixLookUp(
                  PrefixConstants.NewWaterServiceConstants.BILL,
                  PrefixConstants.NewWaterServiceConstants.CAA, organisation);
          final List<TbTaxMasEntity> taxMas = tbTaxMasService.getTaxMasterByTaxCategoryId(deptId, interestTax, orgid,
                  chargeApplicableAt.getLookUpId());
          if ((taxMas != null) && !taxMas.isEmpty()) {
              return taxMas.get(0);
          }
          return null;
      }
  
      @Override
      public List<AdjustmentBillDetailMappingEntity> doAdjustmentAgainstBalanceAmount(final List<TbBillMas> listBill,
              final List<AdjustmentMasterEntity> adjustmentEntity) {
          final List<AdjustmentBillDetailMappingEntity> mappingList = new ArrayList<>(0);
          listBill.forEach(billMas -> {
              List<TbBillDet> previous = null;
              adjustmentEntity.forEach(adjMaster -> {
                  final AtomicDouble amountAdjusted = new AtomicDouble();
                  adjMaster.getAdjDetail().forEach(detail -> {
                      AdjustmentBillDetailMappingEntity mapping = null;
                      for (final TbBillDet det : billMas.getTbWtBillDet()) {
                          if (det.getTaxId().equals(detail.getTaxId()) && (detail.getAdjBalanceAmount() > 0d)) {
                              double adjusted = 0d;
                              if (constantNO.equals(adjMaster.getAdjType())) {
                                  final double adjAmount = det.getBdCurBalTaxamt() - detail.getAdjBalanceAmount();
                                  if (adjAmount >= 0d) {
                                      det.setBdCurBalTaxamt(adjAmount);
                                      adjusted += detail.getAdjBalanceAmount();
                                      amountAdjusted.addAndGet(detail.getAdjBalanceAmount());
                                      detail.setAdjAdjustedAmount(detail.getAdjAdjustedAmount() + detail.getAdjBalanceAmount());
                                      detail.setAdjBalanceAmount(0d);
                                      detail.setAdjAdjustedFlag(constantYES);
                                  } else {
                                      adjusted += det.getBdCurBalTaxamt();
                                      amountAdjusted.addAndGet(det.getBdCurBalTaxamt());
                                      detail.setAdjAdjustedAmount(detail.getAdjAdjustedAmount() + det.getBdCurBalTaxamt());
                                      det.setBdCurBalTaxamt(0d);
                                      detail.setAdjBalanceAmount(Math.abs(adjAmount));
                                      detail.setAdjAdjustedFlag(constantNO);
                                  }
                              } else {
  