Merge branch 'temp' into develop
This commit is contained in:
@ -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
|
||||
|
||||
|
9
api.compose.yml
Normal file
9
api.compose.yml
Normal file
@ -0,0 +1,9 @@
|
||||
services:
|
||||
httpclient:
|
||||
profiles:
|
||||
- testing
|
||||
container_name: incoviba_client
|
||||
image: flawiddsouza/restfox
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${HTTPCLIENT_PORT:-4004}:4004"
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
use Incoviba\Controller\API\Contabilidad\Nubox;
|
||||
|
||||
$app->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']);
|
||||
});
|
||||
|
6
app/resources/routes/api/contabilidad/tesoreria.php
Normal file
6
app/resources/routes/api/contabilidad/tesoreria.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
use Incoviba\Controller\API\Contabilidad\Tesoreria;
|
||||
|
||||
$app->group('/tesoreria', function($app) {
|
||||
$app->post('/import[/]', [Tesoreria::class, 'import']);
|
||||
});
|
@ -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']);
|
||||
});
|
||||
|
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
use Incoviba\Controller\API\Inmobiliarias\Agentes;
|
||||
|
||||
$app->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']);
|
||||
});
|
||||
|
7
app/resources/routes/api/inmobiliarias/sociedades.php
Normal file
7
app/resources/routes/api/inmobiliarias/sociedades.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
use Incoviba\Controller\API\Inmobiliarias\Sociedades;
|
||||
|
||||
$app->group('/sociedades', function($app) {
|
||||
$app->post('/add[/]', [Sociedades::class, 'add']);
|
||||
$app->get('[/]', Sociedades::class);
|
||||
});
|
17
app/resources/routes/api/sociedades.php
Normal file
17
app/resources/routes/api/sociedades.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
use Incoviba\Controller\API\Sociedades;
|
||||
|
||||
$app->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');
|
||||
});
|
6
app/resources/routes/api/ventas/facturas.php
Normal file
6
app/resources/routes/api/ventas/facturas.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
use Incoviba\Controller\API\Ventas\Facturas;
|
||||
|
||||
$app->group('/facturas', function($app) {
|
||||
$app->post('/add[/]', [Facturas::class, 'add']);
|
||||
});
|
@ -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']);
|
||||
});
|
||||
|
4
app/resources/routes/contabilidad/cuadratura.php
Normal file
4
app/resources/routes/contabilidad/cuadratura.php
Normal file
@ -0,0 +1,4 @@
|
||||
<?php
|
||||
use Incoviba\Controller\Contabilidad;
|
||||
|
||||
$app->get('/cuadratura[/]', [Contabilidad::class, 'cuadratura']);
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
use Incoviba\Controller\Contabilidad;
|
||||
use Incoviba\Controller\Contabilidad\Tesoreria;
|
||||
|
||||
$app->group('/tesoreria', function($app) {
|
||||
$app->get('/import[/]', [Tesoreria::class, 'import']);
|
||||
$app->get('[/[{fecha}[/]]]', [Contabilidad::class, 'tesoreria']);
|
||||
});
|
||||
|
6
app/resources/routes/inmobiliarias/proveedores.php
Normal file
6
app/resources/routes/inmobiliarias/proveedores.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
use Incoviba\Controller\Inmobiliarias\Proveedores;
|
||||
|
||||
$app->group('/proveedores', function($app) {
|
||||
$app->get('[/]', Proveedores::class);
|
||||
});
|
@ -52,8 +52,7 @@
|
||||
<th class="right aligned">Cargo</th>
|
||||
<th class="right aligned">Abono</th>
|
||||
<th class="right aligned">Saldo</th>
|
||||
<th>Centro de Costo</th>
|
||||
<th>Detalle</th>
|
||||
<th class="right aligned"></th>
|
||||
<th>Orden</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -115,10 +114,85 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui modal" id="edit_modal" data-cartola="">
|
||||
<div class="header">
|
||||
Movimiento
|
||||
<div class="meta">
|
||||
<span id="edit_inmobiliaria"></span> |
|
||||
<span id="edit_cuenta"></span> |
|
||||
<span id="edit_fecha"></span> |
|
||||
<span id="edit_glosa"></span> |
|
||||
<span id="edit_cargo"></span> |
|
||||
<span id="edit_abono"></span> |
|
||||
<span id="edit_saldo"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<form class="ui form" id="edit_form">
|
||||
<input type="hidden" name="movimiento_id" value="" />
|
||||
<div class="equal width fields">
|
||||
<div class="field">
|
||||
<label>Centro de Costo</label>
|
||||
<div class="ui search selection dropdown">
|
||||
<input type="hidden" name="centro_costo_id" />
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Centro de Costo</div>
|
||||
<div class="menu">
|
||||
@foreach($centrosCostos as $centro)
|
||||
<div class="item" data-value="{{$centro->id}}">
|
||||
{{$centro->id}} - {{$centro->descripcion}}
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Categoría</label>
|
||||
<div class="ui input">
|
||||
<input type="text" name="categoria" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Detalle</label>
|
||||
<div class="ui input">
|
||||
<input type="text" name="detalle" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="equal width fields">
|
||||
<div class="field">
|
||||
<label>RUT</label>
|
||||
<div class="ui right labeled input">
|
||||
<input type="text" name="rut" />
|
||||
<div class="ui basic label">-<span id="digito"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Nombres</label>
|
||||
<div class="ui input">
|
||||
<input type="text" name="nombres" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Identificador</label>
|
||||
<div class="ui input">
|
||||
<input type="text" name="identificador" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="ui approve button">
|
||||
Editar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@include('layout.head.styles.datatables')
|
||||
@include('layout.body.scripts.datatables')
|
||||
@include('layout.body.scripts.rut')
|
||||
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
@ -126,7 +200,8 @@
|
||||
idx
|
||||
inmobiliaria = {
|
||||
rut: 0,
|
||||
razon: ''
|
||||
razon: '',
|
||||
sigla: ''
|
||||
}
|
||||
cuenta = {
|
||||
id: 0,
|
||||
@ -187,46 +262,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
update() {
|
||||
return {
|
||||
centro: (idx, centro_id) => {
|
||||
const id = this.movimientos[idx].id
|
||||
const url = '{{$urls->api}}/contabilidad/movimiento/' + id + '/detalles'
|
||||
const body = new FormData()
|
||||
body.set('centro_id', centro_id)
|
||||
return fetchAPI(url, {method: 'post', body}).then(response => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
response.json().then(json => {
|
||||
if (!json.status) {
|
||||
return
|
||||
}
|
||||
const dropdown = $(".dropdown[data-idx='" + idx + "']")
|
||||
dropdown.dropdown('set selected', json.centro.id, true)
|
||||
})
|
||||
})
|
||||
},
|
||||
detalle: (idx, detalle) => {
|
||||
const id = this.movimientos[idx].id
|
||||
const url = '{{$urls->api}}/contabilidad/movimiento/' + id + '/detalles'
|
||||
const body = new FormData()
|
||||
body.set('detalle', detalle)
|
||||
return fetchAPI(url, {method: 'post', body}).then(response => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
response.json().then(json => {
|
||||
if (!json.status) {
|
||||
return
|
||||
}
|
||||
const input = $("input[data-idx='" + idx + "']")
|
||||
input.val(json.detalle)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
draw() {
|
||||
return {
|
||||
form: ($form, inmobiliarias, first = false) => {
|
||||
@ -326,6 +361,10 @@
|
||||
onChange: (value, text, $choice) => {
|
||||
this.inmobiliaria.rut = value
|
||||
this.inmobiliaria.razon = text
|
||||
const inmobiliaria = diaria.data.inmobiliarias.find(inmobiliaria => inmobiliaria.rut === parseInt(value))
|
||||
if (typeof inmobiliaria !== 'undefined') {
|
||||
this.inmobiliaria.sigla = inmobiliaria.sigla
|
||||
}
|
||||
this.get().bancos(value).then(() => {
|
||||
$cuentas_dropdown.dropdown('change values', this.bancos)
|
||||
})
|
||||
@ -380,74 +419,42 @@
|
||||
cartola: ($tbody, dateFormatter, numberFormatter) => {
|
||||
this.movimientos.forEach((row, idx) => {
|
||||
$tbody.append(
|
||||
$('<tr></tr>').append(
|
||||
'<td>' + this.inmobiliaria.razon + '</td>' + "\n"
|
||||
+ '<td>' + this.cuenta.descripcion + '</td>' + "\n"
|
||||
+ '<td>' + dateFormatter.format(row.fecha) + '</td>' + "\n"
|
||||
+ '<td>' + row.glosa + '</td>' + "\n"
|
||||
+ '<td class="right aligned">' + (row.cargo === 0 ? '' : numberFormatter.format(row.cargo)) + '</td>' + "\n"
|
||||
+ '<td class="right aligned">' + (row.abono === 0 ? '' : numberFormatter.format(row.abono)) + '</td>' + "\n"
|
||||
+ '<td class="right aligned">' + (row.saldo === 0 ? '' : numberFormatter.format(row.saldo)) + '</td>' + "\n"
|
||||
).append(
|
||||
$('<td></td>').append(
|
||||
this.draw().centroCosto(idx)
|
||||
)
|
||||
).append(
|
||||
$('<td></td>').append(
|
||||
this.draw().detalle(idx)
|
||||
)
|
||||
).append(
|
||||
$('<td></td>').html(idx + 1)
|
||||
)
|
||||
[
|
||||
'<tr>',
|
||||
`<td>${this.inmobiliaria.sigla ?? this.inmobiliaria.razon}</td>`,
|
||||
`<td>${this.cuenta.descripcion}</td>`,
|
||||
`<td>${dateFormatter.format(row.fecha)}</td>`,
|
||||
`<td>${row.glosa}</td>`,
|
||||
`<td class="right aligned">${row.cargo === 0 ? '' : numberFormatter.format(row.cargo)}</td>`,
|
||||
`<td class="right aligned">${row.abono === 0 ? '' : numberFormatter.format(row.abono)}</td>`,
|
||||
`<td class="right aligned">${row.saldo === 0 ? '' : numberFormatter.format(row.saldo)}</td>`,
|
||||
'<td class="center aligned">',
|
||||
`<button class="ui icon button edit_movimiento" data-movimiento="${idx}">`,
|
||||
'<i class="edit icon"></i>',
|
||||
'</button>',
|
||||
'</td>',
|
||||
`<td>${(idx + 1).toString()}</td>`,
|
||||
].join("\n")
|
||||
)
|
||||
})
|
||||
Array.from(document.getElementsByClassName('edit_movimiento')).forEach(button => {
|
||||
button.addEventListener('click', function(clickEvent) {
|
||||
const idx = clickEvent.currentTarget.dataset['movimiento']
|
||||
const movimiento = this.movimientos[idx]
|
||||
const $modal = $('#edit_modal')
|
||||
$modal.attr('data-cartola', this.idx)
|
||||
$modal.find('#edit_inmobiliaria').html(this.inmobiliaria.razon)
|
||||
$modal.find('#edit_cuenta').html(this.cuenta.descripcion)
|
||||
$modal.find('#edit_fecha').html(dateFormatter.format(movimiento.fecha))
|
||||
$modal.find('#edit_glosa').html(movimiento.glosa)
|
||||
$modal.find('#edit_cargo').html(numberFormatter.format(movimiento.cargo))
|
||||
$modal.find('#edit_abono').html(numberFormatter.format(movimiento.abono))
|
||||
$modal.find('#edit_saldo').html(numberFormatter.format(movimiento.saldo))
|
||||
$modal.find('input[name="movimiento_id"]').val(movimiento.id)
|
||||
$modal.modal('show')
|
||||
}.bind(this))
|
||||
})
|
||||
},
|
||||
centroCosto: idx => {
|
||||
const centros = JSON.parse('{!! json_encode($centrosCostos) !!}')
|
||||
const menu = $('<div></div>').addClass('menu')
|
||||
centros.forEach(centro => {
|
||||
menu.append(
|
||||
'<div class="item" data-value="' + centro.id + '">'
|
||||
+ centro.id + ' - ' + centro.descripcion
|
||||
+ '</div>'
|
||||
)
|
||||
})
|
||||
const dropdown = $('<div></div>').addClass('ui search selection dropdown').attr('data-idx', idx).html(
|
||||
'<input type="hidden" name="centro" />' + "\n" +
|
||||
'<i class="dropdown icon"></i>' + "\n" +
|
||||
'<div class="default text">Centro de Costo</div>' + "\n"
|
||||
).append(menu)
|
||||
dropdown.dropdown({
|
||||
onChange: (value, text, $element) => {
|
||||
const idx = $element.parent().parent().data('idx')
|
||||
this.update().centro(idx, value)
|
||||
}
|
||||
})
|
||||
|
||||
if (this.movimientos[idx].centro !== '') {
|
||||
const cid = centros.findIndex(centro => centro.descripcion === this.movimientos[idx].centro)
|
||||
dropdown.dropdown('set selected', centros[cid].id, true)
|
||||
}
|
||||
return dropdown
|
||||
},
|
||||
detalle: idx => {
|
||||
const detalle = document.createElement('input')
|
||||
detalle.type = 'text'
|
||||
detalle.name = 'detalle' + idx
|
||||
detalle.placeholder = 'Detalle'
|
||||
detalle.setAttribute('data-idx', idx)
|
||||
const input = document.createElement('div')
|
||||
input.className = 'ui input'
|
||||
input.appendChild(detalle)
|
||||
if (this.movimientos[idx].detalle !== '') {
|
||||
detalle.value = this.movimientos[idx].detalle
|
||||
}
|
||||
detalle.addEventListener('blur', event => {
|
||||
const idx = event.currentTarget.dataset['idx']
|
||||
this.update().detalle(idx, event.currentTarget.value)
|
||||
})
|
||||
return $(input)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -460,8 +467,7 @@
|
||||
'cargo',
|
||||
'abono',
|
||||
'saldo',
|
||||
'centro',
|
||||
'detalle',
|
||||
'edit',
|
||||
'orden'
|
||||
];
|
||||
@endphp
|
||||
@ -471,17 +477,18 @@
|
||||
inmobiliarias: JSON.parse('{!! json_encode($inmobiliarias) !!}'),
|
||||
cartolasIdx: [],
|
||||
cartolas: [],
|
||||
movimientos: [],
|
||||
},
|
||||
dataTableConfig: {
|
||||
order: [[{{array_search('orden', $columns)}}, 'asc']],
|
||||
columnDefs: [
|
||||
{
|
||||
targets: [{{implode(',', array_keys(array_filter($columns, function($column) {return in_array($column, ['fecha', 'cargo', 'abono', 'saldo']);})))}}],
|
||||
width: '{{round((1/(count($columns) + 3 - 1)) * 100,2)}}%'
|
||||
targets: [{{implode(',', array_keys(array_filter($columns, function($column) {return in_array($column, ['fecha', 'cargo', 'abono', 'saldo', 'edit']);})))}}],
|
||||
width: '{{round((1/(count($columns) + 2)) * 100, 2)}}%'
|
||||
},
|
||||
{
|
||||
targets: [{{implode(',', array_keys(array_filter($columns, function($column) {return in_array($column, ['sociedad', 'cuenta', 'glosa', 'centro', 'detalle']);})))}}],
|
||||
width: '{{round((1/(count($columns) + 3 - 1)) * 2 * 100, 2)}}%'
|
||||
targets: [{{implode(',', array_keys(array_filter($columns, function($column) {return in_array($column, ['sociedad', 'cuenta', 'glosa']);})))}}],
|
||||
width: '{{round((1/(count($columns) + 2)) * 2 * 100, 2)}}%'
|
||||
},
|
||||
{
|
||||
targets: [{{array_search('orden', $columns)}}],
|
||||
@ -605,8 +612,12 @@
|
||||
cargo: row.cargo,
|
||||
abono: row.abono,
|
||||
saldo: row.saldo,
|
||||
centro: row.detalles?.centro_costo.descripcion ?? '',
|
||||
detalle: row.detalles?.detalle ?? ''
|
||||
centro: row.detalles?.centro_costo?.id ?? '',
|
||||
detalle: row.detalles?.detalle ?? '',
|
||||
categoria: row.detalles?.categoria ?? '',
|
||||
rut: row.detalles?.rut ?? '',
|
||||
nombres: row.detalles?.nombres ?? '',
|
||||
identificador: row.detalles?.identificador ?? ''
|
||||
}
|
||||
})
|
||||
const ayer = new Date(this.data.cartolas[cartolaIdx].fecha.getTime())
|
||||
@ -638,6 +649,51 @@
|
||||
$(this.ids.table.base).DataTable(this.dataTableConfig)
|
||||
|
||||
this.cartolas().add()
|
||||
|
||||
$(this.ids.editModal).modal({
|
||||
onApprove: $element => {
|
||||
const idx = $(this.ids.editModal).data('cartola')
|
||||
const id = $(this.ids.editModal).find('input[name="movimiento_id"]').val()
|
||||
const body = new FormData($(this.ids.editModal).find('form')[0])
|
||||
body.set('idx', idx)
|
||||
if (body.has('rut')) {
|
||||
body.set('rut', body.get('rut').replace(/\D/g, ''))
|
||||
body.set('digito', Rut.digitoVerificador(body.get('rut')))
|
||||
}
|
||||
const url = '{{$urls->api}}/contabilidad/movimiento/' + id + '/detalles'
|
||||
|
||||
return fetchAPI(url, {method: 'post', body}).then(response => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
response.json().then(json => {
|
||||
if (!json.status || json.movimiento === null || json.movimiento.detalles === null) {
|
||||
return
|
||||
}
|
||||
const idx = diaria.data.cartolas.findIndex(cartola => cartola.idx = json.input.idx)
|
||||
const movimiento = diaria.data.cartolas[idx].movimientos.find(movimiento => movimiento.id === id)
|
||||
movimiento.centro = json.movimiento.detalles.centro_costo.id
|
||||
movimiento.categoria = json.movimiento.detalles.categoria
|
||||
movimiento.detalle = json.movimiento.detalles.detalle
|
||||
movimiento.rut = json.movimiento.detalles.rut
|
||||
movimiento.digito = json.movimiento.detalles.digito
|
||||
movimiento.nombres = json.movimiento.detalles.nombres
|
||||
movimiento.identificador = json.movimiento.detalles.identificador
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
$(this.ids.editModal).find('.dropdown').dropdown()
|
||||
$(this.ids.editModal).find('[name="rut"]').on('input', function(event) {
|
||||
const rut = event.currentTarget.value
|
||||
const rut_clean = rut.replace(/\D/g, '')
|
||||
event.currentTarget.value = Rut.format(rut_clean)
|
||||
document.getElementById('digito').innerHTML = Rut.digitoVerificador(rut_clean)
|
||||
}.bind(this))
|
||||
const rut = $(this.ids.editModal).find('[name="rut"]')
|
||||
const rut_clean = rut.val().replace(/\D/g, '')
|
||||
rut.val(Rut.format(rut_clean))
|
||||
document.getElementById('digito').innerHTML = Rut.digitoVerificador(rut_clean)
|
||||
}
|
||||
}
|
||||
const manual = {
|
||||
@ -807,7 +863,8 @@
|
||||
add: '#add_button',
|
||||
process: '#process_button'
|
||||
},
|
||||
loader: '#loader'
|
||||
loader: '#loader',
|
||||
editModal: '#edit_modal'
|
||||
})
|
||||
manual.setup({
|
||||
modal: '#manual_modal',
|
||||
|
300
app/resources/views/contabilidad/cartolas/import.blade.php
Normal file
300
app/resources/views/contabilidad/cartolas/import.blade.php
Normal file
@ -0,0 +1,300 @@
|
||||
@extends('layout.base')
|
||||
|
||||
@section('page_content')
|
||||
<div class="ui container">
|
||||
<h1 class="ui header">
|
||||
Importar Cartola Diaria
|
||||
</h1>
|
||||
<div class="ui grid">
|
||||
<div class="right aligned sixteen wide column">
|
||||
<button class="ui green icon button" id="add_button">
|
||||
Agregar
|
||||
<i class="plus icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form class="ui form" id="cartola_form">
|
||||
</form>
|
||||
<div class="ui two columns grid">
|
||||
<div class="column">
|
||||
<button class="ui icon button" id="process_button">
|
||||
<i class="file excel icon"></i>
|
||||
Procesar
|
||||
</button>
|
||||
</div>
|
||||
<div class="right aligned column">
|
||||
<div class="ui inline active loader" id="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="ui celled table" id="movimientos" style="display: none;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Fecha</th>
|
||||
<th>Glosa</th>
|
||||
<th class="right aligned">Cargo</th>
|
||||
<th class="right aligned">Abono</th>
|
||||
<th class="right aligned">Saldo</th>
|
||||
<th class="center aligned">Centro de Costo</th>
|
||||
<th>Categoría</th>
|
||||
<th>Detalle</th>
|
||||
<th>RUT</th>
|
||||
<th>Nombres</th>
|
||||
<th class="center aligned">Identificador</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
@endsection
|
||||
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
class Cartola {
|
||||
props
|
||||
ids
|
||||
constructor({index, ids}) {
|
||||
this.props = {
|
||||
index
|
||||
}
|
||||
this.ids = ids
|
||||
}
|
||||
get sociedad() {
|
||||
return $(`#${this.ids.sociedad}${this.props.index}`).dropdown('get value')
|
||||
}
|
||||
get banco() {
|
||||
return $(`#${this.ids.banco}${this.props.index}`).dropdown('get value')
|
||||
}
|
||||
get file() {
|
||||
return $(`#archivo${this.props.index}`)[0].files[0]
|
||||
}
|
||||
get data() {
|
||||
return {
|
||||
sociedad_rut: this.sociedad,
|
||||
banco_id: this.banco,
|
||||
file: this.file,
|
||||
index: this.props.index
|
||||
}
|
||||
}
|
||||
draw({sociedades, bancos}) {
|
||||
const output = [
|
||||
`<div class="fields" data-idx="${this.props.index}">`,
|
||||
'<div class="six wide field">',
|
||||
'<label>Sociedad</label>',
|
||||
`<div class="ui search selection dropdown" id="${this.ids.sociedad}${this.props.index}">`,
|
||||
`<input type="hidden" name="sociedad_rut${this.props.index}" />`,
|
||||
'<i class="dropdown icon"></i>',
|
||||
'<div class="default text">Sociedad</div>',
|
||||
'<div class="menu">',
|
||||
...sociedades.map(sociedad => {
|
||||
return [
|
||||
`<div class="item" data-value="${sociedad.rut}">${sociedad.razon}</div>`
|
||||
].join("\n")
|
||||
}),
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="two wide field">',
|
||||
'<label>Banco</label>',
|
||||
`<div class="ui search selection dropdown" id="${this.ids.banco}${this.props.index}">`,
|
||||
`<input type="hidden" name="banco_id${this.props.index}" />`,
|
||||
'<i class="dropdown icon"></i>',
|
||||
'<div class="default text">Banco</div>',
|
||||
'<div class="menu">',
|
||||
...bancos.map(banco => {
|
||||
return [
|
||||
`<div class="item" data-value="${banco.id}">${banco.nombre}</div>`
|
||||
].join("\n")
|
||||
}),
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="six wide field">',
|
||||
'<label>Archivo</label>',
|
||||
'<div class="ui file action input">',
|
||||
`<input type="file" name="archivo${this.props.index}" id="archivo${this.props.index}" />`,
|
||||
'<div class="ui icon button" id="archivo_button">',
|
||||
'<i class="file icon"></i>',
|
||||
'Seleccionar',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
]
|
||||
if (this.props.index > 1) {
|
||||
output.push(...[
|
||||
'<div class="field">',
|
||||
'<label> </label>',
|
||||
`<button class="ui red icon button remove" data-idx="${this.props.index}">`,
|
||||
'<i class="trash icon"></i>',
|
||||
'</button>',
|
||||
'</div>',
|
||||
])
|
||||
}
|
||||
output.push('</div>')
|
||||
return output.join("\n")
|
||||
}
|
||||
activate() {
|
||||
$(`#${this.ids.sociedad}${this.props.index}`).dropdown()
|
||||
$(`#${this.ids.banco}${this.props.index}`).dropdown()
|
||||
if (this.props.index > 1) {
|
||||
$(`.${this.ids.buttons.remove}[data-idx="${this.props.index}"]`).click(clickEvent => {
|
||||
const index = $(clickEvent.currentTarget).data('idx')
|
||||
this.remove(index)
|
||||
})
|
||||
}
|
||||
}
|
||||
remove(idx) {
|
||||
$(`.fields[data-idx=${idx}]`).remove()
|
||||
cartolas.data.cartolas = cartolas.data.cartolas.filter(cartola => cartola.props.index !== idx)
|
||||
cartolas.draw().form()
|
||||
}
|
||||
}
|
||||
class Movimiento {
|
||||
props
|
||||
constructor({fecha, glosa, cargo, abono, saldo, categoria, detalle, centro_costo, rut, nombres, identificador}) {
|
||||
this.props = {
|
||||
fecha,
|
||||
glosa,
|
||||
cargo,
|
||||
abono,
|
||||
saldo,
|
||||
categoria,
|
||||
detalle,
|
||||
centro_costo,
|
||||
rut,
|
||||
nombres,
|
||||
identificador
|
||||
}
|
||||
}
|
||||
draw({formatters}) {
|
||||
const fecha = new Date(this.props.fecha)
|
||||
return [
|
||||
'<tr>',
|
||||
`<td>${formatters.date.format(fecha)}</td>`,
|
||||
`<td>${this.props.glosa}</td>`,
|
||||
`<td class="right aligned">${formatters.number.format(this.props.cargo ?? 0)}</td>`,
|
||||
`<td class="right aligned">${formatters.number.format(this.props.abono ?? 0)}</td>`,
|
||||
`<td class="right aligned">${formatters.number.format(this.props.saldo)}</td>`,
|
||||
`<td class="center aligned">${this.props.centro_costo ?? ''}</td>`,
|
||||
`<td>${this.props.categoria ?? ''}</td>`,
|
||||
`<td>${this.props.detalle ?? ''}</td>`,
|
||||
`<td>${this.props.rut ?? ''}</td>`,
|
||||
`<td>${this.props.nombres ?? ''}</td>`,
|
||||
`<td class="center aligned">${this.props.identificador ?? ''}</td>`,
|
||||
'</tr>'
|
||||
].join("\n")
|
||||
}
|
||||
}
|
||||
const cartolas = {
|
||||
ids: {},
|
||||
data: {
|
||||
sociedades: {!! json_encode($inmobiliarias) !!},
|
||||
bancos: {!! json_encode($bancos) !!},
|
||||
cartolas: [],
|
||||
movimientos: [],
|
||||
},
|
||||
formatters: {
|
||||
number: new Intl.NumberFormat('es-CL', {minimumFractionDigits: 0, maximumFractionDigits: 0}),
|
||||
date: new Intl.DateTimeFormat('es-CL', {dateStyle: 'short', timeStyle: 'short'})
|
||||
},
|
||||
add() {
|
||||
return {
|
||||
cartola: () => {
|
||||
const idx = cartolas.data.cartolas.length + 1
|
||||
const cartola = new Cartola({index: idx, ids: cartolas.ids.cartolas})
|
||||
cartolas.data.cartolas.push(cartola)
|
||||
cartolas.draw().form()
|
||||
}
|
||||
}
|
||||
},
|
||||
draw() {
|
||||
return {
|
||||
form: () => {
|
||||
const form = $(this.ids.form)
|
||||
form.empty()
|
||||
form.append(`<input type="hidden" name="cartolas" value="${this.data.cartolas.length}" />`)
|
||||
this.data.cartolas.forEach(cartola => {
|
||||
form.append(cartola.draw({sociedades: this.data.sociedades, bancos: this.data.bancos}))
|
||||
cartola.activate()
|
||||
})
|
||||
},
|
||||
movimientos: () => {
|
||||
const table = $(this.ids.movimientos)
|
||||
const tbody = table.find('tbody')
|
||||
tbody.empty()
|
||||
this.data.movimientos.forEach(movimiento => {
|
||||
tbody.append(movimiento.draw({formatters: this.formatters}))
|
||||
})
|
||||
table.show()
|
||||
}
|
||||
}
|
||||
},
|
||||
import() {
|
||||
return {
|
||||
cartolas: () => {
|
||||
const url = '{{$urls->api}}/contabilidad/cartolas/importar'
|
||||
const method = 'post'
|
||||
const body = new FormData()
|
||||
this.data.cartolas.forEach(cartola => {
|
||||
Object.entries(cartola.data).forEach(([key, value]) => {
|
||||
body.append(key, value)
|
||||
})
|
||||
})
|
||||
|
||||
fetchAPI(url, {method, body}).then(response => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
return response.json().then(data => {
|
||||
this.data.movimientos = data.movimientos.map(movimiento => new Movimiento(movimiento))
|
||||
this.draw().movimientos()
|
||||
})
|
||||
}).catch(error => {
|
||||
const table = $(this.ids.movimientos)
|
||||
const tbody = table.find('tbody')
|
||||
tbody.empty()
|
||||
table.hide()
|
||||
}).finally(() => {
|
||||
$(this.ids.loader).hide()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
setup(ids) {
|
||||
this.ids = ids
|
||||
this.add().cartola()
|
||||
$(this.ids.buttons.add).click(() => {
|
||||
this.add().cartola()
|
||||
})
|
||||
$(this.ids.loader).hide()
|
||||
$(this.ids.form).submit(submitEvent => {
|
||||
submitEvent.preventDefault()
|
||||
$(this.ids.loader).show()
|
||||
this.import().cartolas()
|
||||
return false
|
||||
})
|
||||
$(this.ids.buttons.process).click(() => {
|
||||
$(this.ids.form).submit()
|
||||
})
|
||||
}
|
||||
}
|
||||
$(document).ready(() => {
|
||||
cartolas.setup({
|
||||
form: '#cartola_form',
|
||||
buttons: {
|
||||
add: '#add_button',
|
||||
process: '#process_button'
|
||||
},
|
||||
movimientos: '#movimientos',
|
||||
loader: '#loader',
|
||||
cartolas: {
|
||||
sociedad: 'sociedad',
|
||||
banco: 'banco',
|
||||
buttons: {
|
||||
remove: 'remove'
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@endpush
|
225
app/resources/views/contabilidad/cuadratura.blade.php
Normal file
225
app/resources/views/contabilidad/cuadratura.blade.php
Normal file
@ -0,0 +1,225 @@
|
||||
@extends('layout.base')
|
||||
|
||||
@section('page_content')
|
||||
<div class="ui container">
|
||||
<h1 class="ui header">
|
||||
Cuadratura de Cartola Mensual
|
||||
</h1>
|
||||
<form class="ui form" id="cuadratura_form">
|
||||
<div class="ui grid">
|
||||
<div class="fourteen wide column">
|
||||
<div class="fields">
|
||||
<div class="five wide field">
|
||||
<label>Inmobiliaria</label>
|
||||
<div class="ui selection search dropdown" id="inmobiliaria">
|
||||
<input type="hidden" name="inmobiliaria"/>
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Inmobiliaria</div>
|
||||
<div class="menu">
|
||||
@foreach ($inmobiliarias as $inmobiliaria)
|
||||
<div class="item" data-value="{{$inmobiliaria->rut}}">{{$inmobiliaria->razon}}</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="two wide field">
|
||||
<label>Banco</label>
|
||||
<div class="ui selection search dropdown" id="banco">
|
||||
<input type="hidden" name="banco"/>
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Banco</div>
|
||||
<div class="menu"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Mes</label>
|
||||
<div class="ui calendar" id="mes">
|
||||
<div class="ui icon input">
|
||||
<i class="calendar icon"></i>
|
||||
<input type="text" name="mes"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="file">Cartola</label>
|
||||
<input type="file" name="file" id="file" class="ui invisible file input" />
|
||||
<label for="file" class="ui icon button">
|
||||
<i class="file icon"></i>
|
||||
Cargar
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="two wide middle aligned column">
|
||||
<button class="ui icon button">
|
||||
Procesar
|
||||
<i class="sync icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="ui two columns grid">
|
||||
<div class="column"></div>
|
||||
<div class="right aligned column">
|
||||
<div class="ui inline active loader" id="loader"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui fluid container" id="movimientos"></div>
|
||||
@endsection
|
||||
|
||||
@include('layout.head.styles.datatables')
|
||||
@include('layout.body.scripts.datatables')
|
||||
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
class LibroMayor {
|
||||
props
|
||||
constructor(props) {
|
||||
this.props = props
|
||||
}
|
||||
}
|
||||
class Cartola {
|
||||
|
||||
}
|
||||
const movimientos = {
|
||||
ids: {},
|
||||
data: {
|
||||
inmobiliaria: {
|
||||
rut: '',
|
||||
razon: ''
|
||||
},
|
||||
banco: {
|
||||
id: '',
|
||||
nombre: ''
|
||||
}
|
||||
},
|
||||
get() {
|
||||
return {
|
||||
bancos: inmobiliaria_rut => {
|
||||
const url = '{{$urls->api}}/inmobiliaria/' + inmobiliaria_rut + '/cuentas'
|
||||
$(this.ids.loader).show()
|
||||
return fetchAPI(url).then(response => {
|
||||
$(this.ids.loader).hide()
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
return response.json().then(json => {
|
||||
if (json.cuentas.length === 0) {
|
||||
return
|
||||
}
|
||||
$(this.ids.inputs.banco).dropdown('change values', json.cuentas.map(cuenta => {
|
||||
return {value: cuenta.banco.id, text: cuenta.banco.nombre, name: cuenta.banco.nombre}
|
||||
})).dropdown('refresh')
|
||||
})
|
||||
})
|
||||
},
|
||||
firstDate: inmobiliaria_rut => {
|
||||
const url = '{{$urls->api}}/inmobiliaria/' + inmobiliaria_rut + '/proyectos'
|
||||
$(this.ids.loader).show()
|
||||
return fetchAPI(url).then(response => {
|
||||
$(this.ids.loader).hide()
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
return response.json().then(json => {
|
||||
if (json.proyectos.length === 0) {
|
||||
return
|
||||
}
|
||||
const min = json.proyectos.reduce((min, proyecto) => {
|
||||
const date = new Date(proyecto.current_estado.fecha.date)
|
||||
if (min > date.getTime()) {
|
||||
return date.getTime()
|
||||
}
|
||||
return min
|
||||
}, (new Date()).getTime())
|
||||
$(this.ids.inputs.mes).calendar('set minDate', new Date(min))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
parse() {
|
||||
return {
|
||||
cartola: submitEvent => {
|
||||
submitEvent.preventDefault()
|
||||
const body = new FormData(document.getElementById('asignar_form'))
|
||||
body.set('mes', $(this.ids.inputs.mes).calendar('get date').toISOString())
|
||||
const url = '{{$urls->api}}/contabilidad/cartolas/procesar'
|
||||
$(this.ids.loader).show()
|
||||
fetchAPI(url, {method: 'post', body}).then(response => {
|
||||
$(this.ids.loader).hide()
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
return response.json().then(json => {
|
||||
if (json.movimientos.length === 0) {
|
||||
return
|
||||
}
|
||||
this.data.movimientos = []
|
||||
json.movimientos.forEach((row, idx) => {
|
||||
const fecha = new Date(row.fecha)
|
||||
fecha.setDate(fecha.getDate() + 1)
|
||||
this.data.movimientos[idx] = {
|
||||
fecha: fecha,
|
||||
glosa: row.glosa,
|
||||
documento: row.documento,
|
||||
cargo: row.cargo,
|
||||
abono: row.abono,
|
||||
}
|
||||
})
|
||||
this.draw().cartola()
|
||||
})
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
},
|
||||
setup(ids) {
|
||||
this.ids = ids
|
||||
|
||||
$(this.ids.inputs.inmobiliaria).dropdown({
|
||||
fireOnInit: true,
|
||||
onChange: (value, text, $choice) => {
|
||||
this.data.inmobiliaria.rut = value
|
||||
this.data.inmobiliaria.razon = text
|
||||
this.get().bancos(value)
|
||||
this.get().firstDate(value)
|
||||
},
|
||||
})
|
||||
$(this.ids.inputs.banco).dropdown({
|
||||
fireOnInit: true,
|
||||
onChange: (value, text, $choice) => {
|
||||
this.data.banco.id = value
|
||||
this.data.banco.nombre = text
|
||||
}
|
||||
})
|
||||
$(this.ids.loader).hide()
|
||||
|
||||
calendar_date_options['type'] = 'month'
|
||||
const lastMonth = new Date()
|
||||
lastMonth.setDate(0)
|
||||
calendar_date_options['maxDate'] = lastMonth
|
||||
calendar_date_options['onChange'] = (date, text, mode) => {
|
||||
this.data.mes = text
|
||||
}
|
||||
$(this.ids.inputs.mes).calendar(calendar_date_options)
|
||||
$(this.ids.form).submit(this.parse().cartola)
|
||||
//$(this.ids.button).click(this.export().cartola)
|
||||
}
|
||||
}
|
||||
$(document).ready(() => {
|
||||
movimientos.setup({
|
||||
movimientos: '#movimientos',
|
||||
form: '#cuadratura_form',
|
||||
loader: '#loader',
|
||||
inputs: {
|
||||
inmobiliaria: '#inmobiliaria',
|
||||
banco: '#banco',
|
||||
mes: '#mes',
|
||||
cartola: '#file'
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@endpush
|
@ -71,7 +71,7 @@
|
||||
<tbody id="movimientos"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="ui modal" id="movimientos_modal">
|
||||
<div class="ui fluid modal" id="movimientos_modal">
|
||||
<div class="content">
|
||||
<h3 class="header">
|
||||
Editar Movimiento
|
||||
@ -92,30 +92,66 @@
|
||||
<form class="ui form" id="movimientos_edit">
|
||||
<input type="hidden" name="index"/>
|
||||
<input type="hidden" name="id"/>
|
||||
<div class="field">
|
||||
<label for="centro_costo">Centro de Costo</label>
|
||||
<div class="ui selection search dropdown" id="centro_costo">
|
||||
<input type="hidden" name="centro_id"/>
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Centro de Costo</div>
|
||||
<div class="menu">
|
||||
@foreach($centros as $centroCosto)
|
||||
<div class="item" data-value="{{$centroCosto->id}}">{{$centroCosto->id}} - {{$centroCosto->descripcion}}</div>
|
||||
@endforeach
|
||||
<div class="fields" id="movimiento_data">
|
||||
<div class="field">
|
||||
<label for="centro_costo">Centro de Costo</label>
|
||||
<div class="ui selection search dropdown" id="centro_costo">
|
||||
<input type="hidden" name="centro_id"/>
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Centro de Costo</div>
|
||||
<div class="menu">
|
||||
@foreach($centros as $centroCosto)
|
||||
<div class="item" data-value="{{$centroCosto->id}}">{{$centroCosto->id}} - {{$centroCosto->descripcion}}</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>RUT</label>
|
||||
<div class="ui right labeled input">
|
||||
<input type="text" name="rut" placeholder="RUT" />
|
||||
<div class="ui basic label">-<span id="digito"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Nombre</label>
|
||||
<input type="text" name="nombre" placeholder="Nombre" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Categoría</label>
|
||||
<input type="text" name="categoria" placeholder="Categoría" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="detalle">Detalle</label>
|
||||
<div class="ui input">
|
||||
<textarea id="detalle" name="detalle"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="detalle">Detalle</label>
|
||||
<div class="ui input">
|
||||
<textarea id="detalle" name="detalle"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<table class="ui table" id="auxiliares">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Cargo</th>
|
||||
<th>Abono</th>
|
||||
<th>Centro Costo</th>
|
||||
<th>RUT</th>
|
||||
<th>Nombre</th>
|
||||
<th>Categoría</th>
|
||||
<th>Detalle</th>
|
||||
<th class="right aligned">
|
||||
<button class="ui green icon button" type="button" id="add_auxiliar">
|
||||
<i class="plus icon"></i>
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui cancel button">Cancelar</div>
|
||||
<div class="ui approve success button">Guardar</div>
|
||||
<div class="ui red cancel button">Cancelar</div>
|
||||
<div class="ui green approve success button">Guardar</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@ -123,10 +159,573 @@
|
||||
@include('layout.body.scripts.datatables')
|
||||
@include('layout.body.scripts.datatables.searchbuilder')
|
||||
@include('layout.body.scripts.datatables.buttons')
|
||||
@include('layout.body.scripts.rut')
|
||||
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
const movimientos = {
|
||||
class CentrosCostos {
|
||||
static data = []
|
||||
static get() {
|
||||
if (this.data.length === 0) {
|
||||
this.data = JSON.parse('{!! json_encode($centros) !!}')
|
||||
}
|
||||
return this.data
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endpush
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
class EventHandler {
|
||||
props
|
||||
constructor({movimientosHandler, modalHandler}) {
|
||||
this.props = {
|
||||
movimientosHandler,
|
||||
modalHandler
|
||||
}
|
||||
}
|
||||
get() {
|
||||
return {
|
||||
movimientos: submitEvent => {
|
||||
submitEvent.preventDefault()
|
||||
submitEvent.data.handler.props.movimientosHandler.get().movimientos({
|
||||
sociedades_ruts: $(submitEvent.data.sociedades_id).dropdown('get values'),
|
||||
mes: $(submitEvent.data.mes_id).calendar('get date')
|
||||
}).then(() => {
|
||||
app.handlers.table.draw().table(app.handlers.results.props.parsed)
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
edit() {
|
||||
return {
|
||||
movimiento: clickEvent => {
|
||||
const id = $(clickEvent.currentTarget).data('id')
|
||||
const index = $(clickEvent.currentTarget).data('index')
|
||||
const type = $(clickEvent.currentTarget).data('type')
|
||||
const movimiento = this.props.movimientosHandler.find().id(id)
|
||||
clickEvent.data.handler.props.modalHandler.show({movimiento, type})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class LoadingHandler {
|
||||
props
|
||||
constructor({ids}) {
|
||||
this.props = {
|
||||
ids
|
||||
}
|
||||
}
|
||||
show() {
|
||||
$(this.props.id).addClass('loading')
|
||||
}
|
||||
hide() {
|
||||
$(this.props.id).removeClass('loading')
|
||||
}
|
||||
}
|
||||
class ControlForm {
|
||||
props
|
||||
constructor({ids,}) {
|
||||
this.props = {
|
||||
ids,
|
||||
}
|
||||
}
|
||||
setup() {
|
||||
$(this.props.ids.sociedades).dropdown()
|
||||
|
||||
const cdo = structuredClone(calendar_date_options)
|
||||
cdo['type'] = 'month'
|
||||
cdo['maxDate'] = new Date()
|
||||
$(this.props.ids.mes).calendar(cdo)
|
||||
|
||||
$(this.props.ids.form).on('submit', {
|
||||
sociedades_id: this.props.ids.sociedades,
|
||||
mes_id: this.props.ids.mes,
|
||||
handler: app.handlers.event
|
||||
}, app.handlers.event.get().movimientos)
|
||||
}
|
||||
}
|
||||
class MovimientosTable {
|
||||
props
|
||||
constructor({ids, eventHandler}) {
|
||||
this.props = {
|
||||
ids,
|
||||
eventHandler,
|
||||
movimientos: [],
|
||||
formatters: {
|
||||
number: new Intl.NumberFormat('es-CL'),
|
||||
date: new Intl.DateTimeFormat('es-CL', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric'
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
draw() {
|
||||
return {
|
||||
table: (movimientos) => {
|
||||
this.props.table.clear().rows.add(this.draw().movimientos(movimientos)).draw()
|
||||
$(this.props.ids.buttons.edit).on('click', {handler: this.props.eventHandler}, this.props.eventHandler.edit().movimiento)
|
||||
},
|
||||
movimientos: (movimientos) => {
|
||||
const output = []
|
||||
movimientos.forEach(movimiento => {
|
||||
this.draw().movimiento({movimiento, output})
|
||||
})
|
||||
return output
|
||||
},
|
||||
movimiento: ({movimiento, output}) => {
|
||||
const valor = movimiento.abono - movimiento.cargo
|
||||
const fecha = movimiento.fecha
|
||||
output.push([
|
||||
movimiento.cuenta.inmobiliaria.sigla,//0
|
||||
movimiento.cuenta.banco.nombre,//1
|
||||
movimiento.cuenta.cuenta,//2
|
||||
this.props.formatters.date.format(fecha),//3
|
||||
[fecha.getFullYear(), fecha.getMonth() + 1, fecha.getDate()].join('-'),//4
|
||||
fecha.getMonth() + 1,//5
|
||||
fecha.getFullYear(),//6
|
||||
this.props.formatters.number.format(valor),//7
|
||||
valor,//8
|
||||
(movimiento.detalles) ? movimiento.detalles.centro_costo.id : '',//9
|
||||
movimiento.glosa,//10
|
||||
(movimiento.detalles) ? movimiento.detalles.detalle : '',//11
|
||||
'<button class="ui icon button edit_button" data-id="' + movimiento.id + '" data-index="' + movimiento.index + '" data-type="movimiento"><i class="edit icon"></i></button>',//12
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
setup() {
|
||||
let dtD = structuredClone(datatables_defaults)
|
||||
dtD = Object.assign(dtD, {
|
||||
columnDefs: [
|
||||
{targets: [0, 5, 9, 12], width: '5%', type: 'string'},
|
||||
{targets: [1, 2, 3, 6, 10], width: '10%', type: 'string'},
|
||||
{targets: [11], width: '20%', type: 'string'},
|
||||
{targets: 4, visible: false},
|
||||
{targets: 7, className: 'dt-right', width: '10%'},
|
||||
{targets: 8, visible: false, type: 'num'}
|
||||
],
|
||||
order: [[4, 'asc']],
|
||||
language: Object.assign(dtD.language, {
|
||||
searchBuilder: {
|
||||
add: 'Filtrar',
|
||||
condition: 'Comparador',
|
||||
clearAll: 'Resetear',
|
||||
delete: 'Eliminar',
|
||||
deleteTitle: 'Eliminar Titulo',
|
||||
data: 'Columna',
|
||||
left: 'Izquierda',
|
||||
leftTitle: 'Titulo Izquierdo',
|
||||
logicAnd: 'Y',
|
||||
logicOr: 'O',
|
||||
right: 'Derecha',
|
||||
rightTitle: 'Titulo Derecho',
|
||||
title: {
|
||||
0: 'Filtros',
|
||||
_: 'Filtros (%d)'
|
||||
},
|
||||
value: 'Opciones',
|
||||
valueJoiner: 'y'
|
||||
}
|
||||
}),
|
||||
layout: {
|
||||
top1: {
|
||||
searchBuilder: {
|
||||
columns: [0, 1, 2, 4, 6, 7, 8]
|
||||
}
|
||||
},
|
||||
top1End: {
|
||||
buttons: [
|
||||
{
|
||||
extend: 'excelHtml5',
|
||||
className: 'green',
|
||||
text: 'Exportar a Excel <i class="file excel icon"></i>',
|
||||
title: 'Movimientos Contables',
|
||||
download: 'open',
|
||||
exportOptions: {
|
||||
columns: [0, 1, 2, 3, 5, 6, 8, 9, 10, 11],
|
||||
format: {
|
||||
body: (data, row, column, node) => {
|
||||
if (column === 3) {
|
||||
return data.split('-').reverse().join('-')
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
data: this.props.movimientos,
|
||||
})
|
||||
this.props.table = new DataTable(this.props.ids.table, dtD)
|
||||
}
|
||||
}
|
||||
class EditModal {
|
||||
props
|
||||
constructor({ids, editForm}) {
|
||||
this.props = {
|
||||
ids,
|
||||
editForm,
|
||||
movimientos: []
|
||||
}
|
||||
}
|
||||
reset() {
|
||||
$(this.props.ids.modal).find('.sociedad').text('')
|
||||
$(this.props.ids.modal).find('.banco').text('')
|
||||
$(this.props.ids.modal).find('.cuenta').text('')
|
||||
$(this.props.ids.modal).find('.fecha').text('')
|
||||
$(this.props.ids.modal).find('.valor').text('')
|
||||
this.props.editForm.reset()
|
||||
}
|
||||
show({movimiento, type}) {
|
||||
$(this.props.ids.modal).modal('show')
|
||||
$(this.props.ids.modal).find('.sociedad').text('Sociedad: ' + movimiento.cuenta.inmobiliaria.sigla)
|
||||
$(this.props.ids.modal).find('.banco').text('Banco: ' + movimiento.cuenta.banco.nombre)
|
||||
$(this.props.ids.modal).find('.cuenta').text('Cuenta: ' + movimiento.cuenta.cuenta)
|
||||
$(this.props.ids.modal).find('.fecha').text('Fecha: ' + movimiento.fecha)
|
||||
$(this.props.ids.modal).find('.valor').text('Valor: ' + (movimiento.abono - movimiento.cargo))
|
||||
this.props.editForm.show({modal: $(this.props.ids.modal), movimiento, type})
|
||||
}
|
||||
hide() {
|
||||
$(this.props.ids.modal).modal('hide')
|
||||
this.reset()
|
||||
}
|
||||
}
|
||||
class EditForm {
|
||||
props
|
||||
constructor({ids}) {
|
||||
this.props = {
|
||||
ids,
|
||||
movimientos: []
|
||||
}
|
||||
}
|
||||
reset() {
|
||||
$(this.props.ids.form).form('reset')
|
||||
}
|
||||
show({modal, movimiento, type}) {
|
||||
if (movimiento.detalles) {
|
||||
modal.find('#movimiento_data').show()
|
||||
modal.find('#auxiliares').hide()
|
||||
modal.find("[name='centro_id']").dropdown('set selected', movimiento.detalles.centro_costo.id)
|
||||
modal.find("[name='rut']").val(movimiento.detalles.rut)
|
||||
modal.find("#digito").text(Rut.digitoVerificador(movimiento.detalles.rut))
|
||||
modal.find("[name='nombre']").val(movimiento.detalles.nombre)
|
||||
modal.find("[name='categoria']").val(movimiento.detalles.categoria)
|
||||
modal.find("[name='detalle']").val(movimiento.detalles.detalle)
|
||||
} else {
|
||||
modal.find('#movimiento_data').hide()
|
||||
modal.find('#auxiliares').show()
|
||||
const tbody = modal.find('#auxiliares tbody')
|
||||
tbody.empty()
|
||||
movimiento.auxiliares.forEach((auxiliar, i) => {
|
||||
tbody.append(`<tr>
|
||||
<td><input type="text" name="cargo${i}" value="${auxiliar.cargo}" /></td>
|
||||
<td><input type="text" name="abono${i}" value="${auxiliar.abono}" /></td>
|
||||
<td>
|
||||
<div class="ui selection search dropdown">
|
||||
<input type="hidden" name="centro_costo${i}" />
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Centro de Costo</div>
|
||||
<div class="menu">
|
||||
${CentrosCostos.get().map(centroCosto => `<div class="item" data-value="${centroCosto.id}">${centroCosto.id} - ${centroCosto.descripcion}</div>`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="ui right labeled input">
|
||||
<input type="text" name="rut${i}" value="${auxiliar.detalles.rut}" />
|
||||
<div class="ui basic label">-<span class="digito" data-index="${i}">${Rut.digitoVerificador(auxiliar.detalles.rut)}</span></div>
|
||||
</div>
|
||||
</td>
|
||||
<td><input type="text" name="nombre${i}" value="${auxiliar.detalles.nombre}" /></td>
|
||||
<td><input type="text" name="categoria${i}" value="${auxiliar.detalles.categoria}" /></td>
|
||||
<td><input type="text" name="detalle${i}" value="${auxiliar.detalles.detalle}" /></td>
|
||||
<td><button class="ui red icon button" type="button"><i class="trash icon"></i></button></td>
|
||||
</tr>`)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
class MovimientosHandler {
|
||||
props
|
||||
constructor({urls, loadingHandler, resultsHandler}) {
|
||||
this.props = {
|
||||
urls,
|
||||
loadingHandler,
|
||||
resultsHandler
|
||||
}
|
||||
}
|
||||
get() {
|
||||
return {
|
||||
movimientos: ({sociedades_ruts, mes}) => {
|
||||
this.props.loadingHandler.show()
|
||||
const method = 'post'
|
||||
const body = new FormData()
|
||||
sociedades_ruts.forEach(sociedad_rut => {
|
||||
body.append('sociedades_ruts[]', sociedad_rut)
|
||||
})
|
||||
body.set('mes', [mes.getFullYear(), mes.getMonth() + 1, mes.getDate()].join('-'))
|
||||
return APIClient.fetch(this.props.urls.get, {method, body}).then(response => {
|
||||
if (!response) {
|
||||
throw new Error('No se pudo obtener los movimientos')
|
||||
}
|
||||
return response.json().then(json => {
|
||||
this.movimientos = json.movimientos
|
||||
this.props.resultsHandler.props.movimientos = json.movimientos
|
||||
this.props.resultsHandler.parse().movimientos()
|
||||
return json.movimientos
|
||||
})
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
}).finally(() => {
|
||||
this.props.loadingHandler.hide()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
edit() {
|
||||
return {
|
||||
movimiento: ({id, index, type, data}) => {
|
||||
/*this.props.resultsHandler.parse().movimientos()
|
||||
this.props.resultsHandler.props.movimientos.forEach((movimiento, i) => {
|
||||
if (movimiento.id === id && movimiento.index === index) {
|
||||
this.props.editModal.show({id, index, type})
|
||||
}
|
||||
})*/
|
||||
}
|
||||
}
|
||||
}
|
||||
find() {
|
||||
return {
|
||||
id: id => {
|
||||
return this.props.resultsHandler.props.movimientos.find(movimiento => movimiento.id === id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class ResultsHandler {
|
||||
props
|
||||
constructor() {
|
||||
this.props = {
|
||||
movimientos: [],
|
||||
timezone: ((new Date()).getTimezoneOffset()) / -60
|
||||
}
|
||||
}
|
||||
parse() {
|
||||
return {
|
||||
movimientos: () => {
|
||||
const movimientos = this.props.movimientos
|
||||
const data = []
|
||||
movimientos.forEach((movimiento, index) => {
|
||||
this.parse().movimiento({data, movimiento, index})
|
||||
})
|
||||
this.props.parsed = data
|
||||
},
|
||||
movimiento: ({data, movimiento, index}) => {
|
||||
const fecha = new Date(movimiento.fecha + 'Z' + this.props.timezone)
|
||||
if (movimiento.auxiliares.length > 0) {
|
||||
movimiento.auxiliares.forEach((auxiliar, indexAuxiliar) => {
|
||||
data.push({
|
||||
tipo: 'auxiliar',
|
||||
id: auxiliar.id,
|
||||
index: index * 100000 + indexAuxiliar,
|
||||
cuenta: movimiento.cuenta,
|
||||
fecha,
|
||||
cargo: auxiliar.cargo,
|
||||
abono: auxiliar.abono,
|
||||
detalles: auxiliar.detalles,
|
||||
glosa: movimiento.glosa,
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
data.push({
|
||||
tipo: 'movimiento',
|
||||
id: movimiento.id,
|
||||
index,
|
||||
cuenta: movimiento.cuenta,
|
||||
fecha,
|
||||
cargo: movimiento.cargo,
|
||||
abono: movimiento.abono,
|
||||
glosa: movimiento.glosa,
|
||||
detalles: movimiento.detalles,
|
||||
auxiliares: movimiento.auxiliares,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*const editForm = {
|
||||
id: '',
|
||||
data: {
|
||||
index: 0,
|
||||
id: 0,
|
||||
sociedad: '',
|
||||
banco: '',
|
||||
fecha: '',
|
||||
valor: 0,
|
||||
glosa: '',
|
||||
},
|
||||
fields: {
|
||||
centro_costo: '',
|
||||
rut: '',
|
||||
nombre: '',
|
||||
categoria: '',
|
||||
detalle: '',
|
||||
},
|
||||
auxiliares: [],
|
||||
show({type, index, id, sociedad, banco, cuenta, fecha, valor, glosa, centro_costo = '', rut = '', nombre = '', categoria = '', detalle = '', auxiliares = []}) {
|
||||
this.data = {
|
||||
index,
|
||||
id,
|
||||
sociedad,
|
||||
banco,
|
||||
cuenta,
|
||||
fecha,
|
||||
valor,
|
||||
glosa,
|
||||
}
|
||||
this.auxiliares = auxiliares
|
||||
$(this.id).find('.sociedad').text('Sociedad: ' + sociedad)
|
||||
$(this.id).find('.banco').text('Banco: ' + banco)
|
||||
$(this.id).find('.cuenta').text('Cuenta: ' + cuenta)
|
||||
$(this.id).find('.fecha').text('Fecha: ' + fecha)
|
||||
$(this.id).find('.valor').text('Valor: ' + valor)
|
||||
$(this.id).find('.glosa').text('Glosa: ' + glosa)
|
||||
if (auxiliares.length > 0) {
|
||||
this.auxiliares = auxiliares
|
||||
$(this.id).find('#movimiento_data').hide()
|
||||
$(this.id).find('#auxiliares').show()
|
||||
const tbody = $(this.id).find('#auxiliares tbody')
|
||||
tbody.empty()
|
||||
auxiliares.forEach((auxiliar, i) => {
|
||||
this.draw().auxiliar({auxiliar, i})
|
||||
})
|
||||
} else {
|
||||
$(this.id).find('#movimiento_data').show()
|
||||
if (type === 'auxiliar') {
|
||||
$(this.id).find('#auxiliares').hide()
|
||||
}
|
||||
if (centro_costo !== '') {
|
||||
$(this.id).find("[name='centro_costo']").dropdown('set selected', centro_costo)
|
||||
}
|
||||
$(this.id).find("[name='rut']").val(rut)
|
||||
$(this.id).find("#digito").text(Rut.digitoVerificador(rut))
|
||||
$(this.id).find("[name='nombre']").val(nombre)
|
||||
$(this.id).find("[name='categoria']").val(categoria)
|
||||
$(this.id).find("[name='detalle']").val(detalle)
|
||||
}
|
||||
$(this.id).modal('show')
|
||||
},
|
||||
draw() {
|
||||
return {
|
||||
auxiliar: ({auxiliar, i}) => {
|
||||
const tbody = $(this.id).find('#auxiliares tbody')
|
||||
const menu = $('<div></div>').addClass('menu')
|
||||
CentrosCostos.get().forEach(centroCosto => {
|
||||
menu.append(`<div class="item" data-value="${centroCosto.id}">${centroCosto.id} - ${centroCosto.descripcion}</div>`)
|
||||
})
|
||||
const tr = $('<tr>')
|
||||
if (typeof auxiliar !== 'undefined' && auxiliar.includes('cargo')) {
|
||||
tr.append(`<td><input type="text" name="cargo${i}" value="${auxiliar.cargo}" /></td>`)
|
||||
} else {
|
||||
tr.append(`<td><input type="text" name="cargo${i}" /></td>`)
|
||||
}
|
||||
if (typeof auxiliar !== 'undefined' && auxiliar.includes('abono')) {
|
||||
tr.append(`<td><input type="text" name="abono${i}" value="${auxiliar.abono}" /></td>`)
|
||||
} else {
|
||||
tr.append(`<td><input type="text" name="abono${i}" /></td>`)
|
||||
}
|
||||
tr.append(
|
||||
$('<td>').append($('<div>').addClass('ui selection search dropdown').attr('data-index', i).append(
|
||||
`<input type="hidden" name="centro_costo${i} />`
|
||||
).append(
|
||||
`<i class="dropdown icon"></i>`
|
||||
).append(
|
||||
`<div class="default text">Centro de Costo</div>`
|
||||
).append(menu)
|
||||
)
|
||||
)
|
||||
if (typeof auxiliar !== 'undefined' && auxiliar.includes('detalles') && auxiliar.detalles.includes('rut')) {
|
||||
tr.append(`<td>
|
||||
<div class="ui right labeled input">
|
||||
<input type="text" name="rut${i}" value="${auxiliar.detalles.rut}" />
|
||||
<div class="ui basic label">-<span class="digito" data-index="${i}">${Rut.digitoVerificador(auxiliar.detalles.rut)}</span></div>
|
||||
</div>
|
||||
</td>`)
|
||||
} else {
|
||||
tr.append(`<td>
|
||||
<div class="ui right labeled input">
|
||||
<input type="text" name="rut${i}" />
|
||||
<div class="ui basic label">-<span class="digito" data-index="${i}"></span></div>
|
||||
</div>
|
||||
</td>`)
|
||||
}
|
||||
if (typeof auxiliar !== 'undefined' && auxiliar.includes('nombre')) {
|
||||
tr.append(`<td><input type="text" name="nombre${i}" value="${auxiliar.nombre}" /></td>`)
|
||||
} else {
|
||||
tr.append(`<td><input type="text" name="nombre${i}" /></td>`)
|
||||
}
|
||||
if (typeof auxiliar !== 'undefined' && auxiliar.includes('categoria')) {
|
||||
tr.append(`<td><input type="text" name="categoria${i}" value="${auxiliar.categoria}" /></td>`)
|
||||
} else {
|
||||
tr.append(`<td><input type="text" name="categoria${i}" /></td>`)
|
||||
}
|
||||
if (typeof auxiliar !== 'undefined' && auxiliar.includes('detalle')) {
|
||||
tr.append(`<td><input type="text" name="detalle${i}" value="${auxiliar.detalle}" /></td>`)
|
||||
} else {
|
||||
tr.append(`<td><input type="text" name="detalle${i}" /></td>`)
|
||||
}
|
||||
tbody.append(tr)
|
||||
$(this.id).find(`.dropdown[data-index='${i}']`).dropdown()
|
||||
if (typeof auxiliar !== 'undefined' && auxiliar.detalles && auxiliar.detalles.centro_costo && auxiliar.detalles.centro_costo.id) {
|
||||
$(this.id).find(`[name='centro_costo${i}']`).val(auxiliar.detalles.centro_costo.id)
|
||||
}
|
||||
$(this.id).find(`[name='rut${i}']`).on('input', inputEvent => {
|
||||
inputEvent.currentTarget.value = Rut.format(inputEvent.currentTarget.value)
|
||||
const index = $(inputEvent.currentTarget).data('index')
|
||||
$(this.id).find(`.digito[data-index='${index}']`).text(Rut.digitoVerificador($(inputEvent.currentTarget).val()))
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
const url = ''
|
||||
const method = 'post'
|
||||
const body = new FormData()
|
||||
const data = this.data
|
||||
data.centro_costo = $(this.id).find("[name='centro_costo']").dropdown('get value')
|
||||
data.rut = $(this.id).find("[name='rut']").val()
|
||||
data.nombre = $(this.id).find("[name='nombre']").val()
|
||||
data.categoria = $(this.id).find("[name='categoria']").val()
|
||||
data.detalle = $(this.id).find("[name='detalle']").val()
|
||||
console.debug(data)
|
||||
},
|
||||
setup(id) {
|
||||
this.id = id
|
||||
$(this.id).modal({
|
||||
onApprove: $element => {
|
||||
this.submit()
|
||||
}
|
||||
})
|
||||
$(this.id).find('#centro_costo').dropdown()
|
||||
$(this.id).find("[name='rut']").on('input', inputEvent => {
|
||||
$(this.id).find('#digito').text(Rut.digitoVerificador($(inputEvent.currentTarget).val()))
|
||||
})
|
||||
$(this.id).find('#digito').text(Rut.digitoVerificador($("[name='rut']").val()))
|
||||
$(this.id).find('#add_auxiliar').click(clickEvent => {
|
||||
const i = this.auxiliares.length + 1
|
||||
this.draw().auxiliar({i})
|
||||
})
|
||||
}
|
||||
}*/
|
||||
/*const movimientos = {
|
||||
ids: {
|
||||
form: {
|
||||
id: '',
|
||||
@ -144,7 +743,7 @@
|
||||
const sociedades_ruts = $(this.ids.forms.search.sociedades).dropdown('get values')
|
||||
const mes = $(this.ids.forms.search.mes).calendar('get date')
|
||||
|
||||
const url = '{{$urls->api}}/contabilidad/movimientos/sociedad/mes'
|
||||
const url = '/contabilidad/movimientos/sociedad/mes'
|
||||
const method = 'post'
|
||||
const body = new FormData()
|
||||
sociedades_ruts.forEach(sociedad_rut => {
|
||||
@ -175,31 +774,37 @@
|
||||
if (data.length === 0) {
|
||||
return
|
||||
}
|
||||
const formatter = new Intl.NumberFormat('es-CL')
|
||||
const dateFormatter = new Intl.DateTimeFormat('es-CL', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric'
|
||||
})
|
||||
const tz = ((new Date()).getTimezoneOffset()) / -60
|
||||
data.forEach((movimiento, index) => {
|
||||
const fecha = new Date(movimiento.fecha + 'Z' + tz)
|
||||
const valor = movimiento.abono - movimiento.cargo
|
||||
this.movimientos.push([
|
||||
movimiento.cuenta.inmobiliaria.sigla,//0
|
||||
movimiento.cuenta.banco.nombre,//1
|
||||
movimiento.cuenta.cuenta,//2
|
||||
dateFormatter.format(fecha),//3
|
||||
[fecha.getFullYear(), fecha.getMonth() + 1, fecha.getDate()].join('-'),//4
|
||||
fecha.getMonth() + 1,//5
|
||||
fecha.getFullYear(),//6
|
||||
formatter.format(valor),//7
|
||||
valor,//8
|
||||
(movimiento.detalles) ? movimiento.detalles.centro_costo.id : '',//9
|
||||
movimiento.glosa,//10
|
||||
(movimiento.detalles) ? movimiento.detalles.detalle : '',//11
|
||||
'<button class="ui icon button edit_button" data-id="' + movimiento.id + '" data-index="' + index + '"><i class="edit icon"></i></button>',//12
|
||||
])
|
||||
if (movimiento.auxiliares.length > 0) {
|
||||
movimiento.auxiliares.forEach((auxiliar, indexAuxiliar) => {
|
||||
this.movimientos.push({
|
||||
tipo: 'auxiliar',
|
||||
id: auxiliar.id,
|
||||
index: index * 100 + indexAuxiliar,
|
||||
cuenta: movimiento.cuenta,
|
||||
fecha,
|
||||
cargo: auxiliar.cargo,
|
||||
abono: auxiliar.abono,
|
||||
detalles: auxiliar.detalles,
|
||||
glosa: movimiento.glosa,
|
||||
})
|
||||
})
|
||||
return
|
||||
}
|
||||
this.movimientos.push({
|
||||
tipo: 'movimiento',
|
||||
id: movimiento.id,
|
||||
index,
|
||||
cuenta: movimiento.cuenta,
|
||||
fecha,
|
||||
cargo: movimiento.cargo,
|
||||
abono: movimiento.abono,
|
||||
glosa: movimiento.glosa,
|
||||
detalles: movimiento.detalles,
|
||||
auxiliares: movimiento.auxiliares,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -238,27 +843,64 @@
|
||||
draw() {
|
||||
return {
|
||||
table: () => {
|
||||
this.table.clear().rows.add(this.movimientos).draw()
|
||||
this.table.clear().rows.add(this.draw().movimientos()).draw()
|
||||
$(this.ids.buttons.edit).click(clickEvent => {
|
||||
const id = $(clickEvent.currentTarget).data('id')
|
||||
const index = $(clickEvent.currentTarget).data('index')
|
||||
this.draw().edit({id, index})
|
||||
})
|
||||
},
|
||||
edit: ({id, index}) => {
|
||||
const form = $('#' + this.ids.forms.edit.id)
|
||||
form.find("[name='id']").val(id)
|
||||
form.find("[name='index']").val(index)
|
||||
$(this.ids.modals.edit).find('.sociedad').text('Sociedad: ' + this.movimientos[index][0])
|
||||
$(this.ids.modals.edit).find('.banco').text('Banco: ' + this.movimientos[index][1])
|
||||
$(this.ids.modals.edit).find('.cuenta').text('Cuenta: ' + this.movimientos[index][2])
|
||||
$(this.ids.modals.edit).find('.fecha').text('Fecha: ' + this.movimientos[index][3])
|
||||
$(this.ids.modals.edit).find('.valor').text('Valor: ' + this.movimientos[index][7])
|
||||
$(this.ids.modals.edit).find('.glosa').text('Glosa: ' + this.movimientos[index][10])
|
||||
form.find("[name='centro_costo']").dropdown('set selected', this.movimientos[index][9])
|
||||
form.find("[name='detalle']").val(this.movimientos[index][11])
|
||||
|
||||
$(this.ids.modals.edit).modal('show')
|
||||
movimientos: () => {
|
||||
const output = []
|
||||
this.movimientos.forEach(movimiento => {
|
||||
this.draw().movimiento({movimiento, output})
|
||||
})
|
||||
return output
|
||||
},
|
||||
movimiento: ({movimiento, output}) => {
|
||||
const formatter = new Intl.NumberFormat('es-CL')
|
||||
const dateFormatter = new Intl.DateTimeFormat('es-CL', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric'
|
||||
})
|
||||
const valor = movimiento.abono - movimiento.cargo
|
||||
const fecha = movimiento.fecha
|
||||
output.push([
|
||||
movimiento.cuenta.inmobiliaria.sigla,//0
|
||||
movimiento.cuenta.banco.nombre,//1
|
||||
movimiento.cuenta.cuenta,//2
|
||||
dateFormatter.format(fecha),//3
|
||||
[fecha.getFullYear(), fecha.getMonth() + 1, fecha.getDate()].join('-'),//4
|
||||
fecha.getMonth() + 1,//5
|
||||
fecha.getFullYear(),//6
|
||||
formatter.format(valor),//7
|
||||
valor,//8
|
||||
(movimiento.detalles) ? movimiento.detalles.centro_costo.id : '',//9
|
||||
movimiento.glosa,//10
|
||||
(movimiento.detalles) ? movimiento.detalles.detalle : '',//11
|
||||
'<button class="ui icon button edit_button" data-id="' + movimiento.id + '" data-index="' + movimiento.index + '" data-type="movimiento"><i class="edit icon"></i></button>',//12
|
||||
])
|
||||
},
|
||||
edit: ({id, index, type}) => {
|
||||
const idx = this.movimientos.findIndex(movimiento => movimiento.index === index)
|
||||
editForm.show({
|
||||
type,
|
||||
id,
|
||||
index,
|
||||
sociedad: this.movimientos[idx].cuenta.inmobiliaria.sigla,
|
||||
banco: this.movimientos[idx].cuenta.banco.nombre,
|
||||
cuenta: this.movimientos[idx].cuenta.cuenta,
|
||||
fecha: this.movimientos[idx].fecha,
|
||||
valor: this.movimientos[idx].abono - this.movimientos[idx].cargo,
|
||||
glosa: this.movimientos[idx].glosa,
|
||||
centro_costo: (this.movimientos[idx].detalles !== null && typeof this.movimientos[idx].detalles.centro_costo) ? this.movimientos[idx].detalles.centro_costo.id : '',
|
||||
rut: (this.movimientos[idx].detalles !== null) ? this.movimientos[idx].detalles.rut : '',
|
||||
nombre: (this.movimientos[idx].detalles !== null) ? this.movimientos[idx].detalles.nombre : '',
|
||||
categoria: (this.movimientos[idx].detalles !== null) ? this.movimientos[idx].detalles.categoria : '',
|
||||
detalle: (this.movimientos[idx].detalles !== null) ? this.movimientos[idx].detalles.detalle : '',
|
||||
auxiliares: this.movimientos[idx].auxiliares,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -274,7 +916,7 @@
|
||||
const index = body.get('index')
|
||||
body.delete('id')
|
||||
body.delete('index')
|
||||
const url = '{{$urls->api}}/contabilidad/movimiento/' + id + '/detalles'
|
||||
const url = '/contabilidad/movimiento/' + id + '/detalles'
|
||||
const method = 'post'
|
||||
return fetchAPI(url, {method, body}).then(response => {
|
||||
if (!response) {
|
||||
@ -363,17 +1005,38 @@
|
||||
})
|
||||
this.table = new DataTable(this.ids.table, dtD)
|
||||
|
||||
$(this.ids.modals.edit).modal({
|
||||
/!*$(this.ids.modals.edit).modal({
|
||||
onApprove: $element => {
|
||||
this.edit()
|
||||
}
|
||||
})*!/
|
||||
editForm.setup(this.ids.modals.edit)
|
||||
//$('#' + this.ids.forms.edit.id).find('#centro_costo').dropdown()
|
||||
}
|
||||
}*/
|
||||
|
||||
const app = {
|
||||
handlers: {},
|
||||
setup() {
|
||||
this.handlers.results = new ResultsHandler()
|
||||
this.handlers.loading = new LoadingHandler({id: '#movimientos_form'})
|
||||
this.handlers.movimientos = new MovimientosHandler({urls: {get: '{{$urls->api}}/contabilidad/movimientos/sociedad/mes', edit: '{{$urls->api}}/contabilidad/movimientos/edit'}, loadingHandler: this.handlers.loading, resultsHandler: this.handlers.results})
|
||||
this.handlers.forms = {}
|
||||
this.handlers.forms.edit = new EditForm({ids: {modal: '#movimientos_modal', form: '#movimientos_edit',}})
|
||||
this.handlers.modals = {}
|
||||
this.handlers.modals.edit = new EditModal({ids: {modal: '#movimientos_modal'}, editForm: this.handlers.forms.edit})
|
||||
this.handlers.events = new EventHandler({movimientosHandler: this.handlers.movimientos, modalHandler: this.handlers.modals.edit})
|
||||
this.handlers.table = new MovimientosTable({ids: {table: '#tabla_movimientos', buttons: {edit: '.edit_button'}}, eventHandler: this.handlers.events})
|
||||
this.handlers.forms.control = new ControlForm({
|
||||
ids: {form: '#movimientos_form', sociedades: '#sociedades', mes: '#mes',},
|
||||
})
|
||||
$('#' + this.ids.forms.edit.id).find('#centro_costo').dropdown()
|
||||
this.handlers.table.setup()
|
||||
this.handlers.forms.control.setup()
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(() => {
|
||||
movimientos.setup({
|
||||
app.setup()
|
||||
/*movimientos.setup({
|
||||
forms: {
|
||||
search: {
|
||||
id: '#movimientos_form',
|
||||
@ -391,7 +1054,7 @@
|
||||
buttons: {
|
||||
edit: '.edit_button'
|
||||
}
|
||||
})
|
||||
})*/
|
||||
})
|
||||
</script>
|
||||
@endpush
|
||||
|
53
app/resources/views/contabilidad/tesoreria/import.blade.php
Normal file
53
app/resources/views/contabilidad/tesoreria/import.blade.php
Normal file
@ -0,0 +1,53 @@
|
||||
@extends('layout.base')
|
||||
|
||||
@section('page_content')
|
||||
<div class="ui container">
|
||||
<h1 class="ui header">Importar Informe de Tesorería</h1>
|
||||
|
||||
<form class="ui form" id="import_form" enctype="multipart/form-data">
|
||||
<div class="ten wide field">
|
||||
<label>Informe</label>
|
||||
<div class="ui file action input">
|
||||
<input type="file" name="file[]" id="file" accept=".xlsx" multiple placeholder="Informe" />
|
||||
<label for="file" class="ui icon button">
|
||||
<i class="file icon"></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ui icon button">
|
||||
<i class="arrow up icon"></i>
|
||||
Subir
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
$(document).ready(() => {
|
||||
$('#import_form').submit(submitEvent => {
|
||||
submitEvent.preventDefault()
|
||||
|
||||
let formData = new FormData()
|
||||
formData.append('file', $('#file')[0].files[0])
|
||||
|
||||
const url = '{{$urls->api}}/contabilidad/tesoreria/import'
|
||||
const method = 'post'
|
||||
const body = new FormData(submitEvent.currentTarget)
|
||||
|
||||
fetchAPI(url, {method, body}).then(response => {
|
||||
if (!response) {
|
||||
return
|
||||
}
|
||||
return response.json().then(data => {
|
||||
console.log(data)
|
||||
|
||||
})
|
||||
}).catch(error => {
|
||||
console.error(error)
|
||||
})
|
||||
return false
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@endpush
|
330
app/resources/views/inmobiliarias/proveedores.blade.php
Normal file
330
app/resources/views/inmobiliarias/proveedores.blade.php
Normal file
@ -0,0 +1,330 @@
|
||||
@extends('layout.base')
|
||||
|
||||
@section('page_content')
|
||||
<div class="ui container">
|
||||
<table class="ui table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nombre</th>
|
||||
<th>Contacto</th>
|
||||
<th class="right aligned">
|
||||
<button class="ui green icon button" id="add_button">
|
||||
<i class="plus icon"></i>
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="proveedores">
|
||||
@foreach ($sociedades as $sociedad)
|
||||
<tr>
|
||||
<td>{{$sociedad->nombre}}</td>
|
||||
<td>{{$sociedad->contacto->nombreCompleto()}}</td>
|
||||
<td class="right aligned">
|
||||
<button class="ui icon button" data-sociedad="{{$sociedad->rut}}">
|
||||
<i class="edit icon"></i>
|
||||
</button>
|
||||
<button class="ui red icon button" data-sociedad="{{$sociedad->rut}}">
|
||||
<i class="remove icon"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="ui modal" id="add_modal">
|
||||
<div class="content">
|
||||
<form class="ui form">
|
||||
<div class="three wide field">
|
||||
<label for="rut">RUT</label>
|
||||
<div class="ui right labeled input">
|
||||
<input class="right aligned" type="text" id="rut" name="rut" placeholder="RUT" maxlength="10" required />
|
||||
<div class="ui basic label">-<span id="dv"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="five wide field">
|
||||
<label for="nombre">Nombre</label>
|
||||
<input type="text" id="nombre" name="nombre" placeholder="Nombre" required />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="razon">Razón Social</label>
|
||||
<input type="text" id="razon" name="razon" placeholder="Razón Social" required />
|
||||
</div>
|
||||
<div class="four wide field">
|
||||
<label for="tipo">Tipo</label>
|
||||
<div class="ui selection dropdown" id="tipo">
|
||||
<input type="hidden" name="tipo" required />
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Tipo</div>
|
||||
<div class="menu">
|
||||
@foreach ($tiposSociedades as $tipo)
|
||||
<div class="item" data-value="{{$tipo->id}}">{{$tipo->descripcion}}</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui divider">Contacto</div>
|
||||
<div class="three wide field">
|
||||
<label for="rut_contacto">RUT</label>
|
||||
<div class="ui right labeled input">
|
||||
<input type="text" id="rut_contacto" name="rut_contacto" placeholder="RUT" maxlength="10" required />
|
||||
<div class="ui basic label">-<span id="dv_contacto"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fields">
|
||||
<div class="five wide field">
|
||||
<label for="nombre_contacto">Nombre</label>
|
||||
<input type="text" id="nombre_contacto" name="nombre_contacto" placeholder="Nombre" required />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="apellido_paterno_contacto">Apellido Paterno</label>
|
||||
<input type="text" id="apellido_paterno_contacto" name="apellido_paterno_contacto" placeholder="Apellido Paterno" required />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="apellido_materno_contacto">Apellido Materno</label>
|
||||
<input type="text" id="apellido_materno_contacto" name="apellido_materno_contacto" placeholder="Apellido Materno" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="email_contacto">Email</label>
|
||||
<input type="email" id="email_contacto" name="email_contacto" placeholder="Email" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="telefono_contacto">Teléfono</label>
|
||||
<div class="ui left labeled input">
|
||||
<div class="ui basic label">+56</div>
|
||||
<input type="text" id="telefono_contacto" name="telefono_contacto" placeholder="Teléfono" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="ui green approve button">Guardar</button>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
const proveedores = {
|
||||
ids: {
|
||||
modal: '',
|
||||
buttons: {
|
||||
add: '',
|
||||
edit: '',
|
||||
remove: ''
|
||||
},
|
||||
add: {
|
||||
form: '',
|
||||
rut: '',
|
||||
dv: '',
|
||||
nombre: '',
|
||||
razon: '',
|
||||
tipo: '',
|
||||
contacto: {
|
||||
rut: '',
|
||||
dv: '',
|
||||
nombre: '',
|
||||
apellido_paterno: '',
|
||||
apellido_materno: '',
|
||||
email: '',
|
||||
telefono: ''
|
||||
}
|
||||
},
|
||||
proveedores: ''
|
||||
},
|
||||
data: JSON.parse('{!! json_encode($sociedades) !!}'),
|
||||
add() {
|
||||
return {
|
||||
sociedad: () => {
|
||||
const data = {
|
||||
rut: $(this.ids.add.rut).val().replace(/\D/g, ''),
|
||||
digito: $(this.ids.add.dv).text(),
|
||||
nombre: $(this.ids.add.nombre).val(),
|
||||
razon: $(this.ids.add.razon).val(),
|
||||
tipo_sociedad_id: $(this.ids.add.tipo).dropdown('get value'),
|
||||
contacto: {
|
||||
rut: $(this.ids.add.contacto.rut).val().replace(/\D/g, ''),
|
||||
digito: $(this.ids.add.contacto.dv).text(),
|
||||
nombres: $(this.ids.add.contacto.nombre).val(),
|
||||
apellido_paterno: $(this.ids.add.contacto.apellido_paterno).val(),
|
||||
apellido_materno: $(this.ids.add.contacto.apellido_materno).val(),
|
||||
email: $(this.ids.add.contacto.email).val(),
|
||||
telefono: $(this.ids.add.contacto.telefono).val().replace(/\D/g, ''),
|
||||
}
|
||||
}
|
||||
const body = new FormData()
|
||||
body.append('sociedades[]', JSON.stringify(data))
|
||||
const url = '{{$urls->api}}/sociedades/add'
|
||||
const method = 'post'
|
||||
fetchAPI(url, {method, body})
|
||||
.then(response => (response) ? response.json() : null)
|
||||
.then(data => {
|
||||
if (data.sociedades !== null) {
|
||||
data.sociedades.forEach(sociedad => {
|
||||
const exists = this.data.find(s => s.rut === sociedad.rut)
|
||||
if (typeof exists !== 'undefined') {
|
||||
return
|
||||
}
|
||||
this.data.push(sociedad)
|
||||
})
|
||||
this.draw().sociedades()
|
||||
$(this.ids.modal).find('form.form').trigger('reset')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
edit() {},
|
||||
remove() {
|
||||
return {
|
||||
sociedad: rut => {
|
||||
const body = new FormData()
|
||||
body.append('sociedades_ruts[]', rut)
|
||||
const url = '{{$urls->api}}/sociedades/delete'
|
||||
const method = 'post'
|
||||
fetchAPI(url, {method, body})
|
||||
.then(response => (response) ? response.json() : null)
|
||||
.then(data => {
|
||||
if (data.sociedades !== null) {
|
||||
data.sociedades.forEach(sociedad => {
|
||||
if (sociedad.sociedad.rut !== rut) {
|
||||
return
|
||||
}
|
||||
if (!sociedad.deleted) {
|
||||
return
|
||||
}
|
||||
$(this.ids.proveedores).find(`button[data-sociedad="${rut}"]`).closest('tr').remove()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
draw() {
|
||||
return {
|
||||
sociedades: () => {
|
||||
$(this.ids.proveedores).empty()
|
||||
this.data.forEach(sociedad => {
|
||||
$(this.ids.proveedores).append(`
|
||||
<tr>
|
||||
<td>${sociedad.nombre}</td>
|
||||
<td>${sociedad.contacto.nombreCompleto}</td>
|
||||
<td class="right aligned">
|
||||
<button class="ui icon button" data-sociedad="${sociedad.rut}">
|
||||
<i class="edit icon"></i>
|
||||
</button>
|
||||
<button class="ui red icon button" data-sociedad="${sociedad.rut}">
|
||||
<i class="remove icon"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
`)
|
||||
})
|
||||
$(this.ids.buttons.remove).click((e) => {
|
||||
this.remove().sociedad($(e.target).data('sociedad'))
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
formatters() {
|
||||
return {
|
||||
rut: value => {
|
||||
const rut = value.replace(/[^0-9]/g, '')
|
||||
if (rut.length <= 1) {
|
||||
return rut
|
||||
}
|
||||
return rut.replace(/\B(?=(\d{3})+(?!\d))/g, '.')
|
||||
},
|
||||
telefono: value => {
|
||||
const phone = value.replace(/[^0-9]/g, '')
|
||||
if (phone.length <= 1) {
|
||||
return phone
|
||||
}
|
||||
return phone.replace(/(\d{2})(\d{3})(\d{4})/, '$1 $2 $3')
|
||||
}
|
||||
}
|
||||
},
|
||||
digitoVerificador(value) {
|
||||
let rut = value.replace(/[^0-9kK]/g, '')
|
||||
if (rut.length < 1) {
|
||||
return ''
|
||||
}
|
||||
let suma = 0
|
||||
let mul = 2
|
||||
for (let i = rut.length-1; i >= 0; i--) {
|
||||
suma += parseInt(rut[i]) * mul
|
||||
mul = (mul + 1) % 8 || 2
|
||||
}
|
||||
const dv = 11 - suma % 11
|
||||
return dv === 10 ? 'K' : (dv === 11 ? '0' : dv.toString())
|
||||
},
|
||||
setup(ids) {
|
||||
this.ids = ids
|
||||
$(this.ids.buttons.add).click(() => {
|
||||
$(this.ids.modal).modal('show')
|
||||
})
|
||||
$(this.ids.add.rut).on('input', (e) => {
|
||||
e.target.value = this.formatters().rut(e.target.value)
|
||||
$(this.ids.add.dv).text(this.digitoVerificador(e.target.value))
|
||||
})
|
||||
if ($(this.ids.add.rut).val().length > 0) {
|
||||
$(this.ids.add.rut).val(this.formatters().rut($(this.ids.add.rut).val()))
|
||||
$(this.ids.add.dv).text(this.digitoVerificador($(this.ids.add.rut).val()))
|
||||
}
|
||||
$(this.ids.tipo).dropdown()
|
||||
$(this.ids.add.contacto.rut).on('input', (e) => {
|
||||
e.target.value = this.formatters().rut(e.target.value)
|
||||
$(this.ids.add.contacto.dv).text(this.digitoVerificador(e.target.value))
|
||||
})
|
||||
if ($(this.ids.add.contacto.rut).val().length > 0) {
|
||||
$(this.ids.add.contacto.rut).val(this.formatters().rut($(this.ids.add.contacto.rut).val()))
|
||||
$(this.ids.add.contacto.dv).text(this.digitoVerificador($(this.ids.add.contacto.rut).val()))
|
||||
}
|
||||
$(this.ids.add.contacto.telefono).on('input', (e) => {
|
||||
e.target.value = this.formatters().telefono(e.target.value)
|
||||
})
|
||||
if ($(this.ids.add.contacto.telefono).val().length > 0) {
|
||||
$(this.ids.add.contacto.telefono).val(this.formatters().telefono($(this.ids.add.contacto.telefono).val()))
|
||||
}
|
||||
$(this.ids.modal).modal({
|
||||
onApprove: () => {
|
||||
this.add().sociedad()
|
||||
}
|
||||
})
|
||||
$(this.ids.buttons.remove).click((e) => {
|
||||
this.remove().sociedad($(e.target).data('sociedad'))
|
||||
})
|
||||
}
|
||||
}
|
||||
$(document).ready(() => {
|
||||
proveedores.setup({
|
||||
modal: '#add_modal',
|
||||
buttons: {
|
||||
add: '#add_button',
|
||||
edit: '.edit',
|
||||
remove: '.remove'
|
||||
},
|
||||
add: {
|
||||
form: '#add_modal form.form',
|
||||
rut: '#rut',
|
||||
dv: '#dv',
|
||||
nombre: '#nombre',
|
||||
razon: '#razon',
|
||||
tipo: '#tipo',
|
||||
contacto: {
|
||||
rut: '#rut_contacto',
|
||||
dv: '#dv_contacto',
|
||||
nombre: '#nombre_contacto',
|
||||
apellido_paterno: '#apellido_paterno_contacto',
|
||||
apellido_materno: '#apellido_materno_contacto',
|
||||
email: '#email_contacto',
|
||||
telefono: '#telefono_contacto'
|
||||
}
|
||||
},
|
||||
proveedores: '#proveedores'
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@endpush
|
@ -16,7 +16,13 @@
|
||||
<a class="item" href="{{$urls->base}}/contabilidad/centros_costos/asignar">Asignar en Cartola</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="item" href="{{$urls->base}}/contabilidad/cartolas/diaria">Cartola Diaria</a>
|
||||
<div class="item">
|
||||
<i class="dropdown icon"></i>
|
||||
<a class="text" href="{{$urls->base}}/contabilidad/cartolas/diaria">Cartola Diaria</a>
|
||||
<div class="menu">
|
||||
<a class="item" href="{{$urls->base}}/contabilidad/cartolas/importar">Importar</a>
|
||||
</div>
|
||||
</div>
|
||||
<a class="item" href="{{$urls->base}}/contabilidad/depositos">Depósitos a Plazo</a>
|
||||
<a class="item" href="{{$urls->base}}/contabilidad/movimientos">Movimientos</a>
|
||||
</div>
|
||||
|
@ -2,6 +2,11 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.9.3/semantic.min.js" integrity="sha512-gnoBksrDbaMnlE0rhhkcx3iwzvgBGz6mOEj4/Y5ZY09n55dYddx6+WYc72A55qEesV8VX2iMomteIwobeGK1BQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
class APIClient {
|
||||
static fetch(url, options=null) {
|
||||
return fetchAPI(url, options)
|
||||
}
|
||||
}
|
||||
function fetchAPI(url, options=null) {
|
||||
if (options === null) {
|
||||
options = {}
|
||||
|
26
app/resources/views/layout/body/scripts/rut.blade.php
Normal file
26
app/resources/views/layout/body/scripts/rut.blade.php
Normal file
@ -0,0 +1,26 @@
|
||||
@push('page_scripts')
|
||||
<script>
|
||||
class Rut {
|
||||
static digitoVerificador(rut) {
|
||||
if (rut.length === 0) {
|
||||
return ''
|
||||
}
|
||||
let M = 0, S = 1
|
||||
for (; rut; rut = Math.floor(rut / 10)) {
|
||||
S = (S + rut % 10 * (9 - M++ % 6)) % 11
|
||||
}
|
||||
return S ? S - 1 : 'K'
|
||||
}
|
||||
static format(rut) {
|
||||
if (rut.length === 0) {
|
||||
return ''
|
||||
}
|
||||
rut.replace(/\D/g, '')
|
||||
return rut.replace(/^(\d{1,2})(\d{3})(\d{3})$/, '$1.$2.$3')
|
||||
}
|
||||
static validar(rut, digito) {
|
||||
return Rut.digitoVerificador(rut) === digito
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endpush
|
@ -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 '<div class="ui divider" data-index="'+index+'"></div>'
|
||||
},
|
||||
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),
|
||||
'<div class="factura" data-index="'+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}),
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join("\n")
|
||||
@ -868,7 +949,7 @@
|
||||
'SUBTOTAL (Bruto): $' + formatters.pesos.format((venta.neto + venta.iva) * propietario.props.proporcion) + '<br />' +
|
||||
'Mas valor terreno: $' + ((venta.exento > 0) ? formatters.pesos.format(venta.exento * propietario.props.proporcion) : emptyTerreno) + '<br />' +
|
||||
'TOTAL (Escritura): $' + formatters.pesos.format(venta.total * propietario.props.proporcion) + '; ' + formatters.ufs.format(venta.totalUF * propietario.props.proporcion) + ' UF<br /><br />' +
|
||||
'Descuento Terreno: ' + ((venta.exento > 0) ? formatters.percent.format(venta.descuento * 100) : emptyTerreno) + '%<br /><br />' +
|
||||
'Descuento Terreno: ' + ((venta.exento > 0) ? formatters.percent.format(venta.descuento * propietario.props.proporcion * 100) : emptyTerreno) + '%<br /><br />' +
|
||||
'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 @@
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join("\n")
|
||||
},
|
||||
guardar: ({index}) => {
|
||||
if (this.props.saved) {
|
||||
return [
|
||||
'<div class="row">',
|
||||
'<div class="fourteen wide column"></div>',
|
||||
'<div class="two wide center aligned column">',
|
||||
'<div class="ui green message">',
|
||||
'<i class="check icon"></i>',
|
||||
'Guardada',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join("\n")
|
||||
}
|
||||
return [
|
||||
'<div class="row">',
|
||||
'<div class="right aligned sixteen wide column">',
|
||||
`<button class="ui primary button guardar" data-index="${index}">Guardar</button>`,
|
||||
'</div>',
|
||||
'</div>'
|
||||
].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()
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
29
app/src/Controller/API/Contabilidad/Tesoreria.php
Normal file
29
app/src/Controller/API/Contabilidad/Tesoreria.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\API\Contabilidad;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Controller\API\withJson;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Tesoreria
|
||||
{
|
||||
use withJson;
|
||||
|
||||
public function import(ServerRequestInterface $request, ResponseInterface $response, LoggerInterface $logger,
|
||||
Service\Contabilidad\Informe\Tesoreria $tesoreriaService): ResponseInterface
|
||||
{
|
||||
$files = $request->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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
35
app/src/Controller/API/Inmobiliarias/Sociedades.php
Normal file
35
app/src/Controller/API/Inmobiliarias/Sociedades.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\API\Inmobiliarias;
|
||||
|
||||
use Incoviba\Controller\API\withJson;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Sociedades extends Ideal\Service
|
||||
{
|
||||
use withJson;
|
||||
|
||||
public function add(ServerRequestInterface $request, ResponseInterface $response,
|
||||
Service\Sociedad $sociedadService, Service\Persona $personaService): ResponseInterface
|
||||
{
|
||||
$input = $request->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);
|
||||
}
|
||||
}
|
132
app/src/Controller/API/Sociedades.php
Normal file
132
app/src/Controller/API/Sociedades.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\API;
|
||||
|
||||
use Incoviba\Common\Ideal\Controller;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Sociedades extends Controller
|
||||
{
|
||||
use withJson;
|
||||
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, Service\Sociedad $sociedadService): ResponseInterface
|
||||
{
|
||||
$output = [
|
||||
'sociedades' => $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);
|
||||
}
|
||||
}
|
32
app/src/Controller/API/Ventas/Facturas.php
Normal file
32
app/src/Controller/API/Ventas/Facturas.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\API\Ventas;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Incoviba\Controller\API\withJson;
|
||||
use Incoviba\Common\Ideal\Controller;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Facturas extends Controller
|
||||
{
|
||||
use withJson;
|
||||
|
||||
public function add(ServerRequestInterface $request, ResponseInterface $response, Service\Venta\Factura $facturaService): ResponseInterface
|
||||
{
|
||||
$data = $request->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);
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
14
app/src/Controller/Contabilidad/Tesoreria.php
Normal file
14
app/src/Controller/Contabilidad/Tesoreria.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\Contabilidad;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Incoviba\Common\Alias\View;
|
||||
|
||||
class Tesoreria
|
||||
{
|
||||
public function import(ServerRequestInterface $request, ResponseInterface $response, View $view): ResponseInterface
|
||||
{
|
||||
return $view->render($response, 'contabilidad.tesoreria.import');
|
||||
}
|
||||
}
|
27
app/src/Controller/Inmobiliarias/Proveedores.php
Normal file
27
app/src/Controller/Inmobiliarias/Proveedores.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Incoviba\Controller\Inmobiliarias;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Common\Alias\View;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Proveedores
|
||||
{
|
||||
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, View $view,
|
||||
Service\Sociedad $sociedadService,
|
||||
Repository\Inmobiliaria\TipoSociedad $tipoSociedad): ResponseInterface
|
||||
{
|
||||
$sociedades = [];
|
||||
try {
|
||||
$sociedades = $sociedadService->getAll('nombre');
|
||||
} catch (EmptyResult) {}
|
||||
$tiposSociedades = [];
|
||||
try {
|
||||
$tiposSociedades = $tipoSociedad->fetchAll('descripcion');
|
||||
} catch (EmptyResult) {}
|
||||
return $view->render($response, 'inmobiliarias.proveedores', compact('sociedades', 'tiposSociedades'));
|
||||
}
|
||||
}
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
36
app/src/Model/Contabilidad/Movimiento/Auxiliar.php
Normal file
36
app/src/Model/Contabilidad/Movimiento/Auxiliar.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Contabilidad\Movimiento;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Auxiliar extends Ideal\Model
|
||||
{
|
||||
public Model\Contabilidad\Movimiento $movimiento;
|
||||
public int $cargo;
|
||||
public int $abono;
|
||||
|
||||
protected ?Model\Contabilidad\Movimiento\Auxiliar\Detalle $detalles;
|
||||
public function getDetalles(): ?Model\Contabilidad\Movimiento\Auxiliar\Detalle
|
||||
{
|
||||
if (!isset($this->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()
|
||||
]);
|
||||
}
|
||||
}
|
39
app/src/Model/Contabilidad/Movimiento/Auxiliar/Detalle.php
Normal file
39
app/src/Model/Contabilidad/Movimiento/Auxiliar/Detalle.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Contabilidad\Movimiento\Auxiliar;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Detalle extends Ideal\Model
|
||||
{
|
||||
public Model\Contabilidad\Movimiento\Auxiliar $auxiliar;
|
||||
public ?Model\Contabilidad\CentroCosto $centroCosto;
|
||||
public ?int $rut;
|
||||
public ?string $digito;
|
||||
public ?string $nombre;
|
||||
public ?string $categoria;
|
||||
public ?string $detalle;
|
||||
|
||||
public function rut(): string
|
||||
{
|
||||
return $this->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(),
|
||||
];
|
||||
}
|
||||
}
|
41
app/src/Model/Contabilidad/Movimiento/Detalle.php
Normal file
41
app/src/Model/Contabilidad/Movimiento/Detalle.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Contabilidad\Movimiento;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Detalle extends Ideal\Model
|
||||
{
|
||||
public Model\Contabilidad\Movimiento $movimiento;
|
||||
public ?Model\Contabilidad\CentroCosto $centroCosto;
|
||||
public ?int $rut;
|
||||
public ?string $digito;
|
||||
public ?string $nombres;
|
||||
public ?string $categoria;
|
||||
public ?string $detalle;
|
||||
public ?string $identificador;
|
||||
|
||||
public function rut(): string
|
||||
{
|
||||
return $this->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()
|
||||
];
|
||||
}
|
||||
}
|
32
app/src/Model/DatosPersona.php
Normal file
32
app/src/Model/DatosPersona.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Incoviba\Model;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
class DatosPersona extends Ideal\Model
|
||||
{
|
||||
public Persona $persona;
|
||||
public ?Direccion $direccion;
|
||||
public ?int $telefono;
|
||||
public ?string $email;
|
||||
public ?DateTimeInterface $fechaNacimiento;
|
||||
public ?string $sexo;
|
||||
public ?string $estadoCivil;
|
||||
public ?string $nacionalidad;
|
||||
public ?string $profesion;
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [
|
||||
'direccion' => $this->direccion,
|
||||
'telefono' => $this->telefono,
|
||||
'email' => $this->email,
|
||||
'fechaNacimiento' => $this->fechaNacimiento,
|
||||
'sexo' => $this->sexo,
|
||||
'estadoCivil' => $this->estadoCivil,
|
||||
'nacionalidad' => $this->nacionalidad,
|
||||
'profesion' => $this->profesion,
|
||||
];
|
||||
}
|
||||
}
|
29
app/src/Model/Inmobiliaria/Proveedor.php
Normal file
29
app/src/Model/Inmobiliaria/Proveedor.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Inmobiliaria;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Proveedor extends Ideal\Model
|
||||
{
|
||||
public Model\Inmobiliaria $inmobiliaria;
|
||||
public Model\Sociedad $sociedad;
|
||||
|
||||
protected array $tipos;
|
||||
public function tipos(): array
|
||||
{
|
||||
if (!isset($this->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(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Movimiento;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Detalle extends Ideal\Model
|
||||
{
|
||||
public Model\Contabilidad\Movimiento $movimiento;
|
||||
public ?Model\Contabilidad\CentroCosto $centroCosto;
|
||||
public ?string $detalle;
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return [
|
||||
'movimiento_id' => $this->movimiento->id,
|
||||
'centro_costo' => $this->centroCosto,
|
||||
'detalle' => $this->detalle
|
||||
];
|
||||
}
|
||||
}
|
46
app/src/Model/Persona.php
Normal file
46
app/src/Model/Persona.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace Incoviba\Model;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
class Persona extends Ideal\Model
|
||||
{
|
||||
public int $rut;
|
||||
public string $digito;
|
||||
public string $nombres;
|
||||
public string $apellidoPaterno;
|
||||
public string $apellidoMaterno;
|
||||
|
||||
public function nombreCompleto(): string
|
||||
{
|
||||
return $this->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(),
|
||||
];
|
||||
}
|
||||
}
|
33
app/src/Model/Sociedad.php
Normal file
33
app/src/Model/Sociedad.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
namespace Incoviba\Model;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model\Inmobiliaria\TipoSociedad;
|
||||
|
||||
class Sociedad extends Ideal\Model
|
||||
{
|
||||
public int $rut;
|
||||
public string $digito;
|
||||
public string $nombre;
|
||||
public string $razonSocial;
|
||||
public TipoSociedad $tipoSociedad;
|
||||
public Persona $contacto;
|
||||
|
||||
public function nombreCompleto(): string
|
||||
{
|
||||
return implode(' ', [$this->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(),
|
||||
];
|
||||
}
|
||||
}
|
86
app/src/Model/Venta/Factura.php
Normal file
86
app/src/Model/Venta/Factura.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Venta;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Factura extends Ideal\Model
|
||||
{
|
||||
public Model\Venta $venta;
|
||||
public int $index;
|
||||
public float $proporcion;
|
||||
public string $emisorRut;
|
||||
public string $emisorNombre;
|
||||
public string $emisorDireccion;
|
||||
public string $receptorRut;
|
||||
public string $receptorNombre;
|
||||
public string $receptorDireccion;
|
||||
public string $receptorComuna;
|
||||
public DateTimeInterface $fecha;
|
||||
public array $unidades;
|
||||
public int $detalleBase;
|
||||
public int $detalleTerreno;
|
||||
public int $detalleNeto;
|
||||
public int $detalleIva;
|
||||
public int $detalleBruto;
|
||||
public float $detalleDescuento;
|
||||
public int $detalleTotal;
|
||||
public int $totalNeto;
|
||||
public int $totalExento;
|
||||
public int $totalIva;
|
||||
public int $totalTotal;
|
||||
public DateTimeInterface $fechaUF;
|
||||
public float $valorUF;
|
||||
|
||||
protected array $estados;
|
||||
public function estados(): array
|
||||
{
|
||||
if (!isset($this->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()
|
||||
]);
|
||||
}
|
||||
}
|
22
app/src/Model/Venta/Factura/Estado.php
Normal file
22
app/src/Model/Venta/Factura/Estado.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Venta\Factura;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Estado extends Ideal\Model
|
||||
{
|
||||
public Model\Venta\Factura $factura;
|
||||
public DateTimeInterface $fecha;
|
||||
public Model\Venta\Factura\Estado\Tipo $tipo;
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return array_merge(parent::jsonSerialize(), [
|
||||
'factura_id' => $this->factura->id,
|
||||
'fecha' => $this->fecha->format('Y-m-d'),
|
||||
'tipo' => $this->tipo
|
||||
]);
|
||||
}
|
||||
}
|
7
app/src/Model/Venta/Factura/Estado/Tipo.php
Normal file
7
app/src/Model/Venta/Factura/Estado/Tipo.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace Incoviba\Model\Venta\Factura\Estado;
|
||||
|
||||
use Incoviba\Model\Tipo as Base;
|
||||
|
||||
class Tipo extends Base
|
||||
{}
|
@ -31,4 +31,13 @@ class Banco extends Ideal\Repository
|
||||
{
|
||||
return $this->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]);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
62
app/src/Repository/Contabilidad/Movimiento/Auxiliar.php
Normal file
62
app/src/Repository/Contabilidad/Movimiento/Auxiliar.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Contabilidad\Movimiento;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class Auxiliar extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection, protected Repository\Contabilidad\Movimiento $movimientoRepository)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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]);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Contabilidad\Movimiento\Auxiliar;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class Detalle extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection,
|
||||
protected Repository\Contabilidad\Movimiento\Auxiliar $auxiliarRepository,
|
||||
protected Repository\Contabilidad\CentroCosto $centroCostoRepository)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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]);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Movimiento;
|
||||
namespace Incoviba\Repository\Contabilidad\Movimiento;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
@ -9,16 +9,17 @@ use Incoviba\Repository;
|
||||
|
||||
class Detalle extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection, protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
public function __construct(Define\Connection $connection,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Repository\Contabilidad\CentroCosto $centroCostoRepository)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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()
|
86
app/src/Repository/DatosPersona.php
Normal file
86
app/src/Repository/DatosPersona.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
|
||||
class DatosPersona extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection, protected Persona $personaRepository,
|
||||
protected Direccion $direccionRepository)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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';
|
||||
}
|
||||
}
|
@ -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']);
|
||||
}));
|
||||
|
61
app/src/Repository/Inmobiliaria/Proveedor.php
Normal file
61
app/src/Repository/Inmobiliaria/Proveedor.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Inmobiliaria;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Proveedor extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection, protected Repository\Inmobiliaria $inmobiliariaRepository,
|
||||
protected Repository\Sociedad $sociedadRepository)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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')));
|
||||
}
|
||||
}
|
49
app/src/Repository/Persona.php
Normal file
49
app/src/Repository/Persona.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Persona extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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';
|
||||
}
|
||||
}
|
55
app/src/Repository/Sociedad.php
Normal file
55
app/src/Repository/Sociedad.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Sociedad extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection,
|
||||
protected Inmobiliaria\TipoSociedad $tipoSociedadRepository,
|
||||
protected Service\Persona $personaService)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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';
|
||||
}
|
||||
}
|
129
app/src/Repository/Venta/Factura.php
Normal file
129
app/src/Repository/Venta/Factura.php
Normal file
@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Venta;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class Factura extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Implement\Connection $connection, protected Repository\Venta $ventaRepository)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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]);
|
||||
}
|
||||
}
|
60
app/src/Repository/Venta/Factura/Estado.php
Normal file
60
app/src/Repository/Venta/Factura/Estado.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Venta\Factura;
|
||||
|
||||
use Incoviba\Common\Define;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class Estado extends Ideal\Repository
|
||||
{
|
||||
public function __construct(Define\Connection $connection, protected Repository\Venta\Factura $facturaRepository, protected Repository\Venta\Factura\Estado\Tipo $tipoRepository)
|
||||
{
|
||||
parent::__construct($connection);
|
||||
$this->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]);
|
||||
}
|
||||
}
|
17
app/src/Repository/Venta/Factura/Estado/Tipo.php
Normal file
17
app/src/Repository/Venta/Factura/Estado/Tipo.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace Incoviba\Repository\Venta\Factura\Estado;
|
||||
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
|
||||
class Tipo extends Repository\Tipo
|
||||
{
|
||||
public function getTable(): string
|
||||
{
|
||||
return 'tipos_estados_facturas';
|
||||
}
|
||||
protected function getBlank(): Model\Venta\Factura\Estado\Tipo
|
||||
{
|
||||
return new Model\Venta\Factura\Estado\Tipo;
|
||||
}
|
||||
}
|
@ -65,7 +65,7 @@ class Propietario extends Ideal\Repository
|
||||
{
|
||||
$model->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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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']
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
];
|
||||
}
|
||||
|
||||
|
36
app/src/Service/Contabilidad/Informe/Semanal.php
Normal file
36
app/src/Service/Contabilidad/Informe/Semanal.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe;
|
||||
|
||||
use DateTimeInterface;
|
||||
use DateInterval;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Semanal extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger, protected Repository\Inmobiliaria $repositoryRepository,
|
||||
protected Service\Inmobiliaria\Cuenta $cuentaService,
|
||||
protected Repository\Contabilidad\Deposito $depositoRepository,
|
||||
protected Service\Contabilidad\Cartola $cartolaService,
|
||||
protected Service\Contabilidad\Movimiento $movimientoService,
|
||||
protected Service\Contabilidad\Informe\Tesoreria\Excel $excelService,
|
||||
protected Service\Contabilidad\Informe\Tesoreria\PDF $pdfService)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
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
|
||||
{}
|
||||
}
|
@ -1,378 +1,23 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe;
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Tesoreria extends Ideal\Service
|
||||
{
|
||||
protected const ORDEN_SOCIEDADES = [
|
||||
99543380,
|
||||
78017310,
|
||||
76837020,
|
||||
76743916,
|
||||
76519798,
|
||||
76309587,
|
||||
77023196,
|
||||
77023201,
|
||||
76309592,
|
||||
76163347,
|
||||
76158424
|
||||
];
|
||||
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Inmobiliaria $inmobiliariaRepository,
|
||||
protected Service\Inmobiliaria\Cuenta $cuentaService,
|
||||
protected Repository\Contabilidad\Deposito $depositoRepository,
|
||||
protected Repository\Contabilidad\Cartola $cartolaRepository,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Service\Contabilidad\Informe\Tesoreria\Excel $excelService,
|
||||
protected Service\Contabilidad\Informe\Tesoreria\PDF $pdfService)
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Tesoreria\Output $outputService,
|
||||
protected Tesoreria\Input $inputService)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
|
36
app/src/Service/Contabilidad/Informe/Tesoreria/Input.php
Normal file
36
app/src/Service/Contabilidad/Informe/Tesoreria/Input.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
class Input extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Input\Excel $excelService,
|
||||
protected Input\Data\SaldosContables $saldosContablesService,
|
||||
protected Input\Data\DAPyFFMM $dapYFFMMService)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function loadFromExcel(UploadedFileInterface $uploadedFile): array
|
||||
{
|
||||
if ($uploadedFile->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']);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input\Data;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
class DAPyFFMM extends Ideal\Service
|
||||
{
|
||||
public function load(array $data): void
|
||||
{
|
||||
$this->logger->error('Cargando DAP y FFMM', $data);
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input\Data;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class SaldosContables extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Inmobiliaria $inmobiliariaRepository,
|
||||
protected Repository\Inmobiliaria\Cuenta $cuentaRepository,
|
||||
protected Repository\Contabilidad\Banco $bancoRepository,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Repository\Contabilidad\Movimiento\Detalle $detalleRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function load(array $data): void
|
||||
{
|
||||
$this->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}'");
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use PhpOffice\PhpSpreadsheet;
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
class Excel extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Excel\SaldosCuentas $saldosCuentasService,
|
||||
protected Excel\DAPyFFMM $dapyFFMMService,
|
||||
protected Excel\DeudaBanco $deudaBancoService)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function load(string $filename): array
|
||||
{
|
||||
try {
|
||||
$reader = PhpSpreadsheet\IOFactory::createReaderForFile($filename);
|
||||
} catch (PhpSpreadsheet\Reader\Exception $e) {
|
||||
$this->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;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input\Excel;
|
||||
|
||||
use stdClass;
|
||||
use PhpOffice\PhpSpreadsheet;
|
||||
|
||||
class DAPyFFMM extends Sheet
|
||||
{
|
||||
public function load(PhpSpreadsheet\Spreadsheet $excel): array
|
||||
{
|
||||
if (!$excel->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;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input\Excel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet;
|
||||
|
||||
class DeudaBanco extends Sheet
|
||||
{
|
||||
public function load(PhpSpreadsheet\Spreadsheet $excel): array
|
||||
{
|
||||
if (!$excel->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;
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input\Excel;
|
||||
|
||||
use stdClass;
|
||||
use PhpOffice\PhpSpreadsheet;
|
||||
|
||||
class SaldosCuentas extends Sheet
|
||||
{
|
||||
public function load(PhpSpreadsheet\Spreadsheet $excel): array
|
||||
{
|
||||
if (!$excel->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;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input\Excel;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet;
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
abstract class Sheet extends Ideal\Service
|
||||
{
|
||||
protected function getCalculatedValue(PhpSpreadsheet\Worksheet\Worksheet $sheet, int|string $columnIndex, ?int $rowIndex = null, mixed $default = 0): mixed
|
||||
{
|
||||
try {
|
||||
if (is_string($columnIndex)) {
|
||||
if ($rowIndex === null) {
|
||||
return $sheet->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;
|
||||
}
|
226
app/src/Service/Contabilidad/Informe/Tesoreria/Output.php
Normal file
226
app/src/Service/Contabilidad/Informe/Tesoreria/Output.php
Normal file
@ -0,0 +1,226 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria;
|
||||
|
||||
use DateInterval;
|
||||
use DateTimeInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Output extends Ideal\Service
|
||||
{
|
||||
protected const ORDEN_SOCIEDADES = [
|
||||
99543380,
|
||||
78017310,
|
||||
76837020,
|
||||
76743916,
|
||||
76519798,
|
||||
76309587,
|
||||
77023196,
|
||||
77023201,
|
||||
76309592,
|
||||
76163347,
|
||||
76158424
|
||||
];
|
||||
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 __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;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Output\Data;
|
||||
|
||||
class Cuenta
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Output\Data;
|
||||
|
||||
class Movimientos
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Output\Data;
|
||||
|
||||
use Incoviba\Model;
|
||||
|
||||
class Sociedad
|
||||
{
|
||||
public Model\Inmobiliaria $sociedad;
|
||||
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);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Output\Data;
|
||||
|
||||
class Totales
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria;
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Output;
|
||||
|
||||
use DateTimeInterface;
|
||||
use DateInterval;
|
||||
use DateTimeInterface;
|
||||
use IntlDateFormatter;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use PhpOffice\PhpSpreadsheet;
|
||||
@ -176,7 +176,7 @@ class Excel extends Ideal\Service
|
||||
$this->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);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria;
|
||||
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Output;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
@ -2,17 +2,18 @@
|
||||
namespace Incoviba\Service\Contabilidad;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal\Service;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Movimiento extends Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Repository\Movimiento\Detalle $detalleRepository)
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Contabilidad\Movimiento $movimientoRepository,
|
||||
protected Repository\Contabilidad\Movimiento\Detalle $detalleRepository,
|
||||
protected Movimiento\Auxiliar $auxiliarService)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
@ -33,6 +34,22 @@ class Movimiento extends Service
|
||||
{
|
||||
return array_map([$this, 'process'], $this->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;
|
||||
}
|
||||
}
|
||||
|
42
app/src/Service/Contabilidad/Movimiento/Auxiliar.php
Normal file
42
app/src/Service/Contabilidad/Movimiento/Auxiliar.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Contabilidad\Movimiento;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Service;
|
||||
|
||||
class Auxiliar extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Contabilidad\Movimiento\Auxiliar $auxiliarRepository,
|
||||
protected Repository\Contabilidad\Movimiento\Auxiliar\Detalle $detalleRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getByMovimiento(int $movimiento_id): ?array
|
||||
{
|
||||
try {
|
||||
return array_map([$this, 'process'], $this->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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
56
app/src/Service/Persona.php
Normal file
56
app/src/Service/Persona.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace Incoviba\Service;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class Persona extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger, protected Repository\Persona $personaRepository,
|
||||
protected Repository\DatosPersona $datosPersonaRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getByRut(int $rut): Model\Persona
|
||||
{
|
||||
return $this->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;
|
||||
}
|
||||
}
|
85
app/src/Service/Sociedad.php
Normal file
85
app/src/Service/Sociedad.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace Incoviba\Service;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Repository;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Common\Implement\Exception\EmptyResult;
|
||||
|
||||
class Sociedad extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger, protected Repository\Sociedad $sociedadRepository,
|
||||
protected Repository\Inmobiliaria $inmobiliariaRepository,
|
||||
protected Repository\Inmobiliaria\Proveedor $proveedorRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getByRut(int $sociedad_rut): ?Model\Sociedad
|
||||
{
|
||||
try {
|
||||
return $this->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;
|
||||
}
|
||||
}
|
95
app/src/Service/Venta/Factura.php
Normal file
95
app/src/Service/Venta/Factura.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Incoviba\Common\Ideal;
|
||||
use Incoviba\Common\Implement;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Repository;
|
||||
|
||||
class Factura extends Ideal\Service
|
||||
{
|
||||
public function __construct(LoggerInterface $logger,
|
||||
protected Repository\Venta\Factura $facturaRepository,
|
||||
protected Repository\Venta\Factura\Estado $estadoRepository,
|
||||
protected Repository\Venta\Factura\Estado\Tipo $tipoRepository)
|
||||
{
|
||||
parent::__construct($logger);
|
||||
}
|
||||
|
||||
public function getAll(null|string|array $orderBy = null): array
|
||||
{
|
||||
try {
|
||||
return array_map([$this, 'process'], $this->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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
2
php-memory.ini
Normal file
2
php-memory.ini
Normal file
@ -0,0 +1,2 @@
|
||||
memory_limit = 512M
|
||||
max_execution_time = 300
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user