@@ -195,6 +195,8 @@ class PaymentController extends ResourceController
|
|||||||
'amount' => $this->request->getPost('amount'),
|
'amount' => $this->request->getPost('amount'),
|
||||||
'payment_method' => $this->request->getPost('payment_method'),
|
'payment_method' => $this->request->getPost('payment_method'),
|
||||||
'reference' => $this->request->getPost('reference'),
|
'reference' => $this->request->getPost('reference'),
|
||||||
|
'school_year' => $this->schoolYear,
|
||||||
|
'update_by' => $this->loggedInUserId(),
|
||||||
'created_at' => utc_now(),
|
'created_at' => utc_now(),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -945,7 +947,7 @@ class PaymentController extends ResourceController
|
|||||||
try {
|
try {
|
||||||
// Lock invoice & get context (also ensure totals are up-to-date before validation)
|
// Lock invoice & get context (also ensure totals are up-to-date before validation)
|
||||||
$row = $this->db->query(
|
$row = $this->db->query(
|
||||||
'SELECT id, parent_id, total_amount, school_year FROM invoices WHERE id = ? FOR UPDATE',
|
'SELECT id, parent_id, invoice_number, total_amount, school_year FROM invoices WHERE id = ? FOR UPDATE',
|
||||||
[$invoiceId]
|
[$invoiceId]
|
||||||
)->getRowArray();
|
)->getRowArray();
|
||||||
|
|
||||||
@@ -1020,6 +1022,20 @@ class PaymentController extends ResourceController
|
|||||||
return redirect()->back()->with('error', 'Failed to record payment.');
|
return redirect()->back()->with('error', 'Failed to record payment.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$this->recordManualPayment(
|
||||||
|
(string)($row['invoice_number'] ?? $invoiceId),
|
||||||
|
$amount,
|
||||||
|
$paymentMethod,
|
||||||
|
$transactionId,
|
||||||
|
$checkFile,
|
||||||
|
$invYear,
|
||||||
|
$paymentDate
|
||||||
|
)) {
|
||||||
|
$this->db->transRollback();
|
||||||
|
log_message('error', '[manualPayUpdate] Failed to record manual payment audit row: ' . json_encode($this->manualPaymentModel->errors()));
|
||||||
|
return redirect()->back()->with('error', 'Payment was not recorded because the manual payment audit row could not be saved.');
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure invoice totals/balance reflect discounts and this payment
|
// Ensure invoice totals/balance reflect discounts and this payment
|
||||||
$ledger = $this->invoiceLedgerService->recalculateInvoice($invoiceId);
|
$ledger = $this->invoiceLedgerService->recalculateInvoice($invoiceId);
|
||||||
|
|
||||||
@@ -1086,6 +1102,35 @@ class PaymentController extends ResourceController
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function recordManualPayment(
|
||||||
|
string $invoiceNumber,
|
||||||
|
float $amount,
|
||||||
|
string $paymentMethod,
|
||||||
|
string $reference,
|
||||||
|
?string $proofPath,
|
||||||
|
string $schoolYear,
|
||||||
|
string $createdAt
|
||||||
|
): bool {
|
||||||
|
return (bool) $this->manualPaymentModel->insert([
|
||||||
|
'invoice_number' => $invoiceNumber,
|
||||||
|
'amount' => $amount,
|
||||||
|
'payment_method' => strtolower($paymentMethod),
|
||||||
|
'reference' => $reference,
|
||||||
|
'proof_path' => $proofPath,
|
||||||
|
'school_year' => $schoolYear,
|
||||||
|
'update_by' => $this->loggedInUserId(),
|
||||||
|
'created_at' => $createdAt,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loggedInUserId(): ?int
|
||||||
|
{
|
||||||
|
$userId = (int) (session()->get('user_id') ?? 0);
|
||||||
|
|
||||||
|
return $userId > 0 ? $userId : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function manualPayEdit()
|
public function manualPayEdit()
|
||||||
{
|
{
|
||||||
$paymentId = (int) $this->request->getPost('payment_id');
|
$paymentId = (int) $this->request->getPost('payment_id');
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class ManualPaymentModel extends Model
|
|||||||
'payment_method',
|
'payment_method',
|
||||||
'reference',
|
'reference',
|
||||||
'proof_path',
|
'proof_path',
|
||||||
'semester',
|
'update_by',
|
||||||
'school_year',
|
'school_year',
|
||||||
'created_at'];
|
'created_at'];
|
||||||
protected $validationRules = [
|
protected $validationRules = [
|
||||||
|
|||||||
@@ -94,6 +94,13 @@ class TestablePaymentController extends PaymentController
|
|||||||
|
|
||||||
class PaymentControllerRegressionTest extends CIUnitTestCase
|
class PaymentControllerRegressionTest extends CIUnitTestCase
|
||||||
{
|
{
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
session()->remove('user_id');
|
||||||
|
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
public function testRedirectPageSendsUsersBackToInvoicePaymentWithInfoMessage(): void
|
public function testRedirectPageSendsUsersBackToInvoicePaymentWithInfoMessage(): void
|
||||||
{
|
{
|
||||||
$controller = new TestablePaymentController();
|
$controller = new TestablePaymentController();
|
||||||
@@ -134,5 +141,27 @@ class PaymentControllerRegressionTest extends CIUnitTestCase
|
|||||||
$this->assertSame('proofs/check-123.pdf', $model->inserted[0]['proof_path']);
|
$this->assertSame('proofs/check-123.pdf', $model->inserted[0]['proof_path']);
|
||||||
$this->assertSame('INV-001', $model->inserted[0]['invoice_number']);
|
$this->assertSame('INV-001', $model->inserted[0]['invoice_number']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testManualPostStoresLoggedInUserIdAsUpdateBy(): void
|
||||||
|
{
|
||||||
|
session()->set('user_id', 42);
|
||||||
|
|
||||||
|
$model = new ManualPaymentModelSpy();
|
||||||
|
$controller = (new TestablePaymentController())
|
||||||
|
->setManualPaymentModel($model)
|
||||||
|
->setAttachmentService(new AttachmentServiceStub())
|
||||||
|
->setRequestObject(new PaymentRequestStub('post', [
|
||||||
|
'invoice_number' => 'INV-002',
|
||||||
|
'amount' => '75.00',
|
||||||
|
'payment_method' => 'cash',
|
||||||
|
'reference' => 'CASH-42',
|
||||||
|
]));
|
||||||
|
|
||||||
|
$response = $controller->manual();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(RedirectResponse::class, $response);
|
||||||
|
$this->assertCount(1, $model->inserted);
|
||||||
|
$this->assertSame(42, $model->inserted[0]['update_by']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user