accounting workflows
This commit is contained in:
@@ -1,91 +1,15 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/FileUploader.php';
|
||||
require '../../../assets/utils/classes/CompanyProfileManager.php';
|
||||
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
|
||||
// ─── Allowed upload types ─────────────────────────────────────────────────
|
||||
const ALLOWED_MIME = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||
const ALLOWED_EXT = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
|
||||
const MAX_SIZE = 2 * 1024 * 1024; // 2 MB
|
||||
|
||||
// ─── Helper: handle one image slot ────────────────────────────────────────
|
||||
function handle_image_slot(
|
||||
string $slot, // 'company_logo' | 'company_seal'
|
||||
string $action, // 'keep' | 'replace' | 'remove'
|
||||
string $current, // current filename from DB
|
||||
string $upload_dir, // absolute path to uploads/company/
|
||||
string $prefix // filename prefix 'logo_' | 'seal_'
|
||||
): ?string {
|
||||
// 'keep' → return current unchanged
|
||||
if ($action === 'keep') return $current;
|
||||
|
||||
// 'remove' → delete file, return ''
|
||||
if ($action === 'remove') {
|
||||
if ($current && file_exists($upload_dir . $current)) {
|
||||
unlink($upload_dir . $current);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 'replace' → validate + save new file
|
||||
if ($action === 'replace' && !empty($_FILES[$slot]['tmp_name'])) {
|
||||
|
||||
$file = $_FILES[$slot];
|
||||
|
||||
if ($file['error'] !== UPLOAD_ERR_OK) {
|
||||
throw new RuntimeException("Upload error on {$slot}: code {$file['error']}.");
|
||||
}
|
||||
if ($file['size'] > MAX_SIZE) {
|
||||
throw new RuntimeException('File too large. Maximum size is 2 MB.');
|
||||
}
|
||||
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mime = finfo_file($finfo, $file['tmp_name']);
|
||||
finfo_close($finfo);
|
||||
|
||||
if (!in_array($mime, ALLOWED_MIME, true)) {
|
||||
throw new RuntimeException('Invalid file type. Only JPEG, PNG, GIF, WEBP allowed.');
|
||||
}
|
||||
|
||||
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
if (!in_array($ext, ALLOWED_EXT, true)) {
|
||||
throw new RuntimeException('Invalid file extension. Only jpg, png, gif, webp allowed.');
|
||||
}
|
||||
|
||||
// Delete old file first
|
||||
if ($current && file_exists($upload_dir . $current)) {
|
||||
unlink($upload_dir . $current);
|
||||
}
|
||||
|
||||
$filename = $prefix . uniqid() . '.' . $ext;
|
||||
|
||||
if (!move_uploaded_file($file['tmp_name'], $upload_dir . $filename)) {
|
||||
throw new RuntimeException("Failed to save {$slot}.");
|
||||
}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
return $current; // fallback
|
||||
}
|
||||
|
||||
try {
|
||||
$companyProfile = new CompanyProfileManager($pdo1, $company_id);
|
||||
|
||||
// ── Fetch current image filenames from DB ─────────────────────────────
|
||||
$sth = $pdo1->prepare(
|
||||
'SELECT company_logo, company_seal FROM company_list WHERE company_id = :id LIMIT 1'
|
||||
);
|
||||
$sth->execute([':id' => $company_id]);
|
||||
db_check($sth, $answer);
|
||||
$current = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$current) {
|
||||
$answer['message'] = 'Company not found.';
|
||||
http_response_code(404);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
$current = $companyProfile->getProfile();
|
||||
|
||||
// ── Upload directory ──────────────────────────────────────────────────
|
||||
$upload_dir = $include_url . 'uploads/company/';
|
||||
@@ -97,60 +21,11 @@
|
||||
$logo_action = $data['logo_action'] ?? 'keep';
|
||||
$seal_action = $data['seal_action'] ?? 'keep';
|
||||
|
||||
$new_logo = handle_image_slot('company_logo', $logo_action, $current['company_logo'] ?? '', $upload_dir, 'logo_');
|
||||
$new_seal = handle_image_slot('company_seal', $seal_action, $current['company_seal'] ?? '', $upload_dir, 'seal_');
|
||||
$new_logo = $companyProfile->handleImageSlot('company_logo', $logo_action, $current['company_logo'] ?? '', $upload_dir, 'logo_');
|
||||
$new_seal = $companyProfile->handleImageSlot('company_seal', $seal_action, $current['company_seal'] ?? '', $upload_dir, 'seal_');
|
||||
|
||||
// ── Text field sanitisation ───────────────────────────────────────────
|
||||
$channel = strtolower(preg_replace('/[^a-z0-9\-_]/', '', $data['channel_name'] ?? ''));
|
||||
|
||||
// ── UPDATE company_list ───────────────────────────────────────────────
|
||||
$sth = $pdo1->prepare("
|
||||
UPDATE company_list SET
|
||||
channel_name = :channel_name,
|
||||
company_name = :company_name,
|
||||
company_name2 = :company_name2,
|
||||
company_logo = :company_logo,
|
||||
company_seal = :company_seal,
|
||||
branch = :branch,
|
||||
branch_no = :branch_no,
|
||||
fiscal_year = :fiscal_year,
|
||||
fx = :fx,
|
||||
address = :address,
|
||||
address2 = :address2,
|
||||
tax_id = :tax_id,
|
||||
prompt_pay = :prompt_pay,
|
||||
entrepreneur = :entrepreneur,
|
||||
email = :email,
|
||||
phone = :phone,
|
||||
fax = :fax,
|
||||
website = :website,
|
||||
facebook_page = :facebook_page
|
||||
WHERE company_id = :company_id
|
||||
");
|
||||
|
||||
$sth->execute([
|
||||
':channel_name' => $channel,
|
||||
':company_name' => trim($data['company_name'] ?? ''),
|
||||
':company_name2' => trim($data['company_name2'] ?? ''),
|
||||
':company_logo' => $new_logo,
|
||||
':company_seal' => $new_seal,
|
||||
':branch' => trim($data['branch'] ?? 'สำนักงานใหญ่'),
|
||||
':branch_no' => trim($data['branch_no'] ?? ''),
|
||||
':fiscal_year' => trim($data['fiscal_year'] ?? ''),
|
||||
':fx' => trim($data['fx'] ?? 'thb'),
|
||||
':address' => trim($data['address'] ?? ''),
|
||||
':address2' => trim($data['address2'] ?? ''),
|
||||
':tax_id' => trim($data['tax_id'] ?? ''),
|
||||
':prompt_pay' => trim($data['prompt_pay'] ?? ''),
|
||||
':entrepreneur' => trim($data['entrepreneur'] ?? ''),
|
||||
':email' => trim($data['email'] ?? ''),
|
||||
':phone' => trim($data['phone'] ?? ''),
|
||||
':fax' => trim($data['fax'] ?? ''),
|
||||
':website' => trim($data['website'] ?? ''),
|
||||
':facebook_page' => trim($data['facebook_page'] ?? ''),
|
||||
':company_id' => $company_id,
|
||||
]);
|
||||
db_check($sth, $answer);
|
||||
// ── Persist company profile ───────────────────────────────────────────
|
||||
$companyProfile->saveProfile($data, $new_logo, $new_seal);
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Company profile saved.';
|
||||
@@ -168,4 +43,4 @@
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/FileUploader.php';
|
||||
require '../../../assets/utils/classes/UserManager.php';
|
||||
|
||||
try {
|
||||
$um = new UserManager($pdo1, $company_id, $user_id);
|
||||
|
||||
// ── Fetch current picture filename from DB ────────────────
|
||||
$sth = $pdo1->prepare(
|
||||
'SELECT profile_picture FROM user WHERE user_id = :user_id LIMIT 1'
|
||||
);
|
||||
$sth->execute([':user_id' => $user_id]);
|
||||
$current_picture = $sth->fetchColumn() ?: '';
|
||||
$current_picture = $um->getProfilePicture();
|
||||
|
||||
// ── Handle new picture upload ─────────────────────────────
|
||||
$db_picture = $current_picture;
|
||||
@@ -36,28 +34,7 @@
|
||||
}
|
||||
|
||||
// ── Update user record ────────────────────────────────────
|
||||
$sth = $pdo1->prepare(
|
||||
"UPDATE user SET
|
||||
name = :name,
|
||||
surname = :surname,
|
||||
email = :email,
|
||||
phone = :phone,
|
||||
country = :country,
|
||||
address = :address,
|
||||
profile_picture = :profile_picture
|
||||
WHERE user_id = :user_id"
|
||||
);
|
||||
$sth->execute([
|
||||
':name' => trim($data['name'] ?? ''),
|
||||
':surname' => trim($data['surname'] ?? ''),
|
||||
':email' => trim($data['email'] ?? ''),
|
||||
':phone' => trim($data['phone'] ?? ''),
|
||||
':country' => trim($data['country'] ?? ''),
|
||||
':address' => trim($data['address'] ?? ''),
|
||||
':profile_picture' => $db_picture,
|
||||
':user_id' => $user_id,
|
||||
]);
|
||||
db_check($sth, $answer);
|
||||
$um->updateProfile($data, $db_picture);
|
||||
|
||||
// ── Refresh session ───────────────────────────────────────
|
||||
$_SESSION['login_name'] = trim($data['name'] ?? '');
|
||||
@@ -73,4 +50,4 @@
|
||||
http_response_code(500);
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
exit(json_encode($answer));
|
||||
|
||||
@@ -1,131 +1,23 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/SmtpManager.php';
|
||||
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
|
||||
// ─── Encrypt password — same method/key/iv as config.php ─────────────────
|
||||
function encrypt_password(string $plain): string {
|
||||
global $pinkey, $method, $iv;
|
||||
return openssl_encrypt($plain, $method, $pinkey, 0, $iv);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$server = trim($data['smtp_host'] ?? '');
|
||||
$port = trim($data['smtp_port'] ?? '587');
|
||||
$username = trim($data['smtp_username'] ?? '');
|
||||
$raw_pass = $data['smtp_password'] ?? ''; // blank = keep current
|
||||
$from_name = trim($data['smtp_from_name'] ?? '');
|
||||
$from_email = trim($data['smtp_from_email'] ?? '');
|
||||
$encryption = trim($data['smtp_encryption'] ?? 'tls');
|
||||
|
||||
if (!$server || !$username) {
|
||||
$answer['message'] = 'SMTP host and username are required.';
|
||||
http_response_code(422);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
if (!in_array($port, ['25', '465', '587'], true)) $port = '587';
|
||||
if (!in_array($encryption, ['tls', 'ssl', 'none'], true)) $encryption = 'tls';
|
||||
|
||||
// Check if row already exists (uses pdo1 — company_smtp lives in wms2)
|
||||
$sth = $pdo1->prepare("
|
||||
SELECT smtp_id FROM company_smtp
|
||||
WHERE company_id = :company_id LIMIT 1
|
||||
");
|
||||
$sth->execute([':company_id' => $company_id]);
|
||||
db_check($sth, $answer);
|
||||
$existing_id = $sth->fetchColumn();
|
||||
|
||||
if ($existing_id) {
|
||||
|
||||
if ($raw_pass !== '') {
|
||||
$sth = $pdo1->prepare("
|
||||
UPDATE company_smtp SET
|
||||
server = :server,
|
||||
port = :port,
|
||||
username = :username,
|
||||
password = :password,
|
||||
from_name = :from_name,
|
||||
from_email = :from_email,
|
||||
encryption = :encryption,
|
||||
updated_at = NOW()
|
||||
WHERE smtp_id = :smtp_id
|
||||
");
|
||||
$sth->execute([
|
||||
':server' => $server,
|
||||
':port' => $port,
|
||||
':username' => $username,
|
||||
':password' => encrypt_password($raw_pass),
|
||||
':from_name' => $from_name,
|
||||
':from_email' => $from_email,
|
||||
':encryption' => $encryption,
|
||||
':smtp_id' => $existing_id,
|
||||
]);
|
||||
} else {
|
||||
// Keep existing password — don't touch it
|
||||
$sth = $pdo1->prepare("
|
||||
UPDATE company_smtp SET
|
||||
server = :server,
|
||||
port = :port,
|
||||
username = :username,
|
||||
from_name = :from_name,
|
||||
from_email = :from_email,
|
||||
encryption = :encryption,
|
||||
updated_at = NOW()
|
||||
WHERE smtp_id = :smtp_id
|
||||
");
|
||||
$sth->execute([
|
||||
':server' => $server,
|
||||
':port' => $port,
|
||||
':username' => $username,
|
||||
':from_name' => $from_name,
|
||||
':from_email' => $from_email,
|
||||
':encryption' => $encryption,
|
||||
':smtp_id' => $existing_id,
|
||||
]);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// New record — password required
|
||||
if ($raw_pass === '') {
|
||||
$answer['message'] = 'Password is required for a new SMTP configuration.';
|
||||
http_response_code(422);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
$sth = $pdo1->prepare("
|
||||
INSERT INTO company_smtp
|
||||
(company_id, server, port, username, password,
|
||||
from_name, from_email, encryption, updated_at)
|
||||
VALUES
|
||||
(:company_id, :server, :port, :username, :password,
|
||||
:from_name, :from_email, :encryption, NOW())
|
||||
");
|
||||
$sth->execute([
|
||||
':company_id' => $company_id,
|
||||
':server' => $server,
|
||||
':port' => $port,
|
||||
':username' => $username,
|
||||
':password' => encrypt_password($raw_pass),
|
||||
':from_name' => $from_name,
|
||||
':from_email' => $from_email,
|
||||
':encryption' => $encryption,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
db_check($sth, $answer);
|
||||
|
||||
$smtp = new SmtpManager($pdo1, $company_id, $method, $pinkey, $iv);
|
||||
$smtp->save($data);
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'SMTP settings saved.';
|
||||
|
||||
} catch (Exception $e) {
|
||||
$answer['message'] = 'Failed to save SMTP settings.';
|
||||
http_response_code(500);
|
||||
$answer['message'] = $e->getMessage();
|
||||
http_response_code(in_array($e->getMessage(), [
|
||||
'SMTP host and username are required.',
|
||||
'Password is required for a new SMTP configuration.',
|
||||
], true) ? 422 : 500);
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -1,42 +1,17 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/CompanyProfileManager.php';
|
||||
|
||||
try {
|
||||
|
||||
$sth = $pdo1->prepare("
|
||||
SELECT
|
||||
company_id, channel_name,
|
||||
company_name, company_name2,
|
||||
company_logo, company_seal,
|
||||
branch, branch_no,
|
||||
fiscal_year, fx,
|
||||
address, address2,
|
||||
tax_id, prompt_pay, entrepreneur,
|
||||
email, phone, fax,
|
||||
website, facebook_page
|
||||
FROM company_list
|
||||
WHERE company_id = :company_id
|
||||
LIMIT 1
|
||||
");
|
||||
$sth->execute([':company_id' => $company_id]);
|
||||
db_check($sth, $answer);
|
||||
|
||||
$company = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$company) {
|
||||
$answer['message'] = 'Company not found.';
|
||||
http_response_code(404);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
$company_profile = new CompanyProfileManager($pdo1, $company_id);
|
||||
$answer['success'] = 1;
|
||||
$answer['output'] = $company;
|
||||
$answer['output'] = $company_profile->getProfile();
|
||||
|
||||
} catch (Exception $e) {
|
||||
$answer['message'] = 'Failed to load company profile.';
|
||||
http_response_code(500);
|
||||
$answer['message'] = $e->getMessage();
|
||||
http_response_code($e->getMessage() === 'Company not found.' ? 404 : 500);
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -1,28 +1,12 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/SmtpManager.php';
|
||||
|
||||
try {
|
||||
|
||||
$sth = $pdo1->prepare("
|
||||
SELECT
|
||||
server,
|
||||
port,
|
||||
username,
|
||||
from_name,
|
||||
from_email,
|
||||
encryption
|
||||
FROM company_smtp
|
||||
WHERE company_id = :company_id
|
||||
LIMIT 1
|
||||
");
|
||||
$sth->execute([':company_id' => $company_id]);
|
||||
db_check($sth, $answer);
|
||||
|
||||
$row = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$smtp = new SmtpManager($pdo1, $company_id, $method, $pinkey, $iv);
|
||||
$answer['success'] = 1;
|
||||
$answer['output'] = $row ?: null; // null = not configured yet
|
||||
$answer['output'] = $smtp->get();
|
||||
|
||||
} catch (Exception $e) {
|
||||
$answer['message'] = $e->getMessage();
|
||||
@@ -30,4 +14,4 @@
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -10,10 +10,9 @@ require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/UserManager.php';
|
||||
|
||||
$action = $data['action'] ?? '';
|
||||
$um = new UserManager($pdo1, $company_id, $user_id);
|
||||
|
||||
if ($action === 'read') {
|
||||
$um = new UserManager($pdo1, $company_id, $user_id);
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['output'] = $um->getCompanyList();
|
||||
$answer['current'] = (int)$_SESSION['login_company_id'];
|
||||
@@ -29,13 +28,7 @@ if ($action === 'update') {
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
$sth = $pdo1->prepare(
|
||||
"SELECT company_id, role FROM company_map_user
|
||||
WHERE company_id = :company_id AND user_id = :user_id
|
||||
LIMIT 1"
|
||||
);
|
||||
$sth->execute([':company_id' => $target_company_id, ':user_id' => $user_id]);
|
||||
$target_map = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
$target_map = $um->getCompanyAccess($target_company_id);
|
||||
|
||||
if (!$target_map) {
|
||||
$answer['message'] = 'You do not have access to this company.';
|
||||
|
||||
@@ -1,57 +1,24 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require '../../../assets/utils/classes/SmtpManager.php';
|
||||
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
|
||||
try {
|
||||
|
||||
$to = trim($data['test_email'] ?? '');
|
||||
|
||||
if (!filter_var($to, FILTER_VALIDATE_EMAIL)) {
|
||||
$answer['message'] = 'Invalid recipient email address.';
|
||||
http_response_code(422);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
// Fetch from_name / channel_name for the sender display
|
||||
$sth = $pdo1->prepare("
|
||||
SELECT from_name FROM company_smtp
|
||||
WHERE company_id = :company_id LIMIT 1
|
||||
");
|
||||
$sth->execute([':company_id' => $company_id]);
|
||||
db_check($sth, $answer);
|
||||
$row = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
$answer['message'] = 'No SMTP configuration found. Please save your settings first.';
|
||||
http_response_code(422);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
$channel_name = $row['from_name'] ?: 'WMS System';
|
||||
|
||||
// Use existing mailer — it reads company_smtp via pdo1 automatically
|
||||
require_once $include_url . 'assets/utils/module/mailer.php';
|
||||
|
||||
$mailer = new mailer(['pdo1' => $pdo1]);
|
||||
$mailer->send_email([
|
||||
'company_id' => $company_id,
|
||||
'smtp' => [], // empty = mailer reads from company_smtp
|
||||
'to' => $to,
|
||||
'subject' => 'SMTP Test — WMS',
|
||||
'message' => "This is a test email from your WMS SMTP configuration.\n\nIf you received this, your SMTP settings are working correctly.",
|
||||
'channel_name' => $channel_name,
|
||||
'key' => $pinkey,
|
||||
]);
|
||||
|
||||
$smtp = new SmtpManager($pdo1, $company_id, $method, $pinkey, $iv);
|
||||
$to = trim((string)($data['test_email'] ?? ''));
|
||||
$smtp->sendTest($to);
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Test email sent to ' . htmlspecialchars($to) . '.';
|
||||
|
||||
} catch (Exception $e) {
|
||||
$answer['message'] = 'Failed to send test email: ' . $e->getMessage();
|
||||
http_response_code(500);
|
||||
$answer['message'] = $e->getMessage();
|
||||
http_response_code(in_array($e->getMessage(), [
|
||||
'Invalid recipient email address.',
|
||||
'No SMTP configuration found. Please save your settings first.',
|
||||
], true) ? 422 : 500);
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user