Download src/app/api/orders/route.ts from phucsd/PrintCal: direct link, hf CLI and curl.
- Browser
- Download file 7.53 kB
-
https://huggingface.co/spaces/phucsd/PrintCal/resolve/main/src/app/api/orders/route.ts
- Command line
-
hf download hf://spaces/phucsd/PrintCal/src/app/api/orders/route.ts
-
curl -L -o route.ts https://huggingface.co/spaces/phucsd/PrintCal/resolve/main/src/app/api/orders/route.ts
7.53 kB
| import { NextRequest, NextResponse } from 'next/server'; | |
| import { getDb } from '@/lib/db'; | |
| import { OrderStatus, ProductType, QuoteOrder } from '@/types'; | |
| export async function GET(req: NextRequest) { | |
| try { | |
| const db = getDb(); | |
| const { searchParams } = new URL(req.url); | |
| const status = searchParams.get('status'); | |
| const search = searchParams.get('search'); | |
| let query = 'SELECT * FROM quotes_orders WHERE 1=1'; | |
| const params: unknown[] = []; | |
| if (status && status !== 'all') { | |
| query += ' AND status = ?'; | |
| params.push(status); | |
| } | |
| if (search) { | |
| query += ' AND (code LIKE ? OR customer_name LIKE ? OR customer_phone LIKE ? OR job_name LIKE ?)'; | |
| const term = `%${search}%`; | |
| params.push(term, term, term, term); | |
| } | |
| query += ' ORDER BY id DESC'; | |
| const rows = db.prepare(query).all(...params) as Record<string, unknown>[]; | |
| const orders: QuoteOrder[] = rows.map((r) => mapOrder(r)); | |
| return NextResponse.json(orders); | |
| } catch (err: unknown) { | |
| return NextResponse.json({ error: (err as Error).message }, { status: 500 }); | |
| } | |
| } | |
| export async function POST(req: NextRequest) { | |
| try { | |
| const body = await req.json(); | |
| const db = getDb(); | |
| // Sinh mã đơn hàng tự động: PC-YYYYMM-XXX | |
| const now = new Date(); | |
| const yearMonth = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}`; | |
| const countRow = db.prepare('SELECT COUNT(*) as count FROM quotes_orders WHERE code LIKE ?').get(`PC-${yearMonth}-%`) as { count: number }; | |
| const nextNum = String(countRow.count + 1).padStart(3, '0'); | |
| const code = body.code || `PC-${yearMonth}-${nextNum}`; | |
| // Tự động thêm hoặc cập nhật khách hàng | |
| let customerId = body.customerId; | |
| if (!customerId && body.customerPhone) { | |
| const existingCust = db.prepare('SELECT id FROM customers WHERE phone = ?').get(body.customerPhone) as { id: number } | undefined; | |
| if (existingCust) { | |
| customerId = existingCust.id; | |
| } else if (body.customerName) { | |
| const custResult = db.prepare(` | |
| INSERT INTO customers (name, phone, email, company) | |
| VALUES (?, ?, ?, ?) | |
| `).run(body.customerName, body.customerPhone, body.customerEmail || '', body.customerCompany || ''); | |
| customerId = Number(custResult.lastInsertRowid); | |
| } | |
| } | |
| const stmt = db.prepare(` | |
| INSERT INTO quotes_orders ( | |
| code, customer_id, customer_name, customer_phone, customer_email, customer_company, | |
| job_name, product_type, print_tech, quantity, width_mm, height_mm, pages, | |
| paper_name, paper_gsm, parent_size, print_size, ups_per_sheet, | |
| total_print_sheets, total_parent_sheets, paper_cost, print_cost, finishing_cost, | |
| total_cost, profit_margin_percent, profit_amount, discount_amount, | |
| vat_percent, vat_amount, final_price, unit_price, status, notes, spec_json | |
| ) | |
| VALUES ( | |
| ?, ?, ?, ?, ?, ?, | |
| ?, ?, ?, ?, ?, ?, ?, | |
| ?, ?, ?, ?, ?, | |
| ?, ?, ?, ?, ?, | |
| ?, ?, ?, ?, | |
| ?, ?, ?, ?, ?, ?, ? | |
| ) | |
| `); | |
| const result = stmt.run( | |
| code, | |
| customerId || null, | |
| body.customerName || 'Khách vãng lai', | |
| body.customerPhone || '', | |
| body.customerEmail || '', | |
| body.customerCompany || '', | |
| body.jobName || 'In ấn phẩm', | |
| body.productType || 'to_roi', | |
| body.printTech || 'offset', | |
| body.quantity, | |
| body.widthMm, | |
| body.heightMm, | |
| body.pages || 2, | |
| body.paperName, | |
| body.paperGsm, | |
| body.parentSize || '', | |
| body.printSize || '', | |
| body.upsPerSheet || 1, | |
| body.totalPrintSheets || 0, | |
| body.totalParentSheets || 0, | |
| body.paperCost || 0, | |
| body.printCost || 0, | |
| body.finishingCost || 0, | |
| body.totalCost || 0, | |
| body.profitMarginPercent || 25, | |
| body.profitAmount || 0, | |
| body.discountAmount || 0, | |
| body.vatPercent || 0, | |
| body.vatAmount || 0, | |
| body.finalPrice || 0, | |
| body.unitPrice || 0, | |
| body.status || 'quote', | |
| body.notes || '', | |
| body.specJson ? JSON.stringify(body.specJson) : null | |
| ); | |
| return NextResponse.json({ success: true, id: Number(result.lastInsertRowid), code }); | |
| } catch (err: unknown) { | |
| console.error('Order save error:', err); | |
| return NextResponse.json({ error: (err as Error).message }, { status: 500 }); | |
| } | |
| } | |
| export async function PUT(req: NextRequest) { | |
| try { | |
| const body = await req.json(); | |
| const db = getDb(); | |
| if (body.action === 'status') { | |
| db.prepare(` | |
| UPDATE quotes_orders | |
| SET status = ?, updated_at = CURRENT_TIMESTAMP | |
| WHERE id = ? | |
| `).run(body.status, body.id); | |
| } else { | |
| db.prepare(` | |
| UPDATE quotes_orders | |
| SET customer_name = ?, customer_phone = ?, customer_email = ?, customer_company = ?, | |
| job_name = ?, status = ?, notes = ?, updated_at = CURRENT_TIMESTAMP | |
| WHERE id = ? | |
| `).run( | |
| body.customerName, | |
| body.customerPhone, | |
| body.customerEmail || '', | |
| body.customerCompany || '', | |
| body.jobName, | |
| body.status, | |
| body.notes || '', | |
| body.id | |
| ); | |
| } | |
| return NextResponse.json({ success: true }); | |
| } catch (err: unknown) { | |
| return NextResponse.json({ error: (err as Error).message }, { status: 500 }); | |
| } | |
| } | |
| export async function DELETE(req: NextRequest) { | |
| try { | |
| const { searchParams } = new URL(req.url); | |
| const id = searchParams.get('id'); | |
| if (!id) return NextResponse.json({ error: 'Thiếu ID đơn hàng' }, { status: 400 }); | |
| const db = getDb(); | |
| db.prepare('DELETE FROM quotes_orders WHERE id = ?').run(Number(id)); | |
| return NextResponse.json({ success: true }); | |
| } catch (err: unknown) { | |
| return NextResponse.json({ error: (err as Error).message }, { status: 500 }); | |
| } | |
| } | |
| function mapOrder(r: Record<string, unknown>): QuoteOrder { | |
| return { | |
| id: r.id as number, | |
| code: r.code as string, | |
| customerId: r.customer_id as number | undefined, | |
| customerName: r.customer_name as string, | |
| customerPhone: r.customer_phone as string, | |
| customerEmail: (r.customer_email as string) || '', | |
| customerCompany: (r.customer_company as string) || '', | |
| jobName: r.job_name as string, | |
| productType: r.product_type as ProductType, | |
| printTech: r.print_tech as 'offset' | 'digital', | |
| quantity: r.quantity as number, | |
| widthMm: r.width_mm as number, | |
| heightMm: r.height_mm as number, | |
| pages: r.pages as number, | |
| paperName: r.paper_name as string, | |
| paperGsm: r.paper_gsm as number, | |
| parentSize: r.parent_size as string, | |
| printSize: r.print_size as string, | |
| upsPerSheet: r.ups_per_sheet as number, | |
| totalPrintSheets: r.total_print_sheets as number, | |
| totalParentSheets: r.total_parent_sheets as number, | |
| paperCost: r.paper_cost as number, | |
| printCost: r.print_cost as number, | |
| finishingCost: r.finishing_cost as number, | |
| totalCost: r.total_cost as number, | |
| profitMarginPercent: r.profit_margin_percent as number, | |
| profitAmount: r.profit_amount as number, | |
| discountAmount: r.discount_amount as number, | |
| vatPercent: r.vat_percent as number, | |
| vatAmount: r.vat_amount as number, | |
| finalPrice: r.final_price as number, | |
| unitPrice: r.unit_price as number, | |
| status: r.status as OrderStatus, | |
| notes: (r.notes as string) || '', | |
| specJson: (r.spec_json as string) || '', | |
| createdAt: r.created_at as string, | |
| updatedAt: r.updated_at as string, | |
| }; | |
| } | |