179 lines
5.0 KiB
TypeScript
179 lines
5.0 KiB
TypeScript
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;
|
|
}
|
|
}
|
|
|