Agregando el backend de lumen

This commit is contained in:
2021-04-20 17:06:51 -04:00
parent cf875c8fdc
commit 99dd982041
43 changed files with 8416 additions and 0 deletions

15
backend/.editorconfig Normal file
View File

@@ -0,0 +1,15 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2

19
backend/.env.example Normal file
View File

@@ -0,0 +1,19 @@
APP_NAME='Restaurant API'
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_TIMEZONE=America/Santiago
LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=
DB_CONNECTION=postgresql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=restaurant
DB_USERNAME=user
DB_PASSWORD=password
CACHE_DRIVER=file
QUEUE_CONNECTION=sync

6
backend/.styleci.yml Normal file
View File

@@ -0,0 +1,6 @@
php:
preset: laravel
disabled:
- unused_use
js: true
css: true

14
backend/README.md Normal file
View File

@@ -0,0 +1,14 @@
# Unified Restaurant API
Unified Restaurant es un servicio web que permitirá a sus usuarios operar y
administrar sus restaurantes.
## Documentación
Esta API tendrá los siguientes endpoints
| Funcionalidad | Endpoint |
| --------------- | ----------------- |
| Bodega | `/api/v1/bodega/` |
| Venta | `/api/v1/venta/` |
| Administración | `/api/v1/admin/` |

View File

View File

@@ -0,0 +1,29 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Laravel\Lumen\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
//
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Events;
use Illuminate\Queue\SerializesModels;
abstract class Event
{
use SerializesModels;
}

View File

@@ -0,0 +1,16 @@
<?php
namespace App\Events;
class ExampleEvent extends Event
{
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Exceptions;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Validation\ValidationException;
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Throwable $exception
* @return void
*
* @throws \Exception
*/
public function report(Throwable $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $exception
* @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*
* @throws \Throwable
*/
public function render($request, Throwable $exception)
{
return parent::render($request, $exception);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Laravel\Lumen\Routing\Controller as BaseController;
class Controller extends BaseController
{
//
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers;
class ExampleController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//
}
//
}

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
class Authenticate
{
/**
* The authentication guard factory instance.
*
* @var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* @param \Illuminate\Contracts\Auth\Factory $auth
* @return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ($this->auth->guard($guard)->guest()) {
return response('Unauthorized.', 401);
}
return $next($request);
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Http\Middleware;
use Closure;
class ExampleMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Jobs;
class ExampleJob extends Job
{
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}

24
backend/app/Jobs/Job.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
abstract class Job implements ShouldQueue
{
/*
|--------------------------------------------------------------------------
| Queueable Jobs
|--------------------------------------------------------------------------
|
| This job base class provides a central location to place any logic that
| is shared across all of your jobs. The trait included with the class
| provides access to the "queueOn" and "delay" queue helper methods.
|
*/
use InteractsWithQueue, Queueable, SerializesModels;
}

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Listeners;
use App\Events\ExampleEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class ExampleListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param \App\Events\ExampleEvent $event
* @return void
*/
public function handle(ExampleEvent $event)
{
//
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Lumen\Auth\Authorizable;
class User extends Model implements AuthenticatableContract, AuthorizableContract
{
use Authenticatable, Authorizable, HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email',
];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'password',
];
}

View File

@@ -0,0 +1,18 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Providers;
use App\Models\User;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Boot the authentication services for the application.
*
* @return void
*/
public function boot()
{
// Here you may define how you wish users to be authenticated for your Lumen
// application. The callback which receives the incoming request instance
// should return either a User instance or null. You're free to obtain
// the User instance via an API token or any other method necessary.
$this->app['auth']->viaRequest('api', function ($request) {
if ($request->input('api_token')) {
return User::where('api_token', $request->input('api_token'))->first();
}
});
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Providers;
use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
\App\Events\ExampleEvent::class => [
\App\Listeners\ExampleListener::class,
],
];
}

35
backend/artisan Normal file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env php
<?php
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| First we need to get an application instance. This creates an instance
| of the application / container and bootstraps the application so it
| is ready to receive HTTP / Console requests from the environment.
|
*/
$app = require __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(
'Illuminate\Contracts\Console\Kernel'
);
exit($kernel->handle(new ArgvInput, new ConsoleOutput));

115
backend/bootstrap/app.php Normal file
View File

@@ -0,0 +1,115 @@
<?php
require_once __DIR__.'/../vendor/autoload.php';
(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
dirname(__DIR__)
))->bootstrap();
date_default_timezone_set(env('APP_TIMEZONE', 'UTC'));
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| Here we will load the environment and create the application instance
| that serves as the central piece of this framework. We'll use this
| application as an "IoC" container and router for this framework.
|
*/
$app = new Laravel\Lumen\Application(
dirname(__DIR__)
);
// $app->withFacades();
// $app->withEloquent();
/*
|--------------------------------------------------------------------------
| Register Container Bindings
|--------------------------------------------------------------------------
|
| Now we will register a few bindings in the service container. We will
| register the exception handler and the console kernel. You may add
| your own bindings here if you like or you can make another file.
|
*/
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
/*
|--------------------------------------------------------------------------
| Register Config Files
|--------------------------------------------------------------------------
|
| Now we will register the "app" configuration file. If the file exists in
| your configuration directory it will be loaded; otherwise, we'll load
| the default version. You may register other files below as needed.
|
*/
$app->configure('app');
/*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/
// $app->middleware([
// App\Http\Middleware\ExampleMiddleware::class
// ]);
// $app->routeMiddleware([
// 'auth' => App\Http\Middleware\Authenticate::class,
// ]);
/*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/
// $app->register(App\Providers\AppServiceProvider::class);
// $app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
/*
|--------------------------------------------------------------------------
| Load The Application Routes
|--------------------------------------------------------------------------
|
| Next we will include the routes file so that they can all be added to
| the application. This will provide all of the URLs the application
| can respond to, as well as the controllers that may handle them.
|
*/
$app->router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) {
require __DIR__.'/../routes/web.php';
});
return $app;

40
backend/composer.json Normal file
View File

@@ -0,0 +1,40 @@
{
"name": "laravel/lumen",
"description": "The Laravel Lumen Framework.",
"keywords": ["framework", "laravel", "lumen"],
"license": "MIT",
"type": "project",
"require": {
"php": "^7.3|^8.0",
"laravel/lumen-framework": "^8.0"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
"mockery/mockery": "^1.3.1",
"phpunit/phpunit": "^9.3"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"classmap": [
"tests/"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
]
}
}

7007
backend/composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
<?php
namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = User::class;
/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
];
}
}

View File

View File

@@ -0,0 +1,18 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// $this->call('UsersTableSeeder');
}
}

17
backend/phpunit.xml Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Application Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
</php>
</phpunit>

21
backend/public/.htaccess Normal file
View File

@@ -0,0 +1,21 @@
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

28
backend/public/index.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| First we need to get an application instance. This creates an instance
| of the application / container and bootstraps the application so it
| is ready to receive HTTP / Console requests from the environment.
|
*/
$app = require __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$app->run();

View File

18
backend/routes/web.php Normal file
View File

@@ -0,0 +1,18 @@
<?php
/** @var \Laravel\Lumen\Routing\Router $router */
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/
$router->get('/', function () use ($router) {
return $router->app->version();
});

2
backend/storage/app/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,3 @@
*
!data/
!.gitignore

View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,2 @@
*
!.gitignore

2
backend/storage/logs/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

View File

@@ -0,0 +1,21 @@
<?php
use Laravel\Lumen\Testing\DatabaseMigrations;
use Laravel\Lumen\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testExample()
{
$this->get('/');
$this->assertEquals(
$this->app->version(), $this->response->getContent()
);
}
}

View File

@@ -0,0 +1,16 @@
<?php
use Laravel\Lumen\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
/**
* Creates the application.
*
* @return \Laravel\Lumen\Application
*/
public function createApplication()
{
return require __DIR__.'/../bootstrap/app.php';
}
}

148
database/inserts.sql Normal file
View File

@@ -0,0 +1,148 @@
-----------------------------------
--- Inserts basicos
-----------------------------------
insert into estados_produccion (nombre)
values ('Enviada'),
('Preparada'),
('Vendida'),
('Mermada'),
('Devuelta');
insert into tipos_canal (nombre)
values ('Mesa'),
('Delivery');
-----------------------------------
--- Creando restaurant de prueba
-----------------------------------
insert into restaurantes (nombre)
values ('Todo Rico Restaurant');
insert into categorias (nombre, restaurante_id)
values ('Platos de fondo', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Bebidas', (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into sectores (nombre, restaurante_id)
values ('Salon Principal', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Salon Secundario', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Virtual', (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into canales_venta (nombre, sector_id, tipo_canal_id, restaurante_id)
values ('1', (select id from sectores where nombre = 'Salon Principal'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('2', (select id from sectores where nombre = 'Salon Principal'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('3', (select id from sectores where nombre = 'Salon Principal'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('4', (select id from sectores where nombre = 'Salon Principal'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('5', (select id from sectores where nombre = 'Salon Principal'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('6', (select id from sectores where nombre = 'Salon Secundario'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('7', (select id from sectores where nombre = 'Salon Secundario'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('8', (select id from sectores where nombre = 'Salon Secundario'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('9', (select id from sectores where nombre = 'Salon Secundario'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('10', (select id from sectores where nombre = 'Salon Secundario'), (select id from tipos_canal where nombre = 'Mesa'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Pedidos Ya', (select id from sectores where nombre = 'Virtual'), (select id from tipos_canal where nombre = 'Delivery'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Uber Eats', (select id from sectores where nombre = 'Virtual'), (select id from tipos_canal where nombre = 'Delivery'), (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into zonas_produccion (nombre, restaurante_id)
values ('Cocina', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Barra', (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into usuarios (auth0_id, nombre)
values ('123456', 'Mesero');
insert into usuarios_restaurantes (usuario_id, restaurante_id)
values ((select id from usuarios where nombre = 'Mesero'), (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into productores (usuario_id, zona_produccion_id)
values ((select id from usuarios where nombre = 'Mesero'), (select id from zonas_produccion where nombre = 'Cocina'));
-----------------------------------
--- Inventando ingredientes y productos de venta
-----------------------------------
insert into ingredientes (nombre, medida, restaurante_id)
values ('Papas', 'Kg', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Papas Pre-Fritas', 'Kg', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Sal', 'Kg', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Mantequilla', 'Kg', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Leche', 'L', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Chuletas', 'Kg', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Aceite', 'L', (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Coca-Cola', 'Unidad', (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into productos (nombre, precio_venta, categoria_id, zona_produccion_id, restaurante_id)
values ('Chuleta con Pure', 4390, (select id from categorias where nombre = 'Platos de fondo'),
(select id from zonas_produccion where nombre = 'Cocina'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Chuleta con Papas Fritas', 4690, (select id from categorias where nombre = 'Platos de fondo'),
(select id from zonas_produccion where nombre = 'Cocina'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('Coca-Cola', 1200, (select id from categorias where nombre = 'Bebidas'),
(select id from zonas_produccion where nombre = 'Barra'), (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into recetas (producto_id, ingrediente_id, unidades)
values ((select id from productos where nombre = 'Chuleta con Pure'), (select id from ingredientes where nombre = 'Papas'), 0.25),
((select id from productos where nombre = 'Chuleta con Pure'), (select id from ingredientes where nombre = 'Sal'), 0.002),
((select id from productos where nombre = 'Chuleta con Pure'), (select id from ingredientes where nombre = 'Mantequilla'), 0.03),
((select id from productos where nombre = 'Chuleta con Pure'), (select id from ingredientes where nombre = 'Leche'), 0.2),
((select id from productos where nombre = 'Chuleta con Pure'), (select id from ingredientes where nombre = 'Chuletas'), 0.25);
insert into recetas (producto_id, ingrediente_id, unidades)
values ((select id from productos where nombre = 'Chuleta con Papas Fritas'), (select id from ingredientes where nombre = 'Papas Pre-Fritas'), 0.25),
((select id from productos where nombre = 'Chuleta con Papas Fritas'), (select id from ingredientes where nombre = 'Aceite'), 0.01),
((select id from productos where nombre = 'Chuleta con Papas Fritas'), (select id from ingredientes where nombre = 'Sal'), 0.002),
((select id from productos where nombre = 'Chuleta con Papas Fritas'), (select id from ingredientes where nombre = 'Chuletas'), 0.25);
insert into recetas (producto_id, ingrediente_id, unidades)
values ((select id from productos where nombre = 'Coca-Cola'), (select id from ingredientes where nombre = 'Coca-Cola'), 1);
-----------------------------------
--- Creando compras para crear un inventario
-----------------------------------
insert into proveedores (rut, nombre, descripcion, direccion, telefono, restaurante_id)
values ('123-1', 'Coca-Cola', 'Vende Coca Cola', null, null, (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('123-1', 'Mr. Carnes', 'Vende Carnes', null, null, (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('123-1', 'Santa Isabel', 'Vende Productos Generales', null, null, (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into compras (fecha_compra, proveedor_id, restaurante_id)
values ('2021-01-01'::date, (select id from proveedores where nombre = 'Coca-Cola'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('2021-02-01'::date, (select id from proveedores where nombre = 'Mr. Carnes'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('2021-02-01'::date, (select id from proveedores where nombre = 'Santa Isabel'), (select id from restaurantes where nombre = 'Todo Rico Restaurant')),
('2021-01-01'::date, (select id from proveedores where nombre = 'Coca-Cola'), (select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into compra_ingredientes (unidades, monto_unitario_bruto, iva, ila, monto_unitario_neto, compra_id, ingrediente_id)
values (20, 500, 500 * .19, 0, 500 * 1.19, (select id from compras limit 1 offset 0), (select id from ingredientes where nombre = 'Coca-Cola')),
(50, 1000, 1000 * .19, 0, 1000 * 1.19, (select id from compras limit 1 offset 1), (select id from ingredientes where nombre = 'Chuletas')),
(25, 1000, 1000 * .19, 0, 1000 * 1.19, (select id from compras limit 1 offset 2), (select id from ingredientes where nombre = 'Papas')),
(10, 500, 500 * .19, 0, 500 * 1.19, (select id from compras limit 1 offset 2), (select id from ingredientes where nombre = 'Papas Pre-Fritas')),
(5, 300, 300 * .19, 0, 300 * 1.19, (select id from compras limit 1 offset 2), (select id from ingredientes where nombre = 'Sal')),
(10, 2000, 2000 * .19, 0, 2000 * 1.19, (select id from compras limit 1 offset 2), (select id from ingredientes where nombre = 'Mantequilla')),
(10, 700, 700 * .19, 0, 700 * 1.19, (select id from compras limit 1 offset 2), (select id from ingredientes where nombre = 'Leche')),
(50, 1000, 1000 * .19, 0, 1000 * 1.19, (select id from compras limit 1 offset 2), (select id from ingredientes where nombre = 'Aceite')),
(20, 500, 500 * .19, 0, 500 * 1.19, (select id from compras limit 1 offset 3), (select id from ingredientes where nombre = 'Coca-Cola'));
insert into facturas (numero, monto_bruto, iva, ila, monto_neto, fecha_emision, fecha_vencimiento, compra_id)
values ('1', 500 * 20, 500 * 20 * .19, 0, 500 * 20 * 1.19, '2021-01-01'::date, '2021-01-30'::date, (select id from compras limit 1 offset 0)),
('1', 1000 * 50, 1000 * 50 * .19, 0, 1000 * 50 * 1.19, '2021-02-01'::date, '2021-02-28'::date, (select id from compras limit 1 offset 1)),
('1', 108500, 20615, 0, 129115, '2021-02-10'::date, '2021-02-28'::date, (select id from compras limit 1 offset 2)),
('1', 500 * 20, 500 * 20 * .19, 0, 500 * 20 * 1.19, '2021-01-01'::date, '2021-01-30'::date, (select id from compras limit 1 offset 0));
-----------------------------------
--- Creando ventas para descontar del inventario
-----------------------------------
insert into ventas (tiempo_venta, mesero_id, canal_id, restaurante_id)
values (current_timestamp, (select id from meseros limit 1), (select id from canales_venta where nombre = '1'),
(select id from restaurantes where nombre = 'Todo Rico Restaurant'));
insert into venta_productos (tiempo_entrada, tiempo_salida, venta_id, producto_id, estado_id)
values (current_timestamp, null, (select id from ventas limit 1), (select id from productos where nombre = 'Coca-Cola'),
(select id from estados_produccion where nombre = 'Enviada')),
(current_timestamp, null, (select id from ventas limit 1), (select id from productos where nombre = 'Coca-Cola'),
(select id from estados_produccion where nombre = 'Enviada')),
(current_timestamp, null, (select id from ventas limit 1), (select id from productos where nombre = 'Coca-Cola'),
(select id from estados_produccion where nombre = 'Enviada')),
(current_timestamp, null, (select id from ventas limit 1), (select id from productos where nombre = 'Chuleta con Papas Fritas'),
(select id from estados_produccion where nombre = 'Enviada')),
(current_timestamp, null, (select id from ventas limit 1), (select id from productos where nombre = 'Chuleta con Papas Fritas'),
(select id from estados_produccion where nombre = 'Enviada')),
(current_timestamp, null, (select id from ventas limit 1), (select id from productos where nombre = 'Chuleta con Pure'),
(select id from estados_produccion where nombre = 'Enviada'));

BIN
database/modelo.vpp Normal file

Binary file not shown.

439
database/schema.sql Normal file
View File

@@ -0,0 +1,439 @@
create table restaurantes (
id uuid primary key default gen_random_uuid(),
nombre text not null,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create table categorias (
id uuid primary key default gen_random_uuid(),
nombre text not null,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index categorias_restaurante_id on categorias (restaurante_id);
create table zonas_produccion (
id uuid primary key default gen_random_uuid(),
nombre text not null,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index zonas_produccion_restaurante_id on zonas_produccion (restaurante_id);
create table usuarios (
id uuid primary key default gen_random_uuid(),
auth0_id text not null,
nombre text not null
);
create table usuarios_restaurantes (
usuario_id uuid references usuarios,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp,
primary key (usuario_id, restaurante_id)
);
create table productores (
id uuid primary key default gen_random_uuid(),
usuario_id uuid references usuarios,
zona_produccion_id uuid references zonas_produccion,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index productores_usuario_id on productores (usuario_id);
create index productores_zona_produccion_id on productores (zona_produccion_id);
create table recaudadores (
id uuid primary key default gen_random_uuid(),
usuario_id uuid references usuarios,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index recaudadores_usuario_id on recaudadores (usuario_id);
create table meseros (
id uuid primary key default gen_random_uuid(),
usuario_id uuid references usuarios,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index meseros_usuario_id on meseros (usuario_id);
create table administradores (
id uuid primary key default gen_random_uuid(),
usuario_id uuid references usuarios,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index administradores_usuario_id on administradores (usuario_id);
create table ingredientes (
id uuid primary key default gen_random_uuid(),
nombre text not null,
medida text not null,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index ingredientes_restaurante_id on ingredientes (restaurante_id);
create table productos (
id uuid primary key default gen_random_uuid(),
nombre text not null,
precio_venta bigint not null,
categoria_id uuid references categorias,
zona_produccion_id uuid references zonas_produccion,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index productos_categoria_id on productos (categoria_id);
create index productos_zona_produccion_id on productos (zona_produccion_id);
create index productos_restaurante_id on productos (restaurante_id);
create table recetas (
producto_id uuid references productos,
ingrediente_id uuid references ingredientes,
unidades numeric not null,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp,
primary key (producto_id, ingrediente_id)
);
create table proveedores (
id uuid primary key default gen_random_uuid(),
rut text not null,
nombre text not null,
descripcion text not null,
direccion text null,
telefono text null,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index proveedores_restaurante_id on proveedores (restaurante_id);
create table compras (
id uuid primary key default gen_random_uuid(),
fecha_compra date not null,
proveedor_id uuid references proveedores,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index compras_proveedor_id on compras (proveedor_id);
create index compras_restaurante_id on compras (restaurante_id);
create table facturas (
id uuid primary key default gen_random_uuid(),
numero text not null,
monto_bruto bigint not null,
iva bigint not null default 0,
ila bigint not null default 0,
monto_neto bigint not null,
fecha_emision date not null,
fecha_vencimiento date not null,
compra_id uuid references compras,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index facturas_compra_id on facturas (compra_id);
create table compra_ingredientes (
id uuid primary key default gen_random_uuid(),
unidades numeric not null,
monto_unitario_bruto bigint not null,
iva bigint not null default 0,
ila bigint not null default 0,
monto_unitario_neto bigint not null,
compra_id uuid references compras,
ingrediente_id uuid references ingredientes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index compra_ingredientes_compra_id on compra_ingredientes (compra_id);
create index compra_ingredientes_ingrediente_id on compra_ingredientes (ingrediente_id);
create table sectores (
id uuid primary key default gen_random_uuid(),
nombre text not null,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index sectores_restaurante_id on sectores (restaurante_id);
create table tipos_canal (
id uuid primary key default gen_random_uuid(),
nombre text not null,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create table canales_venta (
id uuid primary key default gen_random_uuid(),
nombre text not null,
sector_id uuid references sectores,
tipo_canal_id uuid references tipos_canal,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index canales_venta_sector_id on canales_venta (sector_id);
create index canales_venta_tipo_canal_id on canales_venta (tipo_canal_id);
create index canales_venta_restaurante_id on canales_venta (restaurante_id);
create table ventas (
id uuid primary key default gen_random_uuid(),
tiempo_venta timestamptz,
mesero_id uuid references meseros,
canal_id uuid references canales_venta,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index ventas_mesero_id on ventas (mesero_id);
create index ventas_canal_id on ventas (canal_id);
create index ventas_restaurante_id on ventas (restaurante_id);
create table boletas_electronicas (
id uuid primary key default gen_random_uuid(),
numero_boleta text not null,
venta_id uuid references ventas,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index boletas_electronicas_venta_id on boletas_electronicas (venta_id);
create index boletas_electronicas_restaurante_id on boletas_electronicas (restaurante_id);
create table boletas_exentas (
id uuid primary key default gen_random_uuid(),
venta_id uuid references ventas,
restaurante_id uuid references restaurantes,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index boletas_exentas_venta_id on boletas_exentas (venta_id);
create index boletas_exentas_restaurante_id on boletas_exentas (restaurante_id);
create table estados_produccion (
id uuid primary key default gen_random_uuid(),
nombre text not null,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create table venta_productos (
id uuid primary key default gen_random_uuid(),
tiempo_entrada timestamptz not null,
tiempo_salida timestamptz null,
venta_id uuid references ventas,
producto_id uuid references productos,
estado_id uuid references estados_produccion,
inserted_at timestamptz not null default current_timestamp,
updated_at timestamptz not null default current_timestamp
);
create index venta_productos_venta_id on venta_productos (venta_id);
create index venta_productos_producto_id on venta_productos (producto_id);
create index venta_productos_estado_id on venta_productos (estado_id);
------------------------------------
--- Triggers para update
------------------------------------
CREATE OR REPLACE FUNCTION trigger_set_timestamp()
RETURNS TRIGGER AS
$$
BEGIN
NEW.updated_at = current_timestamp;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
create trigger trigger_update_restaurantes
before update
on restaurantes
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_categorias
before update
on categorias
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_zonas_produccion
before update
on zonas_produccion
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_usuarios
before update
on usuarios
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_usuarios_restaurantes
before update
on usuarios_restaurantes
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_productores
before update
on productores
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_recaudadores
before update
on recaudadores
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_meseros
before update
on meseros
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_administradores
before update
on administradores
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_ingredientes
before update
on ingredientes
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_productos
before update
on productos
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_recetas
before update
on recetas
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_proveedores
before update
on proveedores
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_compras
before update
on compras
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_facturas
before update
on facturas
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_compra_ingredientes
before update
on compra_ingredientes
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_sectores
before update
on sectores
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_tipos_canal
before update
on tipos_canal
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_canales_venta
before update
on canales_venta
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_ventas
before update
on ventas
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_boletas_electronicas
before update
on boletas_electronicas
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_boletas_exentas
before update
on boletas_exentas
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_estados_produccion
before update
on estados_produccion
for each row
execute procedure trigger_set_timestamp();
create trigger trigger_update_venta_productos
before update
on venta_productos
for each row
execute procedure trigger_set_timestamp();
------------------------------------
--- Views para crear la bodega
------------------------------------
--- View para obtener la lista de egresos de bodega
create view bodega_egresos as
select recetas.ingrediente_id as ingrediente_id,
recetas.unidades as unidades,
date(venta_productos.tiempo_entrada) as fecha,
ventas.restaurante_id as restaurante_id
from ventas
join venta_productos on ventas.id = venta_productos.venta_id
join productos on venta_productos.producto_id = productos.id
join recetas on productos.id = recetas.producto_id;
--- View para obtener la lista de ingresos a bodega
create view bodega_ingresos as
select compra_ingredientes.ingrediente_id as ingrediente_id,
compra_ingredientes.unidades as unidades,
compras.fecha_compra as fecha,
compras.restaurante_id as restaurante_id
from compras
join compra_ingredientes on compras.id = compra_ingredientes.compra_id;
--- View que une el estado de bodega en una sola tabla
create view bodega_movimientos as
select ingrediente_id, unidades * -1 as unidades, fecha, restaurante_id
from bodega_egresos
union all
select ingrediente_id, unidades, fecha, restaurante_id
from bodega_ingresos;
--- View que muestra el estado actual de la bodega por cada ingrediente
create view bodega_actual as
select ingrediente_id as ingrediente_id, sum(unidades) as stock, restaurante_id as restaurante_id
from bodega_movimientos
group by bodega_movimientos.ingrediente_id, bodega_movimientos.restaurante_id;

8
database/selects.sql Normal file
View File

@@ -0,0 +1,8 @@
select *
from bodega_ingresos;
select *
from bodega_egresos;
select *
from bodega_movimientos;
select *
from bodega_actual;