This commit is contained in:
root
2025-12-20 19:00:17 +01:00
commit 02830aa7df
14 changed files with 2967 additions and 0 deletions

View 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;
}
}