Version 3.0
New technologies
This commit is contained in:
@ -1,174 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use \Model;
|
||||
use ProVM\Common\Factory\Model as ModelFactory;
|
||||
use Contabilidad\Consolidado;
|
||||
use Contabilidad\Cuenta;
|
||||
use Contabilidad\Transaccion;
|
||||
|
||||
class Consolidar {
|
||||
public function __construct(ModelFactory $factory, Queuer $queuer) {
|
||||
$this->setFactory($factory);
|
||||
$this->setQueuer($queuer);
|
||||
}
|
||||
protected ModelFactory $factory;
|
||||
public function setFactory(ModelFactory $factory): Consolidar {
|
||||
$this->factory = $factory;
|
||||
return $this;
|
||||
}
|
||||
protected Queuer $queuer;
|
||||
public function setQueuer(Queuer $queuer): Consolidar {
|
||||
$this->queuer = $queuer;
|
||||
return $this;
|
||||
}
|
||||
protected $cuentas;
|
||||
public function getCuentas() {
|
||||
if ($this->cuentas === null) {
|
||||
$this->cuentas = $this->factory->find(Cuenta::class)->many();
|
||||
}
|
||||
return $this->cuentas;
|
||||
}
|
||||
|
||||
public function isConsolidado(): bool {
|
||||
$cuentas = $this->getCuentas();
|
||||
if ($cuentas === null) {
|
||||
return true;
|
||||
}
|
||||
foreach ($cuentas as $cuenta) {
|
||||
$transacciones = $cuenta->hasTransacciones();
|
||||
if (!$transacciones) {
|
||||
continue;
|
||||
}
|
||||
$pendientes = $cuenta->hasConsolidadosPending();
|
||||
if ($pendientes) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public function queue() {
|
||||
$this->queuer->queue('consolidar');
|
||||
}
|
||||
public function consolidar() {
|
||||
ini_set('max_execution_time', 60*5);
|
||||
|
||||
foreach ($this->getCuentas() as $cuenta) {
|
||||
if (!$cuenta->hasTransacciones()) {
|
||||
continue;
|
||||
}
|
||||
$first = $this->getFirst($cuenta);
|
||||
$last = $this->getLast($cuenta);
|
||||
for ($current = $first->copy()->startOfMonth(); $current < $last->copy()->addMonthWithoutOverflow()->endOfMonth(); $current = $current->copy()->addMonthWithoutOverflow()) {
|
||||
$this->consolidarCuenta($cuenta, $current);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function consolidarCuenta(Cuenta $cuenta, Carbon $mes) {
|
||||
if (!$cuenta->hasTransacciones($mes)) {
|
||||
return;
|
||||
}
|
||||
$transacciones = $this->getTransacciones($cuenta, $mes);
|
||||
if (count($transacciones) == 0) {
|
||||
return;
|
||||
}
|
||||
array_walk($transacciones, function(&$item) use ($cuenta) {
|
||||
$item->valor = $item->transformar($cuenta->moneda());
|
||||
});
|
||||
$saldo = array_reduce($transacciones, function($sum, $item) {
|
||||
return $sum + $item->valor;
|
||||
});
|
||||
if ($cuenta->tipo()->cargo()) {
|
||||
$saldo += -1;
|
||||
}
|
||||
$consolidado = $this->factory->find(Consolidado::class)->where([['cuenta_id', $cuenta->id], ['fecha', $mes->format('Y-m-1')]])->one();
|
||||
if ($consolidado === null) {
|
||||
$data = [
|
||||
'cuenta_id' => $cuenta->id,
|
||||
'fecha' => $mes->format('Y-m-1'),
|
||||
'periodo' => 'P1M',
|
||||
'saldo' => $saldo
|
||||
];
|
||||
$consolidado = $this->factory->create(Consolidado::class, $data);
|
||||
}
|
||||
$consolidado->saldo = $saldo;
|
||||
$consolidado->save();
|
||||
}
|
||||
public function getFirst(Cuenta $cuenta): ?Carbon {
|
||||
$first = [
|
||||
Model::factory(Transaccion::class)
|
||||
->select('fecha')
|
||||
->whereEqual('debito_id', $cuenta->id)
|
||||
->orderByAsc('fecha')
|
||||
->findOne(),
|
||||
Model::factory(Transaccion::class)
|
||||
->select('fecha')
|
||||
->whereEqual('credito_id', $cuenta->id)
|
||||
->orderByAsc('fecha')
|
||||
->findOne()
|
||||
];
|
||||
if (!$first[0]) {
|
||||
if (!$first[1]) {
|
||||
return null;
|
||||
}
|
||||
return $first[1]->fecha();
|
||||
}
|
||||
if (!$first[1]) {
|
||||
return $first[0]->fecha();
|
||||
}
|
||||
if ($first[0]->fecha() < $first[1]->fecha()) {
|
||||
return $first[0]->fecha();
|
||||
}
|
||||
return $first[1]->fecha();
|
||||
}
|
||||
public function getLast(Cuenta $cuenta): ?Carbon {
|
||||
$fechas = [
|
||||
Model::factory(Transaccion::class)
|
||||
->select('fecha')
|
||||
->whereEqual('debito_id', $cuenta->id)
|
||||
->orderByDesc('fecha')
|
||||
->findOne(),
|
||||
Model::factory(Transaccion::class)
|
||||
->select('fecha')
|
||||
->whereEqual('credito_id', $cuenta->id)
|
||||
->orderByDesc('fecha')
|
||||
->findOne()
|
||||
];
|
||||
if (!$fechas[0]) {
|
||||
if (!$fechas[1]) {
|
||||
return null;
|
||||
}
|
||||
return $fechas[1]->fecha();
|
||||
}
|
||||
if (!$fechas[1]) {
|
||||
return $fechas[0]->fecha();
|
||||
}
|
||||
if ($fechas[0]->fecha() > $fechas[1]->fecha()) {
|
||||
return $fechas[0]->fecha();
|
||||
}
|
||||
return $fechas[1]->fecha();
|
||||
}
|
||||
public function getTransacciones(Cuenta $cuenta, Carbon $fecha) {
|
||||
$start = $fecha->copy()->startOfMonth();
|
||||
$end = $fecha->copy()->endOfMonth();
|
||||
$debitos = Model::factory(Transaccion::class)
|
||||
->whereEqual('debito_id', $cuenta->id)
|
||||
->whereRaw("fecha BETWEEN '{$start->format('Y-m-d')}' AND '{$end->format('Y-m-d')}'")
|
||||
->findMany();
|
||||
if ($debitos) {
|
||||
array_walk($debitos, function(&$item) {
|
||||
$item->valor *= -1;
|
||||
});
|
||||
}
|
||||
$creditos = Model::factory(Transaccion::class)
|
||||
->whereEqual('credito_id', $cuenta->id)
|
||||
->whereRaw("fecha BETWEEN '{$start->format('Y-m-d')}' AND '{$end->format('Y-m-d')}'")
|
||||
->findMany();
|
||||
$transacciones = array_merge($debitos, $creditos);
|
||||
foreach ($transacciones as &$transaccion) {
|
||||
$transaccion->setFactory($this->factory);
|
||||
}
|
||||
return $transacciones;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use Contabilidad\Common\Concept\DocumentHandler;
|
||||
|
||||
class CsvHandler extends DocumentHandler {
|
||||
public function load(): ?array {
|
||||
$folder = $this->folder;
|
||||
$files = new \DirectoryIterator($folder);
|
||||
$output = [];
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir() or $file->getExtension() != 'csv') {
|
||||
continue;
|
||||
}
|
||||
$bank = 'unknown';
|
||||
$text = trim(file_get_contents($file->getRealPath()));
|
||||
if (str_contains($text, 'SCOTIABANK')) {
|
||||
$bank = 'Scotiabank';
|
||||
}
|
||||
if (str_contains($text, 'BICE')) {
|
||||
$bank = 'BICE';
|
||||
}
|
||||
$data = explode(PHP_EOL, $text);
|
||||
array_walk($data, function(&$item) {
|
||||
$item = trim($item, '; ');
|
||||
if (str_contains($item, ';') !== false) {
|
||||
$item = explode(';', $item);
|
||||
}
|
||||
});
|
||||
$output []= ['bank' => $bank, 'filename' => $file->getBasename(), 'data' => $data];
|
||||
}
|
||||
return $this->build($output);
|
||||
}
|
||||
protected function build(array $data): ?array {
|
||||
return $data;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
class DocumentHandler {
|
||||
protected array $handlers;
|
||||
public function __construct(array $handlers) {
|
||||
$this->handlers = $handlers;
|
||||
}
|
||||
public function handle(): array {
|
||||
$output = [];
|
||||
foreach ($this->handlers as $handler) {
|
||||
$output = array_merge($output, $handler->load());
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
use Nyholm\Psr7\Stream;
|
||||
|
||||
class FileHandler {
|
||||
protected $base_folder;
|
||||
protected $valid_types;
|
||||
protected $folders;
|
||||
public function __construct(object $params) {
|
||||
$this->base_folder = $params->folder;
|
||||
$this->addValidTypes(array_keys($params->types));
|
||||
$this->addFolders($params->types);
|
||||
}
|
||||
public function addFolders(array $folders): FileHandler {
|
||||
foreach ($folders as $type => $folder) {
|
||||
$this->addFolder($type, $folder);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function addFolder(string $type, string $folder): FileHandler {
|
||||
$this->folders[$type] = $folder;
|
||||
return $this;
|
||||
}
|
||||
public function addValidTypes(array $valid_types): FileHandler {
|
||||
foreach ($valid_types as $type) {
|
||||
$this->addValidType($type);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
public function addValidType(string $type): FileHandler {
|
||||
$this->valid_types []= $type;
|
||||
return $this;
|
||||
}
|
||||
public function getType(string $folder): string {
|
||||
return array_search($folder, $this->folders);
|
||||
}
|
||||
|
||||
public function uploadFile(UploadedFileInterface $file, string $new_name = null): bool {
|
||||
if ($file->getError() !== UPLOAD_ERR_OK) {
|
||||
return false;
|
||||
}
|
||||
if (!in_array($file->getClientMediaType(), $this->valid_types)) {
|
||||
return false;
|
||||
}
|
||||
if ($new_name === null) {
|
||||
$new_name = $file->getClientFilename();
|
||||
}
|
||||
$filenfo = new \SplFileInfo($file->getClientFilename());
|
||||
if (!str_contains($new_name, $filenfo->getExtension())) {
|
||||
$new_name .= '.' . $filenfo->getExtension();
|
||||
}
|
||||
$to = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $this->folders[$file->getClientMediaType()], $new_name]);
|
||||
$file->moveTo($to);
|
||||
return file_exists($to);
|
||||
}
|
||||
public function listFiles(): array {
|
||||
$output = [];
|
||||
foreach ($this->folders as $f) {
|
||||
$folder = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $f]);
|
||||
if (!file_exists($folder)) {
|
||||
continue;
|
||||
}
|
||||
$files = new \DirectoryIterator($folder);
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir()) {
|
||||
continue;
|
||||
}
|
||||
$output []= (object) ['folder' => $f, 'filename' => $file->getBasename()];
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
protected function validateFilename(string $folder, string $filename): bool|string {
|
||||
if (!in_array($folder, $this->folders)) {
|
||||
return false;
|
||||
}
|
||||
$f = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $folder, $filename]);
|
||||
if (!file_exists($f)) {
|
||||
return false;
|
||||
}
|
||||
return $f;
|
||||
}
|
||||
public function getInfo(string $folder, string $filename): \SplFileInfo|bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
return new \SplFileInfo($f);
|
||||
}
|
||||
public function getFile(string $folder, string $filename): StreamInterface|bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
return Stream::create(file_get_contents($f));
|
||||
}
|
||||
public function editFilename(string $folder, string $filename, string $new_name): bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
$info = new \SplFileInfo($f);
|
||||
$new = implode(DIRECTORY_SEPARATOR, [$this->base_folder, $folder, $new_name . '.' . $info->getExtension()]);
|
||||
return rename($f, $new);
|
||||
}
|
||||
public function deleteFile(string $folder, string $filename): bool {
|
||||
if (!$f = $this->validateFilename($folder, $filename)) {
|
||||
return false;
|
||||
}
|
||||
return unlink($f);
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use Contabilidad\Common\Concept\DocumentHandler;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class PdfHandler extends DocumentHandler {
|
||||
protected Client $client;
|
||||
protected string $url;
|
||||
public function __construct(Client $client, string $pdf_folder, string $url) {
|
||||
parent::__construct($pdf_folder);
|
||||
$this->client = $client;
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function load(): ?array {
|
||||
$folder = $this->folder;
|
||||
$files = new \DirectoryIterator($folder);
|
||||
$output = [];
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir() or $file->getExtension() != 'pdf') {
|
||||
continue;
|
||||
}
|
||||
$output []= ['filename' => $file->getBasename()];
|
||||
}
|
||||
$response = $this->client->post($this->url, ['json' => ['files' => $output]]);
|
||||
$output = json_decode($response->getBody());
|
||||
return $this->build($output);
|
||||
}
|
||||
protected function build(array $data): ?array {
|
||||
foreach ($data as &$file) {
|
||||
$i = $this->findStartRow($file->text);
|
||||
if ($i === -1) {
|
||||
continue;
|
||||
}
|
||||
$e = $this->findEndRow($file->text, $i);
|
||||
if ($e == $i) {
|
||||
continue;
|
||||
}
|
||||
$file->data = array_filter($file->text, function($key) use ($i, $e) {
|
||||
return ($key >= $i) and ($key <= $e);
|
||||
}, ARRAY_FILTER_USE_KEY);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
protected function findStartRow(array $data): int {
|
||||
foreach ($data as $i => $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$maybe = false;
|
||||
foreach ($row as $cell) {
|
||||
if (str_contains($cell, '/')) {
|
||||
$maybe = true;
|
||||
}
|
||||
if ($maybe and str_contains($cell, '$')) {
|
||||
return $i - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
protected function findEndRow(array $data, int $start): int {
|
||||
$l = count($data[$start]);
|
||||
for ($i = $start; $i < count($data); $i ++) {
|
||||
if (!is_array($data[$i])) {
|
||||
return $i - 1;
|
||||
}
|
||||
if (count($data[$i]) != $l) {
|
||||
return $i - 1;
|
||||
}
|
||||
}
|
||||
return $start;
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use ProVM\Common\Factory\Model as Factory;
|
||||
use Contabilidad\Queue;
|
||||
use Contabilidad\QueueArgument;
|
||||
|
||||
class Queuer {
|
||||
protected Factory $factory;
|
||||
public function __construct(Factory $factory) {
|
||||
$this->setFactory($factory);
|
||||
}
|
||||
public function setFactory(Factory $factory): Queuer {
|
||||
$this->factory = $factory;
|
||||
return $this;
|
||||
}
|
||||
public function queue(string $command, array $arguments = []) {
|
||||
if ($this->isProcessed($command, $arguments)) {
|
||||
return;
|
||||
}
|
||||
$queue = $this->factory->create(Queue::class, ['command' => $command, 'created' => (new \DateTime('now'))->format('Y-m-d H:i:s')]);
|
||||
$queue->save();
|
||||
if (count($arguments) > 0) {
|
||||
foreach ($arguments as $argument => $value) {
|
||||
$arg = $this->factory->create(QueueArgument::class, ['queue_id' => $queue->id, 'argument' => $argument, 'value' => $value]);
|
||||
$arg->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
public function isProcessed(string $command, array $arguments = []): bool {
|
||||
$queues = $this->find($command, $arguments);
|
||||
if ($queues == null or count($queues) === 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public function find(string $command, array $arguments = []): ?array {
|
||||
$queues = $this->factory->find(Queue::class)->where([['command', $command], ['processed', 0]])->many();
|
||||
if ($queues === null) {
|
||||
return null;
|
||||
}
|
||||
if (count($arguments) > 0) {
|
||||
$queues = array_filter($queues, function($item) use ($arguments) {return count($arguments) === count($item->matchArguments($arguments));});
|
||||
}
|
||||
return $queues;
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Exception\ServerException;
|
||||
use ProVM\Common\Factory\Model as Factory;
|
||||
use Contabilidad\Moneda;
|
||||
use Contabilidad\TipoCambio;
|
||||
|
||||
class TiposCambios {
|
||||
protected $client;
|
||||
protected $factory;
|
||||
protected $base_url;
|
||||
protected $key;
|
||||
public function __construct(Client $client, Factory $factory, $api_url, $api_key) {
|
||||
$this->client = $client;
|
||||
$this->factory = $factory;
|
||||
$this->base_url = $api_url;
|
||||
$this->key = $api_key;
|
||||
}
|
||||
protected function getWeekday(\DateTimeInterface $fecha) {
|
||||
if ($fecha->weekday() == 0) {
|
||||
return $fecha->subWeek()->weekday(5);
|
||||
}
|
||||
if ($fecha->weekday() == 6) {
|
||||
return $fecha->weekday(5);
|
||||
}
|
||||
return $fecha;
|
||||
}
|
||||
protected function getValor(\DateTimeInterface $fecha, string $moneda_codigo) {
|
||||
$data = [
|
||||
'fecha' => $fecha->format('Y-m-d'),
|
||||
'desde' => $moneda_codigo
|
||||
];
|
||||
$headers = [
|
||||
'Authorization' => "Bearer {$this->key}"
|
||||
];
|
||||
$url = implode('/', [
|
||||
$this->base_url,
|
||||
'cambio',
|
||||
'get'
|
||||
]);
|
||||
try {
|
||||
$response = $this->client->request('POST', $url, ['json' => $data, 'headers' => $headers]);
|
||||
} catch (ConnectException | RequestException | ServerException $e) {
|
||||
error_log($e);
|
||||
return null;
|
||||
}
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
error_log('Could not connect to python API.');
|
||||
return null;
|
||||
}
|
||||
$result = json_decode($response->getBody());
|
||||
if (isset($result->message) and $result->message === 'Not Authorized') {
|
||||
error_log('Not authorized for connecting to python API.');
|
||||
return null;
|
||||
}
|
||||
return $result->serie[0]->valor;
|
||||
}
|
||||
public function get(string $fecha, int $moneda_id) {
|
||||
$fecha = Carbon::parse($fecha);
|
||||
$moneda = $this->factory->find(Moneda::class)->one($moneda_id);
|
||||
if ($moneda->codigo == 'USD') {
|
||||
$fecha = $this->getWeekday($fecha);
|
||||
}
|
||||
// If a value exists in the database
|
||||
$cambio = $moneda->cambio($fecha);
|
||||
if ($cambio !== null) {
|
||||
if ($cambio->desde()->id != $moneda->id) {
|
||||
return 1 / $cambio->valor;
|
||||
}
|
||||
return $cambio->valor;
|
||||
}
|
||||
$valor = $this->getValor($fecha, $moneda->codigo);
|
||||
if ($valor === null) {
|
||||
return 1;
|
||||
}
|
||||
$data = [
|
||||
'fecha' => $fecha->format('Y-m-d H:i:s'),
|
||||
'desde_id' => $moneda->id,
|
||||
'hasta_id' => 1,
|
||||
'valor' => $valor
|
||||
];
|
||||
$tipo = TipoCambio::add($this->factory, $data);
|
||||
if ($tipo !== false and $tipo->is_new()) {
|
||||
$tipo->save();
|
||||
}
|
||||
return $valor;
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
<?php
|
||||
namespace Contabilidad\Common\Service;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\IOFactory;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
|
||||
use thiagoalessio\TesseractOCR\TesseractOCR;
|
||||
use Contabilidad\Common\Concept\DocumentHandler;
|
||||
|
||||
class XlsHandler extends DocumentHandler {
|
||||
public function load(): ?array {
|
||||
$folder = $this->folder;
|
||||
$files = new \DirectoryIterator($folder);
|
||||
$output = [];
|
||||
foreach ($files as $file) {
|
||||
if ($file->isDir() or $file->getExtension() != 'xls') {
|
||||
continue;
|
||||
}
|
||||
$reader = IOFactory::createReader(ucfirst($file->getExtension()));
|
||||
$xls = $reader->load($file->getRealPath());
|
||||
$data = [];
|
||||
$bank = 'unknown';
|
||||
for ($s = 0; $s < $xls->getSheetCount(); $s ++) {
|
||||
$sheet = $xls->getSheet($s);
|
||||
foreach ($sheet->getRowIterator() as $row) {
|
||||
$r = [];
|
||||
foreach ($row->getCellIterator() as $cell) {
|
||||
$r []= $cell->getValue();
|
||||
}
|
||||
$data []= $r;
|
||||
}
|
||||
foreach ($sheet->getDrawingCollection() as $drawing) {
|
||||
if ($drawing instanceof MemoryDrawing) {
|
||||
ob_start();
|
||||
call_user_func(
|
||||
$drawing->getRenderingFunction(),
|
||||
$drawing->getImageResource()
|
||||
);
|
||||
$imageContents = ob_get_contents();
|
||||
$size = ob_get_length();
|
||||
ob_end_clean();
|
||||
$ocr = new TesseractOCR();
|
||||
$ocr->imageData($imageContents, $size);
|
||||
$image = $ocr->run();
|
||||
if (str_contains($image, 'BICE')) {
|
||||
$bank = 'BICE';
|
||||
}
|
||||
if (str_contains($image, 'Scotiabank')) {
|
||||
$bank = 'Scotiabank';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$output []= ['bank' => $bank, 'filename' => $file->getBasename(), 'data' => $data];
|
||||
}
|
||||
return $this->build($output);
|
||||
}
|
||||
protected function build(array $data): ?array {
|
||||
return $data;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user