|
|
1 일 전 | |
|---|---|---|
| .devcontainer | 2 일 전 | |
| backend | 1 일 전 | |
| database | 2 일 전 | |
| docker | 1 일 전 | |
| frontend | 1 일 전 | |
| .dockerignore | 2 일 전 | |
| .env.example | 1 일 전 | |
| .env.external | 2 일 전 | |
| .gitignore | 1 일 전 | |
| DEV_SETUP.md | 1 일 전 | |
| DOCKER_DEPLOYMENT.md | 1 일 전 | |
| DOCKER_README.md | 2 일 전 | |
| Dockerfile | 1 일 전 | |
| Dockerfile.unified | 2 일 전 | |
| Dockerfile.unified-working | 1 일 전 | |
| README.md | 1 일 전 | |
| build.sh | 1 일 전 | |
| composer.phar | 1 일 전 | |
| docker-compose.prod.yml | 2 일 전 | |
| docker-compose.unified.prod.yml | 2 일 전 | |
| docker-compose.unified.yml | 2 일 전 | |
| docker-compose.yml | 1 일 전 | |
| fix_image_urls.php | 1 일 전 | |
| test-env.php | 1 일 전 | |
| test_timer_stop.php | 1 일 전 |
A comprehensive inventory management system built with Vue 3 frontend and PHP backend, featuring inventory tracking, client management, project management, bookkeeping, and authentication.
The system uses a normalized database structure with proper relationships:
Clone the repository:
git clone <repository-url>
cd inventory
Database Setup:
# Create database and import complete schema
mysql -u root -p < backend/migrate_complete.sql
# Update database credentials
nano backend/config/database.php
Backend Server:
cd backend
php -S localhost:8080
Frontend Setup:
cd frontend
npm install
npm run dev -- --host 0.0.0.0 --port 3000
Access Application:
http://localhost:8080 (API)http://localhost:3000 (Web Interface)Backup existing database:
mysqldump -u root -p inventory_db > backup.sql
Run migration script:
mysql -u root -p inventory_db < backend/migrate_complete.sql
Restart services:
# Restart PHP server if running
sudo systemctl restart apache2
# or
sudo systemctl restart nginx
Update backend/config/database.php with your database credentials:
<?php
class Database {
private $host = "localhost";
private $db_name = "inventory_db";
private $username = "root";
private $password = "your_password";
public function getConnection() {
$conn = null;
try {
$conn = new PDO(
"mysql:host={$this->host};dbname={$this->db_name}",
$this->username,
$this->password
);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
return $conn;
} catch(PDOException $exception) {
echo "Connection error: " . $exception->getMessage();
return null;
}
}
}
?>
Create .env file for sensitive configuration:
DB_HOST=localhost
DB_NAME=inventory_db
DB_USER=root
DB_PASSWORD=your_password
Update frontend/src/main.js if needed for different API endpoints:
axios.defaults.baseURL = 'http://localhost:8000/api';
POST /api/auth.php - Login, Register, Logout
{
"action": "login|register|logout",
"username": "string",
"password": "string",
"email": "string",
"first_name": "string",
"last_name": "string"
}
GET /api/auth.php?action=status - Check authentication status
/api/items.php - List all items/api/items.php?id={id} - Get single item/api/items.php - Create new item/api/items.php - Update existing item/api/items.php?id={id} - Delete item/api/clients.php - List all clients/api/clients.php?id={id} - Get single client/api/clients.php?search={term} - Search clients/api/clients.php - Create new client/api/clients.php - Update existing client/api/clients.php?id={id} - Delete client/api/contact_persons.php?client_id={id} - Get contact persons for client/api/contact_persons.php?id={id} - Get single contact person/api/contact_persons.php - Create new contact person/api/contact_persons.php - Update existing contact person/api/contact_persons.php?id={id} - Delete contact person/api/timers.php?action=active - Get active timers/api/timers.php?action=list - Get timer historyPOST /api/timers.php - Start new timer
{
"action": "start",
"task_id": 1,
"user_id": 1,
"description": "Timer description"
}
POST /api/timer_stop.php - Stop timer
{
"action": "stop",
"id": 1
}
POST /api/timer_update.php - Update timer (convert to work hours)
{
"action": "update",
"id": 1,
"description": "Updated description",
"task_id": 1,
"hours": 2.5
}
GET /api/timer_history.php - Get timer history with filters
/api/work_hours.php - Get work hours/api/work_hours.php - Create work hour entry/api/work_hours.php - Update work hour entry/api/work_hours.php?id={id} - Delete work hour entry/api/rental_prices.php?item_id={id} - Get rental prices for item/api/rental_prices.php?id={id} - Get single rental price/api/rental_prices.php - Create new rental price/api/rental_prices.php - Update existing rental price/api/rental_prices.php?id={id} - Delete rental price/api/attachments.php?item_id={id} - Get attachments for item/api/attachments.php?id={id} - Get single attachment/api/attachments.php - Upload attachment file/api/attachments.php?id={id} - Delete attachment/api/upload.php - Upload picture files
multipart/form-data/api/projects.php - List all projects/api/projects.php?id={id} - Get single project/api/projects.php?customer_id={id} - Get projects for customer/api/projects.php - Create new project/api/projects.php - Update existing project/api/projects.php?id={id} - Delete project/api/subprojects.php?project_id={id} - Get subprojects for project/api/subprojects.php?id={id} - Get single subproject/api/subprojects.php - Create new subproject/api/subprojects.php - Update existing subproject/api/subprojects.php?id={id} - Delete subproject/api/invoices.php - List all invoices/api/invoices.php?id={id} - Get single invoice with items and payments/api/invoices.php - Create new invoice/api/invoices.php - Update existing invoice/api/invoices.php?id={id} - Delete invoice/api/chart_of_accounts.php - List chart of accounts/api/chart_of_accounts.php?id={id} - Get single account/api/chart_of_accounts.php - Create new account/api/chart_of_accounts.php - Update existing accountDELETE /api/chart_of_accounts.php?id={id} - Delete account
GET /api/journal_entries.php - List journal entries
GET /api/journal_entries.php?id={id} - Get single journal entry with transactions
POST /api/journal_entries.php - Create new journal entry with transactions
PUT /api/journal_entries.php - Update existing journal entry
DELETE /api/journal_entries.php?id={id} - Delete journal entry
GET /api/account_transactions.php?journal_entry_id={id} - Get transactions for journal entry
GET /api/account_transactions.php?id={id} - Get single transaction
POST /api/account_transactions.php - Create new transaction
PUT /api/account_transactions.php - Update existing transaction
DELETE /api/account_transactions.php?id={id} - Delete transaction
// Login
const loginResponse = await axios.post('/api/auth.php', {
action: 'login',
username: 'admin',
password: 'password123'
});
// Register
const registerResponse = await axios.post('/api/auth.php', {
action: 'register',
username: 'newuser',
email: 'user@example.com',
password: 'password123',
first_name: 'John',
last_name: 'Doe'
});
// Check authentication status
const authStatus = await axios.get('/api/auth.php?action=status');
// Get all items
const items = await axios.get('/api/items.php');
// Create new item with picture
const formData = new FormData();
formData.append('name', 'Laptop');
formData.append('description', 'High-performance laptop');
formData.append('quantity', 10);
formData.append('price', 1299.99);
formData.append('serial_number', 'LP001');
formData.append('picture', fileInput.files[0]); // File upload
const newItem = await axios.post('/api/items.php', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
// Start a new timer for a task
const startTimer = await axios.post('/api/timers.php', {
action: 'start',
task_id: 1,
user_id: 1,
description: 'Working on project setup'
});
// Get active timers
const activeTimers = await axios.get('/api/timers.php?action=active');
// Stop a timer
const stopTimer = await axios.post('/api/timer_stop.php', {
action: 'stop',
id: 1
});
// Update timer and convert to work hours
const updateTimer = await axios.post('/api/timer_update.php', {
action: 'update',
id: 1,
description: 'Updated description',
task_id: 1,
hours: 2.5
});
// Get timer history
const timerHistory = await axios.get('/api/timer_history.php');
// Create new client with y-tunnus
const newClient = await axios.post('/api/clients.php', {
y_tunnus: '1234567-8',
company_name: 'Tech Corp',
first_name: 'Jane',
last_name: 'Smith',
email: 'jane@techcorp.com',
hour_price: 150.00,
address: '123 Business St',
city: 'Helsinki',
country: 'Finland'
});
// Add contact person
const newContact = await axios.post('/api/contact_persons.php', {
client_id: 1,
first_name: 'John',
last_name: 'Doe',
email: 'john.doe@techcorp.com',
position: 'Project Manager',
is_primary: true
});
// Create new project
const newProject = await axios.post('/api/projects.php', {
customer_id: 1,
project_name: 'Website Redesign',
description: 'Complete website overhaul project',
status: 'planning',
start_date: '2024-01-15',
end_date: '2024-03-15',
budget: 50000.00
});
// Add subproject
const newSubproject = await axios.post('/api/subprojects.php', {
project_id: 1,
subproject_name: 'Frontend Development',
description: 'Create responsive frontend design',
status: 'in_progress',
budget: 15000.00
});
// Create invoice with line items
const newInvoice = await axios.post('/api/invoices.php', {
client_id: 1,
invoice_number: 'INV-2024-001',
issue_date: '2024-01-15',
due_date: '2024-02-15',
status: 'sent',
subtotal: 10000.00,
tax_amount: 2400.00,
total_amount: 12400.00,
transactions: [
{
account_id: 1, // Revenue account
debit_amount: 0,
credit_amount: 12400.00,
description: 'Website redesign services'
},
{
account_id: 2, // Bank account
debit_amount: 12400.00,
credit_amount: 0,
description: 'Payment received'
}
]
});
// Create journal entry with double-entry
const newJournalEntry = await axios.post('/api/journal_entries.php', {
entry_number: 'JE-2024-001',
entry_date: '2024-01-15',
description: 'Monthly revenue entry',
reference_number: 'REF-001',
transactions: [
{
account_id: 1, // Revenue account
debit_amount: 15000.00,
credit_amount: 0,
description: 'Service revenue'
},
{
account_id: 2, // Bank account
debit_amount: 0,
credit_amount: 15000.00,
description: 'Bank deposit'
}
]
});
password_hash() functionhtmlspecialchars()Environment Configuration
export NODE_ENV=production
export DB_HOST=your-production-host
Web Server Configuration
Database Optimization
This project is licensed under the MIT License - feel free to use, modify, and distribute according to your needs.
Last Updated: April 2026 Version: 2.0.0 Compatible with: PHP 7.4+, MySQL 5.7+, Node.js 14+, Vue 3
inventory/
├── backend/
│ ├── config/
│ │ └── database.php
│ ├── models/
│ │ ├── Item.php
│ │ ├── RentalPrice.php
│ │ ├── Attachment.php
│ │ ├── Client.php
│ │ ├── ContactPerson.php
│ │ ├── Project.php
│ │ ├── Subproject.php
│ │ ├── ChartOfAccounts.php
│ │ ├── JournalEntry.php
│ │ ├── AccountTransaction.php
│ │ └── User.php
│ ├── api/
│ │ ├── items.php
│ │ ├── rental_prices.php
│ │ ├── attachments.php
│ │ ├── clients.php
│ │ ├── contact_persons.php
│ │ ├── projects.php
│ │ ├── subprojects.php
│ │ ├── invoices.php
│ │ ├── chart_of_accounts.php
│ │ ├── journal_entries.php
│ │ ├── account_transactions.php
│ │ ├── auth.php
│ │ └── upload.php
│ ├── migrate_complete.sql
│ ├── migrate_y_tunnus.sql
│ ├── migrate_new_tables.sql
│ ├── migrate_clients.sql
│ ├── migrate_projects.sql
│ ├── migrate_bookkeeping.sql
│ └── migrate_auth.sql
├── frontend/
│ ├── src/
│ │ ├── App.vue
│ │ └── main.js
│ ├── index.html
│ ├── package.json
│ └── vite.config.js
└── README.md
For new installations, use the complete migration script:
mysql -u root -p < backend/migrate_complete.sql
For upgrading existing installations: ```bash
mysql -u root -p < backend/migrate_y_tunnus.sql
mysql -u root -p < backend/migrate_new_tables.sql
mysql -u root -p < backend/migrate_clients.sql
mysql -u root -p < backend/migrate_projects.sql
postal_code - Postal code (optional)country - Country (optional)notes - Additional notes (optional)created_at - Creation timestampupdated_at - Last update timestampid - Primary keyclient_id - Foreign key to clients tablefirst_name - First name (required)last_name - Last name (required)email - Email address (optional)phone - Phone number (optional)position - Job position/title (optional)is_primary - Primary contact flag (boolean)created_at - Creation timestampupdated_at - Last update timestampbackend/api/uploads/ directorybackend/api/attachments/ directory