'Method not allowed'], 405); } $input = json_decode(file_get_contents('php://input'), true); if (empty($input['items']) || !is_array($input['items'])) { jsonResponse(['error' => 'No items provided'], 400); } $items = $input['items']; $paymentMethod = $input['payment_method'] ?? 'cash'; $notes = $input['notes'] ?? ''; $customerId = $input['customer_id'] ?? null; $customerEmail = $input['customer_email'] ?? null; $discountAmount = floatval($input['discount'] ?? 0); $couponCode = $input['coupon_code'] ?? null; // Calculate totals $subtotal = 0; $orderItems = []; foreach ($items as $item) { // Verify product exists and has stock $product = db()->fetch( "SELECT product_id, name, price, sale_price, stock FROM products WHERE product_id = :id AND is_active = 1", ['id' => $item['product_id']] ); if (!$product) { jsonResponse(['error' => 'Product not found: ' . $item['name']], 400); } if ($product['stock'] < $item['quantity']) { jsonResponse(['error' => 'Insufficient stock for: ' . $product['name']], 400); } $price = $product['sale_price'] ?? $product['price']; $lineTotal = $price * $item['quantity']; $subtotal += $lineTotal; $orderItems[] = [ 'product_id' => $product['product_id'], 'name' => $product['name'], 'price' => $price, 'quantity' => $item['quantity'], 'total' => $lineTotal ]; } // Apply coupon if provided $couponDiscount = 0; if ($couponCode) { $coupon = db()->fetch( "SELECT * FROM coupons WHERE code = :code AND is_active = 1 AND (starts_at IS NULL OR starts_at <= NOW()) AND (expires_at IS NULL OR expires_at > NOW()) AND (max_uses IS NULL OR times_used < max_uses)", ['code' => strtoupper($couponCode)] ); if ($coupon) { if ($coupon['min_order_amount'] && $subtotal < $coupon['min_order_amount']) { // Coupon minimum not met, ignore } else { if ($coupon['discount_type'] === 'percentage') { $couponDiscount = $subtotal * ($coupon['discount_value'] / 100); } else { $couponDiscount = min($coupon['discount_value'], $subtotal); } // Update coupon usage db()->query("UPDATE coupons SET times_used = times_used + 1 WHERE coupon_id = :id", ['id' => $coupon['coupon_id']]); } } } // Calculate final total $discount = $discountAmount + $couponDiscount; $taxRate = 0; // Adjust based on settings $tax = ($subtotal - $discount) * $taxRate; $total = $subtotal - $discount + $tax; // Handle wallet payment $walletUsed = 0; if ($paymentMethod === 'wallet' && $customerId) { $customer = db()->fetch( "SELECT wallet_balance FROM customers WHERE customer_id = :id", ['id' => $customerId] ); if (!$customer || $customer['wallet_balance'] < $total) { jsonResponse(['error' => 'Insufficient wallet balance'], 400); } $walletUsed = $total; // Deduct from wallet db()->query( "UPDATE customers SET wallet_balance = wallet_balance - :amount WHERE customer_id = :id", ['amount' => $walletUsed, 'id' => $customerId] ); // Log wallet transaction $newBalance = $customer['wallet_balance'] - $walletUsed; db()->insert('wallet_transactions', [ 'transaction_id' => generateId('wt_'), 'customer_id' => $customerId, 'amount' => -$walletUsed, 'balance_after' => $newBalance, 'type' => 'purchase', 'description' => 'POS Purchase' ]); } // Generate order $orderId = generateId('ord_'); $orderNumber = generateOrderNumber(); try { // Create order db()->insert('orders', [ 'order_id' => $orderId, 'order_number' => $orderNumber, 'customer_id' => $customerId, 'customer_email' => $customerEmail ?? 'pos@store.local', 'customer_name' => $input['customer_name'] ?? 'POS Customer', 'items' => json_encode($orderItems), 'subtotal' => $subtotal, 'tax' => $tax, 'discount' => $discount, 'wallet_amount_used' => $walletUsed, 'total' => $total, 'payment_method' => $paymentMethod, 'payment_status' => 'paid', 'order_status' => 'confirmed', 'notes' => $notes, 'is_pos_order' => 1 ]); // Insert order items foreach ($orderItems as $item) { db()->insert('order_items', [ 'order_id' => $orderId, 'product_id' => $item['product_id'], 'name' => $item['name'], 'price' => $item['price'], 'quantity' => $item['quantity'], 'total' => $item['total'] ]); // Update stock db()->query( "UPDATE products SET stock = stock - :qty WHERE product_id = :id", ['qty' => $item['quantity'], 'id' => $item['product_id']] ); } // Award reward points if customer if ($customerId) { $pointsEarned = floor($total); // 1 point per dollar db()->query( "UPDATE customers SET reward_points = reward_points + :points WHERE customer_id = :id", ['points' => $pointsEarned, 'id' => $customerId] ); } jsonResponse([ 'success' => true, 'order_id' => $orderId, 'order_number' => $orderNumber, 'total' => $total, 'items' => $orderItems ]); } catch (Exception $e) { jsonResponse(['error' => 'Failed to create order: ' . $e->getMessage()], 500); }