Subversion Repositories SmartDukaan

Rev

Rev 23131 | Rev 23137 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.service.user;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.common.model.CustomAddress;
import com.spice.profitmandi.common.model.CustomShop;
import com.spice.profitmandi.common.model.UpdateRetailerRequest;
import com.spice.profitmandi.dao.entity.dtr.Retailer;
import com.spice.profitmandi.dao.entity.dtr.RetailerRegisteredAddress;
import com.spice.profitmandi.dao.entity.dtr.Shop;
import com.spice.profitmandi.dao.entity.dtr.ShopAddress;
import com.spice.profitmandi.dao.entity.dtr.User;
import com.spice.profitmandi.dao.entity.dtr.UserAccounts;
import com.spice.profitmandi.dao.entity.dtr.UserRole;
import com.spice.profitmandi.dao.entity.user.Address;
import com.spice.profitmandi.dao.entity.user.Cart;
import com.spice.profitmandi.dao.enumuration.dtr.AccountType;
import com.spice.profitmandi.dao.enumuration.dtr.RetailerType;
import com.spice.profitmandi.dao.enumuration.dtr.RoleType;
import com.spice.profitmandi.dao.repository.dtr.DocumentRepository;
import com.spice.profitmandi.dao.repository.dtr.RetailerRegisteredAddressRepository;
import com.spice.profitmandi.dao.repository.dtr.RetailerRepository;
import com.spice.profitmandi.dao.repository.dtr.ShopAddressRepository;
import com.spice.profitmandi.dao.repository.dtr.ShopRepository;
import com.spice.profitmandi.dao.repository.dtr.UserAccountRepository;
import com.spice.profitmandi.dao.repository.dtr.UserRepository;
import com.spice.profitmandi.dao.repository.dtr.UserRoleRepository;
import com.spice.profitmandi.dao.repository.user.AddressRepository;
import com.spice.profitmandi.dao.repository.user.CartRepository;

import in.shop2020.model.v1.user.CartStatus;

@Component
public class RetailerServiceImpl implements RetailerService {
        
        private static final Logger LOGGER = LoggerFactory.getLogger(RetailerServiceImpl.class);
        
        @Autowired
        private RetailerRepository retailerRepository;
        
        @Autowired
        private UserAccountRepository userAccountRepository;
        
        @Autowired
        private UserRepository userRepository;
        
        @Autowired
        private CartRepository cartRepository;
        
        @Autowired
        private RetailerRegisteredAddressRepository retailerRegisteredAddressRepository;
        
        @Autowired
        private AddressRepository addressRepository;
        
        @Autowired
        private ShopRepository shopRepository;
        
        @Autowired
        private ShopAddressRepository shopAddressRepository;
        
        @Autowired
        private UserRoleRepository userRoleRepository;
        
        @Autowired
        private DocumentRepository documentRepository;
        
        @Autowired
        @Qualifier("userUserRepository")
        private com.spice.profitmandi.dao.repository.user.UserRepository userUserRepository;
        
        @Override
        public Map<String, Object> getByEmailIdOrMobileNumber(String emailIdOrMobileNumber)
                        throws ProfitMandiBusinessException {
                User user = userRepository.selectByEmailIdOrMobileNumber(emailIdOrMobileNumber);
                List<UserRole> userRoles = userRoleRepository.selectByUserId(user.getId());
                Map<String, Object> map = new HashMap<>();
                map.put("user", user);
                //map.put("retailer", retailer);
                
                
                map.put("userRoles", this.toString(userRoles));
                try{
                        int retailerId = userAccountRepository.selectRetailerIdByUserId(user.getId());
                        Retailer retailer = retailerRepository.selectById(retailerId);
                        
                        map.put("retailer", retailer);
                        try{
                                int retailerAddressId = retailerRegisteredAddressRepository.selectAddressIdByRetailerId(retailer.getId());
                                Address retailerAddress = addressRepository.selectById(retailerAddressId);
                                map.put("retailerAddress", retailerAddress);
                                List<Shop> shops = shopRepository.selectByRetailerId(retailer.getId());
                                map.put("shops", shops);
                                this.addAddress(shops);
                        }catch(ProfitMandiBusinessException profitMandiBusinessException){
                                LOGGER.error("Retailer Registered Address not found");
                        }
                }catch(ProfitMandiBusinessException profitMandiBusinessException){
                        LOGGER.error("Retailer not found in user_account");
                }
                
                return map;
        }
        
        @SuppressWarnings("unchecked")
        @Override
        public Map<String, Object> updateRetailerDetails(UpdateRetailerRequest updateRetailerRequest)
                        throws ProfitMandiBusinessException {
                Map<String, Object> map = this.getByEmailIdOrMobileNumber(updateRetailerRequest.getEmailIdOrMobileNumber());
                User user = (User)map.get("user");
                Retailer retailer = (Retailer)map.get("retailer");
                if(retailer == null){
                        retailer = this.updateRetailer(user, retailer, updateRetailerRequest);
                        map.put("retailer", retailer);
                }
                Address retailerAddress = (Address)map.get("retailerAddress");
                if(retailerAddress == null){
                        retailerAddress = this.updateRetailerAddress(retailerAddress, updateRetailerRequest.getAddress(), retailer.getId());
                        map.put("retailerAddress", retailerAddress);
                }
                List<Shop> shops = (List<Shop>)map.get("shops");
                if(shops == null){
                        shops = new ArrayList<>();
                        map.put("shops", shops);
                }
                this.updateRetailerShops(shops, updateRetailerRequest.getShops(), retailer.getId(), retailerAddress);
                return map;
        }
        
        private int createSaholicUser(User user, String retailerName){
                com.spice.profitmandi.dao.entity.user.User saholicUser = null;
                try {
                        saholicUser = userUserRepository.selectByEmailId(user.getEmailId());
                }catch (ProfitMandiBusinessException e) {
                        LOGGER.info("User doesnt exist in old system");
                }
                if(saholicUser == null){
                        Cart cart = new Cart();
                        cart.setCartStatus(CartStatus.ACTIVE);
                        cartRepository.persist(cart);
                        saholicUser = new com.spice.profitmandi.dao.entity.user.User();
                        saholicUser.setEmailId(user.getEmailId());
                        saholicUser.setName(retailerName);
                        saholicUser.setActiveCartId(cart.getId());
                        userUserRepository.persist(saholicUser);
                        
                        UserAccounts ua = new UserAccounts();
                        ua.setAccount_key(String.valueOf(saholicUser.getId()));
                        ua.setUser_id(user.getId());
                        ua.setAccount_type(AccountType.saholic);
                        userAccountRepository.persist(ua);

                        UserAccounts ua2 = new UserAccounts();
                        ua2.setAccount_key(String.valueOf(saholicUser.getActiveCartId()));
                        ua2.setUser_id(user.getId());
                        ua2.setAccount_type(AccountType.cartId);
                        userAccountRepository.persist(ua2);
                }
                return saholicUser.getId();
        }
        
        private Retailer updateRetailer(User user, Retailer retailer, UpdateRetailerRequest updateRetailerRequest) throws ProfitMandiBusinessException{
                if(retailer == null){
                        int saholicUserId = this.createSaholicUser(user, updateRetailerRequest.getName());
                        retailer = new Retailer();
                        retailer.setId(saholicUserId);
                        UserRole userRole = new UserRole();
                        userRole.setUserId(user.getId());
                        userRole.setRoleType(RoleType.RETAILER);
                        userRoleRepository.persist(userRole);
                }
                retailer.setName(updateRetailerRequest.getName());
                retailer.setNumber(updateRetailerRequest.getNumber());
                if(updateRetailerRequest.getNumber() == null || updateRetailerRequest.getNumber().isEmpty()){
                        retailer.setType(RetailerType.UNREGISTERED_SHOP);
                }else{
                        retailer.setType(RetailerType.GSTIN);
                }
                if(updateRetailerRequest.getDocumentId() > 0){
                        retailer.setDocumentId(updateRetailerRequest.getDocumentId());
                }
                retailerRepository.persist(retailer);
                return retailer;
        }
        
        private Address updateRetailerAddress(Address address, CustomAddress customAddress, int retailerId) throws ProfitMandiBusinessException{
                if(address == null){
                        address = new Address();
                        address.setRetaierId(retailerId);
                        this.updateAddress(address, customAddress);
                        //addressRepository.persist(addressRetailer);
                        
                        final RetailerRegisteredAddress retailerRegisteredAddress = new RetailerRegisteredAddress();
                        retailerRegisteredAddress.setRetailerId(retailerId);
                        retailerRegisteredAddress.setAddressId(address.getId());
                        retailerRegisteredAddressRepository.persist(retailerRegisteredAddress);
                }
                return address;
        }
        
        private void updateAddress(Address address, CustomAddress customAddress){
                address.setName(customAddress.getName());
                address.setLine1(customAddress.getLine1());
                address.setLine2(customAddress.getLine2());
                address.setCity(customAddress.getCity());
                address.setPinCode(customAddress.getPinCode());
                address.setState(customAddress.getState());
                addressRepository.persist(address);
        }
        
        private void updateRetailerShops(List<Shop> shops, Set<CustomShop> customShops, int retailerId, Address sameAsRetailerAddressValue) throws ProfitMandiBusinessException{
                if(shops.isEmpty()){
                        for(CustomShop customShop : customShops){
                                Shop shop = new Shop();
                                this.createOrUpdateShop(shop, customShop, retailerId, sameAsRetailerAddressValue);
                                shops.add(shop);
                        }
                }else{
                        for(Shop shop : shops){
                                for(CustomShop customShop : customShops){
                                        if(shop.getId() == customShop.getShopId()){
                                                this.createOrUpdateShop(shop, customShop, retailerId, sameAsRetailerAddressValue);
                                        }
                                }
                        }
                        for(CustomShop customShop : customShops){
                                if(customShop.getShopId() == 0){
                                        Shop shop = new Shop();
                                        this.createOrUpdateShop(shop, customShop, retailerId, sameAsRetailerAddressValue);
                                        shops.add(shop);
                                }
                        }
                }
        }
        
        private void createOrUpdateShop(Shop shop, CustomShop customShop, int retailerId, Address sameAsRetailerAddressValue) throws ProfitMandiBusinessException{
                shop.setRetailerId(retailerId);
                shop.setName(customShop.getName());
                if(customShop.getDocumentId() > 0){
                        shop.setDocumentId(customShop.getDocumentId());
                        documentRepository.markDocumentAsPersisted(customShop.getDocumentId());
                }
                if(shop.getAddressId() == null){
                        Address address = null;
                        if(customShop.isSameAsRetailerAddress()){
                                address = sameAsRetailerAddressValue;
                        }else{
                                //shop.setDocumentId(customShop.getDocumentId());
                                address = new Address();
                                this.updateAddress(address, customShop.getAddress());
                        }
                        shop.setAddressId(address.getId());
                        shop.setAddress(address);
                        shopRepository.persist(shop);
                        ShopAddress shopAddress = null;
                        try{
                                shopAddress = shopAddressRepository.selectByShopId(shop.getId());
                                shopAddress.setAddressId(address.getId());
                        }catch(ProfitMandiBusinessException profitMandiBusinessException){
                                shopAddress = new ShopAddress();
                                shopAddress.setAddressId(address.getId());
                                shopAddress.setShopId(shop.getId());
                        }
                        shopAddressRepository.persist(shopAddress);
                }else{
                        Address address = addressRepository.selectById(shop.getAddressId());
                        CustomAddress customAddress = customShop.getAddress();
                        if(address.getName().equals(customAddress.getName()) &&
                                address.getLine1().equals(customAddress.getLine1()) &&
                                address.getLine2().equals(customAddress.getLine2())     &&
                                address.getCity().equals(customAddress.getCity()) &&
                                address.getPinCode().equals(customAddress.getPinCode()) &&
                                address.getState().equals(customAddress.getState())){
                                this.updateAddress(address, customShop.getAddress());
                        }else{
                                address = new Address();
                                ShopAddress shopAddress = shopAddressRepository.selectByShopId(shop.getId());
                                this.updateAddress(address, customAddress);
                                shopAddress.setAddressId(address.getId());
                                shopAddressRepository.persist(shopAddress);
                        }
                        
                        shop.setAddress(address);
                        shopRepository.persist(shop);
                }
                
        }
        
        
        private void addAddress(List<Shop> shops){
                Set<Integer> shopIds = this.toShopIds(shops);
                if(shopIds.isEmpty()){
                        return;
                }
                List<ShopAddress> shopAddresses = shopAddressRepository.selectByShopIds(shopIds);
                Map<Integer, Address> addressIdAddressMap = this.toAddressIdAddressMap(shopAddresses);
                
                for(Shop shop : shops){
                        shop.setAddress(addressIdAddressMap.get(shop.getAddressId()));
                }
        }

        private Map<Integer, Address> toAddressIdAddressMap(List<ShopAddress> shopAddresses){
                Map<Integer, Address> addressIdAddressMap = new HashMap<>();
                List<Integer> addressIds = this.toAddressIds(shopAddresses);
                List<Address> addresses = addressRepository.selectByIds(addressIds);
                for(Address address : addresses){
                        addressIdAddressMap.put(address.getId(), address);
                }
                return addressIdAddressMap;
        }
        
        private List<Integer> toAddressIds(List<ShopAddress> shopAddresses){
                Function<ShopAddress, Integer> shopAddressToAddressIdFunction = new Function<ShopAddress, Integer>(){
                        @Override
                        public Integer apply(ShopAddress shopAddress) {
                                return shopAddress.getAddressId();
                        }
                };
                return shopAddresses.stream().map(shopAddressToAddressIdFunction).collect(Collectors.toList());
        }
        
        private Set<Integer> toShopIds(List<Shop> shops){
                Function<Shop, Integer> shopToAddressIdFunction = new Function<Shop, Integer>(){
                        @Override
                        public Integer apply(Shop shop) {
                                return shop.getId();
                        }
                };
                return shops.stream().map(shopToAddressIdFunction).collect(Collectors.toSet());
        }
        
        private String toString(List<UserRole> userRoles){
                Function<UserRole, String> userRoleToRoleNameFunction = new Function<UserRole, String>(){
                        public String apply(UserRole userRole) {
                                return userRole.getRoleType().toString();
                        };
                };
                Set<String> userRoleStrings = userRoles.stream().map(userRoleToRoleNameFunction).collect(Collectors.toSet());
                return String.join(", ", userRoleStrings);
        }

}