This commit is contained in:
2021-12-06 22:10:41 -03:00
parent 10b2485cfd
commit 8ef4ab1c7d
41 changed files with 1256 additions and 57 deletions

View File

@ -0,0 +1,49 @@
<?php
namespace Contabilidad\Common\Service;
use Psr\Http\Message\ServerRequestInterface as Request;
class Auth {
protected string $key;
public function __construct(string $api_key) {
$this->key = $api_key;
}
public function isValid(Request $request): bool {
if ($request->hasHeader('Authorization')) {
$sent_key = $this->getAuthKey($request->getHeader('Authorization'));
return $this->key == $sent_key;
}
if (isset($request->getParsedBody()['api_key'])) {
$sent_key = $request->getParsedBody()['api_key'];
return $this->key == $sent_key;
}
$post = $request->getParsedBody() ?? json_decode($request->getBody());
$sent_key = $this->getArrayKey($post);
if ($sent_key !== null) {
return $this->key == $sent_key;
}
$sent_key = $this->getArrayKey($request->getQueryParams());
return $this->key == $sent_key;
}
protected function getAuthKey($auth) {
if (is_array($auth)) {
$auth = $auth[0];
}
if (str_contains($auth, 'Bearer')) {
$auth = explode(' ', $auth)[1];
}
return $auth;
}
protected function getArrayKey($array) {
$posible_keys = [
'API_KEY',
'api_key',
];
foreach ($posible_keys as $key) {
if (isset($array[$key])) {
return $array[$key];
}
}
return null;
}
}

View File

@ -0,0 +1,37 @@
<?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;
}
}

View File

@ -0,0 +1,16 @@
<?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;
}
}

View File

@ -1,15 +1,15 @@
<?php
namespace Contabilidad\Common\Service;
use Contabilidad\Common\Concept\DocumentHandler;
use GuzzleHttp\Client;
class PdfHandler {
class PdfHandler extends DocumentHandler {
protected Client $client;
protected string $folder;
protected string $url;
public function __construct(Client $client, string $pdf_folder, string $url) {
parent::__construct($pdf_folder);
$this->client = $client;
$this->folder = $pdf_folder;
$this->url = $url;
}
@ -25,6 +25,51 @@ class PdfHandler {
}
$response = $this->client->post($this->url, ['json' => ['files' => $output]]);
$output = json_decode($response->getBody());
return $output;
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;
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace Contabilidad\Common\Service;
use Carbon\Carbon;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
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;
}
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') {
if ($fecha->weekday() == 0) {
$fecha = $fecha->subWeek()->weekday(5);
}
if ($fecha->weekday() == 6) {
$fecha = $fecha->weekday(5);
}
}
$cambio = $moneda->cambio($fecha);
if ($cambio) {
if ($cambio->desde()->id != $moneda->id) {
return 1 / $cambio->valor;
}
return $cambio->valor;
}
$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 $e) {
error_log($e);
return null;
}
if ($response->getStatusCode() !== 200) {
return null;
}
$result = json_decode($response->getBody());
$valor = $result->serie[0]->valor;
$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;
}
}

View File

@ -0,0 +1,60 @@
<?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;
}
}