Additional rules for credits

This commit is contained in:
David Bomba 2024-08-21 17:19:44 +10:00
parent c894cdff8b
commit dfca75229d
2 changed files with 312 additions and 218 deletions

View File

@ -51,36 +51,32 @@ class ProcessBankRules extends AbstractService
} }
} }
// $payment.amount => "Payment Amount", float // $payment.amount
// $payment.transaction_reference => "Payment Transaction Reference", string // $payment.transaction_reference
// $invoice.amount => "Invoice Amount", float // $payment.custom1
// $invoice.number => "Invoice Number", string // $payment.custom2
// $client.id_number => "Client ID Number", string // $payment.custom3
// $client.email => "Client Email", string // $payment.custom4
// $invoice.po_number => "Invoice Purchase Order Number", string // $invoice.amount
// $invoice.number
// $invoice.po_number
// $invoice.custom1
// $invoice.custom2
// $invoice.custom3
// $invoice.custom4
// $client.id_number
// $client.email
// $client.custom1
// $client.custom2
// $client.custom3
// $client.custom4
private function matchCredit() private function matchCredit()
{ {
$this->invoices = Invoice::query()->where('company_id', $this->bank_transaction->company_id)
->whereIn('status_id', [1,2,3])
->where('is_deleted', 0)
->get();
$invoice = $this->invoices->first(function ($value, $key) {
return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number);
});
if ($invoice) {
$this->bank_transaction->invoice_ids = $invoice->hashed_id;
$this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED;
$this->bank_transaction->save();
return;
}
$this->credit_rules = $this->bank_transaction->company->credit_rules(); $this->credit_rules = $this->bank_transaction->company->credit_rules();
//stub for credit rules foreach ($this->credit_rules as $bank_transaction_rule)
foreach ($this->credit_rules as $bank_transaction_rule) { {
$matches = 0;
if (!is_array($bank_transaction_rule['rules'])) { if (!is_array($bank_transaction_rule['rules'])) {
continue; continue;
@ -89,284 +85,378 @@ class ProcessBankRules extends AbstractService
foreach ($bank_transaction_rule['rules'] as $rule) { foreach ($bank_transaction_rule['rules'] as $rule) {
$rule_count = count($bank_transaction_rule['rules']); $rule_count = count($bank_transaction_rule['rules']);
$invoiceNumbers = false; $invoices = Invoice::query()
$invoiceNumber = false; ->withTrashed()
$invoiceAmounts = false; ->where('company_id', $this->bank_transaction->company_id)
$paymentAmounts = false; ->whereIn('status_id', [1,2,3])
$paymentReferences = false; ->where('is_deleted', 0)
$clientIdNumbers = false; ->get();
$clientEmails = false;
$invoicePONumbers = false;
if ($rule['search_key'] == '$invoice.number') { $payments = Payment::query()
->withTrashed()
->whereIn('status_id', [1,4])
->where('is_deleted', 0)
->whereNull('transaction_id')
->get();
$invoiceNumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id) match($rule['search_key']){
->whereIn('status_id', [1,2,3]) '$payment.amount' => $results = $this->searchPaymentResource('amount'),
->where('is_deleted', 0) '$payment.transaction_reference' => $results = $this->searchPaymentResource('transaction_reference'),
->get(); '$payment.custom1' => $results = $this->searchPaymentResource('custom1'),
'$payment.custom2' => $results = $this->searchPaymentResource('custom2'),
'$payment.custom3' => $results = $this->searchPaymentResource('custom3'),
'$payment.custom4' => $results = $this->searchPaymentResource('custom4'),
'$invoice.amount' => $results = $this->searchInvoiceResource('amount'),
'$invoice.number' => $results = $this->searchInvoiceResource('number'),
'$invoice.po_number' => $results = $this->searchInvoiceResource('po_number'),
'$invoice.custom1' => $results = $this->searchInvoiceResource('custom1'),
'$invoice.custom2' => $results = $this->searchInvoiceResource('custom2'),
'$invoice.custom3' => $results = $this->searchInvoiceResource('custom3'),
'$invoice.custom4' => $results = $this->searchInvoiceResource('custom4'),
'$client.id_number' => $results = $this->searchClientResource('id_number'),
'$client.email' => $results = $this->searchClientResource('email'),
'$client.custom1' => $results = $this->searchClientResource('custom1'),
'$client.custom2' => $results = $this->searchClientResource('custom2'),
'$client.custom3' => $results = $this->searchClientResource('custom3'),
'$client.custom4' => $results = $this->searchClientResource('custom4'),
};
}
$invoiceNumber = $invoiceNumbers->first(function ($value, $key) { }
return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number); }
});
if($invoiceNumber) private function searchInvoiceResource()
$matches++; {
} }
private function searchPaymentResource()
{
if ($rule['search_key'] == '$invoice.po_number') { }
$invoicePONumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id) private function searchClientResource()
->whereIn('status_id', [1,2,3]) {
->where('is_deleted', 0)
->where('po_number', $this->bank_transaction->description)
->get();
if($invoicePONumbers->count() > 0) { }
$matches++; // $payment.amount => "Payment Amount", float
} // $payment.transaction_reference => "Payment Transaction Reference", string
// $invoice.amount => "Invoice Amount", float
} // $invoice.number => "Invoice Number", string
// $client.id_number => "Client ID Number", string
if ($rule['search_key'] == '$invoice.amount') { // $client.email => "Client Email", string
// $invoice.po_number => "Invoice Purchase Order Number", string
$$invoiceAmounts = Invoice::query()->where('company_id', $this->bank_transaction->company_id)
->whereIn('status_id', [1,2,3])
->where('is_deleted', 0)
->where('amount', $rule['operator'], $this->bank_transaction->amount)
->get();
$invoiceAmounts = $this->invoices;
if($invoiceAmounts->count() > 0) {
$matches++;
}
}
if ($rule['search_key'] == '$payment.amount') {
$paymentAmounts = Payment::query()->where('company_id', $this->bank_transaction->company_id) // private function matchCredit()
->whereIn('status_id', [1,4]) // {
->where('is_deleted', 0) // $this->invoices = Invoice::query()->where('company_id', $this->bank_transaction->company_id)
->whereNull('transaction_id') // ->whereIn('status_id', [1,2,3])
->where('amount', $rule['operator'], $this->bank_transaction->amount) // ->where('is_deleted', 0)
->get(); // ->get();
// $invoice = $this->invoices->first(function ($value, $key) {
// return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number);
// });
// if ($invoice) {
// $this->bank_transaction->invoice_ids = $invoice->hashed_id;
// $this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED;
// $this->bank_transaction->save();
// return;
// }
// $this->credit_rules = $this->bank_transaction->company->credit_rules();
// //stub for credit rules
// foreach ($this->credit_rules as $bank_transaction_rule) {
// $matches = 0;
// if (!is_array($bank_transaction_rule['rules'])) {
// continue;
// }
// foreach ($bank_transaction_rule['rules'] as $rule) {
// $rule_count = count($bank_transaction_rule['rules']);
// $invoiceNumbers = false;
// $invoiceNumber = false;
// $invoiceAmounts = false;
// $paymentAmounts = false;
// $paymentReferences = false;
// $clientIdNumbers = false;
// $clientEmails = false;
// $invoicePONumbers = false;
// if ($rule['search_key'] == '$invoice.number') {
// $invoiceNumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id)
// ->whereIn('status_id', [1,2,3])
// ->where('is_deleted', 0)
// ->get();
// $invoiceNumber = $invoiceNumbers->first(function ($value, $key) {
// return str_contains($this->bank_transaction->description, $value->number) || str_contains(str_replace("\n", "", $this->bank_transaction->description), $value->number);
// });
// if($invoiceNumber)
// $matches++;
// }
// if ($rule['search_key'] == '$invoice.po_number') {
// $invoicePONumbers = Invoice::query()->where('company_id', $this->bank_transaction->company_id)
// ->whereIn('status_id', [1,2,3])
// ->where('is_deleted', 0)
// ->where('po_number', $this->bank_transaction->description)
// ->get();
// if($invoicePONumbers->count() > 0) {
// $matches++;
// }
// }
// if ($rule['search_key'] == '$invoice.amount') {
// $$invoiceAmounts = Invoice::query()->where('company_id', $this->bank_transaction->company_id)
// ->whereIn('status_id', [1,2,3])
// ->where('is_deleted', 0)
// ->where('amount', $rule['operator'], $this->bank_transaction->amount)
// ->get();
// $invoiceAmounts = $this->invoices;
// if($invoiceAmounts->count() > 0) {
// $matches++;
// }
// }
// if ($rule['search_key'] == '$payment.amount') {
// $paymentAmounts = Payment::query()->where('company_id', $this->bank_transaction->company_id)
// ->whereIn('status_id', [1,4])
// ->where('is_deleted', 0)
// ->whereNull('transaction_id')
// ->where('amount', $rule['operator'], $this->bank_transaction->amount)
// ->get();
if($paymentAmounts->count() > 0) { // if($paymentAmounts->count() > 0) {
$matches++; // $matches++;
} // }
} // }
if ($rule['search_key'] == '$payment.transaction_reference') { // if ($rule['search_key'] == '$payment.transaction_reference') {
$ref_search = $this->bank_transaction->description; // $ref_search = $this->bank_transaction->description;
switch ($rule['operator']) { // switch ($rule['operator']) {
case 'is': // case 'is':
$operator = '='; // $operator = '=';
break; // break;
case 'contains': // case 'contains':
$ref_search = "%".$ref_search."%"; // $ref_search = "%".$ref_search."%";
$operator = 'LIKE'; // $operator = 'LIKE';
break; // break;
default: // default:
$operator = '='; // $operator = '=';
break; // break;
} // }
$paymentReferences = Payment::query()->where('company_id', $this->bank_transaction->company_id) // $paymentReferences = Payment::query()->where('company_id', $this->bank_transaction->company_id)
->whereIn('status_id', [1,4]) // ->whereIn('status_id', [1,4])
->where('is_deleted', 0) // ->where('is_deleted', 0)
->whereNull('transaction_id') // ->whereNull('transaction_id')
->where('transaction_reference', $operator, $ref_search) // ->where('transaction_reference', $operator, $ref_search)
->get(); // ->get();
if($paymentReferences->count() > 0) { // if($paymentReferences->count() > 0) {
$matches++; // $matches++;
} // }
} // }
if ($rule['search_key'] == '$client.id_number') { // if ($rule['search_key'] == '$client.id_number') {
$ref_search = $this->bank_transaction->description; // $ref_search = $this->bank_transaction->description;
switch ($rule['operator']) { // switch ($rule['operator']) {
case 'is': // case 'is':
$operator = '='; // $operator = '=';
break; // break;
case 'contains': // case 'contains':
$ref_search = "%".$ref_search."%"; // $ref_search = "%".$ref_search."%";
$operator = 'LIKE'; // $operator = 'LIKE';
break; // break;
default: // default:
$operator = '='; // $operator = '=';
break; // break;
} // }
$clientIdNumbers = Client::query()->where('company_id', $this->bank_transaction->company_id) // $clientIdNumbers = Client::query()->where('company_id', $this->bank_transaction->company_id)
->where('id_number', $operator, $ref_search) // ->where('id_number', $operator, $ref_search)
->get(); // ->get();
if($clientIdNumbers->count() > 0) { // if($clientIdNumbers->count() > 0) {
$matches++; // $matches++;
} // }
} // }
if ($rule['search_key'] == '$client.email') { // if ($rule['search_key'] == '$client.email') {
$clientEmails = Client::query() // $clientEmails = Client::query()
->where('company_id', $this->bank_transaction->company_id) // ->where('company_id', $this->bank_transaction->company_id)
->whereHas('contacts', function ($q){ // ->whereHas('contacts', function ($q){
$q->where('email', $this->bank_transaction->description); // $q->where('email', $this->bank_transaction->description);
}) // })
->get(); // ->get();
if($clientEmails->count() > 0) { // if($clientEmails->count() > 0) {
$matches++; // $matches++;
} // }
if (($bank_transaction_rule['matches_on_all'] && ($matches == $rule_count)) || (!$bank_transaction_rule['matches_on_all'] && $matches > 0)) { // if (($bank_transaction_rule['matches_on_all'] && ($matches == $rule_count)) || (!$bank_transaction_rule['matches_on_all'] && $matches > 0)) {
//determine which combination has succeeded, ie link a payment / or / invoice // //determine which combination has succeeded, ie link a payment / or / invoice
$invoice_ids = null; // $invoice_ids = null;
$payment_id = null; // $payment_id = null;
if($invoiceNumber){ // if($invoiceNumber){
$invoice_ids = $invoiceNumber->hashed_id; // $invoice_ids = $invoiceNumber->hashed_id;
} // }
if($invoicePONumbers && strlen($invoice_ids ?? '') == 0){ // if($invoicePONumbers && strlen($invoice_ids ?? '') == 0){
if($clientEmails){ // @phpstan-ignore-line // if($clientEmails){ // @phpstan-ignore-line
$invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientEmails); // $invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientEmails);
} // }
if($clientIdNumbers && strlen($invoice_ids ?? '') == 0) // if($clientIdNumbers && strlen($invoice_ids ?? '') == 0)
{ // {
$invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientIdNumbers); // $invoice_ids = $this->matchInvoiceAndClient($invoicePONumbers, $clientIdNumbers);
} // }
if(strlen($invoice_ids ?? '') == 0) // if(strlen($invoice_ids ?? '') == 0)
{ // {
$invoice_ids = $invoicePONumbers->first()->hashed_id; // $invoice_ids = $invoicePONumbers->first()->hashed_id;
} // }
} // }
if($invoiceAmounts && strlen($invoice_ids ?? '') == 0) { // if($invoiceAmounts && strlen($invoice_ids ?? '') == 0) {
if($clientEmails) {// @phpstan-ignore-line // if($clientEmails) {// @phpstan-ignore-line
$invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientEmails); // $invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientEmails);
} // }
if($clientIdNumbers && strlen($invoice_ids ?? '') == 0) { // if($clientIdNumbers && strlen($invoice_ids ?? '') == 0) {
$invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientIdNumbers); // $invoice_ids = $this->matchInvoiceAndClient($invoiceAmounts, $clientIdNumbers);
} // }
if(strlen($invoice_ids ?? '') == 0) { // if(strlen($invoice_ids ?? '') == 0) {
$invoice_ids = $invoiceAmounts->first()->hashed_id; // $invoice_ids = $invoiceAmounts->first()->hashed_id;
} // }
} // }
if($paymentAmounts && strlen($invoice_ids ?? '') == 0 && is_null($payment_id)) { // if($paymentAmounts && strlen($invoice_ids ?? '') == 0 && is_null($payment_id)) {
if($clientEmails) {// @phpstan-ignore-line // if($clientEmails) {// @phpstan-ignore-line
$payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails); // $payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails);
} // }
if($clientIdNumbers && is_null($payment_id)) { // if($clientIdNumbers && is_null($payment_id)) {
$payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails); // $payment_id = $this->matchPaymentAndClient($paymentAmounts, $clientEmails);
} // }
if(is_null($payment_id)) { // if(is_null($payment_id)) {
$payment_id = $paymentAmounts->first()->id; // $payment_id = $paymentAmounts->first()->id;
} // }
} // }
if(strlen($invoice_ids ?? '') > 1 || is_int($payment_id)) // if(strlen($invoice_ids ?? '') > 1 || is_int($payment_id))
{ // {
$this->bank_transaction->payment_id = $payment_id; // $this->bank_transaction->payment_id = $payment_id;
$this->bank_transaction->invoice_ids = $invoice_ids; // $this->bank_transaction->invoice_ids = $invoice_ids;
$this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED; // $this->bank_transaction->status_id = BankTransaction::STATUS_MATCHED;
$this->bank_transaction->bank_transaction_rule_id = $bank_transaction_rule->id; // $this->bank_transaction->bank_transaction_rule_id = $bank_transaction_rule->id;
$this->bank_transaction->save(); // $this->bank_transaction->save();
} // }
} // }
} // }
} // }
} // }
} // }
private function matchPaymentAndClient($payments, $clients): ?int // private function matchPaymentAndClient($payments, $clients): ?int
{ // {
/** @var \Illuminate\Support\Collection<Payment> $payments */ // /** @var \Illuminate\Support\Collection<Payment> $payments */
foreach($payments as $payment) { // foreach($payments as $payment) {
foreach($clients as $client) { // foreach($clients as $client) {
if($payment->client_id == $client->id) { // if($payment->client_id == $client->id) {
return $payment->id; // return $payment->id;
} // }
} // }
} // }
return null; // return null;
} // }
private function matchInvoiceAndClient($invoices, $clients): ?Invoice // private function matchInvoiceAndClient($invoices, $clients): ?Invoice
{ // {
/** @var \Illuminate\Support\Collection<Invoice> $invoices */ // /** @var \Illuminate\Support\Collection<Invoice> $invoices */
foreach($invoices as $invoice) { // foreach($invoices as $invoice) {
foreach($clients as $client) { // foreach($clients as $client) {
if($invoice->client_id == $client->id) { // if($invoice->client_id == $client->id) {
return $invoice->hashed_id; // return $invoice->hashed_id;
} // }
} // }
} // }
return null; // return null;
} // }
private function matchDebit() private function matchDebit()
{ {

View File

@ -16,6 +16,10 @@ return new class extends Migration
$table->unsignedInteger('e_invoice_quota')->nullable()->index(); $table->unsignedInteger('e_invoice_quota')->nullable()->index();
}); });
Schema::table('bank_transaction_rules', function (Blueprint $table){
$table->enum('on_credit_match', ['create_payment', 'link_payment'])->default('create_payment');
});
} }
/** /**