Compare commits

...

10 Commits

Author SHA1 Message Date
c582efcf77 Merge branch 'develop' of http://git.provm.cl/Incoviba/operadores.git
into develop
2023-04-12 23:34:56 -04:00
f7bd54b1c2 Change in menu order 2023-04-12 23:27:03 -04:00
93aa4b0576 Update docker and ENV settings 2023-04-12 23:26:48 -04:00
c898bcf1d4 Integrate docker to main page 2023-02-10 06:42:07 +00:00
52e922685d Update 2022-03-07 2022-03-07 12:43:32 +00:00
71e10c52bd FIX: link informes 2022-01-24 18:19:46 -03:00
e672ac48a7 FIX: API Proyecto Operadores 2022-01-24 17:58:20 -03:00
4f7241e146 v0.1.0 2021-08-18 19:03:58 -04:00
b58cda3e4e UI 2021-08-16 22:13:15 -04:00
49374254e4 API 2021-08-16 22:13:08 -04:00
46 changed files with 1466 additions and 151 deletions

4
.db.env.sample Normal file
View File

@ -0,0 +1,4 @@
MYSQL_ROOT_PASSWORD=password
MYSQL_DATABASE=database
MYSQL_USER=user
MYSQL_PASSWORD=password

3
.ui.env.sample Normal file
View File

@ -0,0 +1,3 @@
DEBUG=true
BASE_URL=http://localhost:8080
API_URL=http://localhost:8081

View File

@ -0,0 +1,50 @@
<?php
namespace Incoviba\Common\Controller;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use \Model;
use Incoviba\Common\Define\Controller\Json;
use Incoviba\FacturaProyectoOperador;
class Facturas {
use Json;
public function __invoke() {
}
public function proyecto_operador(Request $request, Response $response): Response {
$post = $request->getParsedBody();
$facturas = Model::factory(FacturaProyectoOperador::class)
->where('proyecto_id', $post['proyecto_id'])
->where('operador_id', $post['operador_id'])
->find_many();
$output = [
'facturas' => $facturas ? array_map(function($item) {
return $item->as_array();
}, $facturas) : null
];
return $this->withJson($response, $output);
}
public function add(Request $request, Response $response): Response {
$post = $request->getParsedBody();
$output = FacturaProyectoOperador::add($post);
return $this->withJson($response, $output);
}
public function ventas(Request $request, Response $response, $id_factura): Response {
$factura = Model::factory(FacturaProyectoOperador::class)->find_one($id_factura);
$output = [
'factura' => $factura->as_array(),
'ventas' => array_map(function($item) {
return $item->as_array();
}, $factura->ventas())
];
return $this->withJson($response, $output);
}
public function add_venta(Request $request, Response $response, $id_factura): Response {
$post = $request->getParsedBody();
$factura = Model::factory(FacturaProyectoOperador::class)->find_one($id_factura);
$output = $factura->addVenta($post);
return $this->withJson($response, $output);
}
}

View File

@ -31,7 +31,10 @@ class Operadores {
} }
public function show(Request $request, Response $response, $id_operador): Response { public function show(Request $request, Response $response, $id_operador): Response {
$operador = Model::factory(Operador::class)->find_one($id_operador); $operador = Model::factory(Operador::class)->find_one($id_operador);
$output = ['operador' => $operador->as_array()]; $output = ['operador' => null];
if ($operador) {
$output = ['operador' => $operador->as_array()];
}
return $this->withJson($response, $output); return $this->withJson($response, $output);
} }
public function add(Request $request, Response $response): Response { public function add(Request $request, Response $response): Response {
@ -49,4 +52,10 @@ class Operadores {
]; ];
return $this->withJson($response, $output); return $this->withJson($response, $output);
} }
public function add_proyecto(Request $request, Response $response, $id_operador): Response {
$operador = Model::factory(Operador::class)->find_one($id_operador);
$post = $request->getParsedBody();
$output = $operador->addProyecto($post);
return $this->withJson($response, $output);
}
} }

View File

@ -20,18 +20,39 @@ class Proyectos {
} }
public function show(Request $request, Response $response, $id_proyecto): Response { public function show(Request $request, Response $response, $id_proyecto): Response {
$proyecto = Model::factory(Proyecto::class)->find_one($id_proyecto); $proyecto = Model::factory(Proyecto::class)->find_one($id_proyecto);
$output = ['proyecto' => $proyecto->as_array()]; $output = ['proyecto' => null];
if ($proyecto) {
$output = ['proyecto' => $proyecto->as_array()];
}
return $this->withJson($response, $output); return $this->withJson($response, $output);
} }
public function ventas(Request $request, Response $response, $id_proyecto): Response { public function ventas(Request $request, Response $response, $id_proyecto): Response {
$proyecto = Model::factory(Proyecto::class)->find_one($id_proyecto); $proyecto = Model::factory(Proyecto::class)->find_one($id_proyecto);
$ventas = $proyecto->ventas();
usort($ventas, function($a, $b) {
return strcmp(str_pad($a->propiedad()->unidades()[0]->descripcion, 4, '0', \STR_PAD_LEFT), str_pad($b->propiedad()->unidades()[0]->descripcion, 4, '0', \STR_PAD_LEFT));
});
$output = [ $output = [
'proyecto' => $proyecto->as_array(), 'proyecto' => $proyecto->as_array(),
'ventas' => array_map(function($item) { 'ventas' => array_map(function($item) {
if ($item) { if ($item) {
return $item->as_array(); return $item->as_array();
} }
}, $proyecto->ventas()) }, $ventas)
];
return $this->withJson($response, $output);
}
public function operadores(Request $request, Response $response, $id_proyecto): Response {
$proyecto = Model::factory(Proyecto::class)->find_one($id_proyecto);
error_log(var_export($proyecto->operadores(), true));
$output = [
'proyecto' => $proyecto->as_array(),
'operadores' => $proyecto->operadores() ? array_map(function($item) {
$arr = $item->as_array();
$arr['agente_tipo'] = $item->agente_tipo()->as_array();
$arr['agente_tipo']['agente'] = $arr['operador'] = $item->agente_tipo()->agente()->as_array();
return $arr;
}, $proyecto->operadores()) : null
]; ];
return $this->withJson($response, $output); return $this->withJson($response, $output);
} }

View File

@ -0,0 +1,23 @@
<?php
namespace Incoviba\Common\Controller;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use \Model;
use Incoviba\Common\Define\Controller\Json;
use Incoviba\Unidad;
class Unidades {
use Json;
public function facturas(Request $request, Response $response, $id_unidad): Response {
$unidad = Model::factory(Unidad::class)->find_one($id_unidad);
$output = [
'unidad' => $unidad->as_array(),
'facturas' => ($unidad->facturas()) ? array_map(function($item) {
return $item->as_array();
}, $unidad->facturas()) : null
];
return $this->withJson($response, $output);
}
}

View File

@ -28,4 +28,20 @@ class Ventas {
]; ];
return $this->withJson($response, $output); return $this->withJson($response, $output);
} }
public function facturas(Request $request, Response $response, $id_venta): Response {
$venta = Model::factory(Venta::class)->find_one($id_venta);
if (!$venta) {
return $this->withJson($response, ['venta' =>null, 'facturas' => null]);
}
$output = [
'venta' => $venta->as_array(),
'facturas' => null
];
if ($venta->facturas() !== null) {
$output['facturas'] = array_map(function($item) {
return $item->as_array();
}, $venta->facturas());
}
return $this->withJson($response, $output);
}
} }

View File

@ -7,7 +7,8 @@
"nyholm/psr7": "^1.4", "nyholm/psr7": "^1.4",
"nyholm/psr7-server": "^1.0", "nyholm/psr7-server": "^1.0",
"zeuxisoo/slim-whoops": "^0.7.3", "zeuxisoo/slim-whoops": "^0.7.3",
"j4mie/paris": "^1.5" "j4mie/paris": "^1.5",
"nesbot/carbon": "^2.51"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.5", "phpunit/phpunit": "^9.5",

View File

@ -18,7 +18,7 @@ server {
location ~ \.php$ { location ~ \.php$ {
try_files $uri =404; try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass backend:9000; fastcgi_pass operadores-backend:9000;
fastcgi_index index.php; fastcgi_index index.php;
include fastcgi_params; include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

View File

@ -0,0 +1,16 @@
<?php
use Incoviba\Common\Controller\Facturas;
$app->group('/facturas', function($app) {
$app->group('/add', function($app) {
$app->post('[/]', [Facturas::class, 'add']);
});
$app->post('[/]', [Facturas::class, 'proyecto_operador']);
$app->get('[/]', Facturas::class);
});
$app->group('/factura/{id_factura}', function($app) {
$app->group('/ventas', function($app) {
$app->post('/add[/]', [Facturas::class, 'add_venta']);
$app->get('[/]', [Facturas::class, 'ventas']);
});
});

View File

@ -9,5 +9,9 @@ $app->group('/operador/{id_operador}', function($app) {
$app->group('/ventas', function($app) { $app->group('/ventas', function($app) {
$app->get('[/]', [Operadores::class, 'ventas']); $app->get('[/]', [Operadores::class, 'ventas']);
}); });
$app->group('/proyectos', function($app) {
$app->post('/add[/]', [Operadores::class, 'add_proyecto']);
$app->get('[/]', [Operadores::class, 'proyectos']);
});
$app->get('[/]', [Operadores::class, 'show']); $app->get('[/]', [Operadores::class, 'show']);
}); });

View File

@ -8,5 +8,8 @@ $app->group('/proyecto/{id_proyecto}', function($app) {
$app->group('/ventas', function($app) { $app->group('/ventas', function($app) {
$app->get('[/]', [Proyectos::class, 'ventas']); $app->get('[/]', [Proyectos::class, 'ventas']);
}); });
$app->group('/operadores', function($app) {
$app->get('[/]', [Proyectos::class, 'operadores']);
});
$app->get('[/]', [Proyectos::class, 'show']); $app->get('[/]', [Proyectos::class, 'show']);
}); });

View File

@ -0,0 +1,8 @@
<?php
use Incoviba\Common\Controller\Unidades;
$app->group('/unidad/{id_unidad}', function($app) {
$app->group('/facturas', function($app) {
$app->get('[/]', [Unidades::class, 'facturas']);
});
});

View File

@ -8,5 +8,8 @@ $app->group('/venta/{id_venta}', function($app) {
$app->group('/operador', function($app) { $app->group('/operador', function($app) {
$app->get('[/]', [Ventas::class, 'operador']); $app->get('[/]', [Ventas::class, 'operador']);
}); });
$app->group('/facturas', function($app) {
$app->get('[/]', [Ventas::class, 'facturas']);
});
$app->get('[/]', [Ventas::class, 'show']); $app->get('[/]', [Ventas::class, 'show']);
}); });

View File

@ -7,7 +7,7 @@ return [
'engine' => 'mysql', 'engine' => 'mysql',
'name' => $_ENV['MYSQL_DATABASE'], 'name' => $_ENV['MYSQL_DATABASE'],
'host' => (object) [ 'host' => (object) [
'name' => 'db' 'name' => $_ENV['MYSQL_HOST']
], ],
'user' => (object) [ 'user' => (object) [
'name' => $_ENV['MYSQL_USER'], 'name' => $_ENV['MYSQL_USER'],

View File

@ -13,4 +13,12 @@ class Agente extends Model {
} }
return $this->agente_tipos; return $this->agente_tipos;
} }
public function findAgenteTipo(string $tipo) {
foreach ($this->agente_tipos() as $at) {
if ($at->tipo()->descripcion == $tipo) {
return $at;
}
}
return false;
}
} }

View File

@ -1,24 +0,0 @@
<?php
namespace Incoviba;
use \Model;
/**
* @property int $id
* @property Operador $operador_id
* @property int $factura
* @property int $valor_neto
* @property int $iva
* @property int $valor_total
*/
class FacturaOperador extends Model {
public static $_table = 'factura_operador';
protected $operador;
public function operador() {
if ($this->operador === null) {
$this->operador = $this->belongs_to(Operador::class, 'operador_id')->find_one();
}
return $this->operador;
}
}

View File

@ -0,0 +1,117 @@
<?php
namespace Incoviba;
use Carbon\Carbon;
use \Model;
/**
* @property int $id
* @property Proyecto $proyecto_id
* @property Operador $operador_id
* @property int $factura
* @property double $valor_uf
* @property int $valor_neto
* @property int $iva
*/
class FacturaProyectoOperador extends Model {
public static $_table = 'factura_proyecto_operador';
protected $proyecto;
public function proyecto() {
if ($this->proyecto === null) {
$this->proyecto = $this->belongs_to(Proyecto::class, 'proyecto_id')->find_one();
}
return $this->proyecto;
}
protected $operador;
public function operador() {
if ($this->operador === null) {
$this->operador = $this->belongs_to(Operador::class, 'operador_id')->find_one();
}
return $this->operador;
}
public function fecha(\DateTime $fecha = null) {
if ($fecha === null) {
return Carbon::parse($this->fecha);
}
$this->fecha = $fecha->format('Y-m-d');
}
public function valor_total() {
return $this->valor_neto + $this->iva;
}
protected $ventas;
public function ventas() {
if ($this->ventas === null) {
$this->ventas = $this->has_many(FacturaVenta::class, 'factura_id')->find_many();
}
return $this->ventas;
}
public static function add($data) {
$fields = [
'proyecto_id',
'operador_id',
'factura',
'valor_uf',
'valor_neto',
'iva'
];
$input = array_intersect_key($data, array_combine($fields, $fields));
$validate = [
'proyecto_id',
'operador_id',
'factura'
];
$orm = Model::factory(FacturaProyectoOperador::class);
foreach ($validate as $field) {
$orm = $orm->where($field, $input[$field]);
}
$factura = $orm->find_one();
$created = false;
$found = true;
if (!$factura) {
$found = false;
$factura = FacturaProyectoOperador::create($input);
$created = $factura->save();
}
$output = [
'input' => $data,
'factura' => $factura->as_array(),
'new' => !$found,
'created' => $created
];
return $output;
}
public function addVenta($data) {
$data['factura_id'] = $this->id;
return FacturaVenta::add($data);
}
public function as_array() {
$arr = parent::as_array();
$arr['proyecto'] = $this->proyecto()->as_array();
$arr['operador'] = $this->operador()->as_array();
$arr['fecha'] = (object) [
'valor' => $this->fecha,
'formateada' => $this->fecha()->format('d-m-Y')
];
$arr['valor_uf'] = (object) [
'valor' => $this->valor_uf,
'formateado' => number_format($this->valor_uf, 2, ',', '.') . ' UF'
];
$arr['valor_neto'] = (object) [
'valor' => $this->valor_neto,
'formateado' => '$ ' . number_format($this->valor_neto, 0, ',', '.')
];
$arr['iva'] = (object) [
'valor' => $this->iva,
'formateado' => '$ ' . number_format($this->iva, 0, ',', '.')
];
$arr['valor_total'] = (object) [
'valor' => $this->valor_total(),
'formateado' => '$ ' . number_format($this->valor_total(), 0, ',', '.')
];
return $arr;
}
}

View File

@ -1,29 +0,0 @@
<?php
namespace Incoviba;
use \Model;
/**
* @property int $id
* @property FacturaOperador $factura_id
* @property Unidad $unidad_id
* @property double $valor
*/
class FacturaUnidad extends Model {
public static $_table = 'factura_unidad';
protected $factura;
public function factura() {
if ($this->factura === null) {
$this->factura = $this->belongs_to(FacturaOperador::class, 'factura_id')->find_one();
}
return $this->factura;
}
protected $unidad;
public function unidad() {
if ($this->unidad === null) {
$this->unidad = $this->belongs_to(Unidad::class, 'unidad_id')->find_one();
}
return $this->unidad;
}
}

71
api/src/FacturaVenta.php Normal file
View File

@ -0,0 +1,71 @@
<?php
namespace Incoviba;
use \Model;
/**
* @property int $id
* @property FacturaOperador $factura_id
* @property Venta $venta_id
* @property double $valor
*/
class FacturaVenta extends Model {
public static $_table = 'factura_venta';
protected $factura;
public function factura() {
if ($this->factura === null) {
$this->factura = $this->belongs_to(FacturaProyectoOperador::class, 'factura_id')->find_one();
}
return $this->factura;
}
protected $venta;
public function venta() {
if ($this->venta === null) {
$this->venta = $this->belongs_to(Venta::class, 'venta_id')->find_one();
}
return $this->venta;
}
public static function add($data) {
$fields = [
'factura_id',
'venta_id',
'valor'
];
$input = array_intersect_key($data, array_combine($fields, $fields));
$validate = [
'factura_id',
'venta_id'
];
$orm = Model::factory(FacturaVenta::class);
foreach ($validate as $field) {
$orm = $orm->where($field, $input[$field]);
}
$factura = $orm->find_one();
$created = false;
$found = true;
if (!$factura) {
$found = false;
$factura = FacturaVenta::create($input);
$created = $factura->save();
}
return [
'input' => $input,
'factura' => $factura->as_array(),
'new' => !$found,
'created' => $created
];
}
public function as_array() {
$arr = parent::as_array();
$arr['factura'] = $this->factura()->as_array();
$arr['venta'] = $this->venta()->as_array();
$arr['valor'] = (object) [
'valor' => $this->valor,
'formateado' => number_format($this->valor, 2, ',', '.') . ' UF'
];
return $arr;
}
}

View File

@ -70,11 +70,19 @@ class Operador extends Agente {
$output = [ $output = [
'input' => $data, 'input' => $data,
'operador' => $operador->as_array(), 'operador' => $operador->as_array(),
'new' => $found, 'new' => !$found,
'created' => $created 'created' => $created
]; ];
return $output; return $output;
} }
public function addProyecto($data) {
$data['agente'] = $this->findAgenteTipo('operador')->id;
$pa = ProyectoAgente::add($data);
return [
'operador' => $this->as_array(),
'proyecto_agente' => $pa
];
}
public function as_array() { public function as_array() {
$arr = parent::as_array(); $arr = parent::as_array();

View File

@ -13,4 +13,33 @@ class Propiedad extends Model {
} }
return $this->venta; return $this->venta;
} }
protected $unidades;
public function unidades() {
if ($this->unidades === null) {
$pus = $this->has_many(PropiedadUnidad::class, 'propiedad')->find_many();
usort($pus, function($a, $b) {
$p = $a->principal - $b->principal;
if ($p == 0) {
$t = $a->unidad()->tipo - $b->unidad()->tipo;
if ($t == 0) {
return $a->unidad()->descripcion - $b->unidad()->descripcion;
}
return $t;
}
return -$p;
});
$this->unidades = array_map(function($item) {
return $item->unidad();
}, $pus);
}
return $this->unidades;
}
public function as_array() {
$arr = parent::as_array();
$arr['unidades'] = array_map(function($item) {
return $item->as_array();
}, $this->unidades());
return $arr;
}
} }

View File

@ -13,4 +13,11 @@ class PropiedadUnidad extends Model {
} }
return $this->propiedad_obj; return $this->propiedad_obj;
} }
protected $unidad_obj;
public function unidad() {
if ($this->unidad_obj === null) {
$this->unidad_obj = $this->belongs_to(Unidad::class, 'unidad')->find_one();
}
return $this->unidad_obj;
}
} }

31
api/src/Propietario.php Normal file
View File

@ -0,0 +1,31 @@
<?php
namespace Incoviba;
use \Model;
class Propietario extends Model {
public static $_table = 'propietario';
public static $_id_columns = ['rut'];
protected $venta;
public function venta() {
if ($this->venta === null) {
$this->venta = $this->has_one(Venta::class, 'propietario', 'rut')->find_one();
}
return $this->venta;
}
public function nombreCompleto() {
return implode(' ', [
$this->nombres,
$this->apellido_paterno,
$this->apellido_materno
]);
}
public function as_array() {
$arr = parent::as_array();
$arr['nombre_completo'] = $this->nombreCompleto();
return $arr;
}
}

View File

@ -41,6 +41,18 @@ class Proyecto extends Model {
return $this->proyecto_tipo_unidades; return $this->proyecto_tipo_unidades;
} }
protected $operadores;
public function operadores() {
if ($this->operadores === null) {
$pas = $this->has_many(ProyectoAgente::class, 'proyecto')->find_many();
$pas = array_filter($pas, function($pa) {
return ($pa->agente_tipo()->tipo() === 'operador');
});
$this->operadores = $pas;
}
return $this->operadores;
}
public function as_array() { public function as_array() {
$arr = parent::as_array(); $arr = parent::as_array();
$arr['inmobiliaria'] = $this->inmobiliaria()->as_array(); $arr['inmobiliaria'] = $this->inmobiliaria()->as_array();

View File

@ -27,4 +27,25 @@ class ProyectoAgente extends Model {
} }
return $this->proyecto_obj; return $this->proyecto_obj;
} }
public static function add($data) {
$fields = ['agente', 'proyecto', 'fecha', 'comision'];
$input = array_intersect_key($data, array_combine($fields, $fields));
$pa = Model::factory(ProyectoAgente::class)
->where('proyecto', $input['proyecto'])
->where('agente', $input['agente'])
->where('fecha', $input['fecha'])
->find_one();
$created = false;
if (!$pa) {
$pa = ProyectoAgente::create($input);
$created = $pa->save();
}
$output = [
'input' => $input,
'proyecto_agente' => $pa->as_array(),
'created' => $created
];
return $output;
}
} }

View File

@ -13,4 +13,12 @@ class ProyectoTipoUnidad extends Model {
} }
return $this->unidades; return $this->unidades;
} }
protected $proyecto_obj;
public function proyecto() {
if ($this->proyecto_obj === null) {
$this->proyecto_obj = $this->belongs_to(Proyecto::class, 'proyecto')->find_one();
}
return $this->proyecto_obj;
}
} }

View File

@ -13,4 +13,11 @@ class Unidad extends Model {
} }
return $this->propiedad_unidad; return $this->propiedad_unidad;
} }
protected $proyecto_tipo_unidad;
public function proyecto_tipo_unidad() {
if ($this->proyecto_tipo_unidad === null) {
$this->proyecto_tipo_unidad = $this->belongs_to(ProyectoTipoUnidad::class, 'pt')->find_one();
}
return $this->proyecto_tipo_unidad;
}
} }

View File

@ -43,4 +43,56 @@ class Venta extends Model {
} }
return $this->activa; return $this->activa;
} }
protected $propietario_obj;
public function propietario() {
if ($this->propietario_obj === null) {
$this->propietario_obj = $this->belongs_to(Propietario::class, 'propietario', 'rut')->find_one();
}
return $this->propietario_obj;
}
protected $propiedad_obj;
public function propiedad() {
if ($this->propiedad_obj === null) {
$this->propiedad_obj = $this->belongs_to(Propiedad::class, 'propiedad')->find_one();
}
return $this->propiedad_obj;
}
protected $comision;
public function comision() {
if ($this->comision === null) {
$proyecto_id = $this->propiedad()->unidades()[0]->proyecto_tipo_unidad()->proyecto()->id;
$comision = array_values(array_filter($this->operador()->comisiones(), function($item) use ($proyecto_id) {
return ($item->proyecto->id == $proyecto_id);
}));
$comision = $comision[0]->comision;
$this->comision = (object) [
'valor' => $comision / 100,
'total' => $comision / 100 * $this->valor_uf
];
}
return $this->comision;
}
protected $facturas;
public function facturas() {
if ($this->facturas === null) {
$this->facturas = $this->has_many(FacturaVenta::class, 'venta_id')->find_many();
}
return $this->facturas;
}
public function as_array() {
$arr = parent::as_array();
$arr['propietario'] = $this->propietario()->as_array();
$arr['propiedad'] = $this->propiedad()->as_array();
$arr['valor'] = [
'valor' => $this->valor_uf,
'formateado' => number_format($this->valor_uf, 2, ',', '.') . ' UF'
];
if ($this->operador()) {
$arr['operador'] = $this->operador()->as_array();
$arr['comision'] = (array) $this->comision();
$arr['comision']['formateada'] = number_format($this->comision()->total, 2, ',', '.') . ' UF';
}
return $arr;
}
} }

View File

@ -1,68 +1,83 @@
version: '3' version: '3'
services: services:
backend-proxy: operadores-backend-proxy:
container_name: backend_proxy profiles:
- operadores
container_name: operadores_api
image: nginx image: nginx
volumes: volumes:
- ./api/:/app/ - ${OPERADORES_PATH:-.}/api/:/app/
- ./api/nginx.conf:/etc/nginx/conf.d/default.conf - ${OPERADORES_PATH:-.}/api/nginx.conf:/etc/nginx/conf.d/default.conf
- ./logs/api/:/var/log/nginx/ - ./logs/operadores/api/:/var/log/nginx/
restart: unless-stopped restart: unless-stopped
ports: ports:
- 8081:80 - 8001:80
depends_on: depends_on:
- backend - operadores-backend
backend: operadores-backend:
container_name: backend profiles:
- operadores
container_name: operadores_backend
restart: unless-stopped
image: php image: php
build: build:
context: ./api context: ${OPERADROES_PATH:-.}/api
dockerfile: PHP.Dockerfile dockerfile: PHP.Dockerfile
env_file: .db.env env_file: ${OPERADORES_PATH:-.}/.db.env
volumes: volumes:
- ./api/:/app/ - ${OPERADORES_PATH:-.}/api/:/app/
depends_on: # depends_on:
- db # - db
frontend-proxy: operadores-frontend-proxy:
container_name: frontend_proxy profiles:
- operadores
container_name: operadores_ui
image: nginx image: nginx
volumes: volumes:
- ./ui/:/app/ - ${OPERADORES_PATH:-.}/ui/:/app/
- ./ui/nginx.conf:/etc/nginx/conf.d/default.conf - ${OPERADORES_PATH:-.}/ui/nginx.conf:/etc/nginx/conf.d/default.conf
- ./logs/ui/:/var/log/nginx/ - ./logs/operadores/ui/:/var/log/nginx/
restart: unless-stopped restart: unless-stopped
ports: ports:
- 8080:80 - 8000:80
depends_on: depends_on:
- frontend - operadores-frontend
frontend: operadores-frontend:
container_name: frontend profiles:
- operadores
container_name: operadores_frontend
restart: unless-stopped
image: php:ui image: php:ui
build: build:
context: ./ui context: ${OPERADORES_PATH:-.}/ui
dockerfile: PHP.Dockerfile dockerfile: PHP.Dockerfile
env_file: .ui.env env_file: ${OPERADORES_PATH:-.}/.ui.env
volumes: volumes:
- ./ui/:/app/ - ${OPERADORES_PATH:-.}/ui/:/app/
#
# db:
# image: mariadb
# volumes:
# - database:/var/lib/mysql
# env_file: .db.env
# adminer:
# image: adminer
# environment:
# ADMINER_PLUGINS: "dump-json edit-foreign enum-option json-column"
# ADMINER_DESIGN: "dracula"
# volumes:
# - ./adminer/plugins-enabled/:/var/www/html/plugins-enabled/
# ports:
# - 8082:8080
# depends_on:
# - db
#
#volumes:
# database:
db: networks:
image: mariadb default:
volumes: external: true
- database:/var/lib/mysql name: incoviba_network
env_file: .db.env
adminer:
image: adminer
environment:
ADMINER_PLUGINS: "dump-json edit-foreign enum-option json-column"
ADMINER_DESIGN: "dracula"
volumes:
- ./adminer/plugins-enabled/:/var/www/html/plugins-enabled/
ports:
- 8082:8080
depends_on:
- db
volumes:
database:

View File

@ -0,0 +1,18 @@
<?php
namespace Incoviba\Common\Controller;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View;
class Facturas {
public function __invoke(Request $request, Response $response, View $view): Response {
return $view->render($response, 'facturas.list');
}
public function proyecto(Request $request, Response $response, View $view, $id_proyecto): Response {
return $view->render($response, 'facturas.proyectos.list', compact('id_proyecto'));
}
public function proyecto_operador(Request $request, Response $response, View $view, $id_proyecto, $id_operador): Response {
return $view->render($response, 'facturas.proyectos.operadores.list', compact('id_proyecto', 'id_operador'));
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace Incoviba\Common\Controller;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Views\Blade as View;
class Ventas {
public function __invoke(Request $request, Response $response, View $view): Response {
return $view->render($response, 'ventas.list');
}
public function proyecto(Request $request, Response $response, View $view, $proyecto_id): Response {
return $view->render($response, 'ventas.show', compact('proyecto_id'));
}
}

View File

@ -13,7 +13,7 @@ server {
location ~ \.php$ { location ~ \.php$ {
try_files $uri =404; try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass frontend:9000; fastcgi_pass operadores-frontend:9000;
fastcgi_index index.php; fastcgi_index index.php;
include fastcgi_params; include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

View File

@ -0,0 +1,10 @@
<?php
use Incoviba\Common\Controller\Facturas;
$app->group('/facturas', function($app) {
$app->group('/{id_proyecto:[0-9]+}', function($app) {
$app->get('/{id_operador:[0-9]+}[/]', [Facturas::class, 'proyecto_operador']);
$app->get('[/]', [Facturas::class, 'proyecto']);
});
$app->get('[/]', Facturas::class);
});

View File

@ -0,0 +1,7 @@
<?php
use Incoviba\Common\Controller\Ventas;
$app->group('/ventas', function($app) {
$app->get('/{proyecto_id:[0-9]+}[/]', [Ventas::class, 'proyecto']);
$app->get('[/]', Ventas::class);
});

View File

@ -0,0 +1,66 @@
@extends('layout.base')
@section('content')
<h1 class="header">
Proyectos
</h1>
<table class="table">
<thead>
<tr>
<th>
Proyecto
</th>
<th>
Inmobiliaria
</th>
</tr>
</thead>
<tbody id="proyectos"></tbody>
</table>
@endsection
@push('scripts')
<script type="text/javascript">
const proyectos = {
id: '#proyectos',
data: [],
get: function() {
return $.ajax({
url: '{{$urls->api}}/proyectos',
method: 'get',
dataType: 'json'
}).then((data) => {
if (data.proyectos === null || data.proyectos.length == 0) {
return
}
this.data = data.proyectos
}).then(() => {
this.draw()
})
},
draw: function() {
const parent = $(this.id)
$.each(this.data, (i, el) => {
const url = '{{$urls->base}}/facturas/' + el.id
parent.append(
$('<tr></tr>').append(
$('<td></td>').append(
$('<a></a>').attr('href', url).html(el.descripcion)
)
).append(
$('<td></td>').append(
$('<a></a>').attr('href', url).html(el.inmobiliaria.abreviacion)
)
)
)
})
},
setup: function() {
this.get()
}
}
$(document).ready(() => {
proyectos.setup()
})
</script>
@endpush

View File

@ -0,0 +1,76 @@
@extends('layout.base')
@section('content')
<h1 class="header">
Proyecto <span id="proyecto"></span>
</h1>
<table class="table">
<thead>
<tr>
<th>Operador</th>
<th>Representante</th>
</tr>
</thead>
<tbody id="operadores"></tbody>
</table>
@endsection
@push('scripts')
<script type="text/javascript">
const proyecto = {
id: '#proyecto',
data: {},
get: function() {
const span = $(this.id)
return $.ajax({
url: '{{$urls->api}}/proyecto/{{$id_proyecto}}',
method: 'get',
dataType: 'json'
}).then((data) => {
this.data = data.proyecto
span.html(data.proyecto.descripcion + ' - ' + data.proyecto.inmobiliaria.abreviacion)
}).then(() => {
operadores.get(this.data.id)
})
},
setup: function() {
this.get()
}
}
const operadores = {
id: '#operadores',
data: [],
get: function(proyecto) {
return $.getJSON('{{$urls->api}}/proyecto/' + proyecto + '/operadores').then((data) => {
if (data.operadores === null || data.operadores.length == 0) {
return
}
this.data = data.operadores
return data.proyecto.id
}).then((proyecto) => {
this.draw(proyecto)
})
},
draw: function(proyecto) {
const parent = $(this.id)
const base_url = '{{$urls->base}}/facturas/' + proyecto + '/'
$.each(this.data, (i, el) => {
parent.append(
$('<tr></tr>').append(
$('<td></td>').append(
$('<a></a>').attr('href', base_url + el.id).html(el.descripcion)
)
).append(
$('<td></td>').append(
$('<a></a>').attr('href', base_url + el.id).html(el.representante)
)
)
)
})
}
}
$(document).ready(() => {
proyecto.setup()
})
</script>
@endpush

View File

@ -0,0 +1,343 @@
@extends('layout.base')
@section('content')
<h1 class="header">
Proyecto <span id="proyecto"></span>
<br />
Operador <span id="operador"></span>
</h1>
<table class="table">
<thead>
<tr>
<th>Factura</th>
<th>Fecha</th>
<th>Ventas</th>
<th>Valor Neto</th>
<th>IVA</th>
<th>Valor Bruto</th>
<th class="text-right">
<button class="btn btn-success" data-toggle="modal" data-target="#modal_agregar">
<span class="glyphicon glyphicon-plus"></span>
</button>
</th>
</tr>
</thead>
<tbody id="facturas"></tbody>
</table>
<div class="modal" id="modal_agregar" tabindex="-1" role="dialog" aria-labelledby="Agregar Factura">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Agregar Factura</h4>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="rut" class="control-label">N&uacute;mero</label>
<input type="text" name="factura" class="form-control" />
</div>
<div class="form-group">
<label for="fecha" class="control-label">Fecha</label>
<div class="ui calendar" id="factura_fecha">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input type="text" name="fecha" />
</div>
</div>
<div class="form-group">
<label for="valor_neto" class="control-label">Valor Neto</label>
<input type="text" name="valor_neto" class="form-control" />
</div>
<div class="form-group">
<label for="iva" class="control-label">IVA</label>
<input type="text" name="iva" class="form-control" />
</div>
<button class="btn btn-default" data-dismiss="modal" id="cerrar_agregar">Agregar</button>
</form>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script type="text/javascript">
const proyecto = {
id: '#proyecto',
get: function() {
return $.getJSON('{{$urls->api}}/proyecto/{{$id_proyecto}}').then((data) => {
$('span#proyecto').html(data.proyecto.descripcion + ' - ' + data.proyecto.inmobiliaria.abreviacion)
return data.proyecto.id
})
},
setup: function() {
this.get().then((proyecto) => {
modal().agregar.setup()
modal().add_ventas.setup()
operador.setup(proyecto)
})
}
}
const operador = {
id: '#operador',
get: function(proyecto) {
return $.getJSON('{{$urls->api}}/operador/{{$id_operador}}').then((data) => {
$('span#operador').html(data.operador.descripcion)
return data.operador.id
})
},
setup: function(proyecto) {
this.get(proyecto).then((operador) => {
facturas.get(proyecto, operador)
})
}
}
class Ventas {
constructor(id) {
this.id = id
this.data = []
}
get() {
return $.getJSON('{{$urls->api}}/factura/' + this.id + '/ventas').then((data) => {
if (data.ventas === null || data.ventas.length == 0) {
return
}
this.data = data.ventas
}).then(() => {
this.draw()
})
}
getParent() {
let tbody = $("tbody.ventas[data-id='" + this.id + "']")
if (tbody.length == 0) {
const td = $("td.ventas[data-id='" + this.id + "']")
tbody = $('<tbody></tbody>').attr('class', 'ventas').attr('data-id', this.id)
td.append(
$('<table></table>').attr('class', 'table').append(
$('<thead></thead>').append(
$('<tr></tr>').append(
$('<th></th>').html('Unidad')
).append(
$('<th></th>').html('Valor')
).append(
$('<th></th>').attr('class', 'text-right').append(
$('<button></button>').attr('class', 'btn btn-success')
.attr('data-toggle', 'modal')
.attr('data-target', '#modal_add_ventas')
.attr('data-factura', this.id)
.append(
$('<span></span>').attr('class', 'glyphicon glyphicon-plus')
)
)
)
)
).append(
tbody
)
)
}
return tbody
}
draw() {
const parent = this.getParent()
parent.html('')
$.each(this.data, (i, el) => {
parent.append(
$('<tr></tr>').append(
$('<td></td>').html(el.venta.propiedad.unidades[0].descripcion)
).append(
$('<td></td>').html(el.valor.formateado)
)
)
})
}
}
const facturas = {
id: '#facturas',
data: [],
get: function(proyecto, operador) {
return $.post('{{$urls->api}}/facturas', {proyecto_id: proyecto, operador_id: operador}).then((data) => {
if (data.facturas === null || data.facturas.length == 0) {
return
}
this.data = data.facturas
}).then(() => {
this.draw()
})
},
draw: function() {
const parent = $(this.id)
parent.html('')
$.each(this.data, (i, el) => {
this.data[i].ventas = new Ventas(el.id)
this.data[i].ventas.get()
parent.append(
$('<tr></tr>').append(
$('<td></td>').html(el.factura)
).append(
$('<td></td>').html(el.fecha.formateada)
).append(
$('<td></td>').attr('class', 'ventas').attr('data-id', el.id)
).append(
$('<td></td>').html(el.valor_neto.formateado)
).append(
$('<td></td>').html(el.iva.formateado)
).append(
$('<td></td>').html(el.valor_total.formateado)
).append(
$('<td></td>')
)
)
})
},
add: function() {
const fecha = $("#factura_fecha").calendar('get date')
const data = {
proyecto_id: {{$id_proyecto}},
operador_id: {{$id_operador}},
factura: $("[name='factura']").val(),
fecha: fecha.getFullYear() + '-' + ('00' +(fecha.getMonth() + 1)).slice(-2) + '-' + ('00' + fecha.getDate()).slice(-2),
valor_neto: $("[name='valor_neto']").val(),
iva: $("[name='iva']").val()
}
return $.post('{{$urls->api}}/facturas/add', data).then((data) => {
this.get(data.input.proyecto_id, data.input.operador_id).then((data) => {
this.draw()
})
})
},
asignar: function(form) {
const data = {
factura_id: form.find("[name='factura']").val(),
venta_id: form.find("[name='venta']").val(),
valor: form.find("[name='valor']").val()
}
return $.post('{{$urls->api}}/factura/' + data.factura_id + '/ventas/add', data).then((result) => {
$.each(this.data, (i, el) => {
if (el.id == data.factura_id) {
el.ventas.get()
}
})
})
},
setup: function() {
this.get()
}
}
const modal = function() {
const base = function(before, id, label) {
const div = $('<div></div>').attr('class', 'modal').attr('id', id.substring(1)).attr('tabindex', -1).attr('role', 'dialog').attr('aria-labelledby', label).append(
$('<div></div>').attr('class', 'modal-dialog').append(
$('<div></div>').attr('class', 'modal-content').append(
$('<div></div>').attr('class', 'modal-header').append(
$('<button></button>').attr('type', 'button').attr('class', 'close').attr('data-dismis', 'modal').attr('aria-label', 'Close').append(
$('<span></span>').attr('aria-hidden', 'true').html('&times;')
)
).append(
$('<h4></h4>').attr('class', 'modal-title').html(label)
)
).append(
$('<div></div>').attr('class', 'modal-body').append(
$('<form></form>')
)
)
)
)
before.after(div)
return div
}
return {
agregar: {
id: '#modal_agregar',
button: '#cerrar_agregar',
setup: function() {
$(this.id).find(this.button).click((e) => {
$(this.id).find('form').trigger('submit')
})
$(this.id).find('form').submit((e) => {
e.preventDefault()
facturas.add().then(() => {
$(e.target).trigger('reset')
$(this.id).modal('toggle')
})
return false
})
const today = new Date()
$('#factura_fecha').calendar({
type: 'date',
minDate: new Date(today.getFullYear()-15, today.getMonth(), today.getDate()),
maxDate: new Date(today.getFullYear()+1, today.getMonth(), today.getDate())
})
}
},
add_ventas: {
id: '#modal_add_ventas',
button: '#cerrar_add_ventas',
build: function() {
const modal = base($('#modal_agregar'), this.id, 'Asignar Venta')
const form = modal.find('form')
form.append(
$('<input/>').attr('type', 'hidden').attr('name', 'factura')
).append(
$('<div></div>').attr('class', 'form-group').append(
$('<label></label>').attr('for', 'venta').html('Venta')
).append(
$('<select></select>').attr('name', 'venta').attr('class', 'form-control')
)
).append(
$('<div></div>').attr('class', 'form-group').append(
$('<label></label>').attr('for', 'valor').html('Valor')
).append(
$('<input/>').attr('type', 'text').attr('name', 'valor').attr('class', 'form-control')
)
).append(
$('<button></button>').attr('class', 'btn btn-default').attr('data-dismiss', 'modal').attr('id', 'cerrar_add_ventas').html('Asignar')
)
this.get().ventas().then((data) => {
const parent = $(this.id).find("select[name='venta']")
$.each(data.ventas, (i, el) => {
parent.append(
$('<option></option>').attr('value', el.id).html(el.propiedad.unidades[0].descripcion)
)
})
})
},
get: function() {
return {
ventas: function() {
return $.getJSON('{{$urls->api}}/proyecto/{{$id_proyecto}}/ventas')
}
}
},
setup: function() {
this.build()
$(this.id).find(this.button).click((e) => {
$(this.id).find('form').trigger('submit')
})
$(this.id).on('show.bs.modal', (e) => {
var btn = $(e.relatedTarget)
var id = btn.data('factura')
$(this.id).find('form').find("[name='factura']").attr('value', id)
})
$(this.id).find('form').submit((e) => {
e.preventDefault()
facturas.asignar($(e.target)).then(() => {
$(e.target).trigger('reset')
$(this.id).modal('toggle')
$(this.id).modal('hide')
})
return false
})
}
}
}
}
$(document).ready(() => {
proyecto.setup()
})
</script>
@endpush

View File

@ -8,10 +8,10 @@
@endif @endif
Incoviba S. A.</title> Incoviba S. A.</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.7.8/semantic.min.css" /> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.7.8/semantic.min.css" />
<link rel="stylesheet" type="text/css" href="css/app.css" /> <link rel="stylesheet" type="text/css" href="{{$urls->base}}/css/app.css" />
<link rel="stylesheet" type="text/css" href="css/custom.css" /> <link rel="stylesheet" type="text/css" href="{{$urls->base}}/css/custom.css" />
<link rel="icon" type="image/png" href="images/Isotipo 32.png" /> <link rel="icon" type="image/png" href="{{$urls->base}}/images/Isotipo 32.png" />
<script type="text/javascript" src="js/app.js"></script> <script type="text/javascript" src="{{$urls->base}}/js/app.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.7.8/semantic.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.7.8/semantic.min.js"></script>
@stack('styles') @stack('styles')

View File

@ -3,7 +3,7 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="logo_cabezal"> <div class="logo_cabezal">
<a href="."><img src="images/logo_cabezal.png" /></a> <a href="."><img src="{{$urls->base}}/images/logo_cabezal.png" /></a>
</div> </div>
</div> </div>
</div> </div>
@ -13,4 +13,4 @@
</div> </div>
</div> </div>
</div> </div>
</header> </header>

View File

@ -23,18 +23,26 @@
@include('layout.menu.informes') @include('layout.menu.informes')
</li> </li>
<li rol="presentation" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Operadores <span class="caret"></span>
</a>
@include('layout.menu.operadores')
</li>
<li role="presentation" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Operadores <span class="caret"></span>
</a>
@include('layout.menu.operadores')
</li>
<li role="presentation" class="dropdown"> <li role="presentation" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false"> <a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Herramientas <span class="caret"></span> Herramientas <span class="caret"></span>
</a> </a>
@include('layout.menu.herramientas') @include('layout.menu.herramientas')
</li> </li>
<li rol="presentation" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
Operadores <span class="caret"></span>
</a>
@include('layout.menu.operadores')
</li>
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li role="presentation" class="dropdown"> <li role="presentation" class="dropdown">

View File

@ -6,6 +6,6 @@
<a href="{{$urls->base}}/ventas">Ventas</a> <a href="{{$urls->base}}/ventas">Ventas</a>
</li> </li>
<li> <li>
<a href="{{$urls->base}}/informe">Informe</a> <a href="{{$urls->base}}/facturas">Informe</a>
</li> </li>
</ul> </ul>

View File

@ -83,6 +83,24 @@
<label for="proyecto" class="control-label">Proyecto</label> <label for="proyecto" class="control-label">Proyecto</label>
<select class="form-control" name="proyecto"></select> <select class="form-control" name="proyecto"></select>
</div> </div>
<div class="form-group">
<label for="fecha" class="control-label">Desde</label>
<div class="ui calendar" id="proyecto_fecha">
<div class="ui input left icon">
<i class="calendar icon"></i>
<input type="text" name="fecha" />
</div>
</div>
</div>
<div class="form-group">
<label for="comision" class="control-label">Comisi&oacute;n</label>
<div class="input-group">
<input type="text" name="comision" class="form-control" />
<div class="input-group-addon">
%
</div>
</div>
</div>
<button class="btn btn-default" data-dismiss="modal" id="cerrar_proyecto">Asignar</button> <button class="btn btn-default" data-dismiss="modal" id="cerrar_proyecto">Asignar</button>
</form> </form>
</div> </div>
@ -93,6 +111,57 @@
@push('scripts') @push('scripts')
<script type="text/javascript"> <script type="text/javascript">
const modal = {
general: {
id: '#modal_general',
button: '#cerrar_general',
setup: function() {
$(this.id).find(this.button).click((e) => {
$(this.id).find('form').trigger('submit')
})
$(this.id).find('form').submit((e) => {
e.preventDefault()
operadores.add().operador().then(() => {
$(e.target).trigger('reset')
$(this.id).modal('toggle')
$(this.id).modal('hide')
})
return false
})
}
},
proyecto: {
id: '#modal_proyecto',
button: '#cerrar_proyecto',
setup: function() {
$(this.id).on('show.bs.modal', function(e) {
const btn = $(e.relatedTarget)
const operador = btn.data('operador')
const modal = $(this)
modal.find("[name='operador']").val(operador)
})
$(this.id).find(this.button).click((e) => {
$(this.id).find('form').trigger('submit')
})
$(this.id).find('form').submit((e) => {
e.preventDefault()
operadores.add().proyecto().then(() => {
$(e.target).trigger('reset')
$(this.id).modal('toggle')
$(this.id).modal('toggle')
})
return false
})
const today = new Date()
$('#proyecto_fecha').calendar({
type: 'date',
minDate: new Date(today.getFullYear()-5, today.getMonth(), today.getDate()),
maxDate: new Date(today.getFullYear()+1, today.getMonth(), today.getDate())
})
}
}
}
const operadores = { const operadores = {
id: '#operadores', id: '#operadores',
data: [], data: [],
@ -130,10 +199,10 @@
}) })
} }
} }
}, },
draw: function() { draw: function() {
const parent = $(this.id) const parent = $(this.id)
parent.html('')
$.each(this.data, (i, el) => { $.each(this.data, (i, el) => {
const row = $('<tr></tr>').append( const row = $('<tr></tr>').append(
$('<td></td>').html(el.descripcion) $('<td></td>').html(el.descripcion)
@ -205,47 +274,36 @@
}, },
proyecto: () => { proyecto: () => {
const parent = $('#modal_proyecto').find('form') const parent = $('#modal_proyecto').find('form')
const operador = parent.find("[name='operador']").val()
const fecha = parent.find("#proyecto_fecha").calendar('get date')
const data = { const data = {
operador: parent.find("[name='operador']").val(), comision: parent.find("[name='comision']").val(),
fecha: fecha.getFullYear() + '-' + ('00' +(fecha.getMonth() + 1)).slice(-2) + '-' + ('00' + fecha.getDate()).slice(-2),
proyecto: parent.find("[name='proyecto']").val() proyecto: parent.find("[name='proyecto']").val()
} }
console.debug(data) return $.ajax({
url: '{{$urls->api}}/operador/' + operador + '/proyectos/add',
method: 'post',
data: data,
dataType: 'json'
}).then(() => {
this.get().operadores()
})
} }
} }
},
edit: function() {
},
remove: function() {
}, },
setup: function() { setup: function() {
this.get().operadores() this.get().operadores()
this.get().proyectos() this.get().proyectos()
$('#modal_general').find('#cerrar_general').click((e) => { modal.general.setup()
$('#modal_general').find('form').trigger('submit') modal.proyecto.setup()
})
$('#modal_general').find('form').submit((e) => {
e.preventDefault()
this.add().operador().then(() => {
$(e.target).trigger('reset')
$('#modal_general').modal('toggle')
})
return false
})
$('#modal_proyecto').on('show.bs.modal', function(e) {
const btn = $(e.relatedTarget)
const operador = btn.data('operador')
const modal = $(this)
modal.find("[name='operador']").val(operador)
})
$('#modal_proyecto').find('#cerrar_proyecto').click((e) => {
$('#modal_proyecto').find('form').trigger('submit')
})
$('#modal_proyecto').find('form').submit((e) => {
e.preventDefault()
this.add().proyecto().then(() => {
$(e.target).trigger('reset')
$('#modal_proyecto').modal('toggle')
})
return false
})
} }
} }
$(document).ready(() => { $(document).ready(() => {

View File

@ -0,0 +1,48 @@
@extends('layout.base')
@section('content')
<h1 class="header">
Ventas
</h1>
<table class="table">
<thead>
<tr>
<th>
Proyecto
</th>
<th>
Inmobiliaria
</th>
</tr>
</thead>
<tbody id="proyectos"></tbody>
</table>
@endsection
@push('scripts')
<script type="text/javascript">
$(document).ready(() => {
const base_url = '{{$urls->base}}/ventas/'
$.ajax({
url: '{{$urls->api}}/proyectos',
method: 'get',
dataType: 'json'
}).then((data) => {
const parent = $('#proyectos')
$.each(data.proyectos, function(i, el) {
parent.append(
$('<tr></tr>').append(
$('<td></td>').append(
$('<a></a>').attr('href', base_url + el.id).html(el.descripcion)
)
).append(
$('<td></td>').append(
$('<a></a>').attr('href', base_url + el.id).html(el.inmobiliaria.abreviacion)
)
)
)
})
})
})
</script>
@endpush

View File

@ -0,0 +1,171 @@
@extends('layout.base')
@section('content')
<h1 class="header">
Ventas - <span id="proyecto"></span>
</h1>
<table class="table">
<thead>
<tr>
<th>
Departamento
</th>
<th>
Propietario
</th>
<th class="text-right">
Valor
</th>
<th>
Operador
</th>
<th class="text-right">
Comisi&oacute;n
</th>
<th>
Facturas
</th>
</tr>
</thead>
<tbody id="ventas">
</tbody>
</table>
@endsection
@push('scripts')
<script type="text/javascript">
const proyecto = {
id: '#proyecto',
data: {},
get: function() {
return $.ajax({
url: '{{$urls->api}}/proyecto/{{$proyecto_id}}',
method: 'get',
dataType: 'json'
}).then((data) => {
this.data = data.proyecto
$(this.id).html(data.proyecto.descripcion + ' - ' + data.proyecto.inmobiliaria.abreviacion)
})
},
setup: function() {
this.get().then(() => {
ventas.get().ventas(this.data.id)
})
}
}
class Facturas {
constructor(venta_id) {
this.venta_id = venta_id
this.facturas = []
}
get() {
return $.ajax({
url: '{{$urls->api}}/venta/' + this.venta_id + '/facturas',
method: 'get',
dataType: 'json'
}).then((data) => {
if (data.facturas === null || data.facturas.length == 0) {
return
}
this.facturas = data.facturas
this.draw()
})
}
draw() {
const parent = $('#' + this.venta_id)
let tbody = parent.find('tbody')
if (tbody.length == 0) {
tbody = $('<tbody></tbody>')
const table = $('<table></table>').attr('class', 'table').append(
$('<thead></thead>').append(
$('<tr></tr>').append(
$('<th></th>').html('Factura')
).append(
$('<th></th>').html('Emisor')
).append(
$('<th></th>').html('Fecha')
).append(
$('<th></th>').html('Valor')
)
)
).append(tbody)
parent.append(table)
}
tbody.html('')
$.each(this.facturas, (i, el) => {
tbody.append(
$('<tr></tr>').append(
$('<td></td>').html(el.factura.factura)
).append(
$('<td></td>').html(el.factura.operador.descripcion)
).append(
$('<td></td>').html(el.factura.fecha.formateada)
).append(
$('<td></td>').html(el.valor.formateado)
)
)
})
}
}
const ventas = {
id: '#ventas',
data: [],
get: function() {
return {
ventas: (proyecto) => {
return $.ajax({
url: '{{$urls->api}}/proyecto/' + proyecto + '/ventas',
method: 'get',
dataType: 'json'
}).then((data) => {
this.data = data.ventas
}).then(() => {
this.draw()
})
},
facturas: (venta) => {
return $.ajax({
url: '{{$urls->api}}/venta/' + venta + '/facturas',
method: 'get',
dataType: 'json'
})
}
}
},
draw: function() {
const parent = $(this.id)
$.each(this.data, (i, el) => {
const row = $('<tr></tr>').append(
$('<td></td>').html(el.propiedad.unidades[0].descripcion)
).append(
$('<td></td>').html(el.propietario.nombre_completo)
).append(
$('<td></td>').attr('class', 'text-right').html(el.valor.formateado)
)
if (el.operador) {
row.append(
$('<td></td>').html(el.operador.descripcion)
).append(
$('<td></td>').attr('class', 'text-right').html(el.comision.formateada)
)
} else {
row.append(
$('<td></td>')
).append(
$('<td></td>')
)
}
row.append(
$('<td></td>').attr('id', el.id)
)
this.data[i].facturas = new Facturas(el.id)
this.data[i].facturas.get()
parent.append(row)
})
}
}
$(document).ready(() => {
proyecto.setup()
})
</script>
@endpush

View File

@ -1,5 +1,6 @@
<?php <?php
return [ return [
'debug' => $_ENV['DEBUG'],
'folders' => function() { 'folders' => function() {
$arr = ['base' => dirname(__DIR__, 2)]; $arr = ['base' => dirname(__DIR__, 2)];
$arr['resources'] = implode(DIRECTORY_SEPARATOR, [ $arr['resources'] = implode(DIRECTORY_SEPARATOR, [