diff --git a/app/assets/css/custom.css b/app/assets/css/custom.css index b262d96..10c0dc4 100644 --- a/app/assets/css/custom.css +++ b/app/assets/css/custom.css @@ -77,4 +77,15 @@ /* Ensure the link itself is styled correctly when not active */ .page-item-secondary .page-link { color: var(--bs-secondary); +} + +.card-loader-overlay { + position: absolute; + inset: 0; + background: rgba(255, 255, 255, 0.85); + display: flex; + align-items: center; + justify-content: center; + z-index: 2; + border-radius: inherit; } \ No newline at end of file diff --git a/app/assets/js/custom.js b/app/assets/js/custom.js index 361e4f3..69dd640 100644 --- a/app/assets/js/custom.js +++ b/app/assets/js/custom.js @@ -115,6 +115,111 @@ $(function () { }); + + $('input.contact_search').each(function (i, el) { + + var $el = $(el); + $el.autocomplete({ + + // Fetch data from server + source: function (request, response) { + + // Abort previous request (prevent multiple firing) + if ($el.data('xhr')) { + $el.data('xhr').abort(); + } + + // Prepare payload + let q = prepare_form_data(0, true); + q['keyword'] = request.term; + let json = JSON.stringify(q); + + // Send AJAX request + var xhr = $.ajax({ + url: server_url + 'ics/api/engine/contact_search.php', + type: 'POST', + dataType: 'json', + data: { json: json }, + // for CSRF validation + headers: { + 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') + }, + + success: function (res) { + + var aca = []; + + // Map result to autocomplete format + $.each(res.result, function (i, item) { + + var temp = ""; + temp += "
"; + temp += "
"; + temp += "Tax ID: " + (item.tax_id || 'N/A'); + temp += "
"; + temp += "
"; + temp += item.contact_name; + temp += "
"; + temp += "
"; + + aca.push({ + label: temp, // HTML dropdown + value: item.contact_name, // Default value + data: item // Full object + }); + + }); + + response(aca); + } + }); + + // Save request reference + $el.data('xhr', xhr); + }, + + minLength: 0, + delay: 300, + + // When selecting item + select: function (e, ui) { + + if (ui.item && ui.item.data) { + + var contact = ui.item.data; + + // Replace input value with SKU + $(this) + .val(contact.contact_name) + .attr("data-id", contact.id) + .attr("secondary", contact.contact_name); + + console.log("Input updated with contact name:", contact.contact_name); + + return false; // Prevent overwrite by default value + } + } + + }) + + // Allow HTML rendering in dropdown + .data("ui-autocomplete")._renderItem = function (ul, item) { + return $("
  • ") + .append($("
    ").html(item.label)) + .appendTo(ul); + }; + + // Add this ↓ + $el.on('blur', function () { + var secondary = $(this).attr('secondary'); + console.log($(this).attr('data-id')) + if (secondary) { + $('input#contact').val($('input#contact').attr('secondary')); + } + }); + + }); + }); @@ -198,7 +303,7 @@ function ajax_request(options) { isAjaxProcessing = false; return Promise.reject("validation_failed"); } - + if(options.data){ Object.entries(options.data).forEach(([key, value]) => { payloadJson[key] = value; @@ -400,3 +505,24 @@ document.addEventListener('DOMContentLoaded', () => { }); }); + + +/** + * Helper function to format date strings (assuming input is in ISO format) + */ +function format_date(iso_string) { + var split = iso_string.split(" "); + if (split.length === 2) { + var datePart = split[0].split("-"); + } + return (datePart) ? `${datePart[2]}/${datePart[1]}/${datePart[0]} ${split[1]}` : iso_string; +} + +function format_number(value, decimal) { + var n = Number(value); + if (isNaN(n)) return '--'; + if (decimal !== undefined) n = n.toFixed(decimal); + var parts = n.toString().split('.'); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); + return parts.join('.'); +} \ No newline at end of file diff --git a/app/assets/utils/db_auth.php b/app/assets/utils/db_auth.php index 7b2e433..931f080 100644 --- a/app/assets/utils/db_auth.php +++ b/app/assets/utils/db_auth.php @@ -57,7 +57,11 @@ function db_check($sth, &$answer, $options = []) { $log_message = $options['log'] ?? "DB Error"; error_log($log_message . " in " . $trace['file'] . " line " . $trace['line'] . ": " . $sth->errorInfo()[2]); + // production version $answer["message"] = $options['message'] ?? "A server error occurred. Please try again."; + + // development version + $answer["message"] = $sth->errorInfo()[2]; http_response_code($options['code'] ?? 500); @@ -148,6 +152,7 @@ if(!empty($_SESSION["login_company_id"])){ $company_id = (int)$_SESSION["login_company_id"]; $user_id = (int)$_SESSION["login_user_id"]; + $uuid = bin2hex(random_bytes(16)); // create json for table logging $logging = array( @@ -158,4 +163,271 @@ if(!empty($_SESSION["login_company_id"])){ ); } -?> + +/** + * HELPER CLASSES AND FUNCTIONS + * These are designed to be reusable across different API endpoints for consistent data handling and error management. + * They are not specific to any single operation and can be used wherever similar patterns arise. + */ + +/** + * Helper class to manage data consistency + */ +class WarehouseManager { + + private $pdo; + private $company_id; + + public function __construct($pdo, $company_id) { + $this->pdo = $pdo; + $this->company_id = $company_id; + } + + public function getWarehouseName($warehouse_id) { + $sql = "SELECT warehouse_name FROM md_warehouse + WHERE company_id = :company_id AND id = :warehouse_id"; + + $sth = $this->pdo->prepare($sql); + $sth->execute([ + ":company_id" => $this->company_id, + ":warehouse_id" => $warehouse_id + ]); + return $sth->fetchColumn(); + } + + public function getStockContext($warehouse_id, $id) { + $name = $this->getWarehouseName($warehouse_id); + $table = "td_stock_" . $name; + + $sql = "SELECT * FROM `$table` + WHERE company_id = :company_id AND id = :id"; + + $sth = $this->pdo->prepare($sql); + $sth->execute([ + ":company_id" => $this->company_id, + ":id" => $id + ]); + + return [ + 'table' => $table, + 'name' => $name, + 'row' => $sth->fetch(PDO::FETCH_ASSOC) ?: [] + ]; + } + + public function adjustBalance($type, $warehouse_id, $product_sku, $old_qty, $new_qty) { + + // Lock the row — other transactions wait here + $sql = "SELECT id FROM warehouse_balance + WHERE company_id = :company_id + AND warehouse_id = :warehouse_id + AND product_sku = :product_sku + FOR UPDATE"; + + $sth = $this->pdo->prepare($sql); + $sth->execute([ + ":company_id" => $this->company_id, + ":warehouse_id" => $warehouse_id, + ":product_sku" => $product_sku + ]); + + if (!$sth->fetchColumn()) { + $sql = "INSERT INTO warehouse_balance + (company_id, warehouse_id, product_sku) + VALUES (:company_id, :warehouse_id, :product_sku)"; + + $sth = $this->pdo->prepare($sql); + $sth->execute([ + ":company_id" => $this->company_id, + ":warehouse_id" => $warehouse_id, + ":product_sku" => $product_sku + ]); + } + + $column = $type === 'in' ? 'total_in' : 'total_out'; + + // This is already atomic since it uses relative update + $sql = "UPDATE warehouse_balance + SET `$column` = `$column` - :old_qty + :new_qty + WHERE company_id = :company_id + AND warehouse_id = :warehouse_id + AND product_sku = :product_sku"; + + $sth = $this->pdo->prepare($sql); + $sth->execute([ + ":company_id" => $this->company_id, + ":warehouse_id" => $warehouse_id, + ":product_sku" => $product_sku, + ":old_qty" => $old_qty, + ":new_qty" => $new_qty + ]); + } +} + + +class FileUploader { + + private $target_dir; + private $allowed_mimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'application/pdf']; + private $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf']; + private $max_size = 5 * 1024 * 1024; // 5MB + private $uploaded_files = []; // newly uploaded filenames + private $deleted_files = []; // files we deleted from disk + + public function __construct($target_dir) { + $this->target_dir = rtrim($target_dir, '/') . '/'; + $this->ensureDirectory(); + } + + private function ensureDirectory() { + if (!is_dir($this->target_dir)) { + mkdir($this->target_dir, 0755, true); + } + if (!is_writable($this->target_dir)) { + throw new Exception("Target directory is not writable."); + } + } + + /** + * Remove files that user deleted in the UI + */ + public function cleanup($existing_csv, $keep_csv) { + if (empty($existing_csv)) return; + + $existing = array_filter(array_map('trim', explode(',', $existing_csv))); + $keep = !empty($keep_csv) ? array_filter(array_map('trim', explode(',', $keep_csv))) : []; + + foreach ($existing as $file) { + if (!in_array($file, $keep)) { + $path = $this->target_dir . $file; + if (file_exists($path)) { + unlink($path); + $this->deleted_files[] = $file; + } + } + } + } + + /** + * Upload new files from $_FILES + * Returns array of errors (empty = success) + */ + public function upload($field_name) { + if (!isset($_FILES[$field_name])) return []; + + $errors = []; + + foreach ($_FILES[$field_name]['name'] as $key => $name) { + $error_code = $_FILES[$field_name]['error'][$key]; + + if ($error_code !== UPLOAD_ERR_OK) { + $errors[] = "{$name}: " . $this->getUploadError($error_code); + continue; + } + + $tmp_name = $_FILES[$field_name]['tmp_name'][$key]; + $file_size = $_FILES[$field_name]['size'][$key]; + $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); + + if ($file_size > $this->max_size) { + $errors[] = "{$name}: exceeds " . ($this->max_size / 1024 / 1024) . "MB limit"; + continue; + } + + if (!in_array($extension, $this->allowed_extensions)) { + $errors[] = "{$name}: .{$extension} is not allowed"; + continue; + } + + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mime = finfo_file($finfo, $tmp_name); + finfo_close($finfo); + + if (!in_array($mime, $this->allowed_mimes)) { + $errors[] = "{$name}: content type ({$mime}) is not allowed"; + continue; + } + + $file_id = uniqid() . "_" . time() . "." . $extension; + $destination = $this->target_dir . $file_id; + + if (move_uploaded_file($tmp_name, $destination)) { + $this->uploaded_files[] = $file_id; + chmod($destination, 0644); + } else { + $errors[] = "{$name}: failed to save"; + } + } + + return $errors; + } + + /** + * Build final CSV string for DB + */ + public function buildFileString($keep_csv) { + $keep = !empty($keep_csv) ? array_filter(array_map('trim', explode(',', $keep_csv))) : []; + $final = array_merge($keep, $this->uploaded_files); + return implode(",", array_filter($final)); + } + + /** + * Rollback uploaded files if DB fails + */ + public function rollbackUploads() { + foreach ($this->uploaded_files as $file) { + $path = $this->target_dir . $file; + if (file_exists($path)) { + unlink($path); + } + } + $this->uploaded_files = []; + } + + private function getUploadError($code) { + $messages = [ + UPLOAD_ERR_INI_SIZE => "exceeds server max upload size (" . ini_get('upload_max_filesize') . ")", + UPLOAD_ERR_FORM_SIZE => "exceeds form max size", + UPLOAD_ERR_PARTIAL => "was only partially uploaded", + UPLOAD_ERR_NO_FILE => "no file was sent", + UPLOAD_ERR_NO_TMP_DIR => "server missing temp folder", + UPLOAD_ERR_CANT_WRITE => "server failed to write to disk", + UPLOAD_ERR_EXTENSION => "blocked by server extension", + ]; + return $messages[$code] ?? "unknown error (code {$code})"; + } +} + + +/** + * Helper function + */ + +// transaction wrapper with retry logic for deadlocks +function dbTransaction($pdo, $callback, $maxRetries = 3) { + for ($attempt = 0; $attempt < $maxRetries; $attempt++) { + try { + $pdo->beginTransaction(); + $result = $callback($pdo); + $pdo->commit(); + return $result; + + } catch (PDOException $e) { + $pdo->rollBack(); + + if ($e->getCode() == '40001' && $attempt < $maxRetries - 1) { + usleep(600000 * ($attempt + 1)); + continue; + } + + error_log("[DB ERROR] " . $e->getMessage() . " | " . $e->getFile() . ":" . $e->getLine()); + throw $e; + + } catch (Exception $e) { + $pdo->rollBack(); + error_log("[ERROR] " . $e->getMessage() . " | " . $e->getFile() . ":" . $e->getLine()); + throw $e; + } + } +} +?> \ No newline at end of file diff --git a/app/contact/api/engine/manage_contact.php b/app/contact/api/engine/manage_contact.php index d57a7eb..a813a61 100644 --- a/app/contact/api/engine/manage_contact.php +++ b/app/contact/api/engine/manage_contact.php @@ -1,212 +1,105 @@ 0) { + $sql = "SELECT `files` FROM md_contact WHERE company_id = :company_id AND id = :id"; + $sth = $pdo2->prepare($sql); + $sth->execute([":company_id" => $company_id, ":id" => $id]); + $uploader->cleanup($sth->fetchColumn(), $data['keep_files'] ?? ''); + } - /** 1. DISK CLEANUP (Removal of deleted files) **/ - if ($id > 0) { - // Fetch currently stored filenames from DB for comparison - $sql_check = "SELECT `files` FROM md_contact WHERE company_id = :company_id AND id = :id"; - $sth_check = $pdo2->prepare($sql_check); - $sth_check->execute([":company_id" => $company_id, ":id" => $id]); - $existing_db_string = $sth_check->fetchColumn(); + // Upload new files + $errors = $uploader->upload('contact_files'); + if (!empty($errors)) { + $answer["success"] = 0; + $answer["message"] = $errors[0]; + exit(json_encode($answer)); + } - if (!empty($existing_db_string)) { - $existing_files_array = explode(',', $existing_db_string); - - // 'keep_files' comes from JS (Dropzone.files names currently in the UI) - $keep_files = isset($data['keep_files']) ? explode(',', $data['keep_files']) : []; + $db_image_string = $uploader->buildFileString($data['keep_files'] ?? ''); - foreach ($existing_files_array as $file_on_disk) { - $file_on_disk = trim($file_on_disk); - if (empty($file_on_disk)) continue; + /** 2. DATABASE **/ + dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging, $id, $db_image_string) { - /** - * If a file exists in the database but is NOT in the 'keep_files' list, - * it means the user clicked 'Remove' in the UI. We delete it from the server. - */ - if (!in_array($file_on_disk, $keep_files)) { - $full_path = $target_dir . $file_on_disk; - if (file_exists($full_path)) { - unlink($full_path); // Physically remove (rm) the file - } - } + $sql = "SELECT `log` FROM md_contact + WHERE company_id = :company_id AND id = :id"; + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + + $table_log = json_decode($sth->fetchColumn() ?: '[]', true); + if (!is_array($table_log)) $table_log = []; + $table_log[] = $logging; + + $params = [ + ":company_id" => $company_id, + ":contact_name" => $data["contact_name"], + ":tax_id" => $data["tax_id"], + ":organization" => $data["organization"], + ":branch" => $data["branch"], + ":contact_type" => (int)$data["contact_type"], + ":billing_address" => $data["billing_address"], + ":shipping_location"=> $data["shipping_location"], + ":shipping_address" => $data["shipping_address"], + ":remark" => $data["remark"], + ":files" => $db_image_string, + ":status" => (int)$data["status"], + ":log" => json_encode($table_log), + ]; + + if ($id > 0) { + $sql = "UPDATE md_contact SET + `contact_name` = :contact_name, + `tax_id` = :tax_id, + `organization` = :organization, + `branch` = :branch, + `contact_type` = :contact_type, + `billing_address` = :billing_address, + `shipping_location` = :shipping_location, + `shipping_address` = :shipping_address, + `remark` = :remark, + `files` = :files, + `status` = :status, + `log` = :log + WHERE id = :id AND company_id = :company_id"; + $params[":id"] = $id; + } else { + $sql = "INSERT INTO md_contact + (company_id, contact_name, tax_id, organization, branch, contact_type, + billing_address, shipping_location, shipping_address, remark, files, status, log) + VALUES + (:company_id, :contact_name, :tax_id, :organization, :branch, :contact_type, + :billing_address, :shipping_location, :shipping_address, :remark, :files, :status, :log)"; } - } + + $sth = $pdo->prepare($sql); + $sth->execute($params); + + }); + + $answer["success"] = 1; + + } catch (PDOException $e) { + // DB failed — rollback uploaded files + if (isset($uploader)) $uploader->rollbackUploads(); + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; + + } catch (Exception $e) { + if (isset($uploader)) $uploader->rollbackUploads(); + $answer["success"] = 0; + $answer["message"] = $e->getMessage(); } - /** 2. PERMISSION & DIRECTORY CHECK **/ - $parent_dir = dirname($target_dir); - if (!is_writable($parent_dir)) { - exit(json_encode([ - "success" => 0, - "message" => "Server error: Target directory is not writable. Check permissions." - ])); - } - - // Ensure the directory exists - if (!is_dir($target_dir)) { - mkdir($target_dir, 0755, true); - } - - /** 3. PROCESSING NEW UPLOADS **/ - $uploaded_names = []; - - // Allowed MIME types whitelist - $allowed_mimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'application/pdf']; - - // Allowed extensions whitelist - $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf']; - - // Max file size: 5MB - $max_size = 5 * 1024 * 1024; - - if (isset($_FILES['contact_files'])) { - foreach ($_FILES['contact_files']['name'] as $key => $name) { - if ($_FILES['contact_files']['error'][$key] === UPLOAD_ERR_OK) { - - $tmp_name = $_FILES['contact_files']['tmp_name'][$key]; - $file_size = $_FILES['contact_files']['size'][$key]; - $extension = strtolower(pathinfo($name, PATHINFO_EXTENSION)); - - // Check 1: File size - if ($file_size > $max_size) { - error_log("Rejected oversized file: " . $name); - continue; - } - - // Check 2: Extension whitelist - if (!in_array($extension, $allowed_extensions)) { - error_log("Rejected extension: " . $name); - continue; - } - - // Check 3: Real MIME type (reads actual file bytes, not filename) - $finfo = finfo_open(FILEINFO_MIME_TYPE); - $mime = finfo_file($finfo, $tmp_name); - finfo_close($finfo); - - if (!in_array($mime, $allowed_mimes)) { - error_log("Rejected MIME type: " . $mime . " for file: " . $name); - continue; - } - - // Safe unique filename — no original extension trusted - $file_id = uniqid() . "_" . time() . "." . $extension; - $destination = $target_dir . $file_id; - - if (move_uploaded_file($tmp_name, $destination)) { - $uploaded_names[] = $file_id; - chmod($destination, 0644); - } else { - error_log("Failed to move uploaded file: " . $name); - } - } - } - } - - /** 4. CONSTRUCTING THE FINAL DATABASE STRING **/ - // Parse files the user kept from the existing session - $keep_files = isset($data['keep_files']) ? explode(',', $data['keep_files']) : []; - - // Merge old kept filenames with the brand-new unique filenames - $final_file_array = array_merge($keep_files, $uploaded_names); - - // Clean up: Remove empty values and trim whitespace - $final_file_array = array_filter(array_map('trim', $final_file_array)); - - // The final comma-separated string for the DB 'files' column - $db_image_string = implode(",", $final_file_array); - - /********************************************************************************** */ - - - // 2. Initialize log array - $table_log = []; - - // Get existing log and existing files if updating - if ($id > 0) { - $sql = "SELECT `log`, `files` FROM md_contact WHERE company_id = :company_id AND id = :id"; - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - ":id" => $id - ]); - - $row = $sth->fetch(PDO::FETCH_ASSOC); - if ($row) { - $table_log = json_decode($row['log'] ?? '[]', true); - } - } - - // Append the new log entry - $table_log[] = $logging; - - // 3. Database Operation - $params = [ - ":company_id" => $company_id, - ":contact_name" => $data["contact_name"], - ":tax_id" => $data["tax_id"], - ":organization" => $data["organization"], - ":branch" => $data["branch"], - ":contact_type" => (int)$data["contact_type"], - ":billing_address" => $data["billing_address"], - ":shipping_location"=> $data["shipping_location"], - ":shipping_address" => $data["shipping_address"], - ":remark" => $data["remark"], - ":files" => $db_image_string, - ":status" => (int)$data["status"], - ":log" => json_encode($table_log) - ]; - - if ($id > 0) { - // UPDATE - $sql = "UPDATE md_contact SET - `contact_name` = :contact_name, - `tax_id` = :tax_id, - `organization` = :organization, - `branch` = :branch, - `contact_type` = :contact_type, - `billing_address` = :billing_address, - `shipping_location` = :shipping_location, - `shipping_address` = :shipping_address, - `remark` = :remark, - `files` = :files, - `status` = :status, - `log` = :log - WHERE id = :id AND company_id = :company_id"; - - $params[":id"] = $id; - $sth = $pdo2->prepare($sql); - $sth->execute($params); - - } else { - // INSERT - $sql = "INSERT INTO md_contact - (company_id, contact_name, tax_id, organization, branch, contact_type, - billing_address, shipping_location, shipping_address, remark, files, status, log) - VALUES - (:company_id, :contact_name, :tax_id, :organization, :branch, :contact_type, - :billing_address, :shipping_location, :shipping_address, :remark, :files, :status, :log)"; - - $sth = $pdo2->prepare($sql); - $sth->execute($params); - } - - $answer["success"] = 1; exit(json_encode($answer)); ?> \ No newline at end of file diff --git a/app/contact/api/engine/manage_contact_type.php b/app/contact/api/engine/manage_contact_type.php index 7478244..ed3d1d0 100644 --- a/app/contact/api/engine/manage_contact_type.php +++ b/app/contact/api/engine/manage_contact_type.php @@ -1,77 +1,66 @@ 0) { - $sql = "SELECT `log` - FROM md_contact_type - WHERE - company_id = :company_id AND - id = :id"; - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - "id" => $id - ]); - - if ($sth->errorCode() !== '00000') { - $error = $sth->errorInfo(); - $answer["message"] = $error[2] ?? $error[0]; - exit(json_encode($answer)); - } - - $row = $sth->fetch(PDO::FETCH_ASSOC); - if ($row) { - $table_log = json_decode($row['log'] ?? '[]', true); - } + $sql = "SELECT `log` FROM md_contact_type + WHERE company_id = :company_id AND id = :id"; + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + + $table_log = json_decode($sth->fetchColumn() ?: '[]', true); + if (!is_array($table_log)) $table_log = []; + $table_log[] = $logging; + + $params = [ + ":company_id" => $company_id, + ":contact_type" => $data["contact_type"], + ":description" => $data["description"], + ":status" => (int)$data["status"], + ":log" => json_encode($table_log), + ]; + + if ($id > 0) { + + $sql = "UPDATE md_contact_type SET + `contact_type` = :contact_type, + `description` = :description, + `status` = :status, + `log` = :log + WHERE id = :id AND company_id = :company_id"; + + $params[":id"] = $id; + + } else { + + $sql = "INSERT INTO md_contact_type + (company_id, contact_type, `description`, `status`, `log`) + VALUES + (:company_id, :contact_type, :description, :status, :log)"; + } + + $sth = $pdo->prepare($sql); + $sth->execute($params); + + }); + + $answer["success"] = 1; + + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; + + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; } - // Append the new log entry (assuming $logging is defined in your preset/utils) - $table_log[] = $logging; - - if ($id > 0) { - // UPDATE existing record - $sql = "UPDATE md_contact_type SET - `contact_type` = :contact_type, - `description` = :description, - `status` = :status, - `log` = :log - WHERE id = :id AND company_id = :company_id"; - - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":id" => $id, - ":company_id" => $company_id, - ":contact_type" => $data["contact_type"], - ":description" => $data["description"], - ":status" => (int)$data["status"], - ":log" => json_encode($table_log), - ]); - - } else { - // INSERT new record - $sql = "INSERT INTO md_contact_type - (company_id, contact_type, `description`, `status`, `log`) - VALUES - (:company_id, :contact_type, :description, :status, :log)"; - - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - ":contact_type" => $data["contact_type"], - ":description" => $data["description"], - ":status" => (int)$data["status"], - ":log" => json_encode($table_log), - ]); - } - - $answer["success"] = 1; exit(json_encode($answer)); ?> \ No newline at end of file diff --git a/app/contact/manage_contact.php b/app/contact/manage_contact.php index c12f9ad..ccfa8a9 100644 --- a/app/contact/manage_contact.php +++ b/app/contact/manage_contact.php @@ -185,7 +185,7 @@ url: "contact/api/engine/manage_contact.php", autoPrepare: true, checkRequired: 1, - debugMode: 1, + debugMode: 0, formData: formData, action: 'manage', onSuccess: function(res) { diff --git a/app/contact/manage_contact_type.php b/app/contact/manage_contact_type.php index e51c057..dffdac4 100644 --- a/app/contact/manage_contact_type.php +++ b/app/contact/manage_contact_type.php @@ -84,7 +84,7 @@ } - function retreive_for_edit() { + function retrieve_for_edit() { return false; @@ -114,7 +114,7 @@ $(async function() { try { - await retreive_for_edit(); + await retrieve_for_edit(); } catch (e) { console.log(e); } diff --git a/app/dbconn.php b/app/dbconn.php index 87f514d..470f01d 100644 --- a/app/dbconn.php +++ b/app/dbconn.php @@ -75,8 +75,10 @@ class db_statement extends PDOStatement { //..................... PDO1 .....................// $pdo1 = new database($db_type.':host='.$db_server.';dbname='.$db_database.';charset=utf8', $db_user, $db_pass); +$pdo1->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //..................... PDO2 .....................// $pdo2 = new database($db_type2.':host='.$db_server2.';dbname='.$db_database2.';charset=utf8', $db_user2, $db_pass2); +$pdo2->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); ?> \ No newline at end of file diff --git a/app/ics/api/engine/contact_search.php b/app/ics/api/engine/contact_search.php new file mode 100644 index 0000000..3ef9a1f --- /dev/null +++ b/app/ics/api/engine/contact_search.php @@ -0,0 +1,25 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":keyword" => '%'.$data["keyword"].'%' + ]); + db_check($sth, $answer); + + $result = $sth->fetchAll(PDO::FETCH_ASSOC); + $answer["result"] = $result; + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/api/engine/manage_stock_in.php b/app/ics/api/engine/manage_stock_in.php new file mode 100644 index 0000000..23a8cf5 --- /dev/null +++ b/app/ics/api/engine/manage_stock_in.php @@ -0,0 +1,87 @@ +getStockContext($warehouse_id, $id); + $row = $warehouse['row'] ?? []; + $table = $warehouse['table']; + + $table_log = json_decode($row['log'] ?? '[]', true); + $table_log[] = $logging; + + if ($id > 0) { + + $sql = "UPDATE `$table` SET + `product_sku` = :product_sku, + `in` = :quantity, + `zone` = :zone, + `aisle` = :aisle, + `rack` = :rack, + `contact_id` = :contact_id, + `description` = :description, + `log` = :log + WHERE id = :id AND company_id = :company_id"; + + $sth = $pdo->prepare($sql); + $sth->execute([ + ":id" => $id, + ":company_id" => $company_id, + ":product_sku" => $data["product_sku"], + ":quantity" => $data["quantity"], + ":zone" => $data["zone"], + ":aisle" => $data["aisle"], + ":rack" => $data["rack"], + ":contact_id" => (int)$data["contact_id"], + ":description" => $data["description"], + ":log" => json_encode($table_log), + ]); + + } else { + + $sql = "INSERT INTO `$table` + (uuid, company_id, `date`, product_sku, `in`, zone, aisle, rack, contact_id, `description`, `log`, `type`) + VALUES + (:uuid, :company_id, :date, :product_sku, :quantity, :zone, :aisle, :rack, :contact_id, :description, :log, 'in')"; + + $sth = $pdo->prepare($sql); + $sth->execute([ + ":uuid" => $uuid, + ":company_id" => $company_id, + ":date" => date('Y-m-d H:i:s'), + ":product_sku" => $data["product_sku"], + ":quantity" => $data["quantity"], + ":zone" => $data["zone"], + ":aisle" => $data["aisle"], + ":rack" => $data["rack"], + ":contact_id" => (int)$data["contact_id"], + ":description" => $data["description"], + ":log" => json_encode($table_log), + ]); + } + + $whMgmt->adjustBalance('in', $warehouse_id, $data["product_sku"], $row['in'] ?? 0, $data["quantity"]); + + }); + + $answer["success"] = 1; + + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; + + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; + } + + exit(json_encode($answer)); +?> \ No newline at end of file diff --git a/app/ics/api/engine/manage_stock_out.php b/app/ics/api/engine/manage_stock_out.php new file mode 100644 index 0000000..d7824ba --- /dev/null +++ b/app/ics/api/engine/manage_stock_out.php @@ -0,0 +1,87 @@ +getStockContext($warehouse_id, $id); + $row = $warehouse['row'] ?? []; + $table = $warehouse['table']; + + $table_log = json_decode($row['log'] ?? '[]', true); + $table_log[] = $logging; + + if ($id > 0) { + + $sql = "UPDATE `$table` SET + `product_sku` = :product_sku, + `out` = :quantity, + `zone` = :zone, + `aisle` = :aisle, + `rack` = :rack, + `contact_id` = :contact_id, + `description` = :description, + `log` = :log + WHERE id = :id AND company_id = :company_id"; + + $sth = $pdo->prepare($sql); + $sth->execute([ + ":id" => $id, + ":company_id" => $company_id, + ":product_sku" => $data["product_sku"], + ":quantity" => $data["quantity"], + ":zone" => $data["zone"], + ":aisle" => $data["aisle"], + ":rack" => $data["rack"], + ":contact_id" => (int)$data["contact_id"], + ":description" => $data["description"], + ":log" => json_encode($table_log), + ]); + + } else { + + $sql = "INSERT INTO `$table` + (uuid, company_id, `date`, product_sku, `out`, zone, aisle, rack, contact_id, `description`, `log`, `type`) + VALUES + (:uuid, :company_id, :date, :product_sku, :quantity, :zone, :aisle, :rack, :contact_id, :description, :log, 'out')"; + + $sth = $pdo->prepare($sql); + $sth->execute([ + ":uuid" => $uuid, + ":company_id" => $company_id, + ":date" => date('Y-m-d H:i:s'), + ":product_sku" => $data["product_sku"], + ":quantity" => $data["quantity"], + ":zone" => $data["zone"], + ":aisle" => $data["aisle"], + ":rack" => $data["rack"], + ":contact_id" => (int)$data["contact_id"], + ":description" => $data["description"], + ":log" => json_encode($table_log), + ]); + } + + $whMgmt->adjustBalance('out', $warehouse_id, $data["product_sku"], $row['out'] ?? 0, $data["quantity"]); + + }); + + $answer["success"] = 1; + + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; + + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; + } + + exit(json_encode($answer)); +?> \ No newline at end of file diff --git a/app/ics/api/engine/manage_stock_transfer.php b/app/ics/api/engine/manage_stock_transfer.php new file mode 100644 index 0000000..b37288b --- /dev/null +++ b/app/ics/api/engine/manage_stock_transfer.php @@ -0,0 +1,113 @@ +getStockContext($warehouse_id, $id); + $row = $warehouse['row'] ?? []; + $table = $warehouse['table']; + + // get uuid for update + if ($id > 0 && $data['type'] == "from") { + $sql = "SELECT uuid FROM `$table` + WHERE company_id = :company_id AND id = :id"; + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + $uuid = $sth->fetchColumn(); + } + + $table_log = json_decode($row['log'] ?? '[]', true); + $table_log[] = $logging; + + if ($id > 0) { + + $sql = "UPDATE `$table` SET + `product_sku` = :product_sku, + `{$data['col']}` = :quantity, + `zone` = :zone, + `aisle` = :aisle, + `rack` = :rack, + `contact_id` = :contact_id, + `description` = :description, + `log` = :log + WHERE uuid = :uuid AND company_id = :company_id"; + + $sth = $pdo->prepare($sql); + $sth->execute([ + ":uuid" => $uuid, + ":company_id" => $company_id, + ":product_sku" => $data["product_sku"], + ":quantity" => $data["quantity"], + ":zone" => $data["zone"], + ":aisle" => $data["aisle"], + ":rack" => $data["rack"], + ":contact_id" => (int)$data["contact_id"], + ":description" => $data["description"], + ":log" => json_encode($table_log), + ]); + + } else { + + $sql = "INSERT INTO `$table` + (uuid, company_id, `date`, product_sku, `{$data['col']}`, ref_warehouse, zone, aisle, rack, contact_id, `description`, `log`, `type`) + VALUES + (:uuid, :company_id, :date, :product_sku, :quantity, :ref_warehouse, :zone, :aisle, :rack, :contact_id, :description, :log, 'transfer')"; + + $sth = $pdo->prepare($sql); + $sth->execute([ + ":uuid" => $uuid, + ":company_id" => $company_id, + ":date" => date('Y-m-d H:i:s'), + ":product_sku" => $data["product_sku"], + ":quantity" => $data["quantity"], + ":ref_warehouse" => $ref_warehouse_id, + ":zone" => $data["zone"], + ":aisle" => $data["aisle"], + ":rack" => $data["rack"], + ":contact_id" => (int)$data["contact_id"], + ":description" => $data["description"], + ":log" => json_encode($table_log), + ]); + } + + $whMgmt->adjustBalance($data['col'], $warehouse_id, $data["product_sku"], $row[$data['col']] ?? 0, $data["quantity"]); + } + + }); + + $answer["success"] = 1; + + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; + + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; + } + + exit(json_encode($answer)); +?> \ No newline at end of file diff --git a/app/ics/api/engine/retrieve_aisle.php b/app/ics/api/engine/retrieve_aisle.php index 8fbee7c..af7fc85 100644 --- a/app/ics/api/engine/retrieve_aisle.php +++ b/app/ics/api/engine/retrieve_aisle.php @@ -4,7 +4,14 @@ require '../../../assets/utils/db_auth.php'; $id = (int)$data['id']; - $warehouse = (int)$data['warehouse']; + // identity source of zone and aisle + if(empty($data["type"])){ + $warehouse = (int)$data['warehouse']; + $zone = $data['zone']; + }else{ + $warehouse = (int)$data['warehouse_'.$data["type"]]; + $zone = $data['zone_'.$data["type"]]; + } $sql = "SELECT * FROM md_storage @@ -18,7 +25,7 @@ $sth->execute([ ":company_id" => $company_id, ":warehouse" => $warehouse, - ":zone" => $data["zone"] + ":zone" => $zone ]); db_check($sth, $answer); @@ -26,7 +33,7 @@ $output = []; foreach ($pre as $key => $value) { - $output = array_merge($output, range($value["aisle_form"], $value["aisle_to"])); + $output = array_merge($output, range($value["aisle_from"], $value["aisle_to"])); } $answer["output"] = $output; diff --git a/app/ics/api/engine/retrieve_rack.php b/app/ics/api/engine/retrieve_rack.php index 6d6d9b9..691406c 100644 --- a/app/ics/api/engine/retrieve_rack.php +++ b/app/ics/api/engine/retrieve_rack.php @@ -3,8 +3,26 @@ require '../../../assets/utils/db_auth.php'; + // identity source of zone and aisle + if(empty($data["type"])){ + $warehouse = (int)$data['warehouse']; + $zone = $data['zone']; + $aisle = $data["aisle"]; + }else{ + $warehouse = (int)$data['warehouse_'.$data["type"]]; + $zone = $data['zone_'.$data["type"]]; + $aisle = $data["aisle_".$data["type"]]; + } + + // Detect if numeric and zero-pad both input and query columns + if (is_numeric($aisle)) { + $aisle = str_pad($aisle, 5, '0', STR_PAD_LEFT); + $condition = "LPAD(aisle_from, 5, '0') <= :aisle_from AND LPAD(aisle_to, 5, '0') >= :aisle_to"; + } else { + $condition = ":aisle_from >= aisle_from AND :aisle_to <= aisle_to"; + } + $id = (int)$data['id']; - $warehouse = (int)$data['warehouse']; $sql = "SELECT * FROM md_storage @@ -12,15 +30,16 @@ company_id = :company_id and warehouse = :warehouse and `zone` = :zone and - :aisle between aisle_from and aisle_to + $condition "; $sth = $pdo2->prepare($sql); $sth->execute([ ":company_id" => $company_id, ":warehouse" => $warehouse, - ":zone" => $data["zone"], - ":aisle" => $data["aisle"] + ":zone" => $zone, + ":aisle_from" => $aisle, + ":aisle_to" => $aisle ]); db_check($sth, $answer); @@ -28,7 +47,7 @@ $output = []; foreach ($pre as $key => $value) { - $output = array_merge($output, range($value["rack_form"], $value["rack_to"])); + $output = array_merge($output, range($value["rack_from"], $value["rack_to"])); } $answer["output"] = $output; diff --git a/app/ics/api/engine/retrieve_stock_in.php b/app/ics/api/engine/retrieve_stock_in.php new file mode 100644 index 0000000..b2add0f --- /dev/null +++ b/app/ics/api/engine/retrieve_stock_in.php @@ -0,0 +1,51 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse + ]); + db_check($sth, $answer); + + $warehouse = $sth->fetchColumn(); + + $table = "td_stock_" . $warehouse; + + $sql = "SELECT a.* , a.in as quantity, b.contact_name, c.product_name + FROM `{$table}` a + LEFT JOIN md_contact b ON + a.company_id = b.company_id and + a.contact_id = b.id + LEFT JOIN md_product c ON + a.company_id = b.company_id and + a.product_sku = c.sku + WHERE + a.company_id = :company_id and + a.id = :id "; + + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); + + $answer["output"] = $sth->fetch(PDO::FETCH_ASSOC); + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/api/engine/retrieve_stock_out.php b/app/ics/api/engine/retrieve_stock_out.php new file mode 100644 index 0000000..40e359d --- /dev/null +++ b/app/ics/api/engine/retrieve_stock_out.php @@ -0,0 +1,51 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse + ]); + db_check($sth, $answer); + + $warehouse = $sth->fetchColumn(); + + $table = "td_stock_" . $warehouse; + + $sql = "SELECT a.* , a.out as quantity, b.contact_name, c.product_name + FROM `{$table}` a + LEFT JOIN md_contact b ON + a.company_id = b.company_id and + a.contact_id = b.id + LEFT JOIN md_product c ON + a.company_id = b.company_id and + a.product_sku = c.sku + WHERE + a.company_id = :company_id and + a.id = :id "; + + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); + + $answer["output"] = $sth->fetch(PDO::FETCH_ASSOC); + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/api/engine/retrieve_stock_transfer.php b/app/ics/api/engine/retrieve_stock_transfer.php new file mode 100644 index 0000000..d17ab4c --- /dev/null +++ b/app/ics/api/engine/retrieve_stock_transfer.php @@ -0,0 +1,101 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse + ]); + db_check($sth, $answer); + + $warehouse = $sth->fetchColumn(); + + $table = "td_stock_" . $warehouse; + + $sql = "SELECT a.* , a.out as quantity, b.contact_name, c.product_name + FROM `{$table}` a + LEFT JOIN md_contact b ON + a.company_id = b.company_id and + a.contact_id = b.id + LEFT JOIN md_product c ON + a.company_id = b.company_id and + a.product_sku = c.sku + WHERE + a.company_id = :company_id and + a.id = :id "; + + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); + db_check($sth, $answer); + + $output = $sth->fetch(PDO::FETCH_ASSOC); + + /** + * TO warehouse, zone, aisle, rack, product name, quantity, contact name + */ + + // get warehouse name + $sql = "SELECT warehouse_name + FROM md_warehouse + WHERE + company_id = :company_id and + id = :warehouse + "; + + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $output["ref_warehouse"] + ]); + db_check($sth, $answer); + + $warehouse = $sth->fetchColumn(); + + $table = "td_stock_" . $warehouse; + + $sql = "SELECT a.* , a.in as quantity, b.contact_name, c.product_name + FROM `{$table}` a + LEFT JOIN md_contact b ON + a.company_id = b.company_id and + a.contact_id = b.id + LEFT JOIN md_product c ON + a.company_id = b.company_id and + a.product_sku = c.sku + WHERE + a.company_id = :company_id and + a.uuid = :id "; + + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $output["uuid"] + ]); + db_check($sth, $answer); + + $output["ref"] = $sth->fetch(PDO::FETCH_ASSOC); + + $answer["output"] = $output; + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/api/engine/retrieve_zone.php b/app/ics/api/engine/retrieve_zone.php index 23fdfd3..304bdf4 100644 --- a/app/ics/api/engine/retrieve_zone.php +++ b/app/ics/api/engine/retrieve_zone.php @@ -4,7 +4,13 @@ require '../../../assets/utils/db_auth.php'; $id = (int)$data['id']; - $warehouse = (int)$data['warehouse']; + + // identity source of zone and aisle + if(empty($data["type"])){ + $warehouse = (int)$data['warehouse']; + }else{ + $warehouse = (int)$data['warehouse_'.$data["type"]]; + } $sql = "SELECT * FROM md_storage diff --git a/app/ics/api/engine/stock_in.php b/app/ics/api/engine/stock_in.php new file mode 100644 index 0000000..f91dffe --- /dev/null +++ b/app/ics/api/engine/stock_in.php @@ -0,0 +1,53 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse + ]); + db_check($sth, $answer); + + $warehouse = $sth->fetchColumn(); + + if(!$warehouse) { + $answer["message"] = "Warehouse not found"; + exit(json_encode($answer)); + } + + $table = "td_stock_" . $warehouse; + + $sql = "SELECT a.* , ROUND(a.in,2) as quantity , + b.product_name + FROM `{$table}` a + LEFT JOIN md_product b ON + a.company_id = b.company_id and + a.product_sku = b.sku + WHERE + a.company_id = {$company_id} and + a.type = 'in' + ORDER BY a.date DESC"; + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); + + $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/api/engine/stock_out.php b/app/ics/api/engine/stock_out.php new file mode 100644 index 0000000..e877c15 --- /dev/null +++ b/app/ics/api/engine/stock_out.php @@ -0,0 +1,53 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse + ]); + db_check($sth, $answer); + + $warehouse = $sth->fetchColumn(); + + if(!$warehouse) { + $answer["message"] = "Warehouse not found"; + exit(json_encode($answer)); + } + + $table = "td_stock_" . $warehouse; + + $sql = "SELECT a.* , ROUND(a.out,2) as quantity , + b.product_name + FROM `{$table}` a + LEFT JOIN md_product b ON + a.company_id = b.company_id and + a.product_sku = b.sku + WHERE + a.company_id = {$company_id} and + a.type = 'out' + ORDER BY a.date DESC"; + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); + + $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/api/engine/stock_transfer.php b/app/ics/api/engine/stock_transfer.php new file mode 100644 index 0000000..9dc36f7 --- /dev/null +++ b/app/ics/api/engine/stock_transfer.php @@ -0,0 +1,54 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":warehouse" => $warehouse + ]); + db_check($sth, $answer); + + $warehouse = $sth->fetchColumn(); + + if(!$warehouse) { + $answer["message"] = "Warehouse not found"; + exit(json_encode($answer)); + } + + $table = "td_stock_" . $warehouse; + + $sql = "SELECT a.* , ROUND(a.in,2) as quantity, + b.product_name + FROM `{$table}` a + LEFT JOIN md_product b ON + a.company_id = b.company_id and + a.product_sku = b.sku + WHERE + a.company_id = {$company_id} and + a.type = 'transfer' and + a.out > 0 + ORDER BY a.date DESC"; + $sth = $pdo2->prepare($sql); + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); + + $answer["output"] = $sth->fetchAll(PDO::FETCH_ASSOC); + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/api/engine/warehouse_stats.php b/app/ics/api/engine/warehouse_stats.php new file mode 100644 index 0000000..6ff71b1 --- /dev/null +++ b/app/ics/api/engine/warehouse_stats.php @@ -0,0 +1,24 @@ +prepare($sql); + $sth->execute([ + ":company_id" => $company_id + ]); + db_check($sth, $answer); + + $output = $sth->fetch(PDO::FETCH_ASSOC); + + $answer["output"] = $output; + $answer["success"] = 1; + exit(json_encode($answer)); + +?> \ No newline at end of file diff --git a/app/ics/add_stock_in.php b/app/ics/manage_stock_in.php similarity index 70% rename from app/ics/add_stock_in.php rename to app/ics/manage_stock_in.php index 99b084e..6dd4427 100644 --- a/app/ics/add_stock_in.php +++ b/app/ics/manage_stock_in.php @@ -76,14 +76,14 @@
    - +
    - - + +
    @@ -108,8 +108,11 @@ return ajax_request({ url: "ics/api/engine/manage_stock_in.php", autoPrepare: true, - checkRequired: 0, + checkRequired: 1, debugMode: 0, + data: { + "contact_id": $("#contact").attr('data-id') + }, action: 'manage', onSuccess: function(res) { @@ -142,13 +145,14 @@ - function retrieve_zone() { + function retrieve_zone(callback) { return ajax_request({ url: "ics/api/engine/retrieve_zone.php", autoPrepare: true, checkRequired: 0, noLoading: true, + debugMode: 0, action: 'read', onSuccess: function(res) { var option = ``; @@ -156,6 +160,8 @@ option += ``; }) $(`select#zone`).html(option); + + if (callback) callback(); // ← add this } }); @@ -163,7 +169,7 @@ - function retrieve_aisle() { + function retrieve_aisle(callback) { return ajax_request({ url: "ics/api/engine/retrieve_aisle.php", @@ -177,6 +183,8 @@ option += ``; }) $(`select#aisle`).html(option); + + if (callback) callback(); // ← add this } }); @@ -184,7 +192,7 @@ - function retrieve_rack() { + function retrieve_rack(callback) { return ajax_request({ url: "ics/api/engine/retrieve_rack.php", @@ -198,6 +206,71 @@ option += ``; }) $(`select#rack`).html(option); + + if (callback) callback(); // ← add this + } + }); + + } + + + + function retrieve_for_edit() { + + + return false; + + + return ajax_request({ + url: "ics/api/engine/retrieve_stock_in.php", + autoPrepare: true, + checkRequired: 0, + debugMode: 0, + action: 'read', + onSuccess: function(res) { + + var data = res.output; + + // 1. Set warehouse (already populated from page load) + + $(`#warehouse`).val('').attr('disabled', true); // set warehouse BEFORE retrieve_zone + + // 2. Retrieve zone (autoPrepare reads warehouse value) + retrieve_zone(function() { + $(`select#zone`).val(data.zone).attr('disabled', true); // set zone BEFORE retrieve_aisle + + // 3. Retrieve aisle (autoPrepare reads zone value) + retrieve_aisle(function() { + $(`#aisle`).val(data.aisle).attr('disabled', true); // set aisle BEFORE retrieve_rack + + // 4. Retrieve rack (autoPrepare reads aisle value) + retrieve_rack(function() { + $(`#rack`).val(data.rack).attr('disabled', true); + + // retrieve for edit + $.each(data, function(key, item) { + if (!['warehouse', 'zone', 'aisle', 'rack'].includes(key)) { + $(`#${key}`).val(item); + } + }); + + $('#contact').val(data.contact_name) + .attr('secondary', data.contact_name) + .attr('data-id', data.contact_id); + + $('#product_name').val(data.product_name); + $('#product_sku').attr('secondary', data.product_sku); + + $(`button[type=submit]`).text('Update'); + $(`button[type=reset]`).hide(); + + }); + }); + }); + // Set re + + + } }); @@ -208,12 +281,13 @@ $(async function() { try { await retrieve_warehouse(); + await retrieve_for_edit(); } catch (e) { console.log(e); } }); - + $("select#warehouse").change(function() { retrieve_zone(); }); @@ -225,8 +299,8 @@ $("select#aisle").change(function() { retrieve_rack(); }); - + diff --git a/app/ics/manage_stock_out.php b/app/ics/manage_stock_out.php new file mode 100644 index 0000000..f173d90 --- /dev/null +++ b/app/ics/manage_stock_out.php @@ -0,0 +1,307 @@ + + + + + + + + +
    +
    +
    +
    +
    +

    Stock Out

    + +
    +
    +
    +
    +
    +
    +
    +

    Add Stock

    +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    + + + + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + + +
    + + +
    + + + +
    + + +
    + + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    + + + + + + + + \ No newline at end of file diff --git a/app/ics/manage_stock_transfer.php b/app/ics/manage_stock_transfer.php new file mode 100644 index 0000000..c4495e8 --- /dev/null +++ b/app/ics/manage_stock_transfer.php @@ -0,0 +1,369 @@ + + + + + + + + +
    +
    +
    +
    +
    +

    Stock Transfer

    + +
    +
    +
    +
    +
    +
    +
    +

    Add Stock

    +
    + +
    + + +
    +
    + + +
    + + +
    + + +
    + + + + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + + + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + + +
    + + +
    + + + +
    + + +
    + + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    + + + + + + + + \ No newline at end of file diff --git a/app/ics/stock_in.php b/app/ics/stock_in.php index 44dfd06..34fc53f 100644 --- a/app/ics/stock_in.php +++ b/app/ics/stock_in.php @@ -18,7 +18,7 @@

    Stock in

    - + ADD Stock In @@ -27,18 +27,31 @@
    + +
    + +
    +
    + +
    +
    + +
    +

    Item List

    - +
    + - - + + + @@ -63,7 +76,100 @@ diff --git a/app/ics/stock_out.php b/app/ics/stock_out.php new file mode 100644 index 0000000..2883583 --- /dev/null +++ b/app/ics/stock_out.php @@ -0,0 +1,177 @@ + + + + + + + + +
    +
    +
    +
    +
    +

    Stock Out +

    + + + ADD Stock Out + +
    +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    + +
    +
    +
    +

    Item List

    +
    +
    Date Product QuantityWarehouseStorage LocationZoneAisleRack Status Action
    + + + + + + + + + + + + + + + + +
    DateProductQuantityZoneAisleRackStatusAction
    +
    +
    + +
    + +
    + +
    + +
    + + + + + + + + + \ No newline at end of file diff --git a/app/ics/stock_overview.php b/app/ics/stock_overview.php index 1f3399c..f59264c 100644 --- a/app/ics/stock_overview.php +++ b/app/ics/stock_overview.php @@ -23,23 +23,26 @@
    -
    +
    - Total Sales -

    1,234

    + Total Capacity +

    0

    Across all warehouses

    + +
    +
    +
    - -
    +
    @@ -53,6 +56,10 @@
    + +
    +
    +
    @@ -71,6 +78,10 @@
    + +
    +
    +
    @@ -89,6 +100,10 @@ + +
    +
    +
    @@ -116,6 +131,10 @@
    + +
    +
    +
    @@ -134,6 +153,10 @@
    + +
    +
    +
    @@ -231,28 +254,39 @@ - -
    -
    -
    -

    Copyright © 2026 InApp Inventory Dashboard. Developed by CodesCandy

    -
    -
    - -
    -
    - Download Now -
    - + + diff --git a/app/ics/stock_transfer.php b/app/ics/stock_transfer.php new file mode 100644 index 0000000..9a6a685 --- /dev/null +++ b/app/ics/stock_transfer.php @@ -0,0 +1,177 @@ + + + + + + + + +
    +
    +
    +
    +
    +

    Stock Transfer +

    + + + ADD Stock Transfer + +
    +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    + +
    +
    +
    +

    Item List

    +
    + + + + + + + + + + + + + + + + + +
    DateProductQuantityZoneAisleRackStatusAction
    +
    +
    + +
    + +
    + +
    + +
    +
    + + + + + + + + \ No newline at end of file diff --git a/app/include_header.php b/app/include_header.php index 4c9ba27..91b0cb2 100644 --- a/app/include_header.php +++ b/app/include_header.php @@ -46,8 +46,8 @@ - + \ No newline at end of file diff --git a/app/include_setting_sidebar.php b/app/include_setting_sidebar.php new file mode 100644 index 0000000..172b998 --- /dev/null +++ b/app/include_setting_sidebar.php @@ -0,0 +1,59 @@ + + diff --git a/app/include_sidebar.php b/app/include_sidebar.php index 3c959f0..12fb427 100644 --- a/app/include_sidebar.php +++ b/app/include_sidebar.php @@ -100,14 +100,14 @@
  • - + Stock Out
  • - + Stock Transfer diff --git a/app/include_topbar.php b/app/include_topbar.php index fa58c0f..ec63b52 100644 --- a/app/include_topbar.php +++ b/app/include_topbar.php @@ -5,6 +5,8 @@ if(!isset($_SESSION["otp"])){ header('Location: '.$server_url.'login/index.php'); } +require 'preset.php'; + ?>
    @@ -109,6 +111,11 @@ if(!isset($_SESSION["otp"])){ Switch Branch + + + Setting + + Log Out @@ -145,4 +152,11 @@ function log_out() { }); } + + +function profile_setting(){ + + window.location.href = "setting/profile.php"; + +} \ No newline at end of file diff --git a/app/inventory/api/engine/manage_category.php b/app/inventory/api/engine/manage_category.php index 692a0f0..dc37c10 100644 --- a/app/inventory/api/engine/manage_category.php +++ b/app/inventory/api/engine/manage_category.php @@ -1,69 +1,74 @@ prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - ":id" => $id - ]); - db_check($sth, $answer); - - $row = $sth->fetch(PDO::FETCH_ASSOC); + $id = (int)$data['id']; - $table_log = json_decode($row['log'] ?? '[]', true); + $sql = "SELECT `log` FROM md_product_category + WHERE company_id = :company_id AND id = :id"; + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); - $table_log[] = $logging; + $table_log = json_decode($sth->fetchColumn() ?: '[]', true); + $table_log[] = $logging; - if ($id > 0) { + if ($id > 0) { - $sql = "UPDATE md_product_category SET - `category` = :category, - `slug` = :slug, - `description` = :description, - `status` = :status, - `log` = :log - WHERE id = :id AND company_id = :company_id"; + $sql = "UPDATE md_product_category SET + `category` = :category, + `slug` = :slug, + `description` = :description, + `status` = :status, + `log` = :log + WHERE id = :id AND company_id = :company_id"; - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":id" => $id, - ":company_id" => $company_id, - ":category" => $data["category"], - ":slug" => $data["slug"], - ":description" => $data["description"], - ":status" => $data["status"], - ":log" => json_encode($table_log), - ]); + $sth = $pdo->prepare($sql); + $sth->execute([ + ":id" => $id, + ":company_id" => $company_id, + ":category" => $data["category"], + ":slug" => $data["slug"], + ":description" => $data["description"], + ":status" => $data["status"], + ":log" => json_encode($table_log), + ]); - } else { + } else { - $sql = "INSERT INTO md_product_category - (company_id, category, slug, `description`, `status`, `log`) - VALUES - (:company_id, :category, :slug, :description, :status, :log)"; + $sql = "INSERT INTO md_product_category + (company_id, category, slug, `description`, `status`, `log`) + VALUES + (:company_id, :category, :slug, :description, :status, :log)"; - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - ":category" => $data["category"], - ":slug" => $data["slug"], - ":description" => $data["description"], - ":status" => $data["status"], - ":log" => json_encode($table_log), - ]); + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":category" => $data["category"], + ":slug" => $data["slug"], + ":description" => $data["description"], + ":status" => $data["status"], + ":log" => json_encode($table_log), + ]); + } + + }); + + $answer["success"] = 1; + + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; + + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; } - $answer["success"] = 1; exit(json_encode($answer)); - ?> \ No newline at end of file diff --git a/app/inventory/api/engine/manage_product.php b/app/inventory/api/engine/manage_product.php index bc8a062..057bd45 100644 --- a/app/inventory/api/engine/manage_product.php +++ b/app/inventory/api/engine/manage_product.php @@ -3,77 +3,87 @@ require '../../../assets/utils/db_auth.php'; - $id = (int)$data['id']; + try { - // get existing log - $sql = "SELECT `log` - FROM md_product - WHERE - company_id = :company_id and - id = :id "; - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - ":id" => $id - ]); - db_check($sth, $answer); - - $row = $sth->fetch(PDO::FETCH_ASSOC); + dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) { - $table_log = json_decode($row['log'] ?? '[]', true); + $id = (int)$data['id']; - $table_log[] = $logging; + // get existing log + $sql = "SELECT `log` FROM md_product + WHERE company_id = :company_id AND id = :id"; + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); - if ($id > 0) { + $table_log = json_decode($sth->fetchColumn() ?: '[]', true); + $table_log[] = $logging; - $sql = "UPDATE md_product SET - product_name = :product_name, - sku = :sku, - price = :price, - category = :category, - product_image = :product_image, - `description` = :description, - `status` = :status, - `log` = :log - WHERE id = :id AND company_id = :company_id"; + if ($id > 0) { - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":id" => $id, - ":company_id" => $company_id, - ":product_name" => $data["product_name"], - ":sku" => $data["sku"], - ":price" => $data["price"], - ":category" => $data["category"], - ":product_image"=> $data["product_image"], - ":description" => $data["description"], - ":status" => $data["status"], - ":log" => json_encode($table_log), - ]); + $sql = "UPDATE md_product SET + product_name = :product_name, + sku = :sku, + price = :price, + min_stock = :min_stock, + category = :category, + product_image = :product_image, + `description` = :description, + `status` = :status, + `log` = :log + WHERE id = :id AND company_id = :company_id"; - } else { + $sth = $pdo->prepare($sql); + $sth->execute([ + ":id" => $id, + ":company_id" => $company_id, + ":product_name" => $data["product_name"], + ":sku" => $data["sku"], + ":price" => $data["price"], + ":min_stock" => $data["min_stock"], + ":category" => $data["category"], + ":product_image"=> $data["product_image"], + ":description" => $data["description"], + ":status" => $data["status"], + ":log" => json_encode($table_log), + ]); - $sql = "INSERT INTO md_product - (company_id, product_name, sku, price, category, product_image, `description`, `status`, `log`) - VALUES - (:company_id, :product_name, :sku, :price, :category, :product_image, :description, :status, :log)"; + } else { - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - ":product_name" => $data["product_name"], - ":sku" => $data["sku"], - ":price" => $data["price"], - ":category" => $data["category"], - ":product_image"=> $data["product_image"], - ":description" => $data["description"], - ":status" => $data["status"], - ":log" => json_encode($table_log), - ]); + $sql = "INSERT INTO md_product + (company_id, product_name, sku, price, min_stock, category, product_image, `description`, `status`, `log`) + VALUES + (:company_id, :product_name, :sku, :price, :min_stock, :category, :product_image, :description, :status, :log)"; + + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":product_name" => $data["product_name"], + ":sku" => $data["sku"], + ":price" => $data["price"], + ":min_stock" => $data["min_stock"], + ":category" => $data["category"], + ":product_image"=> $data["product_image"], + ":description" => $data["description"], + ":status" => $data["status"], + ":log" => json_encode($table_log), + ]); + } + + }); + + $answer["success"] = 1; + + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; + + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; } - - $answer["success"] = 1; exit(json_encode($answer)); - ?> \ No newline at end of file diff --git a/app/inventory/api/engine/manage_storage.php b/app/inventory/api/engine/manage_storage.php index 1460e2f..9ff4a0b 100644 --- a/app/inventory/api/engine/manage_storage.php +++ b/app/inventory/api/engine/manage_storage.php @@ -1,93 +1,76 @@ prepare($sql); -$sth->execute([ - ':company_id' => $company_id, - ':id' => $id, -]); + $sql = "SELECT `log` FROM md_storage + WHERE company_id = :company_id AND id = :id"; + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); -db_check($sth, $answer); + $table_log = json_decode($sth->fetchColumn() ?: '[]', true); + if (!is_array($table_log)) $table_log = []; + $table_log[] = $logging; -$row = $sth->fetch(PDO::FETCH_ASSOC); + $params = [ + ":company_id" => $company_id, + ":warehouse" => $data["warehouse"] ?? "", + ":zone" => $data["zone"] ?? "", + ":aisle_from" => $data["aisle_from"] ?? "", + ":aisle_to" => $data["aisle_to"] ?? "", + ":rack_from" => $data["rack_from"] ?? "", + ":rack_to" => $data["rack_to"] ?? "", + ":description" => $data["description"] ?? "", + ":status" => (int)($data["status"] ?? 1), + ":log" => json_encode($table_log, JSON_UNESCAPED_UNICODE), + ]; -$table_log = json_decode($row['log'] ?? '[]', true); -if (!is_array($table_log)) $table_log = []; + if ($id > 0) { -// add new log entry (assumes $logging already prepared) -$table_log[] = $logging; + $sql = "UPDATE md_storage SET + warehouse = :warehouse, + zone = :zone, + aisle_from = :aisle_from, + aisle_to = :aisle_to, + rack_from = :rack_from, + rack_to = :rack_to, + description = :description, + status = :status, + `log` = :log + WHERE id = :id AND company_id = :company_id"; -if ($id > 0) { + $params[":id"] = $id; - $sql = "UPDATE md_storage SET - warehouse = :warehouse, - zone = :zone, - aisle_from = :aisle_from, - aisle_to = :aisle_to, - rack_from = :rack_from, - rack_to = :rack_to, - description = :description, - status = :status, - `log` = :log - WHERE id = :id - AND company_id = :company_id"; + } else { - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":id" => $id, - ":company_id" => $company_id, + $sql = "INSERT INTO md_storage + (company_id, warehouse, zone, aisle_from, aisle_to, rack_from, rack_to, description, status, `log`) + VALUES + (:company_id, :warehouse, :zone, :aisle_from, :aisle_to, :rack_from, :rack_to, :description, :status, :log)"; + } - ":warehouse" => $data["warehouse"] ?? "", - ":zone" => $data["zone"] ?? "", + $sth = $pdo->prepare($sql); + $sth->execute($params); - ":aisle_from" => $data["aisle_from"] ?? "", - ":aisle_to" => $data["aisle_to"] ?? "", + }); - ":rack_from" => $data["rack_from"] ?? "", - ":rack_to" => $data["rack_to"] ?? "", + $answer["success"] = 1; - ":description" => $data["description"] ?? "", - ":status" => (int)($data["status"] ?? 1), - ":log" => json_encode($table_log, JSON_UNESCAPED_UNICODE), - ]); + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; -} else { + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; + } - $sql = "INSERT INTO md_storage - (company_id, warehouse, zone, aisle_from, aisle_to, rack_from, rack_to, description, status, `log`) - VALUES - (:company_id, :warehouse, :zone, :aisle_from, :aisle_to, :rack_from, :rack_to, :description, :status, :log)"; - - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - - ":warehouse" => $data["warehouse"] ?? "", - ":zone" => $data["zone"] ?? "", - - ":aisle_from" => $data["aisle_from"] ?? "", - ":aisle_to" => $data["aisle_to"] ?? "", - - ":rack_from" => $data["rack_from"] ?? "", - ":rack_to" => $data["rack_to"] ?? "", - - ":description" => $data["description"] ?? "", - ":status" => (int)($data["status"] ?? 1), - ":log" => json_encode($table_log, JSON_UNESCAPED_UNICODE), - ]); -} - -db_check($sth, $answer); - -$answer["success"] = 1; -exit(json_encode($answer)); -?> + exit(json_encode($answer)); +?> \ No newline at end of file diff --git a/app/inventory/api/engine/manage_warehouse.php b/app/inventory/api/engine/manage_warehouse.php index d0425c1..9c90d31 100644 --- a/app/inventory/api/engine/manage_warehouse.php +++ b/app/inventory/api/engine/manage_warehouse.php @@ -1,98 +1,79 @@ beginTransaction(); + $sql = "SELECT `log` FROM md_warehouse + WHERE company_id = :company_id AND id = :id"; + $sth = $pdo->prepare($sql); + $sth->execute([ + ":company_id" => $company_id, + ":id" => $id + ]); -// get existing log -$sql = "SELECT `log` - FROM md_warehouse - WHERE company_id = :company_id - AND id = :id"; -$sth = $pdo2->prepare($sql); -$sth->execute([ - ':company_id' => $company_id, - ':id' => $id, -]); + $table_log = json_decode($sth->fetchColumn() ?: '[]', true); + if (!is_array($table_log)) $table_log = []; + $table_log[] = $logging; -db_check($sth, $answer); + $params = [ + ":company_id" => $company_id, + ":warehouse_name" => $data["warehouse_name"] ?? "", + ":location" => $data["location"] ?? "", + ":manager" => (int)($data["manager"] ?? 0), + ":capacity" => (int)($data["capacity"] ?? 0), + ":description" => $data["description"] ?? "", + ":status" => (int)($data["status"] ?? 1), + ":log" => json_encode($table_log, JSON_UNESCAPED_UNICODE), + ]; -$row = $sth->fetch(PDO::FETCH_ASSOC); + if ($id > 0) { -$table_log = json_decode($row['log'] ?? '[]', true); -if (!is_array($table_log)) $table_log = []; + $sql = "UPDATE md_warehouse SET + `warehouse_name` = :warehouse_name, + `location` = :location, + `manager` = :manager, + `capacity` = :capacity, + `description` = :description, + `status` = :status, + `log` = :log + WHERE id = :id AND company_id = :company_id"; -// add new log entry (assumes $logging already prepared) -$table_log[] = $logging; + $params[":id"] = $id; -if ($id > 0) { + } else { - $sql = "UPDATE md_warehouse SET - warehouse_name = :warehouse_name, - location = :location, - manager = :manager, - capacity = :capacity, - description = :description, - status = :status, - `log` = :log - WHERE id = :id - AND company_id = :company_id"; + $sql = "INSERT INTO md_warehouse + (company_id, warehouse_name, location, manager, capacity, description, status, `log`) + VALUES + (:company_id, :warehouse_name, :location, :manager, :capacity, :description, :status, :log)"; + } - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":id" => $id, - ":company_id" => $company_id, - ":warehouse_name" => $data["warehouse_name"] ?? "", - ":location" => $data["location"] ?? "", - ":manager" => (int)($data["manager"] ?? 0), - ":capacity" => (int)($data["capacity"] ?? 0), - ":description" => $data["description"] ?? "", - ":status" => (int)($data["status"] ?? 1), - ":log" => json_encode($table_log, JSON_UNESCAPED_UNICODE), - ]); - db_check($sth, $answer); + $sth = $pdo->prepare($sql); + $sth->execute($params); -} else { + // Create stock table for new warehouse + if ($id == 0 && !empty($data["warehouse_name"])) { + $safe_name = 'td_stock_' . preg_replace('/[^a-zA-Z0-9_]/', '', $data["warehouse_name"]); + $sql = "CREATE TABLE `$safe_name` LIKE `td_stock`"; + $pdo->exec($sql); + } - $sql = "INSERT INTO md_warehouse - (company_id, warehouse_name, location, manager, capacity, description, status, `log`) - VALUES - (:company_id, :warehouse_name, :location, :manager, :capacity, :description, :status, :log)"; + }); - $sth = $pdo2->prepare($sql); - $sth->execute([ - ":company_id" => $company_id, - ":warehouse_name" => $data["warehouse_name"] ?? "", - ":location" => $data["location"] ?? "", - ":manager" => (int)($data["manager"] ?? 0), - ":capacity" => (int)($data["capacity"] ?? 0), - ":description" => $data["description"] ?? "", - ":status" => (int)($data["status"] ?? 1), - ":log" => json_encode($table_log, JSON_UNESCAPED_UNICODE), - ]); - db_check($sth, $answer); + $answer["success"] = 1; + } catch (PDOException $e) { + $answer["success"] = 0; + $answer["message"] = "Database error, please try again"; - - if(!empty($data["warehouse_name"])){ - /** - * Create warehouse table - */ - $safe_name = 'td_stock_' . preg_replace('/[^a-zA-Z0-9_]/', '', $data["warehouse_name"]); - - $sql = "CREATE TABLE `$safe_name` LIKE `td_stock`"; - $sth = $pdo2->prepare($sql); - $sth->execute(); - db_check($sth, $answer); - } - -} + } catch (Exception $e) { + $answer["success"] = 0; + $answer["message"] = "Something went wrong"; + } -$pdo2->commit(); - -$answer["success"] = 1; -exit(json_encode($answer)); -?> + exit(json_encode($answer)); +?> \ No newline at end of file diff --git a/app/inventory/manage_category.php b/app/inventory/manage_category.php index 541cb12..856b96b 100644 --- a/app/inventory/manage_category.php +++ b/app/inventory/manage_category.php @@ -87,7 +87,7 @@ } - function retreive_for_edit() { + function retrieve_for_edit() { return false; @@ -117,7 +117,7 @@ $(async function() { try { - await retreive_for_edit(); + await retrieve_for_edit(); } catch (e) { console.log(e); } diff --git a/app/inventory/manage_product.php b/app/inventory/manage_product.php index 0d51f8c..056ac79 100644 --- a/app/inventory/manage_product.php +++ b/app/inventory/manage_product.php @@ -43,6 +43,10 @@ +
    + + +
    @@ -115,7 +119,7 @@ } - function retreive_for_edit() { + function retrieve_for_edit() { return false; @@ -146,7 +150,7 @@ $(async function() { try { await retrieve_category(); - await retreive_for_edit(); + await retrieve_for_edit(); } catch (e) { console.log(e); } diff --git a/app/inventory/manage_storage.php b/app/inventory/manage_storage.php index 8185301..d03527e 100644 --- a/app/inventory/manage_storage.php +++ b/app/inventory/manage_storage.php @@ -120,7 +120,7 @@ } - function retreive_for_edit() { + function retrieve_for_edit() { return ajax_request({ url: "inventory/api/engine/retrieve_storage.php", @@ -148,7 +148,7 @@ try { await retrieve_warehouse(); - await retreive_for_edit(); + await retrieve_for_edit(); } catch (e) { console.log(e); diff --git a/app/inventory/manage_warehouse.php b/app/inventory/manage_warehouse.php index 0b80f35..379bc6f 100644 --- a/app/inventory/manage_warehouse.php +++ b/app/inventory/manage_warehouse.php @@ -113,7 +113,7 @@ } - function retreive_for_edit() { + function retrieve_for_edit() { return ajax_request({ url: "inventory/api/engine/retrieve_warehouse.php", @@ -141,7 +141,7 @@ try { await retrieve_manager(); - await retreive_for_edit(); + await retrieve_for_edit(); } catch (e) { console.log(e); diff --git a/app/inventory/product.php b/app/inventory/product.php index fa657a1..3c6d189 100644 --- a/app/inventory/product.php +++ b/app/inventory/product.php @@ -344,7 +344,7 @@ ${item['product_name']} ${item['sku']} ${item['description']} - ${item['status']} + ${format_number(item['min_stock'],2)} ${(item['status'])?'Active':'Inactive'} diff --git a/app/inventory/warehouse.php b/app/inventory/warehouse.php index 93060d5..a7e1e7c 100644 --- a/app/inventory/warehouse.php +++ b/app/inventory/warehouse.php @@ -295,7 +295,7 @@ ${item['warehouse_name']} ${item['location']} ${item['manager']} - ${item['capacity']} + ${format_number(item['capacity'],2)} ${item['product']} ${item.status} diff --git a/app/preset.php b/app/preset.php index bbc8e8c..5a2805d 100644 --- a/app/preset.php +++ b/app/preset.php @@ -3,11 +3,9 @@ //<><><><><><><><> MAIN TRCLOUD <><><><><><><><>// if(true){ $expire = "2027-01-01"; - - - + // configuration + // global variables + $prop['limit'] = 50; } -// configuration - ?> diff --git a/app/setting/profile.php b/app/setting/profile.php new file mode 100644 index 0000000..27dbd41 --- /dev/null +++ b/app/setting/profile.php @@ -0,0 +1,191 @@ + + + + + + + + +
    +
    +
    +
    +
    +
    +

    Manage Profile

    +

    Update profile detail

    +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    + + +
    + +
    + +
    +
    +
    +
    + +
    + +
    + + + + + + + + + + \ No newline at end of file