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/PaymentManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid payment ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new PaymentManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Payment 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,33 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
require '../../../assets/utils/classes/PaymentBillingManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid payment billing ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new PaymentBillingManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Payment billing 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,33 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
require '../../../assets/utils/classes/ReceiptManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid receipt ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new ReceiptManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Receipt 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,33 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../../../assets/utils/db_auth.php';
|
||||
require_role($user_role, ['owner', 'admin']);
|
||||
require '../../../assets/utils/classes/ReceiptBillingManager.php';
|
||||
|
||||
$id = (int)($data['id'] ?? 0);
|
||||
|
||||
if (!$id) {
|
||||
$answer['message'] = 'Invalid receipt billing ID.';
|
||||
http_response_code(400);
|
||||
exit(json_encode($answer));
|
||||
}
|
||||
|
||||
try {
|
||||
dbTransaction($pdo2, function($pdo) use ($id, $company_id) {
|
||||
$mgr = new ReceiptBillingManager($pdo, $company_id);
|
||||
$mgr->softDelete($id);
|
||||
});
|
||||
|
||||
$answer['success'] = 1;
|
||||
$answer['message'] = 'Receipt billing 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));
|
||||
@@ -123,6 +123,9 @@
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_void" onclick="void_payment()">
|
||||
<i class="ti ti-ban me-1"></i>Void Payment
|
||||
</button>
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete" onclick="delete_payment()">
|
||||
<i class="ti ti-trash me-1"></i>Delete Payment
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,6 +136,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var payment_id = <?php echo $payment_id; ?>;
|
||||
var payment = null;
|
||||
|
||||
@@ -184,6 +190,7 @@
|
||||
$('#display_method').html(display_text(method_label(payment.payment_method)));
|
||||
$('#display_notes').html(payment.notes ? escape_html(payment.notes).replace(/\n/g, '<br>') : '<span class="text-muted">—</span>');
|
||||
$('#btn_void').toggleClass('d-none', String(payment.status) === '4');
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !payment_id);
|
||||
|
||||
var selected_formula = payment.formula_id || '';
|
||||
ajax_request({
|
||||
@@ -245,6 +252,25 @@
|
||||
});
|
||||
}
|
||||
|
||||
function delete_payment() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this payment? The GL entry and invoice allocations will be reversed.',
|
||||
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?>finance/api/engine/delete_payment.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: payment_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>finance/payment.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function void_payment() {
|
||||
bootbox.confirm('Void this payment? Allocated purchase invoices and supplier credit notes will be reopened if not fully settled by other payments.', function(ok) {
|
||||
if (!ok) return;
|
||||
|
||||
@@ -88,6 +88,9 @@
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_void" onclick="void_billing()">
|
||||
<i class="ti ti-ban me-1"></i>Void Billing
|
||||
</button>
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete" onclick="delete_billing()">
|
||||
<i class="ti ti-trash me-1"></i>Delete Billing
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -98,6 +101,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var billing_id = <?php echo $billing_id; ?>;
|
||||
var billing = null;
|
||||
|
||||
@@ -148,6 +154,7 @@
|
||||
$('#btn_payment').attr('href', '<?php echo $server_url?>finance/payment.php?billing_id=' + billing.id);
|
||||
$('#btn_payment').toggleClass('d-none', String(billing.status) === '4' || parseFloat(billing.balance_amount || 0) <= 0.0001);
|
||||
$('#btn_void').toggleClass('d-none', String(billing.status) === '4' || parseFloat(billing.paid_amount || 0) > 0.0001);
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !billing_id);
|
||||
|
||||
var rows = '';
|
||||
$.each(billing.allocations || [], function(i, line) {
|
||||
@@ -168,6 +175,25 @@
|
||||
$('#allocation_tbody').html(rows || '<tr><td colspan="5" class="text-center py-5 text-muted">No documents found.</td></tr>');
|
||||
}
|
||||
|
||||
function delete_billing() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this billing? All linked payments must be deleted first.',
|
||||
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?>finance/api/engine/delete_payment_billing.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: billing_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>finance/payment_billing.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function void_billing() {
|
||||
bootbox.confirm('Void this payment billing?', function(ok) {
|
||||
if (!ok) return;
|
||||
|
||||
@@ -123,6 +123,9 @@
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_void" onclick="void_receipt()">
|
||||
<i class="ti ti-ban me-1"></i>Void Receipt
|
||||
</button>
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete" onclick="delete_receipt()">
|
||||
<i class="ti ti-trash me-1"></i>Delete Receipt
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,6 +136,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var receipt_id = <?php echo $receipt_id; ?>;
|
||||
var receipt = null;
|
||||
|
||||
@@ -184,6 +190,7 @@
|
||||
$('#display_method').html(display_text(method_label(receipt.payment_method)));
|
||||
$('#display_notes').html(receipt.notes ? escape_html(receipt.notes).replace(/\n/g, '<br>') : '<span class="text-muted">—</span>');
|
||||
$('#btn_void').toggleClass('d-none', String(receipt.status) === '4');
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !receipt_id);
|
||||
|
||||
var selected_formula = receipt.formula_id || '';
|
||||
ajax_request({
|
||||
@@ -245,6 +252,25 @@
|
||||
});
|
||||
}
|
||||
|
||||
function delete_receipt() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this receipt? The GL entry and invoice allocations will be reversed.',
|
||||
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?>finance/api/engine/delete_receipt.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: receipt_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>finance/receipt.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function void_receipt() {
|
||||
bootbox.confirm('Void this receipt? Allocated invoices and credit notes will be reopened if not fully settled by other receipts.', function(ok) {
|
||||
if (!ok) return;
|
||||
|
||||
@@ -88,6 +88,9 @@
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_void" onclick="void_billing()">
|
||||
<i class="ti ti-ban me-1"></i>Void Billing
|
||||
</button>
|
||||
<button class="btn btn-outline-danger w-100 d-none" id="btn_delete" onclick="delete_billing()">
|
||||
<i class="ti ti-trash me-1"></i>Delete Billing
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -98,6 +101,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var billing_id = <?php echo $billing_id; ?>;
|
||||
var billing = null;
|
||||
|
||||
@@ -148,6 +154,7 @@
|
||||
$('#btn_receipt').attr('href', '<?php echo $server_url?>finance/receipt.php?billing_id=' + billing.id);
|
||||
$('#btn_receipt').toggleClass('d-none', String(billing.status) === '4' || parseFloat(billing.balance_amount || 0) <= 0.0001);
|
||||
$('#btn_void').toggleClass('d-none', String(billing.status) === '4' || parseFloat(billing.received_amount || 0) > 0.0001);
|
||||
$('#btn_delete').toggleClass('d-none', !can_delete || !billing_id);
|
||||
|
||||
var rows = '';
|
||||
$.each(billing.allocations || [], function(i, line) {
|
||||
@@ -168,6 +175,25 @@
|
||||
$('#allocation_tbody').html(rows || '<tr><td colspan="5" class="text-center py-5 text-muted">No documents found.</td></tr>');
|
||||
}
|
||||
|
||||
function delete_billing() {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this billing? All linked receipts must be deleted first.',
|
||||
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?>finance/api/engine/delete_receipt_billing.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: billing_id },
|
||||
onSuccess: function() { window.location.href = '<?php echo $server_url?>finance/receipt_billing.php'; }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function void_billing() {
|
||||
bootbox.confirm('Void this receipt billing?', function(ok) {
|
||||
if (!ok) return;
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var open_billings = [];
|
||||
var prefill_billing_id = <?php echo $prefill_billing_id; ?>;
|
||||
var formula_map = {};
|
||||
@@ -258,6 +261,7 @@
|
||||
<a href="<?php echo $server_url?>finance/manage_payment.php?id=${r.id}" title="View payment">
|
||||
<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_payment(${r.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -457,6 +461,24 @@
|
||||
$(this).removeAttr('data-id');
|
||||
});
|
||||
|
||||
function delete_payment(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this payment? The GL entry and invoice allocations will be reversed.',
|
||||
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?>finance/api/engine/delete_payment.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { load_payments(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
flatpickr('#payment_date', { dateFormat: 'd/m/Y', allowInput: true });
|
||||
load_departments('department_id');
|
||||
|
||||
@@ -138,6 +138,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var billable_documents = [];
|
||||
|
||||
function show_billing_form() {
|
||||
@@ -207,6 +210,7 @@
|
||||
<a href="<?php echo $server_url?>finance/manage_payment_billing.php?id=${r.id}" title="View payment billing">
|
||||
<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_billing(${r.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -347,6 +351,24 @@
|
||||
$(this).removeAttr('data-id');
|
||||
});
|
||||
|
||||
function delete_billing(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this billing? All linked payments must be deleted first.',
|
||||
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?>finance/api/engine/delete_payment_billing.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { load_billings(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
flatpickr('#billing_date', { dateFormat: 'd/m/Y', allowInput: true });
|
||||
load_billings();
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var open_billings = [];
|
||||
var prefill_billing_id = <?php echo $prefill_billing_id; ?>;
|
||||
var formula_map = {};
|
||||
@@ -288,6 +291,7 @@
|
||||
<a href="<?php echo $server_url?>finance/manage_receipt.php?id=${r.id}" title="View receipt">
|
||||
<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_receipt(${r.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -482,6 +486,24 @@
|
||||
$(this).removeAttr('data-id');
|
||||
});
|
||||
|
||||
function delete_receipt(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this receipt? The GL entry and invoice allocations will be reversed.',
|
||||
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?>finance/api/engine/delete_receipt.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { load_receipts(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(async function() {
|
||||
flatpickr('#receipt_date', { dateFormat: 'd/m/Y', allowInput: true });
|
||||
load_departments('department_id');
|
||||
|
||||
@@ -138,6 +138,9 @@
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
|
||||
const can_delete = ['admin', 'owner'].includes(user_role);
|
||||
|
||||
var billable_documents = [];
|
||||
|
||||
function show_billing_form() {
|
||||
@@ -207,6 +210,7 @@
|
||||
<a href="<?php echo $server_url?>finance/manage_receipt_billing.php?id=${r.id}" title="View receipt billing">
|
||||
<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_billing(${r.id})"><i class="ti ti-trash fs-5"></i></a>` : ''}
|
||||
</td>
|
||||
</tr>`;
|
||||
});
|
||||
@@ -347,6 +351,24 @@
|
||||
$(this).removeAttr('data-id');
|
||||
});
|
||||
|
||||
function delete_billing(id) {
|
||||
bootbox.confirm({
|
||||
message: 'Delete this billing? All linked receipts must be deleted first.',
|
||||
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?>finance/api/engine/delete_receipt_billing.php',
|
||||
autoPrepare: false,
|
||||
checkRequired: 0,
|
||||
action: 'delete',
|
||||
data: { id: id },
|
||||
onSuccess: function() { load_billings(); }
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
flatpickr('#billing_date', { dateFormat: 'd/m/Y', allowInput: true });
|
||||
load_billings();
|
||||
|
||||
Reference in New Issue
Block a user