roles guard + docs + logo
This commit is contained in:
+1
-1
@@ -145,5 +145,5 @@ vite.config.ts.timestamp-*
|
|||||||
# custom files
|
# custom files
|
||||||
AGENTS.md
|
AGENTS.md
|
||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
ROLES.md
|
|
||||||
SESSION.php
|
SESSION.php
|
||||||
|
docs/
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to TRx WMS are documented here.
|
||||||
|
Format: `## [version] — YYYY-MM-DD` with sections Added / Changed / Fixed / Removed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Planned
|
||||||
|
- Role-based access control enforcement across all API endpoints and UI pages (see `ROLES.md`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.6.0] — 2026-05-06
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Barcode system — `md_barcode` table, SKU label page (`ics/sku_barcode_label.php`), Location label page (`ics/location_barcode_label.php`)
|
||||||
|
- `scanner.js` — unified scanner module supporting USB scanner, handheld, phone camera (Html5Qrcode), and clipboard paste
|
||||||
|
- Scan-driven stock flows — scan SKU label → scan location label → F2 to save (no mouse required)
|
||||||
|
- `ics/api/engine/barcode_lookup.php` — validates barcode string, returns typed result (`sku` / `loc` / `raw`)
|
||||||
|
- `ics/api/engine/validate_scan_location.php` — pre-save location validation for stock in/out/transfer
|
||||||
|
- `ics/api/engine/sku_label_lots.php`, `sku_label_products.php` — lot and product data feeds for SKU label page
|
||||||
|
- Cost, price, and margin fields on `md_product`
|
||||||
|
- Contact module linked to setting sidebar
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `location_barcode_label.php` — `ON DUPLICATE KEY UPDATE` now includes `status = 1` so previewing a previously-disabled location barcode re-enables it
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.5.0] — 2026-04
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Purchase Orders (`po/`) — create, confirm, receive, cancel, payment tracking
|
||||||
|
- Order module (`order/`) — sales orders, returns, invoices (invoice / credit note / debit note), order confirmation, payment status
|
||||||
|
- `td_order`, `td_invoice`, `td_return`, `td_purchase_order` tables
|
||||||
|
- Invoice print view (`order/print_invoice.php`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.4.0] — 2026-03
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Warehouse location modes — simple (warehouse + rack) and advanced (warehouse + zone + aisle + rack)
|
||||||
|
- `company_setting` keys: `advanced_location`, `location_label_rack/zone/aisle`, `default_stock_status`, `auto_complete_on_ship`, `auto_invoice_and_credit_note`
|
||||||
|
- Per-warehouse stock tables (`td_stock_{warehouse_id}`) — balance = `SUM(in) - SUM(out)` where `status = 1`
|
||||||
|
- Stock approval flow — transactions created as `status = 0` (draft) and approved separately
|
||||||
|
- Rack occupancy report (`reports/occupy_rack.php`)
|
||||||
|
- Expired / near-expiry report (`reports/expired_stock.php`)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Warehouse layers made switchable via `advanced_location` setting
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.3.0] — 2026-02
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Contact module (`contact/`) — supplier/customer contacts, contact types
|
||||||
|
- Stock movement report with date and SKU filters
|
||||||
|
- Product lot report with expiry date tracking
|
||||||
|
- Low-stock dashboard widget with restock shortcut
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.2.0] — 2026-01
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Multi-tenant branch support — `company_list`, `company_map_user`, branch switcher in topbar
|
||||||
|
- User management (`setting/users.php`) — invite by email, role assignment, remove member
|
||||||
|
- SMTP configuration (`setting/smtp.php`)
|
||||||
|
- OTP validation on every API request (HMAC-SHA1 based on user password + session time)
|
||||||
|
- CSRF token enforcement on all POST requests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.1.0] — 2025-12
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial project scaffold — PHP + MySQL + Bootstrap 5 + jQuery
|
||||||
|
- Login / registration / onboarding flow
|
||||||
|
- Product master (`inventory/product.php`) — SKU, name, UOM, category, barcode
|
||||||
|
- Warehouse master (`inventory/warehouse.php`) — warehouses and rack definitions
|
||||||
|
- Stock In / Out / Transfer pages with manual form entry
|
||||||
|
- `td_stock` base table structure
|
||||||
|
- Dashboard with basic stock summary
|
||||||
@@ -1,2 +1,136 @@
|
|||||||
# inapp-pro
|
# TRx WMS
|
||||||
inapp-pro Inventory Dashboard Admin Template
|
|
||||||
|
A multi-tenant Warehouse Management System (WMS) built with PHP, MySQL, and vanilla JavaScript. Designed for small-to-medium operations that need barcode-driven stock control, lot/serial traceability, and multi-warehouse support — accessible from any browser without installing a native app.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### Dashboard
|
||||||
|
- Live stock overview with key metrics (total SKUs, low-stock count, near-expiry alerts)
|
||||||
|
- Low-stock product list with one-click restock shortcut to Stock In
|
||||||
|
- Dashboard widgets per warehouse
|
||||||
|
|
||||||
|
### Inventory Management
|
||||||
|
- **Product master** — SKU, name, unit of measure, barcode, category, cost/price/margin tracking
|
||||||
|
- **Categories** — group products for filtering and reporting
|
||||||
|
- **Warehouse master** — multi-warehouse support; simple or advanced location mode (warehouse → rack, or warehouse → zone → aisle → rack)
|
||||||
|
- **Storage / rack master** — define physical rack locations per warehouse
|
||||||
|
- **Product lots** — lot number, expiry date, per-lot traceability across all warehouses
|
||||||
|
|
||||||
|
### Stock Control (ICS)
|
||||||
|
- **Stock In** — receive stock into a specific location; supports lot, expiry, serial, unit price, and contact (supplier)
|
||||||
|
- **Stock Out** — remove stock from a location; cascaded lot/serial dropdowns filtered to available stock
|
||||||
|
- **Stock Transfer** — move stock between any two locations (same or different warehouse)
|
||||||
|
- **Stock Overview** — real-time balance per SKU across all warehouses and locations
|
||||||
|
- Two-step approval flow: transactions created as `pending` and approved separately
|
||||||
|
|
||||||
|
### Barcode System
|
||||||
|
- **SKU barcode labels** — generate `SKU|{sku}|{lot}|{serial}` labels; print, disable, re-enable per serial
|
||||||
|
- **Location barcode labels** — generate `LOC|{warehouse}|{rack}` (simple) or `LOC|{warehouse}|{zone}|{aisle}|{rack}` (advanced) labels
|
||||||
|
- **Scanner support** — USB scanner, handheld scanner, phone camera (Html5Qrcode), and clipboard paste all handled by a unified `scanner.js` module
|
||||||
|
- Scan-driven stock flows: scan SKU label → scan location label → press F2 to save (no mouse required)
|
||||||
|
- Disabled barcodes are rejected at scan time with a clear error message
|
||||||
|
|
||||||
|
### Orders
|
||||||
|
- **Sales orders** — create, confirm, and track customer orders
|
||||||
|
- **Returns** — manage product returns linked to original orders
|
||||||
|
- **Invoices** — generate and print invoices per order
|
||||||
|
- **Purchase orders (PO)** — create and track supplier purchase orders
|
||||||
|
|
||||||
|
### Contacts
|
||||||
|
- Supplier and customer contact management
|
||||||
|
- Contact types (supplier, customer, other)
|
||||||
|
- Linked to stock-in, stock-out, orders, and POs
|
||||||
|
|
||||||
|
### Reports
|
||||||
|
- **Stock Movement** — full transaction history with in/out/net summary; filterable by date, SKU, warehouse
|
||||||
|
- **Product Lots** — lot-level stock balance with expiry dates across all warehouses
|
||||||
|
- **Expired / Near Expiry** — products approaching or past their expiry date
|
||||||
|
- **Rack Occupancy** — visual overview of which racks are occupied, empty, or locked
|
||||||
|
|
||||||
|
### Settings
|
||||||
|
- **Company profile** — name, logo, branch details
|
||||||
|
- **System config** — location mode (simple/advanced), custom zone/aisle/rack labels, stock uniqueness rules
|
||||||
|
- **User management** — invite users by email, assign roles (admin / staff / viewer), remove members
|
||||||
|
- **SMTP** — configure outbound email for notifications
|
||||||
|
- **Profile** — per-user name, username, password, profile picture
|
||||||
|
|
||||||
|
### Multi-Tenant / Branch Support
|
||||||
|
- Each company is isolated; users can belong to multiple companies
|
||||||
|
- Branch switcher in the topbar for users with access to more than one company
|
||||||
|
- All data (products, stock, orders, contacts) is scoped to the active company
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- Session-based authentication with TOTP-style OTP validation on every API request
|
||||||
|
- CSRF token enforcement on all POST requests
|
||||||
|
- Role-based access control: `owner`, `admin`, `staff`, `viewer` (see `ROLES.md`)
|
||||||
|
- Passwords hashed; profile picture uploads sandboxed to `uploads/profile/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
| Layer | Technology |
|
||||||
|
|-------|-----------|
|
||||||
|
| Backend | PHP 8.x, Apache |
|
||||||
|
| Databases | MySQL — `wms` (system/auth), `wms2` (operational data) |
|
||||||
|
| Frontend | Bootstrap 5, jQuery, Flatpickr, ApexCharts, JsBarcode, Html5Qrcode |
|
||||||
|
| Build | Vite (`npm run dev` / `npm run build`) |
|
||||||
|
| Auth | Session + HMAC-SHA1 OTP + CSRF tokens |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Module Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
app/
|
||||||
|
├── dashboard/ # Dashboard and low-stock widgets
|
||||||
|
├── ics/ # Stock In / Out / Transfer, barcode labels
|
||||||
|
├── inventory/ # Product, warehouse, rack, category masters
|
||||||
|
├── order/ # Sales orders, returns, invoices
|
||||||
|
├── po/ # Purchase orders
|
||||||
|
├── reports/ # Stock movement, lots, expiry, rack occupancy
|
||||||
|
├── contact/ # Supplier / customer contacts
|
||||||
|
├── setting/ # Company, users, SMTP, system config, profile
|
||||||
|
├── assets/
|
||||||
|
│ ├── js/ # main.js, scanner.js, custom.js
|
||||||
|
│ ├── css/ # main.css, custom.css
|
||||||
|
│ └── utils/ # db_auth.php, db_helpers.php, shared classes
|
||||||
|
└── login/ # Login, OTP, onboarding
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Front-end assets (Vite)
|
||||||
|
npm run dev
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Syntax-check a PHP file
|
||||||
|
php -l app/ics/manage_stock_in.php
|
||||||
|
|
||||||
|
# Apply a schema migration to the client database
|
||||||
|
mysql -uroot -p2618 wms2 < migration.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
App is served by Apache at `http://localhost/wms/app/`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
| File | Contents |
|
||||||
|
|------|----------|
|
||||||
|
| `CHANGELOG.md` | Version history and notable changes |
|
||||||
|
| `docs/ROLES.md` | Role-based access control spec (admin / staff / viewer) |
|
||||||
|
| `docs/DATABASE.md` | Full schema for both databases — tables, columns, relationships |
|
||||||
|
| `docs/API.md` | All API endpoints — request fields, response format, error codes |
|
||||||
|
| `docs/DEPLOYMENT.md` | Installation, Apache/PHP/MySQL setup, environment checklist |
|
||||||
|
| `docs/TESTING.md` | Manual test checklists — barcode flow, stock ops, regression |
|
||||||
|
| `docs/SECURITY.md` | Auth model, OTP flow, CSRF, session management, XSS/SQL rules |
|
||||||
|
| `docs/STOCK.md` | Stock ledger, approval flow, rack lifecycle, StockManager/WarehouseManager |
|
||||||
|
| `docs/SCANNER.md` | scanner.js internals, device support, integrating scanning into new pages |
|
||||||
|
| `docs/CONTRIBUTING.md` | Patterns for adding new APIs, pages, modules, settings, and schema changes |
|
||||||
|
|||||||
@@ -89,3 +89,14 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logo-area > a > img:first-child {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
transition: width 0.2s ease, height 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar.collapsed .logo-area > a > img:first-child {
|
||||||
|
width: 24px !important;
|
||||||
|
height: 24px !important;
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 334 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 11 KiB |
@@ -786,3 +786,25 @@ function set_btn_state(selector, enabled, hint) {
|
|||||||
.attr('title', hint || '');
|
.attr('title', hint || '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ROLE_RANK = { viewer: 0, staff: 1, admin: 2, owner: 3 };
|
||||||
|
|
||||||
|
function apply_role_ui() {
|
||||||
|
var role = document.getElementById('session-context')?.dataset.role || 'viewer';
|
||||||
|
var rank = ROLE_RANK[role] ?? 0;
|
||||||
|
|
||||||
|
$('[data-min-role]').each(function() {
|
||||||
|
var required = ROLE_RANK[$(this).data('min-role')] ?? 99;
|
||||||
|
if (rank < required) $(this).hide();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
apply_role_ui();
|
||||||
|
if (window.MutationObserver) {
|
||||||
|
var roleObserver = new MutationObserver(function() {
|
||||||
|
apply_role_ui();
|
||||||
|
});
|
||||||
|
roleObserver.observe(document.body, { childList: true, subtree: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -9,6 +9,15 @@ require_once __DIR__."/db_helpers.php";
|
|||||||
// xhr.responseJSON from being populated automatically in ajax_request().
|
// xhr.responseJSON from being populated automatically in ajax_request().
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
if (!function_exists('require_role')) {
|
||||||
|
function require_role(string $user_role, array $allowed): void {
|
||||||
|
if (!in_array($user_role, $allowed, true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit(json_encode(['success' => 0, 'message' => 'Access denied.']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!empty($_SESSION["login_company_id"])){
|
if(!empty($_SESSION["login_company_id"])){
|
||||||
|
|
||||||
// CSRF Validation — add right at the top of the logged-in block
|
// CSRF Validation — add right at the top of the logged-in block
|
||||||
@@ -63,6 +72,9 @@ if(!empty($_SESSION["login_company_id"])){
|
|||||||
exit(json_encode($answer));
|
exit(json_encode($answer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$user_role = $map[0]['role'] ?? 'viewer';
|
||||||
|
$_SESSION['login_role'] = $user_role;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up ANSWER
|
// set up ANSWER
|
||||||
@@ -86,6 +98,7 @@ if(!empty($_SESSION["login_company_id"])){
|
|||||||
|
|
||||||
$company_id = (int)$_SESSION["login_company_id"];
|
$company_id = (int)$_SESSION["login_company_id"];
|
||||||
$user_id = (int)$_SESSION["login_user_id"];
|
$user_id = (int)$_SESSION["login_user_id"];
|
||||||
|
$user_role = $_SESSION['login_role'] ?? ($user_role ?? 'viewer');
|
||||||
$uuid = bin2hex(random_bytes(16));
|
$uuid = bin2hex(random_bytes(16));
|
||||||
|
|
||||||
// create json for table logging
|
// create json for table logging
|
||||||
|
|||||||
@@ -33,6 +33,10 @@
|
|||||||
$aisle = trim($data['aisle'] ?? '');
|
$aisle = trim($data['aisle'] ?? '');
|
||||||
$rack = trim($data['rack'] ?? '');
|
$rack = trim($data['rack'] ?? '');
|
||||||
|
|
||||||
|
if ($label_action !== 'list') {
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
}
|
||||||
|
|
||||||
if ($label_action === 'list') {
|
if ($label_action === 'list') {
|
||||||
$sth = $pdo2->prepare(
|
$sth = $pdo2->prepare(
|
||||||
"SELECT barcode, warehouse_id, zone, aisle, rack, status, print_count, last_printed_dt
|
"SELECT barcode, warehouse_id, zone, aisle, rack, status, print_count, last_printed_dt
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$csm = new CompanySettingManager($pdo1, $company_id);
|
$csm = new CompanySettingManager($pdo1, $company_id);
|
||||||
$auto_approve = (int)$csm->get('default_stock_status') === 1;
|
$auto_approve = (int)$csm->get('default_stock_status') === 1;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$csm = new CompanySettingManager($pdo1, $company_id);
|
$csm = new CompanySettingManager($pdo1, $company_id);
|
||||||
$auto_approve = (int)$csm->get('default_stock_status') === 1;
|
$auto_approve = (int)$csm->get('default_stock_status') === 1;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$csm = new CompanySettingManager($pdo1, $company_id);
|
$csm = new CompanySettingManager($pdo1, $company_id);
|
||||||
$auto_approve = (int)$csm->get('default_stock_status') === 1;
|
$auto_approve = (int)$csm->get('default_stock_status') === 1;
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,10 @@
|
|||||||
$product_sku = trim($data['product_sku'] ?? '');
|
$product_sku = trim($data['product_sku'] ?? '');
|
||||||
$lot_number = trim($data['lot_number'] ?? '');
|
$lot_number = trim($data['lot_number'] ?? '');
|
||||||
|
|
||||||
|
if (in_array($label_action, ['create', 'print', 'disable', 'enable'], true)) {
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
}
|
||||||
|
|
||||||
if ($label_action === 'print') {
|
if ($label_action === 'print') {
|
||||||
$barcode = trim($data['barcode'] ?? '');
|
$barcode = trim($data['barcode'] ?? '');
|
||||||
if ($barcode === '') {
|
if ($barcode === '') {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$whMgmt = new WarehouseManager($pdo2, $company_id);
|
$whMgmt = new WarehouseManager($pdo2, $company_id);
|
||||||
|
|
||||||
$mode = $data['mode'] ?? '';
|
$mode = $data['mode'] ?? '';
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin', 'staff'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -17,13 +21,13 @@
|
|||||||
<p class="mb-0 text-muted">Print or reprint labels from the rack master list.</p>
|
<p class="mb-0 text-muted">Print or reprint labels from the rack master list.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
<button id="btn_print" class="btn btn-outline-success" onclick="print_selected_label()" disabled>
|
<button id="btn_print" class="btn btn-outline-success" data-min-role="staff" onclick="print_selected_label()" disabled>
|
||||||
<i class="ti ti-printer me-1"></i>Print
|
<i class="ti ti-printer me-1"></i>Print
|
||||||
</button>
|
</button>
|
||||||
<button id="btn_disable" class="btn btn-outline-danger" onclick="disable_selected_label()" disabled>
|
<button id="btn_disable" class="btn btn-outline-danger" data-min-role="staff" onclick="disable_selected_label()" disabled>
|
||||||
<i class="ti ti-ban me-1"></i>Disable
|
<i class="ti ti-ban me-1"></i>Disable
|
||||||
</button>
|
</button>
|
||||||
<button id="btn_reenable" class="btn btn-outline-primary d-none" onclick="reenable_selected_label()">
|
<button id="btn_reenable" class="btn btn-outline-primary d-none" data-min-role="staff" onclick="reenable_selected_label()">
|
||||||
<i class="ti ti-refresh me-1"></i>Re-enable
|
<i class="ti ti-refresh me-1"></i>Re-enable
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin', 'staff'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -114,7 +118,7 @@
|
|||||||
|
|
||||||
<!-- Submit Button -->
|
<!-- Submit Button -->
|
||||||
<div class="mb-3 col-lg-12">
|
<div class="mb-3 col-lg-12">
|
||||||
<button type="submit" class="btn btn-primary" onclick="manage_stock_in();">Add Stock</button>
|
<button type="submit" class="btn btn-primary" data-min-role="staff" onclick="manage_stock_in();">Add Stock</button>
|
||||||
<button type="button" class="btn btn-success ms-2 d-none" id="approve_stock_btn" onclick="approve_current_stock();">Approve</button>
|
<button type="button" class="btn btn-success ms-2 d-none" id="approve_stock_btn" onclick="approve_current_stock();">Approve</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin', 'staff'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -103,7 +107,7 @@
|
|||||||
|
|
||||||
<!-- Submit Button -->
|
<!-- Submit Button -->
|
||||||
<div class="mb-3 col-lg-12">
|
<div class="mb-3 col-lg-12">
|
||||||
<button type="submit" class="btn btn-primary" onclick="manage_stock_out();">Remove Stock</button>
|
<button type="submit" class="btn btn-primary" data-min-role="staff" onclick="manage_stock_out();">Remove Stock</button>
|
||||||
<button type="button" class="btn btn-success ms-2 d-none" id="approve_stock_btn" onclick="approve_current_stock();">Approve</button>
|
<button type="button" class="btn btn-success ms-2 d-none" id="approve_stock_btn" onclick="approve_current_stock();">Approve</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin', 'staff'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -135,7 +139,7 @@
|
|||||||
|
|
||||||
<!-- Submit -->
|
<!-- Submit -->
|
||||||
<div class="mb-3 col-lg-12">
|
<div class="mb-3 col-lg-12">
|
||||||
<button type="submit" class="btn btn-primary" onclick="manage_stock_transfer();">Transfer Stock</button>
|
<button type="submit" class="btn btn-primary" data-min-role="staff" onclick="manage_stock_transfer();">Transfer Stock</button>
|
||||||
<button type="button" class="btn btn-success ms-2 d-none" id="approve_stock_btn" onclick="approve_current_stock();">Approve</button>
|
<button type="button" class="btn btn-success ms-2 d-none" id="approve_stock_btn" onclick="approve_current_stock();">Approve</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin', 'staff'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -17,13 +21,13 @@
|
|||||||
<p class="mb-0 text-muted">Print or reprint product identity labels from the lot master list.</p>
|
<p class="mb-0 text-muted">Print or reprint product identity labels from the lot master list.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
<button class="btn btn-success" onclick="open_create_label_modal()">
|
<button class="btn btn-success" data-min-role="staff" onclick="open_create_label_modal()">
|
||||||
<i class="ti ti-plus me-1"></i>New Barcode
|
<i class="ti ti-plus me-1"></i>New Barcode
|
||||||
</button>
|
</button>
|
||||||
<button id="btn_print" class="btn btn-outline-success" onclick="print_selected_label()" disabled>
|
<button id="btn_print" class="btn btn-outline-success" data-min-role="staff" onclick="print_selected_label()" disabled>
|
||||||
<i class="ti ti-printer me-1"></i>Print
|
<i class="ti ti-printer me-1"></i>Print
|
||||||
</button>
|
</button>
|
||||||
<button id="btn_disable" class="btn btn-outline-danger" onclick="disable_selected_label()" disabled>
|
<button id="btn_disable" class="btn btn-outline-danger" data-min-role="staff" onclick="disable_selected_label()" disabled>
|
||||||
<i class="ti ti-ban me-1"></i>Disable
|
<i class="ti ti-ban me-1"></i>Disable
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>ThreeWMS</title>
|
<title>TRx WMS</title>
|
||||||
<meta name="csrf-token" content="<?= htmlspecialchars($_SESSION['csrf_token'] ?? '') ?>">
|
<meta name="csrf-token" content="<?= htmlspecialchars($_SESSION['csrf_token'] ?? '') ?>">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="<?php echo $server_url?>assets/images/favicon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="<?php echo $server_url?>assets/images/favicon.png">
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
$current_page = basename($_SERVER['PHP_SELF']);
|
$current_page = basename($_SERVER['PHP_SELF']);
|
||||||
|
$master_role = $_SESSION['login_role'] ?? 'viewer';
|
||||||
|
$master_can_admin = in_array($master_role, ['owner', 'admin'], true);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- SIDEBAR -->
|
<!-- SIDEBAR -->
|
||||||
@@ -28,13 +30,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<?php if ($master_can_admin): ?>
|
||||||
<a class="nav-link" href="<?php echo $server_url?>ics/sku_barcode_label.php">
|
|
||||||
<i class="ti ti-barcode"></i>
|
|
||||||
<span class="nav-text">SKU Labels</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a class="nav-link <?php echo in_array($current_page, ['warehouse.php', 'manage_warehouse.php', 'manage_storage.php']) ? 'active' : ''; ?>"
|
<a class="nav-link <?php echo in_array($current_page, ['warehouse.php', 'manage_warehouse.php', 'manage_storage.php']) ? 'active' : ''; ?>"
|
||||||
href="<?php echo $server_url?>inventory/warehouse.php">
|
href="<?php echo $server_url?>inventory/warehouse.php">
|
||||||
@@ -42,13 +38,7 @@
|
|||||||
<span class="nav-text">Warehouse Location</span>
|
<span class="nav-text">Warehouse Location</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
<li>
|
|
||||||
<a class="nav-link" href="<?php echo $server_url?>ics/location_barcode_label.php">
|
|
||||||
<i class="ti ti-map-pin-code"></i>
|
|
||||||
<span class="nav-text">Location Labels</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a class="nav-link <?php echo in_array($current_page, ['contact.php', 'manage_contact.php', 'manage_contact_type.php']) ? 'active' : ''; ?>"
|
<a class="nav-link <?php echo in_array($current_page, ['contact.php', 'manage_contact.php', 'manage_contact_type.php']) ? 'active' : ''; ?>"
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
$current_page = basename($_SERVER['PHP_SELF']);
|
$current_page = basename($_SERVER['PHP_SELF']);
|
||||||
|
$setting_role = $_SESSION['login_role'] ?? 'viewer';
|
||||||
|
$setting_can_admin = in_array($setting_role, ['owner', 'admin'], true);
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- SIDEBAR -->
|
<!-- SIDEBAR -->
|
||||||
@@ -36,6 +38,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<?php if ($setting_can_admin): ?>
|
||||||
<li>
|
<li>
|
||||||
<a class="nav-link <?php echo $current_page === 'users.php' ? 'active' : ''; ?>"
|
<a class="nav-link <?php echo $current_page === 'users.php' ? 'active' : ''; ?>"
|
||||||
href="<?php echo $server_url?>setting/users.php">
|
href="<?php echo $server_url?>setting/users.php">
|
||||||
@@ -43,6 +46,7 @@
|
|||||||
<span class="nav-text">Users Access</span>
|
<span class="nav-text">Users Access</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a class="nav-link <?php echo $current_page === 'smtp.php' ? 'active' : ''; ?>"
|
<a class="nav-link <?php echo $current_page === 'smtp.php' ? 'active' : ''; ?>"
|
||||||
@@ -52,6 +56,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<?php if ($setting_can_admin): ?>
|
||||||
<li>
|
<li>
|
||||||
<a class="nav-link <?php echo $current_page === 'system_config.php' ? 'active' : ''; ?>"
|
<a class="nav-link <?php echo $current_page === 'system_config.php' ? 'active' : ''; ?>"
|
||||||
href="<?php echo $server_url?>setting/system_config.php">
|
href="<?php echo $server_url?>setting/system_config.php">
|
||||||
@@ -59,6 +64,7 @@
|
|||||||
<span class="nav-text">System Configuration</span>
|
<span class="nav-text">System Configuration</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<!-- Back -->
|
<!-- Back -->
|
||||||
<li class="nav-text-space mt-2">
|
<li class="nav-text-space mt-2">
|
||||||
|
|||||||
+21
-1
@@ -1,10 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
$sidebar_role = $_SESSION['login_role'] ?? 'viewer';
|
||||||
|
$sidebar_can_staff = in_array($sidebar_role, ['owner', 'admin', 'staff'], true);
|
||||||
|
?>
|
||||||
<!-- SIDEBAR -->
|
<!-- SIDEBAR -->
|
||||||
<aside id="sidebar" class="sidebar overflow-y-auto">
|
<aside id="sidebar" class="sidebar overflow-y-auto">
|
||||||
<div class="logo-area">
|
<div class="logo-area">
|
||||||
<a href="index.html" class="d-inline-flex">
|
<a href="index.html" class="d-inline-flex">
|
||||||
<img src="<?php echo $server_url?>assets/images/favicon.png" alt="" width="40"/>
|
<img src="<?php echo $server_url?>assets/images/favicon.png" alt="" width="40"/>
|
||||||
<span class="logo-text ms-2">
|
<span class="logo-text ms-2">
|
||||||
<img src="<?php echo $server_url?>assets/images/logo.svg" alt="" />
|
<img src="<?php echo $server_url?>assets/images/logo.png" alt="" height="40"/>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,6 +46,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<?php if ($sidebar_can_staff): ?>
|
||||||
<li>
|
<li>
|
||||||
<a class="nav-link" href="<?php echo $server_url?>ics/stock_in.php">
|
<a class="nav-link" href="<?php echo $server_url?>ics/stock_in.php">
|
||||||
<i class="ti ti-package-import"></i>
|
<i class="ti ti-package-import"></i>
|
||||||
@@ -63,6 +68,21 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a class="nav-link" href="<?php echo $server_url?>ics/sku_barcode_label.php">
|
||||||
|
<i class="ti ti-barcode"></i>
|
||||||
|
<span class="nav-text">SKU Labels</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a class="nav-link" href="<?php echo $server_url?>ics/location_barcode_label.php">
|
||||||
|
<i class="ti ti-map-pin-code"></i>
|
||||||
|
<span class="nav-text">Location Labels</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<!-- Orders & Sales -->
|
<!-- Orders & Sales -->
|
||||||
<li class="nav-text-space">
|
<li class="nav-text-space">
|
||||||
<small class="nav-text text-muted">Orders & Sales</small>
|
<small class="nav-text text-muted">Orders & Sales</small>
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ $topbar_avatar_src = $topbar_picture
|
|||||||
<!-- Global Variables -->
|
<!-- Global Variables -->
|
||||||
<div id="session-context"
|
<div id="session-context"
|
||||||
data-company-id="<?php echo htmlspecialchars($_SESSION['login_company_id'] ?? 0, ENT_QUOTES, 'UTF-8'); ?>"
|
data-company-id="<?php echo htmlspecialchars($_SESSION['login_company_id'] ?? 0, ENT_QUOTES, 'UTF-8'); ?>"
|
||||||
data-otp="<?php echo htmlspecialchars($_SESSION['otp'] ?? '', ENT_QUOTES, 'UTF-8'); ?>">
|
data-otp="<?php echo htmlspecialchars($_SESSION['otp'] ?? '', ENT_QUOTES, 'UTF-8'); ?>"
|
||||||
|
data-role="<?php echo htmlspecialchars($_SESSION['login_role'] ?? 'viewer', ENT_QUOTES, 'UTF-8'); ?>">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Switch Branch Modal -->
|
<!-- Switch Branch Modal -->
|
||||||
@@ -121,6 +122,7 @@ $topbar_avatar_src = $topbar_picture
|
|||||||
// Global Variables
|
// Global Variables
|
||||||
var server_url = '<?php echo $server_url; ?>';
|
var server_url = '<?php echo $server_url; ?>';
|
||||||
var prop_limit = '<?php echo $prop['limit']; ?>';
|
var prop_limit = '<?php echo $prop['limit']; ?>';
|
||||||
|
var user_role = document.getElementById('session-context')?.dataset.role || 'viewer';
|
||||||
|
|
||||||
// ── Log out ───────────────────────────────────────────────────────────────────
|
// ── Log out ───────────────────────────────────────────────────────────────────
|
||||||
function log_out() {
|
function log_out() {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/ProductManager.php';
|
require '../../../assets/utils/classes/ProductManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) {
|
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) {
|
||||||
$product = new ProductManager($pdo, $company_id);
|
$product = new ProductManager($pdo, $company_id);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
require '../../../assets/utils/classes/FileUploader.php';
|
require '../../../assets/utils/classes/FileUploader.php';
|
||||||
require '../../../assets/utils/classes/ProductManager.php';
|
require '../../../assets/utils/classes/ProductManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
$id = (int)$data['id'];
|
$id = (int)$data['id'];
|
||||||
$min_stock = (float)($data['min_stock'] ?? 0);
|
$min_stock = (float)($data['min_stock'] ?? 0);
|
||||||
$reorder_point = (float)($data['reorder_point'] ?? 0);
|
$reorder_point = (float)($data['reorder_point'] ?? 0);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$setting = new CompanySettingManager($pdo1, $company_id, $pdo2);
|
$setting = new CompanySettingManager($pdo1, $company_id, $pdo2);
|
||||||
$advanced_location = (int)$setting->get('advanced_location') === 1;
|
$advanced_location = (int)$setting->get('advanced_location') === 1;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$newWarehouseId = null;
|
$newWarehouseId = null;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/ProductManager.php';
|
require '../../../assets/utils/classes/ProductManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/ProductManager.php';
|
require '../../../assets/utils/classes/ProductManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
dbTransaction($pdo2, function($pdo) use ($data, $company_id) {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -124,7 +128,7 @@
|
|||||||
placeholder="Enter product description"></textarea>
|
placeholder="Enter product description"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
<button type="submit" class="btn btn-primary" onclick="manage_product();">Create</button>
|
<button type="submit" class="btn btn-primary" data-min-role="admin" onclick="manage_product();">Create</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -99,7 +103,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
<button type="submit" class="btn btn-primary" onclick="manage_storage();">Add Storage</button>
|
<button type="submit" class="btn btn-primary" data-min-role="admin" onclick="manage_storage();">Add Storage</button>
|
||||||
<button type="reset" class="btn btn-secondary" onclick="reset_input('#storageForm')">Clear</button>
|
<button type="reset" class="btn btn-secondary" onclick="reset_input('#storageForm')">Clear</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@@ -60,7 +64,7 @@
|
|||||||
placeholder="Enter warehouse description"></textarea>
|
placeholder="Enter warehouse description"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
<button type="submit" class="btn btn-primary" onclick="manage_warehouse();">Add Warehouse</button>
|
<button type="submit" class="btn btn-primary" data-min-role="admin" onclick="manage_warehouse();">Add Warehouse</button>
|
||||||
<button type="reset" class="btn btn-secondary" onclick="reset_input('#warehouseForm')">Clear</button>
|
<button type="reset" class="btn btn-secondary" onclick="reset_input('#warehouseForm')">Clear</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -171,7 +171,7 @@
|
|||||||
<p class="mb-0">List of all products</p>
|
<p class="mb-0">List of all products</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="<?php echo $server_url?>inventory/manage_product.php" class="btn btn-secondary">
|
<a href="<?php echo $server_url?>inventory/manage_product.php" class="btn btn-secondary" data-min-role="admin">
|
||||||
<span class="me-1"><i class="ti ti-plus"></i></span>
|
<span class="me-1"><i class="ti ti-plus"></i></span>
|
||||||
<span>Add Product</span>
|
<span>Add Product</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -388,8 +388,8 @@
|
|||||||
${(item['status']==1)?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
${(item['status']==1)?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
||||||
</td>
|
</td>
|
||||||
<td class="py-3">
|
<td class="py-3">
|
||||||
<a href="<?php echo $server_url?>inventory/manage_product.php?id=${item['id']}" class=""><i class="ti ti-eye fs-5"></i></a>
|
<a href="<?php echo $server_url?>inventory/manage_product.php?id=${item['id']}" class="" data-min-role="admin"><i class="ti ti-eye fs-5"></i></a>
|
||||||
<a href="javascript:;" class="link-danger" onclick="remove_product(${item['id']},$(this))"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
<a href="javascript:;" class="link-danger" data-min-role="admin" onclick="remove_product(${item['id']},$(this))"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
@@ -152,7 +156,7 @@
|
|||||||
<p>All warehouse facilities and their current status</p>
|
<p>All warehouse facilities and their current status</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="<?php echo $server_url?>inventory/manage_warehouse.php" class="btn btn-primary">
|
<a href="<?php echo $server_url?>inventory/manage_warehouse.php" class="btn btn-primary" data-min-role="admin">
|
||||||
Add Warehouse
|
Add Warehouse
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -205,7 +209,7 @@
|
|||||||
<p id="storage_subtitle">Zones, aisles, and rack assignments</p>
|
<p id="storage_subtitle">Zones, aisles, and rack assignments</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a href="<?php echo $server_url?>inventory/manage_storage.php" class="btn btn-secondary">
|
<a href="<?php echo $server_url?>inventory/manage_storage.php" class="btn btn-secondary" data-min-role="admin">
|
||||||
Add Storage
|
Add Storage
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -390,8 +394,8 @@
|
|||||||
${(item['status']==1)?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
${(item['status']==1)?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
||||||
</td>
|
</td>
|
||||||
<td class="py-3">
|
<td class="py-3">
|
||||||
<a href="<?php echo $server_url?>inventory/manage_warehouse.php?id=${item['id']}" class=""><i class="ti ti-eye fs-5"></i></a>
|
<a href="<?php echo $server_url?>inventory/manage_warehouse.php?id=${item['id']}" class="" data-min-role="admin"><i class="ti ti-eye fs-5"></i></a>
|
||||||
<a href="javascript:;" class="link-danger" onclick="remove_warehouse(${item['id']},$(this))"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
<a href="javascript:;" class="link-danger" data-min-role="admin" onclick="remove_warehouse(${item['id']},$(this))"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
});
|
});
|
||||||
@@ -456,8 +460,8 @@
|
|||||||
${location_cells}
|
${location_cells}
|
||||||
<td class="py-3"></td>
|
<td class="py-3"></td>
|
||||||
<td class="py-3">
|
<td class="py-3">
|
||||||
<a href="<?php echo $server_url?>inventory/manage_storage.php?id=${item['id']}" class=""><i class="ti ti-eye fs-5"></i></a>
|
<a href="<?php echo $server_url?>inventory/manage_storage.php?id=${item['id']}" class="" data-min-role="admin"><i class="ti ti-eye fs-5"></i></a>
|
||||||
<a href="javascript:;" class="link-danger" onclick="remove_storage(${item['id']},$(this))"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
<a href="javascript:;" class="link-danger" data-min-role="admin" onclick="remove_storage(${item['id']},$(this))"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -124,6 +124,17 @@ $_SESSION["login_surname"] = $temp["surname"];
|
|||||||
$_SESSION["login_company_id"] = $temp["default_company"];
|
$_SESSION["login_company_id"] = $temp["default_company"];
|
||||||
$_SESSION["login_profile_picture"] = $temp["profile_picture"] ?? '';
|
$_SESSION["login_profile_picture"] = $temp["profile_picture"] ?? '';
|
||||||
|
|
||||||
|
$role_sth = $pdo1->prepare(
|
||||||
|
"SELECT role FROM company_map_user
|
||||||
|
WHERE company_id = :company_id AND user_id = :user_id
|
||||||
|
LIMIT 1"
|
||||||
|
);
|
||||||
|
$role_sth->execute([
|
||||||
|
':company_id' => $_SESSION["login_company_id"],
|
||||||
|
':user_id' => $_SESSION["login_user_id"],
|
||||||
|
]);
|
||||||
|
$_SESSION["login_role"] = $role_sth->fetchColumn() ?: 'viewer';
|
||||||
|
|
||||||
// ── Step 6: Respond ───────────────────────────────────────────────────────────
|
// ── Step 6: Respond ───────────────────────────────────────────────────────────
|
||||||
$answer["success"] = 1;
|
$answer["success"] = 1;
|
||||||
$answer["message"] = "Login Complete!";
|
$answer["message"] = "Login Complete!";
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
require '../../../assets/utils/classes/OrderManager.php';
|
require '../../../assets/utils/classes/OrderManager.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
require '../../../assets/utils/classes/ReturnManager.php';
|
require '../../../assets/utils/classes/ReturnManager.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/OrderManager.php';
|
require '../../../assets/utils/classes/OrderManager.php';
|
||||||
require '../../../assets/utils/classes/StockManager.php';
|
require '../../../assets/utils/classes/StockManager.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/ReturnManager.php';
|
require '../../../assets/utils/classes/ReturnManager.php';
|
||||||
require '../../../assets/utils/classes/InvoiceManager.php';
|
require '../../../assets/utils/classes/InvoiceManager.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/InvoiceManager.php';
|
require '../../../assets/utils/classes/InvoiceManager.php';
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/InvoiceManager.php';
|
require '../../../assets/utils/classes/InvoiceManager.php';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/OrderManager.php';
|
require '../../../assets/utils/classes/OrderManager.php';
|
||||||
|
|
||||||
// Decode items JSON string back to array
|
// Decode items JSON string back to array
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/ReturnManager.php';
|
require '../../../assets/utils/classes/ReturnManager.php';
|
||||||
|
|
||||||
$data['items'] = json_decode($data['items'] ?? '[]', true) ?: [];
|
$data['items'] = json_decode($data['items'] ?? '[]', true) ?: [];
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/InvoiceManager.php';
|
require '../../../assets/utils/classes/InvoiceManager.php';
|
||||||
|
|
||||||
$order_id = (int)($data['order_id'] ?? 0);
|
$order_id = (int)($data['order_id'] ?? 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/InvoiceManager.php';
|
require '../../../assets/utils/classes/InvoiceManager.php';
|
||||||
|
|
||||||
$id = (int)($data['invoice_id'] ?? 0);
|
$id = (int)($data['invoice_id'] ?? 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/OrderManager.php';
|
require '../../../assets/utils/classes/OrderManager.php';
|
||||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
$payment_status = (int)($data['payment_status'] ?? 0);
|
$payment_status = (int)($data['payment_status'] ?? 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
require '../../../assets/utils/classes/InvoiceManager.php';
|
require '../../../assets/utils/classes/InvoiceManager.php';
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
||||||
|
|
||||||
$data['items'] = json_decode($data['items'] ?? '[]', true) ?: [];
|
$data['items'] = json_decode($data['items'] ?? '[]', true) ?: [];
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
||||||
require '../../../assets/utils/classes/StockManager.php';
|
require '../../../assets/utils/classes/StockManager.php';
|
||||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
|
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||||
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
require '../../../assets/utils/classes/PurchaseOrderManager.php';
|
||||||
|
|
||||||
$id = (int)($data['id'] ?? 0);
|
$id = (int)($data['id'] ?? 0);
|
||||||
|
|||||||
@@ -3,5 +3,9 @@ session_start();
|
|||||||
require '../../../assets/utils/db_auth.php';
|
require '../../../assets/utils/db_auth.php';
|
||||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||||
|
|
||||||
|
if (($data['action'] ?? '') === 'update') {
|
||||||
|
require_role($user_role, ['owner', 'admin']);
|
||||||
|
}
|
||||||
|
|
||||||
$csm = new CompanySettingManager($pdo1, $company_id, $pdo2);
|
$csm = new CompanySettingManager($pdo1, $company_id, $pdo2);
|
||||||
$csm->handle($data);
|
$csm->handle($data);
|
||||||
|
|||||||
@@ -45,19 +45,21 @@ if ($action === 'update') {
|
|||||||
|
|
||||||
// Verify user actually belongs to the requested company
|
// Verify user actually belongs to the requested company
|
||||||
$sth = $pdo1->prepare(
|
$sth = $pdo1->prepare(
|
||||||
"SELECT company_id FROM company_map_user
|
"SELECT company_id, role FROM company_map_user
|
||||||
WHERE company_id = :company_id AND user_id = :user_id
|
WHERE company_id = :company_id AND user_id = :user_id
|
||||||
LIMIT 1"
|
LIMIT 1"
|
||||||
);
|
);
|
||||||
$sth->execute([':company_id' => $target_company_id, ':user_id' => $user_id]);
|
$sth->execute([':company_id' => $target_company_id, ':user_id' => $user_id]);
|
||||||
|
$target_map = $sth->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if (!$sth->fetch()) {
|
if (!$target_map) {
|
||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
$answer['message'] = 'You do not have access to this company.';
|
$answer['message'] = 'You do not have access to this company.';
|
||||||
exit(json_encode($answer));
|
exit(json_encode($answer));
|
||||||
}
|
}
|
||||||
|
|
||||||
$_SESSION['login_company_id'] = $target_company_id;
|
$_SESSION['login_company_id'] = $target_company_id;
|
||||||
|
$_SESSION['login_role'] = $target_map['role'] ?? 'viewer';
|
||||||
|
|
||||||
$answer['success'] = 1;
|
$answer['success'] = 1;
|
||||||
$answer['message'] = 'Switched successfully.';
|
$answer['message'] = 'Switched successfully.';
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
session_start();
|
session_start();
|
||||||
require '../config.php';
|
require '../config.php';
|
||||||
|
if (!in_array($_SESSION['login_role'] ?? 'viewer', ['owner', 'admin'], true)) {
|
||||||
|
http_response_code(403);
|
||||||
|
exit('Access denied.');
|
||||||
|
}
|
||||||
require '../include_header.php';
|
require '../include_header.php';
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user