diff --git a/app/common/Implement/Database/Query/Select.php b/app/common/Implement/Database/Query/Select.php
index 0f7a88b..aa4874a 100644
--- a/app/common/Implement/Database/Query/Select.php
+++ b/app/common/Implement/Database/Query/Select.php
@@ -126,7 +126,7 @@ class Select extends Ideal\Query implements Define\Query\Select
}
protected function addCondition(string $condition): Select
{
- if (!isset($this->coditions)) {
+ if (!isset($this->conditions)) {
$this->conditions = [];
}
$this->conditions []= $condition;
diff --git a/app/resources/views/contabilidad/cartolas/import.blade.php b/app/resources/views/contabilidad/cartolas/import.blade.php
index 365f734..e840d50 100644
--- a/app/resources/views/contabilidad/cartolas/import.blade.php
+++ b/app/resources/views/contabilidad/cartolas/import.blade.php
@@ -42,6 +42,7 @@
RUT |
Nombres |
Identificador |
+ |
@@ -179,9 +180,10 @@
}
class Movimiento {
props
- constructor({sociedad, fecha, glosa, cargo, abono, saldo, categoria, detalle, centro_costo, rut, nombres,
- identificador, relacionado, relacionadoType}) {
+ constructor({id, sociedad, fecha, glosa, cargo, abono, saldo, categoria, detalle, centro_costo, rut, nombres,
+ identificador, relacionado, relacionadoType, nuevo = false, obsoleto = false}) {
this.props = {
+ id,
sociedad,
fecha,
glosa,
@@ -195,7 +197,9 @@
nombres,
identificador,
relacionado,
- relacionadoType
+ relacionadoType,
+ nuevo,
+ obsoleto
}
}
draw({formatters}) {
@@ -210,8 +214,17 @@
nombre = this.props.nombres
}
}
+ let edit = ''
+ let color = ''
+ if (this.props.nuevo) {
+ color = ' class="green"'
+ }
+ if (this.props.obsoleto) {
+ color = ' class="red"'
+ edit = ``
+ }
return [
- '',
+ `
`,
`${this.props.sociedad.sigla} | `,
`${formatters.date.format(fecha)} | `,
`${this.props.glosa} | `,
@@ -224,6 +237,7 @@
`${this.props.rut ?? ''} | `,
`${nombre} | `,
`${this.props.identificador ?? ''} | `,
+ `${edit} | `,
'
'
].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() {
return {
form: () => {
@@ -269,6 +299,12 @@
tbody.append(movimiento.draw({formatters: this.formatters}))
})
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) {
return
}
diff --git a/app/src/Repository/Contabilidad/Movimiento.php b/app/src/Repository/Contabilidad/Movimiento.php
index a59f1a9..84313a6 100644
--- a/app/src/Repository/Contabilidad/Movimiento.php
+++ b/app/src/Repository/Contabilidad/Movimiento.php
@@ -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')]);
}
+ 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')]);
+ }
}
diff --git a/app/src/Service/Contabilidad/Cartola.php b/app/src/Service/Contabilidad/Cartola.php
index 61a29f4..c525580 100644
--- a/app/src/Service/Contabilidad/Cartola.php
+++ b/app/src/Service/Contabilidad/Cartola.php
@@ -91,12 +91,16 @@ class Cartola extends Service
$cartola = $this->buildCartola($cuenta, $fecha, $cartolaData);
return compact('cartola', 'movimientos');
}
+
public function import(int $cuenta_id, UploadedFileInterface $file): array
{
$cuenta = $this->cuentaRepository->fetchById($cuenta_id);
$movimientos = $this->process($cuenta->banco, $file);
- foreach ($movimientos as $dataMovimiento) {
+ $inmobiliaria = $cuenta->inmobiliaria;
+
+ $addedMovimientos = [];
+ foreach ($movimientos as &$dataMovimiento) {
$dataMovimiento['cuenta_id'] = $cuenta->id;
if (array_key_exists('centro_costo', $dataMovimiento) and $dataMovimiento['centro_costo'] !== 0) {
$dataMovimiento['centro_costo_id'] = $dataMovimiento['centro_costo'];
@@ -112,10 +116,21 @@ class Cartola extends Service
$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) {
- return $movimiento['fecha'];
+ return $movimiento['fecha']->format('Y-m-d');
}, $movimientos));
foreach ($fechas as $dia) {
try {
@@ -140,11 +155,25 @@ class Cartola extends Service
$this->buildCartola($cuenta, new DateTimeImmutable($dia), $cartolaData);
}
- $inmobiliaria = $cuenta->inmobiliaria;
- return array_map(function($movimiento) use ($inmobiliaria) {
- $movimiento['sociedad'] = $inmobiliaria;
+ $startDate = new DateTimeImmutable(min($fechas));
+ $endDate = new DateTimeImmutable(max($fechas));
+ $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;
- }, $movimientos);
+ }, array_merge($movimientos, $movimientosObsoletos));
}
public function check(): array
{
diff --git a/app/src/Service/Contabilidad/Movimiento.php b/app/src/Service/Contabilidad/Movimiento.php
index 8e4ee2e..97aee84 100644
--- a/app/src/Service/Contabilidad/Movimiento.php
+++ b/app/src/Service/Contabilidad/Movimiento.php
@@ -85,6 +85,14 @@ class Movimiento extends Service
{
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
{