ICS modules
This commit is contained in:
@@ -78,3 +78,14 @@
|
||||
.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;
|
||||
}
|
||||
@@ -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 += "<div class='contact-result-item' style='font-family:\"Poppins\",sans-serif;padding:4px 0;'>";
|
||||
temp += "<div style='font-size:10px;text-transform:uppercase;color:#E66239;font-weight:600;line-height:1.2;'>";
|
||||
temp += "Tax ID: " + (item.tax_id || 'N/A');
|
||||
temp += "</div>";
|
||||
temp += "<div style='font-size:13px;font-weight:500;color:#171717;margin-top:2px;'>";
|
||||
temp += item.contact_name;
|
||||
temp += "</div>";
|
||||
temp += "</div>";
|
||||
|
||||
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 $("<li>")
|
||||
.append($("<div>").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'));
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -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('.');
|
||||
}
|
||||
@@ -57,8 +57,12 @@ 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);
|
||||
|
||||
if(isset($options['before_exit'])) {
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,162 +1,46 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
|
||||
/** * FILE SYNCHRONIZATION & UPLOAD LOGIC
|
||||
* -----------------------------------------------------------------------------------
|
||||
* Strategy: "Keep & Sync"
|
||||
* 1. Identify which existing files were removed by the user and delete them from disk.
|
||||
* 2. Upload any brand-new files dropped into the Dropzone.
|
||||
* 3. Re-assemble a final comma-separated string containing (Kept Files + New Files).
|
||||
* -----------------------------------------------------------------------------------
|
||||
*/
|
||||
try {
|
||||
/** 1. FILE HANDLING **/
|
||||
$uploader = new FileUploader($include_url . "uploads/contact/");
|
||||
|
||||
// Define the physical path for storage
|
||||
$target_dir = $include_url . "uploads/contact/";
|
||||
|
||||
/** 1. DISK CLEANUP (Removal of deleted files) **/
|
||||
// Cleanup 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();
|
||||
|
||||
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']) : [];
|
||||
|
||||
foreach ($existing_files_array as $file_on_disk) {
|
||||
$file_on_disk = trim($file_on_disk);
|
||||
if (empty($file_on_disk)) continue;
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 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";
|
||||
$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'] ?? '');
|
||||
}
|
||||
|
||||
// Upload new files
|
||||
$errors = $uploader->upload('contact_files');
|
||||
if (!empty($errors)) {
|
||||
$answer["success"] = 0;
|
||||
$answer["message"] = $errors[0];
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
$db_image_string = $uploader->buildFileString($data['keep_files'] ?? '');
|
||||
|
||||
/** 2. DATABASE **/
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging, $id, $db_image_string) {
|
||||
|
||||
$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
|
||||
]);
|
||||
|
||||
$row = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row) {
|
||||
$table_log = json_decode($row['log'] ?? '[]', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Append the new log entry
|
||||
$table_log = json_decode($sth->fetchColumn() ?: '[]', true);
|
||||
if (!is_array($table_log)) $table_log = [];
|
||||
$table_log[] = $logging;
|
||||
|
||||
// 3. Database Operation
|
||||
$params = [
|
||||
":company_id" => $company_id,
|
||||
":contact_name" => $data["contact_name"],
|
||||
@@ -170,11 +54,10 @@
|
||||
":remark" => $data["remark"],
|
||||
":files" => $db_image_string,
|
||||
":status" => (int)$data["status"],
|
||||
":log" => json_encode($table_log)
|
||||
":log" => json_encode($table_log),
|
||||
];
|
||||
|
||||
if ($id > 0) {
|
||||
// UPDATE
|
||||
$sql = "UPDATE md_contact SET
|
||||
`contact_name` = :contact_name,
|
||||
`tax_id` = :tax_id,
|
||||
@@ -189,24 +72,34 @@
|
||||
`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);
|
||||
}
|
||||
|
||||
$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();
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
@@ -1,43 +1,34 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) {
|
||||
|
||||
$id = (int)$data['id'];
|
||||
|
||||
// Initialize log array
|
||||
$table_log = [];
|
||||
|
||||
// Get existing log only if we are updating an existing record
|
||||
if ($id > 0) {
|
||||
$sql = "SELECT `log`
|
||||
FROM md_contact_type
|
||||
WHERE
|
||||
company_id = :company_id AND
|
||||
id = :id";
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$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
|
||||
":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);
|
||||
}
|
||||
}
|
||||
|
||||
// Append the new log entry (assuming $logging is defined in your preset/utils)
|
||||
$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) {
|
||||
// UPDATE existing record
|
||||
|
||||
$sql = "UPDATE md_contact_type SET
|
||||
`contact_type` = :contact_type,
|
||||
`description` = :description,
|
||||
@@ -45,33 +36,31 @@
|
||||
`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),
|
||||
]);
|
||||
$params[":id"] = $id;
|
||||
|
||||
} 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),
|
||||
]);
|
||||
}
|
||||
|
||||
$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";
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
@@ -185,7 +185,7 @@
|
||||
url: "<?php echo $server_url?>contact/api/engine/manage_contact.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 1,
|
||||
debugMode: 1,
|
||||
debugMode: 0,
|
||||
formData: formData,
|
||||
action: 'manage',
|
||||
onSuccess: function(res) {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
}
|
||||
|
||||
|
||||
function retreive_for_edit() {
|
||||
function retrieve_for_edit() {
|
||||
|
||||
<?php if(empty($_GET['id'])){ ?>
|
||||
return false;
|
||||
@@ -114,7 +114,7 @@
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retreive_for_edit();
|
||||
await retrieve_for_edit();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$sql = "SELECT *
|
||||
FROM md_contact
|
||||
WHERE
|
||||
company_id = :company_id and
|
||||
contact_name like :keyword
|
||||
LIMIT 50
|
||||
";
|
||||
$sth = $pdo2->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));
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging, $uuid, &$answer) {
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse_id = (int)$data["warehouse"];
|
||||
$whMgmt = new WarehouseManager($pdo, $company_id);
|
||||
|
||||
$warehouse = $whMgmt->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));
|
||||
?>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging, $uuid) {
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse_id = (int)$data["warehouse"];
|
||||
$whMgmt = new WarehouseManager($pdo, $company_id);
|
||||
|
||||
$warehouse = $whMgmt->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));
|
||||
?>
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging, $uuid) {
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$whMgmt = new WarehouseManager($pdo, $company_id);
|
||||
|
||||
for ($i = 0; $i < 2; $i++) {
|
||||
|
||||
$data['type'] = ($i == 0) ? "from" : "to";
|
||||
$data['ref_type'] = ($i == 0) ? "to" : "from";
|
||||
$data['col'] = ($i == 0) ? "out" : "in";
|
||||
|
||||
$warehouse_id = (int)$data['warehouse_' . $data["type"]];
|
||||
$ref_warehouse_id = (int)$data['warehouse_' . $data["ref_type"]];
|
||||
$data["warehouse"] = $data['warehouse_' . $data["type"]];
|
||||
$data["zone"] = $data['zone_' . $data["type"]];
|
||||
$data["aisle"] = $data['aisle_' . $data["type"]];
|
||||
$data["rack"] = $data['rack_' . $data["type"]];
|
||||
|
||||
$warehouse = $whMgmt->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));
|
||||
?>
|
||||
@@ -4,7 +4,14 @@
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
// 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;
|
||||
|
||||
@@ -3,8 +3,26 @@
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
// 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'];
|
||||
|
||||
$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;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse = (int)$data["wh"];
|
||||
|
||||
// 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" => $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));
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse = (int)$data["wh"];
|
||||
|
||||
// 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" => $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));
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse = (int)$data["wh"];
|
||||
|
||||
/**
|
||||
* FROM 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" => $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));
|
||||
|
||||
?>
|
||||
@@ -4,7 +4,13 @@
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
|
||||
// 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
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse = (int)$data["warehouse"];
|
||||
|
||||
// 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" => $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));
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse = (int)$data["warehouse"];
|
||||
|
||||
// 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" => $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));
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
$id = (int)$data['id'];
|
||||
$warehouse = (int)$data["warehouse"];
|
||||
|
||||
// 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" => $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));
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
|
||||
$sql = "SELECT SUM(capacity) as total_capacity, count(*) as total_warehouse
|
||||
FROM md_warehouse a
|
||||
WHERE
|
||||
a.company_id = :company_id
|
||||
";
|
||||
$sth = $pdo2->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));
|
||||
|
||||
?>
|
||||
@@ -76,14 +76,14 @@
|
||||
<!-- Contact -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="contact" class="form-label">Contact</label>
|
||||
<input type="text" class="form-control" id="contact" placeholder="Enter contact name">
|
||||
<input type="text" class="form-control contact_search" id="contact" placeholder="Enter contact name">
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Notes / Description -->
|
||||
<div class="mb-3 col-lg-12">
|
||||
<label for="notes" class="form-label">Notes / Description</label>
|
||||
<textarea class="form-control" id="notes" rows="3" placeholder="Enter any notes"></textarea>
|
||||
<label for="description" class="form-label">Notes / Description</label>
|
||||
<textarea class="form-control" id="description" rows="3" placeholder="Enter any notes"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
@@ -108,8 +108,11 @@
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_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: "<?php echo $server_url?>ics/api/engine/retrieve_zone.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
noLoading: true,
|
||||
debugMode: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select zone</option>`;
|
||||
@@ -156,6 +160,8 @@
|
||||
option += `<option value='${item.zone}'>${item.zone}</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: "<?php echo $server_url?>ics/api/engine/retrieve_aisle.php",
|
||||
@@ -177,6 +183,8 @@
|
||||
option += `<option value='${item}'>${item}</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: "<?php echo $server_url?>ics/api/engine/retrieve_rack.php",
|
||||
@@ -198,6 +206,71 @@
|
||||
option += `<option value='${item}'>${item}</option>`;
|
||||
})
|
||||
$(`select#rack`).html(option);
|
||||
|
||||
if (callback) callback(); // ← add this
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_for_edit() {
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
return false;
|
||||
<?php } ?>
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_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('<?php echo $_GET["wh"];?>').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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
$("select#warehouse").change(function() {
|
||||
retrieve_zone();
|
||||
});
|
||||
@@ -226,7 +300,7 @@
|
||||
retrieve_rack();
|
||||
});
|
||||
|
||||
|
||||
<?php } ?>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
@@ -0,0 +1,307 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../config.php';
|
||||
require '../include_header.php';
|
||||
|
||||
?>
|
||||
|
||||
<body>
|
||||
<?php require '../include_topbar.php';?>
|
||||
<?php require '../include_sidebar.php';?>
|
||||
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
<main id="content" class="content py-15">
|
||||
<div class="container-fluid">
|
||||
<div class="row ">
|
||||
<div class="col-12">
|
||||
<div class="mb-6">
|
||||
<h1 class="fs-3 mb-0">Stock Out</h1>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g">
|
||||
<div class="col-lg-8 col-12">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="fs-5 mb-4">Add Stock</h2>
|
||||
<form class="row gx-5">
|
||||
<!-- Product Name -->
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="product_sku" class="form-label">SKU</label>
|
||||
<input type="text" id="product_sku" class="form-control product_search"
|
||||
placeholder="Type product sku..." autocomplete="off" required>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="product_name" class="form-label">Name</label>
|
||||
<input type="text" id="product_name" class="form-control" autocomplete="off" disabled>
|
||||
</div>
|
||||
|
||||
<!-- SKU or Product Code -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="quantity" class="form-label">Quantity</label>
|
||||
<input type="number" class="form-control" id="quantity" placeholder="Enter quantity" required>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Warehouse -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="warehouse" class="form-label">Warehouse</label>
|
||||
<select name="warehouse" id="warehouse" class="form-select" required></select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="zone" class="form-label">Zone</label>
|
||||
<select name="zone" id="zone" class="form-select" required>
|
||||
<option value="">Please select zone</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="aisle" class="form-label">Aisle</label>
|
||||
<select name="aisle" id="aisle" class="form-select" required>
|
||||
<option value="">Please select aisle</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="rack" class="form-label">Rack</label>
|
||||
<select name="rack" id="rack" class="form-select" required>
|
||||
<option value="">Please select rack</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Contact -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="contact" class="form-label">Contact</label>
|
||||
<input type="text" class="form-control contact_search" id="contact" placeholder="Enter contact name">
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Notes / Description -->
|
||||
<div class="mb-3 col-lg-12">
|
||||
<label for="description" class="form-label">Notes / Description</label>
|
||||
<textarea class="form-control" id="description" rows="3" placeholder="Enter any notes"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<div class="mb-3 col-lg-12">
|
||||
<button type="submit" class="btn btn-primary" onclick="manage_stock_out();">Add Stock</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php require "../include_ending.php";?>
|
||||
|
||||
<script>
|
||||
function manage_stock_out() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/manage_stock_out.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 1,
|
||||
debugMode: 0,
|
||||
data: {
|
||||
"contact_id": $("#contact").attr('data-id')
|
||||
},
|
||||
action: 'manage',
|
||||
onSuccess: function(res) {
|
||||
|
||||
window.location.href = "<?php echo $server_url?>ics/stock_out.php";
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_warehouse() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/warehouse.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select warehouse</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item.id}'>${item.warehouse_name}</option>`;
|
||||
})
|
||||
$(`select#warehouse`).html(option);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_zone(callback) {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_zone.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
noLoading: true,
|
||||
debugMode: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select zone</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item.zone}'>${item.zone}</option>`;
|
||||
})
|
||||
$(`select#zone`).html(option);
|
||||
|
||||
if (callback) callback(); // ← add this
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_aisle(callback) {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_aisle.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
noLoading: true,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select aisle</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item}'>${item}</option>`;
|
||||
})
|
||||
$(`select#aisle`).html(option);
|
||||
|
||||
if (callback) callback(); // ← add this
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_rack(callback) {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_rack.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
noLoading: true,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select rack</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item}'>${item}</option>`;
|
||||
})
|
||||
$(`select#rack`).html(option);
|
||||
|
||||
if (callback) callback(); // ← add this
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_for_edit() {
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
return false;
|
||||
<?php } ?>
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_stock_out.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(<?php echo $_GET["wh"];?>).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
|
||||
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retrieve_warehouse();
|
||||
await retrieve_for_edit();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
$("select#warehouse").change(function() {
|
||||
retrieve_zone();
|
||||
});
|
||||
|
||||
$("select#zone").change(function() {
|
||||
retrieve_aisle();
|
||||
});
|
||||
|
||||
$("select#aisle").change(function() {
|
||||
retrieve_rack();
|
||||
});
|
||||
|
||||
<?php } ?>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,369 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../config.php';
|
||||
require '../include_header.php';
|
||||
|
||||
?>
|
||||
|
||||
<body>
|
||||
<?php require '../include_topbar.php';?>
|
||||
<?php require '../include_sidebar.php';?>
|
||||
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
<main id="content" class="content py-15">
|
||||
<div class="container-fluid">
|
||||
<div class="row ">
|
||||
<div class="col-12">
|
||||
<div class="mb-6">
|
||||
<h1 class="fs-3 mb-0">Stock Transfer</h1>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g">
|
||||
<div class="col-lg-8 col-12">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="fs-5 mb-4">Add Stock</h2>
|
||||
<form class="row gx-5">
|
||||
<!-- Product Name -->
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="product_sku" class="form-label">SKU</label>
|
||||
<input type="text" id="product_sku" class="form-control product_search"
|
||||
placeholder="Type product sku..." autocomplete="off" required>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="product_name" class="form-label">Name</label>
|
||||
<input type="text" id="product_name" class="form-control" autocomplete="off" disabled>
|
||||
</div>
|
||||
|
||||
<!-- SKU or Product Code -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="quantity" class="form-label">Quantity</label>
|
||||
<input type="number" class="form-control" id="quantity" placeholder="Enter quantity" required>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Warehouse -->
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="warehouse" class="form-label">From Warehouse</label>
|
||||
<select name="warehouse" id="warehouse_from" role="from" class="form-select" required></select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="zone" class="form-label">From Zone</label>
|
||||
<select name="zone" id="zone_from" role="from" class="form-select" required>
|
||||
<option value="">Please select zone</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="aisle" class="form-label">From Aisle</label>
|
||||
<select name="aisle" id="aisle_from" role="from" class="form-select" required>
|
||||
<option value="">Please select aisle</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="rack" class="form-label">From Rack</label>
|
||||
<select name="rack" id="rack_from" role="from" class="form-select" required>
|
||||
<option value="">Please select rack</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Warehouse -->
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="warehouse" class="form-label">To Warehouse</label>
|
||||
<select name="warehouse" id="warehouse_to" role="to" class="form-select" required></select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="zone" class="form-label">To Zone</label>
|
||||
<select name="zone" id="zone_to" role="to" class="form-select" required>
|
||||
<option value="">Please select zone</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="aisle" class="form-label">To Aisle</label>
|
||||
<select name="aisle" id="aisle_to" role="to" class="form-select" required>
|
||||
<option value="">Please select aisle</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 col-lg-3">
|
||||
<label for="rack" class="form-label">To Rack</label>
|
||||
<select name="rack" id="rack_to" role="to" class="form-select" required>
|
||||
<option value="">Please select rack</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Contact -->
|
||||
<div class="mb-3 col-lg-6">
|
||||
<label for="contact" class="form-label">Contact</label>
|
||||
<input type="text" class="form-control contact_search" id="contact" placeholder="Enter contact name">
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Notes / Description -->
|
||||
<div class="mb-3 col-lg-12">
|
||||
<label for="description" class="form-label">Notes / Description</label>
|
||||
<textarea class="form-control" id="description" rows="3" placeholder="Enter any notes"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Submit Button -->
|
||||
<div class="mb-3 col-lg-12">
|
||||
<button type="submit" class="btn btn-primary" onclick="manage_stock_transfer();">Add Stock</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php require "../include_ending.php";?>
|
||||
|
||||
<script>
|
||||
function manage_stock_transfer() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/manage_stock_transfer.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 1,
|
||||
debugMode: 0,
|
||||
data: {
|
||||
"contact_id": $("#contact").attr('data-id')
|
||||
},
|
||||
action: 'manage',
|
||||
onSuccess: function(res) {
|
||||
|
||||
window.location.href = "<?php echo $server_url?>ics/stock_transfer.php";
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_warehouse(type) {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/warehouse.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
data: {
|
||||
"type": type
|
||||
},
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select warehouse</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item.id}'>${item.warehouse_name}</option>`;
|
||||
})
|
||||
$(`select[name='warehouse'][role='${type}']`).html(option);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_zone(type, callback) {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_zone.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
data: {
|
||||
"type": type
|
||||
},
|
||||
noLoading: true,
|
||||
debugMode: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select zone</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item.zone}'>${item.zone}</option>`;
|
||||
})
|
||||
$(`select[name='zone'][role='${type}']`).html(option);
|
||||
|
||||
if (callback) callback(); // ← add this
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_aisle(type, callback) {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_aisle.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
data: {
|
||||
"type": type
|
||||
},
|
||||
noLoading: true,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select aisle</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item}'>${item}</option>`;
|
||||
})
|
||||
$(`select[name='aisle'][role='${type}']`).html(option);
|
||||
|
||||
if (callback) callback(); // ← add this
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_rack(type, callback) {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_rack.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
data: {
|
||||
"type": type
|
||||
},
|
||||
noLoading: true,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = `<option value="">Please select rack</option>`;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item}'>${item}</option>`;
|
||||
})
|
||||
$(`select[name='rack'][role='${type}']`).html(option);
|
||||
|
||||
if (callback) callback(); // ← add this
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_for_edit() {
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
return false;
|
||||
<?php } ?>
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/retrieve_stock_transfer.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
debugMode: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
|
||||
var type = 'from';
|
||||
var warehouse = res.output.ref.ref_warehouse;
|
||||
var data = res.output;
|
||||
|
||||
/**
|
||||
* From warehouse
|
||||
*/
|
||||
$(`select[name='warehouse'][role=${type}]`).val(warehouse).attr('disabled', true);
|
||||
|
||||
retrieve_zone(type, function() {
|
||||
$(`select[name='zone'][role=${type}]`).val(data.zone).attr('disabled', true);
|
||||
|
||||
retrieve_aisle(type, function() {
|
||||
$(`select[name='aisle'][role=${type}]`).val(data.aisle).attr('disabled', true);
|
||||
|
||||
retrieve_rack(type, function() {
|
||||
$(`select[name='rack'][role=${type}]`).val(data.rack).attr('disabled', true);
|
||||
|
||||
type = 'to';
|
||||
warehouse = res.output.ref_warehouse;
|
||||
data = res.output.ref;
|
||||
|
||||
/**
|
||||
* To warehouse
|
||||
*/
|
||||
$(`select[name='warehouse'][role=${type}]`).val(warehouse).attr('disabled', true);
|
||||
|
||||
retrieve_zone(type, function() {
|
||||
$(`select[name='zone'][role=${type}]`).val(data.zone).attr('disabled', true);
|
||||
|
||||
retrieve_aisle(type, function() {
|
||||
$(`select[name='aisle'][role=${type}]`).val(data.aisle).attr('disabled',true);
|
||||
|
||||
retrieve_rack(type, function() {
|
||||
$(`select[name='rack'][role=${type}]`).val(data.rack).attr('disabled',true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var data = res.output;
|
||||
|
||||
// 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();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retrieve_warehouse("from");
|
||||
await retrieve_warehouse("to");
|
||||
await retrieve_for_edit();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
$("select[name='warehouse']").change(function() {
|
||||
retrieve_zone($(this).attr('role'));
|
||||
});
|
||||
|
||||
$("select[name='zone']").change(function() {
|
||||
retrieve_aisle($(this).attr('role'));
|
||||
});
|
||||
|
||||
$("select[name='aisle']").change(function() {
|
||||
retrieve_rack($(this).attr('role'));
|
||||
});
|
||||
|
||||
<?php } ?>
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+110
-4
@@ -18,7 +18,7 @@
|
||||
<div class="mb-6 d-flex justify-content-between align-items-center">
|
||||
<h1 class="fs-3 mb-0">Stock in
|
||||
</h1>
|
||||
<a href="<?php echo $server_url?>ics/add_stock_in.php" class="btn btn-primary">
|
||||
<a href="<?php echo $server_url?>ics/manage_stock_in.php" class="btn btn-primary">
|
||||
<span><i class="ti ti-plus"></i></span>
|
||||
<span>ADD Stock In</span></a>
|
||||
|
||||
@@ -27,18 +27,31 @@
|
||||
</div>
|
||||
|
||||
<div class="row g-5">
|
||||
|
||||
<div class="mb-3 col-lg-2">
|
||||
<input class="form-control" value='Warehouse' disabled>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-4">
|
||||
<select name="warehouse" id="warehouse" class="form-select" required></select>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-6">
|
||||
<button class='btn btn-secondary' onclick='retrieve_stock_in()'>Search</button>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="mb-4 fs-5">Item List</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0 table-centered" id="product">
|
||||
<table class="table table-hover mb-0 table-centered" id="stock_in">
|
||||
<thead class="table-primary border-light">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Product</th>
|
||||
<th>Quantity</th>
|
||||
<th>Warehouse</th>
|
||||
<th>Storage Location</th>
|
||||
<th>Zone</th>
|
||||
<th>Aisle</th>
|
||||
<th>Rack</th>
|
||||
<th>Status</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
@@ -63,7 +76,100 @@
|
||||
<?php require "../include_ending.php";?>
|
||||
|
||||
<script>
|
||||
function retrieve_stock_in() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/stock_in.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
debugMode: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
|
||||
// Register the array as a table name
|
||||
alasql('CREATE TABLE IF NOT EXISTS stock_in');
|
||||
alasql.tables.stock_in.data = res.output || [];
|
||||
|
||||
var total_records = alasql.tables.stock_in.data.length;
|
||||
|
||||
var table_id = 'stock_in';
|
||||
|
||||
var page = generate_pagination(table_id, total_records);
|
||||
$(`table#${table_id} tfoot`).html(page);
|
||||
|
||||
// dynamic function name
|
||||
if (typeof window[`change_page_${table_id}`] === "function") {
|
||||
window[`change_page_${table_id}`](1);
|
||||
} else {
|
||||
console.error(`Function change_page_${table_id} does not exist.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function change_page_stock_in(page_num) {
|
||||
|
||||
var offset = (page_num - 1) * prop_limit;
|
||||
|
||||
var page_data = alasql(`SELECT * FROM stock_in LIMIT ${prop_limit} OFFSET ${offset}`);
|
||||
|
||||
var body = ``;
|
||||
|
||||
var warehouse = $(`select#warehouse`).val();
|
||||
|
||||
$.each(page_data, function(key, item) {
|
||||
body += `<tr>
|
||||
<td class="py-3">${format_date(item["date"])}</td>
|
||||
<td class="py-3">${item["product_sku"]}: ${item['product_name']}</td>
|
||||
<td class="py-3">${item['quantity']}</td>
|
||||
<td class="py-3">${item['zone']}</td>
|
||||
<td class="py-3">${item['aisle']}</td>
|
||||
<td class="py-3">${item['rack']}</td>
|
||||
<td class="py-3">
|
||||
${(item['status'])?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
<a href="<?php echo $server_url?>ics/manage_stock_in.php?id=${item['id']}&wh=${warehouse}" class=""><i class="ti ti-eye fs-5"></i></a>
|
||||
<a href="#" class="link-danger"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
||||
</td>
|
||||
</tr>`;
|
||||
})
|
||||
|
||||
$("table#stock_in > tbody").html(body);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_warehouse() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/warehouse.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = ``;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item.id}'>${item.warehouse_name}</option>`;
|
||||
})
|
||||
$(`select#warehouse`).html(option);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retrieve_warehouse();
|
||||
await retrieve_stock_in();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../config.php';
|
||||
require '../include_header.php';
|
||||
|
||||
?>
|
||||
|
||||
<body>
|
||||
<?php require '../include_topbar.php';?>
|
||||
<?php require '../include_sidebar.php';?>
|
||||
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
<main id="content" class="content py-15">
|
||||
<div class="container-fluid">
|
||||
<div class="row ">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 d-flex justify-content-between align-items-center">
|
||||
<h1 class="fs-3 mb-0">Stock Out
|
||||
</h1>
|
||||
<a href="<?php echo $server_url?>ics/manage_stock_out.php" class="btn btn-primary">
|
||||
<span><i class="ti ti-plus"></i></span>
|
||||
<span>ADD Stock Out</span></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-5">
|
||||
|
||||
<div class="mb-3 col-lg-2">
|
||||
<input class="form-control" value='Warehouse' disabled>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-4">
|
||||
<select name="warehouse" id="warehouse" class="form-select" required></select>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-6">
|
||||
<button class='btn btn-secondary' onclick='retrieve_stock_out()'>Search</button>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="mb-4 fs-5">Item List</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0 table-centered" id="stock_out">
|
||||
<thead class="table-primary border-light">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Product</th>
|
||||
<th>Quantity</th>
|
||||
<th>Zone</th>
|
||||
<th>Aisle</th>
|
||||
<th>Rack</th>
|
||||
<th>Status</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tfoot class="">
|
||||
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php require "../include_ending.php";?>
|
||||
|
||||
<script>
|
||||
function retrieve_stock_out() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/stock_out.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
debugMode: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
|
||||
// Register the array as a table name
|
||||
alasql('CREATE TABLE IF NOT EXISTS stock_out');
|
||||
alasql.tables.stock_out.data = res.output || [];
|
||||
|
||||
var total_records = alasql.tables.stock_out.data.length;
|
||||
|
||||
var table_id = 'stock_out';
|
||||
|
||||
var page = generate_pagination(table_id, total_records);
|
||||
$(`table#${table_id} tfoot`).html(page);
|
||||
|
||||
// dynamic function name
|
||||
if (typeof window[`change_page_${table_id}`] === "function") {
|
||||
window[`change_page_${table_id}`](1);
|
||||
} else {
|
||||
console.error(`Function change_page_${table_id} does not exist.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function change_page_stock_out(page_num) {
|
||||
|
||||
var offset = (page_num - 1) * prop_limit;
|
||||
|
||||
var page_data = alasql(`SELECT * FROM stock_out LIMIT ${prop_limit} OFFSET ${offset}`);
|
||||
|
||||
var body = ``;
|
||||
|
||||
var warehouse = $(`select#warehouse`).val();
|
||||
|
||||
$.each(page_data, function(key, item) {
|
||||
body += `<tr>
|
||||
<td class="py-3">${format_date(item["date"])}</td>
|
||||
<td class="py-3">${item["product_sku"]}: ${item['product_name']}</td>
|
||||
<td class="py-3">${item['quantity']}</td>
|
||||
<td class="py-3">${item['zone']}</td>
|
||||
<td class="py-3">${item['aisle']}</td>
|
||||
<td class="py-3">${item['rack']}</td>
|
||||
<td class="py-3">
|
||||
${(item['status'])?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
<a href="<?php echo $server_url?>ics/manage_stock_out.php?id=${item['id']}&wh=${warehouse}" class=""><i class="ti ti-eye fs-5"></i></a>
|
||||
<a href="#" class="link-danger"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
||||
</td>
|
||||
</tr>`;
|
||||
})
|
||||
|
||||
$("table#stock_out > tbody").html(body);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_warehouse() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/warehouse.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = ``;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item.id}'>${item.warehouse_name}</option>`;
|
||||
})
|
||||
$(`select#warehouse`).html(option);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retrieve_warehouse();
|
||||
await retrieve_stock_out();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+52
-18
@@ -23,23 +23,26 @@
|
||||
</div>
|
||||
<div class="row g-5 mb-5">
|
||||
<div class="col-xl-3 col-md-6 col-12">
|
||||
<div class="card ">
|
||||
<div class="card" id="capacity">
|
||||
<div class="card-body p-5">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<span class="mb-4 d-block">Total Sales</span>
|
||||
<h3 class="fw-bold mb-0">1,234</h3>
|
||||
<span class="mb-4 d-block">Total Capacity</span>
|
||||
<h3 class="fw-bold mb-0 text-info">0</h3>
|
||||
<p class="mb-0 small text-secondary">Across all warehouses</p>
|
||||
</div>
|
||||
<div class="">
|
||||
<i class="ti ti-box-seam fs-3 text-muted"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- overlay -->
|
||||
<div class="card-loader-overlay">
|
||||
<div class="spinner-border spinner-border-sm text-primary"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-xl-3 col-md-6 col-12">
|
||||
<div class="card ">
|
||||
<div class="card-body p-5">
|
||||
@@ -53,6 +56,10 @@
|
||||
<i class="ti ti-trending-up fs-3 text-success"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- overlay -->
|
||||
<div class="card-loader-overlay">
|
||||
<div class="spinner-border spinner-border-sm text-primary"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -71,6 +78,10 @@
|
||||
<i class="ti ti-trending-down fs-3 text-danger"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- overlay -->
|
||||
<div class="card-loader-overlay">
|
||||
<div class="spinner-border spinner-border-sm text-primary"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -89,6 +100,10 @@
|
||||
<i class="ti ti-alert-triangle fs-3 text-warning"></i>
|
||||
</div>
|
||||
</div>
|
||||
<!-- overlay -->
|
||||
<div class="card-loader-overlay">
|
||||
<div class="spinner-border spinner-border-sm text-primary"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -116,6 +131,10 @@
|
||||
<div>
|
||||
<div id="stockMovementChart"></div>
|
||||
</div>
|
||||
<!-- overlay -->
|
||||
<div class="card-loader-overlay">
|
||||
<div class="spinner-border spinner-border-sm text-primary"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,6 +153,10 @@
|
||||
<div>
|
||||
<div id="stockLevelTrendChart"></div>
|
||||
</div>
|
||||
<!-- overlay -->
|
||||
<div class="card-loader-overlay">
|
||||
<div class="spinner-border spinner-border-sm text-primary"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -232,19 +255,6 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<footer class="text-center py-2 mt-6 text-secondary ">
|
||||
<p class="mb-0">Copyright © 2026 InApp Inventory Dashboard. Developed by <a href="https://codescandy.com/"
|
||||
target="_blank" class="text-primary">CodesCandy</a> </p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="position-fixed end-0 bottom-0 m-4">
|
||||
<a href="https://codescandy.com/template/inventory-admin-dashboard-template/" class="btn btn-dark"
|
||||
target="_blank"> Download Now</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
@@ -252,7 +262,31 @@
|
||||
<?php require "../include_ending.php";?>
|
||||
|
||||
<script>
|
||||
function retrieve_warehouse_stats() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/warehouse_stats.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
|
||||
console.log(res);
|
||||
|
||||
$("#capacity h3").text(format_number(res.output.total_capacity,2));
|
||||
$("#capacity p").text("Accross "+ format_number(res.output.total_warehouse) + " warehouses");
|
||||
$("#capacity .card-loader-overlay").hide();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$(function() {
|
||||
|
||||
retrieve_warehouse_stats();
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../config.php';
|
||||
require '../include_header.php';
|
||||
|
||||
?>
|
||||
|
||||
<body>
|
||||
<?php require '../include_topbar.php';?>
|
||||
<?php require '../include_sidebar.php';?>
|
||||
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
<main id="content" class="content py-15">
|
||||
<div class="container-fluid">
|
||||
<div class="row ">
|
||||
<div class="col-12">
|
||||
<div class="mb-6 d-flex justify-content-between align-items-center">
|
||||
<h1 class="fs-3 mb-0">Stock Transfer
|
||||
</h1>
|
||||
<a href="<?php echo $server_url?>ics/manage_stock_transfer.php" class="btn btn-primary">
|
||||
<span><i class="ti ti-plus"></i></span>
|
||||
<span>ADD Stock Transfer</span></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-5">
|
||||
|
||||
<div class="mb-3 col-lg-2">
|
||||
<input class="form-control" value='Warehouse From' disabled>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-4">
|
||||
<select name="warehouse" id="warehouse" class="form-select" required></select>
|
||||
</div>
|
||||
<div class="mb-3 col-lg-4">
|
||||
<button class='btn btn-secondary' onclick='retrieve_stock_transfer()'>Search</button>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body p-5">
|
||||
<h2 class="mb-4 fs-5">Item List</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover mb-0 table-centered" id="stock_transfer">
|
||||
<thead class="table-primary border-light">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Product</th>
|
||||
<th>Quantity</th>
|
||||
<th>Zone</th>
|
||||
<th>Aisle</th>
|
||||
<th>Rack</th>
|
||||
<th>Status</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tfoot class="">
|
||||
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php require "../include_ending.php";?>
|
||||
|
||||
<script>
|
||||
function retrieve_stock_transfer() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>ics/api/engine/stock_transfer.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
debugMode: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
|
||||
// Register the array as a table name
|
||||
alasql('CREATE TABLE IF NOT EXISTS stock_transfer');
|
||||
alasql.tables.stock_transfer.data = res.output || [];
|
||||
|
||||
var total_records = alasql.tables.stock_transfer.data.length;
|
||||
|
||||
var table_id = 'stock_transfer';
|
||||
|
||||
var page = generate_pagination(table_id, total_records);
|
||||
$(`table#${table_id} tfoot`).html(page);
|
||||
|
||||
// dynamic function name
|
||||
if (typeof window[`change_page_${table_id}`] === "function") {
|
||||
window[`change_page_${table_id}`](1);
|
||||
} else {
|
||||
console.error(`Function change_page_${table_id} does not exist.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function change_page_stock_transfer(page_num) {
|
||||
|
||||
var offset = (page_num - 1) * prop_limit;
|
||||
|
||||
var page_data = alasql(`SELECT * FROM stock_transfer LIMIT ${prop_limit} OFFSET ${offset}`);
|
||||
|
||||
var body = ``;
|
||||
|
||||
var warehouse = $(`select#warehouse`).val();
|
||||
|
||||
$.each(page_data, function(key, item) {
|
||||
body += `<tr>
|
||||
<td class="py-3">${format_date(item["date"])}</td>
|
||||
<td class="py-3">${item["product_sku"]}: ${item['product_name']}</td>
|
||||
<td class="py-3">${item['quantity']}</td>
|
||||
<td class="py-3">${item['zone']}</td>
|
||||
<td class="py-3">${item['aisle']}</td>
|
||||
<td class="py-3">${item['rack']}</td>
|
||||
<td class="py-3">
|
||||
${(item['status'])?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
||||
</td>
|
||||
<td class="py-3">
|
||||
<a href="<?php echo $server_url?>ics/manage_stock_transfer.php?id=${item['id']}&wh=${warehouse}" class=""><i class="ti ti-eye fs-5"></i></a>
|
||||
<a href="#" class="link-danger"><i class="ti ti-trash ms-2 fs-5"></i></a>
|
||||
</td>
|
||||
</tr>`;
|
||||
})
|
||||
|
||||
$("table#stock_transfer > tbody").html(body);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function retrieve_warehouse() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/warehouse.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var option = ``;
|
||||
$.each(res.output, function(key, item) {
|
||||
option += `<option value='${item.id}'>${item.warehouse_name}</option>`;
|
||||
})
|
||||
$(`select#warehouse`).html(option);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retrieve_warehouse();
|
||||
await retrieve_stock_transfer();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -46,8 +46,8 @@
|
||||
|
||||
<!-- theme script -->
|
||||
<link rel="stylesheet" href="<?php echo $server_url?>assets/css/main.css">
|
||||
<link rel="stylesheet" href="<?php echo $server_url?>assets/css/custom.css">
|
||||
<script type="module" src="<?php echo $server_url?>assets/js/main.js"></script>
|
||||
<link rel="stylesheet" href="<?php echo $server_url?>assets/css/custom.css">
|
||||
<script src="<?php echo $server_url?>assets/js/custom.js"></script>
|
||||
|
||||
</head>
|
||||
@@ -0,0 +1,59 @@
|
||||
<!-- SIDEBAR -->
|
||||
<aside id="sidebar" class="sidebar overflow-y-auto">
|
||||
<div class="logo-area">
|
||||
<a href="<?php echo $server_url?>index.php" class="d-inline-flex">
|
||||
<img
|
||||
src="data:image/svg+xml,%3csvg%20width='62'%20height='67'%20viewBox='0%200%2062%2067'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M30.604%2066.378L0.00805664%2048.1582V35.7825L30.604%2054.0023V66.378Z'%20fill='%23302C4D'/%3e%3cpath%20d='M61.1996%2048.1582L30.604%2066.378V54.0023L61.1996%2035.7825V48.1582Z'%20fill='%23E66239'/%3e%3cpath%20d='M30.5955%200L0%2018.2198V30.5955L30.5955%2012.3757V0Z'%20fill='%23657E92'/%3e%3cpath%20d='M61.191%2018.2198L30.5955%200V12.3757L61.191%2030.5955V18.2198Z'%20fill='%23A3B2BE'/%3e%3cpath%20d='M30.604%2048.8457L0.00805664%2030.6259V18.2498L30.604%2036.47V48.8457Z'%20fill='%23302C4D'/%3e%3cpath%20d='M61.1996%2030.6259L30.604%2048.8457V36.47L61.1996%2018.2498V30.6259Z'%20fill='%23E66239'/%3e%3c/svg%3e"
|
||||
alt=""
|
||||
width="24"
|
||||
/>
|
||||
<span class="logo-text ms-2">
|
||||
<img src="./assets/images/logo.svg" alt="" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<ul class="nav flex-column">
|
||||
|
||||
<!-- Main -->
|
||||
<li class="nav-text-space">
|
||||
<small class="nav-text text-muted">Setting</small>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a class="nav-link active" href="index.html">
|
||||
<i class="ti ti-home"></i>
|
||||
<span class="nav-text">Dashboard</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a class="nav-link" href="inventory.html">
|
||||
<i class="ti ti-box-seam"></i>
|
||||
<span class="nav-text">Inventory</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a class="nav-link" href="low-stock-products.html">
|
||||
<i class="ti ti-alert-triangle"></i>
|
||||
<span class="nav-text">Low Stock Products</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a class="nav-link" href="stock-expired.html">
|
||||
<i class="ti ti-clock"></i>
|
||||
<span class="nav-text">Expired Stock</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a class="nav-link" href="reports.html">
|
||||
<i class="ti ti-receipt"></i>
|
||||
<span class="nav-text">Reports</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</aside>
|
||||
@@ -100,14 +100,14 @@
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a class="nav-link" href="stock-out.html">
|
||||
<a class="nav-link" href="<?php echo $server_url?>ics/stock_out.php">
|
||||
<i class="ti ti-package-export"></i>
|
||||
<span class="nav-text">Stock Out</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a class="nav-link" href="stock-out.html">
|
||||
<a class="nav-link" href="<?php echo $server_url?>ics/stock_transfer.php">
|
||||
<i class="ti ti-package"></i>
|
||||
<span class="nav-text">Stock Transfer</span>
|
||||
</a>
|
||||
|
||||
@@ -5,6 +5,8 @@ if(!isset($_SESSION["otp"])){
|
||||
header('Location: '.$server_url.'login/index.php');
|
||||
}
|
||||
|
||||
require 'preset.php';
|
||||
|
||||
?>
|
||||
|
||||
<div id="overlay" class="overlay"></div>
|
||||
@@ -109,6 +111,11 @@ if(!isset($_SESSION["otp"])){
|
||||
<span>Switch Branch</span>
|
||||
</a>
|
||||
|
||||
<a href="javascript:;" class="" onclick="profile_setting();">
|
||||
|
||||
<span> Setting</span>
|
||||
</a>
|
||||
|
||||
<a href="javascript:;" class="" onclick="log_out();">
|
||||
|
||||
<span> Log Out</span>
|
||||
@@ -145,4 +152,11 @@ function log_out() {
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function profile_setting(){
|
||||
|
||||
window.location.href = "<?php echo $server_url?>setting/profile.php";
|
||||
|
||||
}
|
||||
</script>
|
||||
@@ -1,27 +1,21 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) {
|
||||
|
||||
$id = (int)$data['id'];
|
||||
|
||||
// get existing log
|
||||
$sql = "SELECT `log`
|
||||
FROM md_product_category
|
||||
WHERE
|
||||
company_id = :company_id and
|
||||
id = :id";
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$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
|
||||
]);
|
||||
db_check($sth, $answer);
|
||||
|
||||
$row = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$table_log = json_decode($row['log'] ?? '[]', true);
|
||||
|
||||
$table_log = json_decode($sth->fetchColumn() ?: '[]', true);
|
||||
$table_log[] = $logging;
|
||||
|
||||
if ($id > 0) {
|
||||
@@ -34,7 +28,7 @@
|
||||
`log` = :log
|
||||
WHERE id = :id AND company_id = :company_id";
|
||||
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([
|
||||
":id" => $id,
|
||||
":company_id" => $company_id,
|
||||
@@ -52,7 +46,7 @@
|
||||
VALUES
|
||||
(:company_id, :category, :slug, :description, :status, :log)";
|
||||
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute([
|
||||
":company_id" => $company_id,
|
||||
":category" => $data["category"],
|
||||
@@ -63,7 +57,18 @@
|
||||
]);
|
||||
}
|
||||
|
||||
$answer["success"] = 1;
|
||||
exit(json_encode($answer));
|
||||
});
|
||||
|
||||
$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));
|
||||
?>
|
||||
@@ -3,25 +3,22 @@
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) {
|
||||
|
||||
$id = (int)$data['id'];
|
||||
|
||||
// get existing log
|
||||
$sql = "SELECT `log`
|
||||
FROM md_product
|
||||
WHERE
|
||||
company_id = :company_id and
|
||||
id = :id ";
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$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
|
||||
]);
|
||||
db_check($sth, $answer);
|
||||
|
||||
$row = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$table_log = json_decode($row['log'] ?? '[]', true);
|
||||
|
||||
$table_log = json_decode($sth->fetchColumn() ?: '[]', true);
|
||||
$table_log[] = $logging;
|
||||
|
||||
if ($id > 0) {
|
||||
@@ -30,6 +27,7 @@
|
||||
product_name = :product_name,
|
||||
sku = :sku,
|
||||
price = :price,
|
||||
min_stock = :min_stock,
|
||||
category = :category,
|
||||
product_image = :product_image,
|
||||
`description` = :description,
|
||||
@@ -37,13 +35,14 @@
|
||||
`log` = :log
|
||||
WHERE id = :id AND company_id = :company_id";
|
||||
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$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"],
|
||||
@@ -54,16 +53,17 @@
|
||||
} else {
|
||||
|
||||
$sql = "INSERT INTO md_product
|
||||
(company_id, product_name, sku, price, category, product_image, `description`, `status`, `log`)
|
||||
(company_id, product_name, sku, price, min_stock, category, product_image, `description`, `status`, `log`)
|
||||
VALUES
|
||||
(:company_id, :product_name, :sku, :price, :category, :product_image, :description, :status, :log)";
|
||||
(:company_id, :product_name, :sku, :price, :min_stock, :category, :product_image, :description, :status, :log)";
|
||||
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$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"],
|
||||
@@ -72,8 +72,18 @@
|
||||
]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$answer["success"] = 1;
|
||||
exit(json_encode($answer));
|
||||
|
||||
} 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));
|
||||
?>
|
||||
@@ -1,31 +1,37 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) {
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
// get existing log
|
||||
$sql = "SELECT `log`
|
||||
FROM md_storage
|
||||
WHERE company_id = :company_id
|
||||
AND id = :id";
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$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,
|
||||
":company_id" => $company_id,
|
||||
":id" => $id
|
||||
]);
|
||||
|
||||
db_check($sth, $answer);
|
||||
|
||||
$row = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$table_log = json_decode($row['log'] ?? '[]', true);
|
||||
$table_log = json_decode($sth->fetchColumn() ?: '[]', true);
|
||||
if (!is_array($table_log)) $table_log = [];
|
||||
|
||||
// add new log entry (assumes $logging already prepared)
|
||||
$table_log[] = $logging;
|
||||
|
||||
$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),
|
||||
];
|
||||
|
||||
if ($id > 0) {
|
||||
|
||||
$sql = "UPDATE md_storage SET
|
||||
@@ -38,27 +44,9 @@ if ($id > 0) {
|
||||
description = :description,
|
||||
status = :status,
|
||||
`log` = :log
|
||||
WHERE id = :id
|
||||
AND company_id = :company_id";
|
||||
WHERE id = :id AND company_id = :company_id";
|
||||
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$sth->execute([
|
||||
":id" => $id,
|
||||
":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),
|
||||
]);
|
||||
$params[":id"] = $id;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -66,28 +54,23 @@ if ($id > 0) {
|
||||
(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);
|
||||
$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";
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
?>
|
||||
@@ -1,49 +1,25 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($data, $company_id, $logging) {
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
$pdo2->beginTransaction();
|
||||
|
||||
// get existing log
|
||||
$sql = "SELECT `log`
|
||||
FROM md_warehouse
|
||||
WHERE company_id = :company_id
|
||||
AND id = :id";
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$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,
|
||||
":company_id" => $company_id,
|
||||
":id" => $id
|
||||
]);
|
||||
|
||||
db_check($sth, $answer);
|
||||
|
||||
$row = $sth->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$table_log = json_decode($row['log'] ?? '[]', true);
|
||||
$table_log = json_decode($sth->fetchColumn() ?: '[]', true);
|
||||
if (!is_array($table_log)) $table_log = [];
|
||||
|
||||
// add new log entry (assumes $logging already prepared)
|
||||
$table_log[] = $logging;
|
||||
|
||||
if ($id > 0) {
|
||||
|
||||
$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";
|
||||
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$sth->execute([
|
||||
":id" => $id,
|
||||
$params = [
|
||||
":company_id" => $company_id,
|
||||
":warehouse_name" => $data["warehouse_name"] ?? "",
|
||||
":location" => $data["location"] ?? "",
|
||||
@@ -52,8 +28,21 @@ if ($id > 0) {
|
||||
":description" => $data["description"] ?? "",
|
||||
":status" => (int)($data["status"] ?? 1),
|
||||
":log" => json_encode($table_log, JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
db_check($sth, $answer);
|
||||
];
|
||||
|
||||
if ($id > 0) {
|
||||
|
||||
$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";
|
||||
|
||||
$params[":id"] = $id;
|
||||
|
||||
} else {
|
||||
|
||||
@@ -61,38 +50,30 @@ if ($id > 0) {
|
||||
(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);
|
||||
$sth = $pdo->prepare($sql);
|
||||
$sth->execute($params);
|
||||
|
||||
|
||||
|
||||
if(!empty($data["warehouse_name"])){
|
||||
/**
|
||||
* Create warehouse table
|
||||
*/
|
||||
// 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`";
|
||||
$sth = $pdo2->prepare($sql);
|
||||
$sth->execute();
|
||||
db_check($sth, $answer);
|
||||
$pdo->exec($sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$pdo2->commit();
|
||||
});
|
||||
|
||||
$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));
|
||||
?>
|
||||
@@ -87,7 +87,7 @@
|
||||
}
|
||||
|
||||
|
||||
function retreive_for_edit() {
|
||||
function retrieve_for_edit() {
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
return false;
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retreive_for_edit();
|
||||
await retrieve_for_edit();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@
|
||||
<label for="price" class="form-label">Price</label>
|
||||
<input type="number" class="form-control" id="price" placeholder="0.00" step="0.01" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="min_stock" class="form-label">min_stock</label>
|
||||
<input type="number" class="form-control" id="min_stock" placeholder="0" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
@@ -115,7 +119,7 @@
|
||||
}
|
||||
|
||||
|
||||
function retreive_for_edit() {
|
||||
function retrieve_for_edit() {
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
}
|
||||
|
||||
|
||||
function retreive_for_edit() {
|
||||
function retrieve_for_edit() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/retrieve_storage.php",
|
||||
@@ -148,7 +148,7 @@
|
||||
try {
|
||||
await retrieve_warehouse();
|
||||
<?php if(!empty($_GET["id"])){ ?>
|
||||
await retreive_for_edit();
|
||||
await retrieve_for_edit();
|
||||
<?php } ?>
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
}
|
||||
|
||||
|
||||
function retreive_for_edit() {
|
||||
function retrieve_for_edit() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/retrieve_warehouse.php",
|
||||
@@ -141,7 +141,7 @@
|
||||
try {
|
||||
await retrieve_manager();
|
||||
<?php if(!empty($_GET["id"])){ ?>
|
||||
await retreive_for_edit();
|
||||
await retrieve_for_edit();
|
||||
<?php } ?>
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
@@ -344,7 +344,7 @@
|
||||
<td class="py-3">${item['product_name']}</td>
|
||||
<td class="py-3">${item['sku']}</td>
|
||||
<td class="py-3">${item['description']}</td>
|
||||
<td class="py-3">${item['status']}</td>
|
||||
<td class="py-3" style='text-align: right;'>${format_number(item['min_stock'],2)}</td>
|
||||
<td class="py-3">
|
||||
${(item['status'])?'<span class="badge bg-success">Active</span>':'<span class="badge bg-secondary">Inactive</span>'}
|
||||
</td>
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
<td class="py-3">${item['warehouse_name']}</td>
|
||||
<td class="py-3">${item['location']}</td>
|
||||
<td class="py-3">${item['manager']}</td>
|
||||
<td class="py-3">${item['capacity']}</td>
|
||||
<td class="py-3" style='text-align: right;'>${format_number(item['capacity'],2)}</td>
|
||||
<td class="py-3">${item['product']}</td>
|
||||
<td class="py-3">
|
||||
<span class="badge bg-${item['bg_class']}">${item.status}</span>
|
||||
|
||||
+3
-5
@@ -3,11 +3,9 @@
|
||||
//<><><><><><><><> MAIN TRCLOUD <><><><><><><><>//
|
||||
if(true){
|
||||
$expire = "2027-01-01";
|
||||
|
||||
|
||||
|
||||
}
|
||||
// configuration
|
||||
|
||||
// global variables
|
||||
$prop['limit'] = 50;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../config.php';
|
||||
require '../include_header.php';
|
||||
|
||||
?>
|
||||
|
||||
<body>
|
||||
<?php require '../include_topbar.php';?>
|
||||
<?php require '../include_setting_sidebar.php';?>
|
||||
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
<main id="content" class="content py-15">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-5 gap-3">
|
||||
<div class="">
|
||||
<h1 class="fs-3 mb-1">Manage Profile</h1>
|
||||
<p class="mb-0">Update profile detail</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" id="userForm">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-body p-6">
|
||||
|
||||
<!-- Row 1: username / email -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" id="username" placeholder="Enter username" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="email" class="form-label">Email</label>
|
||||
<input type="email" class="form-control" id="email" placeholder="Enter email" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 2: password / phone -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" id="password" placeholder="Enter password" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="phone" class="form-label">Phone</label>
|
||||
<input type="text" class="form-control" id="phone" placeholder="Enter phone number">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 3: name / surname -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="name" class="form-label">Name</label>
|
||||
<input type="text" class="form-control" id="name" placeholder="Enter first name" required>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="surname" class="form-label">Surname</label>
|
||||
<input type="text" class="form-control" id="surname" placeholder="Enter last name" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Row 4: country / language -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="country" class="form-label">Country</label>
|
||||
<input type="text" class="form-control" id="country" placeholder="Enter country">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="language" class="form-label">Language</label>
|
||||
<select class="form-select" id="language">
|
||||
<option value="th" selected>Thai (th)</option>
|
||||
<option value="en">English (en)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- default_company / profile_picture -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="default_company" class="form-label">Default Company ID</label>
|
||||
<input type="number" class="form-control" id="default_company" placeholder="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- address -->
|
||||
<div class="mb-3">
|
||||
<label for="address" class="form-label">Address</label>
|
||||
<input type="text" class="form-control" id="address" placeholder="Enter address">
|
||||
</div>
|
||||
|
||||
<!-- facebook / line_code -->
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="facebook" class="form-label">Facebook</label>
|
||||
<input type="text" class="form-control" id="facebook" placeholder="Enter Facebook profile">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="line_code" class="form-label">Line Code</label>
|
||||
<input type="text" class="form-control" id="line_code" placeholder="Enter Line ID">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- signature -->
|
||||
<div class="mb-3">
|
||||
<label for="signature" class="form-label">Signature</label>
|
||||
<input type="text" class="form-control" id="signature" placeholder="Enter signature">
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary" onclick="manage_user();">Create</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php require "../include_ending.php";?>
|
||||
|
||||
<script>
|
||||
function manage_category() {
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/manage_category.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 1,
|
||||
debugMode: 0,
|
||||
action: 'manage',
|
||||
onSuccess: function(res) {
|
||||
|
||||
window.location.href = "<?php echo $server_url?>inventory/product.php";
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function retrieve_for_edit() {
|
||||
|
||||
<?php if(empty($_GET["id"])){ ?>
|
||||
return false;
|
||||
<?php } ?>
|
||||
|
||||
return ajax_request({
|
||||
url: "<?php echo $server_url?>inventory/api/engine/retrieve_category.php",
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
|
||||
$.each(res.output, function(key, item) {
|
||||
$(`#${key}`).val(item);
|
||||
});
|
||||
|
||||
$(`button[type=submit]`).text('Update');
|
||||
|
||||
$(`button[type=reset]`).hide();
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
$(async function() {
|
||||
try {
|
||||
await retrieve_for_edit();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user