diff --git a/src/api/company-service.test.ts b/src/api/company-service.test.ts index d6477ff..e5535ad 100644 --- a/src/api/company-service.test.ts +++ b/src/api/company-service.test.ts @@ -70,3 +70,28 @@ test('isOndemandDailyApiPeriod', () => { expect(service.isOndemandDailyApiPeriod(DateParam.from(new Date()))).toBe(false) expect(service.isOndemandDailyApiPeriod(DateParam.from('latest'))).toBe(false) }) + +test('isOutOfQuarterApiRange', () => { + const client = new CachingBuffettCodeApiClientV3('token') + const service = new CompanyService('2371', client) + + expect(service.isOutOfQuarterApiRange(new YearQuarter(2001, 3))).toBe(true) + expect(service.isOutOfQuarterApiRange(new YearQuarter(2001, 4))).toBe(false) + expect(service.isOutOfQuarterApiRange(new YearQuarterParam(LY, 3))).toBe(false) + expect(service.isOutOfQuarterApiRange(new YearQuarterParam(2001, LQ))).toBe(true) + expect(service.isOutOfQuarterApiRange(new YearQuarterParam(LY, LQ))).toBe(false) + expect(service.isOutOfQuarterApiRange(new YearQuarterParam(new LyWithOffset(-20), 3))).toBe(true) + expect(service.isOutOfQuarterApiRange(new YearQuarterParam(new LyWithOffset(-20), 4))).toBe(false) + expect(service.isOutOfQuarterApiRange(new YearQuarterParam(new LyWithOffset(-20), LQ))).toBe(true) +}) + +test('isOutOfDailyApiRange', () => { + const client = new CachingBuffettCodeApiClientV3('token') + const service = new CompanyService('2371', client) + + expect(service.isOutOfDailyApiRange(DateParam.from(new Date('2003-10-09')))).toBe(true) + expect(service.isOutOfDailyApiRange(DateParam.from(new Date('2003-10-10')))).toBe(false) + expect(service.isOutOfDailyApiRange(DateParam.from(new Date()))).toBe(false) + expect(service.isOutOfDailyApiRange(DateParam.from(new Date('2999-12-31')))).toBe(true) + expect(service.isOutOfDailyApiRange(DateParam.from('latest'))).toBe(false) +}) diff --git a/src/api/company-service.ts b/src/api/company-service.ts index 8898859..8a2cf21 100644 --- a/src/api/company-service.ts +++ b/src/api/company-service.ts @@ -57,4 +57,34 @@ export class CompanyService { return date.toDate().valueOf() < fixedTierOldestDate.valueOf() } + + public isOutOfQuarterApiRange(_period: YearQuarter | YearQuarterParam): boolean { + let period: YearQuarter + if (_period instanceof YearQuarterParam) { + period = this.convertYearQuarterParamToYearQuarter(_period) + } else { + period = _period + } + + const oldestPeriod = new YearQuarter( + this.company.data['oldest_fiscal_year'], + this.company.data['oldest_fiscal_quarter'] + ) + + return !period.isAfterOrEqual(oldestPeriod) + } + + public isOutOfDailyApiRange(dateParam: DateParam): boolean { + if (dateParam.isLatest()) { + return false + } + + const date = dateParam.toDate() + if (date.valueOf() > new Date().valueOf()) { + return true + } + + const oldestDate = new Date(this.company.data['oldest_date']) + return date.valueOf() < oldestDate.valueOf() + } } diff --git a/src/custom-functions/error.ts b/src/custom-functions/error.ts index e97b712..f532e94 100644 --- a/src/custom-functions/error.ts +++ b/src/custom-functions/error.ts @@ -33,3 +33,12 @@ export class UnsupportedTickerError implements Error { this.message = message } } + +export class UnsupportedRangeError implements Error { + public name = 'UnsupportedRangeError' + public message: string + + constructor(message = '') { + this.message = message + } +} diff --git a/src/custom-functions/v3/bcode-daily.ts b/src/custom-functions/v3/bcode-daily.ts index 27793d0..bd63138 100644 --- a/src/custom-functions/v3/bcode-daily.ts +++ b/src/custom-functions/v3/bcode-daily.ts @@ -1,6 +1,11 @@ import { CompanyService } from '~/api/company-service' import { BuffettCodeApiClientV3 } from '~/api/v3/client' -import { ApiResponseError, OndemandApiNotEnabledError, PropertyNotFoundError } from '~/custom-functions/error' +import { + ApiResponseError, + OndemandApiNotEnabledError, + PropertyNotFoundError, + UnsupportedRangeError +} from '~/custom-functions/error' import { BcodeResult } from '~/custom-functions/v3/bcode-result' import { Daily } from '~/entities/v3/daily' import { DateParam } from '~/fiscal-periods/date-param' @@ -15,6 +20,10 @@ export function bcodeDaily( ): BcodeResult { const companyService = new CompanyService(ticker, client) + if (companyService.isOutOfDailyApiRange(date)) { + throw new UnsupportedRangeError() + } + let daily: Daily if (forceOndemandApiEnabled || companyService.isOndemandDailyApiPeriod(date)) { if (!ondemandApiEnabled) { diff --git a/src/custom-functions/v3/bcode-quarter.ts b/src/custom-functions/v3/bcode-quarter.ts index ec73abe..6bde18a 100644 --- a/src/custom-functions/v3/bcode-quarter.ts +++ b/src/custom-functions/v3/bcode-quarter.ts @@ -1,6 +1,11 @@ import { CompanyService } from '~/api/company-service' import { BuffettCodeApiClientV3 } from '~/api/v3/client' -import { ApiResponseError, OndemandApiNotEnabledError, PropertyNotFoundError } from '~/custom-functions/error' +import { + ApiResponseError, + OndemandApiNotEnabledError, + PropertyNotFoundError, + UnsupportedRangeError +} from '~/custom-functions/error' import { BcodeResult } from '~/custom-functions/v3/bcode-result' import { Quarter } from '~/entities/v3/quarter' import { YearQuarterParam } from '~/fiscal-periods/year-quarter-param' @@ -15,6 +20,10 @@ export function bcodeQuarter( ): BcodeResult { const companyService = new CompanyService(ticker, client) + if (companyService.isOutOfQuarterApiRange(period)) { + throw new UnsupportedRangeError() + } + let quarter: Quarter if (forceOndemandApiEnabled || companyService.isOndemandQuarterApiPeriod(period)) { if (!ondemandApiEnabled) { diff --git a/src/services/error-handler.ts b/src/services/error-handler.ts index 20a0eae..1dc12c6 100644 --- a/src/services/error-handler.ts +++ b/src/services/error-handler.ts @@ -3,7 +3,8 @@ import { ApiResponseError, OndemandApiNotEnabledError, PropertyNotFoundError, - UnsupportedTickerError + UnsupportedTickerError, + UnsupportedRangeError } from '~/custom-functions/error' import { InvalidLYLQError, InvalidYearError, InvalidQuarterError } from '~/fiscal-periods/error' @@ -25,6 +26,8 @@ export class ErrorHandler { throw new Error(`<<無効な四半期が指定されています>>`) } else if (e instanceof PropertyNotFoundError) { throw new Error(`<<サポートされていない科目です>>`) + } else if (e instanceof UnsupportedRangeError) { + throw new Error(`<<サポートされていない範囲が指定されています>>`) } else { console.error('未定義のエラー', e.name, e.message) throw new Error(