diff --git a/.cursorrules b/.cursorrules deleted file mode 100644 index 4be2d19..0000000 --- a/.cursorrules +++ /dev/null @@ -1,194 +0,0 @@ -You are helping to build an AI first Invoice Processing POC which will eventually go into an Accounts Payable Platform - Xelix. - -# Persona Information - -# AP Processor Context for Xelix Invoice Processing - -You are assisting a Senior Accounts Payable Processor using Xelix. They process 200-300 invoices daily, with 40% requiring manual intervention for matching exceptions. - -## Critical Mindset: -- **Match resolution focus**: "Show me WHY this invoice won't match to PO/GR" -- **Exception patterns**: "Are these all quantity mismatches I can bulk-approve?" -- **Tolerance awareness**: "Is this $50 variance worth blocking a $50K payment?" -- **Vendor relationships**: Every matching delay = supplier calling about payment - -## Matching Workflow in Xelix: - -### 2-Way Match (Invoice ↔ PO): -``` -Invoice arrives → Find PO → Amount match? → Approve - ↓ No ↓ No ↓ Wait - Fuzzy search Price variance? Check tolerance - Quantity diff? Contact buyer -``` - -### 3-Way Match (Invoice ↔ PO ↔ GR): -``` -Invoice → Match PO → Match GR → All align? → Approve - ↓ No ↓ No ↓ No ↓ - "Show similar POs" "GR pending?" "Show mismatches" - "Partial GR?" "Who to contact?" -``` - -## Common Matching Exceptions They Face: -- **Quantity**: "GR shows 95 units received, invoice for 100" -- **Price**: "PO says $10/unit, invoice shows $10.50" -- **Partial delivery**: "Multiple GRs for one PO - which ones?" -- **Unit mismatch**: "PO in cases, invoice in pieces, GR in pallets" -- **Timing**: "Goods received but GR not yet in system" - -## Their Resolution Strategies: -1. **Quick fixes**: "If variance <$100, approve within tolerance" -2. **Bulk actions**: "Select all price increases from this vendor" -3. **Smart routing**: "Quantity issues → Warehouse, Price → Procurement" -4. **History-based**: "This vendor always ships 5% over - it's accepted" - -## Language for Matching Issues: -- "Short-shipped" = GR quantity < Invoice quantity -- "Price creep" = Unauthorized price increase on invoice -- "Split delivery" = One PO, multiple GRs to reconcile -- "Goods in transit" = Physical receipt without system GR -- "Tolerance breach" = Variance exceeds auto-approval threshold - -## What They Need from Xelix: -- **Visual clarity**: Highlight WHAT doesn't match (quantity/price/dates) -- **Smart suggestions**: "3 other invoices have same price increase" -- **One-click actions**: "Approve all within 2% tolerance" -- **Clear routing**: "Send to Mike in Warehouse for GR confirmation" - -## Hidden Matching Needs: -- **Pattern memory**: "Remember this vendor always invoices in different UOM" -- **Proactive alerts**: "5 invoices waiting for same missing GR" -- **Tolerance templates**: Different rules for different vendors/categories -- **Match confidence**: "90% sure this is PO 4500123 despite typo" - -## Approval Workflow Challenges: - -### Approval Routing Logic: -``` -Exception found → Determine approver → Available? → Approve - ↓ ↓ No ↓ Wait - By amount/type/dept Find backup Chase - Escalate up Remind -``` - -### Common Approval Bottlenecks: -- **Single approver trap**: "Sarah from Procurement is on vacation - 50 invoices stuck" -- **Circular routing**: "AP → Procurement → Finance → back to AP" -- **Authority limits**: "$5K needs manager, $25K needs director, now what?" -- **Missing delegates**: "Who covers for Tom when he's out?" -- **Approval fatigue**: "200 invoices in John's queue, he's overwhelmed" - -## What They Need for Approvals: -- **Smart routing**: "Route to Amy (backup) since Bob is OOO" -- **Bulk capabilities**: "John, approve these 30 similar variances at once" -- **Escalation paths**: "Waiting >48hrs → auto-escalate to manager" -- **Mobile approval**: "Let Sarah approve urgent items from her phone" -- **Context in request**: "Approve $500 variance - history shows normal" - -## Approval Language: -- "Sitting with" = Currently in someone's approval queue -- "Approval chain" = Sequential approvers needed (manager → director) -- "Delegation matrix" = Who can approve for whom -- "Auto-escalate" = System pushes to next level after timeout -- "Approval threshold" = Dollar limit for self-approval - -## Their Approval Frustrations: -1. **Visibility**: "I can't see where this invoice is stuck" -2. **Reminders**: "I shouldn't manually email chasers all day" -3. **Delegation**: "System doesn't know Lisa covers for Mark" -4. **History**: "Why can't approvers see this variance is normal?" - -Remember: They're not just matching documents - they're orchestrating complex approval workflows while balancing speed vs. accuracy, maintaining vendor trust while protecting against overpayment. Every matching exception Xelix surfaces should come with a suggested resolution path and clear approval routing. - - -When working inside the backend directory, you are an expert in Python, Django, and scalable web application development. - -Key Principles for the backend: - - - Write clear, technical responses with precise Django examples. - - Use Django's built-in features and tools wherever possible to leverage its full capabilities. - - Prioritize readability and maintainability; follow Django's coding style guide (PEP 8 compliance). - - Use descriptive variable and function names; adhere to naming conventions (e.g., lowercase with underscores for functions and variables). - - Structure your project in a modular way using Django apps to promote reusability and separation of concerns. - - Django/Python - - Use Django's class-based views (CBVs) for more complex views; prefer function-based views (FBVs) for simpler logic. - - Leverage Django's ORM for database interactions; avoid raw SQL queries unless necessary for performance. - - Use Django's built-in user model and authentication framework for user management. - - Utilize Django's form and model form classes for form handling and validation. - - Follow the MVT (Model-View-Template) pattern strictly for clear separation of concerns. - - Use middleware judiciously to handle cross-cutting concerns like authentication, logging, and caching. - - Error Handling and Validation - - Implement error handling at the view level and use Django's built-in error handling mechanisms. - - Use Django's validation framework to validate form and model data. - - Prefer try-except blocks for handling exceptions in business logic and views. - - Customize error pages (e.g., 404, 500) to improve user experience and provide helpful information. - - Use Django signals to decouple error handling and logging from core business logic. - - Dependencies - - Django - - Django REST Framework (for API development) - - Django-Specific Guidelines - - Use Django templates for rendering HTML and DRF serializers for JSON responses. - - Keep business logic in models and forms; keep views light and focused on request handling. - - Use Django's URL dispatcher (urls.py) to define clear and RESTful URL patterns. - - Apply Django's security best practices (e.g., CSRF protection, SQL injection protection, XSS prevention). - - Use Django's built-in tools for testing (unittest and pytest-django) to ensure code quality and reliability. - - Leverage Django's caching framework to optimize performance for frequently accessed data. - - Use Django's middleware for common tasks such as authentication, logging, and security. - - Performance Optimization - - Optimize query performance using Django ORM's select_related and prefetch_related for related object fetching. - - Use Django's cache framework with backend support (e.g., Redis or Memcached) to reduce database load. - - Implement database indexing and query optimization techniques for better performance. - - Use asynchronous views and background tasks (via Celery) for I/O-bound or long-running operations. - - Optimize static file handling with Django's static file management system (e.g., WhiteNoise or CDN integration). - - Key Conventions - 1. Follow Django's "Convention Over Configuration" principle for reducing boilerplate code. - 2. Prioritize security and performance optimization in every stage of development. - 3. Maintain a clear and logical project structure to enhance readability and maintainability. - - Refer to Django documentation for best practices in views, models, forms, and security considerations. - -When working inside the frontend directory: - -You are a Senior Front-End Developer and an Expert in ReactJS, NextJS, JavaScript, TypeScript, HTML, CSS and modern UI/UX frameworks (e.g., TailwindCSS, Shadcn, Radix). You are thoughtful, give nuanced answers, and are brilliant at reasoning. You carefully provide accurate, factual, thoughtful answers, and are a genius at reasoning. - -- Follow the user's requirements carefully & to the letter. -- First think step-by-step - describe your plan for what to build in pseudocode, written out in great detail. -- Confirm, then write code! -- Always write correct, best practice, DRY principle (Dont Repeat Yourself), bug free, fully functional and working code also it should be aligned to listed rules down below at Code Implementation Guidelines. -- Focus on easy and readability code, over being performant. -- Fully implement all requested functionality. -- Leave NO todo's, placeholders or missing pieces. -- Ensure code is complete! Verify thoroughly finalised. -- Include all required imports, and ensure proper naming of key components. -- Be concise Minimize any other prose. -- If you think there might not be a correct answer, you say so. -- If you do not know the answer, say so, instead of guessing. - -### Coding Environment -The user asks questions about the following coding languages: -- ReactJS -- NextJS -- JavaScript -- TypeScript -- TailwindCSS -- HTML -- CSS - -### Code Implementation Guidelines -Follow these rules when you write code: -- Use early returns whenever possible to make the code more readable. -- Always use Tailwind classes for styling HTML elements; avoid using CSS or tags. -- Use "class:" instead of the tertiary operator in class tags whenever possible. -- Use descriptive variable and function/const names. Also, event functions should be named with a "handle" prefix, like "handleClick" for onClick and "handleKeyDown" for onKeyDown. -- Implement accessibility features on elements. For example, a tag should have a tabindex="0", aria-label, on:click, and on:keydown, and similar attributes. -- Use consts instead of functions, for example, "const toggle = () =>". Also, define a type if possible. - - -Before doing anything, only act when you have 95% confidence in what you are doing. Ask any follow up questions that you may need for clarification until you get this confidence. \ No newline at end of file diff --git a/.gitignore b/.gitignore index d42acc7..0af3e83 100644 --- a/.gitignore +++ b/.gitignore @@ -1,145 +1,28 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -# Dependencies -/frontend/node_modules/ -/backend/venv/ -__pycache__/ -*.py[cod] -*$py.class +# dependencies +/node_modules -# Next.js (Frontend) -/frontend/.next/ -/frontend/out/ +# next.js +/.next/ +/out/ -# Production builds -/frontend/build/ -/backend/staticfiles/ -/dist/ +# production +/build -# Debug logs +# debug npm-debug.log* yarn-debug.log* yarn-error.log* .pnpm-debug.log* -# Environment files (contains sensitive API keys) +# env files .env* -!.env.example +venv/ -# Vercel +# vercel .vercel -# TypeScript +# typescript *.tsbuildinfo -next-env.d.ts - -# Python/Django specific -*.log -*.pot -*.pyc -*.pyo -*.pyd -__pycache__/ -*.so -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# Django specific -db.sqlite3 -db.sqlite3-journal -/backend/media/ -/backend/staticfiles/ -/backend/static/ -*.log - -# Virtual environments -venv/ -ENV/ -env/ -.venv/ - -# IDE and editor files -.vscode/ -.idea/ -*.swp -*.swo -*~ - -# OS generated files -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -# Temporary files -temp/ -tmp/ -*.tmp -*.temp - -# Testing -.coverage -.pytest_cache/ -.tox/ -.nox/ -coverage.xml -*.cover -*.py,cover -.hypothesis/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -.python-version - -# Celery -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ \ No newline at end of file +next-env.d.ts \ No newline at end of file diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md deleted file mode 100644 index 76a360d..0000000 --- a/DEPLOYMENT.md +++ /dev/null @@ -1,138 +0,0 @@ -# 🚀 Deployment Guide - -## Overview - -This project consists of: - -- **Backend**: Django REST API (deployed to Railway) -- **Frontend**: Next.js application (deployed to Vercel) - -## 🏗️ Backend Deployment (Railway) - -### 1. Connect to Railway - -1. Go to [Railway](https://railway.app) and sign up/login -2. Click "New Project" → "Deploy from GitHub repo" -3. Select your `MikeHiett/invoice-processing-poc` repository -4. Choose the `django-railway` branch - -### 2. Configure Environment Variables - -In Railway, go to your project → Variables tab and add: - -```bash -# Django Configuration -DEBUG=False -SECRET_KEY=your-super-secret-key-here-make-it-long-and-random -ALLOWED_HOSTS=your-app-name.railway.app - -# AI Service (choose one) -ANTHROPIC_API_KEY=your-anthropic-api-key - -# CORS (will be updated after Vercel deployment) -CORS_ALLOWED_ORIGINS=http://localhost:3000 -``` - -### 3. Add PostgreSQL Database - -1. In Railway, click "New" → "Database" → "PostgreSQL" -2. Railway will automatically set the `DATABASE_URL` environment variable - -### 4. Deploy Settings - -Railway should automatically: - -- Detect it's a Python project -- Use the `Procfile` for deployment commands -- Run migrations and collect static files - -Your backend will be available at: `https://your-app-name.railway.app` - -## 🌐 Frontend Deployment (Vercel) - -### 1. Connect to Vercel - -1. Go to [Vercel](https://vercel.com) and sign up/login -2. Click "New Project" → Import from GitHub -3. Select your `MikeHiett/invoice-processing-poc` repository -4. Set the **Root Directory** to `frontend` - -### 2. Configure Environment Variables - -In Vercel, go to your project → Settings → Environment Variables: - -```bash -NEXT_PUBLIC_API_URL=https://your-railway-app-name.railway.app -``` - -### 3. Deploy - -Vercel will automatically deploy your Next.js app. - -Your frontend will be available at: `https://your-app-name.vercel.app` - -## 🔗 Connect Frontend and Backend - -### Update Railway CORS Settings - -Once your Vercel app is deployed, update the Railway environment variables: - -```bash -CORS_ALLOWED_ORIGINS=https://your-vercel-app.vercel.app,http://localhost:3000 -ALLOWED_HOSTS=your-railway-app.railway.app,localhost,127.0.0.1 -``` - -## 🧪 Testing the Deployment - -1. Visit your Vercel frontend URL -2. Go to `/invoices/upload` -3. Upload a test invoice -4. Verify it processes correctly - -## 🔧 Troubleshooting - -### Backend Issues - -- Check Railway logs: Railway dashboard → your project → View logs -- Verify environment variables are set correctly -- Ensure database is connected - -### Frontend Issues - -- Check Vercel logs: Vercel dashboard → your project → Functions tab -- Verify `NEXT_PUBLIC_API_URL` is set correctly -- Check browser console for errors - -### CORS Issues - -- Ensure your Vercel domain is in `CORS_ALLOWED_ORIGINS` -- Verify the backend URL in frontend env vars - -## 📝 Environment Variables Summary - -### Railway (Backend) - -```bash -DEBUG=False -SECRET_KEY=your-secret-key -ALLOWED_HOSTS=your-railway-app.railway.app -ANTHROPIC_API_KEY=your-api-key -CORS_ALLOWED_ORIGINS=https://your-vercel-app.vercel.app,http://localhost:3000 -``` - -### Vercel (Frontend) - -```bash -NEXT_PUBLIC_API_URL=https://your-railway-app.railway.app -``` - -## 🎉 Success! - -Once deployed, you'll have: - -- ✅ Django API running on Railway with PostgreSQL -- ✅ Next.js frontend on Vercel -- ✅ AI-powered invoice extraction -- ✅ Automatic deployments on git push - -Your invoice processing app is now live! 🚀 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 9a2a1d8..0000000 --- a/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -# Use Python 3.11 -FROM python:3.11-slim - -# Set environment variables -ENV PYTHONUNBUFFERED=1 -ENV PYTHONDONTWRITEBYTECODE=1 - -# Set work directory -WORKDIR /app - -# Install system dependencies including OpenCV requirements -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - gcc \ - pkg-config \ - libpq-dev \ - libgl1-mesa-glx \ - libglib2.0-0 \ - libgomp1 \ - libglib2.0-0 \ - && rm -rf /var/lib/apt/lists/* - -# Copy requirements and install Python dependencies -COPY backend/requirements.txt /app/backend/ -RUN pip install --no-cache-dir -r backend/requirements.txt - -# Copy project files -COPY . /app/ - -# Create staticfiles directory -RUN mkdir -p /app/backend/staticfiles - -# Expose port -EXPOSE $PORT - -# Command to run the application -# Migrations, load fixtures, collectstatic, then start server -CMD cd backend && \ - python manage.py migrate && \ - python manage.py load_csv_data && \ - python manage.py collectstatic --noinput && \ - gunicorn invoice_backend.wsgi:application --bind 0.0.0.0:$PORT \ No newline at end of file diff --git a/Procfile b/Procfile deleted file mode 100644 index c8bb45b..0000000 --- a/Procfile +++ /dev/null @@ -1,2 +0,0 @@ -web: cd backend && python manage.py migrate && python manage.py load_csv_data && python manage.py collectstatic --noinput && gunicorn invoice_backend.wsgi:application --bind 0.0.0.0:$PORT -release: cd backend && python manage.py migrate && python manage.py load_csv_data diff --git a/README.md b/README.md index 36845c0..b9190ba 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ This proof of concept application demonstrates a modern approach to invoice proc - AI-powered invoice data extraction - Clean, responsive interface for managing invoices -- Seamless integration between Next.js frontend and Django backend +- Seamless integration between Next.js frontend and Python backend ## Architecture -The project follows a modern full-stack architecture: +The project follows a hybrid architecture: ### Frontend @@ -23,12 +23,10 @@ The project follows a modern full-stack architecture: ### Backend -- **Django**: Python web framework with Django REST Framework -- **AI Engineering**: Modular AI services for invoice extraction - - **Anthropic Claude**: AI models for extracting data from invoice images - - **AWS Bedrock**: Alternative AI service +- **FastAPI**: Python-based API server for invoice extraction +- **OpenAI (Claude)**: AI models for extracting data from invoice images - **PyMuPDF**: PDF processing -- **PostgreSQL/SQLite**: Database for storing invoices and extraction jobs +- **AWS Bedrock**: Alternative AI service ## Features @@ -37,14 +35,12 @@ The project follows a modern full-stack architecture: - Preview invoice files - Create/edit invoices - Dashboard for invoice management -- Purchase order and goods received tracking -- Invoice validation and approval workflow ## Getting Started ### Prerequisites -- Node.js 18+ and npm/pnpm +- Node.js 18+ and pnpm - Python 3.11+ - API keys for Claude/Anthropic or AWS (optional for demo mode) @@ -60,37 +56,21 @@ The project follows a modern full-stack architecture: 2. Install frontend dependencies: ```bash - cd frontend - npm install - # or pnpm install ``` -3. Set up backend: +3. Install backend dependencies: ```bash - cd ../backend - python -m venv venv - source venv/bin/activate # On Windows: venv\Scripts\activate + cd backend pip install -r requirements.txt ``` -4. Set up Django: - - ```bash - python manage.py migrate - python manage.py collectstatic --noinput - python manage.py createsuperuser # Optional - ``` - -5. Set up environment variables: - - Create a `.env` file in the backend directory +4. Set up environment variables: + - Create a `.env.local` file in the root directory - Add your API keys (optional): ``` - SECRET_KEY=your_django_secret_key ANTHROPIC_API_KEY=your_api_key_here - AWS_ACCESS_KEY_ID=your_aws_key - AWS_SECRET_ACCESS_KEY=your_aws_secret ``` ### Running the Application @@ -104,52 +84,32 @@ chmod +x start-dev.sh This will start: -- Django backend on port 8000 +- FastAPI backend on port 8000 - Next.js frontend on port 3000 -### Manual Development - -Alternatively, you can run each part manually: - -```bash -# Terminal 1 - Backend -cd backend -source venv/bin/activate -python manage.py runserver - -# Terminal 2 - Frontend -cd frontend -npm run dev -``` - ## Development ### Project Structure ``` invoice-processing-poc/ -├── frontend/ # Next.js frontend -│ ├── app/ # Next.js app directory -│ ├── components/ # React components -│ ├── public/ # Static assets -│ ├── package.json # Frontend dependencies +├── app/ # Next.js app directory +│ ├── api/ # Next.js API routes +│ ├── invoices/ # Invoice pages +│ └── ... +├── backend/ # Python FastAPI backend +│ ├── api.py # Main API endpoints +│ ├── anthropic_client.py # AI service integration │ └── ... -├── backend/ # Django backend -│ ├── ai_engineering/ # AI services and extraction logic -│ ├── invoices/ # Invoice management app -│ ├── invoice_extraction/ # AI extraction job management -│ ├── purchase_orders/ # Purchase order management -│ ├── goods_received/ # Goods received management -│ └── manage.py # Django management -├── start-dev.sh # Development startup script -└── README.md +├── components/ # React components +├── public/ # Static assets +└── ... ``` ### Adding New Features -1. Backend changes: Add Django apps, models, views, and API endpoints -2. AI changes: Modify modules in `backend/ai_engineering/` -3. Frontend changes: Modify components or add new pages in the `frontend/app/` directory +1. Backend changes: Add endpoints in `backend/api.py` +2. Frontend changes: Modify components or add new pages in the `app` directory ## License diff --git a/frontend/app/api/extract-invoice/route.ts b/app/api/extract-invoice/route.ts similarity index 54% rename from frontend/app/api/extract-invoice/route.ts rename to app/api/extract-invoice/route.ts index 7672aa1..8c9da16 100644 --- a/frontend/app/api/extract-invoice/route.ts +++ b/app/api/extract-invoice/route.ts @@ -1,49 +1,29 @@ import { NextRequest, NextResponse } from 'next/server'; // Ensure we're using the full URL with protocol -const PYTHON_API_URL = process.env.NODE_ENV === 'development' - ? (process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000') - : (process.env.NEXT_PUBLIC_API_URL || 'https://invoice-processing-poc-production.up.railway.app'); +const PYTHON_API_URL = process.env.PYTHON_API_URL || 'http://localhost:8000'; export async function POST(request: NextRequest) { try { - console.log(`Attempting to connect to Python API at: ${PYTHON_API_URL}/api/extract-invoice/`); + console.log(`Attempting to connect to Python API at: ${PYTHON_API_URL}/extract-invoice`); - // Forward the request to the Python Django server + // Forward the request to the Python FastAPI server const formData = await request.formData(); console.log(`Request form data keys: ${Array.from(formData.keys()).join(', ')}`); - const response = await fetch(`${PYTHON_API_URL}/api/extract-invoice/`, { + const response = await fetch(`${PYTHON_API_URL}/extract-invoice`, { method: 'POST', body: formData, // Add a timeout to avoid hanging indefinitely signal: AbortSignal.timeout(10000) // 10 second timeout }); - // Check if response is ok and log more details - console.log(`Response status: ${response.status}`); - console.log(`Response headers:`, Object.fromEntries(response.headers.entries())); - - if (!response.ok) { - const errorText = await response.text(); - console.error(`Error response from Django API: ${errorText}`); - throw new Error(`Django API returned ${response.status}: ${errorText}`); - } - // Get the response data const data = await response.json(); console.log('Successfully received response from Python API'); - // Transform the Django response to match frontend expectations - const transformedData = { - document_type: "invoice", - invoices: data.extracted_invoices || [] - }; - - console.log('Transformed data:', transformedData); - - // Return the transformed response - return NextResponse.json(transformedData, { status: response.status }); + // Return the response from the Python API + return NextResponse.json(data, { status: response.status }); } catch (error: any) { console.error('Error proxying to Python API:', error); diff --git a/app/api/goods-received/route.ts b/app/api/goods-received/route.ts new file mode 100644 index 0000000..490dd5a --- /dev/null +++ b/app/api/goods-received/route.ts @@ -0,0 +1,12 @@ +import { getGoodsReceived } from "@/lib/data-utils" +import { NextResponse } from "next/server" + +export async function GET() { + try { + const goodsReceived = await getGoodsReceived() + return NextResponse.json(goodsReceived) + } catch (error) { + console.error("Error fetching goods received:", error) + return NextResponse.json({ error: "Failed to fetch goods received" }, { status: 500 }) + } +} diff --git a/app/api/invoices/route.ts b/app/api/invoices/route.ts new file mode 100644 index 0000000..d1c9c29 --- /dev/null +++ b/app/api/invoices/route.ts @@ -0,0 +1,12 @@ +import { getInvoices } from "@/lib/data-utils" +import { NextResponse } from "next/server" + +export async function GET() { + try { + const invoices = await getInvoices() + return NextResponse.json(invoices) + } catch (error) { + console.error("Error fetching invoices:", error) + return NextResponse.json({ error: "Failed to fetch invoices" }, { status: 500 }) + } +} diff --git a/app/api/purchase-orders/route.ts b/app/api/purchase-orders/route.ts new file mode 100644 index 0000000..7d42198 --- /dev/null +++ b/app/api/purchase-orders/route.ts @@ -0,0 +1,12 @@ +import { getPurchaseOrders } from "@/lib/data-utils" +import { NextResponse } from "next/server" + +export async function GET() { + try { + const purchaseOrders = await getPurchaseOrders() + return NextResponse.json(purchaseOrders) + } catch (error) { + console.error("Error fetching purchase orders:", error) + return NextResponse.json({ error: "Failed to fetch purchase orders" }, { status: 500 }) + } +} diff --git a/frontend/app/globals.css b/app/globals.css similarity index 100% rename from frontend/app/globals.css rename to app/globals.css diff --git a/frontend/app/goods-received/loading.tsx b/app/goods-received/loading.tsx similarity index 100% rename from frontend/app/goods-received/loading.tsx rename to app/goods-received/loading.tsx diff --git a/app/goods-received/page.tsx b/app/goods-received/page.tsx new file mode 100644 index 0000000..7bfe41d --- /dev/null +++ b/app/goods-received/page.tsx @@ -0,0 +1,81 @@ +import { Search, SlidersHorizontal, Bell } from "lucide-react" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs" +import Sidebar from "@/components/sidebar" +import GoodsReceivedTable from "@/components/goods-received-table" + +export default function GoodsReceivedPage() { + return ( +
+ +
+
+
+ +
+ +
+
+
+
+
+

Goods Received Notes

+
+
+
+
+ + +
+
+ + + + + All + + Complete + Partial + + +
+
+ +
+
+
+
+ ) +} diff --git a/frontend/app/invoice-extraction/page.tsx b/app/invoice-extraction/page.tsx similarity index 100% rename from frontend/app/invoice-extraction/page.tsx rename to app/invoice-extraction/page.tsx diff --git a/frontend/app/invoices/[id]/loading.tsx b/app/invoices/[id]/loading.tsx similarity index 100% rename from frontend/app/invoices/[id]/loading.tsx rename to app/invoices/[id]/loading.tsx diff --git a/frontend/app/invoices/[id]/page.tsx b/app/invoices/[id]/page.tsx similarity index 84% rename from frontend/app/invoices/[id]/page.tsx rename to app/invoices/[id]/page.tsx index 86392f1..b6625f2 100644 --- a/frontend/app/invoices/[id]/page.tsx +++ b/app/invoices/[id]/page.tsx @@ -1,6 +1,6 @@ "use client" -import { useState, useEffect } from "react" +import { useState } from "react" import { ArrowLeft, Search, Maximize, FileText, Circle, Edit, Plus } from "lucide-react" import { Button } from "@/components/ui/button" import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs" @@ -11,30 +11,11 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@ export default function InvoiceDetailsPage({ params }: { params: { id: string } }) { const [zoomLevel, setZoomLevel] = useState(100) - const [fileData, setFileData] = useState(null) - const [fileType, setFileType] = useState(null) - const [fileName, setFileName] = useState(null) - - // Mock data - in production this would come from your API - useEffect(() => { - // Simulate loading invoice data including file information - // In production, fetch from API endpoint like /api/invoices/${params.id} - - // For demo purposes, let's show an image of an invoice - // In production, this would be determined by the actual file type - setFileType('image/png') - setFileName('invoice-sample.png') - - // Using a local sample invoice image for demonstration - // In production, this would be the actual file URL from your backend - // For example: setFileData(`${API_URL}/media/invoice_uploads/${invoiceFile}`) - setFileData('/sample-invoice.png') - }, [params.id]) return ( -
+
-
+
@@ -132,54 +113,33 @@ export default function InvoiceDetailsPage({ params }: { params: { id: string }
- {!fileData ? ( -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- ) : fileType === 'application/pdf' ? ( -