diff --git a/api/common/Controller/Facturas.php b/api/common/Controller/Facturas.php new file mode 100644 index 0000000..605fabc --- /dev/null +++ b/api/common/Controller/Facturas.php @@ -0,0 +1,44 @@ +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); + } +} diff --git a/api/common/Controller/Operadores.php b/api/common/Controller/Operadores.php index c6659b5..c89040f 100644 --- a/api/common/Controller/Operadores.php +++ b/api/common/Controller/Operadores.php @@ -31,7 +31,10 @@ class Operadores { } public function show(Request $request, Response $response, $id_operador): Response { $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); } public function add(Request $request, Response $response): Response { @@ -49,4 +52,10 @@ class Operadores { ]; 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); + } } diff --git a/api/common/Controller/Proyectos.php b/api/common/Controller/Proyectos.php index 937994d..106e840 100644 --- a/api/common/Controller/Proyectos.php +++ b/api/common/Controller/Proyectos.php @@ -20,18 +20,37 @@ class Proyectos { } public function show(Request $request, Response $response, $id_proyecto): Response { $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); } public function ventas(Request $request, Response $response, $id_proyecto): Response { $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 = [ 'proyecto' => $proyecto->as_array(), 'ventas' => array_map(function($item) { if ($item) { 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); + $output = [ + 'proyecto' => $proyecto->as_array(), + 'operadores' => $proyecto->operadores() ? array_map(function($item) { + if ($item) { + return $item->as_array(); + } + }, $proyecto->operadores()) : null ]; return $this->withJson($response, $output); } diff --git a/api/common/Controller/Unidades.php b/api/common/Controller/Unidades.php new file mode 100644 index 0000000..78ee21d --- /dev/null +++ b/api/common/Controller/Unidades.php @@ -0,0 +1,23 @@ +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); + } +} diff --git a/api/composer.json b/api/composer.json index d592361..c700679 100644 --- a/api/composer.json +++ b/api/composer.json @@ -7,7 +7,8 @@ "nyholm/psr7": "^1.4", "nyholm/psr7-server": "^1.0", "zeuxisoo/slim-whoops": "^0.7.3", - "j4mie/paris": "^1.5" + "j4mie/paris": "^1.5", + "nesbot/carbon": "^2.51" }, "require-dev": { "phpunit/phpunit": "^9.5", diff --git a/api/resources/routes/01_facturas.php b/api/resources/routes/01_facturas.php new file mode 100644 index 0000000..ff7e78b --- /dev/null +++ b/api/resources/routes/01_facturas.php @@ -0,0 +1,15 @@ +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->get('[/]', [Facturas::class, 'ventas']); + }); +}); diff --git a/api/resources/routes/02_operadores.php b/api/resources/routes/01_operadores.php similarity index 70% rename from api/resources/routes/02_operadores.php rename to api/resources/routes/01_operadores.php index 6214116..e54ed3b 100644 --- a/api/resources/routes/02_operadores.php +++ b/api/resources/routes/01_operadores.php @@ -9,5 +9,9 @@ $app->group('/operador/{id_operador}', function($app) { $app->group('/ventas', function($app) { $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']); }); diff --git a/api/resources/routes/02_proyectos.php b/api/resources/routes/01_proyectos.php similarity index 76% rename from api/resources/routes/02_proyectos.php rename to api/resources/routes/01_proyectos.php index 298c190..3008470 100644 --- a/api/resources/routes/02_proyectos.php +++ b/api/resources/routes/01_proyectos.php @@ -8,5 +8,8 @@ $app->group('/proyecto/{id_proyecto}', function($app) { $app->group('/ventas', function($app) { $app->get('[/]', [Proyectos::class, 'ventas']); }); + $app->group('/operadores', function($app) { + $app->get('[/]', [Proyectos::class, 'operadores']); + }); $app->get('[/]', [Proyectos::class, 'show']); }); diff --git a/api/resources/routes/01_unidades.php b/api/resources/routes/01_unidades.php new file mode 100644 index 0000000..8863673 --- /dev/null +++ b/api/resources/routes/01_unidades.php @@ -0,0 +1,8 @@ +group('/unidad/{id_unidad}', function($app) { + $app->group('/facturas', function($app) { + $app->get('[/]', [Unidades::class, 'facturas']); + }); +}); diff --git a/api/resources/routes/02_ventas.php b/api/resources/routes/01_ventas.php similarity index 100% rename from api/resources/routes/02_ventas.php rename to api/resources/routes/01_ventas.php diff --git a/api/src/Agente.php b/api/src/Agente.php index b06d918..a173dd0 100644 --- a/api/src/Agente.php +++ b/api/src/Agente.php @@ -13,4 +13,12 @@ class Agente extends Model { } return $this->agente_tipos; } + public function findAgenteTipo(string $tipo) { + foreach ($this->agente_tipos() as $at) { + if ($at->tipo()->descripcion == $tipo) { + return $at; + } + } + return false; + } } diff --git a/api/src/FacturaOperador.php b/api/src/FacturaOperador.php deleted file mode 100644 index 591b590..0000000 --- a/api/src/FacturaOperador.php +++ /dev/null @@ -1,24 +0,0 @@ -operador === null) { - $this->operador = $this->belongs_to(Operador::class, 'operador_id')->find_one(); - } - return $this->operador; - } -} diff --git a/api/src/FacturaProyectoOperador.php b/api/src/FacturaProyectoOperador.php new file mode 100644 index 0000000..5c9d5a7 --- /dev/null +++ b/api/src/FacturaProyectoOperador.php @@ -0,0 +1,113 @@ +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 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; + } +} diff --git a/api/src/FacturaUnidad.php b/api/src/FacturaUnidad.php deleted file mode 100644 index a8cfd17..0000000 --- a/api/src/FacturaUnidad.php +++ /dev/null @@ -1,29 +0,0 @@ -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; - } -} diff --git a/api/src/FacturaVenta.php b/api/src/FacturaVenta.php new file mode 100644 index 0000000..d4e2d14 --- /dev/null +++ b/api/src/FacturaVenta.php @@ -0,0 +1,40 @@ +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 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; + } +} diff --git a/api/src/Operador.php b/api/src/Operador.php index 4d89710..985b2db 100644 --- a/api/src/Operador.php +++ b/api/src/Operador.php @@ -70,11 +70,19 @@ class Operador extends Agente { $output = [ 'input' => $data, 'operador' => $operador->as_array(), - 'new' => $found, + 'new' => !$found, 'created' => $created ]; 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() { $arr = parent::as_array(); diff --git a/api/src/Propiedad.php b/api/src/Propiedad.php index 7c1c1b6..6a6edc6 100644 --- a/api/src/Propiedad.php +++ b/api/src/Propiedad.php @@ -13,4 +13,33 @@ class Propiedad extends Model { } 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; + } } diff --git a/api/src/PropiedadUnidad.php b/api/src/PropiedadUnidad.php index cdfe646..716552d 100644 --- a/api/src/PropiedadUnidad.php +++ b/api/src/PropiedadUnidad.php @@ -13,4 +13,11 @@ class PropiedadUnidad extends Model { } 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; + } } diff --git a/api/src/Propietario.php b/api/src/Propietario.php new file mode 100644 index 0000000..8f46c55 --- /dev/null +++ b/api/src/Propietario.php @@ -0,0 +1,31 @@ +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; + } +} diff --git a/api/src/Proyecto.php b/api/src/Proyecto.php index 24c41e7..dbf7d92 100644 --- a/api/src/Proyecto.php +++ b/api/src/Proyecto.php @@ -41,6 +41,20 @@ class Proyecto extends Model { return $this->proyecto_tipo_unidades; } + protected $operadores; + public function operadores() { + if ($this->operadores === null) { + $pas = $this->has_many(ProyectoAgente::class, 'proyecto')->find_many(); + $operadores = []; + foreach ($pas as $pa) { + $id = $pa->agente_tipo()->agente()->id; + $operadores []= Model::factory(Operador::class)->find_one($id); + } + $this->operadores = $operadores; + } + return $this->operadores; + } + public function as_array() { $arr = parent::as_array(); $arr['inmobiliaria'] = $this->inmobiliaria()->as_array(); diff --git a/api/src/ProyectoAgente.php b/api/src/ProyectoAgente.php index 7c00983..7370d80 100644 --- a/api/src/ProyectoAgente.php +++ b/api/src/ProyectoAgente.php @@ -27,4 +27,25 @@ class ProyectoAgente extends Model { } 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; + } } diff --git a/api/src/ProyectoTipoUnidad.php b/api/src/ProyectoTipoUnidad.php index 019f56d..b12483f 100644 --- a/api/src/ProyectoTipoUnidad.php +++ b/api/src/ProyectoTipoUnidad.php @@ -13,4 +13,12 @@ class ProyectoTipoUnidad extends Model { } 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; + } } diff --git a/api/src/Unidad.php b/api/src/Unidad.php index 45116fd..9a48d78 100644 --- a/api/src/Unidad.php +++ b/api/src/Unidad.php @@ -13,4 +13,18 @@ class Unidad extends Model { } 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; + } + protected $facturas; + public function facturas() { + if ($this->facturas === null) { + $this->facturas = $this->has_many(FacturaUnidad::class, 'unidad_id')->find_many(); + } + return $this->facturas; + } } diff --git a/api/src/Venta.php b/api/src/Venta.php index 6556631..8499022 100644 --- a/api/src/Venta.php +++ b/api/src/Venta.php @@ -43,4 +43,46 @@ class Venta extends Model { } 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; + } + + public function as_array() { + $arr = parent::as_array(); + $arr['propietario'] = $this->propietario()->as_array(); + $arr['propiedad'] = $this->propiedad()->as_array(); + $arr['valor'] = '$ ' . number_format($this->valor_uf, 2, ',', '.'); + if ($this->operador()) { + $arr['operador'] = $this->operador()->as_array(); + $arr['comision'] = (array) $this->comision(); + $arr['comision']['formateada'] = '$ ' . number_format($this->comision()->total, 2, ',', '.'); + } + return $arr; + } }