mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-08 17:24:29 -04:00
commit
42a5cd7e69
@ -15,6 +15,7 @@ use App\Libraries\MultiDB;
|
|||||||
use App\Models\Backup;
|
use App\Models\Backup;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\Design;
|
use App\Models\Design;
|
||||||
|
use App\Models\Document;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
@ -76,29 +77,51 @@ class BackupUpdate extends Command
|
|||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
//logos
|
//logos
|
||||||
|
Company::cursor()
|
||||||
Company::query()
|
|
||||||
->cursor()
|
|
||||||
->each(function ($company){
|
->each(function ($company){
|
||||||
|
|
||||||
$logo = @file_get_contents($company->present()->logo());
|
$company_logo = $company->present()->logo();
|
||||||
|
|
||||||
|
if($company_logo == 'https://invoicing.co/images/new_logo.png')
|
||||||
|
return;
|
||||||
|
|
||||||
|
$logo = @file_get_contents($company_logo);
|
||||||
|
|
||||||
if($logo){
|
if($logo){
|
||||||
|
|
||||||
$path = str_replace("https://object.invoicing.co/", "", $company->present()->logo());
|
$path = str_replace("https://objects.invoicing.co/", "", $company->present()->logo());
|
||||||
$path = str_replace("https://v5-at-backup.us-southeast-1.linodeobjects.com/", "", $path);
|
$path = str_replace("https://v5-at-backup.us-southeast-1.linodeobjects.com/", "", $path);
|
||||||
|
|
||||||
Storage::disk($this->option('disk'))->put($path, $logo);
|
Storage::disk($this->option('disk'))->put($path, $logo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//documents
|
//documents
|
||||||
|
Document::cursor()
|
||||||
|
->each(function ($document){
|
||||||
|
|
||||||
|
$doc_bin = $document->getFile();
|
||||||
|
|
||||||
|
if($doc_bin)
|
||||||
|
Storage::disk($this->option('disk'))->put($document->url, $doc_bin);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
//backups
|
//backups
|
||||||
|
Backup::cursor()
|
||||||
|
->each(function ($backup){
|
||||||
|
|
||||||
|
$backup_bin = Storage::disk('s3')->get($backup->filename);
|
||||||
|
|
||||||
|
if($backup_bin)
|
||||||
|
Storage::disk($this->option('disk'))->put($backup->filename, $backup_bin);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,9 @@ class ProductFilters extends QueryFilters
|
|||||||
{
|
{
|
||||||
$sort_col = explode('|', $sort);
|
$sort_col = explode('|', $sort);
|
||||||
|
|
||||||
|
if(!is_array($sort_col))
|
||||||
|
return $this->builder;
|
||||||
|
|
||||||
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
return $this->builder->orderBy($sort_col[0], $sort_col[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
78
app/Helpers/Epc/EpcQrGenerator.php
Normal file
78
app/Helpers/Epc/EpcQrGenerator.php
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Helpers\Epc;
|
||||||
|
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use BaconQrCode\Renderer\ImageRenderer;
|
||||||
|
use BaconQrCode\Renderer\Image\SvgImageBackEnd;
|
||||||
|
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
|
||||||
|
use BaconQrCode\Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EpcQrGenerator.
|
||||||
|
*/
|
||||||
|
class EpcQrGenerator
|
||||||
|
{
|
||||||
|
|
||||||
|
private array $sepa = [
|
||||||
|
'serviceTag' => 'BCD',
|
||||||
|
'version' => 2,
|
||||||
|
'characterSet' => 1,
|
||||||
|
'identification' => 'SCT',
|
||||||
|
'bic' => '',
|
||||||
|
'purpose' => '',
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(protected Company $company, protected Invoice $invoice, protected float $amount){}
|
||||||
|
|
||||||
|
public function getQrCode()
|
||||||
|
{
|
||||||
|
|
||||||
|
$renderer = new ImageRenderer(
|
||||||
|
new RendererStyle(200),
|
||||||
|
new SvgImageBackEnd()
|
||||||
|
);
|
||||||
|
$writer = new Writer($renderer);
|
||||||
|
|
||||||
|
$qr = $writer->writeString($this->encodeMessage());
|
||||||
|
|
||||||
|
return "<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>
|
||||||
|
<rect x='0' y='0' width='100%'' height='100%' />{$qr}</svg>";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function encodeMessage()
|
||||||
|
{
|
||||||
|
|
||||||
|
return rtrim(implode("\n", array(
|
||||||
|
$this->sepa['serviceTag'],
|
||||||
|
sprintf('%03d', $this->sepa['version']),
|
||||||
|
$this->sepa['characterSet'],
|
||||||
|
$this->sepa['identification'],
|
||||||
|
$this->sepa['bic'],
|
||||||
|
$this->company->present()->name(),
|
||||||
|
$this->company?->custom_fields?->company1 ?: '',
|
||||||
|
$this->formatMoney($this->amount),
|
||||||
|
$this->sepa['purpose'],
|
||||||
|
substr($this->invoice->number,0,34),
|
||||||
|
substr($this->invoice->public_notes,0,139),
|
||||||
|
''
|
||||||
|
)), "\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatMoney($value) {
|
||||||
|
return sprintf('EUR%s', number_format($value, 2, '.', ''));
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ use App\Http\Requests\BankIntegration\UpdateBankIntegrationRequest;
|
|||||||
use App\Jobs\Bank\ProcessBankTransactions;
|
use App\Jobs\Bank\ProcessBankTransactions;
|
||||||
use App\Models\BankIntegration;
|
use App\Models\BankIntegration;
|
||||||
use App\Repositories\BankIntegrationRepository;
|
use App\Repositories\BankIntegrationRepository;
|
||||||
use App\Services\Bank\BankService;
|
use App\Services\Bank\BankMatchingService;
|
||||||
use App\Transformers\BankIntegrationTransformer;
|
use App\Transformers\BankIntegrationTransformer;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -27,7 +27,7 @@ use App\Http\Requests\Import\PreImportRequest;
|
|||||||
use App\Jobs\Bank\MatchBankTransactions;
|
use App\Jobs\Bank\MatchBankTransactions;
|
||||||
use App\Models\BankTransaction;
|
use App\Models\BankTransaction;
|
||||||
use App\Repositories\BankTransactionRepository;
|
use App\Repositories\BankTransactionRepository;
|
||||||
use App\Services\Bank\BankService;
|
use App\Services\Bank\BankMatchingService;
|
||||||
use App\Transformers\BankTransactionTransformer;
|
use App\Transformers\BankTransactionTransformer;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -26,7 +26,7 @@ use App\Models\Currency;
|
|||||||
use App\Models\ExpenseCategory;
|
use App\Models\ExpenseCategory;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use App\Models\Payment;
|
use App\Models\Payment;
|
||||||
use App\Services\Bank\BankService;
|
use App\Services\Bank\BankMatchingService;
|
||||||
use App\Utils\Ninja;
|
use App\Utils\Ninja;
|
||||||
use App\Utils\Traits\GeneratesCounter;
|
use App\Utils\Traits\GeneratesCounter;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
|
@ -16,7 +16,7 @@ use App\Libraries\MultiDB;
|
|||||||
use App\Models\BankIntegration;
|
use App\Models\BankIntegration;
|
||||||
use App\Models\BankTransaction;
|
use App\Models\BankTransaction;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Services\Bank\BankService;
|
use App\Services\Bank\BankMatchingService;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
@ -79,7 +79,7 @@ class ProcessBankTransactions implements ShouldQueue
|
|||||||
}
|
}
|
||||||
while($this->stop_loop);
|
while($this->stop_loop);
|
||||||
|
|
||||||
BankService::dispatch($this->company->id, $this->company->db);
|
BankMatchingService::dispatch($this->company->id, $this->company->db);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,7 +1107,7 @@ class CompanyImport implements ShouldQueue
|
|||||||
|
|
||||||
$storage_url = (object)$this->getObject('storage_url', true);
|
$storage_url = (object)$this->getObject('storage_url', true);
|
||||||
|
|
||||||
if(!Storage::exists($new_document->url)){
|
if(!Storage::exists($new_document->url) && is_string($storage_url)){
|
||||||
|
|
||||||
$url = $storage_url . $new_document->url;
|
$url = $storage_url . $new_document->url;
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
use App\Models\Filterable;
|
use App\Models\Filterable;
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
|
use App\Services\Bank\BankService;
|
||||||
use App\Utils\Traits\MakesHash;
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
@ -98,22 +99,9 @@ class BankTransaction extends BaseModel
|
|||||||
return $this->belongsTo(Account::class)->withTrashed();
|
return $this->belongsTo(Account::class)->withTrashed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function service() :BankService
|
||||||
public function matchInvoiceNumber()
|
|
||||||
{
|
{
|
||||||
|
return new BankService($this);
|
||||||
if(strlen($this->description) > 1)
|
|
||||||
{
|
|
||||||
|
|
||||||
$i = Invoice::where('company_id', $this->company_id)
|
|
||||||
->whereIn('status_id', [1,2,3])
|
|
||||||
->where('is_deleted', 0)
|
|
||||||
->where('number', 'LIKE', '%'.$this->description.'%')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
return $i ?: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -87,16 +87,19 @@ trait Utilities
|
|||||||
|
|
||||||
$error_message = '';
|
$error_message = '';
|
||||||
|
|
||||||
if (array_key_exists('actions', $_payment) && array_key_exists('response_summary', end($_payment['actions']))) {
|
if (is_array($_payment) && array_key_exists('actions', $_payment) && array_key_exists('response_summary', end($_payment['actions']))) {
|
||||||
$error_message = end($_payment['actions'])['response_summary'];
|
$error_message = end($_payment['actions'])['response_summary'];
|
||||||
} elseif (array_key_exists('status', $_payment)) {
|
} elseif (is_array($_payment) && array_key_exists('status', $_payment)) {
|
||||||
$error_message = $_payment['status'];
|
$error_message = $_payment['status'];
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$error_message = 'Error processing payment.';
|
||||||
|
}
|
||||||
|
|
||||||
$this->getParent()->sendFailureMail($error_message);
|
$this->getParent()->sendFailureMail($error_message);
|
||||||
|
|
||||||
$message = [
|
$message = [
|
||||||
'server_response' => $_payment,
|
'server_response' => $_payment ?: 'Server did not return any response. Most likely failed before payment was created.',
|
||||||
'data' => $this->getParent()->payment_hash->data,
|
'data' => $this->getParent()->payment_hash->data,
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -110,7 +113,7 @@ trait Utilities
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ($throw_exception) {
|
if ($throw_exception) {
|
||||||
throw new PaymentFailed($_payment['status'].' '.$error_message, 500);
|
throw new PaymentFailed($error_message, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ class CheckoutComPaymentDriver extends BaseDriver
|
|||||||
$this->init();
|
$this->init();
|
||||||
$this->setPaymentHash($request->getPaymentHash());
|
$this->setPaymentHash($request->getPaymentHash());
|
||||||
|
|
||||||
//11-08-2022 check the user is autenticated
|
//11-08-2022 check the user is authenticated
|
||||||
if (!Auth::guard('contact')->check()) {
|
if (!Auth::guard('contact')->check()) {
|
||||||
$client = $request->getClient();
|
$client = $request->getClient();
|
||||||
auth()->guard('contact')->loginUsingId($client->contacts()->first()->id, true);
|
auth()->guard('contact')->loginUsingId($client->contacts()->first()->id, true);
|
||||||
@ -455,6 +455,8 @@ class CheckoutComPaymentDriver extends BaseDriver
|
|||||||
return $this->processUnsuccessfulPayment($payment);
|
return $this->processUnsuccessfulPayment($payment);
|
||||||
}
|
}
|
||||||
} catch (CheckoutApiException | Exception $e) {
|
} catch (CheckoutApiException | Exception $e) {
|
||||||
|
nlog("checkout");
|
||||||
|
nlog($e->getMessage());
|
||||||
return $this->processInternallyFailedPayment($this, $e);
|
return $this->processInternallyFailedPayment($this, $e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class BankTransactionRepository extends BaseRepository
|
|||||||
|
|
||||||
$bank_transaction->save();
|
$bank_transaction->save();
|
||||||
|
|
||||||
if($bank_transaction->base_type == 'CREDIT' && $invoice = $bank_transaction->matchInvoiceNumber())
|
if($bank_transaction->base_type == 'CREDIT' && $invoice = $bank_transaction->service()->matchInvoiceNumber())
|
||||||
{
|
{
|
||||||
$bank_transaction->invoice_ids = $invoice->hashed_id;
|
$bank_transaction->invoice_ids = $invoice->hashed_id;
|
||||||
$bank_transaction->status_id = BankTransaction::STATUS_MATCHED;
|
$bank_transaction->status_id = BankTransaction::STATUS_MATCHED;
|
||||||
|
84
app/Services/Bank/BankMatchingService.php
Normal file
84
app/Services/Bank/BankMatchingService.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Bank;
|
||||||
|
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\BankTransaction;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\Invoice;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class BankMatchingService implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
private $company_id;
|
||||||
|
|
||||||
|
private Company $company;
|
||||||
|
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
private $invoices;
|
||||||
|
|
||||||
|
public $deleteWhenMissingModels = true;
|
||||||
|
|
||||||
|
public function __construct($company_id, $db)
|
||||||
|
{
|
||||||
|
$this->company_id = $company_id;
|
||||||
|
$this->db = $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
|
||||||
|
MultiDB::setDb($this->db);
|
||||||
|
|
||||||
|
$this->company = Company::find($this->company_id);
|
||||||
|
|
||||||
|
$this->invoices = Invoice::where('company_id', $this->company->id)
|
||||||
|
->whereIn('status_id', [1,2,3])
|
||||||
|
->where('is_deleted', 0)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$this->match();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function match()
|
||||||
|
{
|
||||||
|
|
||||||
|
BankTransaction::where('company_id', $this->company->id)
|
||||||
|
->where('status_id', BankTransaction::STATUS_UNMATCHED)
|
||||||
|
->cursor()
|
||||||
|
->each(function ($bt){
|
||||||
|
|
||||||
|
$invoice = $this->invoices->first(function ($value, $key) use ($bt){
|
||||||
|
|
||||||
|
return str_contains($bt->description, $value->number);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
if($invoice)
|
||||||
|
{
|
||||||
|
$bt->invoice_ids = $invoice->hashed_id;
|
||||||
|
$bt->status_id = BankTransaction::STATUS_MATCHED;
|
||||||
|
$bt->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -11,74 +11,40 @@
|
|||||||
|
|
||||||
namespace App\Services\Bank;
|
namespace App\Services\Bank;
|
||||||
|
|
||||||
use App\Libraries\MultiDB;
|
|
||||||
use App\Models\BankTransaction;
|
use App\Models\BankTransaction;
|
||||||
use App\Models\Company;
|
|
||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use Illuminate\Bus\Queueable;
|
use App\Services\Bank\ProcessBankRule;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
class BankService implements ShouldQueue
|
class BankService
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
||||||
|
|
||||||
private $company_id;
|
public function __construct(public BankTransaction $bank_transaction) {}
|
||||||
|
|
||||||
private Company $company;
|
|
||||||
|
|
||||||
private $db;
|
public function matchInvoiceNumber()
|
||||||
|
|
||||||
private $invoices;
|
|
||||||
|
|
||||||
public $deleteWhenMissingModels = true;
|
|
||||||
|
|
||||||
public function __construct($company_id, $db)
|
|
||||||
{
|
|
||||||
$this->company_id = $company_id;
|
|
||||||
$this->db = $db;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
MultiDB::setDb($this->db);
|
if(strlen($this->bank_transaction->description) > 1)
|
||||||
|
{
|
||||||
|
|
||||||
$this->company = Company::find($this->company_id);
|
$i = Invoice::where('company_id', $this->bank_transaction->company_id)
|
||||||
|
->whereIn('status_id', [1,2,3])
|
||||||
|
->where('is_deleted', 0)
|
||||||
|
->where('number', 'LIKE', '%'.$this->bank_transaction->description.'%')
|
||||||
|
->first();
|
||||||
|
|
||||||
$this->invoices = Invoice::where('company_id', $this->company->id)
|
return $i ?: false;
|
||||||
->whereIn('status_id', [1,2,3])
|
}
|
||||||
->where('is_deleted', 0)
|
|
||||||
->get();
|
return false;
|
||||||
|
|
||||||
$this->match();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function match()
|
public function processRule($rule)
|
||||||
{
|
{
|
||||||
|
(new ProcessBankRule($this->bank_transaction, $rule))->run();
|
||||||
|
|
||||||
BankTransaction::where('company_id', $this->company->id)
|
return $this;
|
||||||
->where('status_id', BankTransaction::STATUS_UNMATCHED)
|
|
||||||
->cursor()
|
|
||||||
->each(function ($bt){
|
|
||||||
|
|
||||||
$invoice = $this->invoices->first(function ($value, $key) use ($bt){
|
|
||||||
|
|
||||||
return str_contains($bt->description, $value->number);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if($invoice)
|
|
||||||
{
|
|
||||||
$bt->invoice_ids = $invoice->hashed_id;
|
|
||||||
$bt->status_id = BankTransaction::STATUS_MATCHED;
|
|
||||||
$bt->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
|
27
app/Services/Bank/ProcessBankRule.php
Normal file
27
app/Services/Bank/ProcessBankRule.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Services\Bank;
|
||||||
|
|
||||||
|
use App\Models\BankTransaction;
|
||||||
|
use App\Services\AbstractService;
|
||||||
|
|
||||||
|
class ProcessBankRule extends AbstractService
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private BankTransaction $bank_transaction, $rule){}
|
||||||
|
|
||||||
|
public function run() : void
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user