Files
streamline-emr/docker/streamline-src/Modules/Invoices/Services/InvoicesService.php
T

316 lines
14 KiB
PHP

<?php
namespace Modules\Invoices\Services;
use Carbon\Carbon;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Streamline\Models\InvoicePayment;
use Streamline\Models\InvoicePaymentRecord;
use Streamline\Models\PatientCategoryInvoice;
class InvoicesService
{
public function __construct()
{
}
/**
* @param string $invoice_number
* @param string $receipt_number
* @param int $amount_paid
* @param string $date_paid
* @param int $amount_written_off
* @param string|null $amount_written_off_at
* @param array<string, mixed> $other_parameters
* @return InvoicePaymentRecord|null
*/
public function saveInvoicePaymentRecord(
string $invoice_number, string $receipt_number, int $amount_paid, string $date_paid,
int $amount_written_off = 0, string $amount_written_off_at = null, array $other_parameters = []
): InvoicePaymentRecord | null {
$record = new InvoicePaymentRecord();
$record->invoice_number = $invoice_number;
$record->receipt_number = $receipt_number;
$record->amount_paid = $amount_paid;
$record->date_paid = Carbon::parse($date_paid)->toDateString();
$record->amount_written_off = $amount_written_off;
$record->amount_written_off_at = $amount_written_off_at;
$record->created_by = Auth::id();
foreach ($other_parameters as $key => $value) {
$record->$key = $value;
}
try {
$record->save();
return $record;
} catch (QueryException $e) {
return null;
}
}
public function updateInvoicePayment(
string $invoice_number, int $amount_paid, int $balance
): InvoicePayment | null {
$record = InvoicePayment::where('invoice_number', $invoice_number)->first();
if (!$record) {
return null;
}
$record->amount_paid = $record->amount_paid + $amount_paid;
$record->balance = $balance;
try {
$record->save();
return $record;
} catch (QueryException $e) {
return null;
}
}
public function updateInvoicePaymentRecord(
string $invoice_number, string $receipt_number, int $amount_paid, string $date_paid,
int $amount_written_off = 0, string $amount_written_off_at = null
): InvoicePaymentRecord | null {
$record = new InvoicePaymentRecord();
$record->invoice_number = $invoice_number;
$record->receipt_number = $receipt_number;
$record->amount_paid = $amount_paid;
$record->date_paid = Carbon::parse($date_paid)->toDateString();
$record->amount_written_off = $amount_written_off;
$record->amount_written_off_at = $amount_written_off_at;
$record->created_by = Auth::id();
try {
$record->save();
return $record;
} catch (QueryException $e) {
return null;
}
}
public function saveInvoicePayment(
string $invoice_number, int $total, int $amount_paid, int $balance,
string $invoice_date, string $patient_category
): InvoicePayment | null {
$record = new InvoicePayment();
$record->invoice_number = $invoice_number;
$record->total = $total;
$record->amount_paid = $amount_paid;
$record->balance = $balance;
$record->invoice_date = $invoice_date;
$record->patient_category = $patient_category;
$record->created_by = Auth::id();
try {
$record->save();
return $record;
} catch (QueryException $e) {
return null;
}
}
public function clearInvoice(string $number): void
{
$payment = InvoicePayment::where('invoice_number', $number)->first();
$invoices = PatientCategoryInvoice::where('invoice_number', $number)->get();
$counter = 1;
$total = count($invoices);
$total_invoice_amount_paid = $payment->amount_paid;
foreach ($invoices as $invoice) {
if ($total_invoice_amount_paid > $invoice->patient_amount && $counter < $total) {
PatientCategoryInvoice::where('id', $invoice->id)->update([
'amount_paid_off' => $invoice->patient_amount,
'payment_date' => Carbon::now(),
'balance_remaining' => 0, 'payment_complete' => 1
]);
$total_invoice_amount_paid -= $invoice->patient_amount;
} else {
PatientCategoryInvoice::where('id', $invoice->id)->update([
'amount_paid_off' => $total_invoice_amount_paid,
'payment_date' => Carbon::now(),
'balance_remaining' => ($invoice->patient_amount - $total_invoice_amount_paid)
]);
$total_invoice_amount_paid = 0;
}
$counter++;
if ($total_invoice_amount_paid < 1) {
break;
}
}
}
public function reverseCashReceived($receivedCashId): void
{
$invoice_payments = InvoicePaymentRecord::where('received_id', $receivedCashId)->get();
foreach ($invoice_payments as $payment) {
InvoicePaymentRecord::where('id', $payment->id)->update([
'received_id' => null,
'received_amount' => null
]);
}
}
/**
* TODO Align this function to new data structure
*
* @param $invoice_number
* @param $amount_to_reverse
* @return void
*/
public function reverseClearedInvoice($invoice_number, $amount_to_reverse)
{
//1.update the balance remaning to null, status t0 0, received to null in patient_cat_invoices table
//2.update the payment_complete to 0 on patient_cat_invoice
//loop through the paid records in patient category invoices
//delete that payment from amounts_history, date_paid_history, staff_in_charge_history etc in the invoice_payments table
$invoices = PatientCategoryInvoice::where('invoice_number', $invoice_number)->where(function ($query) {
$query->whereNotNull('balance_remaining')
->orWhere('balance_remaining', '=', 0);
})->get();
$total_invoice_amount_paid = $amount_to_reverse;
$invoice_amount_after_one_patient_bill_reduction = $total_invoice_amount_paid;
foreach ($invoices as $invoice) {
$patient_invoice_bill = $invoice->patient_amount;
if (!is_null($invoice->balance_remaining)) {
if (($invoice_amount_after_one_patient_bill_reduction > $patient_invoice_bill) || ($invoice_amount_after_one_patient_bill_reduction == $patient_invoice_bill)) {
PatientCategoryInvoice::where('id', $invoice->id)->update(['amount_paid_off' => null, 'balance_remaining' => null, 'payment_complete' => 0]);
$invoice_amount_after_one_patient_bill_reduction = $invoice_amount_after_one_patient_bill_reduction - $patient_invoice_bill;
} elseif (($invoice_amount_after_one_patient_bill_reduction < $patient_invoice_bill) && ($invoice_amount_after_one_patient_bill_reduction > 0)) {
//not sober right now, need to review this later
$balance_remaining = $patient_invoice_bill - $invoice_amount_after_one_patient_bill_reduction;
PatientCategoryInvoice::where('id', $invoice->id)->update([
'amount_paid_off' => $invoice_amount_after_one_patient_bill_reduction,
'balance_remaining' => $balance_remaining
]);
break;
}
}
}
//do the adjustments in the invoice_payments table
$invoice_payment = InvoicePayment::where('invoice_number', $invoice_number)->first();
$invoice_payment->amount_paid = $invoice_payment->amount_paid - $amount_to_reverse;
$invoice_payment->balance = $invoice_payment->balance + $amount_to_reverse;
//remove the details in receipt_number, amount_paid_history, date_paid_history, staff_incharge_history, received_id_history, received_amount_history, banked_history
$amount_paid_history_array = unserialize($invoice_payment->amount_paid_history);
$amount_to_reverse_position_offset = array_search($amount_to_reverse, $amount_paid_history_array);
$invoice_payment->amount_paid_history = remove_an_element_from_serialized_data($amount_to_reverse_position_offset, $invoice_payment->amount_paid_history);
$invoice_payment->receipt_number = remove_an_element_from_serialized_data($amount_to_reverse_position_offset, $invoice_payment->receipt_number);
$invoice_payment->date_paid_history = remove_an_element_from_serialized_data($amount_to_reverse_position_offset, $invoice_payment->date_paid_history);
$invoice_payment->staff_incharge_history = remove_an_element_from_serialized_data($amount_to_reverse_position_offset, $invoice_payment->staff_incharge_history);
$invoice_payment->received_id_history = remove_an_element_from_serialized_data($amount_to_reverse_position_offset, $invoice_payment->received_id_history);
$invoice_payment->received_amount_history = remove_an_element_from_serialized_data($amount_to_reverse_position_offset, $invoice_payment->received_amount_history);
$invoice_payment->banked_history = remove_an_element_from_serialized_data($amount_to_reverse_position_offset, $invoice_payment->banked_history);
$invoice_payment->update();
}
public function getInvoicePayments(Request $request): array
{
$results = [];
$staff_member = $request->staff_member;
$today = date('Y-m-d');
$yesterday = date('Y-m-d', strtotime("-1 days"));
$end = Carbon::parse($request->end_date)->toDateString();
$start = Carbon::parse($request->start_date)->toDateString();
$total_amount_paid = 0;
$unreceived_amount = 0;
$received_amount = 0;
if ($request->staff_member == 0) {
if ($request->dates == "today") {
$results = DB::table('invoice_payment_records')->where('date_paid', $today)->whereNull('deleted_at')->get();
} else if ($request->dates == "yesterday") {
$results = DB::table('invoice_payment_records')->where('date_paid', $yesterday)->whereNull('deleted_at')->get();
} else if ($request->dates == "custom_date") {
$results = DB::table('invoice_payment_records')->where('date_paid', $start)->whereNull('deleted_at')->get();
} else if ($request->dates == "custom_date_range") {
$results = DB::table('invoice_payment_records')->whereBetween('date_paid', [$start, $end])->whereNull('deleted_at')->get();
}
} else {
if ($request->dates == "today") {
$results = DB::table('invoice_payment_records')->where('created_by', $staff_member)->where('date_paid', $today)->whereNull('deleted_at')->get();
} else if ($request->dates == "yesterday") {
$results = DB::table('invoice_payment_records')->where('created_by', $staff_member)->where('date_paid', $yesterday)->whereNull('deleted_at')->get();
} else if ($request->dates == "custom_date") {
$results = DB::table('invoice_payment_records')->where('created_by', $staff_member)->where('date_paid', $start)->whereNull('deleted_at')->get();
} else if ($request->dates == "custom_date_range") {
$results = DB::table('invoice_payment_records')->where('created_by', $staff_member)->whereBetween('date_paid', [$start, $end])->whereNull('deleted_at')->get();
}
}
foreach ($results as $result) {
if (is_null($result->received_amount)) {
$unreceived_amount += $result->amount_paid;
} else {
$received_amount += $result->received_amount;
}
$total_amount_paid += $result->amount_paid;
}
return ['total' => $total_amount_paid, 'unreceived' => $unreceived_amount, 'received' => $received_amount];
}
function getDonorInvoicePayments($start, $end, $staff_member): array
{
if ($staff_member == 0) {
$payments = DB::table('donor_invoice_payments')->whereBetween('created_at', [$start, $end])
->whereNull('deleted_at')->get()->toArray();
} else {
$payments = DB::table('donor_invoice_payments')->whereBetween('created_at', [$start, $end])
->where('created_by', $staff_member)->whereNull('deleted_at')->get()->toArray();
}
$total_amount_paid = $received_amount = 0;
foreach ($payments as $payment) {
// get total amount paid regardless of whether its received or not.
$amount_history_array = unserialize($payment->amount_paid_history);
$received_amount_history_array = unserialize($payment->received_amount_history);
$total_amount_paid += is_array($amount_history_array) ? array_sum($amount_history_array) : 0;
// get total of payments received specifically.
if ($payment->received) {
$received_amount += is_array($received_amount_history_array) ? array_sum($received_amount_history_array) : 0;
}
}
$unreceived_amount = $total_amount_paid - $received_amount;
return [
'total' => $total_amount_paid,
'unreceived' => $unreceived_amount,
'received' => $received_amount
];
}
}