feat: Enhance software tool with country selection and tax calculation

- Added a helper function to generate country select options in software tool.
- Updated user info modal and payment modal to use country dropdowns instead of text inputs.
- Implemented tax calculation based on selected country in payment modal.
- Improved software options loading behavior in debug mode.
- Enhanced description formatting in payment modal.
- Added log modal for equipment updates with a link to view logs.
- Introduced a new countries settings file with tax rates for various countries.
- Minor adjustments to various PHP files for better handling of equipment and payment processes.
This commit is contained in:
“VeLiTi”
2026-01-16 16:01:31 +01:00
parent 7aebb762d3
commit 3db13b9ebf
27 changed files with 652 additions and 114 deletions

BIN
api/v2/.DS_Store vendored

Binary file not shown.

View File

@@ -294,8 +294,9 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){
FROM products_software_upgrade_paths pup
JOIN products_software_versions from_ver ON pup.from_version_id = from_ver.rowID
WHERE pup.to_version_id = ?
AND LOWER(TRIM(LEADING "0" FROM from_ver.version)) = ?
AND pup.is_active = 1';
AND (LOWER(TRIM(LEADING "0" FROM from_ver.version)) = ?
OR pup.from_version_id = 9999999)
AND pup.is_active = 1';
$stmt = $pdo->prepare($sql);
$stmt->execute([$version['version_id'], $current_sw_version]);
$upgrade_path = $stmt->fetch(PDO::FETCH_ASSOC);

View File

@@ -332,26 +332,28 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){
} else {
//Part of an upgrade path system
//Only show if there's an explicit path FROM current version TO this version
// OR a wildcard path (from_version_id = 9999999)
$sql = 'SELECT pup.price, pup.currency
FROM products_software_upgrade_paths pup
JOIN products_software_versions from_ver ON pup.from_version_id = from_ver.rowID
WHERE pup.to_version_id = ?
AND LOWER(TRIM(LEADING "0" FROM from_ver.version)) = ?
AND pup.is_active = 1';
AND (LOWER(TRIM(LEADING "0" FROM from_ver.version)) = ?
OR pup.from_version_id = 9999999)
AND pup.is_active = 1';
$stmt = $pdo->prepare($sql);
$stmt->execute([$version['version_id'], $current_sw_version]);
$upgrade_path = $stmt->fetch(PDO::FETCH_ASSOC);
if ($upgrade_path) {
//Valid upgrade path found FROM current version
//Valid upgrade path found FROM current version or wildcard
$show_version = true;
$final_price = $upgrade_path['price'] ?? '0.00';
$final_currency = $upgrade_path['currency'] ?? '';
$decision_reason = 'Showing - found upgrade path FROM current (' . $current_sw_version . ') with price: ' . $final_price . ' ' . $final_currency;
$decision_reason = 'Showing - found upgrade path FROM current (' . $current_sw_version . ') or wildcard with price: ' . $final_price . ' ' . $final_currency;
} else {
$decision_reason = 'Skipped - has upgrade paths but none FROM current version (' . $current_sw_version . ')';
$decision_reason = 'Skipped - has upgrade paths but none FROM current version (' . $current_sw_version . ') or wildcard';
}
//If no path from current version exists, don't show (show_version stays false)
//If no path from current version or wildcard exists, don't show (show_version stays false)
}
}
}

View File

@@ -148,9 +148,9 @@ if ($command == 'update'){
//RESET WARRANTY AND SERVICE DATES WHEN STATUS IS CHANGED TO SEND(3)
if (isset($post_content['status']) && $post_content['status'] == 3 && $equipment_data['status'] != 3)
{
$post_content['service_date'] = $date;
$post_content['warranty_date'] = $date;
$post_content['service_date'] = date("Y-m-d", strtotime("+" . SERVICE_MONTHS . " months"));
$post_content['warranty_date'] = date("Y-m-d", strtotime("+" . WARRANTY_MONTHS . " months"));
$post_content['order_send_date'] = $date;
}
//UPDATE CHANGELOG BASED ON STATUS CHANGE
if (isset($post_content['status']) && $post_content['status'] != $equipment_data['status'])
@@ -188,8 +188,15 @@ elseif ($command == 'insert'){
$post_content['created'] = $date;
$post_content['createdby'] = $username;
$post_content['accounthierarchy'] = $accounthierarchy;
$post_content['service_date'] = $date;
$post_content['warranty_date'] = $date;
$post_content['service_date'] = date("Y-m-d", strtotime("+" . SERVICE_MONTHS . " months"));
$post_content['warranty_date'] = date("Y-m-d", strtotime("+" . WARRANTY_MONTHS . " months"));
if (isset($post_content['status']) && $post_content['status'] == 3)
{
$post_content['order_send_date'] = $date;
}
}
else {
//do nothing

View File

@@ -44,12 +44,16 @@ if (isset($post_content['sn']) && (isset($post_content['payload']) || isset($pos
$updateObject_visual = 0; //update visual inspection object
$sendServiceReport = 0; //send service report via email
$transfercartest = 0; //Update cartest table with incoming data
$create_software_license = 0; //Create software license
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
//SET DEFAULT PARAMETERS
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
$user = $username;
$account = $partnerhierarchy; //string
$current_date = date("Y-m-d");
$service_date = date("Y-m-d", strtotime("+" . SERVICE_MONTHS . " months"));
$warranty_date = date("Y-m-d", strtotime("+" . WARRANTY_MONTHS . " months"));
$order_send_date = date("Y-m-d");
$input_type = $post_content['type'];
$testdetails = json_encode($post_content['payload']);
$serial = $post_content['sn'];
@@ -146,6 +150,11 @@ if (isset($post_content['sn']) && (isset($post_content['payload']) || isset($pos
$transfercartest = 1;
break;
case 12: //customer_consent
$historytype = 'Customer_consent';
$create_software_license = 1;
break;
case 'firmware': //update from Portal
$historytype = $HistoryType_2;
$equipmentUpdate = 1;
@@ -164,14 +173,14 @@ if (isset($post_content['sn']) && (isset($post_content['payload']) || isset($pos
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Connect to DB
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Get whereclause based on serialnumber
$whereclause = checkSerial($serial);
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
//CHECK if EQUIPMENT EXISTS
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
$sql = "SELECT count(rowID) as total, rowID FROM equipment $whereclause";
$sql = "SELECT count(rowID) as total, rowID, hw_version FROM equipment $whereclause";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$total = $stmt->fetchAll(PDO::FETCH_ASSOC);
@@ -182,9 +191,9 @@ if (isset($post_content['sn']) && (isset($post_content['payload']) || isset($pos
// Create equipment when not exist +++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
if ($equipmentCreate == 1 && $total_equipment == 0){
$sql = 'INSERT INTO equipment (productrowid,created,createdby,status,accounthierarchy,serialnumber,service_date,warranty_date) VALUES (?,?,?,?,?,?,?,?)';
$sql = 'INSERT INTO equipment (productrowid,created,createdby,status,accounthierarchy,serialnumber,service_date,warranty_date,order_send_date) VALUES (?,?,?,?,?,?,?,?,?)';
$stmt = $pdo->prepare($sql);
$stmt->execute([$productrowid,$date,$user,$status0,$account,$serial,$current_date,$current_date]);
$stmt->execute([$productrowid,$date,$user,$status0,$account,$serial,$service_date,$warranty_date,$order_send_date]);
$rowID = $pdo->lastInsertId();
}
@@ -305,7 +314,7 @@ if (isset($post_content['sn']) && (isset($post_content['payload']) || isset($pos
//Update Equipment record
$sql = "UPDATE equipment SET service_date = ? $whereclause";
$stmt = $pdo->prepare($sql);
$stmt->execute([$current_date]);
$stmt->execute([$service_date]);
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -357,6 +366,49 @@ if (isset($post_content['sn']) && (isset($post_content['payload']) || isset($pos
if ($transfercartest == 1){
convertCartest();
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
// create software license ++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
if ($create_software_license == 1){
// Generate unique license key
$license_key = generateUniqueLicenseKey();
$sw_version_consent = strtolower($post_content['testdetails']['logdetails']['FW'] ?? '');// version_id
$eq_version_hw = strtolower($rowID['hw_version'] ?? '');
//GET VERSION_ID FROM VERSION TABLE
$sql = 'SELECT rowID FROM products_software_versions WHERE version = ? and hw_version = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$sw_version_consent, $eq_version_hw]);
$version_row = $stmt->fetch(PDO::FETCH_ASSOC);
//GET VERSION_ID or use WILDCARD
$sw_version_consent = $version_row['rowID'] ?? '9999999';
// Create license
$sql = 'INSERT INTO products_software_licenses
(version_id, license_type, license_key, status, starts_at, expires_at, transaction_id, created, createdby)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)';
$stmt = $pdo->prepare($sql);
$stmt->execute([
$sw_version_consent,
1, // license_type (1 = upgrade)
$license_key,
1, // status = active
date('Y-m-d H:i:s'),
'2099-12-31 23:59:59', // effectively permanent
'Customer_consent',
date('Y-m-d H:i:s'),
$user
]);
// Update equipment.sw_version_license
$sql = 'UPDATE equipment SET sw_version_license = ? WHERE rowID = ?';
$stmt = $pdo->prepare($sql);
$stmt->execute([$license_key, $rowID]);
}
}
else
{

View File

@@ -25,6 +25,11 @@ $user_data = $post_content['user_data'] ?? [];
// Read payment_provider from top level first, then fallback to user_data
$payment_provider = $post_content['payment_provider'] ?? $user_data['payment_provider'] ?? 'mollie';
// Extract tax information from user_data (sent from frontend)
$item_price = $user_data['item_price'] ?? null; // Price without VAT
$tax_amount = $user_data['tax_amount'] ?? 0; // VAT amount
$payment_amount = $user_data['payment_amount'] ?? null; // Total including VAT
//+++++++++++++++++++++++++++++++++++++++++++++++++++++
// STEP 1: Get equipment data from serial_number
//+++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -165,8 +170,17 @@ if (debug) {
// STEP 7: Create payment based on provider
//+++++++++++++++++++++++++++++++++++++++++++++++++++++
try {
// Use payment_amount (with tax) if provided, otherwise use final_price
$amount_to_charge = $payment_amount ? (float)$payment_amount : (float)$final_price;
// Format price (must be string with 2 decimals)
$formatted_price = number_format((float)$final_price, 2, '.', '');
$formatted_price = number_format($amount_to_charge, 2, '.', '');
if (debug) {
debuglog("DEBUG: Item Price (excl. VAT): " . ($item_price ?? $final_price));
debuglog("DEBUG: Tax Amount: " . $tax_amount);
debuglog("DEBUG: Total Amount (incl. VAT): " . $amount_to_charge);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++
// STEP 7A: Generate transaction ID BEFORE creating payment
@@ -252,7 +266,7 @@ try {
throw new Exception("No approval URL received from PayPal");
}
$payment_method_id = 1; // PayPal
$payment_method_id = 3; // PayPal
$payment_metadata = 'paypal_order_id';
} else {
@@ -291,7 +305,7 @@ try {
debuglog("DEBUG: Checkout URL: $checkout_url");
}
$payment_method_id = 0; // Mollie
$payment_method_id = 1; // Mollie
$payment_metadata = 'mollie_payment_id';
}
@@ -313,13 +327,14 @@ try {
// BUILD UP PARTNERHIERARCHY FROM USER
$partner_product = json_encode(array("salesid"=>$partner->salesid,"soldto"=>$partner->soldto), JSON_UNESCAPED_UNICODE);
$sql = 'INSERT INTO transactions (txn_id, payment_amount, payment_status, payer_email, first_name, last_name,
$sql = 'INSERT INTO transactions (txn_id, payment_amount, tax_amount, payment_status, payer_email, first_name, last_name,
address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, accounthierarchy, created)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
$stmt = $pdo->prepare($sql);
$stmt->execute([
$txn_id,
$final_price,
$amount_to_charge, // Total amount including tax
$tax_amount, // Tax amount
0, // 0 = pending
$user_data['email'] ?? '',
$first_name,
@@ -348,13 +363,16 @@ try {
$payment_metadata => $payment_id // Store payment provider ID
], JSON_UNESCAPED_UNICODE);
// Use item_price (without VAT) if provided, otherwise use final_price
$item_price_to_store = $item_price ? (float)$item_price : (float)$final_price;
$sql = 'INSERT INTO transactions_items (txn_id, item_id, item_price, item_quantity, item_options, created)
VALUES (?, ?, ?, ?, ?, ?)';
$stmt = $pdo->prepare($sql);
$stmt->execute([
$transaction_id,
$version_id,
$final_price,
$item_price_to_store, // Price without VAT
1,
$item_options,
date('Y-m-d H:i:s')