Skip to content

Commit

Permalink
feat(api): [createBudget] add calc period start/end (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
duongdev committed Jun 8, 2024
1 parent c778017 commit 2ed3f38
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 3 deletions.
6 changes: 6 additions & 0 deletions apps/api/lib/dayjs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import dayjsExtended from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'

dayjsExtended.extend(quarterOfYear)

export { dayjsExtended }
1 change: 1 addition & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@hono/clerk-auth": "^2.0.0",
"@hono/zod-validator": "^0.2.2",
"@prisma/client": "^5.15.0",
"dayjs": "^1.11.11",
"hono": "^4.4.3",
"zod": "^3.23.8"
},
Expand Down
57 changes: 54 additions & 3 deletions apps/api/v1/services/budget.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { dayjsExtended } from '@/lib/dayjs'
import prisma from '@/lib/prisma'
import { type Budget, BudgetUserPermission, type User } from '@prisma/client'
import {
type Budget,
BudgetPeriodType,
BudgetUserPermission,
type User,
} from '@prisma/client'
import type { CreateBudget, UpdateBudget } from '../validation'
import { inviteUserToBudget } from './budget-invitation.service'

Expand Down Expand Up @@ -89,6 +95,46 @@ export async function findBudget({ budgetId }: { budgetId: string }) {
})
}

/**
* Given an anchor date and period type,
* calculate the start and end dates of the budget period.
* Example:
* - anchorDate: 2022-01-15
* - periodType: MONTHLY
* - startDate: 2022-01-01
* - endDate: 2022-01-31
*/
function calculateBudgetPeriodStartEndDates({
anchorDate,
type,
}: {
anchorDate: Date
type: BudgetPeriodType
}) {
switch (type) {
case BudgetPeriodType.MONTHLY:
return {
startDate: dayjsExtended(anchorDate).startOf('month').toDate(),
endDate: dayjsExtended(anchorDate).endOf('month').toDate(),
}
case BudgetPeriodType.QUARTERLY:
return {
startDate: dayjsExtended(anchorDate).startOf('quarter').toDate(),
endDate: dayjsExtended(anchorDate).endOf('quarter').toDate(),
}
case BudgetPeriodType.YEARLY:
return {
startDate: dayjsExtended(anchorDate).startOf('year').toDate(),
endDate: dayjsExtended(anchorDate).endOf('year').toDate(),
}
default:
return {
startDate: null,
endDate: null,
}
}
}

export async function createBudget({
user,
data,
Expand All @@ -105,6 +151,11 @@ export async function createBudget({
inviteeEmails = [],
} = data

const periodConfig = calculateBudgetPeriodStartEndDates({
anchorDate: new Date(),
type: period.type,
})

const budget = await prisma.budget.create({
data: {
name,
Expand All @@ -115,8 +166,8 @@ export async function createBudget({
create: {
type: period.type,
amount: period.amount,
startDate: period.startDate,
endDate: period.endDate,
startDate: period.endDate ?? periodConfig.startDate,
endDate: period.endDate ?? periodConfig.endDate,
},
},
budgetUsers: {
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2ed3f38

Please sign in to comment.