I then thought, well I only want this for deleting old missing orders, so why not just "add a button that deletes all missing orders older than 2 months?". And it worked perfect on first attempt.
1500+ orders removed in one click without having to go into the database!

I didn't even tell it which version of OC I'm using (3.0.3).
Ai, interesting, exciting, and worrying, all at the same time.
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<modification>
<id>Admin Orders Delete Button</id>
<version>1.5</version>
<vqmver>2.6.0</vqmver>
<author>Your Name</author>
<description>Adds delete buttons to the admin orders page and implements order deletion functions</description>
<!-- Add Delete Button to Orders List Page -->
<file name="admin/view/template/sale/order_list.twig">
<operation>
<search><![CDATA[<button type="button" data-toggle="tooltip" title="{{ button_filter }}" onclick="$('#filter-order').toggleClass('hidden-sm hidden-xs');" class="btn btn-default hidden-md hidden-lg"><i class="fa fa-filter"></i></button>]]></search>
<add position="before"><![CDATA[
<button type="button" id="button-delete" class="btn btn-danger"><i class="fa fa-trash"></i> Delete</button>
<button type="button" id="button-delete-missing" class="btn btn-warning"><i class="fa fa-trash"></i> Delete Missing Orders (Older than 2 Months)</button>
<script>
document.getElementById('button-delete').addEventListener('click', function() {
if (confirm('Are you sure you want to delete the selected orders?')) {
var selected = [];
document.querySelectorAll('input[name="selected[]"]:checked').forEach(function(el) {
selected.push(el.value);
});
if (selected.length > 0) {
let formData = new FormData();
selected.forEach(id => formData.append('selected[]', id));
fetch('index.php?route=sale/order/deleteOrders&user_token=' + getURLVar('user_token'), {
method: 'POST',
body: formData
}).then(response => response.json()).then(data => {
if (data.success) {
location.reload();
} else {
alert('Error deleting orders: ' + (data.error || 'Unknown error'));
}
}).catch(error => console.error('Error:', error));
} else {
alert('No orders selected!');
}
}
});
document.getElementById('button-delete-missing').addEventListener('click', function() {
if (confirm('Are you sure you want to delete all missing orders older than 2 months?')) {
fetch('index.php?route=sale/order/deleteMissingOrders&user_token=' + getURLVar('user_token'), {
method: 'POST'
}).then(response => response.json()).then(data => {
if (data.success) {
location.reload();
} else {
alert('Error deleting missing orders: ' + (data.error || 'Unknown error'));
}
}).catch(error => console.error('Error:', error));
}
});
</script>
]]></add>
</operation>
</file>
<!-- Add Delete Actions to Controller -->
<file name="admin/controller/sale/order.php">
<operation>
<search><![CDATA[class ControllerSaleOrder extends Controller {]]></search>
<add position="after"><![CDATA[
public function deleteOrders() {
$this->load->language('sale/order');
$json = [];
if (!$this->user->hasPermission('modify', 'sale/order')) {
$json['error'] = $this->language->get('error_permission');
} else {
if (!empty($this->request->post['selected']) && is_array($this->request->post['selected'])) {
$this->load->model('sale/order');
foreach ($this->request->post['selected'] as $order_id) {
$this->model_sale_order->deleteOrder($order_id);
}
$json['success'] = 'Selected orders have been deleted!';
} else {
$json['error'] = 'No orders selected or invalid format!';
}
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
public function deleteMissingOrders() {
$this->load->model('sale/order');
$this->model_sale_order->deleteMissingOrders();
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode(['success' => 'All missing orders older than 2 months have been deleted!']));
}
]]></add>
</operation>
</file>
<!-- Add Delete Missing Orders Function to Model -->
<file name="admin/model/sale/order.php">
<operation>
<search><![CDATA[class ModelSaleOrder extends Model {]]></search>
<add position="after"><![CDATA[
public function deleteOrder($order_id) {
$this->db->query("DELETE FROM " . DB_PREFIX . "order WHERE order_id = '" . (int)$order_id . "'");
$this->db->query("DELETE FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int)$order_id . "'");
$this->db->query("DELETE FROM " . DB_PREFIX . "order_option WHERE order_id = '" . (int)$order_id . "'");
$this->db->query("DELETE FROM " . DB_PREFIX . "order_history WHERE order_id = '" . (int)$order_id . "'");
$this->db->query("DELETE FROM " . DB_PREFIX . "order_total WHERE order_id = '" . (int)$order_id . "'");
}
public function deleteMissingOrders() {
$this->db->query("DELETE FROM " . DB_PREFIX . "order WHERE order_status_id = 0 AND date_added < DATE_SUB(NOW(), INTERVAL 2 MONTH)");
}
]]></add>
</operation>
</file>
</modification>