Subversion Repositories SmartDukaan

Rev

Blame | Last modification | View Log | RSS feed

package com.spice.profitmandi.service.tag;

import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.dao.entity.catalog.TagListing;
import com.spice.profitmandi.dao.entity.catalog.TagListingPriceLog;
import com.spice.profitmandi.dao.entity.inventory.VendorCatalogPricingLog;
import com.spice.profitmandi.dao.enumuration.inventory.VendorCatalogPricingStatus;
import com.spice.profitmandi.dao.model.VendorCatalogPricingModel;
import com.spice.profitmandi.dao.repository.catalog.TagListingPriceLogRepository;
import com.spice.profitmandi.dao.repository.catalog.TagListingRepository;
import com.spice.profitmandi.service.inventory.VendorCatalogPricingService;
import com.spice.profitmandi.web.config.AppConfig;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Local-database integration tests (rolled back) for the tag listing price log, the reference TP and the internal
 * supplier pricing guard.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {AppConfig.class})
@Transactional
public class TagListingPricingTest {

    @Autowired private TagListingPriceService tagListingPriceService;
    @Autowired private TagListingPriceLogRepository tagListingPriceLogRepository;
    @Autowired private TagListingRepository tagListingRepository;
    @Autowired private VendorCatalogPricingService vendorCatalogPricingService;
    @Autowired private SessionFactory sessionFactory;

    @Test
    @Rollback
    public void priceChangeIsLoggedWithOldAndNewValues() throws Exception {
        TagListing listing = tagListingRepository.selectByItemId(this.anyListedItemId());
        float oldDp = listing.getSellingPrice(), oldMop = listing.getMop(), oldMrp = listing.getMrp();

        TagListingPriceLog log = tagListingPriceService.setPrices(listing, oldDp + 100, oldMop + 100, null,
                TagListingPriceLog.SOURCE_ADD_PRICING, 42);
        this.session().flush();

        Assert.assertNotNull(log);
        Assert.assertEquals(oldDp + 100, listing.getSellingPrice(), 0.001f);
        Assert.assertEquals(oldMop + 100, listing.getMop(), 0.001f);
        Assert.assertEquals("null MRP leaves it unchanged", oldMrp, listing.getMrp(), 0.001f);

        List<TagListingPriceLog> logs = tagListingPriceLogRepository.selectByItemId(listing.getItemId());
        TagListingPriceLog saved = logs.get(0);
        Assert.assertEquals(oldDp, saved.getOldSellingPrice(), 0.001f);
        Assert.assertEquals(oldDp + 100, saved.getNewSellingPrice(), 0.001f);
        Assert.assertEquals(oldMop, saved.getOldMop(), 0.001f);
        Assert.assertEquals(oldMop + 100, saved.getNewMop(), 0.001f);
        Assert.assertEquals(oldMrp, saved.getOldMrp(), 0.001f);
        Assert.assertEquals(oldMrp, saved.getNewMrp(), 0.001f);
        Assert.assertEquals(TagListingPriceLog.SOURCE_ADD_PRICING, saved.getSource());
        Assert.assertEquals(Integer.valueOf(42), saved.getChangedBy());
        Assert.assertEquals(listing.getTagId(), saved.getTagId());
    }

    @Test
    @Rollback
    public void unchangedPricesAreNotLogged() throws Exception {
        TagListing listing = tagListingRepository.selectByItemId(this.anyListedItemId());
        int before = tagListingPriceLogRepository.selectByItemId(listing.getItemId()).size();

        TagListingPriceLog log = tagListingPriceService.setPrices(listing, listing.getSellingPrice(), listing.getMop(), listing.getMrp(),
                TagListingPriceLog.SOURCE_ADD_PRICING, 42);
        this.session().flush();

        Assert.assertNull(log);
        Assert.assertEquals(before, tagListingPriceLogRepository.selectByItemId(listing.getItemId()).size());
    }

    @Test
    @Rollback
    public void newListingIsLoggedWithoutOldValues() throws Exception {
        Number itemId = (Number) this.session().createNativeQuery(
                "SELECT i.id FROM catalog.item i WHERE NOT EXISTS (SELECT 1 FROM catalog.tag_listing tl WHERE tl.item_id = i.id)" +
                " ORDER BY i.id DESC LIMIT 1").getSingleResult();
        TagListing listing = new TagListing();
        listing.setItemId(itemId.intValue());
        listing.setTagId(4);
        listing.setActive(true);

        TagListingPriceLog log = tagListingPriceService.setPrices(listing, 1000, 1100, 1200f, TagListingPriceLog.SOURCE_ADD_PRICING, null);
        tagListingRepository.persist(listing);
        this.session().flush();

        Assert.assertNotNull(log);
        Assert.assertNull(log.getOldSellingPrice());
        Assert.assertNull(log.getOldMop());
        Assert.assertNull(log.getOldMrp());
        Assert.assertEquals(1200f, log.getNewMrp(), 0.001f);
        Assert.assertNull(log.getChangedBy());
    }

    @Test
    @Rollback
    public void referenceTpIsLatestApprovedExternalPrice() throws Exception {
        @SuppressWarnings("unchecked")
        List<Number> catalogIds = this.session().createNativeQuery(
                "SELECT DISTINCT l.catalog_id FROM inventory.vendor_catalog_pricing_log l JOIN warehouse.supplier s ON s.id = l.vendor_id AND s.internal = 0" +
                " WHERE l.status = 'APPROVED' ORDER BY l.catalog_id DESC LIMIT 50").getResultList();
        Assert.assertFalse(catalogIds.isEmpty());

        Map<Integer, Float> batch = vendorCatalogPricingService.getReferenceTransferPrices(
                catalogIds.stream().map(Number::intValue).collect(Collectors.toList()));
        for (Number catalogId : catalogIds) {
            Number expected = (Number) this.session().createNativeQuery(
                    "SELECT l.transfer_price FROM inventory.vendor_catalog_pricing_log l JOIN warehouse.supplier s ON s.id = l.vendor_id AND s.internal = 0" +
                    " WHERE l.catalog_id = :c AND l.status = 'APPROVED' ORDER BY l.effected_on DESC, l.id DESC LIMIT 1")
                    .setParameter("c", catalogId.intValue()).getSingleResult();
            Assert.assertEquals("batch, catalog " + catalogId, expected.floatValue(), batch.get(catalogId.intValue()), 0.001f);
            Assert.assertEquals("single, catalog " + catalogId, expected.floatValue(),
                    vendorCatalogPricingService.getReferenceTransferPrice(catalogId.intValue()), 0.001f);
        }
        Assert.assertNull(vendorCatalogPricingService.getReferenceTransferPrice(-1));
    }

    @Test(expected = ProfitMandiBusinessException.class)
    @Rollback
    public void internalSupplierPricingRequestIsRejected() throws Exception {
        VendorCatalogPricingModel model = new VendorCatalogPricingModel();
        model.setVendorId(this.internalSupplierId());
        model.setCatalogId(this.anyCatalogId());
        model.setTp(100);
        model.setDp(110);
        model.setMop(120);
        model.setEffectedOn(LocalDate.now());
        model.setAuthId(1);
        vendorCatalogPricingService.createVendorCatalogPricingLog(model);
    }

    @Test
    @Rollback
    public void internalSupplierApprovalWritesNoPricing() throws Exception {
        int vendorId = this.internalSupplierId();
        int catalogId = this.anyCatalogId();
        VendorCatalogPricingLog log = new VendorCatalogPricingLog();
        log.setVendorId(vendorId);
        log.setCatalogId(catalogId);
        log.setTransferPrice(100);
        log.setDealerPrice(110);
        log.setMop(120);
        log.setEffectedOn(LocalDate.now());
        log.setStatus(VendorCatalogPricingStatus.PENDING);
        log.setCreatedTimestamp(LocalDateTime.now());
        log.setUpdatedTimestamp(LocalDateTime.now());
        this.session().persist(log);

        vendorCatalogPricingService.approveVendorCatalogPricingLog(log, 1);
        this.session().flush();

        Assert.assertEquals(VendorCatalogPricingStatus.REJECTED, log.getStatus());
        Number rows = (Number) this.session().createNativeQuery(
                "SELECT COUNT(*) FROM inventory.vendor_catalog_pricing WHERE vendor_id = :v AND catalog_id = :c AND effected_on = CURDATE()")
                .setParameter("v", vendorId).setParameter("c", catalogId).getSingleResult();
        Assert.assertEquals(0, rows.intValue());
    }

    private int anyListedItemId() {
        return ((Number) this.session().createNativeQuery(
                "SELECT item_id FROM catalog.tag_listing WHERE tag_id = 4 AND active = 1 AND selling_price > 0 ORDER BY id DESC LIMIT 1")
                .getSingleResult()).intValue();
    }

    private int internalSupplierId() {
        return ((Number) this.session().createNativeQuery("SELECT id FROM warehouse.supplier WHERE internal = 1 ORDER BY id LIMIT 1")
                .getSingleResult()).intValue();
    }

    private int anyCatalogId() {
        return ((Number) this.session().createNativeQuery("SELECT catalog_item_id FROM catalog.item ORDER BY id DESC LIMIT 1")
                .getSingleResult()).intValue();
    }

    private Session session() {
        return sessionFactory.getCurrentSession();
    }
}