public ReconciliationVoucher createReconciliationVoucher(
     ReconciliationType reconciliationType, String remark) {
   User loggedOnUser = userService.getLoggedInUser();
   ReconciliationVoucher reconciliationVoucher = new ReconciliationVoucher();
   reconciliationVoucher.setReconciliationType(reconciliationType);
   reconciliationVoucher.setCreateDate(new Date());
   reconciliationVoucher.setCreatedBy(loggedOnUser);
   reconciliationVoucher.setWarehouse(userService.getWarehouseForLoggedInUser());
   reconciliationVoucher.setRemarks(remark);
   reconciliationVoucher.setReconciliationDate(new Date());
   reconciliationVoucher =
       (ReconciliationVoucher) reconciliationVoucherDao.save(reconciliationVoucher);
   return reconciliationVoucher;
 }
  @Transactional
  public RvLineItem reconcileInventoryForPV(
      RvLineItem rvLineItem, List<SkuItem> inStockSkuItems, Sku sku) {
    RvLineItem rvLineItemSaved = null;
    User loggedOnUser = userService.getLoggedInUser();
    int deleteQty = rvLineItem.getQty().intValue();
    rvLineItem.setSku(sku);
    rvLineItem.setReconciledQty(rvLineItem.getQty());
    rvLineItem.setReconciliationType(
        EnumReconciliationType.ProductVariantAudited.asReconciliationType());
    rvLineItemSaved = (RvLineItem) reconciliationVoucherDao.save(rvLineItem);

    for (int i = 0; i < deleteQty; i++) {
      SkuItem skuItem = inStockSkuItems.get(i);
      // Delete -1 entry in PVI
      adminInventoryService.inventoryCheckinCheckout(
          sku,
          skuItem,
          null,
          null,
          null,
          rvLineItemSaved,
          null,
          inventoryService.getInventoryTxnType(EnumInvTxnType.PRODUCT_VARIANT_AUDITED),
          -1L,
          loggedOnUser);

      // set sku item status to Product_variant_ Audited
      skuItem.setSkuItemStatus(EnumSkuItemStatus.ProductVariantAudited.getSkuItemStatus());
      skuItem = skuGroupService.saveSkuItem(skuItem);
    }

    // Check inventory health now.
    inventoryService.checkInventoryHealth(sku.getProductVariant());
    // save RvLine item

    return rvLineItemSaved;
  }
  @Transactional
  public void reconcileAddRV(
      User loggedOnUser,
      List<RvLineItem> rvLineItems,
      ReconciliationVoucher reconciliationVoucher) {

    if (reconciliationVoucher == null || reconciliationVoucher.getId() == null) {
      // reconciliationVoucher = new ReconciliationVoucher();
      reconciliationVoucher.setCreateDate(new Date());
      reconciliationVoucher.setCreatedBy(loggedOnUser);
      reconciliationVoucher.setReconciliationType(
          EnumReconciliationType.Add.asReconciliationType());
    }
    reconciliationVoucher =
        (ReconciliationVoucher) reconciliationVoucherDao.save(reconciliationVoucher);

    logger.debug("rvLineItems@Save: " + rvLineItems.size());

    for (RvLineItem rvLineItem : rvLineItems) {
      Sku sku = rvLineItem.getSku();
      if (sku == null) {
        sku =
            skuService.getSKU(rvLineItem.getProductVariant(), reconciliationVoucher.getWarehouse());
      }
      if (rvLineItem.getQty() != null && rvLineItem.getQty() == 0 && rvLineItem.getId() != null) {
        getBaseDao().delete(rvLineItem);
      } else if (rvLineItem.getId() == null) {

        Long additionType = rvLineItem.getReconciliationType().getId();
        EnumReconciliationType enumReconciliationType =
            EnumReconciliationType.getEnumReconciliationTypeById(additionType);
        InvTxnType invTxnType = null;

        switch (enumReconciliationType) {
          case AddDamage:
            invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_ADD_DAMAGED);
            break;
          case AddExpired:
            invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_ADD_EXPIRED);
            break;
          case AddBatchMismatch:
            invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_ADD_BATCH_MISMATCH);
            break;
          case CustomerReturn:
            invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_CUSTOMER_RETURN);
            break;
          case PharmaReturn:
            invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_PHARMA_RETURN);
            break;
          case AddFreeVariant:
            invTxnType =
                inventoryService.getInventoryTxnType(EnumInvTxnType.RV_ADD_FREE_VARIANT_RECONCILE);
            break;
          case AddIncorrectCounting:
            invTxnType =
                inventoryService.getInventoryTxnType(EnumInvTxnType.RV_ADD_INCORRECT_COUNTING);
            break;
        }

        rvLineItem.setSku(sku);
        rvLineItem.setReconciliationVoucher(reconciliationVoucher);
        rvLineItem = (RvLineItem) getBaseDao().save(rvLineItem);
        SkuGroup skuGroup = null;
        if (productVariantInventoryDao.getPVIForRV(sku, rvLineItem).isEmpty()) {
          // Create batch and checkin inv
          //                        SkuGroup skuGroup =
          // adminInventoryService.createSkuGroup(rvLineItem.getBatchNumber(),
          // rvLineItem.getMfgDate(), rvLineItem.getExpiryDate(), rvLineItem.getCostPrice(),
          // rvLineItem.getMrp(), null, reconciliationVoucher, null, sku);
          skuGroup =
              adminInventoryService.createSkuGroupWithoutBarcode(
                  rvLineItem.getBatchNumber(),
                  rvLineItem.getMfgDate(),
                  rvLineItem.getExpiryDate(),
                  rvLineItem.getCostPrice(),
                  rvLineItem.getMrp(),
                  null,
                  reconciliationVoucher,
                  null,
                  sku);
          adminInventoryService.createSkuItemsAndCheckinInventory(
              skuGroup,
              rvLineItem.getQty(),
              null,
              null,
              rvLineItem,
              null,
              invTxnType,
              loggedOnUser);
          rvLineItem.setSkuGroup(skuGroup);
        }
        rvLineItem.setReconciledQty(rvLineItem.getQty());
        rvLineItem = (RvLineItem) getBaseDao().save(rvLineItem);

        // Add PVI Entry with -1  and  set sku item status to expired
        if ((additionType.intValue()) == (EnumReconciliationType.AddExpired.getId().intValue())) {
          for (SkuItem skuItem : skuGroup.getSkuItems()) {
            adminInventoryService.inventoryCheckinCheckout(
                sku,
                skuItem,
                null,
                null,
                null,
                rvLineItem,
                null,
                EnumInvTxnType.RV_ADD_EXPIRED_AUTOMATIC_DELETION.asInvTxnType(),
                -1L,
                userService.getLoggedInUser());
            skuItem.setSkuItemStatus(EnumSkuItemStatus.Expired.getSkuItemStatus());
            skuGroupService.saveSkuItem(skuItem);
          }
        }

        // Check inventory health now.
        inventoryService.checkInventoryHealth(rvLineItem.getSku().getProductVariant());
      }
    }
  }
  @Transactional
  public RvLineItem reconcileSKUItems(
      ReconciliationVoucher reconciliationVoucher,
      ReconciliationType reconciliationType,
      SkuItem skuItem,
      String remarks) {
    SkuGroup skuGroup = skuItem.getSkuGroup();
    Sku sku = skuGroup.getSku();
    Long subtractionType = reconciliationType.getId();
    EnumReconciliationType subtractTypeEnum =
        EnumReconciliationType.getEnumReconciliationTypeById(subtractionType);
    InvTxnType invTxnType = null;
    SkuItemStatus skuItemStatus = null;

    switch (subtractTypeEnum) {
      case SubtractDamage:
        invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_SUBTRACT_DAMAGED);
        skuItemStatus = EnumSkuItemStatus.Damaged.getSkuItemStatus();
        break;
      case SubtractExpired:
        invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_SUBTRACT_EXPIRED);
        skuItemStatus = EnumSkuItemStatus.Expired.getSkuItemStatus();
        break;
      case Lost:
        invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_LOST_PILFERAGE);
        skuItemStatus = EnumSkuItemStatus.Lost.getSkuItemStatus();
        break;
      case SubtractBatchMismatch:
        invTxnType =
            inventoryService.getInventoryTxnType(EnumInvTxnType.RV_SUBTRACT_BATCH_MISMATCH);
        skuItemStatus = EnumSkuItemStatus.BatchMismatch.getSkuItemStatus();
        break;
      case MrpMismatch:
        invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_MRP_MISMATCH);
        skuItemStatus = EnumSkuItemStatus.MrpMismatch.getSkuItemStatus();
        break;
      case NonMoving:
        invTxnType = inventoryService.getInventoryTxnType(EnumInvTxnType.RV_NON_MOVING);
        skuItemStatus = EnumSkuItemStatus.NonMoving.getSkuItemStatus();
        break;
      case SubtractFreeVariant:
        invTxnType =
            inventoryService.getInventoryTxnType(EnumInvTxnType.RV_SUBTRACT_FREE_VARIANT_RECONCILE);
        skuItemStatus = EnumSkuItemStatus.FreeVariant.getSkuItemStatus();
        break;
      case SubtractIncorrectCounting:
        invTxnType =
            inventoryService.getInventoryTxnType(EnumInvTxnType.RV_SUBTRACT_INCORRECT_COUNTING);
        skuItemStatus = EnumSkuItemStatus.IncorrectCounting.getSkuItemStatus();
        break;
    }

    RvLineItem rvLineItem =
        reconciliationVoucherDao.getRvLineItems(
            reconciliationVoucher, sku, skuGroup, reconciliationType);
    if (rvLineItem == null) {
      rvLineItem = createRVLineItemWithBasicDetails(skuGroup, sku);
    }
    rvLineItem.setReconciliationType(reconciliationType);
    rvLineItem.setReconciliationVoucher(reconciliationVoucher);
    rvLineItem.setRemarks(remarks);
    if (rvLineItem.getReconciledQty() != null) {
      rvLineItem.setReconciledQty(rvLineItem.getReconciledQty() + 1L);
      rvLineItem.setQty(rvLineItem.getQty() + 1L);
    } else {
      rvLineItem.setReconciledQty(1L);
      rvLineItem.setQty(1L);
    }

    rvLineItem = (RvLineItem) getBaseDao().save(rvLineItem);
    adminInventoryService.inventoryCheckinCheckout(
        sku,
        skuItem,
        null,
        null,
        null,
        rvLineItem,
        null,
        invTxnType,
        -1L,
        userService.getLoggedInUser());
    if (skuItemStatus != null) {
      skuItem.setSkuItemStatus(skuItemStatus);
    }
    skuItem = skuGroupService.saveSkuItem(skuItem);
    if (reconciliationType.getId().equals(EnumReconciliationType.SubtractDamage.getId())) {
      adminInventoryService.damageInventoryCheckin(skuItem, null);
    }
    // Check inventory health now.
    inventoryService.checkInventoryHealth(rvLineItem.getSku().getProductVariant());
    return rvLineItem;
  }