Subversion Repositories SmartDukaan

Rev

Rev 23883 | Blame | Last modification | View Log | RSS feed

package com.spice.profitmandi.web.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.spice.profitmandi.common.enumuration.ItemType;
import com.spice.profitmandi.common.enumuration.ScanType;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CreateItemRequest;
import com.spice.profitmandi.common.model.InstructionItemRequest;
import com.spice.profitmandi.common.model.ProfitMandiConstants;
import com.spice.profitmandi.common.model.ScanInItemRequest;
import com.spice.profitmandi.common.model.ScanInPartnerItemRequest;
import com.spice.profitmandi.common.model.ScanOutItemRequest;
import com.spice.profitmandi.common.model.ScanOutPartnerItemRequest;
import com.spice.profitmandi.dao.entity.nonbillable.AdminCurrentInventorySnapshot;
import com.spice.profitmandi.dao.entity.nonbillable.AdminDeliveryNote;
import com.spice.profitmandi.dao.entity.nonbillable.InstructionItem;
import com.spice.profitmandi.dao.entity.nonbillable.InstructionItemDetail;
import com.spice.profitmandi.dao.entity.nonbillable.Item;
import com.spice.profitmandi.dao.entity.nonbillable.PartnerCurrentInventorySnapshot;
import com.spice.profitmandi.dao.entity.nonbillable.ScanOutPartnerItem;
import com.spice.profitmandi.dao.entity.nonbillable.Vendor;
import com.spice.profitmandi.dao.entity.nonbillable.Warehouse;
import com.spice.profitmandi.dao.entity.user.Address;
import com.spice.profitmandi.dao.enumuration.dtr.RoleType;
import com.spice.profitmandi.dao.enumuration.nonbillable.InstructionItemStatus;
import com.spice.profitmandi.dao.repository.dtr.RetailerRegisteredAddressRepository;
import com.spice.profitmandi.dao.repository.dtr.RoleRepository;
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
import com.spice.profitmandi.dao.repository.dtr.UserRoleRepository;
import com.spice.profitmandi.dao.repository.nonbillable.AdminCurrentInventorySnapshotRepository;
import com.spice.profitmandi.dao.repository.nonbillable.AdminDeliveryNoteDetailRepository;
import com.spice.profitmandi.dao.repository.nonbillable.AdminDeliveryNoteRepository;
import com.spice.profitmandi.dao.repository.nonbillable.AdminInventoryItemRepository;
import com.spice.profitmandi.dao.repository.nonbillable.InstructionItemDetailRepository;
import com.spice.profitmandi.dao.repository.nonbillable.InstructionItemRepository;
import com.spice.profitmandi.dao.repository.nonbillable.ItemRepository;
import com.spice.profitmandi.dao.repository.nonbillable.PartnerCurrentInventorySnapshotRepository;
import com.spice.profitmandi.dao.repository.nonbillable.PartnerInventoryItemRepository;
import com.spice.profitmandi.dao.repository.nonbillable.ScanOutPartnerItemRepository;
import com.spice.profitmandi.dao.repository.nonbillable.UserWarehouseRepository;
import com.spice.profitmandi.dao.repository.nonbillable.VendorRepository;
import com.spice.profitmandi.dao.repository.nonbillable.WarehouseRepository;
import com.spice.profitmandi.dao.repository.user.AddressRepository;
import com.spice.profitmandi.service.nonbillable.InventoryService;
import com.spice.profitmandi.service.user.RetailerService;
import com.spice.profitmandi.service.user.UserService;
import com.spice.profitmandi.web.model.LoginDetails;
import com.spice.profitmandi.web.util.CookiesProcessor;

@Controller
@Transactional
public class ItemController {

        private static final Logger LOGGER = LogManager.getLogger(ItemController.class);

        @Autowired
        @Qualifier("nonbillableItemRepository")
        private ItemRepository itemRepository;

        @Autowired
        @Qualifier("nonbillableInventoryService")
        private InventoryService inventoryService;
        @Autowired
        private RoleRepository roleRepository;
        @Autowired
        private UserService userService;
        @Autowired
        private AdminCurrentInventorySnapshotRepository adminCurrentInventorySnapshotRepository;

        @Autowired
        private AdminInventoryItemRepository adminInventoryItemRepository;

        @Autowired
        private PartnerCurrentInventorySnapshotRepository partnerCurrentInventorySnapshotRepository;

        @Autowired
        private VendorRepository vendorRepository;

        @Autowired
        private WarehouseRepository warehouseRepository;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        @Qualifier(value = "userRepository")
        private UserRepository userRepository;
        @Autowired
        private UserRoleRepository userRoleRepository;
        @Autowired
        private UserWarehouseRepository userWarehouseRepository;

        @Autowired
        private AdminDeliveryNoteRepository adminDeliveryNoteRepository;

        @Autowired
        private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;

        @Autowired
        private AddressRepository addressRepository;

        @Autowired
        private PartnerInventoryItemRepository partnerInventoryItemRepository;

        @Autowired
        private ScanOutPartnerItemRepository scanOutPartnerItemRepository;

        @Autowired
        private InstructionItemRepository instructionItemRepository;

        @Autowired
        private InstructionItemDetailRepository instructionItemDetailRepository;

        @Autowired
        private AdminDeliveryNoteDetailRepository adminDeliveryNoteDetailRepository;

        @Autowired
        private CookiesProcessor cookiesProcessor;

        private Map<Integer, String> itemsToVendorIdNameMap(List<Item> items) {
                Map<Integer, String> vendorIdNameMap = new HashMap<>();
                if (items.isEmpty()) {
                        return vendorIdNameMap;
                }
                Set<Integer> vendorIds = new HashSet<>();
                for (Item item : items) {
                        vendorIds.add(item.getVendorId());
                }

                List<Vendor> vendors = vendorRepository.selectByIds(vendorIds);
                for (Vendor vendor : vendors) {
                        vendorIdNameMap.put(vendor.getId(), vendor.getName());
                }
                return vendorIdNameMap;
        }

        private Map<Integer, String> adminCurrentInventorySnapshotsToItemIdDescriptionMap(
                        List<AdminCurrentInventorySnapshot> currentInventorySnapshots) {
                if (currentInventorySnapshots.isEmpty()) {
                        return new HashMap<>();
                }
                Set<Integer> itemIds = new HashSet<>();
                for (AdminCurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
                        itemIds.add(currentInventorySnapshot.getItemId());
                }
                return itemIdDescriptionMap(itemIds);
        }

        private Map<Integer, String> adminCurrentInventorySnapshotsToItemIdTypeMap(
                        List<AdminCurrentInventorySnapshot> currentInventorySnapshots) {
                if (currentInventorySnapshots.isEmpty()) {
                        return new HashMap<>();
                }
                Set<Integer> itemIds = new HashSet<>();
                for (AdminCurrentInventorySnapshot currentInventorySnapshot : currentInventorySnapshots) {
                        itemIds.add(currentInventorySnapshot.getItemId());
                }
                return itemIdTypeMap(itemIds);
        }

        private Map<Integer, String> partnerCurrentInventorySnapshotsToItemIdDescriptionMap(
                        List<PartnerCurrentInventorySnapshot> partnerCurrentInventorySnapshots) {
                if (partnerCurrentInventorySnapshots.isEmpty()) {
                        return new HashMap<>();
                }
                Set<Integer> itemIds = new HashSet<>();
                for (PartnerCurrentInventorySnapshot partnerCurrentInventorySnapshot : partnerCurrentInventorySnapshots) {
                        itemIds.add(partnerCurrentInventorySnapshot.getItemId());
                }
                return itemIdDescriptionMap(itemIds);
        }

        /*
         * private Map<Integer, String>
         * adminDeliveryNotesToItemIdDescriptionMap(List<AdminDeliveryNote>
         * adminDeliveryNotes){ if(adminDeliveryNotes.isEmpty()) { return new
         * HashMap<>(); } Set<Integer> itemIds = new HashSet<>(); for(AdminDeliveryNote
         * adminDeliveryNote : adminDeliveryNotes) {
         * itemIds.add(adminDeliveryNote.getItemId()); } return
         * itemIdDescriptionMap(itemIds); }
         */

        private Map<Integer, String> scanOutPartnerItemsToItemIdDescriptionMap(
                        List<ScanOutPartnerItem> scanOutPartnerItems) {
                if (scanOutPartnerItems.isEmpty()) {
                        return new HashMap<>();
                }
                Set<Integer> itemIds = new HashSet<>();
                for (ScanOutPartnerItem scanOutPartnerItem : scanOutPartnerItems) {
                        itemIds.add(scanOutPartnerItem.getItemId());
                }
                return itemIdDescriptionMap(itemIds);
        }

        private Map<Integer, String> itemIdDescriptionMap(Set<Integer> itemIds) {
                Map<Integer, String> itemIdDescriptionMap = new HashMap<>();
                List<Item> items = itemRepository.selectByIds(itemIds);
                for (Item item : items) {
                        itemIdDescriptionMap.put(item.getId(), item.getBrand() + " " + item.getDescription());
                }
                return itemIdDescriptionMap;
        }

        private Map<Integer, String> itemIdTypeMap(Set<Integer> itemIds) {
                Map<Integer, String> itemIdTypeMap = new HashMap<>();
                List<Item> items = itemRepository.selectByIds(itemIds);
                for (Item item : items) {
                        itemIdTypeMap.put(item.getId(), item.getType().toString());
                }
                return itemIdTypeMap;
        }

        private Map<Integer, String> warehouseIdNameMap(List<Warehouse> warehouses) {
                Map<Integer, String> warehouseIdNameMap = new HashMap<>();
                for (Warehouse warehouse : warehouses) {
                        warehouseIdNameMap.put(warehouse.getId(), warehouse.getName());
                }
                return warehouseIdNameMap;
        }

        private Set<Integer> instructionItemsToWarehouseIds(List<InstructionItem> instructionItems) {
                Set<Integer> warehouseIds = new HashSet<>();
                for (InstructionItem instructionItem : instructionItems) {
                        warehouseIds.add(instructionItem.getWarehouseId());
                }
                return warehouseIds;
        }

        private Set<Integer> instructionItemsToFofoIds(List<InstructionItem> instructionItems) {
                Set<Integer> fofoIds = new HashSet<>();
                for (InstructionItem instructionItem : instructionItems) {
                        fofoIds.add(instructionItem.getFofoId());
                }
                return fofoIds;
        }

        private Set<Integer> instructionItemsToInstructionItemIds(List<InstructionItem> instructionItems) {
                Set<Integer> instructionItemIds = new HashSet<>();
                for (InstructionItem instructionItem : instructionItems) {
                        instructionItemIds.add(instructionItem.getId());
                }
                return instructionItemIds;
        }

        private Map<Integer, Integer> instructionItemDetailsToItemIdQuantityMap(
                        List<InstructionItemDetail> instructionItemDetails) {
                Map<Integer, Integer> itemIdQuantityMap = new HashMap<>();
                for (InstructionItemDetail instructionItemDetail : instructionItemDetails) {
                        if (!itemIdQuantityMap.containsKey(instructionItemDetail.getItemId())) {
                                itemIdQuantityMap.put(instructionItemDetail.getItemId(), instructionItemDetail.getQuantity());
                        } else {
                                itemIdQuantityMap.put(instructionItemDetail.getItemId(),
                                                itemIdQuantityMap.get(instructionItemDetail.getItemId()) + instructionItemDetail.getQuantity());
                        }
                }
                return itemIdQuantityMap;
        }

        private Map<Integer, List<InstructionItemDetail>> instructionItemsToInstructionItemIdInstructionItemDetailsMap(
                        List<InstructionItemDetail> instructionItemDetails) {
                // Set<Integer> instructionItemIds =
                // this.instructionItemsToInstructionItemIds(instructionItems);
                // List<InstructionItemDetail> instructionItemDetails =
                // instructionItemDetailRepository.selectByInstructionItemIds(instructionItemIds);
                Map<Integer, List<InstructionItemDetail>> instructionIdInstructionItemDetailMap = new HashMap<>();
                for (InstructionItemDetail instructionItemDetail : instructionItemDetails) {
                        if (!instructionIdInstructionItemDetailMap.containsKey(instructionItemDetail.getInstructionItemId())) {
                                List<InstructionItemDetail> instructionItemDetailsList = new ArrayList<>();
                                instructionItemDetailsList.add(instructionItemDetail);
                                instructionIdInstructionItemDetailMap.put(instructionItemDetail.getInstructionItemId(),
                                                instructionItemDetailsList);
                        } else {
                                instructionIdInstructionItemDetailMap.get(instructionItemDetail.getInstructionItemId())
                                                .add(instructionItemDetail);
                        }
                }
                return instructionIdInstructionItemDetailMap;
        }

        private Set<Integer> instructionItemDetailsToItemIds(List<InstructionItemDetail> instructionItemDetails) {
                Set<Integer> itemIds = new HashSet<>();
                for (InstructionItemDetail instructionItemDetail : instructionItemDetails) {
                        itemIds.add(instructionItemDetail.getItemId());
                }
                return itemIds;
        }

        private Set<Integer> adminDeliveryNotesToWarehouseIds(List<AdminDeliveryNote> adminDeliveryNotes) {
                Set<Integer> warehouseIds = new HashSet<>();
                for (AdminDeliveryNote adminDeliveryNote : adminDeliveryNotes) {
                        warehouseIds.add(adminDeliveryNote.getWarehouseId());
                }
                return warehouseIds;
        }

        private Set<Integer> adminDeliveryNotesToFofoIds(List<AdminDeliveryNote> adminDeliveryNotes) {
                Set<Integer> fofoIds = new HashSet<>();
                for (AdminDeliveryNote adminDeliveryNote : adminDeliveryNotes) {
                        fofoIds.add(adminDeliveryNote.getFofoId());
                }
                return fofoIds;
        }

        @RequestMapping(value = "/createItem", method = RequestMethod.GET)
        public String createItem(HttpServletRequest request, @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                List<Item> items = itemRepository.selectAll(offset, limit);
                long size = itemRepository.selectAllCount();
                Map<Integer, String> vendorIdNameMap = this.itemsToVendorIdNameMap(items);
                List<Vendor> vendors = vendorRepository.selectAll();
                model.addAttribute("vendors", vendors);
                model.addAttribute("items", items);
                model.addAttribute("types", ItemType.values());
                model.addAttribute("vendorIdNameMap", vendorIdNameMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (items.size() < limit) {
                        model.addAttribute("end", offset + items.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "items";
        }

        @RequestMapping(value = "/createItem", method = RequestMethod.POST)
        public String createItem(HttpServletRequest request, @RequestBody CreateItemRequest createItemRequest,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {} with body {}", request.getRequestURI(), createItemRequest);
                inventoryService.createItem(createItemRequest);
                List<Item> items = itemRepository.selectAll(offset, limit);
                Map<Integer, String> vendorIdNameMap = this.itemsToVendorIdNameMap(items);
                long size = itemRepository.selectAllCount();
                List<Vendor> vendors = vendorRepository.selectAll();
                model.addAttribute("vendors", vendors);
                model.addAttribute("items", items);
                model.addAttribute("types", ItemType.values());
                model.addAttribute("vendorIdNameMap", vendorIdNameMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (items.size() < limit) {
                        model.addAttribute("end", offset + items.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "items";
        }

        @RequestMapping(value = "/getPaginatedItems", method = RequestMethod.GET)
        public String getPaginatedItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                List<Item> items = itemRepository.selectAll(offset, limit);
                Map<Integer, String> vendorIdNameMap = this.itemsToVendorIdNameMap(items);
                List<Vendor> vendors = vendorRepository.selectAll();
                model.addAttribute("vendors", vendors);
                model.addAttribute("items", items);
                model.addAttribute("vendorIdNameMap", vendorIdNameMap);
                return "items-paginated";
        }

        @RequestMapping(value = "/scanInItems", method = RequestMethod.POST)
        public String scanInItems(HttpServletRequest request, @RequestBody ScanInItemRequest scanInItemRequest,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {} with body {}", request.getRequestURI(), scanInItemRequest);
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<Integer> warehouseIds = userWarehouseRepository.selectWarehouseIdsByUserId(loginDetails.getFofoId());
                List<Item> items = itemRepository.selectAll();
                inventoryService.scanInItem(scanInItemRequest, loginDetails.getFofoId());
                List<AdminCurrentInventorySnapshot> adminCurrentInventorySnapshots = adminCurrentInventorySnapshotRepository
                                .selectAllByAdminId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this
                                .adminCurrentInventorySnapshotsToItemIdDescriptionMap(adminCurrentInventorySnapshots);
                long size = adminCurrentInventorySnapshotRepository.selectAllCountByAdminId(loginDetails.getFofoId());
                if (!warehouseIds.isEmpty()) {
                        model.addAttribute("warehouses", warehouseRepository.selectByIds(new HashSet<>(warehouseIds)));
                }
                model.addAttribute("items", items);
                model.addAttribute("adminCurrentInventorySnapshots", adminCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (adminCurrentInventorySnapshots.size() < limit) {
                        model.addAttribute("end", offset + adminCurrentInventorySnapshots.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "scan-in-items";
        }

        @RequestMapping(value = "/getScanInItems", method = RequestMethod.GET)
        public String getScanInItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<Integer> warehouseIds = userWarehouseRepository.selectWarehouseIdsByUserId(loginDetails.getFofoId());
                List<Item> items = itemRepository.selectAll();
                List<AdminCurrentInventorySnapshot> adminCurrentInventorySnapshots = adminCurrentInventorySnapshotRepository
                                .selectAllByAdminId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this
                                .adminCurrentInventorySnapshotsToItemIdDescriptionMap(adminCurrentInventorySnapshots);
                long size = adminCurrentInventorySnapshotRepository.selectAllCountByAdminId(loginDetails.getFofoId());
                if (!warehouseIds.isEmpty()) {
                        model.addAttribute("warehouses", warehouseRepository.selectByIds(new HashSet<>(warehouseIds)));
                }
                model.addAttribute("items", items);
                model.addAttribute("adminCurrentInventorySnapshots", adminCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (adminCurrentInventorySnapshots.size() < limit) {
                        model.addAttribute("end", offset + adminCurrentInventorySnapshots.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "scan-in-items";
        }

        @RequestMapping(value = "/getPaginatedScanInItems", method = RequestMethod.GET)
        public String getPaginatedScanInItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<AdminCurrentInventorySnapshot> adminCurrentInventorySnapshots = adminCurrentInventorySnapshotRepository
                                .selectAllByAdminId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this
                                .adminCurrentInventorySnapshotsToItemIdDescriptionMap(adminCurrentInventorySnapshots);
                model.addAttribute("adminCurrentInventorySnapshots", adminCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                return "scan-in-items-paginated";
        }

        @RequestMapping(value = "/getScanInPartnerItems", method = RequestMethod.GET)
        public String getScanInPartnerItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);

                // List<Item> items = itemRepository.selectAll();
                List<PartnerCurrentInventorySnapshot> partnerCurrentInventorySnapshots = partnerCurrentInventorySnapshotRepository
                                .selectAllByFofoId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this
                                .partnerCurrentInventorySnapshotsToItemIdDescriptionMap(partnerCurrentInventorySnapshots);
                long size = partnerCurrentInventorySnapshotRepository.selectAllCountByFofoId(loginDetails.getFofoId());
                // model.addAttribute("items", items);
                model.addAttribute("partnerCurrentInventorySnapshots", partnerCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (partnerCurrentInventorySnapshots.size() < limit) {
                        model.addAttribute("end", offset + partnerCurrentInventorySnapshots.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "scan-in-partner-items";
        }

        @RequestMapping(value = "/scanInPartnerItems", method = RequestMethod.POST)
        public String getScanInPartnerItems(HttpServletRequest request,
                        @RequestBody ScanInPartnerItemRequest scanInPartnerItemRequest,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                inventoryService.scanInPartnerItem(scanInPartnerItemRequest, loginDetails.getFofoId());
                List<PartnerCurrentInventorySnapshot> partnerCurrentInventorySnapshots = partnerCurrentInventorySnapshotRepository
                                .selectAllByFofoId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this
                                .partnerCurrentInventorySnapshotsToItemIdDescriptionMap(partnerCurrentInventorySnapshots);
                long size = partnerCurrentInventorySnapshotRepository.selectAllCountByFofoId(loginDetails.getFofoId());
                model.addAttribute("partnerCurrentInventorySnapshots", partnerCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (partnerCurrentInventorySnapshots.size() < limit) {
                        model.addAttribute("end", offset + partnerCurrentInventorySnapshots.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "scan-in-partner-items";
        }

        @RequestMapping(value = "/getPaginatedScanInPartnerItems", method = RequestMethod.GET)
        public String getPaginatedScanInPartnerItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<PartnerCurrentInventorySnapshot> partnerCurrentInventorySnapshots = partnerCurrentInventorySnapshotRepository
                                .selectAllByFofoId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this
                                .partnerCurrentInventorySnapshotsToItemIdDescriptionMap(partnerCurrentInventorySnapshots);
                model.addAttribute("partnerCurrentInventorySnapshots", partnerCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                return "scan-in-partner-items-paginated";
        }

        private Map<Integer, Integer> partnerCurrentInventorySnapshotsItemIdQuantityMap(
                        List<PartnerCurrentInventorySnapshot> partnerCurrentInventorySnapshots) {
                Map<Integer, Integer> itemIdQuantityMap = new HashMap<>();
                for (PartnerCurrentInventorySnapshot partnerCurrentInventorySnapshot : partnerCurrentInventorySnapshots) {
                        itemIdQuantityMap.put(partnerCurrentInventorySnapshot.getItemId(),
                                        partnerCurrentInventorySnapshot.getAvailability());
                }
                return itemIdQuantityMap;
        }

        @RequestMapping(value = "/getScanOutPartnerItems", method = RequestMethod.GET)
        public String getScanOutPartnerItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);

                int addressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(loginDetails.getFofoId());
                Address address = addressRepository.selectById(addressId);

                List<PartnerCurrentInventorySnapshot> partnerCurrentInventorySnapshots = partnerCurrentInventorySnapshotRepository
                                .selectByFofoId(loginDetails.getFofoId());
                Map<Integer, Integer> itemIdQuantityMap = this
                                .partnerCurrentInventorySnapshotsItemIdQuantityMap(partnerCurrentInventorySnapshots);
                List<Item> items = itemRepository.selectByIds(itemIdQuantityMap.keySet());

                List<ScanOutPartnerItem> scanOutPartnerItems = scanOutPartnerItemRepository
                                .selectAllByFofoId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this.scanOutPartnerItemsToItemIdDescriptionMap(scanOutPartnerItems);
                long size = scanOutPartnerItemRepository.selectCountByFofoId(loginDetails.getFofoId());
                model.addAttribute("items", items);
                // model.addAttribute("stateNames", Utils.getAllStateNames());
                model.addAttribute("retailerStateName", address.getState());
                model.addAttribute("scanOutPartnerItems", scanOutPartnerItems);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("itemIdQuantityMap", itemIdQuantityMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (scanOutPartnerItems.size() < limit) {
                        model.addAttribute("end", offset + scanOutPartnerItems.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "scan-out-partner-items";
        }

        @RequestMapping(value = "/instructionItem", method = RequestMethod.POST)
        public String instructionItems(HttpServletRequest request,
                        @RequestBody InstructionItemRequest instructionItemRequest,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {} with body {}", request.getRequestURI(), instructionItemRequest);
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                inventoryService.instructionItem(instructionItemRequest, loginDetails.getFofoId());
                return this.getInstructionItems(request, offset, limit, model);
        }

        @RequestMapping(value = "/getInstructionItems", method = RequestMethod.GET)
        public String getInstructionItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<InstructionItem> instructionItems = instructionItemRepository.selectAllByAdminId(loginDetails.getFofoId(),
                                offset, limit);
                LOGGER.info("instructionItems" + instructionItems);
                Set<Integer> instructionItemWarehouseIds = this.instructionItemsToWarehouseIds(instructionItems);
                LOGGER.info("instructionItemWarehouseIds" + instructionItemWarehouseIds);
                List<Warehouse> warehouses = new ArrayList<>();
                if (!instructionItemWarehouseIds.isEmpty()) {

                        warehouses = warehouseRepository.selectByIds(instructionItemWarehouseIds);

                }
                Map<Integer, String> warehouseIdNameMap = this.warehouseIdNameMap(warehouses);

                List<Integer> warehouseIds = userWarehouseRepository.selectWarehouseIdsByUserId(loginDetails.getFofoId());
                if (!warehouseIds.isEmpty()) {
                        model.addAttribute("warehouses", warehouseRepository.selectByIds(new HashSet<>(warehouseIds)));
                        LOGGER.info(warehouseRepository.selectByIds(new HashSet<>(warehouseIds)) + "warehouseIdNameMap");
                }

                List<Integer> userIds = userRoleRepository
                                .selectUserIdsByRoleId(roleRepository.selectByName(RoleType.FOFO_ADMIN.toString()).getId());
                Map<Integer, String> userIdEmailIdMap = userService.getAllUseUserIdEmailIdMap(userIds);

                model.addAttribute("fofoIdEmailIdMap", userIdEmailIdMap);
                long size = instructionItemRepository.selectCountByAdminId(loginDetails.getFofoId());
                model.addAttribute("warehouseIdNameMap", warehouseIdNameMap);
                model.addAttribute("instructionItems", instructionItems);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (instructionItems.size() < limit) {
                        model.addAttribute("end", offset + instructionItems.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }

                return "instruction-items";
        }

        @RequestMapping(value = "/getPaginatedInstructionItems", method = RequestMethod.GET)
        public String getPaginatedInstructionItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<InstructionItem> instructionItems = instructionItemRepository.selectAllByAdminId(loginDetails.getFofoId(),
                                offset, limit);

                Set<Integer> warehouseIds = this.instructionItemsToWarehouseIds(instructionItems);
                List<Warehouse> warehouses = warehouseRepository.selectByIds(warehouseIds);
                Map<Integer, String> warehouseIdNameMap = this.warehouseIdNameMap(warehouses);

                model.addAttribute("warehouseIdNameMap", warehouseIdNameMap);
                model.addAttribute("instructionItems", instructionItems);
                return "scan-out-partner-items-paginated";
        }

        @RequestMapping(value = "/scanOutPartnerItem", method = RequestMethod.POST)
        public String scanOutPartnerItems(HttpServletRequest request,
                        @RequestBody ScanOutPartnerItemRequest scanOutPartnerItemRequest,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                inventoryService.scanOutPartnerItem(scanOutPartnerItemRequest, loginDetails.getFofoId());
                return this.scanOutPartnerItems(request, scanOutPartnerItemRequest, offset, limit, model);
        }

        @RequestMapping(value = "/getPaginatedScanOutPartnerItems", method = RequestMethod.GET)
        public String getPaginatedScanOutPartnerItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<ScanOutPartnerItem> scanOutPartnerItems = scanOutPartnerItemRepository
                                .selectAllByFofoId(loginDetails.getFofoId(), offset, limit);
                Map<Integer, String> itemIdDescriptionMap = this.scanOutPartnerItemsToItemIdDescriptionMap(scanOutPartnerItems);
                model.addAttribute("scanOutPartnerItems", scanOutPartnerItems);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                return "scan-out-partner-items-paginated";
        }

        @RequestMapping(value = "/deliveryNoteDetails", method = RequestMethod.GET)
        public String deliveryNoteDetails(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.DELIVERY_NOTE_ID) String deliveryNoteId, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                AdminDeliveryNote adminDeliveryNote = adminDeliveryNoteRepository
                                .selectByDeliveryNoteIdAndFofoid(deliveryNoteId, loginDetails.getFofoId());
                if (adminDeliveryNote.getCompleteTimestamp() != null) {
                        throw new ProfitMandiBusinessException(
                                        ProfitMandiConstants.DELIVERY_NOTE_ID + ", " + ProfitMandiConstants.FOFO_ID,
                                        deliveryNoteId + ", " + loginDetails.getFofoId(), "NNBLBL_ITM_1002");
                }
                Warehouse warehouse = warehouseRepository.selectId(adminDeliveryNote.getWarehouseId());
                List<Integer> instructionItemIds = adminDeliveryNoteDetailRepository
                                .selectInstructionItemIdsByDeliveryNoteId(deliveryNoteId);
                List<InstructionItemDetail> instructionItemDetails = instructionItemDetailRepository
                                .selectByInstructionItemIds(new HashSet<>(instructionItemIds));
                Map<Integer, Integer> itemIdQuantityMap = this
                                .instructionItemDetailsToItemIdQuantityMap(instructionItemDetails);
                Map<Integer, String> itemIdDescriptionMap = this.itemIdDescriptionMap(itemIdQuantityMap.keySet());
                Map<Integer, String> itemIdTypeMap = this.itemIdTypeMap(itemIdQuantityMap.keySet());
                model.addAttribute("deliveryNoteId", deliveryNoteId);
                model.addAttribute("warehouseName", warehouse.getName());
                model.addAttribute("itemIdQuantityMap", itemIdQuantityMap);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("itemIdTypeMap", itemIdTypeMap);
                return "delivery-note-details";
        }

        @RequestMapping(value = "/getItemsByWarehouseId", method = RequestMethod.GET)
        public String getItemsByWarehouseId(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.WAREHOUSE_ID) int warehouseId, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                List<AdminCurrentInventorySnapshot> adminCurrentInventorySnapshots = adminCurrentInventorySnapshotRepository
                                .selectAllAvailableByWarehouseId(warehouseId);
                Map<Integer, String> itemIdDescriptionMap = this
                                .adminCurrentInventorySnapshotsToItemIdDescriptionMap(adminCurrentInventorySnapshots);
                Map<Integer, String> itemIdTypeMap = this
                                .adminCurrentInventorySnapshotsToItemIdTypeMap(adminCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("itemIdTypeMap", itemIdTypeMap);
                return "warehouse-items";
        }

        @RequestMapping(value = "/getInstructionItemsByWarehouseId", method = RequestMethod.GET)
        public String getInstructionItemsByWarehouseId(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.WAREHOUSE_ID) int warehouseId, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                List<AdminCurrentInventorySnapshot> adminCurrentInventorySnapshots = adminCurrentInventorySnapshotRepository
                                .selectAllAvailableByWarehouseId(warehouseId);
                Map<Integer, String> itemIdDescriptionMap = this
                                .adminCurrentInventorySnapshotsToItemIdDescriptionMap(adminCurrentInventorySnapshots);
                Map<Integer, String> itemIdTypeMap = this
                                .adminCurrentInventorySnapshotsToItemIdTypeMap(adminCurrentInventorySnapshots);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("itemIdTypeMap", itemIdTypeMap);
                return "warehouse-instruction-items";
        }

        @RequestMapping(value = "/getPendingInstructionItems", method = RequestMethod.GET)
        public String getPendingInstructionItems(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.WAREHOUSE_ID) int warehouseId,
                        @RequestParam(name = ProfitMandiConstants.USER_ID) int userId, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<InstructionItem> instructionItems = instructionItemRepository.selectByAdminIdWarehouseIdUserIdStatus(
                                loginDetails.getFofoId(), warehouseId, userId, InstructionItemStatus.PENDING);
                Set<Integer> instructionItemIds = this.instructionItemsToInstructionItemIds(instructionItems);
                List<InstructionItemDetail> instructionItemDetails = instructionItemDetailRepository
                                .selectByInstructionItemIds(instructionItemIds);
                Set<Integer> itemIds = this.instructionItemDetailsToItemIds(instructionItemDetails);
                Map<Integer, List<InstructionItemDetail>> instructionItemIdInstructionItemDetailsMap = this
                                .instructionItemsToInstructionItemIdInstructionItemDetailsMap(instructionItemDetails);
                Map<Integer, String> itemIdDescriptionMap = this.itemIdDescriptionMap(itemIds);
                Map<Integer, String> itemIdTypeMap = this.itemIdTypeMap(itemIds);
                model.addAttribute("instructionItems", instructionItems);
                model.addAttribute("instructionItemIdInstructionItemDetailsMap", instructionItemIdInstructionItemDetailsMap);
                model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                model.addAttribute("itemIdTypeMap", itemIdTypeMap);
                return "pending-instruction-items";
        }

        @RequestMapping(value = "/getScanOutItems", method = RequestMethod.GET)
        public String getScanOutItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                // List<AdminCurrentInventorySnapshot> adminCurrentInventorySnapshots =
                // adminCurrentInventorySnapshotRepository.selectAll();
                // Set<Integer> adminIds = this.getAdminIds(adminCurrentInventorySnapshots);
                // Map<Integer, String> adminIdEmailIdMap =
                // retailerService.getAllFofoRetailerIdEmailIdMap(adminIds);
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                List<InstructionItem> instructionItems = instructionItemRepository
                                .selectByAdminIdStatus(loginDetails.getFofoId(), InstructionItemStatus.PENDING);

                List<Warehouse> warehouses = new ArrayList<>();
                Map<Integer, String> fofoIdEmailIdMap = new HashMap<>();
                if (!instructionItems.isEmpty()) {
                        Set<Integer> warehouseIds = this.instructionItemsToWarehouseIds(instructionItems);
                        warehouses = warehouseRepository.selectByIds(warehouseIds);
                        Set<Integer> fofoIds = this.instructionItemsToFofoIds(instructionItems);
                        fofoIdEmailIdMap = retailerService.getAllFofoRetailerIdEmailIdMap(fofoIds);
                }

                List<AdminDeliveryNote> adminDeliveryNotes = adminDeliveryNoteRepository.selectAll(offset, limit);
                Map<Integer, String> warehouseIdNameMap = new HashMap<>();
                if (!adminDeliveryNotes.isEmpty()) {
                        List<Warehouse> adminDeliveryNoteWarehouses = warehouseRepository
                                        .selectByIds(this.adminDeliveryNotesToWarehouseIds(adminDeliveryNotes));
                        warehouseIdNameMap = this.warehouseIdNameMap(adminDeliveryNoteWarehouses);
                        fofoIdEmailIdMap = retailerService
                                        .getAllFofoRetailerIdEmailIdMap(this.adminDeliveryNotesToFofoIds(adminDeliveryNotes));
                }
                long size = adminDeliveryNoteRepository.selectAllCount();
                // model.addAttribute("adminIdEmailIdMap", adminIdEmailIdMap);
                model.addAttribute("adminDeliveryNotes", adminDeliveryNotes);
                model.addAttribute("warehouses", warehouses);
                model.addAttribute("warehouseIdNameMap", warehouseIdNameMap);
                model.addAttribute("fofoIdEmailIdMap", fofoIdEmailIdMap);
                model.addAttribute("start", offset + 1);
                model.addAttribute("size", size);
                if (adminDeliveryNotes.size() < limit) {
                        model.addAttribute("end", offset + adminDeliveryNotes.size());
                } else {
                        model.addAttribute("end", offset + limit);
                }
                return "scan-out-items";
        }

        @RequestMapping(value = "/scanOutItems", method = RequestMethod.POST)
        public String scanOutItems(HttpServletRequest request, @RequestBody ScanOutItemRequest scanOutItemRequest,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {} with body {}", request.getRequestURI(), scanOutItemRequest);
                LoginDetails loginDetails = cookiesProcessor.getCookiesObject(request);
                inventoryService.scanOutItem(scanOutItemRequest, loginDetails.getFofoId());
                return this.getScanOutItems(request, offset, limit, model);
        }

        @RequestMapping(value = "/getPaginatedScanOutItems", method = RequestMethod.GET)
        public String getPaginatedScanOutItems(HttpServletRequest request,
                        @RequestParam(name = "offset", defaultValue = "0") int offset,
                        @RequestParam(name = "limit", defaultValue = "10") int limit, Model model)
                        throws ProfitMandiBusinessException {
                LOGGER.info("Request Received at url {}", request.getRequestURI());
                /*
                 * List<Warehouse> warehouses = warehouseRepository.selectAll();
                 * List<AdminDeliveryNote> adminDeliveryNotes =
                 * adminDeliveryNoteRepository.selectAll(offset, limit); Map<Integer, String>
                 * itemIdDescriptionMap =
                 * this.adminDeliveryNotesToItemIdDescriptionMap(adminDeliveryNotes);
                 * Map<Integer, String> warehouseIdNameMap =
                 * this.warehouseIdNameMap(warehouses); Map<Integer, String> fofoIdEmailIdMap =
                 * retailerService.getAllFofoRetailerIdEmailIdMap();
                 * model.addAttribute("adminDeliveryNotes", adminDeliveryNotes);
                 * model.addAttribute("warehouseIdNameMap", warehouseIdNameMap);
                 * model.addAttribute("fofoIdEmailIdMap", fofoIdEmailIdMap);
                 * model.addAttribute("itemIdDescriptionMap", itemIdDescriptionMap);
                 */
                return "scan-out-items-paginated";
        }

        @RequestMapping(value = "/getSerialNumbersByItemIdWarehouseId", method = RequestMethod.GET)
        public String getSerialNumbersByItemIdWarehouseId(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.ITEM_ID) int itemId,
                        @RequestParam(name = ProfitMandiConstants.WAREHOUSE_ID) int warehouseId, Model model)
                        throws ProfitMandiBusinessException {
                List<String> itemSerialNumbers = adminInventoryItemRepository
                                .selectSerialNumbersByWarehouseIdItemIdScanType(warehouseId, itemId, ScanType.IN);
                model.addAttribute("itemSerialNumbers", itemSerialNumbers);
                return "item-serial-numbers";
        }

        @RequestMapping(value = "/getSerialNumbersByItemId", method = RequestMethod.GET)
        public String getSerialNumbersByItemId(HttpServletRequest request,
                        @RequestParam(name = ProfitMandiConstants.ITEM_ID) int itemId, Model model)
                        throws ProfitMandiBusinessException {
                List<String> itemSerialNumbers = partnerInventoryItemRepository.selectSerialNumbersByItemIdScanType(itemId,
                                ScanType.IN);
                model.addAttribute("itemSerialNumbers", itemSerialNumbers);
                return "item-serial-numbers-single";
        }

}