feature/colores-importar-movimientos #4

Merged
aldarien merged 4 commits from feature/colores-importar-movimientos into develop 2024-12-17 00:08:12 -03:00
5 changed files with 100 additions and 13 deletions

View File

@ -126,7 +126,7 @@ class Select extends Ideal\Query implements Define\Query\Select
} }
protected function addCondition(string $condition): Select protected function addCondition(string $condition): Select
{ {
if (!isset($this->coditions)) { if (!isset($this->conditions)) {
$this->conditions = []; $this->conditions = [];
} }
$this->conditions []= $condition; $this->conditions []= $condition;

View File

@ -42,6 +42,7 @@
<th>RUT</th> <th>RUT</th>
<th>Nombres</th> <th>Nombres</th>
<th class="center aligned">Identificador</th> <th class="center aligned">Identificador</th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -179,9 +180,10 @@
} }
class Movimiento { class Movimiento {
props props
constructor({sociedad, fecha, glosa, cargo, abono, saldo, categoria, detalle, centro_costo, rut, nombres, constructor({id, sociedad, fecha, glosa, cargo, abono, saldo, categoria, detalle, centro_costo, rut, nombres,
identificador, relacionado, relacionadoType}) { identificador, relacionado, relacionadoType, nuevo = false, obsoleto = false}) {
this.props = { this.props = {
id,
sociedad, sociedad,
fecha, fecha,
glosa, glosa,
@ -195,7 +197,9 @@
nombres, nombres,
identificador, identificador,
relacionado, relacionado,
relacionadoType relacionadoType,
nuevo,
obsoleto
} }
} }
draw({formatters}) { draw({formatters}) {
@ -210,8 +214,17 @@
nombre = this.props.nombres nombre = this.props.nombres
} }
} }
let edit = ''
let color = ''
if (this.props.nuevo) {
color = ' class="green"'
}
if (this.props.obsoleto) {
color = ' class="red"'
edit = `<button class="ui tertiary red icon button remove_movimiento" data-id="${this.props.id}"><i class="remove icon"></i></button>`
}
return [ return [
'<tr>', `<tr${color}>`,
`<td>${this.props.sociedad.sigla}</td>`, `<td>${this.props.sociedad.sigla}</td>`,
`<td>${formatters.date.format(fecha)}</td>`, `<td>${formatters.date.format(fecha)}</td>`,
`<td>${this.props.glosa}</td>`, `<td>${this.props.glosa}</td>`,
@ -224,6 +237,7 @@
`<td>${this.props.rut ?? ''}</td>`, `<td>${this.props.rut ?? ''}</td>`,
`<td>${nombre}</td>`, `<td>${nombre}</td>`,
`<td class="center aligned">${this.props.identificador ?? ''}</td>`, `<td class="center aligned">${this.props.identificador ?? ''}</td>`,
`<td class="right aligned">${edit}</td>`,
'</tr>' '</tr>'
].join("\n") ].join("\n")
} }
@ -250,6 +264,22 @@
} }
} }
}, },
remove() {
return {
movimiento: id => {
const url = `{{$urls->api}}/contabilidad/movimiento/${id}`
const method = 'delete'
APIClient.fetch(url, {method}).then(response => {
if (!response.status) {
return
}
const index = this.data.movimientos.findIndex(movimiento => movimiento.id === response.movimiento.id)
this.data.movimientos.splice(index, 1)
this.draw().movimientos()
})
}
}
},
draw() { draw() {
return { return {
form: () => { form: () => {
@ -269,6 +299,12 @@
tbody.append(movimiento.draw({formatters: this.formatters})) tbody.append(movimiento.draw({formatters: this.formatters}))
}) })
table.show() table.show()
Object.values(document.getElementsByClassName('remove_movimiento')).forEach(element => {
element.addEventListener('click', clickEvent => {
const id = clickEvent.currentTarget.dataset['id']
this.remove().movimiento(id)
})
})
} }
} }
}, },
@ -293,7 +329,7 @@
}) })
}) })
fetchAPI(url, {method, body}).then(response => { APIClient.fetch(url, {method, body}).then(response => {
if (!response) { if (!response) {
return return
} }

View File

@ -99,4 +99,18 @@ class Movimiento extends Ideal\Repository
} }
return $this->fetchMany($query, [$sociedad_rut, $mes->format('Y-m-01'), $mes->format('Y-m-t')]); return $this->fetchMany($query, [$sociedad_rut, $mes->format('Y-m-01'), $mes->format('Y-m-t')]);
} }
public function fetchMissingInDateRange(int $cuenta_id, DateTimeInterface $startDate, DateTimeInterface $endDate, array $idList = []): array
{
$query = $this->connection->getQueryBuilder()
->select()
->from($this->getTable())
->where('cuenta_id = ? AND fecha BETWEEN ? AND ?');
if (count($idList) > 0) {
$idString = implode(', ', array_map(function(int $id) {
return $this->connection->getPDO()->quote($id);
}, $idList));
$query->where("id NOT IN ({$idString})");
}
return $this->fetchMany($query, [$cuenta_id, $startDate->format('Y-m-d'), $endDate->format('Y-m-d')]);
}
} }

View File

@ -91,12 +91,16 @@ class Cartola extends Service
$cartola = $this->buildCartola($cuenta, $fecha, $cartolaData); $cartola = $this->buildCartola($cuenta, $fecha, $cartolaData);
return compact('cartola', 'movimientos'); return compact('cartola', 'movimientos');
} }
public function import(int $cuenta_id, UploadedFileInterface $file): array public function import(int $cuenta_id, UploadedFileInterface $file): array
{ {
$cuenta = $this->cuentaRepository->fetchById($cuenta_id); $cuenta = $this->cuentaRepository->fetchById($cuenta_id);
$movimientos = $this->process($cuenta->banco, $file); $movimientos = $this->process($cuenta->banco, $file);
foreach ($movimientos as $dataMovimiento) { $inmobiliaria = $cuenta->inmobiliaria;
$addedMovimientos = [];
foreach ($movimientos as &$dataMovimiento) {
$dataMovimiento['cuenta_id'] = $cuenta->id; $dataMovimiento['cuenta_id'] = $cuenta->id;
if (array_key_exists('centro_costo', $dataMovimiento) and $dataMovimiento['centro_costo'] !== 0) { if (array_key_exists('centro_costo', $dataMovimiento) and $dataMovimiento['centro_costo'] !== 0) {
$dataMovimiento['centro_costo_id'] = $dataMovimiento['centro_costo']; $dataMovimiento['centro_costo_id'] = $dataMovimiento['centro_costo'];
@ -112,10 +116,21 @@ class Cartola extends Service
$dataMovimiento['digito'] = $ruts[0]['digito']; $dataMovimiento['digito'] = $ruts[0]['digito'];
} }
} }
$this->movimientoService->add($dataMovimiento); try {
$movimiento = $this->movimientoRepository
->fetchByCuentaAndFechaAndGlosaAndCargoAndAbonoAndSaldo($dataMovimiento['cuenta_id'], $dataMovimiento['fecha'],
$dataMovimiento['glosa'], $dataMovimiento['cargo'] ?? 0,
$dataMovimiento['abono'] ?? 0, $dataMovimiento['saldo']);
} catch (Exception\EmptyResult) {
$movimiento = $this->movimientoService->add($dataMovimiento);
$dataMovimiento['nuevo'] = true;
}
$dataMovimiento['id'] = $movimiento->id;
$dataMovimiento['sociedad'] = $inmobiliaria;
$addedMovimientos []= $movimiento->id;
} }
$fechas = array_unique(array_map(function($movimiento) { $fechas = array_unique(array_map(function($movimiento) {
return $movimiento['fecha']; return $movimiento['fecha']->format('Y-m-d');
}, $movimientos)); }, $movimientos));
foreach ($fechas as $dia) { foreach ($fechas as $dia) {
try { try {
@ -140,11 +155,25 @@ class Cartola extends Service
$this->buildCartola($cuenta, new DateTimeImmutable($dia), $cartolaData); $this->buildCartola($cuenta, new DateTimeImmutable($dia), $cartolaData);
} }
$inmobiliaria = $cuenta->inmobiliaria; $startDate = new DateTimeImmutable(min($fechas));
return array_map(function($movimiento) use ($inmobiliaria) { $endDate = new DateTimeImmutable(max($fechas));
$movimiento['sociedad'] = $inmobiliaria; $movimientosFaltantes = $this->movimientoService->findMissing($cuenta, $addedMovimientos, $startDate, $endDate);
$movimientosObsoletos = [];
if (count($movimientosFaltantes) > 0) {
$movimientosObsoletos = array_map(function(&$movimiento) {
$arr = (array) $movimiento;
$arr['sociedad'] = $movimiento->cuenta->inmobiliaria;
$arr['obsoleto'] = true;
return $arr;
}, $movimientosFaltantes);
}
return array_map(function($movimiento) {
if (is_a($movimiento['fecha'], DateTimeInterface::class)) {
$movimiento['fecha'] = $movimiento['fecha']->format('Y-m-d');
}
return $movimiento; return $movimiento;
}, $movimientos); }, array_merge($movimientos, $movimientosObsoletos));
} }
public function check(): array public function check(): array
{ {

View File

@ -85,6 +85,14 @@ class Movimiento extends Service
{ {
return $this->detalleService->findRut($rut); return $this->detalleService->findRut($rut);
} }
public function findMissing(Model\Inmobiliaria\Cuenta $cuenta, array $currentIdList, DateTimeInterface $startDate, DateTimeInterface $endDate): array
{
try {
return $this->movimientoRepository->fetchMissingInDateRange($cuenta->id, $startDate, $endDate, $currentIdList);
} catch (EmptyResult) {
return [];
}
}
public function process(Model\Contabilidad\Movimiento $movimiento): Model\Contabilidad\Movimiento public function process(Model\Contabilidad\Movimiento $movimiento): Model\Contabilidad\Movimiento
{ {