Skip to content

Commit a3e6d4f

Browse files
chore: wip
1 parent ae5764a commit a3e6d4f

File tree

4 files changed

+315
-0
lines changed

4 files changed

+315
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { db } from '@stacksjs/database'
2+
import { fetchById } from './fetch'
3+
4+
/**
5+
* Delete a gift card by ID
6+
* @param id The ID of the gift card to delete
7+
* @returns A boolean indicating whether the deletion was successful
8+
*/
9+
export async function remove(id: number): Promise<boolean> {
10+
// First check if the gift card exists
11+
const giftCard = await fetchById(id)
12+
13+
if (!giftCard) {
14+
throw new Error(`Gift card with ID ${id} not found`)
15+
}
16+
17+
// Delete the gift card
18+
const result = await db
19+
.deleteFrom('gift_cards')
20+
.where('id', '=', id)
21+
.executeTakeFirst()
22+
23+
return !!result
24+
}
25+
26+
/**
27+
* Bulk delete multiple gift cards
28+
* @param ids Array of gift card IDs to delete
29+
* @returns Number of gift cards successfully deleted
30+
*/
31+
export async function bulkRemove(ids: number[]): Promise<number> {
32+
if (!ids.length) {
33+
return 0
34+
}
35+
36+
// Delete all gift cards in the array
37+
const result = await db
38+
.deleteFrom('gift_cards')
39+
.where('id', 'in', ids)
40+
.executeTakeFirst()
41+
42+
return Number(result?.numDeletedRows) || 0
43+
}
44+
45+
/**
46+
* Delete expired gift cards
47+
* @returns Number of gift cards deleted
48+
*/
49+
export async function removeExpired(): Promise<number> {
50+
const currentDate = new Date().toISOString().split('T')[0]
51+
52+
// Delete expired gift cards
53+
const result = await db
54+
.deleteFrom('gift_cards')
55+
.where('expiry_date', '<', currentDate)
56+
.executeTakeFirst()
57+
58+
return Number(result?.numDeletedRows) || 0
59+
}
60+
61+
/**
62+
* Deactivate a gift card (set is_active to false)
63+
* @param id The ID of the gift card to deactivate
64+
* @returns A boolean indicating whether the deactivation was successful
65+
*/
66+
export async function deactivate(id: number): Promise<boolean> {
67+
// First check if the gift card exists
68+
const giftCard = await fetchById(id)
69+
70+
if (!giftCard) {
71+
throw new Error(`Gift card with ID ${id} not found`)
72+
}
73+
74+
// Update the gift card status
75+
const result = await db
76+
.updateTable('gift_cards')
77+
.set({
78+
is_active: false,
79+
status: 'DEACTIVATED',
80+
updated_at: new Date(),
81+
})
82+
.where('id', '=', id)
83+
.executeTakeFirst()
84+
85+
return !!result
86+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Export types that might be needed elsewhere
2+
export type {
3+
GiftCardJsonResponse,
4+
GiftCardsTable,
5+
NewGiftCard,
6+
} from '../../../../orm/src/models/GiftCard'
7+
8+
// Export functions from delete.ts
9+
export {
10+
bulkRemove,
11+
deactivate,
12+
remove,
13+
removeExpired,
14+
} from './destroy'
15+
16+
// Export functions from fetch.ts
17+
export {
18+
checkBalance,
19+
fetchActive,
20+
fetchByCode,
21+
fetchById,
22+
fetchPaginated,
23+
fetchStats,
24+
} from './fetch'
25+
26+
// Export functions from store.ts
27+
export {
28+
store,
29+
} from './store'
30+
31+
// Export functions from update.ts
32+
export {
33+
update,
34+
updateBalance,
35+
} from './update'
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { GiftCardRequestType } from '@stacksjs/orm'
2+
import type { GiftCardJsonResponse, NewGiftCard } from '../../../../orm/src/models/GiftCard'
3+
import { db } from '@stacksjs/database'
4+
5+
/**
6+
* Create a new gift card
7+
*
8+
* @param request The gift card data to store
9+
* @returns The newly created gift card record
10+
*/
11+
export async function store(request: GiftCardRequestType): Promise<GiftCardJsonResponse | undefined> {
12+
await request.validate()
13+
14+
const giftCardData: NewGiftCard = {
15+
code: request.get<string>('code'),
16+
initial_balance: request.get<number>('initial_balance'),
17+
current_balance: request.get<number>('initial_balance'), // Initially set to same as initial balance
18+
currency: request.get<string>('currency'),
19+
status: request.get<string>('status') || 'ACTIVE',
20+
user_id: request.get<number>('user_id'),
21+
purchaser_id: request.get<string>('purchaser_id'),
22+
recipient_email: request.get<string>('recipient_email'),
23+
recipient_name: request.get<string>('recipient_name'),
24+
personal_message: request.get<string>('personal_message'),
25+
is_digital: request.get<boolean>('is_digital'),
26+
is_reloadable: request.get<boolean>('is_reloadable'),
27+
is_active: request.get<boolean>('is_active') ?? true,
28+
expiry_date: request.get<string>('expiry_date'),
29+
template_id: request.get<string>('template_id'),
30+
}
31+
32+
try {
33+
// Insert the gift card record
34+
const createdGiftCard = await db
35+
.insertInto('gift_cards')
36+
.values(giftCardData)
37+
.executeTakeFirst()
38+
39+
// If insert was successful, retrieve the newly created gift card
40+
if (createdGiftCard.insertId) {
41+
const giftCard = await db
42+
.selectFrom('gift_cards')
43+
.where('id', '=', Number(createdGiftCard.insertId))
44+
.selectAll()
45+
.executeTakeFirst()
46+
47+
return giftCard
48+
}
49+
50+
return undefined
51+
}
52+
catch (error) {
53+
if (error instanceof Error) {
54+
if (error.message.includes('Duplicate entry') && error.message.includes('code')) {
55+
throw new Error('A gift card with this code already exists')
56+
}
57+
58+
throw new Error(`Failed to create gift card: ${error.message}`)
59+
}
60+
61+
throw error
62+
}
63+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import type { GiftCardRequestType } from '@stacksjs/orm'
2+
import type { GiftCardJsonResponse } from '../../../../orm/src/models/GiftCard'
3+
import { db } from '@stacksjs/database'
4+
import { fetchById } from './fetch'
5+
6+
/**
7+
* Update a gift card by ID
8+
*
9+
* @param id The ID of the gift card to update
10+
* @param request The updated gift card data
11+
* @returns The updated gift card record
12+
*/
13+
export async function update(id: number, request: GiftCardRequestType): Promise<GiftCardJsonResponse | undefined> {
14+
// Validate the request data
15+
await request.validate()
16+
17+
// Check if gift card exists
18+
const existingGiftCard = await fetchById(id)
19+
if (!existingGiftCard) {
20+
throw new Error(`Gift card with ID ${id} not found`)
21+
}
22+
23+
// Create update data object using request fields
24+
const updateData: Record<string, any> = {
25+
code: request.get<string>('code'),
26+
initial_balance: request.get<number>('initial_balance'),
27+
current_balance: request.get<number>('current_balance'),
28+
currency: request.get<string>('currency'),
29+
status: request.get<string>('status'),
30+
user_id: request.get<number>('user_id'),
31+
purchaser_id: request.get<string>('purchaser_id'),
32+
recipient_email: request.get<string>('recipient_email'),
33+
recipient_name: request.get<string>('recipient_name'),
34+
personal_message: request.get<string>('personal_message'),
35+
is_digital: request.get<boolean>('is_digital'),
36+
is_reloadable: request.get<boolean>('is_reloadable'),
37+
is_active: request.get<boolean>('is_active'),
38+
expiry_date: request.get<string>('expiry_date'),
39+
last_used_date: request.get<string>('last_used_date'),
40+
template_id: request.get<string>('template_id'),
41+
updated_at: new Date(),
42+
}
43+
44+
// Remove undefined fields to avoid overwriting with null values
45+
Object.keys(updateData).forEach((key) => {
46+
if (updateData[key] === undefined) {
47+
delete updateData[key]
48+
}
49+
})
50+
51+
// If no fields to update, just return the existing gift card
52+
if (Object.keys(updateData).length === 0) {
53+
return existingGiftCard
54+
}
55+
56+
try {
57+
// Update the gift card
58+
await db
59+
.updateTable('gift_cards')
60+
.set(updateData)
61+
.where('id', '=', id)
62+
.execute()
63+
64+
// Fetch and return the updated gift card
65+
return await fetchById(id)
66+
}
67+
catch (error) {
68+
if (error instanceof Error) {
69+
// Handle duplicate code error
70+
if (error.message.includes('Duplicate entry') && error.message.includes('code')) {
71+
throw new Error('A gift card with this code already exists')
72+
}
73+
74+
throw new Error(`Failed to update gift card: ${error.message}`)
75+
}
76+
77+
throw error
78+
}
79+
}
80+
81+
/**
82+
* Update a gift card's balance
83+
*
84+
* @param id The ID of the gift card
85+
* @param amount The amount to adjust (positive to add, negative to deduct)
86+
* @returns The updated gift card with new balance
87+
*/
88+
export async function updateBalance(id: number, amount: number): Promise<GiftCardJsonResponse | undefined> {
89+
// Check if gift card exists and is active
90+
const giftCard = await fetchById(id)
91+
92+
if (!giftCard) {
93+
throw new Error(`Gift card with ID ${id} not found`)
94+
}
95+
96+
if (!giftCard.is_active || giftCard.status !== 'ACTIVE') {
97+
throw new Error(`Gift card is not active`)
98+
}
99+
100+
// Calculate new balance
101+
const newBalance = giftCard.current_balance + amount
102+
103+
// Make sure balance doesn't go below zero
104+
if (newBalance < 0) {
105+
throw new Error(`Insufficient gift card balance`)
106+
}
107+
108+
try {
109+
// Update the gift card balance
110+
await db
111+
.updateTable('gift_cards')
112+
.set({
113+
current_balance: newBalance,
114+
last_used_date: new Date().toISOString(),
115+
status: newBalance === 0 ? 'USED' : 'ACTIVE',
116+
updated_at: new Date(),
117+
})
118+
.where('id', '=', id)
119+
.execute()
120+
121+
// Fetch the updated gift card
122+
return await fetchById(id)
123+
}
124+
catch (error) {
125+
if (error instanceof Error) {
126+
throw new TypeError(`Failed to update gift card balance: ${error.message}`)
127+
}
128+
129+
throw error
130+
}
131+
}

0 commit comments

Comments
 (0)