Skip to content

Commit

Permalink
fix: fix calc period limits for middle months
Browse files Browse the repository at this point in the history
  • Loading branch information
BATMAH69 committed Aug 21, 2024
1 parent ba9f311 commit 01c1c45
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 37 deletions.
87 changes: 79 additions & 8 deletions modules/motions/hooks/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ describe('calcPeriodData', () => {
const periodData = {
alreadySpentAmount: '500',
spendableBalanceInPeriod: '500',
periodStartTimestamp: moment().unix() - EIGTH_HOURS_SECONDS,
periodEndTimestamp: moment().unix() + EIGTH_HOURS_SECONDS * 2,
periodStartTimestamp: moment().startOf('month').unix(),
periodEndTimestamp: moment()
.startOf('month')
.add(limits.periodDurationMonths, 'M')
.startOf('month')
.unix(),
}
const isPending = false

Expand Down Expand Up @@ -49,8 +53,12 @@ describe('calcPeriodData', () => {
const periodData = {
alreadySpentAmount: '500',
spendableBalanceInPeriod: '500',
periodStartTimestamp: moment().unix() - EIGTH_HOURS_SECONDS * 10,
periodEndTimestamp: moment().unix() - EIGTH_HOURS_SECONDS * 2,
periodStartTimestamp: moment()
.startOf('month')
.subtract(limits.periodDurationMonths, 'M')
.startOf('month')
.unix(),
periodEndTimestamp: moment().startOf('month').unix(),
}
const isPending = false

Expand Down Expand Up @@ -266,13 +274,17 @@ describe('calcPeriodData', () => {
const motionDuration = BigNumber.from(MONTH_HOURS_SECONDS) // seconds
const limits = {
limit: '1000',
periodDurationMonths: 2, // month
periodDurationMonths: 3, // month
}
const periodData = {
alreadySpentAmount: '500',
spendableBalanceInPeriod: '500',
periodStartTimestamp: moment().subtract(6, 'month').unix(),
periodEndTimestamp: moment().subtract(4, 'month').unix(),
periodStartTimestamp: moment()
.subtract(3 * limits.periodDurationMonths, 'M')
.unix(),
periodEndTimestamp: moment()
.subtract(2 * limits.periodDurationMonths, 'M')
.unix(),
}
const isPending = false

Expand All @@ -285,7 +297,7 @@ describe('calcPeriodData', () => {

const newStartTime = moment
.unix(periodData.periodStartTimestamp)
.add(6, 'M')
.add(3 * limits.periodDurationMonths, 'M')
.startOf('month')
const newEndTime = moment(newStartTime)
.add(limits.periodDurationMonths, 'M')
Expand All @@ -306,4 +318,63 @@ describe('calcPeriodData', () => {
isEndInNextPeriod: false,
})
})

it('Motion start in next N period and end in current, in the middle of period', () => {
const motionDuration = BigNumber.from(259200)
const limits = {
limit: '3000000.0',
periodDurationMonths: 3,
}
// second month of period 2024-08-21
const currentDateMock = moment.unix(1724258258)

jest
.spyOn(Date, 'now')
.mockImplementation(() =>
new Date(currentDateMock.toISOString()).getTime(),
)

const periodStartTimestamp = moment()
.subtract(1 + 2 * limits.periodDurationMonths, 'month')
.startOf('month')
.unix()
const periodEndTimestamp = moment()
.subtract(1 + limits.periodDurationMonths, 'month')
.startOf('month')
.unix()

const periodData = {
alreadySpentAmount: '700000.0',
spendableBalanceInPeriod: '2300000.0',
periodStartTimestamp: periodStartTimestamp,
periodEndTimestamp: periodEndTimestamp,
}

const result = calcPeriodData({
motionDuration,
limits,
periodData,
})

const periodStartTimestampNew = moment()
.subtract(1, 'month')
.startOf('month')
.unix()
const periodEndTimestampNew = moment()
.add(2, 'month')
.startOf('month')
.unix()

expect(result).toEqual({
limits,
periodData: {
alreadySpentAmount: '0',
spendableBalanceInPeriod: limits.limit,
periodStartTimestamp: periodStartTimestampNew,
periodEndTimestamp: periodEndTimestampNew,
},
motionDuration: motionDuration.toNumber() / 60 / 60, // hours
isEndInNextPeriod: false,
})
})
})
55 changes: 26 additions & 29 deletions modules/motions/hooks/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,49 +36,46 @@ export const calcPeriodData = ({
}) => {
let currentPeriodData = { ...periodData }

const dateOfEndMotionPeriod = moment.unix(periodData.periodEndTimestamp)
const dateOfEndMotionPeriod = moment.unix(
currentPeriodData.periodEndTimestamp,
)
const dateOfStartMotionPeriod = moment.unix(
currentPeriodData.periodStartTimestamp,
)
const isStartInNextPeriod = moment().isAfter(dateOfEndMotionPeriod)
if (isStartInNextPeriod) {
// will be more than 2
const diffMonthCount = moment()
.startOf('month')
.diff(dateOfStartMotionPeriod.startOf('month'), 'months')
// for period 3 => 3,4,5 = 1, 6,7,8 = 2, ...
let periodRatio = Math.floor(diffMonthCount / limits.periodDurationMonths)

const dateOfEndMotion = moment().add(motionDuration.toNumber(), 'seconds')
const periodEnd = isStartInNextPeriod
? moment()
.startOf('month')
.add(limits.periodDurationMonths, 'M')
.startOf('month')
: moment.unix(periodData.periodEndTimestamp)
const newPeriodStartTime = dateOfStartMotionPeriod.add(
limits.periodDurationMonths * periodRatio,
'M',
)

const isEndInNextPeriod = dateOfEndMotion.isAfter(periodEnd)

if (isEndInNextPeriod && !isPending) {
currentPeriodData = getNewPeriod({
periodLimit: limits.limit,
periodDurationMonths: limits.periodDurationMonths,
newPeriodStartTime: moment
.unix(periodData.periodStartTimestamp)
.add(limits.periodDurationMonths, 'M')
.startOf('month'),
newPeriodStartTime,
})
}

if (isStartInNextPeriod) {
const diffMonthCount = moment()
.startOf('month')
.diff(dateOfEndMotionPeriod.startOf('month'), 'months')
let periodRatio = Math.ceil(diffMonthCount / limits.periodDurationMonths)
if (isEndInNextPeriod) periodRatio += 1
const dateOfEndMotion = moment().add(motionDuration.toNumber(), 'seconds')
const periodEnd = moment.unix(currentPeriodData.periodEndTimestamp)

const newPeriodStartTime =
diffMonthCount >= limits.periodDurationMonths
? dateOfEndMotionPeriod.add(
limits.periodDurationMonths * periodRatio,
'M',
)
: dateOfEndMotionPeriod
const isEndInNextPeriod = dateOfEndMotion.isAfter(periodEnd)

if (isEndInNextPeriod && !isPending) {
currentPeriodData = getNewPeriod({
periodLimit: limits.limit,
periodDurationMonths: limits.periodDurationMonths,
newPeriodStartTime,
newPeriodStartTime: moment
.unix(currentPeriodData.periodStartTimestamp)
.add(limits.periodDurationMonths, 'M')
.startOf('month'),
})
}

Expand Down

0 comments on commit 01c1c45

Please sign in to comment.