Merge branch 'refs/heads/master' into funcion/planilla-pedidos-total

# Conflicts:
#	app/GrupoDeCompra.php
This commit is contained in:
Alejandro Tasistro 2024-09-01 13:11:53 -03:00
commit 449579a768
41 changed files with 5413 additions and 7310 deletions

3
.gitignore vendored
View File

@ -12,3 +12,6 @@ npm-debug.log
yarn-error.log
.idea
/resources/csv/exports/*.csv
/public/css/
/public/js/
/public/mix-manifest.json

8
.idea/.gitignore vendored
View File

@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

File diff suppressed because it is too large Load Diff

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="framework" type="frameworkType"/>
<xs:complexType name="commandType">
<xs:all>
<xs:element type="xs:string" name="name" minOccurs="1" maxOccurs="1"/>
<xs:element type="xs:string" name="params" minOccurs="0" maxOccurs="1"/>
<xs:element type="xs:string" name="help" minOccurs="0" maxOccurs="1"/>
<xs:element type="optionsBeforeType" name="optionsBefore" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>
<xs:complexType name="frameworkType">
<xs:sequence>
<xs:element type="xs:string" name="extraData" minOccurs="0" maxOccurs="1"/>
<xs:element type="commandType" name="command" maxOccurs="unbounded" minOccurs="0"/>
<xs:element type="xs:string" name="help" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute type="xs:string" name="name" use="required"/>
<xs:attribute type="xs:string" name="invoke" use="required"/>
<xs:attribute type="xs:string" name="alias" use="required"/>
<xs:attribute type="xs:boolean" name="enabled" use="required"/>
<xs:attribute type="xs:integer" name="version" use="required"/>
<xs:attribute type="xs:string" name="frameworkId" use="optional"/>
</xs:complexType>
<xs:complexType name="optionsBeforeType">
<xs:sequence>
<xs:element type="optionType" name="option" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="optionType">
<xs:sequence>
<xs:element type="xs:string" name="help" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:attribute type="xs:string" name="name" use="required"/>
<xs:attribute type="xs:string" name="shortcut" use="optional"/>
<xs:attribute name="pattern" use="optional">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="space"/>
<xs:enumeration value="equals"/>
<xs:enumeration value="unknown"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pedi2.iml" filepath="$PROJECT_DIR$/.idea/pedi2.iml" />
</modules>
</component>
</project>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php81" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
<excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/flysystem" />
<excludeFolder url="file://$MODULE_DIR$/vendor/opis/closure" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/csv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/mime-type-detection" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/collection" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/voku/portable-ascii" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/flare-client-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fideloper/proxy" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/tinker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/ui" />
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/sanctum" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psy/psysh" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nunomaduro/collision" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
<excludeFolder url="file://$MODULE_DIR$/vendor/league/commonmark" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/fakerphp/faker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-iconv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dragonmantank/cron-expression" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
<excludeFolder url="file://$MODULE_DIR$/vendor/setasign/fpdi" />
<excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
<excludeFolder url="file://$MODULE_DIR$/vendor/mpdf/mpdf" />
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/message-factory" />
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php81" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/asm89/stack-cors" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/brick/math" />
<path value="$PROJECT_DIR$/vendor/swiftmailer/swiftmailer" />
<path value="$PROJECT_DIR$/vendor/league/flysystem" />
<path value="$PROJECT_DIR$/vendor/opis/closure" />
<path value="$PROJECT_DIR$/vendor/league/csv" />
<path value="$PROJECT_DIR$/vendor/league/mime-type-detection" />
<path value="$PROJECT_DIR$/vendor/ramsey/collection" />
<path value="$PROJECT_DIR$/vendor/ramsey/uuid" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/voku/portable-ascii" />
<path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
<path value="$PROJECT_DIR$/vendor/facade/flare-client-php" />
<path value="$PROJECT_DIR$/vendor/facade/ignition" />
<path value="$PROJECT_DIR$/vendor/fideloper/proxy" />
<path value="$PROJECT_DIR$/vendor/laravel/tinker" />
<path value="$PROJECT_DIR$/vendor/laravel/framework" />
<path value="$PROJECT_DIR$/vendor/laravel/ui" />
<path value="$PROJECT_DIR$/vendor/laravel/sanctum" />
<path value="$PROJECT_DIR$/vendor/fruitcake/laravel-cors" />
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
<path value="$PROJECT_DIR$/vendor/psy/psysh" />
<path value="$PROJECT_DIR$/vendor/nunomaduro/collision" />
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
<path value="$PROJECT_DIR$/vendor/league/commonmark" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
<path value="$PROJECT_DIR$/vendor/filp/whoops" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/fakerphp/faker" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/psr/http-client" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-iconv" />
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/vendor/rmccue/requests" />
<path value="$PROJECT_DIR$/vendor/prexview/prexview" />
<path value="$PROJECT_DIR$/vendor/setasign/fpdi" />
<path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
<path value="$PROJECT_DIR$/vendor/mpdf/mpdf" />
<path value="$PROJECT_DIR$/vendor/php-http/message-factory" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.2">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
</project>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -2,21 +2,28 @@
namespace App;
use App\Producto;
use Illuminate\Database\Eloquent\Model;
use Mpdf\Mpdf;
use League\Csv\CannotInsertRecord;
use League\Csv\Writer;
use DB;
use App\Producto;
use Illuminate\Support\Facades\DB;
use League\Csv\Reader;
class GrupoDeCompra extends Model
{
public $timestamps = false;
protected $fillable = [ "nombre","region","telefono","correo","referente_finanzas","cantidad_de_nucleos","fila"];
protected $fillable = [ "nombre","region","telefono","correo","referente_finanzas","cantidad_de_nucleos","fila", "devoluciones_habilitadas"];
protected $table = 'grupos_de_compra';
protected $hidden = ['password'];
public function toggleDevoluciones()
{
$this->devoluciones_habilitadas = !$this->devoluciones_habilitadas;
$this->save();
return $this->devoluciones_habilitadas;
}
public function subpedidos() {
return $this->hasMany('App\Subpedido');
}

View File

@ -74,10 +74,11 @@ class SubpedidoController extends Controller
// recibe request, saca producto y cantidad, valida, y pasa a syncProducto en Subpedido
public function syncProductos(Subpedido $subpedido) {
if ($subpedido->aprobado) return new SubpedidoResource($subpedido);
if ($subpedido->aprobado)
return new SubpedidoResource($subpedido);
$valid = request()->validate([
'cantidad' => 'required|min:0',
'cantidad' => 'required|min:0',
'producto_id' => [
'required',
Rule::in(Producto::all()->pluck('id')),
@ -85,7 +86,6 @@ class SubpedidoController extends Controller
]);
$producto = Producto::find($valid['producto_id']);
$subpedido->syncProducto($producto, $valid['cantidad']);
return new SubpedidoResource($subpedido);
}
@ -98,4 +98,15 @@ class SubpedidoController extends Controller
return new SubpedidoResource($subpedido);
}
public function syncDevoluciones(Subpedido $subpedido) {
if ($subpedido->aprobado) return new SubpedidoResource($subpedido);
$valid = request()->validate([
'total' => 'required|min:0',
'notas' => 'min:0'
]);
$subpedido->syncDevoluciones($valid['total'], $valid['notas'] ?? "");
return new SubpedidoResource($subpedido);
}
}

View File

@ -22,9 +22,12 @@ class SubpedidoResource extends JsonResource
'bonos_de_transporte' => $this->cantidadBDT(),
'subtotal_bonos_de_transporte' => number_format($this->getSubtotalBDT(),0),
'total' => number_format($this->getTotal(),0),
'total_menos_devoluciones' => number_format($this->getTotalMenosDevoluciones(),0),
'grupo_de_compra' => $this->grupoDeCompra,
'productos' => $this->productos,
'aprobado' => (bool) $this->aprobado
'aprobado' => (bool) $this->aprobado,
'devoluciones_total' => (double) $this->devoluciones_total,
'devoluciones_notas' => $this->devoluciones_notas
];
}
}

View File

@ -11,7 +11,7 @@ use App\Filtros\FiltroDeSubpedido;
class Subpedido extends Model
{
public $timestamps = false;
protected $fillable = ['grupo_de_compra_id', 'aprobado', 'nombre'];
protected $fillable = ['grupo_de_compra_id', 'aprobado', 'nombre', 'devoluciones_total', 'devoluciones_notas'];
public function productos()
{
@ -69,6 +69,10 @@ class Subpedido extends Model
return $this->totalSinBonos() + $this->getSubtotalBDT() + $this->getSubtotalBonos();
}
public function getTotalMenosDevoluciones() {
return $this->getTotal() - $this->getDevoluciones();
}
//Actualiza el pedido, agregando o quitando del subpedido según sea necesario. Debe ser llamado desde el controlador de subpedidos, luego de validar que los parámetros $producto y $cantidad son correctos. También calcula el subtotal por producto.
public function syncProducto(Producto $producto, Int $cantidad) {
if ($cantidad){
@ -94,5 +98,17 @@ class Subpedido extends Model
$view = view("pdfgen.subpedido_tabla", ["subpedido" => $this]);
return $view->render();
}
public function getDevoluciones() {
return $this->devoluciones_total;
}
public function getNotasDevoluciones() {
return $this->devoluciones_notas;
}
public function syncDevoluciones(float $total, string $notas) {
$this->devoluciones_total = $total;
$this->devoluciones_notas = $notas;
$this->save();
}
}

1049
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class DevolucionesPedido extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('subpedidos', function (Blueprint $table) {
$table->double('devoluciones_total', 10, 2)->default(0);
$table->string('devoluciones_notas')->default("");
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('subpedidos', function (Blueprint $table) {
$table->dropColumn('devoluciones_total');
$table->dropColumn('devoluciones_notas');
});
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class HabilitarDevoluciones extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('grupos_de_compra', function (Blueprint $table) {
$table->boolean('devoluciones_habilitadas')->default(false);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('grupos_de_compra', function (Blueprint $table) {
$table->dropColumn('devoluciones_habilitadas');
});
}
}

View File

@ -1,50 +0,0 @@
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0be94811453f bc48a6b1eec1 "/bin/sh -c 'apt-get…" 3 days ago Exited (100) 3 days ago festive_poitras
20904ea983a8 bc48a6b1eec1 "/bin/sh -c 'apt-get…" 3 days ago Exited (100) 3 days ago nifty_antonelli
eb71d65b34cc odoo:15 "/entrypoint.sh odoo" 6 weeks ago Up 6 days 0.0.0.0:8069->8069/tcp, 8071-8072/tcp odoo_bar_web_1
6b08d5b023b7 postgres:latest "docker-entrypoint.s…" 6 weeks ago Up 6 weeks 0.0.0.0:32775->5432/tcp odoo_bar_db_1
2be39cf0f208 wordpress:latest "docker-entrypoint.s…" 2 months ago Up 2 months 0.0.0.0:8007->80/tcp wordpress-mps_wordpress_1
1fb3ab9d5196 mariadb:10.3 "docker-entrypoint.s…" 2 months ago Up 2 months 3306/tcp wordpress-mps_db_1
62d94ac320a9 wordpress:cli-php8.0 "docker-entrypoint.s…" 2 months ago Exited (1) 2 months ago wordpress-mps_wpcli_1
dfa0be51db2f mysql:5.7 "docker-entrypoint.s…" 6 months ago Up 4 months 33060/tcp, 0.0.0.0:33060->3306/tcp pedi2-db
d2261994fbbb nginx:alpine "/docker-entrypoint.…" 6 months ago Up 4 months 0.0.0.0:8903->80/tcp pedi2-nginx
8dfd4713c569 laravel-image "docker-php-entrypoi…" 6 months ago Up 4 months 9000/tcp pedi2-app
1717f2e0e075 collabora/code:latest "/start-collabora-on…" 6 months ago Up 4 months 0.0.0.0:9980->9980/tcp collabora
949c45e8e331 nginx:alpine "/docker-entrypoint.…" 11 months ago Up 4 months 0.0.0.0:8902->80/tcp planifibot-nginx
855c759a117d 70bc6d959246 "docker-php-entrypoi…" 11 months ago Up 4 months 9000/tcp planifibot-app
f8591a57bab7 mysql:5.7 "docker-entrypoint.s…" 11 months ago Up 4 months 33060/tcp, 0.0.0.0:3316->3306/tcp planifibot-db
a7de86736ea4 akaunting/akaunting:es "/usr/local/bin/akau…" 12 months ago Exited (0) 8 months ago akaunting
0f4753ad709d mariadb "docker-entrypoint.s…" 12 months ago Exited (0) 8 months ago akaunting-db
7dab3c403e21 127.0.0.1:5000/mps/planifibot:latest "docker-php-entrypoi…" 12 months ago Exited (255) 12 months ago 0.0.0.0:8044->80/tcp planifibot
5880418fe8df 105826cada74 "docker-php-entrypoi…" 12 months ago Exited (255) 12 months ago 0.0.0.0:8044->80/tcp admiring_lumiere
8fd9068db7ed 592f6de18841 "docker-php-entrypoi…" 12 months ago Exited (0) 12 months ago tender_kare
db313e1dc227 72ba750ea9de "/bin/sh -c 'chown -…" 12 months ago Exited (1) 12 months ago pedantic_torvalds
4bd63fb01f80 8e2bc9d43c26 "/bin/sh -c 'chown -…" 12 months ago Exited (1) 12 months ago stoic_goldstine
8181000e76cc 1ed58aad8567 "/bin/sh -c 'docker-…" 12 months ago Exited (1) 12 months ago lucid_lalande
ec7da80bde1a b042c91004f0 "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago keen_mendel
43fd36cd860f b042c91004f0 "/bin/sh -c 'docker-…" 12 months ago Exited (1) 12 months ago jovial_khayyam
02a551fc62b5 b042c91004f0 "/bin/sh -c 'docker-…" 12 months ago Exited (1) 12 months ago heuristic_curie
47f377f81a3e 1b37a536c088 "/bin/sh -c 'apt-get…" 12 months ago Exited (1) 12 months ago laughing_franklin
0f63ee6729d9 1b37a536c088 "/bin/sh -c 'apt-get…" 12 months ago Exited (1) 12 months ago elegant_hoover
8a97c786f1e8 1b37a536c088 "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago distracted_yonath
d4c7f0f8b235 1b37a536c088 "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago vigilant_brown
a6d3cf25487e 80bfd1c2ffed "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago dazzling_williams
50030ac55043 80bfd1c2ffed "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago pedantic_lovelace
0ba2516ca8bd 1e9cc426f6db "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago suspicious_merkle
506eb5744961 1e9cc426f6db "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago stupefied_curie
29a25c955eef 1e9cc426f6db "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago competent_greider
bcbd4a6e70fc 1e9cc426f6db "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago condescending_chaum
0ff1e51bf0c5 1e9cc426f6db "/bin/sh -c 'apt-get…" 12 months ago Exited (100) 12 months ago eager_morse
4b200797fbb8 9ff09bb3bbaf "/bin/sh -c 'apk add…" 12 months ago Exited (127) 12 months ago trusting_euler
4630e65da875 38b8d34febc3 "/bin/sh -c 'docker-…" 12 months ago Exited (2) 12 months ago pensive_khorana
31bc5cbeebda 38b8d34febc3 "/bin/sh -c 'docker-…" 13 months ago Exited (2) 13 months ago elated_chatterjee
dcbaf807509c c2521253d4dc "/bin/sh -c 'docker-…" 13 months ago Exited (2) 13 months ago mystifying_cohen
a8d287e4972e c2521253d4dc "/bin/sh -c 'docker-…" 13 months ago Exited (2) 13 months ago adoring_boyd
57e55bd140e5 919da407c087 "/bin/sh -c 'apt-get…" 13 months ago Exited (100) 13 months ago blissful_turing
16759118d07b 919da407c087 "/bin/sh -c 'apt-get…" 13 months ago Exited (100) 13 months ago modest_edison
686e965026ac 919da407c087 "/bin/sh -c 'apt-get…" 13 months ago Exited (100) 13 months ago upbeat_khorana
e6a4f4e0bc55 919da407c087 "/bin/sh -c 'apt-get…" 13 months ago Exited (100) 13 months ago inspiring_lovelace
d19e81ca0ad2 34258187e19e "/bin/sh -c 'wget -q…" 17 months ago Exited (127) 17 months ago hardcore_lederberg
0d3305ea4c5d fc0cc68061fd "/bin/sh -c 'apt-get…" 17 months ago Exited (2) 17 months ago epic_einstein
1f0cc817b5f9 fc0cc68061fd "/bin/sh -c 'apt-get…" 17 months ago Exited (2) 17 months ago flamboyant_jang
ec330033c36f mariadb:10.3 "docker-entrypoint.s…" 22 months ago Exited (137) 17 months ago akaunting_db_1

7572
package-lock.json generated

File diff suppressed because it is too large Load Diff

5
public/css/app.css vendored

File diff suppressed because one or more lines are too long

2
public/js/app.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,11 +0,0 @@
/*!
* Vue.js v2.6.14
* (c) 2014-2021 Evan You
* Released under the MIT License.
*/
/*!
* bulma-toast 2.4.1
* (c) 2018-present @rfoel <rafaelfr@outlook.com>
* Released under the MIT License.
*/

View File

@ -1,4 +0,0 @@
{
"/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css"
}

63
resources/js/app.js vendored
View File

@ -24,14 +24,14 @@ files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(
* Constants
*/
Vue.prototype.$rootMiga = {
nombre: "Categorías",
nombre: "Categorías",
href: "/productos"
}
/**
* Global methods
*/
Vue.prototype.$settearProducto = function(cantidad, id) {
Event.$emit("sync-subpedido", this.cant, this.producto.id)
Vue.prototype.$settearProducto = function(cantidad, id) {
Event.$emit("sync-subpedido", this.cant, this.producto.id)
}
Vue.prototype.$toast = function(mensaje, duration = 1000) {
return window.bulmaToast.toast({
@ -59,7 +59,8 @@ const app = new Vue({
data() {
return {
gdc: null,
pedido: null
pedido: null,
devoluciones: null,
}
},
computed: {
@ -71,20 +72,34 @@ const app = new Vue({
cantidad(producto) {
let pedido = this.productos.some(p => p.id == producto.id)
return pedido ? this.productos.find(p => p.id == producto.id).pivot.cantidad : 0
}
},
settearDevoluciones() {
axios.get(`/api/grupos-de-compra/${this.gdc}/devoluciones`)
.then(response => {
this.devoluciones = response.data.devoluciones;
});
}
},
mounted() {
Event.$on('obtener-sesion', () => {
axios.get('/subpedidos/obtener_sesion')
.then(response => {
this.pedido = response.data.subpedido.id
axios.get('/api/subpedidos/' + this.pedido)
.then(response => {
this.pedido = response.data.data
this.gdc = this.pedido.grupo_de_compra.id
})
})
})
Event.$on('obtener-sesion', () => {
axios.get('/subpedidos/obtener_sesion')
.then(response => {
if (response.data.subpedido.id) {
this.gdc = response.data.gdc;
this.settearDevoluciones();
this.pedido = response.data.subpedido.id;
axios.get('/api/subpedidos/' + this.pedido)
.then(response => {
this.pedido = response.data.data;
});
} else {
axios.get('/admin/obtener_sesion')
.then(response => {
this.gdc = response.data.gdc
});
}
})
})
Event.$on('sync-subpedido', (cantidad, id) => {
if (this.pedido.aprobado) {
this.$toast('No se puede modificar un pedido ya aprobado', 2000);
@ -98,6 +113,22 @@ const app = new Vue({
this.$toast('Pedido actualizado exitosamente')
});
});
// Actualizar monto y notas de devoluciones
Event.$on('sync-devoluciones', (total, notas) => {
if (this.pedido.aprobado) {
this.$toast('No se puede modificar un pedido ya aprobado', 2000);
return;
}
axios.post("api/subpedidos/" + this.pedido.id + "/sync_devoluciones", {
total: total,
notas: notas,
}).then((response) => {
this.pedido = response.data.data;
this.$toast('Pedido actualizado');
});
});
Event.$on('aprobacion-subpedido', (subpedidoId, aprobado) => {
axios.post("/api/admin/subpedidos/" + subpedidoId + "/aprobacion", {
aprobacion: aprobado

View File

@ -11,13 +11,6 @@
</tr>
</thead>
<tfoot>
<tr>
<th><abbr title="Bonos Solidarios">B. Solidarios</abbr></th>
<th>{{ cantidadBonos }}</th>
<th>{{ totalBonos }}</th>
<th></th>
<th></th>
</tr>
<tr>
<th><abbr title="Bonos de Transporte">B. Transporte</abbr></th>
<th class="has-text-right">{{ cantidadBonosDeTransporte }}</th>
@ -25,10 +18,23 @@
<th></th>
<th></th>
</tr>
<tr v-if="this.$root.devoluciones">
<th><p>Devoluciones</p></th>
<td><p :title="this.$root.pedido.devoluciones_notas">...</p></td>
<th class="has-text-right">-{{ this.$root.pedido.devoluciones_total }}</th>
<th>
<button @click.capture="modificarDevoluciones()" class="button is-warning">
<span class="icon">
<i class="fas fa-edit"></i>
</span>
</button>
</th>
<th></th>
</tr>
<tr>
<th>Total total</th>
<th></th>
<th>{{ total }}</th>
<th class="has-text-right">{{ total }}</th>
<th></th>
<th></th>
</tr>
@ -55,16 +61,15 @@
totalBonosDeTransporte: function() {
return this.$limpiarInt(this.$root.pedido.subtotal_bonos_de_transporte)
},
cantidadBonos: function() {
return this.$limpiarInt(this.$root.pedido.subtotal_bonos) / 20
},
totalBonos: function() {
return this.$limpiarInt(this.$root.pedido.subtotal_bonos)
},
total: function() {
return this.$limpiarInt(this.$root.pedido.total)
return this.$limpiarInt(this.$root.devoluciones ? this.$root.pedido.total_menos_devoluciones : this.$root.pedido.total)
}
},
methods: {
modificarDevoluciones: function() {
Event.$emit("modificar-devoluciones");
},
}
}
</script>
@ -74,4 +79,4 @@
max-width: 80vw;
}
}
</style>
</style>

View File

@ -5,7 +5,7 @@
<span class="icon is-small mr-1">
<img src="/assets/chismosa.png">
</span>
<span v-text="'$' + this.$limpiarInt(this.$root.pedido.total)"></span>
<span v-text="'$' + this.$limpiarInt($root.devoluciones ? $root.pedido.total_menos_devoluciones : $root.pedido.total)"></span>
</a>
</div>
<div class="dropdown-menu chismosa-menu" :id="id" role="menu">
@ -61,4 +61,4 @@ export default {
max-height: 75vh;
}
}
</style>
</style>

View File

@ -0,0 +1,67 @@
<template>
<div v-bind:class="visible ? 'is-active modal' : 'modal'">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Devoluciones</p>
<button class="delete" aria-label="close" @click.capture="cerrar"></button>
</header>
<section class="modal-card-body">
<div class="field has-addons is-centered is-thin-centered">
<p class="control">
Total:
<input id="total" class="input" type="number" v-model="total" style="text-align: center">
</p>
</div>
<div class="field has-addons is-centered is-thin-centered">
<p class="control">
Notas:
<input id="notas" class="input" type="text" v-model.text="notas">
</p>
</div>
</section>
<footer class="modal-card-foot">
<button class="button is-success" @click="modificar">Aceptar</button>
<button class="button" @click.capture="cerrar">Cancelar</button>
</footer>
</div>
</div>
</template>
<script>
export default {
data() {
return {
visible: false,
total: 0,
notas: "",
}
},
computed: {
miga: function() {
return {
nombre: "Devoluciones",
href: "#devoluciones",
}
},
},
methods: {
cerrar() {
this.visible = false;
Event.$emit("migas-pop");
},
modificar() {
Event.$emit('sync-devoluciones', this.total, this.notas);
this.cerrar();
}
},
mounted() {
Event.$on('modificar-devoluciones', () => {
this.visible = true;
this.total = this.$root.pedido.devoluciones_total;
this.notas = this.$root.pedido.devoluciones_notas;
Event.$emit("migas-agregar", this.miga);
});
},
}
</script>

View File

@ -8,7 +8,7 @@
</div>
<div class="control">
<a class="button is-warning" @click="togglePassword">
{{ (passwordVisible ? 'Ocultar' : 'Mostrar') + ' contraseña'}}
{{ (passwordVisible ? 'Ocultar' : 'Mostrar') + ' contraseña'}}
</a>
</div>
</div>

View File

@ -1,8 +1,8 @@
<template>
<div class="container is-max-widescreen is-max-desktop">
<pedidos-admin-tabs-secciones></pedidos-admin-tabs-secciones>
<div class="block" id="pedidos-seccion"
:class="seccionActiva === 'pedidos-seccion' ? 'is-active' : 'is-hidden'">
<div class="block" id="pedidos-seccion"
:class="seccionActiva === 'pedidos-seccion' ? 'is-active' : 'is-hidden'">
<div class="block pb-6" id="pedidos-tabla-y-dropdown" v-show="hayPedidos">
<pedidos-admin-dropdown-descargar
:gdc="gdc">
@ -15,8 +15,8 @@
Todavía no hay ningún pedido para administrar.
</p>
</div>
<div class="block pb-6" id="bonos-seccion"
:class="seccionActiva === 'bonos-seccion' ? 'is-active' : 'is-hidden'">
<div class="block pb-6" id="bonos-seccion"
:class="seccionActiva === 'bonos-seccion' ? 'is-active' : 'is-hidden'">
<pedidos-admin-tabla-bonos v-show="hayAprobados"
:pedidos="pedidos">
</pedidos-admin-tabla-bonos>
@ -24,6 +24,11 @@
Todavía no hay pedidos aprobados.
</p>
</div>
<div class="block pb-6" id="caracteristicas-seccion"
:class="seccionActiva === 'caracteristicas-seccion' ? 'is-active' : 'is-hidden'">
<pedidos-admin-caracteristicas-opcionales>
</pedidos-admin-caracteristicas-opcionales>
</div>
</div>
</template>
@ -32,9 +37,11 @@ import PedidosAdminTabsSecciones from './PedidosAdminTabsSecciones.vue';
import PedidosAdminDropdownDescargar from "./PedidosAdminDropdownDescargar.vue";
import PedidosAdminTablaBonos from './PedidosAdminTablaBonos.vue';
import PedidosAdminTablaPedidos from "./PedidosAdminTablaPedidos.vue";
import PedidosAdminCaracteristicasOpcionales from "./PedidosAdminCaracteristicasOpcionales.vue";
export default {
name: "PedidosAdminBody",
components: {
PedidosAdminCaracteristicasOpcionales,
PedidosAdminTabsSecciones,
PedidosAdminDropdownDescargar,
PedidosAdminTablaPedidos,
@ -47,7 +54,7 @@ export default {
bonosDeTransporte: 0,
totalBonosBarriales: 0,
tabActiva: "pedidos",
seccionActiva: "pedidos-seccion"
seccionActiva: "pedidos-seccion",
}
},
computed: {
@ -69,6 +76,8 @@ export default {
.then(response => {
this.pedidos = response.data.data
}).get;
axios.get("/api/grupos-de-compra/"+this.gdc+"/bonos-barriales", {})
.then(response => this.totalBonosBarriales = response.data.bonos_barriales)
},
setSeccionActiva(tabId) {
this.tabActiva = tabId;

View File

@ -0,0 +1,45 @@
<script>
import axios from "axios";
import PedidosAdminFilaCaracteristica from "./PedidosAdminFilaCaracteristica.vue";
export default {
name: "PedidosAdminCaracteristicasOpcionales",
components: {PedidosAdminFilaCaracteristica},
data() {
return {
caracteristicas: [
{
id: "devoluciones",
nombre: "Devoluciones",
habilitada: false
},
]
}
},
}
</script>
<template>
<div class="block">
<table class="table is-fullwidth is-striped is-bordered">
<thead>
<tr>
<th> Característica </th>
<th> Habilitada </th>
</tr>
</thead>
<tbody>
<pedidos-admin-fila-caracteristica
v-for="(c,i) in caracteristicas"
:key="i"
:caracteristica="c">
</pedidos-admin-fila-caracteristica>
</tbody>
</table>
</div>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,68 @@
<script>
import axios from "axios";
export default {
name: "PedidosAdminFilaCaracteristica",
props: {
caracteristica: Object
},
data: {
gdc: undefined
},
watch: {
'$root.gdc' : {
handler(newValue) {
if (newValue) {
this.gdc = newValue;
this.obtenerValor();
}
}
},
},
methods: {
toggleActivacion() {
const id = this.caracteristica.id;
axios.post(`/api/grupos-de-compra/${this.gdc}/${id}`)
.then(response => {
this.caracteristica.habilitada = response.data[id];
this.$root[id] = response.data[id];
});
},
obtenerValor() {
const id = this.caracteristica.id;
axios.get(`/api/grupos-de-compra/${this.gdc}/${id}`)
.then(response => {
this.caracteristica.habilitada = response.data[id];
this.$root[id] = response.data[id];
});
},
},
mounted() {
if (this.$root.gdc) {
this.gdc = this.$root.gdc;
this.obtenerValor(this);
}
}
}
</script>
<template>
<tr>
<td>{{ caracteristica.nombre }}</td>
<td>
<div class="field">
<input type="checkbox" class="switch is-rounded is-success"
:id="'switch-'+caracteristica.id"
:checked="caracteristica.habilitada"
@change="toggleActivacion(caracteristica)">
<label :for="'switch-'+caracteristica.id">
<span class="is-hidden-mobile">{{ caracteristica.habilitada ? 'Habilitada' : 'Deshabilitada' }}</span>
</label>
</div>
</td>
</tr>
</template>
<style scoped>
</style>

View File

@ -1,7 +1,9 @@
<template>
<tr>
<td>{{ pedido.nombre }}</td>
<td class="has-text-right" >{{ this.$limpiarInt(pedido.total) }}</td>
<td v-if="$root.devoluciones" class="has-text-right" >{{ this.$limpiarInt(pedido.total) }}</td>
<td v-if="$root.devoluciones" class="has-text-right" ><abbr :title="pedido.devoluciones_notas">-{{ pedido.devoluciones_total }}</abbr></td>
<td class="has-text-right" >{{ $root.devoluciones ? pedido.total_menos_devoluciones : pedido.total }}</td>
<td>
<pedidos-admin-switch-aprobacion
:pedido="pedido">

View File

@ -1,8 +1,8 @@
<template>
<div class="field">
<input type="checkbox" name="switchRoundedSuccess" class="switch is-rounded is-success"
:id="'switch'+this.pedido.id"
:checked="pedido.aprobado"
:id="'switch'+this.pedido.id"
:checked="pedido.aprobado"
@change="toggleAprobacion">
<label :for="'switch'+this.pedido.id">
<span class="is-hidden-mobile">{{ mensaje }}</span>
@ -23,7 +23,7 @@ export default {
},
computed: {
mensaje: function () {
return this.aprobado ? "Aprobado" : "No aprobado"
return this.aprobado ? "Pagado" : "No pagado"
}
},
methods: {

View File

@ -1,35 +1,48 @@
<template>
<table class="table is-fullwidth is-striped is-bordered">
<div>
<table class="table is-fullwidth is-striped is-bordered">
<thead>
<tr>
<th>Núcleo</th>
<th><abbr title="Total a Pagar">Total $</abbr></th>
<th class="is-1"><abbr title="Aprobacion">Aprobación</abbr></th>
</tr>
</thead>
<tfoot>
<tr>
<th></th>
<th>Total a recaudar:</th>
<th class="has-text-right">$ {{ totalAprobados() }}</th>
</tr>
<tr>
<th></th>
<th>Total bonos barriales:</th>
<th class="has-text-right">$ {{ totalBonosBarriales }}</th>
</tr>
<tr>
<th></th>
<th>Total a transferir:</th>
<th class="has-text-right">$ {{ totalAprobados() - totalBonosBarriales }}</th>
</tr>
</tfoot>
<tbody>
<pedidos-admin-fila-pedido v-for="pedido in this.pedidos"
:pedido="pedido" :key="pedido.id">
</pedidos-admin-fila-pedido>
</tbody>
<tr>
<th>Núcleo</th>
<th v-if="$root.devoluciones"><abbr title="Total sin tomar en cuenta las devoluciones">Total parcial $</abbr></th>
<th v-if="$root.devoluciones"><abbr title="Devoluciones correspondientes al núcleo">Devoluciones $</abbr></th>
<th><abbr title="Total a Pagar por el núleo">{{ $root.devoluciones ? 'Total real' : 'Total' }} $</abbr></th>
<th class="is-1"><abbr title="Pagado">Pagado</abbr></th>
</tr>
</thead>
<tbody>
<pedidos-admin-fila-pedido
v-for="pedido in this.pedidos"
:pedido="pedido" :key="pedido.id">
</pedidos-admin-fila-pedido>
</tbody>
</table>
<table class="table is-striped is-bordered">
<tr>
<th colspan="2" class="has-background-black has-text-white has-text-centered">TOTALES</th>
</tr>
<tr>
<th>Total a recaudar:</th>
<td class="has-text-right">$ {{ totalARecaudar }}</td>
</tr>
<tr>
<th>Total bonos barriales:</th>
<td class="has-text-right">$ {{ $parent.totalBonosBarriales }}</td>
</tr>
<tr v-if="$root.devoluciones">
<th>Total devoluciones:</th>
<td class="has-text-right">- $ {{ totalDevoluciones() }}</td>
</tr>
<tr>
<th>Total bonos de transporte:</th>
<td class="has-text-right">$ {{ bonosDeTransporte * 15 }}</td>
</tr>
<tr>
<th>Total a depositar:</th>
<td class="has-text-right">$ {{ totalAprobadosConTransporteRecalculado() - totalBonosBarriales }}</td>
</tr>
</table>
</div>
</template>
<script>
@ -53,15 +66,17 @@ export default {
required: true
},
},
computed: {
totalARecaudar: function() {
return this.$root.devoluciones ? this.totalAprobadosMenosDevoluciones() : this.totalAprobados();
},
},
methods: {
totalBonosBarriales() {
let suma = 0;
totalDevoluciones() {
let suma = 0
let aprobados = this.pedidos.filter(p => p.aprobado);
for (let i = 0; i < aprobados.length; i++) {
let bonoBarrial = aprobados[i].productos.find(p => p.nombre.includes("barrial"))
if (bonoBarrial) {
suma += this.$limpiarInt(bonoBarrial.pivot.total)
}
suma += aprobados[i].devoluciones_total
}
return suma;
},
@ -69,8 +84,24 @@ export default {
let suma = 0
let aprobados = this.pedidos.filter(p => p.aprobado);
for (let i = 0; i < aprobados.length; i++) {
suma += this.$limpiarFloat(aprobados[i].subtotal_bonos)
suma += this.$limpiarFloat(aprobados[i].subtotal_productos)
suma += this.$limpiarFloat(aprobados[i].total)
}
return suma;
},
totalAprobadosMenosDevoluciones() {
let suma = 0
let aprobados = this.pedidos.filter(p => p.aprobado);
for (let i = 0; i < aprobados.length; i++) {
suma += this.$limpiarFloat(aprobados[i].total_menos_devoluciones)
}
return suma;
},
totalAprobadosConTransporteRecalculado() {
let suma = 0
let aprobados = this.pedidos.filter(p => p.aprobado);
for (let i = 0; i < aprobados.length; i++) {
suma += this.$limpiarFloat(aprobados[i].total)
suma -= this.$limpiarFloat(aprobados[i].subtotal_bonos_de_transporte)
}
suma += parseInt(this.bonosDeTransporte)*15
return suma;
@ -81,4 +112,4 @@ export default {
<style>
</style>
</style>

View File

@ -3,11 +3,11 @@
<div class="tabs is-boxed" id="tabs">
<ul class="has-bottom-line">
<li v-for="(tab, index) in tabs" class="is-size-6"
:key="index"
:id="tab.id + '-tab'"
:key="index"
:id="tab.id + '-tab'"
:class="{'is-active': tab.id === tabActiva}">
<a @click="setTabActiva(tab.id)">
<span>
<span>
{{ tab.nombre }}
</span>
</a>
@ -31,6 +31,10 @@ export default {
{
id: "bonos",
nombre: "Bonos"
},
{
id: "caracteristicas",
nombre: "Caracteristicas opcionales"
}
]
}
@ -59,4 +63,4 @@ export default {
border-bottom-color: #e3342f;
color: #e3342f;
}
</style>
</style>

View File

@ -0,0 +1,110 @@
<script>
export default {
name: "ProductoCard",
props: {
producto: Object
},
data() {
return {
cantidad: this.producto.cantidad,
enChismosa: this.producto.cantidad,
}
},
mounted() {
Event.$on('sync-subpedido', (cantidad,productoId) => {
if (this.producto.id === productoId)
this.sincronizar(cantidad);
});
},
methods: {
decrementar() {
this.cantidad -= 1;
},
incrementar() {
this.cantidad += 1;
},
confirmar() {
Event.$emit('sync-subpedido', this.cantidad, this.producto.id);
},
borrar() {
this.cantidad = 0;
this.confirmar();
},
sincronizar(cantidad) {
this.cantidad = cantidad;
this.producto.cantidad = cantidad;
this.enChismosa = cantidad;
},
hayCambios() {
return this.cantidad != this.enChismosa;
},
puedeBorrar() {
return this.enChismosa > 0;
},
}
}
</script>
<template>
<div class="block column min-width">
<div class="box" style="height:100%">
<div class="columns">
<div class="column is-three-quarters">
<p class="title is-6">
{{ producto.nombre }}
</p>
<p class="subtitle is-7" v-text="producto.proveedor"></p>
</div>
<div class="column is-one-quarter has-text-right">
<p class="has-text-weight-bold has-text-primary">$<span v-text="producto.precio"></span></p>
<p class="subtitle is-7" v-if="enChismosa !== 0">{{ enChismosa }} en chismosa</p>
</div>
</div>
<footer class="columns">
<div class="column is-three-quarters">
<div class="field has-addons">
<div class="control">
<button class="button is-small" @click.capture="decrementar();">
<i class="fa fa-solid fa-minus"></i>
</button>
</div>
<div class="control">
<input id="cantidad" v-model="cantidad" class="input is-small" type="number" style="text-align: center">
</div>
<div class="control" @click="incrementar();">
<button class="button is-small">
<i class="fa fa-solid fa-plus"></i>
</button>
</div>
<button :disabled="!hayCambios()" class="button is-small is-success ml-3" @click="confirmar()">
<span class="icon">
<i class="fas fa-check"></i>
</span>
</button>
<button :disabled="!puedeBorrar()" class="button is-small is-danger ml-3" @click="borrar()">
<span class="icon">
<i class="fas fa-trash-alt"></i>
</span>
</button>
</div>
</div>
<div class="column is-one-quarter has-text-right">
<p>
<img v-show="producto.economia_solidaria" height="30px" width="30px" src="/assets/solidaria.png" alt="proveedor de economía solidaria">
<img v-show="producto.nacional" height="30px" width="30px" src="/assets/uruguay.png" alt="proveedor nacional"/>
</p>
</div>
</footer>
</div><!-- END BOX -->
</div>
</template>
<style lang="scss" scoped>
@use "bulma/sass/utilities/mixins";
@include mixins.desktop {
.min-width {
min-width: 25rem;
}
}
</style>

View File

@ -1,113 +0,0 @@
<template>
<div v-bind:class="visible ? 'is-active modal' : 'modal'">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title" v-text="producto.nombre"></p>
<button class="delete" aria-label="close" @click.capture="cerrar"></button>
</header>
<section class="modal-card-body">
<div class="card-image">
<figure v-show="producto.nacional" class="image icono is-32x32" style="z-index:10">
<img src="/assets/uruguay.png">
</figure>
<figure v-show="producto.economia_solidaria" class="image icono is-32x32" style="z-index:10">
<img src="/assets/solidaria.png">
</figure>
<figure class="image is-4by3">
<img
v-bind:src="producto.imagen ? producto.imagen : 'https://bulma.io/images/placeholders/1280x960.png'">
</figure>
</div>
<div class="media-content">
<p class="title is-4" v-text="producto.proveedor"></p>
<p class="subtitle is-4">$<span v-text="producto.precio"></span></p>
<p class="subtitle is-6"><span v-show="producto.apto_veganxs">Apto para veganxs. </span><span v-show="producto.apto_celiacxs">Apto para celíacxs.</span></p>
<p class="subtitle is-5"><span v-text="producto.descripcion"></span></p>
<div class="field has-addons is-centered is-thin-centered">
<p class="control">
<button class="button" @click="cantidad !== 0 ? cantidad-- : cantidad">
<span class="icon is-small">
<!-- Habría que ver de poner un ícono de - -->
</span>
<span>-</span>
</button>
</p>
<p class="control">
<input id="cantidad" class="input" type="number" v-model.number="cantidad" style="text-align: center">
</p>
<p class="control">
<button class="button" @click="cantidad++">
<span class="icon is-small">
<!-- Habría que ver de poner un ícono de + -->
</span>
<span>+</span>
</button>
</p>
</div>
</div>
</section>
<footer class="modal-card-foot">
<!-- Habría que ver si cambiar el botón cuando al cantidad es 0 -->
<button class="button is-success" :disabled="cantidad <= 0" @click="agregarProducto">Aceptar</button>
<button class="button" @click.capture="cerrar">Cancelar</button>
</footer>
</div>
</div>
</template>
<script>
export default {
data() {
return {
producto: null,
visible: false,
cantidad: 0
}
},
computed: {
miga: function(){
return {
nombre: this.producto.nombre,
href: "#" + this.producto.nombre
}
}
},
methods: {
cerrar() {
this.cantidad = 0;
this.visible = false;
Event.$emit("migas-pop");
},
agregarProducto() {
if (this.cantidad < 0) alert("No se puede agregar cantidades negativas")
else if (!Number.isInteger(this.cantidad)) alert("Las cantidades deben ser números enteros")
else {
Event.$emit('sync-subpedido',this.cantidad, this.producto.id);
this.cerrar();
}
}
},
mounted() {
Event.$on('producto-seleccionado', (producto) => {
this.producto = producto;
this.cantidad = this.$root.cantidad(producto)
this.visible = true;
Event.$emit("migas-agregar",this.miga);
});
}
}
</script>
<style>
figure.image.icono {
float: right;
margin: 4px;
}
.is-thin-centered {
width: 50%;
margin-left: auto;
margin-right: auto;
}
</style>

View File

@ -8,26 +8,25 @@
<i class="fas fa-edit"></i>
</span>
</button></td>
<td><button @click.capture="eliminarProducto(producto)" class="button is-danger">
<td><button @click.capture="eliminarProducto()" class="button is-danger">
<span class="icon">
<i class="fas fa-trash-alt"></i>
</span>
</button></td>
</tr>
</template>
producto
<script>
export default {
props: {
producto: Object
},
methods: {
seleccionarProducto(producto) {
Event.$emit("producto-seleccionado",producto);
seleccionarProducto() {
Event.$emit("producto-seleccionado",this.producto);
},
eliminarProducto(producto) {
eliminarProducto() {
Event.$emit("sync-subpedido", 0, this.producto.id);
Event.$emit("sync-subpedido");
}
}
}

View File

@ -1,37 +1,17 @@
<template>
<div v-show="visible" class="container">
<div v-show="visible" class="block ml-6 mr-6">
<div class="columns is-multiline is-mobile">
<div v-for="(producto,i) in productos" :key="i" class="block column is-one-quarter-desktop is-one-third-tablet is-half-mobile">
<div @click.capture="seleccionarProducto(producto)" class="card" style="height:100%">
<div class="card-image">
<figure class="image is-4by3">
<img v-bind:src="producto.imagen ? producto.imagen : 'https://bulma.io/images/placeholders/1280x960.png'">
</figure>
<figure v-show="producto.nacional" class="image icono is-32x32">
<img src="/assets/uruguay.png">
</figure>
<figure v-show="producto.economia_solidaria" class="image icono is-32x32">
<img src="/assets/solidaria.png">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<p class="title is-6" v-text="producto.nombre"></p>
<p class="subtitle is-7" v-text="producto.proveedor"></p>
<p class="subtitle is-7">$<span v-text="producto.precio"></span></p>
<p class="subtitle has-text-right is-7" v-if="producto.cantidad != 0"><span v-text="producto.cantidad"></span> en chismosa</p>
</div>
</div>
</div>
</div><!-- END CARD -->
</div><!-- END BLOCK COLUMN -->
<producto-card v-for="(producto,i) in productos" :key="i" :producto="producto">
</producto-card><!-- END BLOCK COLUMN -->
</div><!-- END COLUMNS -->
</div><!-- END CONTAINER -->
</template>
<script>
import ProductoCard from "./ProductoCard.vue";
export default {
components: {ProductoCard},
data() {
return {
productos: [],
@ -64,14 +44,10 @@ export default {
});
},
methods: {
seleccionarProducto(producto) {
Event.$emit("producto-seleccionado",producto);
},
params: function(filtro,valor) {
params(filtro,valor) {
let params = { paginar: this.paginar }
params[filtro] = valor
return params
}
},
}
}
</script>
}</script>

View File

@ -79,7 +79,8 @@
},
guardarSubpedidoEnSesion(subpedido) {
axios.post("/subpedidos/guardar_sesion", {
subpedido: subpedido
subpedido: subpedido,
grupo_de_compra_id: this.gdcid
}).then(_ => {
Event.$emit('obtener-sesion')
window.location.href = 'productos';

View File

@ -5,4 +5,5 @@
<categorias-container></categorias-container>
<productos-container></productos-container>
<producto-modal></producto-modal>
<devoluciones-modal></devoluciones-modal>
@endsection

View File

@ -36,6 +36,14 @@ Route::middleware('api')->group(function () {
$grupo = GrupoDeCompra::where('id',$gdc)->first();
return ['bonos_barriales' => $grupo->totalBonosBarriales()];
});
Route::get('/{gdc}/devoluciones', function($gdc) {
$habilitadas = GrupoDeCompra::find($gdc)->devoluciones_habilitadas;
return ['devoluciones' => $habilitadas];
});
Route::post('/{gdc}/devoluciones', function($gdc) {
$habilitadas = GrupoDeCompra::find($gdc)->toggleDevoluciones();
return ['devoluciones' => $habilitadas];
});
});
Route::prefix('subpedidos')->group(function () {
@ -44,6 +52,7 @@ Route::middleware('api')->group(function () {
Route::get('{subpedido}','Api\SubpedidoController@show');
Route::post('/','Api\SubpedidoController@store');
Route::post('/{subpedido}/sync', 'Api\SubpedidoController@syncProductos');
Route::post('/{subpedido}/sync_devoluciones', 'Api\SubpedidoController@syncDevoluciones');
});
Route::prefix('admin')->group(function () {

View File

@ -54,8 +54,12 @@ Route::middleware('auth')->group( function() {
if (!isset($r["subpedido"])) {
throw new HttpException(400, "La request necesita un subpedido para guardar en sesión");
}
if (!isset($r["grupo_de_compra_id"])) {
throw new HttpException(400, "La request necesita un grupo de compra para guardar en sesión");
}
session(["subpedido_nombre" => $r["subpedido"]["nombre"]]);
session(["subpedido_id" => $r["subpedido"]["id"]]);
session(["gdc" => $r["grupo_de_compra_id"]]);
return "Subpedido guardado en sesión";
})->name('guardarSesion');
@ -64,7 +68,8 @@ Route::middleware('auth')->group( function() {
'subpedido' => [
'nombre' => session("subpedido_nombre"),
'id' => session("subpedido_id")
]
],
'gdc' => session("gdc")
];
return $sesion;
})->name('obtenerSesion');