softDelete features
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
require '../../../assets/utils/classes/QuotationManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid quotation ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new QuotationManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Quotation deleted.';
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$answer['message'] = 'Database error, please try again.';
|
||||
http_response_code(500);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$answer['message'] = $e->getMessage();
|
||||
http_response_code(400);
|
||||
}
|
||||
|
||||
exit(json_encode($answer));
|
||||
@@ -157,6 +157,9 @@
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_cancel" onclick="cancel_order()">
|
||||
<i class="ti ti-x me-1"></i>Cancel Order
|
||||
</button>
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete" onclick="delete_order()">
|
||||
<i class="ti ti-trash me-1"></i>Delete Order
|
||||
</button>
|
||||
<a href="<?php echo $server_url?>revenue/order.php" class="btn btn-light w-100">
|
||||
Back
|
||||
</a>
|
||||
@@ -172,6 +175,8 @@
|
||||
|
||||
<script>
|
||||
// custom.js globals: remove_item(), init_product_search_inputs(), escape_html(), format_number()
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var order_id = <?php echo $order_id; ?>;
|
||||
var order_data = null;
|
||||
var item_index = 0;
|
||||
@@ -306,6 +311,7 @@
|
||||
}
|
||||
|
||||
$('#btn_cancel').toggleClass('d-none', status !== -2);
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !order_id);
|
||||
|
||||
var is_existing = order_id > 0;
|
||||
var can_invoice = is_existing && status >= 1 && status !== -1 && !has_active_invoice;
|
||||
@@ -426,6 +432,25 @@
|
||||
});
|
||||
}
|
||||
|
||||
function delete_order() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this order? Unconfirmed stock-out rows will also be removed.',
|
||||
buttons: { confirm: { label: 'Delete', className: 'btn-danger' }, cancel: { label: 'Back', className: 'btn-secondary' } },
|
||||
callback: function(result) {
|
||||
if (!result) return;
|
||||
ajax_request({
|
||||
url: '<?php echo $server_url?>order/api/engine/delete_order.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: order_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>revenue/order.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function cancel_order() {
|
||||
bootbox.confirm({
|
||||
message: 'Cancel this pending sales order? It will be removed from WMS queue.',
|
||||
|
||||
@@ -187,6 +187,11 @@
|
||||
<i class="ti ti-ban me-1"></i>Cancel Quotation
|
||||
</button>
|
||||
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete"
|
||||
onclick="delete_quotation()">
|
||||
<i class="ti ti-trash me-1"></i>Delete Quotation
|
||||
</button>
|
||||
|
||||
<hr class="d-none" id="hr_convert">
|
||||
<a href="javascript:void(0);" class="btn btn-success w-100 d-none" id="btn_convert"
|
||||
onclick="convert_to_order()">
|
||||
@@ -207,6 +212,8 @@
|
||||
<script>
|
||||
// custom.js globals: remove_item(), init_product_search_inputs(), escape_html(), format_number()
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var quotation_id = <?php echo $quotation_id; ?>;
|
||||
var quotation_data = null;
|
||||
var item_index = 0;
|
||||
@@ -342,6 +349,7 @@
|
||||
$('#btn_reject').toggleClass('d-none', !is_sent);
|
||||
$('#btn_reopen').toggleClass('d-none', is_draft || is_closed);
|
||||
$('#btn_cancel').toggleClass('d-none', is_closed || (is_draft && !quotation_id));
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !quotation_id);
|
||||
|
||||
// Convert to Order — only on Accepted, not yet converted
|
||||
var show_convert = is_accepted && !is_converted;
|
||||
@@ -481,6 +489,25 @@
|
||||
}
|
||||
|
||||
|
||||
function delete_quotation() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this quotation? This cannot be undone.',
|
||||
buttons: { confirm: { label: 'Delete', className: 'btn-danger' }, cancel: { label: 'Back', className: 'btn-secondary' } },
|
||||
callback: function(result) {
|
||||
if (!result) return;
|
||||
ajax_request({
|
||||
url: '<?php echo $server_url?>revenue/api/engine/delete_quotation.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: quotation_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>revenue/quotation.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).on('contact:selected', '#contact', function(e, contact) {
|
||||
$('#contact_id').val(contact.id);
|
||||
});
|
||||
|
||||
@@ -152,6 +152,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
function order_status_badge(status) {
|
||||
const map = {
|
||||
'-2': '<span class="badge bg-danger">Pending Warehouse</span>',
|
||||
@@ -243,6 +246,7 @@
|
||||
<a href="<?php echo $server_url?>revenue/manage_order.php?id=${o.id}" title="View SO">
|
||||
<i class="ti ti-eye fs-5"></i>
|
||||
</a>
|
||||
${can_delete ? `<a href="javascript:void(0);" class="link-danger ms-2" title="Delete" onclick="delete_order(${o.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -250,6 +254,24 @@
|
||||
$('table#revenue_order_list tbody').html(body);
|
||||
}
|
||||
|
||||
function delete_order(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this order? Unconfirmed stock-out rows will also be removed.',
|
||||
buttons: { confirm: { label: 'Delete', className: 'btn-danger' }, cancel: { label: 'Back', className: 'btn-secondary' } },
|
||||
callback: function(result) {
|
||||
if (!result) return;
|
||||
ajax_request({
|
||||
url: '<?php echo $server_url?>order/api/engine/delete_order.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { retrieve_orders(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
await load_dept_cache();
|
||||
populate_dept_filter('filter_dept');
|
||||
|
||||
@@ -158,6 +158,8 @@
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var status_badge = {
|
||||
'-1': '<span class="badge bg-secondary">Cancelled</span>',
|
||||
'0': '<span class="badge bg-warning text-dark">Draft</span>',
|
||||
@@ -224,6 +226,7 @@
|
||||
<a href="<?php echo $server_url?>revenue/manage_quotation.php?id=${q.id}" title="View">
|
||||
<i class="ti ti-eye fs-5"></i>
|
||||
</a>
|
||||
${can_delete ? `<a href="javascript:void(0);" class="link-danger ms-2" title="Delete" onclick="delete_quotation(${q.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -231,6 +234,24 @@
|
||||
$('table#quotation_list tbody').html(body);
|
||||
}
|
||||
|
||||
function delete_quotation(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this quotation? This cannot be undone.',
|
||||
buttons: { confirm: { label: 'Delete', className: 'btn-danger' }, cancel: { label: 'Back', className: 'btn-secondary' } },
|
||||
callback: function(result) {
|
||||
if (!result) return;
|
||||
ajax_request({
|
||||
url: '<?php echo $server_url?>revenue/api/engine/delete_quotation.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { retrieve_quotations(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
await load_dept_cache();
|
||||
populate_dept_filter('filter_dept');
|
||||
|
||||
Reference in New Issue
Block a user