init
This commit is contained in:
178
src/database/paymentService.ts
Normal file
178
src/database/paymentService.ts
Normal file
@@ -0,0 +1,178 @@
|
||||
import { pool } from './connection';
|
||||
import { PendingOrder, Sale } from './types';
|
||||
|
||||
/**
|
||||
* Find a pending order by order_id
|
||||
*/
|
||||
export async function findPendingOrderByOrderId(orderId: string): Promise<PendingOrder | null> {
|
||||
try {
|
||||
const [rows] = await pool.execute(
|
||||
'SELECT * FROM pending_orders WHERE order_id = ?',
|
||||
[orderId]
|
||||
) as [PendingOrder[], any];
|
||||
|
||||
if (Array.isArray(rows) && rows.length > 0) {
|
||||
return rows[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('Error finding pending order:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sale record from a pending order
|
||||
*/
|
||||
export async function createSaleFromPendingOrder(pendingOrder: PendingOrder): Promise<Sale> {
|
||||
try {
|
||||
const [result] = await pool.execute(
|
||||
'INSERT INTO sales (drop_id, buyer_id, size, payment_id, created_at) VALUES (?, ?, ?, ?, NOW())',
|
||||
[
|
||||
pendingOrder.drop_id,
|
||||
pendingOrder.buyer_id,
|
||||
pendingOrder.size,
|
||||
pendingOrder.payment_id
|
||||
]
|
||||
);
|
||||
|
||||
const insertResult = result as any;
|
||||
const saleId = insertResult.insertId;
|
||||
|
||||
// Fetch the created sale
|
||||
const [rows] = await pool.execute(
|
||||
'SELECT * FROM sales WHERE id = ?',
|
||||
[saleId]
|
||||
) as [Sale[], any];
|
||||
|
||||
if (Array.isArray(rows) && rows.length > 0) {
|
||||
return rows[0];
|
||||
}
|
||||
|
||||
throw new Error('Failed to retrieve created sale');
|
||||
} catch (error) {
|
||||
console.error('Error creating sale:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a pending order by order_id
|
||||
*/
|
||||
export async function deletePendingOrderByOrderId(orderId: string): Promise<boolean> {
|
||||
try {
|
||||
const [result] = await pool.execute(
|
||||
'DELETE FROM pending_orders WHERE order_id = ?',
|
||||
[orderId]
|
||||
);
|
||||
|
||||
const deleteResult = result as any;
|
||||
return deleteResult.affectedRows > 0;
|
||||
} catch (error) {
|
||||
console.error('Error deleting pending order:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a payment from pending_orders to sales
|
||||
* This is the main function that handles the complete transaction
|
||||
*/
|
||||
export async function movePaymentToSales(orderId: string, paymentId: string): Promise<Sale> {
|
||||
const connection = await pool.getConnection();
|
||||
|
||||
try {
|
||||
// Start transaction
|
||||
await connection.beginTransaction();
|
||||
|
||||
// Find the pending order by order_id
|
||||
const [pendingRows] = await connection.execute(
|
||||
'SELECT * FROM pending_orders WHERE order_id = ? FOR UPDATE',
|
||||
[orderId]
|
||||
) as [PendingOrder[], any];
|
||||
|
||||
if (!Array.isArray(pendingRows) || pendingRows.length === 0) {
|
||||
throw new Error(`Pending order not found for order_id: ${orderId}`);
|
||||
}
|
||||
|
||||
const pendingOrder = pendingRows[0];
|
||||
|
||||
// Validate all required fields are present
|
||||
if (pendingOrder.drop_id === undefined || pendingOrder.drop_id === null) {
|
||||
throw new Error(`Pending order missing drop_id for order_id: ${orderId}`);
|
||||
}
|
||||
if (pendingOrder.buyer_id === undefined || pendingOrder.buyer_id === null) {
|
||||
throw new Error(`Pending order missing buyer_id for order_id: ${orderId}`);
|
||||
}
|
||||
if (pendingOrder.size === undefined || pendingOrder.size === null) {
|
||||
throw new Error(`Pending order missing size for order_id: ${orderId}`);
|
||||
}
|
||||
if (!paymentId) {
|
||||
throw new Error(`Payment ID is required but was ${paymentId} for order_id: ${orderId}`);
|
||||
}
|
||||
|
||||
// Create sale record
|
||||
const [insertResult] = await connection.execute(
|
||||
'INSERT INTO sales (drop_id, buyer_id, size, payment_id, created_at) VALUES (?, ?, ?, ?, NOW())',
|
||||
[
|
||||
pendingOrder.drop_id,
|
||||
pendingOrder.buyer_id,
|
||||
pendingOrder.size,
|
||||
paymentId
|
||||
]
|
||||
);
|
||||
|
||||
const insert = insertResult as any;
|
||||
const saleId = insert.insertId;
|
||||
|
||||
// Delete pending order by order_id
|
||||
await connection.execute(
|
||||
'DELETE FROM pending_orders WHERE order_id = ?',
|
||||
[orderId]
|
||||
);
|
||||
|
||||
// Fetch the created sale
|
||||
const [saleRows] = await connection.execute(
|
||||
'SELECT * FROM sales WHERE id = ?',
|
||||
[saleId]
|
||||
) as [Sale[], any];
|
||||
|
||||
if (!Array.isArray(saleRows) || saleRows.length === 0) {
|
||||
throw new Error('Failed to retrieve created sale');
|
||||
}
|
||||
|
||||
// Commit transaction
|
||||
await connection.commit();
|
||||
|
||||
console.log(`✅ Successfully moved order ${orderId} (payment_id: ${paymentId}) from pending_orders to sales (sale_id: ${saleId})`);
|
||||
return saleRows[0];
|
||||
} catch (error) {
|
||||
// Rollback transaction on error
|
||||
await connection.rollback();
|
||||
console.error('Error moving payment to sales:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
// Release connection back to pool
|
||||
connection.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a payment already exists in sales
|
||||
*/
|
||||
export async function paymentExistsInSales(paymentId: string): Promise<boolean> {
|
||||
try {
|
||||
const [rows] = await pool.execute(
|
||||
'SELECT COUNT(*) as count FROM sales WHERE payment_id = ?',
|
||||
[paymentId]
|
||||
);
|
||||
|
||||
const result = rows as any[];
|
||||
return result[0]?.count > 0;
|
||||
} catch (error) {
|
||||
console.error('Error checking sale existence:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user