Subversion Repositories SmartDukaan

Rev

Rev 23784 | 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.nonbillable.InstructionItemStatus;
import com.spice.profitmandi.dao.repository.dtr.RetailerRegisteredAddressRepository;
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
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.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 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 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);
        
        Set<Integer> instructionItemWarehouseIds = this.instructionItemsToWarehouseIds(instructionItems);
        
        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)));
                }
        Map<Integer, String> fofoIdEmailIdMap = retailerService.getAllFofoRetailerIdEmailIdMap();
        model.addAttribute("fofoIdEmailIdMap", fofoIdEmailIdMap);
        
        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";
    }
        
        
}