jp.co.ntt.atrs.domain.service.b0.TicketSharedServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for jp.co.ntt.atrs.domain.service.b0.TicketSharedServiceImpl.java

Source

/*
 * Copyright 2014-2018 NTT Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package jp.co.ntt.atrs.domain.service.b0;

import jp.co.ntt.atrs.domain.common.exception.AtrsBusinessException;
import jp.co.ntt.atrs.domain.common.masterdata.BoardingClassProvider;
import jp.co.ntt.atrs.domain.common.masterdata.PeakTimeProvider;
import jp.co.ntt.atrs.domain.common.util.DateTimeUtil;
import jp.co.ntt.atrs.domain.common.util.FareTypeUtil;
import jp.co.ntt.atrs.domain.common.util.FareUtil;
import jp.co.ntt.atrs.domain.model.BoardingClass;
import jp.co.ntt.atrs.domain.model.BoardingClassCd;
import jp.co.ntt.atrs.domain.model.FareType;
import jp.co.ntt.atrs.domain.model.FareTypeCd;
import jp.co.ntt.atrs.domain.model.Flight;
import jp.co.ntt.atrs.domain.model.PeakTime;
import jp.co.ntt.atrs.domain.model.Route;
import jp.co.ntt.atrs.domain.repository.flight.FlightRepository;
import jp.co.ntt.atrs.domain.service.b1.TicketSearchErrorCode;
import jp.co.ntt.atrs.domain.service.b2.TicketReserveErrorCode;

import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Interval;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.terasoluna.gfw.common.date.jodatime.JodaTimeDateFactory;
import org.terasoluna.gfw.common.exception.BusinessException;

import java.util.Date;
import java.util.List;

import javax.inject.Inject;

/**
 * ?
 * 
 * @author NTT 
 */
@Service
public class TicketSharedServiceImpl implements TicketSharedService {

    /**
     * ??(%)
     */
    private static final int MULTIPLICATION_RATIO_IN_NORMAL_TIME = 100;

    /**
     * ????????????()
     */
    @Value("${atrs.reserveIntervalTime}")
    private int reserveIntervalTime;

    /**
     * ??
     */
    @Value("${atrs.limitDay}")
    private int limitDay;

    /**
     * ??
     */
    @Inject
    JodaTimeDateFactory dateFactory;

    /**
     * ???
     */
    @Inject
    BoardingClassProvider boardingClassProvider;

    /**
     * ??
     */
    @Inject
    PeakTimeProvider peakTimeProvider;

    /**
     * ?
     */
    @Inject
    FlightRepository flightRepository;

    /**
     * {@inheritDoc}
     */
    @Override
    public LocalDate getSearchLimitDate() {
        // ?? = ??
        LocalDate sysDate = dateFactory.newDateTime().toLocalDate();
        LocalDate limitDate = sysDate.plusDays(limitDay);
        return limitDate;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void validateFlightList(List<Flight> flightList) throws BusinessException, InvalidFlightException {

        Assert.notEmpty(flightList);
        Assert.isTrue(flightList.size() <= 2);

        // ???
        Flight outwardFlight = flightList.get(0);
        Assert.notNull(outwardFlight);
        if (outwardFlight.getFlightMaster() == null) {
            throw new InvalidFlightException("flightMaster is null :" + outwardFlight);
        }
        if (!existsFlight(outwardFlight)) {
            throw new InvalidFlightException("flight not found :" + outwardFlight);
        }

        // 2??????
        if (flightList.size() == 2) {

            // 
            Flight homewardFlight = flightList.get(1);
            Assert.notNull(homewardFlight);
            if (homewardFlight.getFlightMaster() == null) {
                throw new InvalidFlightException("flightMaster is null :" + homewardFlight);
            }
            if (!existsFlight(homewardFlight)) {
                throw new InvalidFlightException("flight not found :" + homewardFlight);
            }

            // ??????????
            validateFlightDepartureDateForRoundTripFlight(outwardFlight, homewardFlight);

            // ??????
            validateFlightRouteForRoundTripFlight(outwardFlight, homewardFlight);

        }

        // ??????????
        validateFlightFareType(flightList);

    }

    /**
     * ???????
     * 
     * @param outwardFlight 
     * @param homewardFlight 
     * @throws BusinessException 
     */
    private void validateFlightDepartureDateForRoundTripFlight(Flight outwardFlight, Flight homewardFlight)
            throws BusinessException {

        // ???
        DateTime outwardArriveDateTime = DateTimeUtil.toDateTime(outwardFlight.getDepartureDate(),
                outwardFlight.getFlightMaster().getArrivalTime());

        // ?
        DateTime homewardDepartureDateTime = DateTimeUtil.toDateTime(homewardFlight.getDepartureDate(),
                homewardFlight.getFlightMaster().getDepartureTime());

        // ?????????
        // (????????
        // ?????)
        Duration flightDuration = new Duration(outwardArriveDateTime, homewardDepartureDateTime);
        if (flightDuration.getStandardMinutes() < reserveIntervalTime) {
            throw new AtrsBusinessException(TicketReserveErrorCode.E_AR_B2_2001);
        }
    }

    /**
     * ?????
     * 
     * @param outwardFlight 
     * @param homewardFlight 
     * @throws BusinessException 
     */
    private void validateFlightRouteForRoundTripFlight(Flight outwardFlight, Flight homewardFlight)
            throws BusinessException {

        // ???????
        Route outwardRoute = outwardFlight.getFlightMaster().getRoute();
        Route homewardRoute = homewardFlight.getFlightMaster().getRoute();
        if (!outwardRoute.getDepartureAirport().getCode().equals(homewardRoute.getArrivalAirport().getCode())
                || !outwardRoute.getArrivalAirport().getCode()
                        .equals(homewardRoute.getDepartureAirport().getCode())) {

            // ????????
            throw new InvalidFlightException("homeward route is not outward route reverse");
        }
    }

    /**
     * ?????
     * 
     * @param flightList 
     * @throws BusinessException 
     */
    private void validateFlightFareType(List<Flight> flightList) throws BusinessException {

        FareTypeCd owFareTypeCd;
        FareTypeCd hwFareTypeCd;

        switch (flightList.size()) {
        case 1:
            // ???

            // ?????????
            owFareTypeCd = flightList.get(0).getFareType().getFareTypeCd();
            if (!FareTypeUtil.isOneWay(owFareTypeCd)) {
                throw new InvalidFlightException("outward flight fareType is invalid :" + owFareTypeCd);
            }
            break;

        case 2:
            // ??

            // ????????????
            owFareTypeCd = flightList.get(0).getFareType().getFareTypeCd();
            if (!FareTypeUtil.isRoundTrip(owFareTypeCd)) {
                throw new InvalidFlightException("outward flight fareType is invalid :" + owFareTypeCd);
            }

            // ??????????????
            hwFareTypeCd = flightList.get(1).getFareType().getFareTypeCd();
            if (!FareTypeUtil.isRoundTrip(hwFareTypeCd)) {
                throw new InvalidFlightException("homeward flight fareType is invalid :" + hwFareTypeCd);
            }
            break;

        default:
            throw new InvalidFlightException("flightList size must be between 1 and 2");
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void validateDepatureDate(Date departureDate) throws BusinessException {
        Assert.notNull(departureDate);

        DateTime sysDateMidnight = dateFactory.newDateTime().withTimeAtStartOfDay();
        DateTime limitDateMidnight = getSearchLimitDate().toDateTimeAtStartOfDay();

        // ????????????
        Interval reservationAvailableInterval = new Interval(sysDateMidnight, limitDateMidnight.plusDays(1));
        if (!reservationAvailableInterval.contains(departureDate.getTime())) {
            throw new AtrsBusinessException(TicketSearchErrorCode.E_AR_B1_2001);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isAvailableFareType(FareType fareType, Date depDate) {
        Assert.notNull(fareType);
        Assert.notNull(depDate);

        DateTime depDateMidnight = new DateTime(depDate).withTimeAtStartOfDay();

        // 
        DateTime rsrvAvailableStartDate = depDateMidnight.minusDays(fareType.getRsrvAvailableStartDayNum());

        // 
        DateTime rsrvAvailableEndDate = depDateMidnight.minusDays(fareType.getRsrvAvailableEndDayNum());

        // ?
        DateTime sysDateMidnight = dateFactory.newDateTime().withTimeAtStartOfDay();

        // ?????????
        return new Interval(rsrvAvailableStartDate, rsrvAvailableEndDate.plusDays(1)).contains(sysDateMidnight);
    }

    /**
     * 
     * {@inheritDoc}
     */
    @Override
    public int calculateBasicFare(int basicFareOfRoute, BoardingClassCd boardingClassCd, Date depDate) {
        Assert.isTrue(basicFareOfRoute >= 0);
        Assert.notNull(boardingClassCd);
        Assert.notNull(depDate);

        // ????
        BoardingClass boardingClass = boardingClassProvider.getBoardingClass(boardingClassCd);
        int boardingClassFare = boardingClass.getExtraCharge();

        // ?????
        int multiplicationRatio = getMultiplicationRatio(depDate);

        // ??
        int basicFare = (int) ((basicFareOfRoute + boardingClassFare) * (multiplicationRatio * 0.01));

        return basicFare;
    }

    /**
     * ?????
     * 
     * @param departureDate ?
     * @return ???
     */
    private int getMultiplicationRatio(Date departureDate) {

        // ??
        PeakTime peakTime = peakTimeProvider.getPeakTime(departureDate);

        // ???????
        if (peakTime != null) {
            return peakTime.getMultiplicationRatio();
        }

        // ???????????
        return MULTIPLICATION_RATIO_IN_NORMAL_TIME;
    }

    /**
     * 
     * {@inheritDoc}
     */
    @Override
    public int calculateFare(int basicFare, int discountRate) {
        Assert.isTrue(basicFare >= 0);
        Assert.isTrue(discountRate >= 0);
        Assert.isTrue(discountRate <= 100);

        // ??
        int fare = (int) (basicFare * (1 - (discountRate * 0.01)));

        // ??100???
        return FareUtil.ceilFare(fare);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean existsFlight(Flight flight) {
        Assert.notNull(flight);
        Assert.notNull(flight.getFlightMaster());
        return flightRepository.exists(flight.getDepartureDate(), flight.getFlightMaster().getFlightName(),
                flight.getBoardingClass(), flight.getFareType());
    }
}