diff --git a/Dockerfile b/Dockerfile
index c8dd985..4641cd6 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -10,6 +10,7 @@ RUN pecl install xdebug-3.1.3 \
COPY ./php-errors.ini /usr/local/etc/php/conf.d/docker-php-errors.ini
COPY ./php-xdebug.ini /usr/local/etc/php/conf.d/docker-php-xdebug.ini
+COPY ./php-memory.ini /usr/local/etc/php/conf.d/docker-php-memory.ini
COPY --from=composer /usr/bin/composer /usr/bin/composer
diff --git a/api.compose.yml b/api.compose.yml
new file mode 100644
index 0000000..e6cd59b
--- /dev/null
+++ b/api.compose.yml
@@ -0,0 +1,9 @@
+services:
+ httpclient:
+ profiles:
+ - testing
+ container_name: incoviba_client
+ image: flawiddsouza/restfox
+ restart: unless-stopped
+ ports:
+ - "${HTTPCLIENT_PORT:-4004}:4004"
diff --git a/app/common/Ideal/Repository.php b/app/common/Ideal/Repository.php
index 527c6ae..af67721 100644
--- a/app/common/Ideal/Repository.php
+++ b/app/common/Ideal/Repository.php
@@ -37,6 +37,9 @@ abstract class Repository implements Define\Repository
$this->connection->execute($query, [$model->id]);
}
+ /**
+ * @throws EmptyResult
+ */
public function fetchById(int $id): Define\Model
{
$query = $this->connection->getQueryBuilder()
@@ -45,6 +48,10 @@ abstract class Repository implements Define\Repository
->where("{$this->getKey()} = ?");
return $this->fetchOne($query, [$id]);
}
+
+ /**
+ * @throws EmptyResult
+ */
public function fetchAll(null|string|array $ordering = null): array
{
$query = $this->connection->getQueryBuilder()
diff --git a/app/common/Implement/Exception/HttpResponse.php b/app/common/Implement/Exception/HttpResponse.php
index 249c7d8..542984a 100644
--- a/app/common/Implement/Exception/HttpResponse.php
+++ b/app/common/Implement/Exception/HttpResponse.php
@@ -2,12 +2,18 @@
namespace Incoviba\Common\Implement\Exception;
use Throwable;
-use HttpResponseException;
+use Exception;
-class HttpResponse extends HttpResponseException
+class HttpResponse extends Exception
{
- public function __construct($message = "", $code = 0, Throwable $previous = null)
+ public function __construct($reason = "", $message = "", $code = 0, Throwable $previous = null)
{
+ $this->reason = "HTTP Reason: {$reason}";
parent::__construct($message, $code, $previous);
}
+ protected string $reason;
+ public function getReason(): string
+ {
+ return $this->reason;
+ }
}
diff --git a/app/common/Implement/Repository/Mapper.php b/app/common/Implement/Repository/Mapper.php
index a8dc82b..d17aeaf 100644
--- a/app/common/Implement/Repository/Mapper.php
+++ b/app/common/Implement/Repository/Mapper.php
@@ -4,6 +4,7 @@ namespace Incoviba\Common\Implement\Repository;
use Error;
use Closure;
use Incoviba\Common\Define;
+use Incoviba\Common\Implement\Exception\EmptyResult;
class Mapper implements Define\Repository\Mapper
{
@@ -68,7 +69,15 @@ class Mapper implements Define\Repository\Mapper
$value = $data[$column];
if ($this->hasFunction()) {
if ($value !== null) {
- $value = ($this->function)($data);
+ try {
+ $value = ($this->function)($data);
+ } catch (EmptyResult $exception) {
+ if ($this->hasDefault()) {
+ $value = $this->default;
+ } else {
+ throw $exception;
+ }
+ }
} elseif ($this->hasDefault()) {
$value = $this->default;
}
diff --git a/app/resources/routes/02_inmobiliarias.php b/app/resources/routes/02_inmobiliarias.php
index 8991df7..ed79667 100644
--- a/app/resources/routes/02_inmobiliarias.php
+++ b/app/resources/routes/02_inmobiliarias.php
@@ -2,5 +2,15 @@
use Incoviba\Controller\Inmobiliarias;
$app->group('/inmobiliarias', function($app) {
+ $folder = implode(DIRECTORY_SEPARATOR, [__DIR__, 'inmobiliarias']);
+ if (file_exists($folder)) {
+ $files = new FilesystemIterator($folder);
+ foreach ($files as $file) {
+ if ($file->isDir()) {
+ continue;
+ }
+ include_once $file->getRealPath();
+ }
+ }
$app->get('[/]', Inmobiliarias::class);
})->add($app->getContainer()->get(Incoviba\Middleware\Authentication::class));
diff --git a/app/resources/routes/api/contabilidad/cartolas.php b/app/resources/routes/api/contabilidad/cartolas.php
index 52cdf3c..9bc2f80 100644
--- a/app/resources/routes/api/contabilidad/cartolas.php
+++ b/app/resources/routes/api/contabilidad/cartolas.php
@@ -3,6 +3,7 @@ use Incoviba\Controller\API\Contabilidad\Cartolas;
$app->group('/cartolas', function($app) {
$app->post('/procesar[/]', [Cartolas::class, 'procesar']);
+ $app->post('/importar[/]', [Cartolas::class, 'importar']);
});
$app->group('/cartola', function($app) {
$app->group('/diaria', function($app) {
diff --git a/app/resources/routes/api/contabilidad/nubox.php b/app/resources/routes/api/contabilidad/nubox.php
index 98a2836..b367ae8 100644
--- a/app/resources/routes/api/contabilidad/nubox.php
+++ b/app/resources/routes/api/contabilidad/nubox.php
@@ -1,5 +1,4 @@
group('/nubox/{inmobiliaria_rut}', function($app) {
@@ -10,5 +9,6 @@ $app->group('/nubox/{inmobiliaria_rut}', function($app) {
$app->post('/mayor[/]', [Nubox::class, 'libroMayor']);
$app->post('/diario[/]', [Nubox::class, 'libroDiario']);
});
+ $app->get('/facturas/{dia}[/]', [Nubox::class, 'facturas']);
$app->post('/cuenta', [Nubox::class, 'cuenta']);
});
diff --git a/app/resources/routes/api/contabilidad/tesoreria.php b/app/resources/routes/api/contabilidad/tesoreria.php
new file mode 100644
index 0000000..238e85d
--- /dev/null
+++ b/app/resources/routes/api/contabilidad/tesoreria.php
@@ -0,0 +1,6 @@
+group('/tesoreria', function($app) {
+ $app->post('/import[/]', [Tesoreria::class, 'import']);
+});
diff --git a/app/resources/routes/api/inmobiliarias.php b/app/resources/routes/api/inmobiliarias.php
index e751cbb..ae2e1de 100644
--- a/app/resources/routes/api/inmobiliarias.php
+++ b/app/resources/routes/api/inmobiliarias.php
@@ -15,7 +15,7 @@ $app->group('/inmobiliarias', function($app) {
$app->get('[/]', Inmobiliarias::class);
});
$app->group('/inmobiliaria/{inmobiliaria_rut}', function($app) {
- $app->post('/agentes', [Inmobiliarias::class, 'agentes']);
+ $app->post('/proveedores', [Inmobiliarias::class, 'proveedores']);
$app->get('/cuentas[/]', [Inmobiliarias::class, 'cuentas']);
$app->get('/proyectos[/]', [Inmobiliarias::class, 'proyectos']);
});
diff --git a/app/resources/routes/api/inmobiliarias/proveedores.php b/app/resources/routes/api/inmobiliarias/proveedores.php
index 9e4efef..df5ab4b 100644
--- a/app/resources/routes/api/inmobiliarias/proveedores.php
+++ b/app/resources/routes/api/inmobiliarias/proveedores.php
@@ -1,11 +1,11 @@
group('/agentes', function($app) {
+$app->group('/proveedores', function($app) {
$app->post('/add[/]', [Agentes::class, 'add']);
$app->post('/register[/]', [Agentes::class, 'register']);
$app->get('[/]', Agentes::class);
});
-$app->group('/agente/{agente_id}', function($app) {
+$app->group('/proveedor/{agente_id}', function($app) {
$app->post('/edit[/]', [Agentes::class, 'edit']);
});
diff --git a/app/resources/routes/api/inmobiliarias/sociedades.php b/app/resources/routes/api/inmobiliarias/sociedades.php
new file mode 100644
index 0000000..5ce542d
--- /dev/null
+++ b/app/resources/routes/api/inmobiliarias/sociedades.php
@@ -0,0 +1,7 @@
+group('/sociedades', function($app) {
+ $app->post('/add[/]', [Sociedades::class, 'add']);
+ $app->get('[/]', Sociedades::class);
+});
diff --git a/app/resources/routes/api/sociedades.php b/app/resources/routes/api/sociedades.php
new file mode 100644
index 0000000..7d51925
--- /dev/null
+++ b/app/resources/routes/api/sociedades.php
@@ -0,0 +1,17 @@
+group('/sociedades', function($app) {
+ $app->group('/add', function($app) {
+ $app->post('/one[/]', Sociedades::class . ':add');
+ $app->post('[/]', Sociedades::class . ':addMany');
+ });
+ $app->post('/get[/]', [Sociedades::class, 'getMany']);
+ $app->post('/edit[/]', [Sociedades::class, 'edit']);
+ $app->post('/delete[/]', [Sociedades::class, 'delete']);
+ $app->post('/asisgnar[/]', [Sociedades::class, 'asignar']);
+ $app->get('[/]', Sociedades::class);
+});
+$app->group('/sociedad/{sociedad_rut}', function($app) {
+ $app->get('[/]', Sociedades::class . ':get');
+});
diff --git a/app/resources/routes/api/ventas/facturas.php b/app/resources/routes/api/ventas/facturas.php
new file mode 100644
index 0000000..697f1b0
--- /dev/null
+++ b/app/resources/routes/api/ventas/facturas.php
@@ -0,0 +1,6 @@
+group('/facturas', function($app) {
+ $app->post('/add[/]', [Facturas::class, 'add']);
+});
diff --git a/app/resources/routes/contabilidad/cartolas.php b/app/resources/routes/contabilidad/cartolas.php
index 7bd0058..fe7a14e 100644
--- a/app/resources/routes/contabilidad/cartolas.php
+++ b/app/resources/routes/contabilidad/cartolas.php
@@ -3,4 +3,5 @@ use Incoviba\Controller\Contabilidad;
$app->group('/cartolas', function($app) {
$app->get('/diaria[/]', [Contabilidad::class, 'diaria']);
+ $app->get('/importar[/]', [Contabilidad::class, 'importar']);
});
diff --git a/app/resources/routes/contabilidad/cuadratura.php b/app/resources/routes/contabilidad/cuadratura.php
new file mode 100644
index 0000000..9572b80
--- /dev/null
+++ b/app/resources/routes/contabilidad/cuadratura.php
@@ -0,0 +1,4 @@
+get('/cuadratura[/]', [Contabilidad::class, 'cuadratura']);
diff --git a/app/resources/routes/contabilidad/informes/tesoreria.php b/app/resources/routes/contabilidad/informes/tesoreria.php
index 9cbca00..20c447e 100644
--- a/app/resources/routes/contabilidad/informes/tesoreria.php
+++ b/app/resources/routes/contabilidad/informes/tesoreria.php
@@ -1,6 +1,8 @@
group('/tesoreria', function($app) {
+ $app->get('/import[/]', [Tesoreria::class, 'import']);
$app->get('[/[{fecha}[/]]]', [Contabilidad::class, 'tesoreria']);
});
diff --git a/app/resources/routes/inmobiliarias/proveedores.php b/app/resources/routes/inmobiliarias/proveedores.php
new file mode 100644
index 0000000..37c6a52
--- /dev/null
+++ b/app/resources/routes/inmobiliarias/proveedores.php
@@ -0,0 +1,6 @@
+group('/proveedores', function($app) {
+ $app->get('[/]', Proveedores::class);
+});
diff --git a/app/resources/views/contabilidad/cartolas/diaria.blade.php b/app/resources/views/contabilidad/cartolas/diaria.blade.php
index 316246b..2988a76 100644
--- a/app/resources/views/contabilidad/cartolas/diaria.blade.php
+++ b/app/resources/views/contabilidad/cartolas/diaria.blade.php
@@ -52,8 +52,7 @@
Cargo |
Abono |
Saldo |
- Centro de Costo |
- Detalle |
+ |
Orden |
@@ -115,10 +114,85 @@
+
@endsection
@include('layout.head.styles.datatables')
@include('layout.body.scripts.datatables')
+@include('layout.body.scripts.rut')
@push('page_scripts')
+@endpush
diff --git a/app/resources/views/contabilidad/cuadratura.blade.php b/app/resources/views/contabilidad/cuadratura.blade.php
new file mode 100644
index 0000000..e833686
--- /dev/null
+++ b/app/resources/views/contabilidad/cuadratura.blade.php
@@ -0,0 +1,225 @@
+@extends('layout.base')
+
+@section('page_content')
+
+
+@endsection
+
+@include('layout.head.styles.datatables')
+@include('layout.body.scripts.datatables')
+
+@push('page_scripts')
+
+@endpush
diff --git a/app/resources/views/contabilidad/movimientos.blade.php b/app/resources/views/contabilidad/movimientos.blade.php
index 5e7713c..9ff85f1 100644
--- a/app/resources/views/contabilidad/movimientos.blade.php
+++ b/app/resources/views/contabilidad/movimientos.blade.php
@@ -71,7 +71,7 @@
-
+
diff --git a/app/resources/views/layout/body/scripts.blade.php b/app/resources/views/layout/body/scripts.blade.php
index 2522dfc..2e721d9 100644
--- a/app/resources/views/layout/body/scripts.blade.php
+++ b/app/resources/views/layout/body/scripts.blade.php
@@ -2,6 +2,11 @@
+@endpush
diff --git a/app/resources/views/ventas/facturacion/emitidas.blade.php b/app/resources/views/ventas/facturacion/emitidas.blade.php
new file mode 100644
index 0000000..e69de29
diff --git a/app/resources/views/ventas/facturacion/show.blade.php b/app/resources/views/ventas/facturacion/show.blade.php
index eed642c..3243187 100644
--- a/app/resources/views/ventas/facturacion/show.blade.php
+++ b/app/resources/views/ventas/facturacion/show.blade.php
@@ -656,9 +656,9 @@
}
add() {
return {
- propietario: ({rut, nombre, proporcion, direccion, comuna, fecha, uf}) => {
+ propietario: ({rut, nombre, proporcion, direccion, comuna, fecha}) => {
const index = this.props.propietarios.length + 1
- const propietario = new Propietario({index, rut, nombre, proporcion, direccion, comuna, fecha, uf})
+ const propietario = new Propietario({index, proporcion, rut, nombre, direccion, comuna, fecha})
this.props.propietarios.push(propietario)
this.add().factura(propietario)
return propietario
@@ -691,6 +691,47 @@
}
}
}
+ save() {
+ return {
+ factura: ({index}) => {
+ const factura = this.props.facturas[index]
+ if (factura.props.saved) {
+ return
+ }
+ const url = '{{$urls->api}}/ventas/facturas/add'
+ const method = 'post'
+ const body = new FormData()
+ body.set('venta_id', this.props.id)
+ body.set('index', (index+1).toString())
+ const data = structuredClone(factura.props)
+ delete data.index
+ data.detalle.base = data.detalle.base.toFixed(0)
+ data.detalle.terreno = data.detalle.terreno.toFixed(0)
+ data.detalle.neto = data.detalle.neto.toFixed(0)
+ data.detalle.iva = data.detalle.iva.toFixed(0)
+ data.detalle.bruto = data.detalle.bruto.toFixed(0)
+ data.detalle.total = data.detalle.total.toFixed(0)
+ data.total.neto = data.total.neto.toFixed(0)
+ data.total.exento = data.total.exento.toFixed(0)
+ data.total.iva = data.total.iva.toFixed(0)
+ data.total.total = data.total.total.toFixed(0)
+ data.fecha = [data.fecha.getFullYear(), data.fecha.getMonth()+1, data.fecha.getDate()].join('-')
+ data.uf.fecha = [data.uf.fecha.getFullYear(), data.uf.fecha.getMonth()+1, data.uf.fecha.getDate()].join('-')
+ body.set('data', JSON.stringify(data))
+ return fetchAPI(url, {method, body}).then(response => {
+ if (!response) {
+ return
+ }
+ return response.json().then(json => {
+ if (!json.saved) {
+ return
+ }
+ this.props.facturas[json.factura.index-1].props.saved = true
+ })
+ })
+ }
+ }
+ }
}
class Factura extends BaseObject {
draw() {
@@ -699,6 +740,45 @@
return '
'
},
factura: ({proyecto, propietario, unidades, terreno, venta, uf, formatters = {date, pesos, ufs, percent}}) => {
+ this.props.proporcion = propietario.props.proporcion
+ this.props.emisor = {
+ nombre: proyecto.inmobiliaria.nombre,
+ rut: proyecto.inmobiliaria.rut,
+ direccion: proyecto.direccion
+ }
+ this.props.receptor = {
+ nombre: propietario.props.nombre,
+ rut: propietario.props.rut,
+ direccion: propietario.props.direccion,
+ comuna: propietario.props.comuna
+ }
+ this.props.fecha = propietario.props.fecha
+ this.props.unidades = []
+ this.props.detalle = {
+ base: venta.base * propietario.props.proporcion,
+ terreno: venta.exento * propietario.props.proporcion,
+ neto: venta.neto * propietario.props.proporcion,
+ iva: venta.iva * propietario.props.proporcion,
+ bruto: venta.bruto * propietario.props.proporcion,
+ descuento: venta.descuento * propietario.props.proporcion,
+ total: venta.total * propietario.props.proporcion
+ }
+ this.props.total = {
+ neto: venta.neto * propietario.props.proporcion,
+ exento: venta.exento * propietario.props.proporcion,
+ iva: venta.iva * propietario.props.proporcion,
+ total: venta.total * propietario.props.proporcion,
+ }
+ this.props.uf = uf
+ unidades.forEach(unidad => {
+ const descuento = terreno.reajustado * unidad.props.prorrateo
+ const bruto = unidad.props.valor * uf.valor - descuento
+ const neto = bruto / 1.19
+ this.props.unidades.push({
+ descripcion: unidad.props.tipo + ' ' + unidad.props.descripcion + ' (UF ' + formatters.ufs.format(unidad.props.valor * propietario.props.proporcion) + ')',
+ precio: (neto * propietario.props.proporcion).toFixed(0)
+ })
+ })
return [
this.draw().divider(propietario.props.index),
'
',
@@ -707,6 +787,7 @@
this.draw().propietario({propietario, formatters}),
this.draw().table({venta, unidades, propietario, terreno, uf, formatters}),
this.draw().totales({propietario, venta, uf, formatters}),
+ this.draw().guardar({index: propietario.props.index}),
'
',
'
'
].join("\n")
@@ -868,7 +949,7 @@
'SUBTOTAL (Bruto): $' + formatters.pesos.format((venta.neto + venta.iva) * propietario.props.proporcion) + '
' +
'Mas valor terreno: $' + ((venta.exento > 0) ? formatters.pesos.format(venta.exento * propietario.props.proporcion) : emptyTerreno) + '
' +
'TOTAL (Escritura): $' + formatters.pesos.format(venta.total * propietario.props.proporcion) + '; ' + formatters.ufs.format(venta.totalUF * propietario.props.proporcion) + ' UF
' +
- 'Descuento Terreno: ' + ((venta.exento > 0) ? formatters.percent.format(venta.descuento * 100) : emptyTerreno) + '%
' +
+ 'Descuento Terreno: ' + ((venta.exento > 0) ? formatters.percent.format(venta.descuento * propietario.props.proporcion * 100) : emptyTerreno) + '%
' +
'UF (' + formatters.date.format(uf.fecha) + '): $' + formatters.ufs.format(uf.valor),
'1 UNID',
formatters.pesos.format(venta.exento * propietario.props.proporcion),
@@ -920,6 +1001,28 @@
'',
''
].join("\n")
+ },
+ guardar: ({index}) => {
+ if (this.props.saved) {
+ return [
+ '',
+ '
',
+ '
',
+ '
',
+ '',
+ 'Guardada',
+ '
',
+ '
',
+ '
'
+ ].join("\n")
+ }
+ return [
+ '',
+ '
',
+ ``,
+ '
',
+ '
'
+ ].join("\n")
}
}
}
@@ -942,6 +1045,10 @@
},
facturas: () => {
document.getElementById(this.ids.facturas).innerHTML = this.venta.draw().facturas(this.formatters)
+ $('button.guardar').click(clickEvent => {
+ const index = clickEvent.currentTarget.getAttribute('data-index')
+ facturas.venta.save().factura({index: index-1})
+ })
}
}
},
@@ -955,7 +1062,7 @@
rut: '{{$venta->proyecto()->inmobiliaria()->rut()}}',
nombre: '{{$venta->proyecto()->inmobiliaria()->nombreCompleto()}}'
},
- direccion: '{{$venta->proyecto()->direccion()->simple()}}'
+ direccion: '{{$venta->proyecto()->direccion()->simple()}}, {{$venta->proyecto()->direccion()->comuna->descripcion}}'
},
valor: {{$venta->valor}},
uf: {
@@ -990,15 +1097,35 @@
propietarios: [],
facturas: []
})
- this.venta.add().propietario({
- rut: '{{$venta->propietario()->rut()}}',
- nombre: '{{$venta->propietario()->nombreCompleto()}}',
- proporcion: 1,
- direccion: '{{$venta->propietario()->datos->direccion->simple()}}',
- comuna: '{{$venta->propietario()->datos->direccion->comuna->descripcion}}',
- fecha: new Date('{{$venta->currentEstado()->fecha->add(new DateInterval('P1D'))->format('Y-m-d')}}'),
- uf: {{$uf}}
- })
+ @if (count($facturas) > 0)
+ this.venta.props.uf = {
+ fecha: new Date('{{$facturas[0]->fechaUF->format('Y-m-d')}}'),
+ valor: {{$facturas[0]->valorUF}}
+ }
+ @foreach ($facturas as $factura)
+ this.venta.props.facturas[{{$factura->index-1}}] = new Factura(JSON.parse('{!! json_encode($factura) !!}'))
+ this.venta.props.facturas[{{$factura->index-1}}].props.saved = true
+ this.venta.props.propietarios[{{$factura->index-1}}] = new Propietario({
+ index: {{$factura->index}},
+ proporcion: {{$factura->proporcion}},
+ rut: '{{$factura->receptorRut}}',
+ nombre: '{{$factura->receptorNombre}}',
+ direccion: '{{$factura->receptorDireccion}}',
+ comuna: '{{$factura->receptorComuna}}',
+ fecha: new Date('{{$factura->fecha->format('Y-m-d')}}'),
+ })
+ @endforeach
+ @else
+ this.venta.add().propietario({
+ rut: '{{$venta->propietario()->rut()}}',
+ nombre: '{{$venta->propietario()->nombreCompleto()}}',
+ proporcion: 1,
+ direccion: '{{$venta->propietario()->datos->direccion->simple()}}',
+ comuna: '{{$venta->propietario()->datos->direccion->comuna->descripcion}}',
+ fecha: new Date('{{$venta->currentEstado()->fecha->add(new DateInterval('P1D'))->format('Y-m-d')}}'),
+ uf: {{$uf}}
+ })
+ @endif
this.draw().venta()
this.draw().facturas()
}
diff --git a/app/setup/setups/services.php b/app/setup/setups/services.php
index 2864326..0c14f39 100644
--- a/app/setup/setups/services.php
+++ b/app/setup/setups/services.php
@@ -72,8 +72,8 @@ return [
)
->register('xlsx', Incoviba\Service\Informe\Excel::class);
},
- Incoviba\Service\Contabilidad\Informe\Tesoreria\Excel::class => function(ContainerInterface $container) {
- return new Incoviba\Service\Contabilidad\Informe\Tesoreria\Excel(
+ \Incoviba\Service\Contabilidad\Informe\Tesoreria\Output\Excel::class => function(ContainerInterface $container) {
+ return new \Incoviba\Service\Contabilidad\Informe\Tesoreria\Output\Excel(
$container->get(Psr\Log\LoggerInterface::class),
$container->get('folders')->get('informes'),
$container->get(Incoviba\Service\UF::class),
diff --git a/app/src/Controller/API/Contabilidad/Cartolas.php b/app/src/Controller/API/Contabilidad/Cartolas.php
index 179c7e2..b8ad3e0 100644
--- a/app/src/Controller/API/Contabilidad/Cartolas.php
+++ b/app/src/Controller/API/Contabilidad/Cartolas.php
@@ -5,10 +5,14 @@ use DateTimeImmutable;
use Incoviba\Common\Ideal\Controller;
use Incoviba\Common\Implement\Exception\EmptyResult;
use Incoviba\Controller\API\withJson;
+use Incoviba\Model\Contabilidad\Banco;
+use Incoviba\Model\Inmobiliaria;
use Incoviba\Repository;
use Incoviba\Service;
+use PhpParser\Node\Stmt\TryCatch;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use Psr\Log\LoggerInterface;
class Cartolas extends Controller
{
@@ -95,4 +99,60 @@ class Cartolas extends Controller
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
+ public function importar(ServerRequestInterface $request, ResponseInterface $response,
+ LoggerInterface $logger,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Contabilidad\Banco $bancoRepository,
+ Repository\Inmobiliaria\Cuenta $cuentaRepository,
+ Service\Contabilidad\Cartola $cartolaService,
+ Service\Contabilidad\Movimiento $movimientoService): ResponseInterface
+ {
+ $body = $request->getParsedBody();
+ $files = $request->getUploadedFiles();
+
+ $output = [
+ 'input' => $body,
+ 'movimientos' => []
+ ];
+ if (is_array($files['file'])) {
+ foreach ($files['file'] as $i => $file) {
+ if ($file->getError() !== UPLOAD_ERR_OK) {
+ continue;
+ }
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['sociedad_rut'][$i]);
+ $banco = $bancoRepository->fetchById($body['banco_id'][$i]);
+ $movimientos = $cartolaService->process($inmobiliaria, $banco, new DateTimeImmutable($body['mes'][$i]), $file);
+ $cuenta = $cuentaRepository->fetchByInmobiliariaAndBanco($inmobiliaria->rut, $banco->id);
+ $this->addMovimientos($movimientoService, $cuenta, $movimientos);
+ $output['movimientos'] = array_merge($output['movimientos'], $movimientos);
+ } catch (EmptyResult) {}
+ }
+ } else {
+ try {
+ $inmobiliaria = $inmobiliariaRepository->fetchById($body['sociedad_rut']);
+ $banco = $bancoRepository->fetchById($body['banco_id']);
+ $movimientos = $cartolaService->process($inmobiliaria, $banco, new DateTimeImmutable($body['mes']), $files['file']);
+ $cuenta = $cuentaRepository->fetchByInmobiliariaAndBanco($inmobiliaria->rut, $banco->id);
+ $this->addMovimientos($movimientoService, $cuenta, $movimientos);
+ $output['movimientos'] = $movimientos;
+ } catch (EmptyResult) {}
+ }
+ return $this->withJson($response, $output);
+ }
+
+ protected function addMovimientos(Service\Contabilidad\Movimiento $movimientoService, Inmobiliaria\Cuenta $cuenta, array $movimientos): void
+ {
+ foreach ($movimientos as $dataMovimiento) {
+ $dataMovimiento['cuenta_id'] = $cuenta->id;
+ $dataMovimiento['centro_costo_id'] = $dataMovimiento['centro_costo'];
+ $dataMovimiento['fecha'] = new DateTimeImmutable($dataMovimiento['fecha']);
+ if (array_key_exists('rut', $dataMovimiento)) {
+ list($rut, $digito) = explode('-', $dataMovimiento['rut']);
+ $dataMovimiento['rut'] = preg_replace('/\D+/', '', $rut);
+ $dataMovimiento['digito'] = $digito;
+ }
+ $movimientoService->add($dataMovimiento);
+ }
+ }
}
diff --git a/app/src/Controller/API/Contabilidad/Movimientos.php b/app/src/Controller/API/Contabilidad/Movimientos.php
index 3daeb2d..c5030cb 100644
--- a/app/src/Controller/API/Contabilidad/Movimientos.php
+++ b/app/src/Controller/API/Contabilidad/Movimientos.php
@@ -23,29 +23,30 @@ class Movimientos extends Ideal\Controller
'movimiento_id' => $movimiento_id,
'input' => $body,
'status' => false,
- 'movimiento' => null,
- 'centro' => null,
- 'detalle' => ''
+ 'movimiento' => null
];
try {
$movimiento = $movimientoService->getById($movimiento_id);
$output['movimiento'] = $this->movimientosToArray([$movimiento])[0];
$data = [];
- if (isset($body['centro_id'])) {
- $centro = $centroCostoRepository->fetchById($body['centro_id']);
- $data['centro_costo_id'] = $centro->id;
- }
- if (isset($body['detalle'])) {
- $data['detalle'] = $body['detalle'];
+ $fieldMap = [
+ 'centro_costo_id',
+ 'categoria',
+ 'detalle',
+ 'rut',
+ 'digito',
+ 'nombres',
+ 'identificador'
+ ];
+ foreach ($fieldMap as $field) {
+ if (key_exists($field, $body)) {
+ $data[$field] = $body[$field];
+ }
}
+
$movimientoService->setDetalles($movimiento, $data);
$output['movimiento'] = $this->movimientosToArray([$movimientoService->getById($movimiento->id)])[0];
- if (isset($body['centro_id'])) {
- $output['centro'] = $centro;
- }
- if (isset($body['detalle'])) {
- $output['detalle'] = $body['detalle'];
- }
+ $output['status'] = true;
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
diff --git a/app/src/Controller/API/Contabilidad/Nubox.php b/app/src/Controller/API/Contabilidad/Nubox.php
index 2fce7b1..c554dea 100644
--- a/app/src/Controller/API/Contabilidad/Nubox.php
+++ b/app/src/Controller/API/Contabilidad/Nubox.php
@@ -120,4 +120,22 @@ class Nubox
}
return $this->withJson($response, $output);
}
+ public function facturas(ServerRequestInterface $request, ResponseInterface $response, Service\Contabilidad\Nubox $nuboxService, int $inmobiliaria_rut, string $dia): ResponseInterface
+ {
+ $output = [
+ 'inmobiliaria_rut' => $inmobiliaria_rut,
+ 'dia' => $dia,
+ 'facturas' => []
+ ];
+ try {
+ $output['facturas'] = $nuboxService->getFacturas($inmobiliaria_rut, new DateTimeImmutable($dia));
+ } catch (HttpResponse $exception) {
+ $output['error'] = [
+ 'code' => $exception->getCode(),
+ 'reason' => $exception->getReason(),
+ 'message' => $exception->getMessage(),
+ ];
+ }
+ return $this->withJson($response, $output);
+ }
}
diff --git a/app/src/Controller/API/Contabilidad/Tesoreria.php b/app/src/Controller/API/Contabilidad/Tesoreria.php
new file mode 100644
index 0000000..651cd2f
--- /dev/null
+++ b/app/src/Controller/API/Contabilidad/Tesoreria.php
@@ -0,0 +1,29 @@
+getUploadedFiles();
+ $output = [];
+ foreach ($files['file'] as $file) {
+ if ($file->getError() !== UPLOAD_ERR_OK) {
+ continue;
+ }
+ $data = $tesoreriaService->getInput()->loadFromExcel($file);
+ $tesoreriaService->getInput()->load($data);
+ $output['informes'] []= $data;
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Inmobiliarias.php b/app/src/Controller/API/Inmobiliarias.php
index 98bdd84..4c50a76 100644
--- a/app/src/Controller/API/Inmobiliarias.php
+++ b/app/src/Controller/API/Inmobiliarias.php
@@ -55,27 +55,33 @@ class Inmobiliarias
} catch (EmptyResult) {}
return $this->withJson($response, $output);
}
- public function agentes(ServerRequestInterface $request, ResponseInterface $response,
- Repository\Inmobiliaria $inmobiliariaRepository,
- Repository\Inmobiliaria\SociedadAgente $sociedadAgenteRepository,
- Repository\Inmobiliaria\TipoAgente $tipoAgenteRepository,
- int $inmobiliaria_rut): ResponseInterface
+ public function proveedores(ServerRequestInterface $request, ResponseInterface $response,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Inmobiliaria\SociedadAgente $sociedadAgenteRepository,
+ Repository\Inmobiliaria\TipoAgente $tipoAgenteRepository,
+ int $inmobiliaria_rut): ResponseInterface
{
$input = $request->getParsedBody();
$output = [
'sociedad_rut' => $inmobiliaria_rut,
'input' => $input,
'sociedad' => null,
- 'agentes' => []
+ 'proveedores' => []
];
try {
$inmobiliaria = $inmobiliariaRepository->fetchById($inmobiliaria_rut);
$output['sociedad'] = $inmobiliaria;
if (isset($input['tipo_agente_id'])) {
$tipo = $tipoAgenteRepository->fetchById($input['tipo_agente_id']);
- $output['agentes'] = $sociedadAgenteRepository->fetchBySociedadAndTipo($inmobiliaria->rut, $tipo->id);
+ $proveedores = $sociedadAgenteRepository->fetchBySociedadAndTipo($inmobiliaria->rut, $tipo->id);
} else {
- $output['agentes'] = $sociedadAgenteRepository->fetchBySociedad($inmobiliaria->rut);
+ $proveedores = $sociedadAgenteRepository->fetchBySociedad($inmobiliaria->rut);
+ }
+ $output['proveedores'] = json_decode(json_encode($proveedores), JSON_OBJECT_AS_ARRAY);
+ foreach ($proveedores as $i => $proveedor) {
+ $output['proveedores'][$i]['sociedad'] = $proveedor->sociedad;
+ $output['proveedores'][$i]['proveedor'] = $proveedor->agenteTipo->agente;
+ $output['proveedores'][$i]['tipo'] = $proveedor->agenteTipo->tipoAgente;
}
} catch (EmptyResult) {}
return $this->withJson($response, $output);
diff --git a/app/src/Controller/API/Inmobiliarias/Sociedades.php b/app/src/Controller/API/Inmobiliarias/Sociedades.php
new file mode 100644
index 0000000..8c4d693
--- /dev/null
+++ b/app/src/Controller/API/Inmobiliarias/Sociedades.php
@@ -0,0 +1,35 @@
+getParsedBody();
+ $output = [
+ 'input' => $input,
+ 'sociedad' => null
+ ];
+ try {
+ $data = json_decode($input, true);
+ $contacto = $personaService->add($data['contacto']);
+ $data['contacto_rut'] = $contacto->rut;
+ unset($data['contacto']);
+ $output['sociedad'] = $sociedadService->add($data);
+ } catch (EmptyResult) {
+ $output['error'] = 'No se pudo agregar la sociedad';
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Sociedades.php b/app/src/Controller/API/Sociedades.php
new file mode 100644
index 0000000..50577f7
--- /dev/null
+++ b/app/src/Controller/API/Sociedades.php
@@ -0,0 +1,132 @@
+ $sociedadService->getAll('nombre'),
+ ];
+ return $this->withJson($response, $output);
+ }
+ public function getMany(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService): ResponseInterface
+ {
+ $input = $request->getParsedBody();
+ $output = [
+ 'input' => $input,
+ 'sociedades' => [],
+ ];
+ foreach ($input['sociedades_ruts'] as $rut) {
+ $sociedad = $sociedadService->getByRut($rut);
+ if ($sociedad === null) {
+ continue;
+ }
+ $output['sociedades'][] = $sociedad;
+ }
+ return $this->withJson($response, $output);
+ }
+ public function get(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService, int $sociedad_rut): ResponseInterface
+ {
+ $output = [
+ 'sociedad_rut' => $sociedad_rut,
+ 'sociedad' => $sociedadService->getByRut($sociedad_rut),
+ ];
+ return $this->withJson($response, $output);
+ }
+ public function add(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService): ResponseInterface
+ {
+ $input = $request->getParsedBody();
+ $output = [
+ 'input' => $input,
+ 'sociedad' => $sociedadService->add($input),
+ ];
+ return $this->withJson($response, $output);
+ }
+ public function addMany(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService, Service\Persona $personaService): ResponseInterface
+ {
+ $input = $request->getParsedBody();
+ $output = [
+ 'input' => $input,
+ 'sociedades' => [],
+ ];
+ try {
+ if (json_decode($input) !== null) {
+ $input = json_decode($input, true);
+ }
+ } catch (\TypeError) {}
+ foreach ($input['sociedades'] as $sociedadData) {
+ try {
+ if (json_decode($sociedadData) !== null) {
+ $sociedadData = json_decode($sociedadData, true);
+ }
+ } catch (\TypeError) {}
+ $contacto = $personaService->add($sociedadData['contacto']);
+ $sociedadData['contacto_rut'] = $contacto->rut;
+ unset($sociedadData['contacto']);
+ $sociedad = $sociedadService->add($sociedadData);
+ if ($sociedad === null) {
+ continue;
+ }
+ $output['sociedades'][] = $sociedad;
+ }
+ return $this->withJson($response, $output);
+ }
+ public function edit(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService): ResponseInterface
+ {
+ $input = $request->getParsedBody();
+ $output = [
+ 'input' => $input,
+ 'sociedades' => [],
+ ];
+ foreach ($input['sociedades'] as $sociedadData) {
+ $sociedad = $sociedadService->edit($sociedadData['rut'], $sociedadData);
+ if ($sociedad === null) {
+ continue;
+ }
+ $output['sociedades'][] = $sociedad;
+ }
+ return $this->withJson($response, $output);
+ }
+ public function delete(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService): ResponseInterface
+ {
+ $input = $request->getParsedBody();
+ $output = [
+ 'input' => $input,
+ 'sociedades' => [],
+ ];
+ foreach ($input['sociedades_ruts'] as $rut) {
+ $sociedad = $sociedadService->getByRut($rut);
+ $deleted = $sociedadService->delete($rut);
+ $output['sociedades'][] = [
+ 'sociedad' => $sociedad,
+ 'deleted' => $deleted,
+ ];
+ }
+ return $this->withJson($response, $output);
+ }
+
+ public function asignar(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService): ResponseInterface
+ {
+ $input = $request->getParsedBody();
+ $output = [
+ 'input' => $input,
+ 'proveedores' => [],
+ ];
+ foreach ($input['proveedores'] as $proveedorData) {
+ $proveedor = $sociedadService->asignar($proveedorData['inmobiliaria_rut'], $proveedorData['sociedad_rut']);
+ if ($proveedor === null) {
+ continue;
+ }
+ $output['proveedores'][] = $proveedor;
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/API/Ventas/Facturas.php b/app/src/Controller/API/Ventas/Facturas.php
new file mode 100644
index 0000000..19c4ff2
--- /dev/null
+++ b/app/src/Controller/API/Ventas/Facturas.php
@@ -0,0 +1,32 @@
+getParsedBody();
+ $output = [
+ 'input' => $data,
+ 'factura' => null,
+ 'saved' => false
+ ];
+ try {
+ $output['factura'] = $facturaService->add($data);
+ $output['saved'] = true;
+ } catch (Implement\Exception\EmptyResult) {
+ $output['error'] = 'No se pudo agregar la factura';
+ return $this->withJson($response, $output, 400);
+ }
+ return $this->withJson($response, $output);
+ }
+}
diff --git a/app/src/Controller/Contabilidad.php b/app/src/Controller/Contabilidad.php
index fc5aa54..9b4160c 100644
--- a/app/src/Controller/Contabilidad.php
+++ b/app/src/Controller/Contabilidad.php
@@ -34,6 +34,20 @@ class Contabilidad extends Controller
$centrosCostos = $centroCostoRepository->fetchAll();
return $view->render($response, 'contabilidad.cartolas.diaria', compact('inmobiliarias', 'centrosCostos'));
}
+ public function importar(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Repository\Inmobiliaria $inmobiliariaRepository,
+ Repository\Contabilidad\Banco $bancoRepository): ResponseInterface
+ {
+ $inmobiliarias = [];
+ try {
+ $inmobiliarias = $inmobiliariaRepository->fetchAll('razon');
+ } catch (EmptyResult) {}
+ $bancos = [];
+ try {
+ $bancos = $bancoRepository->fetchAll('nombre');
+ } catch (EmptyResult) {}
+ return $view->render($response, 'contabilidad.cartolas.import', compact('inmobiliarias', 'bancos'));
+ }
public function depositos(ServerRequestInterface $request, ResponseInterface $response, View $view,
Service\Redis $redisService,
Repository\Inmobiliaria $inmobiliariaRepository,
@@ -68,7 +82,7 @@ class Contabilidad extends Controller
string $fecha = 'today'): ResponseInterface
{
$fecha = new DateTimeImmutable($fecha);
- $anterior = $contabilidadService->getAnterior($fecha);
+ $anterior = $contabilidadService->getOutput()->getAnterior($fecha);
$yesterday = new DateTimeImmutable('yesterday');
$siguiente = null;
if ($yesterday > $fecha) {
@@ -77,10 +91,16 @@ class Contabilidad extends Controller
$siguiente = $fecha->add(new DateInterval('P3D'));
}
}
- $informes = $contabilidadService->build($fecha);
+ $informes = $contabilidadService->getOutput()->build($fecha);
$filename = "Informe de Tesorería {$fecha->format('d.m.Y')}";
return $view->render($response, 'contabilidad.informes.tesoreria', compact('fecha', 'anterior', 'siguiente', 'informes', 'filename'));
}
+ /*public function semanal(ServerRequestInterface $request, ResponseInterface $response, View $view,
+ Service\Contabilidad\Informe\Semanal $semanalService,
+ string $fecha = 'today'): ResponseInterface
+ {
+
+ }*/
public function cuadratura(ServerRequestInterface $request, ResponseInterface $response, View $view,
Repository\Inmobiliaria $inmobiliariaRepository): ResponseInterface
{
diff --git a/app/src/Controller/Contabilidad/Informes.php b/app/src/Controller/Contabilidad/Informes.php
index 6f3dc14..203dcf5 100644
--- a/app/src/Controller/Contabilidad/Informes.php
+++ b/app/src/Controller/Contabilidad/Informes.php
@@ -13,7 +13,7 @@ class Informes extends Ideal\Controller
{
$fecha = new DateTimeImmutable($fecha);
- $tesoreriaService->buildInforme($fecha, $tesoreriaService->build($fecha));
+ $tesoreriaService->getOutput()->buildInforme($fecha, $tesoreriaService->getOutput()->build($fecha));
$response->getBody()->write(file_get_contents('php://output'));
return $response;
}
diff --git a/app/src/Controller/Contabilidad/Tesoreria.php b/app/src/Controller/Contabilidad/Tesoreria.php
new file mode 100644
index 0000000..fe3924a
--- /dev/null
+++ b/app/src/Controller/Contabilidad/Tesoreria.php
@@ -0,0 +1,14 @@
+render($response, 'contabilidad.tesoreria.import');
+ }
+}
diff --git a/app/src/Controller/Inmobiliarias/Proveedores.php b/app/src/Controller/Inmobiliarias/Proveedores.php
new file mode 100644
index 0000000..09d736e
--- /dev/null
+++ b/app/src/Controller/Inmobiliarias/Proveedores.php
@@ -0,0 +1,27 @@
+getAll('nombre');
+ } catch (EmptyResult) {}
+ $tiposSociedades = [];
+ try {
+ $tiposSociedades = $tipoSociedad->fetchAll('descripcion');
+ } catch (EmptyResult) {}
+ return $view->render($response, 'inmobiliarias.proveedores', compact('sociedades', 'tiposSociedades'));
+ }
+}
diff --git a/app/src/Controller/Ventas/Facturacion.php b/app/src/Controller/Ventas/Facturacion.php
index 0b5a689..868826c 100644
--- a/app/src/Controller/Ventas/Facturacion.php
+++ b/app/src/Controller/Ventas/Facturacion.php
@@ -26,9 +26,10 @@ class Facturacion extends Ideal\Controller
* @throws Exception
*/
public function show(ServerRequestInterface $request, ResponseInterface $response, View $view,
- Service\Venta $ventaService, Service\Proyecto\Terreno $terrenoService,
- Service\IPC $ipcService, Service\UF $ufService,
- int $venta_id): ResponseInterface
+ Service\Venta $ventaService, Service\Proyecto\Terreno $terrenoService,
+ Service\IPC $ipcService, Service\UF $ufService,
+ Service\Venta\Factura $facturasService,
+ int $venta_id): ResponseInterface
{
$venta = $ventaService->getById($venta_id);
$uf = $ufService->get($venta->currentEstado()->fecha);
@@ -48,7 +49,8 @@ class Facturacion extends Ideal\Controller
$ipc = $ipcService->get($prevMonthTerreno, $prevMonth);
}
}
+ $facturas = $facturasService->getByVenta($venta->id);
- return $view->render($response, 'ventas.facturacion.show', compact('venta', 'terreno', 'uf', 'ipc'));
+ return $view->render($response, 'ventas.facturacion.show', compact('venta', 'terreno', 'uf', 'ipc', 'facturas'));
}
}
diff --git a/app/src/Model/Contabilidad/Movimiento.php b/app/src/Model/Contabilidad/Movimiento.php
index 8bb0b91..1f4adbf 100644
--- a/app/src/Model/Contabilidad/Movimiento.php
+++ b/app/src/Model/Contabilidad/Movimiento.php
@@ -4,8 +4,8 @@ namespace Incoviba\Model\Contabilidad;
use DateTimeInterface;
use Incoviba\Common\Ideal;
use Incoviba\Common\Implement\Exception\EmptyResult;
+use Incoviba\Model\Contabilidad\Movimiento\Detalle;
use Incoviba\Model\Inmobiliaria;
-use Incoviba\Model\Movimiento\Detalle;
class Movimiento extends Ideal\Model
{
@@ -21,15 +21,20 @@ class Movimiento extends Ideal\Model
public function getDetalles(): ?Detalle
{
if (!isset($this->detalles)) {
- try {
- $this->detalles = $this->runFactory('detalles');
- } catch (EmptyResult) {
- $this->detalles = null;
- }
+ $this->detalles = $this->runFactory('detalles');
}
return $this->detalles;
}
+ /*protected ?array $auxiliares;
+ public function getAuxiliares(): ?array
+ {
+ if (!isset($this->auxiliares)) {
+ $this->auxiliares = $this->runFactory('auxiliares');
+ }
+ return $this->auxiliares;
+ }*/
+
public function jsonSerialize(): mixed
{
return array_merge(parent::jsonSerialize(), [
@@ -40,7 +45,8 @@ class Movimiento extends Ideal\Model
'cargo' => $this->cargo,
'abono' => $this->abono,
'saldo' => $this->saldo,
- 'detalles' => $this->getDetalles() ?? null
+ 'detalles' => $this->getDetalles(),
+ //'auxiliares' => $this->getAuxiliares()
]);
}
}
diff --git a/app/src/Model/Contabilidad/Movimiento/Auxiliar.php b/app/src/Model/Contabilidad/Movimiento/Auxiliar.php
new file mode 100644
index 0000000..afbfe0a
--- /dev/null
+++ b/app/src/Model/Contabilidad/Movimiento/Auxiliar.php
@@ -0,0 +1,36 @@
+detalles)) {
+ try {
+ $this->detalles = $this->runFactory('detalles');
+ } catch (Implement\Exception\EmptyResult) {
+ $this->detalles = null;
+ }
+ }
+ return $this->detalles;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'movimiento_id' => $this->movimiento->id,
+ 'cargo' => $this->cargo,
+ 'abono' => $this->abono,
+ 'detalles' => $this->getDetalles()
+ ]);
+ }
+}
diff --git a/app/src/Model/Contabilidad/Movimiento/Auxiliar/Detalle.php b/app/src/Model/Contabilidad/Movimiento/Auxiliar/Detalle.php
new file mode 100644
index 0000000..ea2e854
--- /dev/null
+++ b/app/src/Model/Contabilidad/Movimiento/Auxiliar/Detalle.php
@@ -0,0 +1,39 @@
+rut . '-' . $this->digito;
+ }
+ public function rutFormatted(): string
+ {
+ return number_format($this->rut, 0, ',', '.') . '-' . $this->digito;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'auxiliar_id' => $this->auxiliar->id,
+ 'centro_costo' => $this->centroCosto,
+ 'rut' => $this->rut,
+ 'digito' => $this->digito,
+ 'nombre' => $this->nombre,
+ 'categoria' => $this->categoria,
+ 'detalle' => $this->detalle,
+ 'rutFormatted' => $this->rutFormatted(),
+ ];
+ }
+}
diff --git a/app/src/Model/Contabilidad/Movimiento/Detalle.php b/app/src/Model/Contabilidad/Movimiento/Detalle.php
new file mode 100644
index 0000000..8fabd68
--- /dev/null
+++ b/app/src/Model/Contabilidad/Movimiento/Detalle.php
@@ -0,0 +1,41 @@
+rut . '-' . $this->digito;
+ }
+ public function rutFormatted(): string
+ {
+ return number_format($this->rut, 0, ',', '.') . '-' . $this->digito;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'movimiento_id' => $this->movimiento->id,
+ 'centro_costo' => $this->centroCosto,
+ 'rut' => $this->rut,
+ 'digito' => $this->digito,
+ 'nombres' => $this->nombres,
+ 'categoria' => $this->categoria,
+ 'detalle' => $this->detalle,
+ 'identificador' => $this->identificador,
+ 'rutFormatted' => $this->rutFormatted()
+ ];
+ }
+}
diff --git a/app/src/Model/DatosPersona.php b/app/src/Model/DatosPersona.php
new file mode 100644
index 0000000..c27f0d0
--- /dev/null
+++ b/app/src/Model/DatosPersona.php
@@ -0,0 +1,32 @@
+ $this->direccion,
+ 'telefono' => $this->telefono,
+ 'email' => $this->email,
+ 'fechaNacimiento' => $this->fechaNacimiento,
+ 'sexo' => $this->sexo,
+ 'estadoCivil' => $this->estadoCivil,
+ 'nacionalidad' => $this->nacionalidad,
+ 'profesion' => $this->profesion,
+ ];
+ }
+}
diff --git a/app/src/Model/Inmobiliaria/Proveedor.php b/app/src/Model/Inmobiliaria/Proveedor.php
new file mode 100644
index 0000000..ccb8934
--- /dev/null
+++ b/app/src/Model/Inmobiliaria/Proveedor.php
@@ -0,0 +1,29 @@
+tipos)) {
+ $this->tipos = $this->runFactory('tipos');
+ }
+ return $this->tipos;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'inmobiliaria' => $this->inmobiliaria,
+ 'sociedad' => $this->sociedad,
+ 'tipos' => $this->tipos(),
+ ]);
+ }
+}
diff --git a/app/src/Model/Movimiento/Detalle.php b/app/src/Model/Movimiento/Detalle.php
deleted file mode 100644
index 96a75d5..0000000
--- a/app/src/Model/Movimiento/Detalle.php
+++ /dev/null
@@ -1,21 +0,0 @@
- $this->movimiento->id,
- 'centro_costo' => $this->centroCosto,
- 'detalle' => $this->detalle
- ];
- }
-}
diff --git a/app/src/Model/Persona.php b/app/src/Model/Persona.php
new file mode 100644
index 0000000..7e0c59a
--- /dev/null
+++ b/app/src/Model/Persona.php
@@ -0,0 +1,46 @@
+nombres . ' ' . $this->apellidoPaterno . ' ' . $this->apellidoMaterno;
+ }
+
+ public function rutCompleto(): string
+ {
+ return number_format($this->rut, 0, ',', '.') . '-' . $this->digito;
+ }
+
+ protected ?DatosPersona $datos;
+ public function datos(): ?DatosPersona
+ {
+ if (!isset($this->datos)) {
+ $this->datos = $this->runFactory('datos');
+ }
+ return $this->datos;
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'rut' => $this->rut,
+ 'digito' => $this->digito,
+ 'nombres' => $this->nombres,
+ 'apellidoPaterno' => $this->apellidoPaterno,
+ 'apellidoMaterno' => $this->apellidoMaterno,
+ 'nombreCompleto' => $this->nombreCompleto(),
+ 'rutCompleto' => $this->rutCompleto(),
+ 'datos' => $this->datos(),
+ ];
+ }
+}
diff --git a/app/src/Model/Sociedad.php b/app/src/Model/Sociedad.php
new file mode 100644
index 0000000..4e443cc
--- /dev/null
+++ b/app/src/Model/Sociedad.php
@@ -0,0 +1,33 @@
+razonSocial, $this->tipoSociedad->descripcion]);
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return [
+ 'rut' => $this->rut,
+ 'digito' => $this->digito,
+ 'nombre' => $this->nombre,
+ 'razonSocial' => $this->razonSocial,
+ 'tipoSociedad' => $this->tipoSociedad,
+ 'contacto' => $this->contacto,
+ 'nombreCompleto' => $this->nombreCompleto(),
+ ];
+ }
+}
diff --git a/app/src/Model/Venta/Factura.php b/app/src/Model/Venta/Factura.php
new file mode 100644
index 0000000..cb0b259
--- /dev/null
+++ b/app/src/Model/Venta/Factura.php
@@ -0,0 +1,86 @@
+estados)) {
+ $this->estados = $this->runFactory('estados');
+ }
+ return $this->estados ?? [];
+ }
+
+ public function jsonSerialize(): mixed
+ {
+ return array_merge(parent::jsonSerialize(), [
+ 'venta_id' => $this->venta->id,
+ 'index' => $this->index,
+ 'proporcion' => $this->proporcion,
+ 'emisor' => [
+ 'rut' => $this->emisorRut,
+ 'nombre' => $this->emisorNombre,
+ 'direccion' => $this->emisorDireccion
+ ],
+ 'receptor' => [
+ 'rut' => $this->receptorRut,
+ 'nombre' => $this->receptorNombre,
+ 'direccion' => $this->receptorDireccion,
+ 'comuna' => $this->receptorComuna
+ ],
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'unidades' => $this->unidades,
+ 'detalle' => [
+ 'base' => $this->detalleBase,
+ 'terreno' => $this->detalleTerreno,
+ 'neto' => $this->detalleNeto,
+ 'iva' => $this->detalleIva,
+ 'bruto' => $this->detalleBruto,
+ 'descuento' => $this->detalleDescuento,
+ 'total' => $this->detalleTotal
+ ],
+ 'total' => [
+ 'neto' => $this->totalNeto,
+ 'exento' => $this->totalExento,
+ 'iva' => $this->totalIva,
+ 'total' => $this->totalTotal
+ ],
+ 'uf' => [
+ 'fecha' => $this->fechaUF->format('Y-m-d'),
+ 'valor' => $this->valorUF
+ ],
+ 'estados' => $this->estados()
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Factura/Estado.php b/app/src/Model/Venta/Factura/Estado.php
new file mode 100644
index 0000000..3bae576
--- /dev/null
+++ b/app/src/Model/Venta/Factura/Estado.php
@@ -0,0 +1,22 @@
+ $this->factura->id,
+ 'fecha' => $this->fecha->format('Y-m-d'),
+ 'tipo' => $this->tipo
+ ]);
+ }
+}
diff --git a/app/src/Model/Venta/Factura/Estado/Tipo.php b/app/src/Model/Venta/Factura/Estado/Tipo.php
new file mode 100644
index 0000000..f53b978
--- /dev/null
+++ b/app/src/Model/Venta/Factura/Estado/Tipo.php
@@ -0,0 +1,7 @@
+update($model, ['nombre'], $new_data);
}
+
+ public function fetchByNombre(string $nombre): Model\Contabilidad\Banco
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('nombre = :nombre');
+ return $this->fetchOne($query, ['nombre' => $nombre]);
+ }
}
diff --git a/app/src/Repository/Contabilidad/Movimiento.php b/app/src/Repository/Contabilidad/Movimiento.php
index 4f36d3c..d45d8ca 100644
--- a/app/src/Repository/Contabilidad/Movimiento.php
+++ b/app/src/Repository/Contabilidad/Movimiento.php
@@ -62,13 +62,13 @@ class Movimiento extends Ideal\Repository
->where('cuenta_id = ? AND fecha = ?');
return $this->fetchMany($query, [$cuenta_id, $fecha->format('Y-m-d')]);
}
- public function fetchByCuentaAndFechaAndCargoAndAbonoAndSaldo(int $cuenta_id, DateTimeInterface $fecha, int $cargo, int $abono, int $saldo): Model\Contabilidad\Movimiento
+ public function fetchByCuentaAndFechaAndGlosaAndCargoAndAbonoAndSaldo(int $cuenta_id, DateTimeInterface $fecha, string $glosa, int $cargo, int $abono, int $saldo): Model\Contabilidad\Movimiento
{
$query = $this->connection->getQueryBuilder()
->select()
->from($this->getTable())
- ->where('cuenta_id = ? AND fecha = ? AND cargo = ? AND abono = ? AND saldo = ?');
- return $this->fetchOne($query, [$cuenta_id, $fecha->format('Y-m-d'), $cargo, $abono, $saldo]);
+ ->where('cuenta_id = ? AND fecha = ? AND glosa = ? AND cargo = ? AND abono = ? AND saldo = ?');
+ return $this->fetchOne($query, [$cuenta_id, $fecha->format('Y-m-d'), $glosa, $cargo, $abono, $saldo]);
}
public function fetchAmountStartingFrom(int $start, int $amount): array
{
diff --git a/app/src/Repository/Contabilidad/Movimiento/Auxiliar.php b/app/src/Repository/Contabilidad/Movimiento/Auxiliar.php
new file mode 100644
index 0000000..065a792
--- /dev/null
+++ b/app/src/Repository/Contabilidad/Movimiento/Auxiliar.php
@@ -0,0 +1,62 @@
+setTable('movimientos_auxiliares');
+ }
+
+ public function create(?array $data = null): Model\Contabilidad\Movimiento\Auxiliar
+ {
+ $map = (new Implement\Repository\MapperParser(['cargo', 'abono']))
+ ->register('movimiento_id', (new Implement\Repository\Mapper())
+ ->setProperty('movimiento')
+ ->setFunction(function($data) {
+ return $this->movimientoRepository->fetchById($data['movimiento_id']);
+ }));
+ return $this->parseData(new Model\Contabilidad\Movimiento\Auxiliar(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Contabilidad\Movimiento\Auxiliar
+ {
+ $model->id = $this->saveNew([
+ 'movimiento_id',
+ 'cargo',
+ 'abono'
+ ],[
+ $model->movimiento->id,
+ $model->cargo,
+ $model->abono
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Contabilidad\Movimiento\Auxiliar
+ {
+ return $this->update($model, [
+ 'movimiento_id',
+ 'cargo',
+ 'abono'
+ ], $new_data);
+ }
+
+ /**
+ * @throws EmptyResult
+ */
+ public function fetchByMovimiento(int $movimiento_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('movimiento_id = :movimiento_id');
+ return $this->fetchMany($query, ['movimiento_id' => $movimiento_id]);
+ }
+}
diff --git a/app/src/Repository/Contabilidad/Movimiento/Auxiliar/Detalle.php b/app/src/Repository/Contabilidad/Movimiento/Auxiliar/Detalle.php
new file mode 100644
index 0000000..77c0b2e
--- /dev/null
+++ b/app/src/Repository/Contabilidad/Movimiento/Auxiliar/Detalle.php
@@ -0,0 +1,72 @@
+setTable('auxiliar_detalles');
+ }
+
+ public function create(?array $data = null): Model\Contabilidad\Movimiento\Auxiliar\Detalle
+ {
+ $map = (new Implement\Repository\MapperParser(['rut', 'digito', 'nombre', 'categoria', 'detalle']))
+ ->register('auxiliar_id', (new Implement\Repository\Mapper())
+ ->setProperty('auxiliar')
+ ->setFunction(function($data) {
+ return $this->auxiliarRepository->fetchById($data['auxiliar_id']);
+ }))
+ ->register('centro_costo_id', (new Implement\Repository\Mapper())
+ ->setProperty('centroCosto')
+ ->setFunction(function($data) {
+ return $this->centroCostoRepository->fetchById($data['centro_costo_id']);
+ })
+ ->setDefault(null));
+ return $this->parseData(new Model\Contabilidad\Movimiento\Auxiliar\Detalle(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Contabilidad\Movimiento\Auxiliar\Detalle
+ {
+ $this->saveNew([
+ 'auxiliar_id',
+ 'rut',
+ 'digito',
+ 'nombre',
+ 'categoria',
+ 'detalle'
+ ], [
+ $model->auxiliar->id,
+ $model->rut,
+ $model->digito,
+ $model->nombre,
+ $model->categoria,
+ $model->detalle
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Contabilidad\Movimiento\Auxiliar\Detalle
+ {
+ return $this->update($model, ['rut', 'digito', 'nombre', 'categoria', 'detalle'], $new_data);
+ }
+
+ /**
+ * @throws EmptyResult
+ */
+ public function fetchByAuxiliar(int $auxiliar_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('auxiliar_id = :auxiliar_id');
+ return $this->fetchMany($query, ['auxiliar_id' => $auxiliar_id]);
+ }
+}
diff --git a/app/src/Repository/Movimiento/Detalle.php b/app/src/Repository/Contabilidad/Movimiento/Detalle.php
similarity index 58%
rename from app/src/Repository/Movimiento/Detalle.php
rename to app/src/Repository/Contabilidad/Movimiento/Detalle.php
index 349feda..ba526c2 100644
--- a/app/src/Repository/Movimiento/Detalle.php
+++ b/app/src/Repository/Contabilidad/Movimiento/Detalle.php
@@ -1,5 +1,5 @@
setTable('movimientos_detalles');
}
- public function create(?array $data = null): Model\Movimiento\Detalle
+ public function create(?array $data = null): Model\Contabilidad\Movimiento\Detalle
{
- $map = (new Implement\Repository\MapperParser(['detalle']))
+ $map = (new Implement\Repository\MapperParser(['rut', 'digito', 'nombres', 'categoria', 'detalle', 'identificador']))
->register('movimiento_id', (new Implement\Repository\Mapper())
->setProperty('movimiento')
->setFunction(function(array $data) {
@@ -28,23 +29,24 @@ class Detalle extends Ideal\Repository
->setProperty('centroCosto')
->setFunction(function(array $data) {
return $this->centroCostoRepository->fetchById($data['centro_costo_id']);
- }));
- return $this->parseData(new Model\Movimiento\Detalle(), $data, $map);
+ })
+ ->setDefault(null));
+ return $this->parseData(new Model\Contabilidad\Movimiento\Detalle(), $data, $map);
}
- public function save(Define\Model $model): Model\Movimiento\Detalle
+ public function save(Define\Model $model): Model\Contabilidad\Movimiento\Detalle
{
$this->saveNew(
- ['movimiento_id', 'centro_costo_id', 'detalle'],
- [$model->movimiento->id, $model->centroCosto->id, $model->detalle]
+ ['movimiento_id', 'centro_costo_id', 'rut', 'digito', 'nombres', 'categoria', 'detalle', 'identificador'],
+ [$model->movimiento->id, $model->centroCosto?->id, $model->rut, $model->digito, $model->nombres, $model->categoria, $model->detalle, $model->identificador]
);
return $model;
}
- public function edit(Define\Model $model, array $new_data): Model\Movimiento\Detalle
+ public function edit(Define\Model $model, array $new_data): Model\Contabilidad\Movimiento\Detalle
{
- return $this->update($model, ['movimiento_id', 'centro_costo_id', 'detalle'], $new_data);
+ return $this->update($model, ['movimiento_id', 'centro_costo_id', 'rut', 'digito', 'nombres', 'categoria', 'detalle', 'identificador'], $new_data);
}
- public function fetchByMovimiento(int $movimiento_id): Model\Movimiento\Detalle
+ public function fetchByMovimiento(int $movimiento_id): Model\Contabilidad\Movimiento\Detalle
{
$query = $this->connection->getQueryBuilder()
->select()
diff --git a/app/src/Repository/DatosPersona.php b/app/src/Repository/DatosPersona.php
new file mode 100644
index 0000000..3b9c0c0
--- /dev/null
+++ b/app/src/Repository/DatosPersona.php
@@ -0,0 +1,86 @@
+setTable('datos_personas');
+ }
+
+ public function create(?array $data = null): Model\DatosPersona
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('persona_rut', (new Implement\Repository\Mapper())
+ ->setProperty('persona')
+ ->setFunction(function($data) {
+ return $this->personaRepository->fetchById($data['persona_rut']);
+ }))
+ ->register('direccion_id', (new Implement\Repository\Mapper())
+ ->setProperty('direccion')
+ ->setFunction(function($data) {
+ return $this->direccionRepository->fetchById($data['direccion_id']);
+ })->setDefault(null))
+ ->register('telefono', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $data['telefono'];
+ })->setDefault(null))
+ ->register('email', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $data['email'];
+ })->setDefault(null))
+ ->register('fecha_nacimiento', (new Implement\Repository\Mapper\DateTime('fecha_nacimiento'))
+ ->setDefault(null)
+ ->setProperty('fechaNacimiento'))
+ ->register('sexo', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $data['sexo'];
+ })->setDefault(null))
+ ->register('estado_civil', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $data['estado_civil'];
+ })->setDefault(null)->setProperty('estadoCivil'))
+ ->register('nacionalidad', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $data['nacionalidad'];
+ })->setDefault(null))
+ ->register('profesion', (new Implement\Repository\Mapper())->setFunction(function($data) {
+ return $data['profesion'];
+ })->setDefault(null));
+ return $this->parseData(new Model\DatosPersona(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\DatosPersona
+ {
+ $this->saveNew([
+ 'persona_rut', 'direccion_id', 'telefono', 'email', 'fecha_nacimiento', 'sexo', 'estado_civil',
+ 'nacionalidad', 'profesion'
+ ], [
+ $model->persona->rut, $model->direccion?->id, $model->telefono, $model->email, $model->fechaNacimiento,
+ $model->sexo, $model->estadoCivil, $model->nacionalidad, $model->profesion
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\DatosPersona
+ {
+ return $this->update($model, [
+ 'direccion_id', 'telefono', 'email', 'fecha_nacimiento', 'sexo', 'estado_civil',
+ 'nacionalidad', 'profesion'
+ ], $new_data);
+ }
+
+ public function fetchByPersona(int $persona_rut): Model\DatosPersona
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('persona_rut = ?');
+ return $this->fetchOne($query, [$persona_rut]);
+ }
+
+ protected function getKey(): string
+ {
+ return 'persona_rut';
+ }
+}
diff --git a/app/src/Repository/Inmobiliaria/AgenteTipo.php b/app/src/Repository/Inmobiliaria/AgenteTipo.php
index 0ec9ed6..d8d2a88 100644
--- a/app/src/Repository/Inmobiliaria/AgenteTipo.php
+++ b/app/src/Repository/Inmobiliaria/AgenteTipo.php
@@ -24,6 +24,7 @@ class AgenteTipo extends Ideal\Repository
return ($data === null) ? null : $this->agenteRepository->fetchById($data['agente']);
}))
->register('tipo', (new Implement\Repository\Mapper())
+ ->setProperty('tipoAgente')
->setFunction(function(?array $data) {
return ($data === null) ? null : $this->tipoAgenteRepository->fetchById($data['tipo']);
}));
diff --git a/app/src/Repository/Inmobiliaria/Proveedor.php b/app/src/Repository/Inmobiliaria/Proveedor.php
new file mode 100644
index 0000000..2f9c27d
--- /dev/null
+++ b/app/src/Repository/Inmobiliaria/Proveedor.php
@@ -0,0 +1,61 @@
+setTable('proveedores');
+ }
+
+ public function create(?array $data = null): Model\Inmobiliaria\Proveedor
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('inmobiliaria_rut', (new Implement\Repository\Mapper())
+ ->setProperty('inmobiliaria')
+ ->setFunction(function($data) {
+ return $this->inmobiliariaRepository->fetchById($data['inmobiliaria_rut']);
+ }))
+ ->register('sociedad_rut', (new Implement\Repository\Mapper())
+ ->setProperty('sociedad')
+ ->setFunction(function($data) {
+ return $this->sociedadRepository->fetchById($data['sociedad_rut']);
+ }));
+ return $this->parseData(new Model\Inmobiliaria\Proveedor(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Inmobiliaria\Proveedor
+ {
+ $model->id = $this->saveNew(['inmobiliaria_rut', 'sociedad_rut'], [$model->inmobiliaria->rut, $model->sociedad->rut]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Inmobiliaria\Proveedor
+ {
+ return $this->update($model, ['sociedad_id'], $new_data);
+ }
+
+ public function fetchByInmobiliaria(int $inmobiliaria_rut): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('inmobiliaria_rut = :inmobiliaria_rut');
+ return array_map([$this, 'load'], $this->fetchMany($query, compact('inmobiliaria_rut')));
+ }
+ public function fetchBySociedad(int $sociedad_rut): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('sociedad_rut = :sociedad_rut');
+ return array_map([$this, 'load'], $this->fetchMany($query, compact('sociedad_rut')));
+ }
+}
diff --git a/app/src/Repository/Persona.php b/app/src/Repository/Persona.php
new file mode 100644
index 0000000..774f844
--- /dev/null
+++ b/app/src/Repository/Persona.php
@@ -0,0 +1,49 @@
+setTable('personas');
+ }
+
+ public function create(?array $data = null): Model\Persona
+ {
+ $map = (new Implement\Repository\MapperParser(['rut', 'digito', 'nombres']))
+ ->register('apellido_paterno', (new Implement\Repository\Mapper())->setProperty('apellidoPaterno'))
+ ->register('apellido_materno', (new Implement\Repository\Mapper())->setProperty('apellidoMaterno'))
+ ;
+ return $this->parseData(new Model\Persona(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Persona
+ {
+ $this->saveNew(['rut', 'digito', 'nombres', 'apellido_paterno', 'apellido_materno'],
+ [$model->rut, $model->digito, $model->nombres, $model->apellidoPaterno, $model->apellidoMaterno]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Persona
+ {
+ return $this->update($model, $new_data, ['rut', 'digito', 'nombres', 'apellido_paterno', 'apellido_materno']);
+ }
+
+ public function fetchByRut(int $rut): Model\Persona
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('rut = ?');
+ return $this->fetchOne($query, [$rut]);
+ }
+
+ protected function getKey(): string
+ {
+ return 'rut';
+ }
+}
diff --git a/app/src/Repository/Sociedad.php b/app/src/Repository/Sociedad.php
new file mode 100644
index 0000000..dfc74ed
--- /dev/null
+++ b/app/src/Repository/Sociedad.php
@@ -0,0 +1,55 @@
+setTable('sociedades');
+ }
+
+ public function create(?array $data = null): Model\Sociedad
+ {
+ $map = (new Implement\Repository\MapperParser(['rut', 'digito', 'nombre']))
+ ->register('razon', (new Implement\Repository\Mapper())
+ ->setProperty('razonSocial'))
+ ->register('tipo_sociedad_id', (new Implement\Repository\Mapper())
+ ->setProperty('tipoSociedad')
+ ->setFunction(function ($data) {
+ return $this->tipoSociedadRepository->fetchById($data['tipo_sociedad_id']);
+ })
+ )
+ ->register('contacto_rut', (new Implement\Repository\Mapper())
+ ->setProperty('contacto')
+ ->setFunction(function ($data) {
+ return $this->personaService->getByRut($data['contacto_rut']);
+ }));
+ return $this->parseData(new Model\Sociedad(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Sociedad
+ {
+ $this->saveNew(['rut', 'digito', 'nombre', 'razon', 'tipo_sociedad_id', 'contacto_rut'],
+ [$model->rut, $model->digito, $model->nombre, $model->razonSocial, $model->tipoSociedad->id,
+ $model->contacto->rut]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Sociedad
+ {
+ return $this->update($model,
+ ['digito', 'nombre', 'razon', 'tipo_sociedad_id', 'contacto_rut'], $new_data);
+ }
+
+ protected function getKey(): string
+ {
+ return 'rut';
+ }
+}
diff --git a/app/src/Repository/Venta/Factura.php b/app/src/Repository/Venta/Factura.php
new file mode 100644
index 0000000..0bd8716
--- /dev/null
+++ b/app/src/Repository/Venta/Factura.php
@@ -0,0 +1,129 @@
+setTable('facturas');
+ }
+
+ public function create(?array $data = null): Model\Venta\Factura
+ {
+ $map = (new Implement\Repository\MapperParser(['index']))
+ ->register('venta_id', (new Implement\Repository\Mapper())
+ ->setProperty('venta')
+ ->setFunction(function($data) {
+ return $this->ventaRepository->fetchById($data['venta_id']);
+ }));
+ $factura = $this->parseData(new Model\Venta\Factura(), $data, $map);
+ $json = json_decode($data['data']);
+ $factura->proporcion = $json->proporcion;
+ $factura->emisorRut = $json->emisor->rut;
+ $factura->emisorNombre = $json->emisor->nombre;
+ $factura->emisorDireccion = $json->emisor->direccion;
+ $factura->receptorRut = $json->receptor->rut;
+ $factura->receptorNombre = $json->receptor->nombre;
+ $factura->receptorDireccion = $json->receptor->direccion;
+ $factura->receptorComuna = $json->receptor->comuna;
+ $factura->fecha = new DateTimeImmutable($json->fecha);
+ $factura->unidades = $json->unidades;
+ $factura->detalleBase = $json->detalle->base;
+ $factura->detalleTerreno = $json->detalle->terreno;
+ $factura->detalleNeto = $json->detalle->neto;
+ $factura->detalleIva = $json->detalle->iva;
+ $factura->detalleBruto = $json->detalle->bruto;
+ $factura->detalleDescuento = $json->detalle->descuento;
+ $factura->detalleTotal = $json->detalle->total;
+ $factura->totalNeto = $json->total->neto;
+ $factura->totalExento = $json->total->exento;
+ $factura->totalIva = $json->total->iva;
+ $factura->totalTotal = $json->total->total;
+ $factura->fechaUF = new DateTimeImmutable($json->uf->fecha);
+ $factura->valorUF = $json->uf->valor;
+ return $factura;
+ }
+ public function save(Define\Model $model): Model\Venta\Factura
+ {
+ $model->id = $this->saveNew([
+ 'venta_id',
+ 'index',
+ 'data'
+ ], [
+ $model->venta->id,
+ $model->index,
+ json_encode([
+ 'proporcion' => $model->proporcion,
+ 'emisor' => [
+ 'rut' => $model->emisorRut,
+ 'nombre' => $model->emisorNombre,
+ 'direccion' => $model->emisorDireccion
+ ],
+ 'receptor' => [
+ 'rut' => $model->receptorRut,
+ 'nombre' => $model->receptorNombre,
+ 'direccion' => $model->receptorDireccion,
+ 'comuna' => $model->receptorComuna
+ ],
+ 'fecha' => $model->fecha->format('Y-m-d'),
+ 'unidades' => $model->unidades,
+ 'detalle' => [
+ 'base' => $model->detalleBase,
+ 'terreno' => $model->detalleTerreno,
+ 'neto' => $model->detalleNeto,
+ 'iva' => $model->detalleIva,
+ 'bruto' => $model->detalleBruto,
+ 'descuento' => $model->detalleDescuento,
+ 'total' => $model->detalleTotal
+ ],
+ 'total' => [
+ 'neto' => $model->totalNeto,
+ 'exento' => $model->totalExento,
+ 'iva' => $model->totalIva,
+ 'total' => $model->totalTotal
+ ],
+ 'uf' => [
+ 'fecha' => $model->fechaUF->format('Y-m-d'),
+ 'valor' => $model->valorUF
+ ]
+ ])
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Factura
+ {
+ return $this->update($model, ['venta_id', 'index', 'data'], $new_data);
+ }
+
+ /**
+ * @throws EmptyResult
+ */
+ public function fetchByVenta(int $venta_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('venta_id = :venta_id');
+ return $this->fetchMany($query, ['venta_id' => $venta_id]);
+ }
+ /**
+ * @throws EmptyResult
+ */
+ public function fetchByVentaAndIndex(int $venta_id, int $index): Model\Venta\Factura
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('venta_id = :venta_id AND index = :index');
+ return $this->fetchOne($query, ['venta_id' => $venta_id, 'index' => $index]);
+ }
+}
diff --git a/app/src/Repository/Venta/Factura/Estado.php b/app/src/Repository/Venta/Factura/Estado.php
new file mode 100644
index 0000000..a12ea53
--- /dev/null
+++ b/app/src/Repository/Venta/Factura/Estado.php
@@ -0,0 +1,60 @@
+setTable('estados_facturas');
+ }
+
+ public function create(?array $data = null): Model\Venta\Factura\Estado
+ {
+ $map = (new Implement\Repository\MapperParser())
+ ->register('factura_id', (new Implement\Repository\Mapper())
+ ->setProperty('factura')
+ ->setFunction(function($data) {
+ return $this->facturaRepository->fetchById($data['factura_id']);
+ }))
+ ->register('fecha', new Implement\Repository\Mapper\DateTime('fecha'))
+ ->register('tipo_id', (new Implement\Repository\Mapper())
+ ->setProperty('tipo')
+ ->setFunction(function($data) {
+ return $this->tipoRepository->fetchById($data['tipo_id']);
+ }));
+ return $this->parseData(new Model\Venta\Factura\Estado(), $data, $map);
+ }
+ public function save(Define\Model $model): Model\Venta\Factura\Estado
+ {
+ $model->id = $this->saveNew([
+ 'factura_id',
+ 'fecha',
+ 'tipo_id'
+ ], [
+ $model->factura->id,
+ $model->fecha->format('Y-m-d'),
+ $model->tipo->id
+ ]);
+ return $model;
+ }
+ public function edit(Define\Model $model, array $new_data): Model\Venta\Factura\Estado
+ {
+ return $this->update($model, ['factura_id', 'fecha', 'tipo_id'], $new_data);
+ }
+
+ public function fetchByFactura(int $factura_id): array
+ {
+ $query = $this->connection->getQueryBuilder()
+ ->select()
+ ->from($this->getTable())
+ ->where('factura_id = :factura_id');
+ return $this->fetchMany($query, ['factura_id' => $factura_id]);
+ }
+}
diff --git a/app/src/Repository/Venta/Factura/Estado/Tipo.php b/app/src/Repository/Venta/Factura/Estado/Tipo.php
new file mode 100644
index 0000000..4206fb4
--- /dev/null
+++ b/app/src/Repository/Venta/Factura/Estado/Tipo.php
@@ -0,0 +1,17 @@
+rut = $this->saveNew(
['rut', 'dv', 'nombres', 'apellido_paterno', 'apellido_materno', 'direccion', 'otro', 'representante'],
- [$model->rut, $model->dv, $model->nombres, $model->apellidos['paterno'], $model->apellidos['materno'], $model->datos->direccion->id, $model->otro->rut ?? 0, $model->representante->rut ?? 0]
+ [$model->rut, $model->dv, $model->nombres, $model->apellidos['paterno'], $model->apellidos['materno'], $model->datos->direccion->id, $model->otro->rut ?? 0, $model->contacto->rut ?? 0]
);
return $model;
}
diff --git a/app/src/Service/Contabilidad.php b/app/src/Service/Contabilidad.php
index a5e87fd..692fe72 100644
--- a/app/src/Service/Contabilidad.php
+++ b/app/src/Service/Contabilidad.php
@@ -15,6 +15,6 @@ class Contabilidad extends Ideal\Controller
public function tesoreria(DateTimeInterface $fecha): array
{
- return $this->tesoreriaService->build($fecha);
+ return $this->tesoreriaService->getOutput()->build($fecha);
}
}
diff --git a/app/src/Service/Contabilidad/Cartola.php b/app/src/Service/Contabilidad/Cartola.php
index 8b3cb76..cd19242 100644
--- a/app/src/Service/Contabilidad/Cartola.php
+++ b/app/src/Service/Contabilidad/Cartola.php
@@ -121,9 +121,10 @@ class Cartola extends Service
{
try {
return $this->movimientoRepository
- ->fetchByCuentaAndFechaAndCargoAndAbonoAndSaldo(
+ ->fetchByCuentaAndFechaAndGlosaAndCargoAndAbonoAndSaldo(
$cuenta->id,
new DateTimeImmutable($data['fecha']),
+ $data['glosa'],
$data['cargo'] ?? 0,
$data['abono'] ?? 0,
$data['saldo']
diff --git a/app/src/Service/Contabilidad/Cartola/BCI.php b/app/src/Service/Contabilidad/Cartola/BCI.php
index dc3b8ab..54ee427 100644
--- a/app/src/Service/Contabilidad/Cartola/BCI.php
+++ b/app/src/Service/Contabilidad/Cartola/BCI.php
@@ -14,7 +14,13 @@ class BCI extends Banco
'Cargo $ (-)' => 'cargo',
'Abono $ (+)' => 'abono',
'Descripción' => 'glosa',
- 'Saldo' => 'saldo'
+ 'Saldo' => 'saldo',
+ 'Categoría' => 'categoria',
+ 'Centro costos' => 'centro_costo',
+ 'Detalle' => 'detalle',
+ 'Factura Boleta' => 'identificador',
+ 'RUT' => 'rut',
+ 'Nombres' => 'nombres',
];
}
protected function getFilename(UploadedFileInterface $uploadedFile): string
diff --git a/app/src/Service/Contabilidad/Cartola/Itau.php b/app/src/Service/Contabilidad/Cartola/Itau.php
index 4639ad5..17bc111 100644
--- a/app/src/Service/Contabilidad/Cartola/Itau.php
+++ b/app/src/Service/Contabilidad/Cartola/Itau.php
@@ -26,7 +26,14 @@ class Itau extends Banco
'Giros o cargos' => 'cargo',
'Documentos' => 'documento',
'Movimientos' => 'glosa',
- 'Saldos' => 'saldo'
+ 'Saldos' => 'saldo',
+ 'Categoría' => 'categoria',
+ 'Centro costo' => 'centro_costo',
+ 'Detalle' => 'detalle',
+ 'Factura Boleta' => 'identificador',
+ 'RUT' => 'rut',
+ 'Nombres' => 'nombres',
+ 'Depto' => 'identificador',
];
}
protected function getFilename(UploadedFileInterface $uploadedFile): string
diff --git a/app/src/Service/Contabilidad/Cartola/Santander.php b/app/src/Service/Contabilidad/Cartola/Santander.php
index 8b6c7ab..d2f6d8b 100644
--- a/app/src/Service/Contabilidad/Cartola/Santander.php
+++ b/app/src/Service/Contabilidad/Cartola/Santander.php
@@ -20,7 +20,13 @@ class Santander extends Banco
'Cargo ($)' => 'cargo',
'Abono ($)' => 'abono',
'Descripcin' => 'glosa',
- 'Saldo Diario' => 'saldo'
+ 'Saldo Diario' => 'saldo',
+ 'Categoría' => 'categoria',
+ 'Centro costos' => 'centro_costo',
+ 'Detalle' => 'detalle',
+ 'Factura Boleta' => 'identificador',
+ 'RUT' => 'rut',
+ 'Nombres' => 'nombres',
];
}
protected function getFilename(UploadedFileInterface $uploadedFile): string
diff --git a/app/src/Service/Contabilidad/Cartola/Security.php b/app/src/Service/Contabilidad/Cartola/Security.php
index f2798b4..c36c9a9 100644
--- a/app/src/Service/Contabilidad/Cartola/Security.php
+++ b/app/src/Service/Contabilidad/Cartola/Security.php
@@ -41,7 +41,14 @@ class Security extends Banco
'nº documento' => 'documento',
'cargos' => 'cargo',
'abonos' => 'abono',
- 'saldos' => 'saldo'
+ 'saldos' => 'saldo',
+ 'categoría' => 'categoria',
+ 'centro costos' => 'centro_costo',
+ 'detalle' => 'detalle',
+ 'factura boleta' => 'identificador',
+ 'rut' => 'rut',
+ 'nombres' => 'nombres',
+ 'depto' => 'identificador',
];
}
diff --git a/app/src/Service/Contabilidad/Informe/Semanal.php b/app/src/Service/Contabilidad/Informe/Semanal.php
new file mode 100644
index 0000000..1c0ff7d
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Semanal.php
@@ -0,0 +1,36 @@
+anterior)) {
+ $this->anterior = $fecha->sub(new DateInterval('P1D'));
+ if ($this->anterior->format('N') === '7') {
+ $this->anterior = $fecha->sub(new DateInterval('P3D'));
+ }
+ }
+ return $this->anterior;
+ }
+ public function build(DateTimeInterface $fecha): array
+ {}
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria.php b/app/src/Service/Contabilidad/Informe/Tesoreria.php
index 5bc8e56..937ae59 100644
--- a/app/src/Service/Contabilidad/Informe/Tesoreria.php
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria.php
@@ -1,378 +1,23 @@
movimientos = new class(self::ORDEN_SOCIEDADES) {
- public function __construct(protected array $ordenSociedades)
- {
- $this->dap = new class()
- {
- public array $ingresos = [];
- public array $egresos = [];
- };
- }
- public object $dap;
- public array $ingresos = [];
- public array $egresos = [];
-
- const INGRESOS = 'ingresos';
- const EGRESOS = 'egresos';
- public function addDap(string $tipo, array $movimientos)
- {
- foreach ($movimientos as $movimiento) {
- $this->dap->{$tipo} []= $movimiento;
- }
- return $this;
- }
- public function updateDap(object $movimiento): void
- {
- foreach ($this->ingresos as $ingreso) {
- if ($movimiento->cuenta->inmobiliaria->rut !== $ingreso->cuenta->inmobiliaria->rut) {
- continue;
- }
- if ($movimiento->fecha->format('Y-m-d') !== $ingreso->fecha->format('Y-m-d')) {
- continue;
- }
- if ($movimiento->documento !== $ingreso->documento) {
- continue;
- }
- $ingreso->glosa = $movimiento->glosa;
- break;
- }
- }
- public function build(): array
- {
- $this->dap->ingresos = $this->sortBySociedades($this->dap->ingresos);
- $this->dap->egresos = $this->sortBySociedades($this->dap->egresos);
- $this->ingresos = $this->sortBySociedades($this->ingresos);
- $this->egresos = $this->sortBySociedades($this->egresos);
- return [
- 'capital dap' => [
- 'ingresos' => $this->dap->ingresos,
- 'egresos' => $this->dap->egresos
- ],
- 'ingresos' => $this->ingresos,
- 'egresos' => $this->egresos
- ];
- }
-
- private function sortBySociedades(array $movimientos): array
- {
- $temp = [];
- foreach ($this->ordenSociedades as $sociedad_rut) {
- $date = null;
- foreach ($movimientos as $movimiento) {
- if ($date === null) {
- $date = $movimiento->fecha;
- }
- if ($movimiento->fecha !== $date) {
- if ($movimiento->cuenta->inmobiliaria->rut === $sociedad_rut) {
- $temp []= $movimiento;
- }
- $date = $movimiento->fecha;
- continue;
- }
- if ($movimiento->cuenta->inmobiliaria->rut === $sociedad_rut) {
- $temp []= $movimiento;
- }
- }
- }
- foreach ($movimientos as $movimiento) {
- if (!in_array($movimiento, $temp)) {
- $temp []= $movimiento;
- }
- }
- return $temp;
- }
- };
- $this->totales = new class() {
- public int $anterior = 0;
- public int $actual = 0;
- public int $ffmm = 0;
- public int $deposito = 0;
- public int $saldo = 0;
-
- public function diferencia(): int
- {
- return $this->actual - $this->anterior;
- }
- public function saldo(): int
- {
- return $this->diferencia() + $this->ffmm + $this->deposito;
- }
- public function cuentas(): int
- {
- return $this->actual;
- }
- public function ffmms(): int
- {
- return $this->ffmm;
- }
- public function depositos(): int
- {
- return $this->deposito;
- }
- public function caja(): int
- {
- return $this->cuentas() + $this->ffmms() + $this->depositos();
- }
- };
}
-
- const DAP_INGRESOS = 'dap->ingresos';
- const DAP_EGRESOS = 'dap->egresos';
- const INGRESOS = 'ingresos';
- const EGRESOS = 'egresos';
- const TOTAL_ANTERIOR = 'anterior';
- const TOTAL_ACTUAL = 'actual';
- const TOTAL_FFMM = 'ffmm';
- const TOTAL_DAP = 'deposito';
-
- protected DateTimeInterface $anterior;
- protected object $totales;
- protected object $movimientos;
-
- public function getAnterior(DateTimeInterface $fecha): DateTimeInterface
+ public function getOutput(): Tesoreria\Output
{
- if (!isset($this->anterior)) {
- $this->anterior = $fecha->sub(new DateInterval('P1D'));
- if ($this->anterior->format('N') === '7') {
- $this->anterior = $fecha->sub(new DateInterval('P3D'));
- }
- }
- return $this->anterior;
+ return $this->outputService;
}
- public function build(DateTimeInterface $fecha): array
+ public function getInput(): Tesoreria\Input
{
- try {
- $inmobiliarias = $this->inmobiliariaRepository->fetchAll();
- } catch (Implement\Exception\EmptyResult) {
- return [];
- }
- $temp = [];
- foreach (self::ORDEN_SOCIEDADES as $sociedad_rut) {
- foreach ($inmobiliarias as $inmobiliaria) {
- if ($inmobiliaria->rut === $sociedad_rut) {
- $temp []= $inmobiliaria;
- }
- }
- }
- foreach ($inmobiliarias as $inmobiliaria) {
- if (!in_array($inmobiliaria, $temp)) {
- $temp []= $inmobiliaria;
- }
- }
- $informe = ['inmobiliarias' => []];
- foreach ($temp as $inmobiliaria) {
- $informe['inmobiliarias'][$inmobiliaria->rut] = $this->buildInmobiliaria($inmobiliaria, $fecha);
- }
- $informe['movimientos'] = $this->buildMovimientos();
- $informe['totales'] = $this->buildTotales();
-
- //$this->buildInforme($fecha, $informe);
-
- return $informe;
- }
- public function buildInforme(DateTimeInterface $fecha, array $data, string $type = 'Xlsx', ?string $filename = 'php://output'): void
- {
- $informe = $this->excelService->build($fecha, $data);
- $this->excelService->save($fecha, $informe, $type, $filename);
- }
-
- protected function buildInmobiliaria(Model\Inmobiliaria $inmobiliaria, DateTimeInterface $fecha): object
- {
- $dataInmobiliaria = new class() {
- public Model\Inmobiliaria $inmobiliaria;
- public array $cuentas = [];
- public function total(): int
- {
- return array_reduce($this->cuentas, function(int $sum, $cuenta) {
- return $sum + $cuenta->actual;
- }, 0);
- }
- public function ffmm(): int
- {
- return array_reduce($this->cuentas, function(int $sum, $cuenta) {
- return $sum + $cuenta->ffmm;
- }, 0);
- }
- public function deposito(): int
- {
- return array_reduce($this->cuentas, function(int $sum, $cuenta) {
- return $sum + $cuenta->deposito;
- }, 0);
- }
- public function caja(): int
- {
- return array_reduce($this->cuentas, function(int $sum, $cuenta) {
- return $sum + $cuenta->saldo();
- }, 0);
- }
- };
- $dataInmobiliaria->inmobiliaria = $inmobiliaria;
- try {
- $cuentas = $this->cuentaService->getAllActiveByInmobiliaria($inmobiliaria->rut);
- } catch (Implement\Exception\EmptyResult) {
- return $dataInmobiliaria;
- }
- foreach ($cuentas as $cuenta) {
- $data = new class() {
- public string $banco;
- public string $numero;
- public int $anterior = 0;
- public int $actual = 0;
- public int $ffmm = 0;
- public int $deposito = 0;
-
- public function diferencia(): int
- {
- return $this->actual - $this->anterior;
- }
- public function saldo(): int
- {
- return $this->diferencia() + $this->ffmm + $this->deposito;
- }
- };
- $data->banco = $cuenta->banco->nombre;
- $data->numero = $cuenta->cuenta;
- try {
- $depositos = $this->depositoRepository->fetchByCuenta($cuenta->id);
- foreach ($depositos as $deposito) {
- if ($deposito->termino < $fecha) {
- continue;
- }
- $data->deposito += $deposito->capital;
- $this->addTotal(self::TOTAL_DAP, $deposito->capital);
- $this->totales->saldo += $deposito->capital;
-
- if ($deposito->inicio->format('Y-m-d') === $fecha->format('Y-m-d')) {
- $this->addMovimientos(self::DAP_EGRESOS, [(object) [
- 'cuenta' => $deposito->cuenta,
- 'fecha' => $deposito->inicio,
- 'cargo' => - $deposito->capital,
- 'abono' => 0,
- 'saldo' => - $deposito->capital,
- 'glosa' => 'INVERSION DAP'
- ]]);
- }
- if ($deposito->termino->format('Y-m-d') === $fecha->format('Y-m-d')) {
- $data->deposito -= $deposito->capital;
- $this->addTotal(self::TOTAL_DAP, -$deposito->capital);
-
- $this->addMovimientos(self::INGRESOS, [(object) [
- 'cuenta' => $deposito->cuenta,
- 'fecha' => $deposito->termino,
- 'cargo' => 0,
- 'abono' => $deposito->futuro - $deposito->capital,
- 'saldo' => $deposito->futuro - $deposito->capital,
- 'glosa' => 'RESCATE DAP',
- 'documento' => $deposito->id
- ]]);
- }
- }
- } catch (Implement\Exception\EmptyResult) {}
- $anterior = $this->getAnterior($fecha);
- try {
- $cartola = $this->cartolaRepository->fetchLastByCuentaAndFecha($cuenta->id, $fecha);
- $data->actual = $cartola->saldo;
- //$anterior = $this->getAnterior($cartola->fecha);
- } catch (Implement\Exception\EmptyResult) {}
- try {
- $cartola = $this->cartolaRepository->fetchLastByCuentaAndFecha($cuenta->id, $anterior);
- $data->anterior = $cartola->saldo;
- $this->totales->saldo += $cartola->saldo;
- } catch (Implement\Exception\EmptyResult) {}
- if ($data->diferencia() !== 0) {
- try {
- $movimientos = $this->movimientoRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
- $this->addMovimientos(self::INGRESOS,
- array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) {
- return $movimiento->abono > 0;
- }));
- $this->addMovimientos(self::EGRESOS,
- array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) {
- return $movimiento->cargo > 0;
- }));
- } catch (Implement\Exception\EmptyResult) {}
- }
- $dataInmobiliaria->cuentas []= $data;
-
- $this->addTotal(
- [self::TOTAL_ANTERIOR, self::TOTAL_ACTUAL],
- [$data->anterior, $data->actual]
- );
- }
-
- return $dataInmobiliaria;
- }
- protected function buildMovimientos(): array
- {
- return $this->movimientos->build();
- }
- protected function buildTotales(): object
- {
- return $this->totales;
- }
- protected function addMovimientos(string $tipo, array $movimientos): Tesoreria
- {
- if (str_starts_with($tipo, 'dap')) {
- list($d, $t) = explode('->', $tipo);
- $this->movimientos->addDap($t, $movimientos);
- return $this;
- }
- foreach ($movimientos as $movimiento) {
- if ($tipo === 'ingresos' and str_contains(strtolower($movimiento->glosa), ' dap ')) {
- $this->movimientos->updateDap($movimiento);
- continue;
- }
- $this->movimientos->{$tipo} []= $movimiento;
- }
- return $this;
- }
- protected function addTotal(string|array $tipo, int|array $total): Tesoreria
- {
- if (is_array($tipo)) {
- foreach ($tipo as $i => $t) {
- $this->addTotal($t, $total[$i]);
- }
- return $this;
- }
- $this->totales->{$tipo} += $total;
- return $this;
+ return $this->inputService;
}
}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input.php
new file mode 100644
index 0000000..4b65e1f
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input.php
@@ -0,0 +1,36 @@
+getSize() === 0) {
+ return [];
+ }
+ $tmpFile = '/tmp/' . $uploadedFile->getClientFilename();
+ $uploadedFile->moveTo($tmpFile);
+ $data = $this->excelService->load($tmpFile);
+ unlink($tmpFile);
+
+ return $data;
+ }
+
+ public function load(array $data): void
+ {
+ $this->saldosContablesService->load($data['saldosContables']);
+ $this->dapYFFMMService->load($data['dapyffmm']);
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Data/DAPyFFMM.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Data/DAPyFFMM.php
new file mode 100644
index 0000000..fb5b57c
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Data/DAPyFFMM.php
@@ -0,0 +1,12 @@
+logger->error('Cargando DAP y FFMM', $data);
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Data/SaldosContables.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Data/SaldosContables.php
new file mode 100644
index 0000000..12f1b61
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Data/SaldosContables.php
@@ -0,0 +1,152 @@
+data = $data['movimientos'];
+ foreach ($data['movimientos'] as $type => $dataMovimiento) {
+ switch ($type) {
+ case 'total':
+ $this->saldoInicial = $dataMovimiento;
+ break;
+ case 'depositos':
+ $this->loadDepositos($dataMovimiento);
+ break;
+ case 'egresos':
+ case 'ingresos':
+ $this->loadMovimiento($dataMovimiento);
+ break;
+ }
+ }
+ }
+
+ protected array $sociedades;
+ protected int $saldoInicial;
+ protected array $data;
+
+ protected function loadDepositos(array $data): void
+ {
+ $this->logger->error('Cargando depositos', $data);
+ }
+ protected function loadMovimiento(array $data): void
+ {
+ $sociedades = $this->getSociedades();
+ $unmatched = [];
+ foreach ($data as $dataMovimiento) {
+ try {
+ $sociedad_rut = $this->matchSociedad($sociedades, $dataMovimiento->empresa);
+ $banco = $this->bancoRepository->fetchByNombre($dataMovimiento->banco);
+ $cuenta = $this->cuentaRepository->fetchByInmobiliariaAndBanco($sociedad_rut, $banco->id);
+ $data = [
+ 'cuenta_id' => $cuenta->id,
+ 'fecha' => $dataMovimiento->fecha->format('Y-m-d'),
+ 'glosa' => mb_convert_encoding($dataMovimiento->{'descripción'}, 'UTF-8'),
+ 'documento' => $dataMovimiento->{'n°Doc'},
+ 'cargo' => -$dataMovimiento->egresos,
+ 'abono' => $dataMovimiento->ingresos,
+ 'saldo' => $this->getSaldo($dataMovimiento)
+ ];
+ try {
+ $movimiento = $this->movimientoRepository->fetchByCuentaAndFechaAndCargoAndAbonoAndSaldo($cuenta->id, $dataMovimiento->fecha, $data['cargo'], $data['abono'], $data['saldo']);
+ } catch (Implement\Exception\EmptyResult) {
+ $movimiento = $this->movimientoRepository->create($data);
+ $movimiento = $this->movimientoRepository->save($movimiento);
+ }
+ list($rut, $digito) = explode('-', $dataMovimiento->rut);
+ $data = [
+ 'movimiento_id' => $movimiento->id,
+ 'centro_costo_id' => $dataMovimiento->cc,
+ 'rut' => (int) preg_replace('/\D*/', '', $rut),
+ 'digito' => $digito,
+ 'nombre' => $dataMovimiento->nombres,
+ 'categoria' => $dataMovimiento->categoria,
+ 'detalle' => $dataMovimiento->detalle,
+ ];
+ if ($data['centro_costo_id'] === 0 and ($data['rut'] === 0 or $data['nombre'] === '' or $data['categoria'] === '' or $data['detalle'] === '')) {
+ continue;
+ }
+ try {
+ $detalles = $this->detalleRepository->fetchByMovimiento($movimiento->id);
+ $this->detalleRepository->edit($detalles, $data);
+ } catch (Implement\Exception\EmptyResult) {
+ $detalles = $this->detalleRepository->create($data);
+ $this->detalleRepository->save($detalles);
+ }
+ } catch (Exception $exception) {
+ $this->logger->error($exception);
+ $unmatched []= $dataMovimiento;
+ }
+ }
+
+ if (count($unmatched) > 0) {
+ $this->logger->error('Movimientos no asociados', $unmatched);
+ }
+ }
+
+ protected function getSociedades(): array
+ {
+ if (!isset($this->sociedades)) {
+ $this->sociedades = [];
+ try {
+ $this->sociedades = $this->inmobiliariaRepository->fetchAll();
+ } catch (Implement\Exception\EmptyResult $e) {
+ $this->logger->error($e->getMessage());
+ }
+ }
+ return $this->sociedades;
+ }
+ protected function getSaldo($movimiento): int
+ {
+ $saldo = $this->saldoInicial;
+ foreach ($this->data as $type => $dataMovimientos) {
+ if (in_array($type, ['total', 'depositos'])) {
+ continue;
+ }
+ foreach ($dataMovimientos as $dataMovimiento) {
+ if ($dataMovimiento !== $movimiento) {
+ continue;
+ }
+ $saldo += $dataMovimiento->ingresos + $dataMovimiento->egresos;
+ }
+ }
+ return $saldo;
+ }
+ protected function matchSociedad(array $sociedades, string $name): int
+ {
+ foreach ($sociedades as $sociedad) {
+ $abreviacion = $sociedad->abreviacion;
+ if ($abreviacion === 'Incoviba') {
+ if (preg_match('/(Vial Balmaceda)+/', $name) === 1) {
+ return $sociedad->rut;
+ }
+ continue;
+ }
+ if (str_contains($abreviacion, 'Optimus')) {
+ $abreviacion = 'Óptimus';
+ }
+ if (preg_match("/({$abreviacion})+/", $name) === 1) {
+ return $sociedad->rut;
+ }
+ }
+
+ throw new Exception("No se encontró la sociedad asociada al nombre '{$name}'");
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel.php
new file mode 100644
index 0000000..e9262d2
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel.php
@@ -0,0 +1,35 @@
+logger->error($e->getMessage());
+ return [];
+ }
+ $excel = $reader->load($filename);
+
+ $data = [];
+ $data['saldosContables'] = $this->saldosCuentasService->load($excel);
+ $data['dapyffmm'] = $this->dapyFFMMService->load($excel);
+ $data['deudaBanco'] = $this->deudaBancoService->load($excel);
+
+ return $data;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/DAPyFFMM.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/DAPyFFMM.php
new file mode 100644
index 0000000..c6623a0
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/DAPyFFMM.php
@@ -0,0 +1,51 @@
+sheetNameExists('DAP y FFMM')) {
+ return [];
+ }
+ $sheet = $excel->getSheetByName('DAP y FFMM');
+ $data = [];
+
+ $rowIndex = 1;
+ while ($sheet->getCell("B{$rowIndex}")->getValue() !== 'EMPRESA') {
+ $rowIndex ++;
+ }
+ $titleRow = $rowIndex;
+ $columnOffset = 2;
+ $titles = $this->getTableTitles($sheet, $titleRow, $columnOffset, 20, 'UF', ['(']);
+
+ $rowIndex ++;
+ while ($sheet->getCell("B{$rowIndex}")->getValue() !== 'TOTAL') {
+ if ($sheet->getCell("B{$rowIndex}")->getValue() !== null) {
+ $data []= $this->getRow($sheet, $titles, $titleRow, $rowIndex, $columnOffset);
+ /*
+ $dap = [];
+ $columnIndex = 0;
+ $dap[$titles[$columnIndex ++]] = $sheet->getCell("B{$rowIndex}")->getValue();
+ $dap[$titles[$columnIndex ++]] = $sheet->getCell("D{$rowIndex}")->getValue();
+ $dap[$titles[$columnIndex ++]] = $sheet->getCell("F{$rowIndex}")->getValue();
+ $dap[$titles[$columnIndex ++]] = $this->getCalculatedValue($sheet, 'H', $rowIndex);
+ $dap[$titles[$columnIndex ++]] = $this->getCalculatedValue($sheet, 'I', $rowIndex);
+ $dap[$titles[$columnIndex ++]] = $this->getCalculatedValue($sheet, 'J', $rowIndex);
+ $dap[$titles[$columnIndex ++]] = $this->getCalculatedValue($sheet, 'K', $rowIndex);
+ $dap[$titles[$columnIndex ++]] = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->getCalculatedValue($sheet, 'L', $rowIndex));
+ $dap[$titles[$columnIndex ++]] = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->getCalculatedValue($sheet, 'M', $rowIndex));
+ $dap[$titles[$columnIndex ++]] = $this->getCalculatedValue($sheet, 'N', $rowIndex);
+ $dap[$titles[$columnIndex]] = $this->getCalculatedValue($sheet, 'O', $rowIndex);
+
+ $data []= (object) $dap;*/
+ }
+ $rowIndex ++;
+ }
+
+ return $data;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/DeudaBanco.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/DeudaBanco.php
new file mode 100644
index 0000000..764b2a3
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/DeudaBanco.php
@@ -0,0 +1,34 @@
+sheetNameExists('Deuda Banco')) {
+ return [];
+ }
+ $sheet = $excel->getSheetByName('Deuda Banco');
+ $data = [];
+
+ $rowIndex = 1;
+ $columnOffset = 2;
+ while ($sheet->getCell([$columnOffset, $rowIndex])->getValue() !== 'EMPRESA') {
+ $rowIndex ++;
+ }
+ $titleRow = $rowIndex;
+ $titles = $this->getTableTitles($sheet, $titleRow, $columnOffset, 13, 'UF', ['(']);
+ $rowIndex ++;
+
+ while ($sheet->getCell([$columnOffset, $rowIndex])->getValue() !== 'TOTAL GRUPO EMPRESAS') {
+ if ($sheet->getCell([$columnOffset, $rowIndex])->getValue() !== null) {
+ $data []= $this->getRow($sheet, $titles, $titleRow, $rowIndex, $columnOffset);
+ }
+ $rowIndex ++;
+ }
+
+ return $data;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/SaldosCuentas.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/SaldosCuentas.php
new file mode 100644
index 0000000..041ef60
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/SaldosCuentas.php
@@ -0,0 +1,109 @@
+sheetNameExists('Saldos cuentas')) {
+ return [];
+ }
+ $sheet = $excel->getSheetByName('Saldos cuentas');
+ $data = [];
+ $data['anterior'] = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->getCalculatedValue($sheet, 'C4'));
+ $data['actual'] = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->getCalculatedValue($sheet, 'C5'));
+ $data['uf'] = $this->getCalculatedValue($sheet, 'F4');
+ $data['usd'] = $this->getCalculatedValue($sheet, 'F5');
+
+ $titleRow = 7;
+ $data['sociedades'] = $this->getSociedades($sheet, $titleRow);
+
+ $titleRow += count($data['sociedades']);
+ while ($sheet->getCell("B{$titleRow}")->getValue() !== 'EMPRESA') {
+ $titleRow ++;
+ }
+ $data['movimientos'] = $this->getMovimientos($sheet, $titleRow);
+
+ return $data;
+ }
+
+ protected function getSociedades(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $titleRow = 7, int $startColumn = 2): array
+ {
+ $totalsColumn = $startColumn;
+ while ($sheet->getCell([$totalsColumn, $titleRow])->getValue() !== null && $sheet->getCell([$totalsColumn, $titleRow])->getValue() !== 'Total Cuentas') {
+ $totalsColumn ++;
+ }
+ $rowIndex = $titleRow + 1;
+ $sociedades = [];
+ while ($rowIndex < 100 and $sheet->getCell("B{$rowIndex}")->getValue() !== 'TOTAL') {
+ $sociedad = new stdClass();
+ $sociedad->razon = $sheet->getCell("B{$rowIndex}")->getValue();
+ $sociedad->cuentas = [];
+ $cuentaColumnIndex = 3;
+ $cuenta = new stdClass();
+ while ($cuentaColumnIndex < $totalsColumn) {
+ $cuenta->banco = $sheet->getCell([$cuentaColumnIndex ++, $rowIndex])->getValue() ?? '';
+ $cuenta->numero = $sheet->getCell([$cuentaColumnIndex ++, $rowIndex])->getValue() ?? '';
+ $cuenta->anterior = $this->getCalculatedValue($sheet, $cuentaColumnIndex ++, $rowIndex);
+ $cuenta->actual = $this->getCalculatedValue($sheet, $cuentaColumnIndex ++, $rowIndex);
+ $cuenta->diferencia = $this->getCalculatedValue($sheet, $cuentaColumnIndex ++, $rowIndex);
+ $cuenta->ffmm = $this->getCalculatedValue($sheet, $cuentaColumnIndex ++, $rowIndex);
+ $cuenta->deposito = $this->getCalculatedValue($sheet, $cuentaColumnIndex ++, $rowIndex);
+ $cuenta->saldo = $this->getCalculatedValue($sheet, $cuentaColumnIndex ++, $rowIndex);
+
+ $sociedad->cuentas []= $cuenta;
+
+ if ($sheet->getCell([$cuentaColumnIndex, $rowIndex])->getValue() === null) {
+ break;
+ }
+ $cuenta = new stdClass();
+ }
+ $sociedades []= $sociedad;
+ $rowIndex ++;
+ }
+ return $sociedades;
+ }
+ protected function getMovimientos(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $titleRow, int $startColumn = 2): array
+ {
+ $data = [];
+ $titles = $this->getTableTitles($sheet, $titleRow, $startColumn, 15);
+
+ $totalRow = $titleRow + 2;
+ $data['total'] = $this->getCalculatedValue($sheet, "V{$totalRow}");
+ $rowIndex = $titleRow + 4;
+ $depositos = [];
+ while ($sheet->getCell("B{$rowIndex}")->getValue() !== 'INGRESOS') {
+ if ( $sheet->getCell("B{$rowIndex}")->getValue() !== null) {
+ $depositos []= $this->getRow($sheet, $titles, $titleRow, $rowIndex, $startColumn);
+ }
+ $rowIndex ++;
+ }
+ $data['depositos'] = $depositos;
+
+ $rowIndex ++;
+ $ingresos = [];
+ while ($sheet->getCell("B{$rowIndex}")->getValue() !== 'EGRESOS') {
+ if ($sheet->getCell("B{$rowIndex}")->getValue() !== null) {
+ $ingresos []= $this->getRow($sheet, $titles, $titleRow, $rowIndex, $startColumn);
+ }
+ $rowIndex ++;
+ }
+ $data['ingresos'] = $ingresos;
+
+ $rowIndex ++;
+ $egresos = [];
+ while ($sheet->getCell("B{$rowIndex}")->getValue() !== 'TOTAL') {
+ if ($sheet->getCell("B{$rowIndex}")->getValue() === null) {
+ break;
+ }
+ $egresos [] = $this->getRow($sheet, $titles, $titleRow, $rowIndex, $startColumn);
+ $rowIndex ++;
+ }
+ $data['egresos'] = $egresos;
+
+ return $data;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/Sheet.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/Sheet.php
new file mode 100644
index 0000000..a0293ef
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Input/Excel/Sheet.php
@@ -0,0 +1,73 @@
+getCell($columnIndex)->getCalculatedValue() ?? $default;
+ }
+ return $sheet->getCell("{$columnIndex}{$rowIndex}")->getCalculatedValue() ?? $default;
+ }
+ return $sheet->getCell([$columnIndex, $rowIndex])->getCalculatedValue() ?? $default;
+ } catch (PhpSpreadsheet\Calculation\Exception $e) {
+ $this->logger->error($e->getMessage());
+ return $default;
+ }
+ }
+ protected function getTableTitles(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $titleRow, int $columnOffset, int $maxColumns, string $duplicateSuffix = '', array $cutoffCharacters = []): array
+ {
+ $titles = [];
+ $columnIndex = $columnOffset;
+ while ($columnIndex < $maxColumns or $sheet->getCell([$columnIndex, $titleRow])->getValue() !== null) {
+ if ($sheet->getCell([$columnIndex, $titleRow])->getValue() !== null) {
+ $title = $this->transformTitle($sheet->getCell([$columnIndex, $titleRow])->getValue(), $cutoffCharacters);
+ if (in_array($title, $titles)) {
+ $title .= $duplicateSuffix;
+ }
+ $titles []= $title;
+ }
+ $columnIndex ++;
+ }
+ return $titles;
+ }
+ protected function getRow(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $titles, int $titleRow, int $rowIndex, int $columnOffset): object
+ {
+ $row = [];
+ $columnIndex = $columnOffset;
+ $titleIndex = 0;
+ $currentTitle = $this->transformTitle($sheet->getCell([$columnIndex, $titleRow])->getValue());
+ while ($columnIndex < count($titles) * 3 and $currentTitle !== last($titles)) {
+ if ($sheet->getCell([$columnIndex, $titleRow])->getValue() === null) {
+ $columnIndex ++;
+ continue;
+ }
+ if (str_contains($titles[$titleIndex], 'fecha')) {
+ $row[$titles[$titleIndex ++]] = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->getCalculatedValue($sheet, $columnIndex ++, $rowIndex));
+ continue;
+ }
+ $row[$titles[$titleIndex ++]] = $this->getCalculatedValue($sheet, $columnIndex ++, $rowIndex);
+ }
+
+ return (object) $row;
+ }
+ protected function transformTitle(string $title, array $cutoffCharacters = []): string
+ {
+ $title = str_replace(' ', '', ucwords(mb_strtolower($title)));
+ $title = strtolower(substr($title, 0, 1)) . substr($title, 1);
+ foreach ($cutoffCharacters as $cutoffCharacter) {
+ if (str_contains($title, $cutoffCharacter)) {
+ $title = substr($title, 0, strpos($title, $cutoffCharacter));
+ }
+ }
+ return $title;
+ }
+
+ abstract public function load(PhpSpreadsheet\Spreadsheet $excel): array;
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Output.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Output.php
new file mode 100644
index 0000000..c3568fb
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Output.php
@@ -0,0 +1,226 @@
+ingresos';
+ const DAP_EGRESOS = 'dap->egresos';
+ const INGRESOS = 'ingresos';
+ const EGRESOS = 'egresos';
+ const TOTAL_ANTERIOR = 'anterior';
+ const TOTAL_ACTUAL = 'actual';
+ const TOTAL_FFMM = 'ffmm';
+ const TOTAL_DAP = 'deposito';
+
+ protected DateTimeInterface $anterior;
+ protected object $totales;
+ protected object $movimientos;
+
+ public function __construct(LoggerInterface $logger,
+ protected Repository\Inmobiliaria $inmobiliariaRepository,
+ protected Repository\Contabilidad\Deposito $depositoRepository,
+ protected Repository\Contabilidad\Cartola $cartolaRepository,
+ protected Repository\Contabilidad\Movimiento $movimientoRepository,
+ protected Service\Inmobiliaria\Cuenta $cuentaService,
+ protected Output\Excel $excelService,
+ protected Output\PDF $pdfService)
+ {
+ parent::__construct($logger);
+
+ $this->movimientos = new Output\Data\Movimientos(self::ORDEN_SOCIEDADES);
+ $this->totales = new Output\Data\Totales();
+ }
+
+ public function getAnterior(DateTimeInterface $fecha): DateTimeInterface
+ {
+ if (!isset($this->anterior)) {
+ $this->anterior = $fecha->sub(new DateInterval('P1D'));
+ if ($this->anterior->format('N') === '7') {
+ $this->anterior = $fecha->sub(new DateInterval('P3D'));
+ }
+ }
+ return $this->anterior;
+ }
+ public function build(DateTimeInterface $fecha): array
+ {
+ try {
+ $inmobiliarias = $this->inmobiliariaRepository->fetchAll();
+ } catch (Implement\Exception\EmptyResult) {
+ return [];
+ }
+ $data = $this->sortBySociedad($inmobiliarias);
+ $informe = ['sociedades' => []];
+ foreach ($data as $sociedad) {
+ $informe['sociedades'][$sociedad->rut] = $this->buildInmobiliaria($sociedad, $fecha);
+ }
+ $informe['movimientos'] = $this->buildMovimientos();
+ $informe['totales'] = $this->buildTotales();
+
+ //$this->buildInforme($fecha, $informe);
+
+ return $informe;
+ }
+ public function buildInforme(DateTimeInterface $fecha, array $data, string $type = 'Xlsx', ?string $filename = 'php://output'): void
+ {
+ $informe = $this->excelService->build($fecha, $data);
+ $this->excelService->save($fecha, $informe, $type, $filename);
+ }
+
+ protected function buildInmobiliaria(Model\Inmobiliaria $inmobiliaria, DateTimeInterface $fecha): object
+ {
+ $dataInmobiliaria = new Output\Data\Sociedad();
+ $dataInmobiliaria->sociedad = $inmobiliaria;
+ try {
+ $cuentas = $this->cuentaService->getAllActiveByInmobiliaria($inmobiliaria->rut);
+ } catch (Implement\Exception\EmptyResult) {
+ return $dataInmobiliaria;
+ }
+ foreach ($cuentas as $cuenta) {
+ $data = new Output\Data\Cuenta();
+ $data->banco = $cuenta->banco->nombre;
+ $data->numero = $cuenta->cuenta;
+ try {
+ $depositos = $this->depositoRepository->fetchByCuenta($cuenta->id);
+ foreach ($depositos as $deposito) {
+ if ($deposito->termino < $fecha) {
+ continue;
+ }
+ $data->deposito += $deposito->capital;
+ $this->addTotal(self::TOTAL_DAP, $deposito->capital);
+ $this->totales->saldo += $deposito->capital;
+
+ if ($deposito->inicio->format('Y-m-d') === $fecha->format('Y-m-d')) {
+ $this->addMovimientos(self::DAP_EGRESOS, [(object) [
+ 'cuenta' => $deposito->cuenta,
+ 'fecha' => $deposito->inicio,
+ 'cargo' => - $deposito->capital,
+ 'abono' => 0,
+ 'saldo' => - $deposito->capital,
+ 'glosa' => 'INVERSION DAP'
+ ]]);
+ }
+ if ($deposito->termino->format('Y-m-d') === $fecha->format('Y-m-d')) {
+ $data->deposito -= $deposito->capital;
+ $this->addTotal(self::TOTAL_DAP, -$deposito->capital);
+
+ $this->addMovimientos(self::DAP_INGRESOS, [(object) [
+ 'cuenta' => $deposito->cuenta,
+ 'fecha' => $deposito->termino,
+ 'cargo' => 0,
+ 'abono' => $deposito->futuro - $deposito->capital,
+ 'saldo' => $deposito->futuro - $deposito->capital,
+ 'glosa' => 'RESCATE DAP',
+ 'documento' => $deposito->id
+ ]]);
+ }
+ }
+ } catch (Implement\Exception\EmptyResult) {}
+ $anterior = $this->getAnterior($fecha);
+ try {
+ $cartola = $this->cartolaRepository->fetchLastByCuentaAndFecha($cuenta->id, $fecha);
+ $data->actual = $cartola->saldo;
+ //$anterior = $this->getAnterior($cartola->fecha);
+ } catch (Implement\Exception\EmptyResult) {}
+ try {
+ $cartola = $this->cartolaRepository->fetchLastByCuentaAndFecha($cuenta->id, $anterior);
+ $data->anterior = $cartola->saldo;
+ $this->totales->saldo += $cartola->saldo;
+ } catch (Implement\Exception\EmptyResult) {}
+ if ($data->diferencia() !== 0) {
+ try {
+ $movimientos = $this->movimientoRepository->fetchByCuentaAndFecha($cuenta->id, $fecha);
+ $this->addMovimientos(self::INGRESOS,
+ array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) {
+ return $movimiento->abono > 0;
+ }));
+ $this->addMovimientos(self::EGRESOS,
+ array_filter($movimientos, function(Model\Contabilidad\Movimiento $movimiento) {
+ return $movimiento->cargo > 0;
+ }));
+ } catch (Implement\Exception\EmptyResult) {}
+ }
+ $dataInmobiliaria->cuentas []= $data;
+
+ $this->addTotal(
+ [self::TOTAL_ANTERIOR, self::TOTAL_ACTUAL],
+ [$data->anterior, $data->actual]
+ );
+ }
+
+ return $dataInmobiliaria;
+ }
+ protected function buildMovimientos(): array
+ {
+ return $this->movimientos->build();
+ }
+ protected function buildTotales(): object
+ {
+ return $this->totales;
+ }
+ protected function addMovimientos(string $tipo, array $movimientos): Output
+ {
+ if (str_starts_with($tipo, 'dap')) {
+ list($d, $t) = explode('->', $tipo);
+ $this->movimientos->addDap($t, $movimientos);
+ return $this;
+ }
+ foreach ($movimientos as $movimiento) {
+ if ($tipo === 'ingresos' and str_contains(strtolower($movimiento->glosa), ' dap ')) {
+ $this->movimientos->updateDap($movimiento);
+ continue;
+ }
+ $this->movimientos->{$tipo} []= $movimiento;
+ }
+ return $this;
+ }
+ protected function addTotal(string|array $tipo, int|array $total): Output
+ {
+ if (is_array($tipo)) {
+ foreach ($tipo as $i => $t) {
+ $this->addTotal($t, $total[$i]);
+ }
+ return $this;
+ }
+ $this->totales->{$tipo} += $total;
+ return $this;
+ }
+ protected function sortBySociedad(array $data): array
+ {
+ $temp = [];
+ foreach (self::ORDEN_SOCIEDADES as $sociedad_rut) {
+ foreach ($data as $inmobiliaria) {
+ if ($inmobiliaria->rut === $sociedad_rut) {
+ $temp []= $inmobiliaria;
+ }
+ }
+ }
+ foreach ($data as $inmobiliaria) {
+ if (!in_array($inmobiliaria, $temp)) {
+ $temp []= $inmobiliaria;
+ }
+ }
+ return $temp;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Cuenta.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Cuenta.php
new file mode 100644
index 0000000..fe951f2
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Cuenta.php
@@ -0,0 +1,21 @@
+actual - $this->anterior;
+ }
+ public function saldo(): int
+ {
+ return $this->diferencia() + $this->ffmm + $this->deposito;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Movimientos.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Movimientos.php
new file mode 100644
index 0000000..00131e3
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Movimientos.php
@@ -0,0 +1,87 @@
+dap = new class()
+ {
+ public array $ingresos = [];
+ public array $egresos = [];
+ };
+ }
+ public object $dap;
+ public array $ingresos = [];
+ public array $egresos = [];
+
+ const INGRESOS = 'ingresos';
+ const EGRESOS = 'egresos';
+ public function addDap(string $tipo, array $movimientos)
+ {
+ foreach ($movimientos as $movimiento) {
+ $this->dap->{$tipo} []= $movimiento;
+ }
+ return $this;
+ }
+ public function updateDap(object $movimiento): void
+ {
+ foreach ($this->ingresos as $ingreso) {
+ if ($movimiento->cuenta->inmobiliaria->rut !== $ingreso->cuenta->inmobiliaria->rut) {
+ continue;
+ }
+ if ($movimiento->fecha->format('Y-m-d') !== $ingreso->fecha->format('Y-m-d')) {
+ continue;
+ }
+ if ($movimiento->documento !== $ingreso->documento) {
+ continue;
+ }
+ $ingreso->glosa = $movimiento->glosa;
+ break;
+ }
+ }
+ public function build(): array
+ {
+ $this->dap->ingresos = $this->sortBySociedades($this->dap->ingresos);
+ $this->dap->egresos = $this->sortBySociedades($this->dap->egresos);
+ $this->ingresos = $this->sortBySociedades($this->ingresos);
+ $this->egresos = $this->sortBySociedades($this->egresos);
+ return [
+ 'capital dap' => [
+ 'ingresos' => $this->dap->ingresos,
+ 'egresos' => $this->dap->egresos
+ ],
+ 'ingresos' => $this->ingresos,
+ 'egresos' => $this->egresos
+ ];
+ }
+
+ private function sortBySociedades(array $movimientos): array
+ {
+ $temp = [];
+ foreach ($this->ordenSociedades as $sociedad_rut) {
+ $date = null;
+ foreach ($movimientos as $movimiento) {
+ if ($date === null) {
+ $date = $movimiento->fecha;
+ }
+ if ($movimiento->fecha !== $date) {
+ if ($movimiento->cuenta->inmobiliaria->rut === $sociedad_rut) {
+ $temp []= $movimiento;
+ }
+ $date = $movimiento->fecha;
+ continue;
+ }
+ if ($movimiento->cuenta->inmobiliaria->rut === $sociedad_rut) {
+ $temp []= $movimiento;
+ }
+ }
+ }
+ foreach ($movimientos as $movimiento) {
+ if (!in_array($movimiento, $temp)) {
+ $temp []= $movimiento;
+ }
+ }
+ return $temp;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Sociedad.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Sociedad.php
new file mode 100644
index 0000000..e28ae8e
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Sociedad.php
@@ -0,0 +1,34 @@
+cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->actual;
+ }, 0);
+ }
+ public function ffmm(): int
+ {
+ return array_reduce($this->cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->ffmm;
+ }, 0);
+ }
+ public function deposito(): int
+ {
+ return array_reduce($this->cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->deposito;
+ }, 0);
+ }
+ public function caja(): int
+ {
+ return array_reduce($this->cuentas, function(int $sum, $cuenta) {
+ return $sum + $cuenta->saldo();
+ }, 0);
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Totales.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Totales.php
new file mode 100644
index 0000000..b59c865
--- /dev/null
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Data/Totales.php
@@ -0,0 +1,36 @@
+actual - $this->anterior;
+ }
+ public function saldo(): int
+ {
+ return $this->diferencia() + $this->ffmm + $this->deposito;
+ }
+ public function cuentas(): int
+ {
+ return $this->actual;
+ }
+ public function ffmms(): int
+ {
+ return $this->ffmm;
+ }
+ public function depositos(): int
+ {
+ return $this->deposito;
+ }
+ public function caja(): int
+ {
+ return $this->cuentas() + $this->ffmms() + $this->depositos();
+ }
+}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Excel.php
similarity index 99%
rename from app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php
rename to app/src/Service/Contabilidad/Informe/Tesoreria/Output/Excel.php
index fe83b77..d40ea0d 100644
--- a/app/src/Service/Contabilidad/Informe/Tesoreria/Excel.php
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/Excel.php
@@ -1,8 +1,8 @@
fillColumns($sheet, $columns, $styles, $startRow);
$rowIndex = $startRow + 1;
- $sociedades = $data['inmobiliarias'];
+ $sociedades = $data['sociedades'];
foreach ($sociedades as $dataSociedad) {
$rowIndex += $this->fillSociedad($sheet, $dataSociedad, $rowIndex);
}
@@ -461,7 +461,7 @@ class Excel extends Ideal\Service
protected function fillSociedad(PhpSpreadsheet\Worksheet\Worksheet $sheet, object $dataSociedad, int $baseRowIndex): int
{
$rowIndex = $baseRowIndex;
- $sheet->getCell("B{$rowIndex}")->setValue($dataSociedad->inmobiliaria->razon);
+ $sheet->getCell("B{$rowIndex}")->setValue($dataSociedad->sociedad->razon);
foreach ($dataSociedad->cuentas as $cuentaRowIndex => $cuenta) {
$this->fillCuenta($sheet, $cuenta, 3, $baseRowIndex + $cuentaRowIndex);
}
diff --git a/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/PDF.php
similarity index 66%
rename from app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php
rename to app/src/Service/Contabilidad/Informe/Tesoreria/Output/PDF.php
index 7357299..2c050e6 100644
--- a/app/src/Service/Contabilidad/Informe/Tesoreria/PDF.php
+++ b/app/src/Service/Contabilidad/Informe/Tesoreria/Output/PDF.php
@@ -1,5 +1,5 @@
movimientoRepository->fetchAmountBySociedadAndMes($sociedad_rut, $mes, $amount));
}
+ public function getByCuentaAndFechaAndGlosaAndCargoAndAbonoAndSaldo(int $cuenta_id, DateTimeInterface $fecha, string $glosa, int $cargo, int $abono, int $saldo): Model\Contabilidad\Movimiento
+ {
+ return $this->process($this->movimientoRepository->fetchByCuentaAndFechaAndGlosaAndCargoAndAbonoAndSaldo($cuenta_id, $fecha, $glosa, $cargo, $abono, $saldo));
+ }
+ public function add(array $data): Model\Contabilidad\Movimiento
+ {
+ try {
+ $movimiento = $this->movimientoRepository->fetchByCuentaAndFechaAndGlosaAndCargoAndAbonoAndSaldo($data['cuenta_id'], $data['fecha'], $data['glosa'], $data['cargo'] ?? 0, $data['abono'] ?? 0, $data['saldo']);
+ } catch (Implement\Exception\EmptyResult) {
+ $data['fecha'] = $data['fecha']->format('Y-m-d');
+ $movimiento = $this->movimientoRepository->create($data);
+ $movimiento = $this->movimientoRepository->save($movimiento);
+ }
+ $movimiento = $this->setDetalles($movimiento, $data);
+ return $this->process($movimiento);
+ }
public function setDetalles(Model\Contabilidad\Movimiento $movimiento, array $data): Model\Contabilidad\Movimiento
{
try {
@@ -48,9 +65,20 @@ class Movimiento extends Service
public function process(Model\Contabilidad\Movimiento $movimiento): Model\Contabilidad\Movimiento
{
- $movimiento->addFactory('detalles', (new Implement\Repository\Factory())->setCallable(function(int $movimiento_id) {
- return $this->detalleRepository->fetchByMovimiento($movimiento_id);
- })->setArgs(['movimiento_id' => $movimiento->id]));
+ $movimiento->addFactory('detalles', (new Implement\Repository\Factory())
+ ->setCallable(function(int $movimiento_id) {
+ try {
+ return $this->detalleRepository->fetchByMovimiento($movimiento_id);
+ } catch (Implement\Exception\EmptyResult) {
+ return null;
+ }
+ })
+ ->setArgs(['movimiento_id' => $movimiento->id]));
+ /*$movimiento->addFactory('auxiliares', (new Implement\Repository\Factory())
+ ->setCallable(function(int $movimiento_id) {
+ return $this->auxiliarService->getByMovimiento($movimiento_id);
+ })
+ ->setArgs(['movimiento_id' => $movimiento->id]));*/
return $movimiento;
}
}
diff --git a/app/src/Service/Contabilidad/Movimiento/Auxiliar.php b/app/src/Service/Contabilidad/Movimiento/Auxiliar.php
new file mode 100644
index 0000000..23fba55
--- /dev/null
+++ b/app/src/Service/Contabilidad/Movimiento/Auxiliar.php
@@ -0,0 +1,42 @@
+auxiliarRepository->fetchByMovimiento($movimiento_id));
+ } catch (Implement\Exception\EmptyResult) {
+ return null;
+ }
+ }
+
+ protected function process(Model\Contabilidad\Movimiento\Auxiliar $auxiliar): Model\Contabilidad\Movimiento\Auxiliar
+ {
+ $auxiliar->addFactory('detalles', (new Implement\Repository\Factory())
+ ->setCallable(function(int $auxiliar_id) {
+ try {
+ return $this->detalleRepository->fetchByAuxiliar($auxiliar_id);
+ } catch (Implement\Exception\EmptyResult) {
+ return null;
+ }
+ })
+ ->setArgs(['auxiliar_id' => $auxiliar->id]));
+ return $auxiliar;
+ }
+}
diff --git a/app/src/Service/Contabilidad/Nubox.php b/app/src/Service/Contabilidad/Nubox.php
index 31d18e5..d100e5c 100644
--- a/app/src/Service/Contabilidad/Nubox.php
+++ b/app/src/Service/Contabilidad/Nubox.php
@@ -40,9 +40,6 @@ class Nubox extends Ideal\Service
->withHeader('Content-Type', 'application/json')
->withHeader('Accept', 'application/json');
$response = $this->client->sendRequest($request);
- if ($response->getStatusCode() !== 200) {
- throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode());
- }
$sistemas = json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
$this->setToken($inmobiliaria_rut, $response->getHeaderLine('Token'))
@@ -133,9 +130,6 @@ class Nubox extends Ideal\Service
];
$uri = 'contabilidad/libro-mayor?' . http_build_query($query);
$response = $this->send($uri, $inmobiliaria_rut);
- if ($response->getStatusCode() !== 200) {
- throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode());
- }
return json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
}
public function getLibroDiario(int $inmobiliaria_rut, DateTimeInterface $from, DateTimeInterface $to): array
@@ -157,10 +151,6 @@ class Nubox extends Ideal\Service
];
$uri = 'contabilidad/libro-diario?' . http_build_query($query);
$response = $this->send($uri, $inmobiliaria_rut);
- if ($response->getStatusCode() !== 200) {
- $this->logger->debug($uri);
- throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode());
- }
return json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
}
public function getMesCuenta(int $inmobiliaria_rut, string $cuenta, DateTimeInterface $mes): array
@@ -186,11 +176,29 @@ class Nubox extends Ideal\Service
];
$uri = 'contabilidad/libro-mayor?' . http_build_query($query);
$response = $this->send($uri, $inmobiliaria_rut);
- if ($response->getStatusCode() !== 200) {
- throw new Exception\HttpResponse($response->getReasonPhrase(), $response->getStatusCode());
- }
return json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
}
+ public function getFacturas(int $inmobiliaria_rut, DateTimeInterface $dia): array
+ {
+ //$inmobiliaria = $this->nuboxRepository->fetchByInmobiliaria($inmobiliaria_rut);
+ $query = [
+ 'factura',
+ 'documento',
+ '78017310-6',
+ 'estadoVenta',
+ 551,
+ 'FAC-EL',
+ 1
+ ];
+ $uri = implode('/', $query);
+ $response = $this->send($uri, $inmobiliaria_rut);
+ $content = json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
+ if (!is_array($content)) {
+ $this->logger->error($content);
+ return [];
+ }
+ return $content;
+ }
private function send(string $uri, int $inmobiliaria_rut, string $method = 'GET', ?StreamInterface $body = null): ResponseInterface
{
@@ -200,6 +208,12 @@ class Nubox extends Ideal\Service
if ($body !== null) {
$request = $request->withBody($body);
}
- return $this->client->sendRequest($request);
+ $response = $this->client->sendRequest($request);
+ if ($response->getStatusCode() !== 200) {
+ $json = json_decode($response->getBody()->getContents(), JSON_OBJECT_AS_ARRAY);
+ $message = $json['Message'] ?? '';
+ throw new Exception\HttpResponse($response->getReasonPhrase(), $message, $response->getStatusCode());
+ }
+ return $response;
}
}
diff --git a/app/src/Service/Persona.php b/app/src/Service/Persona.php
new file mode 100644
index 0000000..0330f08
--- /dev/null
+++ b/app/src/Service/Persona.php
@@ -0,0 +1,56 @@
+process($this->personaRepository->fetchByRut($rut));
+ }
+ public function add(array $data): Model\Persona
+ {
+ try {
+ $persona = $this->personaRepository->fetchByRut($data['rut']);
+ } catch (Implement\Exception\EmptyResult) {
+ $persona = $this->personaRepository->create($data);
+ $persona = $this->personaRepository->save($persona);
+ }
+ if (isset($data['email']) or isset($data['telefono'])) {
+ $datosData = ['persona_rut' => $persona->rut];
+ if (isset($data['email'])) {
+ $datosData['email'] = $data['email'];
+ }
+ if (isset($data['telefono'])) {
+ $datosData['telefono'] = $data['telefono'];
+ }
+ try {
+ $datos = $this->datosPersonaRepository->fetchByPersona($persona->rut);
+ $this->datosPersonaRepository->edit($datos, $data);
+ } catch (Implement\Exception\EmptyResult) {
+ $datos = $this->datosPersonaRepository->create($datosData);
+ $this->datosPersonaRepository->save($datos);
+ }
+ }
+ return $this->process($persona);
+ }
+
+ protected function process(Model\Persona $persona): Model\Persona
+ {
+ $persona->addFactory('datos', (new Implement\Repository\Factory())
+ ->setCallable([$this->datosPersonaRepository, 'fetchByPersona'])
+ ->setArgs(['persona_rut' => $persona->rut]));
+ return $persona;
+ }
+}
diff --git a/app/src/Service/Sociedad.php b/app/src/Service/Sociedad.php
new file mode 100644
index 0000000..c2844bb
--- /dev/null
+++ b/app/src/Service/Sociedad.php
@@ -0,0 +1,85 @@
+process($this->sociedadRepository->fetchById($sociedad_rut));
+ } catch (EmptyResult) {
+ return null;
+ }
+ }
+ public function getAll(?string $orderBy = null): array
+ {
+ try {
+ return array_map([$this, 'process'], $this->sociedadRepository->fetchAll($orderBy));
+ } catch (EmptyResult) {
+ return [];
+ }
+ }
+ public function add(array $data): ?Model\Sociedad
+ {
+ try {
+ return $this->process($this->sociedadRepository->fetchById($data['rut']));
+ } catch (EmptyResult) {
+ try {
+ return $this->process($this->sociedadRepository->save($this->sociedadRepository->create($data)));
+ } catch (EmptyResult) {
+ return null;
+ }
+ }
+ }
+ public function edit(int $sociedad_rut, array $data): ?Model\Sociedad
+ {
+ try {
+ return $this->process(
+ $this->sociedadRepository->edit(
+ $this->sociedadRepository->fetchById($sociedad_rut), $data));
+ } catch (EmptyResult) {
+ return null;
+ }
+ }
+ public function delete(int $sociedad_rut): bool
+ {
+ try {
+ $this->sociedadRepository->remove($this->sociedadRepository->fetchById($sociedad_rut));
+ return true;
+ } catch (EmptyResult) {
+ return false;
+ }
+ }
+ public function asignar(int $inmobiliaria_rut, int $sociedad_rut): ?Model\Inmobiliaria\Proveedor
+ {
+ try {
+ $inmobiliaria = $this->inmobiliariaRepository->fetchById($inmobiliaria_rut);
+ $sociedad = $this->sociedadRepository->fetchById($sociedad_rut);
+ $data = [
+ 'inmobiliaria_rut' => $inmobiliaria->rut,
+ 'sociedad_rut' => $sociedad->rut,
+ ];
+ return $this->proveedorRepository->save($this->proveedorRepository->create($data));
+ } catch (EmptyResult) {
+ return null;
+ }
+ }
+
+ protected function process(Model\Sociedad $sociedad): Model\Sociedad
+ {
+ return $sociedad;
+ }
+}
diff --git a/app/src/Service/Venta/Factura.php b/app/src/Service/Venta/Factura.php
new file mode 100644
index 0000000..7715810
--- /dev/null
+++ b/app/src/Service/Venta/Factura.php
@@ -0,0 +1,95 @@
+facturaRepository->fetchAll($orderBy));
+ } catch (Implement\Exception\EmptyResult) {
+ return [];
+ }
+ }
+ public function getByVenta(int $venta_id): array
+ {
+ try {
+ return array_map([$this, 'process'], $this->facturaRepository->fetchByVenta($venta_id));
+ } catch (Implement\Exception\EmptyResult) {
+ return [];
+ }
+ }
+ public function getById(int $factura_id): ?Model\Venta\Factura
+ {
+ try {
+ return $this->process($this->facturaRepository->fetchById($factura_id));
+ } catch (Implement\Exception\EmptyResult) {
+ return null;
+ }
+ }
+ public function getByVentaAndIndex(int $venta_id, int $index): ?Model\Venta\Factura
+ {
+ try {
+ return $this->process($this->facturaRepository->fetchByVentaAndIndex($venta_id, $index));
+ } catch (Implement\Exception\EmptyResult) {
+ return null;
+ }
+ }
+
+ public function add(array $data): Model\Venta\Factura
+ {
+ $factura = $this->getByVentaAndIndex($data['venta_id'], $data['index']);
+ if ($factura !== null) {
+ return $factura;
+ }
+ $factura = $this->facturaRepository->save($this->facturaRepository->create($data));
+ $tipo = $this->tipoRepository->fetchByDescripcion('generada');
+ $this->estadoRepository->save($this->estadoRepository->create([
+ 'factura_id' => $factura->id,
+ 'tipo_id' => $tipo->id,
+ 'fecha' => $factura->fecha
+ ]));
+ return $this->process($factura);
+ }
+ public function aprobar(int $factura_id, DateTimeInterface $fecha): ?Model\Venta\Factura
+ {
+ try {
+ $factura = $this->facturaRepository->fetchById($factura_id);
+ $tipo = $this->tipoRepository->fetchByDescripcion('aprobada');
+ $this->estadoRepository->save($this->estadoRepository->create([
+ 'factura_id' => $factura->id,
+ 'tipo_id' => $tipo->id,
+ 'fecha' => $fecha->format('Y-m-d')
+ ]));
+ return $this->process($factura);
+ } catch (Implement\Exception\EmptyResult) {
+ $this->logger->error('Error al aprobar factura', ['factura_id' => $factura_id]);
+ return null;
+ }
+ }
+
+ protected function process(Model\Venta\Factura $factura): Model\Venta\Factura
+ {
+ $factura->addFactory('estados', (new Implement\Repository\Factory())
+ ->setCallable(function($factura_id) {
+ return $this->estadoRepository->fetchByFactura($factura_id);
+ })
+ ->setArgs(['factura_id' => $factura->id]));
+ return $factura;
+ }
+}
diff --git a/app/src/Service/Venta/Propietario.php b/app/src/Service/Venta/Propietario.php
index 0882104..a0de35a 100644
--- a/app/src/Service/Venta/Propietario.php
+++ b/app/src/Service/Venta/Propietario.php
@@ -94,7 +94,7 @@ class Propietario extends Service
if ($sociedad->datos->direccion->id !== $mapped_data['direccion']) {
$edits['direccion'] = $mapped_data['direccion'];
}
- if ($sociedad->representante->rut !== $mapped_data['representante']) {
+ if ($sociedad->contacto->rut !== $mapped_data['representante']) {
$edits['representante'] = $mapped_data['representante'];
}
$sociedad = $this->propietarioRepository->edit($sociedad, $edits);
diff --git a/php-memory.ini b/php-memory.ini
new file mode 100644
index 0000000..50601e5
--- /dev/null
+++ b/php-memory.ini
@@ -0,0 +1,2 @@
+memory_limit = 512M
+max_execution_time = 300
diff --git a/php.ini.bak b/php.ini.bak
new file mode 100644
index 0000000..b3d2738
Binary files /dev/null and b/php.ini.bak differ
diff --git a/redisinsight.compose.yml b/redisinsight.compose.yml
new file mode 100644
index 0000000..b813053
--- /dev/null
+++ b/redisinsight.compose.yml
@@ -0,0 +1,14 @@
+services:
+ insight:
+ profiles:
+ - insight
+ container_name: incoviba_insight
+ image: redis/redisinsight:latest
+ restart: unless-stopped
+ volumes:
+ - redisinsight:/data
+ ports:
+ - "5540:5540"
+
+volumes:
+ redisinsight: {}