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/InvoiceManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid invoice ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new InvoiceManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Document 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));
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
require '../../../assets/utils/classes/OrderManager.php';
|
||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid order ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new OrderManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Sales order 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));
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
require '../../../assets/utils/classes/ReturnManager.php';
|
||||
require '../../../assets/utils/classes/WarehouseManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid return ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new ReturnManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Return 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));
|
||||
@@ -3,7 +3,7 @@
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require_role($user_role, ['owner', 'admin', 'staff']);
|
||||
require '../../../assets/utils/classes/OrderManager.php';
|
||||
require '../../../assets/utils/classes/CompanySettingManager.php';
|
||||
require_once '../../../assets/utils/classes/CompanySettingManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
$tracking_number = trim((string)($data['shipping_tracking_number'] ?? ''));
|
||||
|
||||
@@ -158,6 +158,8 @@
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
function doc_type_badge(doc_type) {
|
||||
const map = {
|
||||
'invoice': '<span class="badge bg-primary">Invoice</span>',
|
||||
@@ -269,6 +271,7 @@
|
||||
onclick="void_invoice(${inv.id})">
|
||||
<i class="ti ti-ban fs-5"></i>
|
||||
</a>` : ''}
|
||||
${can_delete ? `<a href="javascript:void(0);" class="link-danger ms-2" title="Delete" onclick="delete_invoice(${inv.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -310,6 +313,7 @@
|
||||
<a href="<?php echo $server_url?>order/manage_invoice.php?id=${cn.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_invoice(${cn.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -342,6 +346,24 @@
|
||||
|
||||
|
||||
// ── Boot ─────────────────────────────────────────────────────────────────
|
||||
function delete_invoice(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this document? Any GL entry will 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_invoice.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { retrieve_invoices(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
await load_dept_cache();
|
||||
populate_dept_filter('filter_dept');
|
||||
|
||||
@@ -146,6 +146,10 @@
|
||||
<i class="ti ti-ban me-1"></i>Void Invoice
|
||||
</button>
|
||||
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete"
|
||||
onclick="delete_invoice()">
|
||||
<i class="ti ti-trash me-1"></i>Delete
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -160,6 +164,8 @@
|
||||
<script>
|
||||
// custom.js globals: format_number()
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var invoice_id = <?php echo $invoice_id; ?>;
|
||||
var invoice_data = null;
|
||||
|
||||
@@ -223,6 +229,7 @@
|
||||
!is_invoice ? 'Only original invoices can be voided'
|
||||
: status === 0 ? 'Invoice has not been issued yet'
|
||||
: status === 4 ? 'Invoice is already void' : '');
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !invoice_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -344,6 +351,25 @@
|
||||
|
||||
|
||||
|
||||
function delete_invoice() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this document? Any GL entry will 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_invoice.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: invoice_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>order/invoice.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function void_invoice() {
|
||||
bootbox.confirm({
|
||||
message: '<strong>Void this invoice?</strong><br>This action cannot be undone.',
|
||||
|
||||
@@ -216,6 +216,11 @@
|
||||
<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>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -230,6 +235,8 @@
|
||||
<script>
|
||||
// custom.js globals: remove_item(), init_product_search_inputs(), format_number()
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var order_id = <?php echo $order_id; ?>;
|
||||
var order_source = <?php echo json_encode($source); ?>;
|
||||
var order_source_id = <?php echo (int)$source_id; ?>;
|
||||
@@ -426,6 +433,7 @@
|
||||
is_pending ? 'Assign warehouses and save first. The order will move to Draft.' : 'Order must be in draft to confirm');
|
||||
set_btn_state('#btn_cancel', can_cancel && !is_cancelled,
|
||||
is_cancelled ? 'Order is already cancelled' : 'Only draft or confirmed orders can be cancelled');
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !order_id);
|
||||
|
||||
set_btn_state('#btn_tracking', can_update_tracking,
|
||||
is_cancelled ? 'Order is cancelled'
|
||||
@@ -631,6 +639,25 @@
|
||||
|
||||
|
||||
// ── Cancel order ──────────────────────────────────────────────────────────
|
||||
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?>order/order.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function cancel_order() {
|
||||
bootbox.confirm({
|
||||
message: 'Cancel this order? All pending stock-out rows will be cancelled.',
|
||||
|
||||
@@ -189,6 +189,11 @@
|
||||
<i class="ti ti-x me-1"></i>Cancel Return
|
||||
</button>
|
||||
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete"
|
||||
onclick="delete_return()">
|
||||
<i class="ti ti-trash me-1"></i>Delete Return
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -202,6 +207,8 @@
|
||||
<script>
|
||||
// custom.js globals: escape_html(), format_number()
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var return_id = <?php echo $return_id; ?>;
|
||||
var return_data = null;
|
||||
var order_data = null;
|
||||
@@ -766,6 +773,7 @@
|
||||
|
||||
set_btn_state('#btn_cancel', is_draft || status === 1,
|
||||
status === -1 ? 'Return is already cancelled' : 'Return is completed and cannot be cancelled');
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !return_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -865,6 +873,25 @@
|
||||
|
||||
|
||||
// ── Cancel return ─────────────────────────────────────────────────────────
|
||||
function delete_return() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this return? Unconfirmed stock rows will 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_return.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: return_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>order/return.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function cancel_return() {
|
||||
bootbox.confirm({
|
||||
message: 'Cancel this return request?',
|
||||
|
||||
@@ -162,6 +162,8 @@
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
// ── Status helpers ────────────────────────────────────────────────────────
|
||||
function order_status_badge(status) {
|
||||
status = parseInt(status);
|
||||
@@ -268,6 +270,7 @@
|
||||
onclick="cancel_order(${o.id})">
|
||||
<i class="ti ti-x 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>`;
|
||||
});
|
||||
@@ -301,6 +304,25 @@
|
||||
}
|
||||
|
||||
|
||||
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(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ── Boot ─────────────────────────────────────────────────────────────────
|
||||
$(async function() {
|
||||
await load_dept_cache();
|
||||
|
||||
@@ -99,6 +99,8 @@
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
function return_status_badge(status) {
|
||||
const map = {
|
||||
'-1': '<span class="badge bg-secondary">Cancelled</span>',
|
||||
@@ -182,6 +184,7 @@
|
||||
onclick="cancel_return(${r.id})">
|
||||
<i class="ti ti-x fs-5"></i>
|
||||
</a>` : ''}
|
||||
${can_delete ? `<a href="javascript:void(0);" class="link-danger ms-2" title="Delete" onclick="delete_return(${r.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -212,6 +215,24 @@
|
||||
}
|
||||
|
||||
|
||||
function delete_return(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this return? Unconfirmed stock rows will 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_return.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { retrieve_returns(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
await load_dept_cache();
|
||||
populate_dept_filter('filter_dept');
|
||||
|
||||
Reference in New Issue
Block a user