diff --git a/.DS_Store b/.DS_Store index 9d4c452..0b0a16d 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/account_manage.php b/account_manage.php index a2c3161..eb225fa 100644 --- a/account_manage.php +++ b/account_manage.php @@ -272,7 +272,7 @@ $view .= '
//Dropdown $partner_data = json_decode($_SESSION['authorization']['partnerhierarchy']); -$soldto_dropdown = listPartner('soldto',$accounthierarchy->soldto,'',$_SESSION['authorization']['permission']); +$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],$accounthierarchy->soldto,''); $view .= '
'.$tab3.' diff --git a/api/v2/get/catalog.php b/api/v2/get/catalog.php index 56d1126..97a1b6d 100644 --- a/api/v2/get/catalog.php +++ b/api/v2/get/catalog.php @@ -1,6 +1,10 @@ $item['version'], 'config_setting' => $item['config'], - 'main_option_for_display' => $item['measurement'], + 'main_option_for_display' => $item['measurement'] ?? '', 'configurations' => [] ]; } @@ -170,6 +174,64 @@ removeKeysRecursive($catalog,$keys_to_remove); //------------------------------------------ $messages = processProductCollection($catalog); +//------------------------------------------ +//check for METAfeed request +//------------------------------------------ +if (isset($criterias['meta'])){ + //------------------------------------------ + // Meta Feed Configuration + //------------------------------------------ + $meta_config = [ + 'base_url' => 'https://www.morvalwatches.com', // Product page URL + 'image_base_url' => 'https://cloud.soveliti.nl', + 'brand' => 'Morval Watches', + 'currency' => 'EUR', + 'condition' => 'new', + 'availability' => 'in stock', + 'google_product_category' => 'Apparel & Accessories > Jewelry > Watches', + 'output_format' => 'json' // Options: 'csv', 'xml', 'json' + ]; + + //------------------------------------------ + // Product Code Based Descriptions + // Keys can be: exact code (MWTH2NB) or pattern (MWTH1*, MWTH2*) + //------------------------------------------ + $meta_descriptions = [ + // Pattern based (will match any product starting with this) + 'MWTH1' => 'The Thomas-I exudes elegance and sophistication. Classic dimensions combined with subtle details in the dial make it an special automatic watch that can be worn on all occasions.', + 'MWTH2' => 'The Thomas-II provides a view of the beating heart of the Swiss timepiece. It marks the precision and perfection with which the time is displayed.', + 'MWABR' => 'Handmade Italian calf leather bracelet', + ]; + + //------------------------------------------ + //Include meta functions + //------------------------------------------ + include_once './assets/functions_meta.php'; + + $meta_feed = catalogToMetaFeed($messages, $meta_config); + //------------------------------------------ + // Output based on format parameter + //------------------------------------------ + if ($criterias['meta'] === true) { + $format = $meta_config['output_format']; + } else { + $format = $criterias['meta']; + } + + switch ($format) { + case 'xml': + $messages = outputMetaFeedXML($meta_feed); + break; + case 'csv': + $messages = outputMetaFeedCSV($meta_feed); + break; + case 'json': + default: + $messages = outputMetaFeedJSON($meta_feed); + break; + } + exit(); +} //------------------------------------------ //JSON_ENCODE //------------------------------------------ diff --git a/api/v2/get/history.php b/api/v2/get/history.php index aa81a11..c2ff77a 100644 --- a/api/v2/get/history.php +++ b/api/v2/get/history.php @@ -102,7 +102,7 @@ if(isset($get_content) && $get_content!=''){ //Filter out only relevant servicereports $filter_key_1 = '"%serialnumber%"'; $filter_key_2 = '"ServiceReport"'; - $clause .= ' AND h.type = '.$filter_key_2.' AND NOT e.productrowid = "31" AND h.description like '.$filter_key_1; + $clause .= ' AND h.type = '.$filter_key_2.' AND e.productrowid = "31" AND h.description like '.$filter_key_1; //remove from criterias to prevent double binding unset($criterias[$v[0]]); } diff --git a/api/v2/get/products_software_licenses.php b/api/v2/get/products_software_licenses.php index f47175d..6b9a1d0 100644 --- a/api/v2/get/products_software_licenses.php +++ b/api/v2/get/products_software_licenses.php @@ -51,7 +51,7 @@ if(isset($get_content) && $get_content!=''){ //Define Query if(isset($criterias['totals']) && $criterias['totals'] ==''){ //Request for total rows - $sql = 'SELECT count(*) as count FROM products_software_licenses '.$whereclause.''; + $sql = 'SELECT count(*) as count FROM products_software_licenses l '.$whereclause.''; } elseif (isset($criterias['list']) && $criterias['list'] =='') { //SQL for list diff --git a/assets/mail/pdf_template_invoice.php b/assets/mail/pdf_template_invoice.php index 29aea68..33a8a1b 100644 --- a/assets/mail/pdf_template_invoice.php +++ b/assets/mail/pdf_template_invoice.php @@ -308,8 +308,9 @@ $pdf .= '
'; if ($tax_amount > 0) { + $tax_percentage = ($subtotal > 0) ? round(($tax_amount / $subtotal) * 100, 2) : 0; $pdf .= '
-
' . htmlspecialchars($lbl_tax) . '
+
' . htmlspecialchars($lbl_tax) . ' (' . $tax_percentage . '%)
€ ' . number_format($tax_amount, 2) . '
'; } else { diff --git a/assets/softwaretool.js b/assets/softwaretool.js index a8855c8..4e5e8f4 100644 --- a/assets/softwaretool.js +++ b/assets/softwaretool.js @@ -230,6 +230,10 @@ async function connectDeviceForSoftware() { deviceVersion = ""; deviceHwVersion = ""; + // Clear the flag so popup shows for each new device connection + // This allows users to connect multiple devices in the same session + sessionStorage.removeItem('customerDataShownThisSession'); + //set progress bar progressBar("1", "", ""); @@ -612,14 +616,23 @@ async function fetchSoftwareOptions() { document.getElementById("softwareOptionsContainer").style.display = "block"; progressBar("100", "Software options loaded", "#04AA6D"); - // Check if customer data already exists in sessionStorage - const savedCustomerData = sessionStorage.getItem('customerData'); + // Check if we're returning from a payment + const urlParams = new URLSearchParams(window.location.search); + const isReturningFromPayment = urlParams.has('payment_return') || urlParams.has('order_id'); - // Show user info modal only if no saved data and not in debug mode - if ((typeof DEBUG === 'undefined' || !DEBUG || typeof DEBUG_ID === 'undefined' || !DEBUG_ID) && !savedCustomerData) { + // Check if customer data was already shown in THIS session (not from previous session) + const customerDataShownThisSession = sessionStorage.getItem('customerDataShownThisSession'); + + // Show user info modal unless: + // 1. We're in debug mode + // 2. We're returning from payment + // 3. We already showed the modal in this session + if ((typeof DEBUG === 'undefined' || !DEBUG || typeof DEBUG_ID === 'undefined' || !DEBUG_ID) + && !isReturningFromPayment + && !customerDataShownThisSession) { showUserInfoModal(); } else { - // Customer data already exists or debug mode - reveal software options immediately + // Debug mode, returning from payment, or already shown this session - reveal software options immediately const softwareOptions = document.getElementById("softwareOptions"); if (softwareOptions) { softwareOptions.style.filter = "none"; @@ -992,6 +1005,9 @@ function showUserInfoModal() { // Save customer data to sessionStorage sessionStorage.setItem('customerData', JSON.stringify(customerData)); + // Mark that we've shown the customer data modal in this session + sessionStorage.setItem('customerDataShownThisSession', 'true'); + // Send to API await sendUserInfoToAPI(customerData); diff --git a/contract_manage.php b/contract_manage.php index 9d7b602..7c46e33 100644 --- a/contract_manage.php +++ b/contract_manage.php @@ -248,10 +248,10 @@ $view .='
$partner_data = json_decode($contract['accounthierarchy']); //BUID UP DROPDOWNS -$salesid_dropdown = listPartner('salesid',$partner_data->salesid,'',$_SESSION['authorization']['permission']); -$soldto_dropdown = listPartner('soldto',$partner_data->soldto,'',$_SESSION['authorization']['permission']); -$shipto_dropdown = listPartner('shipto',$partner_data->shipto,'',$_SESSION['authorization']['permission']); -$location_dropdown = listPartner('location',$partner_data->location,'',$_SESSION['authorization']['permission']); +$salesid_dropdown = listPartner('salesid',$_SESSION['authorization']['permission'],$partner_data->salesid,''); +$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],$partner_data->soldto,''); +$shipto_dropdown = listPartner('shipto',$_SESSION['authorization']['permission'],$partner_data->shipto,''); +$location_dropdown = listPartner('location',$_SESSION['authorization']['permission'],$partner_data->location,''); //DISPLAY $view .= '
diff --git a/equipment_manage.php b/equipment_manage.php index e72fa6e..8e8f031 100644 --- a/equipment_manage.php +++ b/equipment_manage.php @@ -216,10 +216,10 @@ $view .= '
//GET PARTNERDATA $partner_data = json_decode($equipment['accounthierarchy']); //BUID UP DROPDOWNS -$salesid_dropdown = listPartner('salesid',$partner_data->salesid,'',$_SESSION['authorization']['permission']); -$soldto_dropdown = listPartner('soldto',$partner_data->soldto,'',$_SESSION['authorization']['permission']); -$shipto_dropdown = listPartner('shipto',$partner_data->shipto,'',$_SESSION['authorization']['permission']); -$location_dropdown = listPartner('location',$partner_data->location,'',$_SESSION['authorization']['permission']); +$salesid_dropdown = listPartner('salesid',$_SESSION['authorization']['permission'],$partner_data->salesid,''); +$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],$partner_data->soldto,''); +$shipto_dropdown = listPartner('shipto',$_SESSION['authorization']['permission'],$partner_data->shipto,''); +$location_dropdown = listPartner('location',$_SESSION['authorization']['permission'],$partner_data->location,''); if (isset($partner_data->section)){$section = getPartnerName($partner_data->section) ?? 'Not specified';} else {$section = 'Not specified';} diff --git a/equipments_mass_update.php b/equipments_mass_update.php index b0e44f1..565043e 100644 --- a/equipments_mass_update.php +++ b/equipments_mass_update.php @@ -200,10 +200,10 @@ $view .= '
//BUID UP DROPDOWNS $partner = json_decode($_SESSION['authorization']['partnerhierarchy'],true); -$salesid_dropdown = listPartner('salesid',$partner['salesid'],'yes',$_SESSION['authorization']['permission']); -$soldto_dropdown = listPartner('soldto','','yes',$_SESSION['authorization']['permission']); -$shipto_dropdown = listPartner('shipto','','',$_SESSION['authorization']['permission']); -$location_dropdown = listPartner('location','','',$_SESSION['authorization']['permission']); +$salesid_dropdown = listPartner('salesid',$_SESSION['authorization']['permission'],$partner['salesid'],'yes'); +$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],'','yes'); +$shipto_dropdown = listPartner('shipto',$_SESSION['authorization']['permission'],'',''); +$location_dropdown = listPartner('location',$_SESSION['authorization']['permission'],'',''); $view .='
diff --git a/firmwaretool.php b/firmwaretool.php index 8e33277..b19bbb8 100644 --- a/firmwaretool.php +++ b/firmwaretool.php @@ -103,7 +103,7 @@ echo ' '; diff --git a/marketing_migrate.php b/marketing_migrate.php new file mode 100644 index 0000000..43c745c --- /dev/null +++ b/marketing_migrate.php @@ -0,0 +1,171 @@ +query("SELECT 1 FROM marketing_files LIMIT 1"); +} catch (PDOException $e) { + echo "Marketing tables not found. Please run marketing_install.php first.
"; + echo "Install Marketing System"; + exit; +} + +// Get marketing structure from settings +$main_marketing_dir = './marketing/'; + +if (!file_exists($main_marketing_dir)) { + echo "Marketing directory not found at: $main_marketing_dir
"; + exit; +} + +echo "

Marketing File Migration

"; +echo "

Migrating existing marketing files to the new system...

"; + +$migrated_folders = 0; +$migrated_files = 0; +$errors = []; + +try { + // Build partner hierarchy for current user + $partner_hierarchy = json_encode(array("salesid" => $partner->salesid, "soldto" => $partner->soldto), JSON_UNESCAPED_UNICODE); + + // Scan marketing directory structure + if (isset($marketing_structure) && is_array($marketing_structure)) { + foreach ($marketing_structure as $product_group => $folders) { + echo "Processing product group: $product_group
"; + + // Create product group folder + $stmt = $pdo->prepare("INSERT INTO marketing_folders (folder_name, description, createdby, accounthierarchy) VALUES (?, ?, ?, ?)"); + $stmt->execute([$product_group, "Migrated from legacy structure", $username, $partner_hierarchy]); + $group_folder_id = $pdo->lastInsertId(); + $migrated_folders++; + + foreach ($folders as $folder_name) { + $folder_path = $main_marketing_dir . $product_group . '/' . $folder_name; + + if (is_dir($folder_path)) { + echo "  - Processing folder: $folder_name
"; + + // Create content folder + $stmt = $pdo->prepare("INSERT INTO marketing_folders (folder_name, parent_id, description, createdby, accounthierarchy) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$folder_name, $group_folder_id, "Migrated from legacy structure", $username, $partner_hierarchy]); + $content_folder_id = $pdo->lastInsertId(); + $migrated_folders++; + + // Process files in folder + $files = array_diff(scandir($folder_path), array('.', '..', 'Thumb')); + + foreach ($files as $file) { + $file_path = $folder_path . '/' . $file; + + if (is_file($file_path) && !is_dir($file_path)) { + $file_info = pathinfo($file); + $file_ext = strtolower($file_info['extension'] ?? ''); + + // Skip system files + if (in_array($file_ext, ['ds_store', 'thumbs.db']) || empty($file_ext)) { + continue; + } + + // Check if file type is supported + $allowed_types = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'mp4', 'mov', 'avi']; + if (!in_array($file_ext, $allowed_types)) { + $errors[] = "Skipped unsupported file type: $file"; + continue; + } + + $file_size = filesize($file_path); + $relative_path = str_replace('./', '', $file_path); + + // Check for existing thumbnail + $thumbnail_path = null; + $thumb_file = $folder_path . '/Thumb/' . $file; + if (file_exists($thumb_file)) { + $thumbnail_path = str_replace('./', '', $thumb_file); + } + + // Generate tags based on product group and folder + $tags = [$product_group, $folder_name]; + if (strpos(strtolower($file), 'brochure') !== false) $tags[] = 'brochure'; + if (strpos(strtolower($file), 'manual') !== false) $tags[] = 'manual'; + if (strpos(strtolower($file), 'spec') !== false) $tags[] = 'specifications'; + + try { + $stmt = $pdo->prepare(" + INSERT INTO marketing_files + (title, original_filename, file_path, thumbnail_path, file_type, file_size, folder_id, tags, createdby, accounthierarchy) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + "); + + $stmt->execute([ + $file_info['filename'], + $file, + $relative_path, + $thumbnail_path, + $file_ext, + $file_size, + $content_folder_id, + json_encode($tags), + $username, + $partner_hierarchy + ]); + + $migrated_files++; + echo "    ✓ $file
"; + + // Insert tags + foreach ($tags as $tag) { + $tag = trim($tag); + if (!empty($tag)) { + // Insert tag if not exists + $pdo->prepare("INSERT IGNORE INTO marketing_tags (tag_name) VALUES (?)")->execute([$tag]); + + // Link file to tag + $tag_id_stmt = $pdo->prepare("SELECT id FROM marketing_tags WHERE tag_name = ?"); + $tag_id_stmt->execute([$tag]); + $tag_id = $tag_id_stmt->fetchColumn(); + + if ($tag_id) { + $pdo->prepare("INSERT IGNORE INTO marketing_file_tags (file_id, tag_id) VALUES (?, ?)") + ->execute([$pdo->lastInsertId(), $tag_id]); + } + } + } + + } catch (PDOException $e) { + $errors[] = "Error migrating file $file: " . $e->getMessage(); + } + } + } + } + } + } + } + + echo "

Migration Summary

"; + echo "✓ Folders migrated: $migrated_folders
"; + echo "✓ Files migrated: $migrated_files
"; + + if (!empty($errors)) { + echo "

Errors/Warnings:

"; + foreach ($errors as $error) { + echo "⚠ $error
"; + } + } + + echo "
Migration completed successfully!
"; + echo "Go to Marketing Page"; + +} catch (Exception $e) { + echo "Migration error: " . $e->getMessage(); +} +?> \ No newline at end of file diff --git a/partner.php b/partner.php index 91eb7e9..ff1cddf 100644 --- a/partner.php +++ b/partner.php @@ -163,8 +163,8 @@ $view .= '
//GET PARTNERDATA $partner_data = json_decode($partner['salesID'])?? json_decode($_SESSION['authorization']['partnerhierarchy']) ; //BUID UP DROPDOWNS -$salesid_dropdown = listPartner('salesid',$partner_data->salesid,'',$_SESSION['authorization']['permission']); -$soldto_dropdown = listPartner('soldto',$partner_data->soldto,'',$_SESSION['authorization']['permission']); +$salesid_dropdown = listPartner('salesid',$_SESSION['authorization']['permission'],$partner_data->salesid,''); +$soldto_dropdown = listPartner('soldto',$_SESSION['authorization']['permission'],$partner_data->soldto,''); //DISPLAY $view .= '
diff --git a/style/admin.css b/style/admin.css index 959804a..c96be5f 100644 --- a/style/admin.css +++ b/style/admin.css @@ -591,7 +591,7 @@ main .content-block-wrapper .content-block { width: 100%; margin: 0 10px; border-radius: 3px; - max-height: 300px; + max-height: 400px; overflow-y: auto; } diff --git a/user.php b/user.php index cb772ac..54c12d3 100644 --- a/user.php +++ b/user.php @@ -494,8 +494,8 @@ $view .= '
'; if ($hierarchyLevel == 0 || $hierarchyLevel == 1){ - $salesid_dropdown = listPartner('salesid', $partner_data->salesid ?? '', '', $_SESSION['authorization']['permission']); - $soldto_dropdown = listPartner('soldto', $partner_data->soldto ?? '', '', $_SESSION['authorization']['permission']); + $salesid_dropdown = listPartner('salesid', $_SESSION['authorization']['permission'], $partner_data->salesid ?? '', ''); + $soldto_dropdown = listPartner('soldto', $_SESSION['authorization']['permission'], $partner_data->soldto ?? '', ''); $view .= ' @@ -513,8 +513,8 @@ if ($hierarchyLevel == 0 || $hierarchyLevel == 1){ '; } -$shipto_dropdown = listPartner('shipto', $partner_data->shipto ?? '', '', $_SESSION['authorization']['permission']); -$location_dropdown = listPartner('location', $partner_data->location ?? '', '', $_SESSION['authorization']['permission']); +$shipto_dropdown = listPartner('shipto', $_SESSION['authorization']['permission'], $partner_data->shipto ?? '', ''); +$location_dropdown = listPartner('location', $_SESSION['authorization']['permission'], $partner_data->location ?? '', ''); $view .= ' diff --git a/webhook_mollie.php b/webhook_mollie.php index cac5356..d02a021 100644 --- a/webhook_mollie.php +++ b/webhook_mollie.php @@ -204,8 +204,8 @@ try { if (!$existing_invoice) { // Create invoice - $sql = 'INSERT INTO invoice (txn_id, payment_status, payment_amount, shipping_amount, discount_amount, tax_amount, created) - VALUES (?, ?, ?, ?, ?, ?, ?)'; + $sql = 'INSERT INTO invoice (txn_id, payment_status, payment_amount, shipping_amount, discount_amount, tax_amount, created,accounthierarchy) + VALUES (?, ?, ?, ?, ?, ?, ?,?)'; $stmt = $pdo->prepare($sql); $stmt->execute([ $transaction['txn_id'], @@ -214,7 +214,8 @@ try { $transaction['shipping_amount'] ?? 0.00, $transaction['discount_amount'] ?? 0.00, $transaction['tax_amount'] ?? 0.00, - date('Y-m-d H:i:s') + date('Y-m-d H:i:s'), + '{"salesid":"21-Total Safety Solutions B.V.","soldto":""}' ]); $invoice_id = $pdo->lastInsertId(); } else { diff --git a/webhook_paypal.php b/webhook_paypal.php index f25f56f..3df5306 100644 --- a/webhook_paypal.php +++ b/webhook_paypal.php @@ -250,8 +250,8 @@ try { if (!$existing_invoice) { // Create invoice - $sql = 'INSERT INTO invoice (txn_id, payment_status, payment_amount, shipping_amount, discount_amount, tax_amount, created) - VALUES (?, ?, ?, ?, ?, ?, ?)'; + $sql = 'INSERT INTO invoice (txn_id, payment_status, payment_amount, shipping_amount, discount_amount, tax_amount, created,accounthierarchy) + VALUES (?, ?, ?, ?, ?, ?, ?,?)'; $stmt = $pdo->prepare($sql); $stmt->execute([ $transaction['txn_id'], @@ -260,7 +260,8 @@ try { $transaction['shipping_amount'] ?? 0.00, $transaction['discount_amount'] ?? 0.00, $transaction['tax_amount'] ?? 0.00, - date('Y-m-d H:i:s') + date('Y-m-d H:i:s'), + '{"salesid":"21-Total Safety Solutions B.V.","soldto":""}' ]); $invoice_id = $pdo->lastInsertId(); } else {
'.($general_salesid ?? 'Sales ID').'
'.($general_shipto ?? 'Ship To').'