first commit

This commit is contained in:
2025-03-05 20:43:35 -06:00
commit aa938a3cab
47 changed files with 4388 additions and 0 deletions

View File

@ -0,0 +1,20 @@
@extends('vuexy-admin::layouts.vuexy.layoutMaster')
@section('title', 'Compañia')
@section('vendor-style')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.scss',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/fonts/bootstrap-icons.scss',
])
@endsection
@section('vendor-script')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.js',
])
@endsection
@section('content')
@livewire('company-index')
@endsection

View File

@ -0,0 +1,775 @@
<div>
<form action="" wire:submit.prevent="onSubmit">
<div class="row">
<div class="col-12 mb-6">
<button type="submit" class="btn btn-submit btn-{{ $mode == 'delete' ? 'danger' : 'primary' }} waves-effect waves mr-3 mb-3">{{ $btnSubmitText }}</button>
<a href="{{ route('admin.store-manager.stores.index') }}" class="btn btn-label-secondary waves-effect waves mr-3 mb-3">Cancelar</a>
</div>
</div>
<div class="row">
<div class="col-lg-4">
<div class="card mb-6">
<div class="card-header">
<h5 class="card-title mb-0">Identificación</h5>
</div>
<div class="card-body">
<div class="row">
<div class="mb-4 col-6 fv-row">
<label class="form-label" for="code">Identificador único</label>
<input type="text" name="code" id="code" wire:model='code' class="form-control" placeholder="UID code" />
@error('code')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="name">Nombre</label>
<input type="text" name="name" id="name" wire:model="name" class="form-control" placeholder="Nombre de la sucursal" />
@error('name')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="description">Descripción</label>
<textarea id="description" name="description" wire:model='description' class="form-control" placeholder="Descripción de la sucursal" aria-label="Descripción de almacén" /></textarea>
@error('description')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
</div>
</div>
@if(false)
<div class="card mb-6">
<div class="card-header">
<h5 class="card-title mb-0">Series de facturación</h5>
</div>
<div class="card-body">
<div class="row">
<div class="mb-4 fv-row">
<label class="form-label" for="serie_ingresos">Serie para Ingresos</label>
<input type="text" name="serie_ingresos" id="serie_ingresos" wire:model="serie_ingresos" class="form-control" placeholder="Serie para Ingresos" />
@error('serie_ingresos')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="serie_egresos">Serie para Egresos</label>
<input type="text" name="serie_egresos" id="serie_egresos" wire:model="serie_egresos" class="form-control" placeholder="Serie para Egresos" />
@error('serie_egresos')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="serie_pagos">Serie para Pagos</label>
<input type="text" name="serie_pagos" id="serie_pagos" wire:model="serie_pagos" class="form-control" placeholder="Serie para Pagos" />
@error('serie_pagos')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
</div>
</div>
</div>
@endIf
<div class="card mb-6">
<div class="card-header">
<h5 class="card-title mb-0">Configuraciones</h5>
</div>
<div class="card-body">
<div class="mb-4 fv-row">
<x-vuexy-admin::form.checkbox
wire:model='status'
parent_class='form-switch'>
Habilitar sucursal
</x-vuexy-admin::form.checkbox>
</div>
<div class="mb-4 fv-row">
<x-vuexy-admin::form.checkbox
wire:model='show_on_website'
parent_class='form-switch'>
Mostrar en sitio web
</x-vuexy-admin::form.checkbox>
</div>
<div class="mb-4 fv-row">
<x-vuexy-admin::form.checkbox
wire:model='enable_ecommerce'
parent_class='form-switch'>
Habilitar eCommerce
</x-vuexy-admin::form.checkbox>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card mb-6">
<div class="card-header">
<h5 class="card-title mb-0">Información de contacto</h5>
</div>
<div class="card-body">
<div class="mb-4 fv-row">
<label class="form-label" for="tel">Teléfono</label>
<input type="tel" name="tel" id="tel" wire:model="tel" class="form-control" placeholder="Teléfono" />
@error('tel')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="tel2">Teléfono secundario</label>
<input type="tel" name="tel2" id="tel2" wire:model="tel2" class="form-control" placeholder="Teléfono secundario" />
@error('tel2')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="email">Correo electrónico</label>
<input type="email" name="email" id="email" wire:model="email" class="form-control" placeholder="Correo electrónico" />
@error('email')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<hr>
<div class="mb-4 fv-row">
<label for="manager_id" class="form-label">Gerente</label>
<x-vuexy-admin::form.select
wire:model='manager_id'
:options="$manager_id_options"
:selected="$manager_id"
placeholder="Selecciona el gerente"
class="select2 form-select" />
</div>
</div>
</div>
<div class="card mb-6">
<div class="card-header">
<h5 class="card-title mb-0">Información fiscal</h5>
</div>
<div class="card-body">
<div class="mb-4 fv-row">
<label class="form-label" for="rfc">RFC</label>
<input type="text" name="rfc" id="rfc" wire:model="rfc" class="form-control" placeholder="Registro Federal de Contribuyentes" />
@error('rfc')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="nombre_fiscal">Nombre fiscal</label>
<input type="text" name="nombre_fiscal" id="nombre_fiscal" wire:model="nombre_fiscal" class="form-control" placeholder="Nombre fiscal" />
@error('nombre_fiscal')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="mb-4 fv-row">
<label for="c_regimen_fiscal" class="form-label">Régimen fiscal</label>
<x-vuexy-admin::form.select
wire:model='c_regimen_fiscal'
:options="$c_regimen_fiscal_options"
:selected="$c_regimen_fiscal"
placeholder="Selecciona el regimen fiscal"
class="select2 form-select" />
</div>
<div class="mb-4 fv-row">
<label class="form-label" for="domicilio_fiscal">Domicilio fiscal</label>
<input type="text" name="domicilio_fiscal" id="domicilio_fiscal" wire:model="domicilio_fiscal" class="form-control" maxlength=5, placeholder="Domicilio fiscal (C.P)" />
@error('domicilio_fiscal')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card mb-6">
<div class="card-header">
<h5 class="card-title mb-0">Dirección</h5>
</div>
<div class="card-body">
@php
/*
dump($c_codigo_postal);
dump($c_estado);
dump($c_localidad);
dump($c_municipio);
dump($c_colonia);
dump($c_localidad_options);
dump($c_municipio_options);
dump($c_colonia_options);
*/
@endphp
<div class="row">
<div class="col-8 mb-4 fv-row">
<label for="c_pais" class="form-label">Pais</label>
<x-vuexy-admin::form.select
wire:model='c_pais'
:options="$c_pais_options"
:selected="$c_pais"
placeholder="Selecciona el pais"
class="select2 form-select" />
</div>
<div class="col-4 mb-4 fv-row if_local_address_show">
<label for="c_codigo_postal" class="form-label">Código postal</label>
<input type="text" name="c_codigo_postal" id="c_codigo_postal" wire:model="c_codigo_postal" class="form-control text-center" maxlength=5, placeholder="Código Postal" />
@error('c_codigo_postal')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
</div>
<div class="mb-4 fv-row">
<label for="c_estado" class="form-label">Estado</label>
<x-vuexy-admin::form.select
wire:model='c_estado'
:options="$c_estado_options"
:selected="$c_estado"
placeholder="Selecciona el estado"
class="select2 form-select" />
</div>
<div class="mb-4 fv-row if_local_address_show">
<label for="c_localidad" class="form-label">Localidad</label>
<x-vuexy-admin::form.select
wire:model='c_localidad'
:options="$c_localidad_options"
:selected="$c_localidad"
class="select2 form-select" />
</div>
<div class="mb-4 fv-row if_local_address_show">
<label for="c_municipio" class="form-label">Municipio</label>
<x-vuexy-admin::form.select
wire:model='c_municipio'
:options="$c_municipio_options"
:selected="$c_municipio"
class="select2 form-select" />
</div>
<div class="mb-4 fv-row if_local_address_show">
<label for="c_colonia" class="form-label">Colonia</label>
<x-vuexy-admin::form.select
wire:model='c_colonia'
:options="$c_colonia_options"
:selected="$c_colonia"
class="select2 form-select" />
</div>
<div class="mb-4 fv-row">
<label for="direccion" class="form-label">Dirección</label>
<input type="text" name="direccion" id="direccion" wire:model="direccion" class="form-control" placeholder="Dirección" />
@error('direccion')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="row">
<div class="col-6 mb-4 fv-row">
<label for="num_ext" class="form-label">Número exterior</label>
<input type="text" name="num_ext" id="num_ext" wire:model="num_ext" class="form-control" placeholder="Núm. exterior" />
@error('num_ext')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="col-6 mb-4 fv-row">
<label for="num_int" class="form-label">Número interior</label>
<input type="text" name="num_int" id="num_int" wire:model="num_int" class="form-control" placeholder="Núm. interior" />
@error('num_int')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
</div>
</div>
</div>
<div class="card mb-6">
<div class="card-header">
<h5 class="card-title mb-0">Ubicación</h5>
</div>
<div class="card-body">
<div class="input-group input-group-merge form-send-message">
<textarea class="form-control message-input" placeholder="Dirección de búsqueda" rows="2"></textarea>
<button type="button" class="message-actions input-group-text">
<i class="ti ti-map-pin-search"></i>
</button>
</div>
<div class="row">
<div class="col-6 mb-4 fv-row">
<label for="lat" class="form-label">Latitud</label>
<input type="number" step="0.000001" name="lat" id="lat" wire:model="lat" class="form-control text-center" placeholder="Latitud" />
@error('lat')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
<div class="col-6 mb-4 fv-row">
<label for="lng" class="form-label">Longitud</label>
<input type="number" step="0.000001" name="lng" id="lng" wire:model="lng" class="form-control text-center" placeholder="Longitud" />
@error('lng')
<span class="text-danger">{{ $message }}</span>
@enderror
</div>
</div>
<div style="height: 400px; z-index: 1;" id="geo_map"></div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 mb-6">
<button type="submit" class="btn btn-submit btn-{{ $mode == 'delete' ? 'danger' : 'primary' }} waves-effect waves mr-3 mb-3">{{ $btnSubmitText }}</button>
<a href="{{ route('admin.store-manager.stores.index') }}" class="btn btn-label-secondary waves-effect waves mr-3 mb-3">Cancelar</a>
</div>
</div>
</form>
</section>
@push('page-script')
<script>
const csrf_token = "{{ csrf_token() }}",
geo_coordinates = [{{ isset($sucursal) && $sucursal->lat && $sucursal->lng? ($sucursal->lat . ', ' . $sucursal->lng): (Koneko\VuexyStoreManager\Models\Store::LATITUDE_DEFAULT . ', ' . Koneko\VuexyStoreManager\Models\Store::LONGITUDE_DEFAULT) }}],
marker_coordinates = [{{ isset($sucursal) && $sucursal->lat && $sucursal->lng? ($sucursal->lat . ', ' . $sucursal->lng): 'false' }}];
let update_codigo_postal = true;
document.addEventListener("DOMContentLoaded", function () {
let $manager_id = $("#manager_id"),
$c_regimen_fiscal = $("#c_regimen_fiscal"),
$c_pais = $("#c_pais"),
$c_localidad = $("#c_localidad"),
$c_codigo_postal = $("#c_codigo_postal"),
$c_estado = $("#c_estado"),
$c_municipio = $("#c_municipio"),
$c_colonia = $("#c_colonia"),
$direccion = $("#direccion");
$manager_id
.select2({
language: "es",
placeholder: "Selecciona el gerente",
allowClear: true,
width: "100%"
})
.on('select2:select', function (e) {
@this.manager_id = e.params.data.id;
})
.on("select2:select select2:clear", function (e) {
@this.manager_id = null;
});
$c_regimen_fiscal
.select2({
language: "es",
placeholder: "Selecciona el gerente",
allowClear: true,
width: "100%"
})
.on('select2:select', function (e) {
@this.c_regimen_fiscal = e.params.data.id;
})
.on("select2:select select2:clear", function (e) {
@this.c_regimen_fiscal = null;
});
$c_codigo_postal
.on('keyup change', function(){
$c_estado.val('').trigger('change.select2');
$c_localidad.empty().prop('disabled', true).trigger('change.select2');
$c_municipio.empty().prop('disabled', true).trigger('change.select2');
$c_colonia.empty().prop('disabled', true).trigger('change.select2');
@this.c_estado = null;
@this.c_localidad = null;
@this.c_municipio = null;
@this.c_colonia = null;
let codigo_postal = $(this).val();
if(codigo_postal.length == 5){
$.ajax({
url: "{{ route('admin.core.sat.get.ajax', 'codigo_postal') }}",
type: 'post',
data: {
_token: csrf_token,
searchTerm: codigo_postal,
firstRow: true,
rawMode: true,
},
success: function(result){
$c_localidad.append(new Option('Selecciona la localidad', '', true, false));
$c_municipio.append(new Option('Selecciona el municipio', '', true, false));
$c_colonia.append(new Option('Selecciona la colonia', '', true, false));
if(result.c_codigo_postal){
$c_estado
.val(result.c_estado)
.prop('disabled', false)
.trigger('change.select2');
@this.c_estado = result.c_estado;
$.ajax({
url: "{{ route('admin.core.sat.get.ajax', 'localidad') }}",
type: "post",
data: {
_token: "{{ csrf_token() }}",
c_estado: result.c_estado,
limit: null
},
success: function (result) {
$.each(result, function (c_localidad, localidad) {
$c_localidad.append(new Option(localidad, c_localidad, false, false));
});
$c_localidad.prop('disabled', false).trigger('change.select2');
},
error: function() {
console.error('Error al cargar los localidades.');
}
});
$c_municipio
.append(new Option(result.municipio, result.c_municipio, false, true))
.prop('disabled', false)
.trigger('change.select2');
@this.c_municipio = result.c_municipio;
$c_colonia.prop('disabled', false).trigger('change.select2');
setTimeout(() => {
$c_colonia.select2('open');
}, 0)
}
}
});
}
});
$c_pais
.select2({
language: "es",
placeholder: "Selecciona el país",
allowClear: true,
width: "100%"
})
.on('select2:open', () => {
document.querySelector('.select2-search__field').focus();
})
.on("select2:select select2:clear", function (e) {
$('.if_local_address_show').hide();
$c_codigo_postal.val('');
$c_estado.empty().prop('disabled', true).trigger('change.select2');
$c_localidad.empty().prop('disabled', true).trigger('change.select2');
$c_municipio.empty().prop('disabled', true).trigger('change.select2');
$c_colonia.empty().prop('disabled', true).trigger('change.select2');
@this.c_pais = null;
@this.c_estado = null;
@this.c_localidad = null;
@this.c_municipio = null;
@this.c_colonia = null;
})
.on('select2:select', function (e) {
// Si NO es México, mostramos las .if_local_address_show y limpiamos c_estado
$c_pais.val() !== 'MEX'
? $('.if_local_address_show').hide()
: $('.if_local_address_show').show();
$c_codigo_postal.val('');
$c_estado.empty().prop('disabled', true).trigger('change.select2');
$c_localidad.empty().prop('disabled', true).trigger('change.select2');
$c_municipio.empty().prop('disabled', true).trigger('change.select2');
$c_colonia.empty().prop('disabled', true).trigger('change.select2');
@this.c_pais = e.params.data.id;
@this.c_estado = null;
@this.c_localidad = null;
@this.c_municipio = null;
@this.c_colonia = null;
$.ajax({
url: "{{ route('admin.core.sat.get.ajax', 'estado') }}",
type: "post",
data: {
_token: "{{ csrf_token() }}",
c_pais: $c_pais.val(),
limit: null
},
success: function (result) {
// Cargar estados en el select c_estado
$c_estado.append(new Option('Selecciona el estado', '', true, true));
$.each(result, function (clave, nombre) {
$c_estado.append(new Option(nombre, clave, false, false));
});
$c_estado.prop('disabled', false).trigger('change.select2');
if($c_estado.find('option').length > 1){
setTimeout(() => {
$c_estado.select2('open');
}, 0)
}
},
error: function() {
console.error('Error al cargar los estados.');
}
});
});
$c_estado
.select2({
language: "es",
placeholder: "Selecciona el estado",
allowClear: true,
width: "100%"
})
.on('select2:open', () => {
document.querySelector('.select2-search__field').focus();
})
.on('select2:select select2:clear', function (e) {
$c_codigo_postal.val('');
$c_localidad.empty().prop('disabled', true).trigger('change.select2');
$c_municipio.empty().prop('disabled', true).trigger('change.select2');
$c_colonia.empty().prop('disabled', true).trigger('change.select2');
@this.c_estado = null;
@this.c_localidad = null;
@this.c_municipio = null;
@this.c_colonia = null;
})
.on('select2:select', function (e) {
$c_codigo_postal.val('');
$c_localidad.empty().prop('disabled', true).trigger('change.select2');
$c_municipio.empty().prop('disabled', true).trigger('change.select2');
$c_colonia.empty().prop('disabled', true).trigger('change.select2');
@this.c_estado = e.params.data.id;
if($c_pais.val() === 'MEX'){
$.ajax({
url: "{{ route('admin.core.sat.get.ajax', 'localidad') }}",
type: "post",
data: {
_token: "{{ csrf_token() }}",
c_estado: $c_estado.val(),
limit: null
},
success: function (result) {
// Cargar localidades en el select c_localidad
$c_localidad.append(new Option('Selecciona la localidad', '', true, true));
$.each(result, function (clave, nombre) {
$c_localidad.append(new Option(nombre, clave, false, false));
});
$c_municipio.prop('disabled', false).trigger('change.select2');
$c_localidad.prop('disabled', false).trigger('change.select2');
setTimeout(() => {
$c_localidad.select2('open');
}, 0)
},
error: function() {
console.error('Error al cargar los localidades.');
}
});
}else{
$direccion.focus();
}
});
$c_localidad
.select2({
language: "es",
placeholder: "Selecciona el estado",
allowClear: true,
width: "100%"
})
.on('select2:open', () => {
document.querySelector('.select2-search__field').focus();
})
.on('select2:select', function (e) {
@this.c_localidad = e.params.data.id;
if(!($c_municipio.val())){
$c_municipio.select2('open');
}
});
$c_municipio
.select2({
ajax: {
url: "{{ route('admin.core.sat.get.ajax', 'municipio') }}",
type: "post",
delay: 250,
dataType: 'json',
data: function(params) {
return {
_token: csrf_token,
select2Mode: true,
searchTerm: params.term,
c_estado: $c_estado.val(),
};
},
processResults: function(response) {
return {
results: response
};
},
cache: true
},
language: "es",
placeholder: "Buscar municipio",
minimumInputLength: 3,
allowClear: true,
width: "100%",
})
.on('select2:open', () => {
document.querySelector('.select2-search__field').focus();
})
.on('select2:select select2:clear', function (e) {
$c_codigo_postal.val('');
$c_colonia.empty().prop('disabled', true).trigger('change.select2');
@this.c_municipio = null;
@this.c_colonia = null;
})
.on('select2:select', function (e) {
$c_codigo_postal.val('');
$c_colonia.empty().prop('disabled', true).trigger('change.select2');
@this.c_municipio = e.params.data.id;
@this.c_colonia = null;
$.ajax({
url: "{{ route('admin.core.sat.get.ajax', 'colonia') }}",
type: 'post',
data: {
_token: csrf_token,
c_estado: $c_estado.val(),
c_municipio: $c_municipio.val(),
limit: null
},
success: function(result){
for (const [c_colonia, colonia] of Object.entries(result)) {
$c_colonia.append(new Option(colonia, c_colonia, false, false))
}
$c_colonia.prop('disabled', false).trigger('change.select2');
setTimeout(() => {
$c_colonia.select2('open');
}, 0)
}
});
});
$c_colonia
.select2({
ajax: {
url: "{{ route('admin.core.sat.get.ajax', 'colonia') }}",
type: "post",
delay: 250,
dataType: 'json',
data: function(params) {
return {
_token: csrf_token,
select2Mode: true,
searchTerm: params.term,
c_codigo_postal: $c_codigo_postal.val(),
c_estado: $c_estado.val(),
c_municipio: $c_municipio.val(),
};
},
processResults: function(response) {
return {
results: response
};
},
cache: true
},
language: "es",
placeholder: "Buscar colonia",
allowClear: true,
width: "100%",
})
.on('select2:open', () => {
update_codigo_postal = true;
document.querySelector('.select2-search__field').focus();
})
.on('select2:clear', function (e) {
update_codigo_postal = false;
$c_codigo_postal.val('');
@this.c_colonia = null;
})
.on('select2:select', function (e) {
if(update_codigo_postal || !($c_codigo_postal.val())){
@this.c_colonia = e.params.data.id;
$.ajax({
url: "{{ route('admin.core.sat.get.ajax', 'colonia') }}",
type: 'post',
data: {
_token: csrf_token,
c_estado: $c_estado.val(),
c_municipio: $c_municipio.val(),
c_colonia: $c_colonia.val(),
firstRow: true,
rawMode: true,
},
success: function(result){
if($c_codigo_postal.val() !== result.c_codigo_postal){
$c_codigo_postal.val(result.c_codigo_postal);
@this.c_codigo_postal = result.c_codigo_postal;
}
$direccion.focus();
}
});
}
update_codigo_postal = true;
});
// Opcionalmente, ocultamos la dirección extranjera al cargar la página,
// si el valor inicial de #c_pais es "MEX"
$(function(){
if ($c_pais.val() === 'MEX') {
$('.if_local_address_show').show();
} else {
$('.if_local_address_show').hide();
}
});
$(document).ready(function(){
var draggableMap = L.map('geo_map').setView(geo_coordinates, 12);
if(marker_coordinates[0]){
var markerLocation = L.marker(marker_coordinates, {
draggable: 'true'
}).addTo(draggableMap);
markerLocation.bindPopup("<b>Aquí es la ubicación</b>").openPopup();
}
L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a>',
maxZoom: 18
}).addTo(draggableMap);
})
});
</script>
@endpush

View File

@ -0,0 +1,170 @@
<div>
<x-vuexy-admin::form id="{{ $formId }}" :mode="$mode" wireSubmit="onSubmit" actionPosition="both">
<x-slot name="actions">
<button type="submit" class="btn btn-submit btn-{{ $mode == 'delete' ? 'danger' : 'primary' }} waves-effect waves mr-3 mb-3">{{ $btnSubmitText }}</button>
<a href="{{ route('admin.store-manager.stores.index') }}" class="btn {{ $mode == 'delete' ? 'btn-text-secondary waves-effect waves-light' : 'btn btn-label-secondary waves-effect' }} mr-3 mb-3">Cancelar</a>
@if($mode == 'delete')
<x-vuexy-admin::form.checkbox model="confirmDeletion" label="Confirmar eliminación" class="data-always-enabled" switch=true switchType="square" color="danger" size="lg" withIcon=true />
@endif
</x-slot>
<div class="row">
<div class="col-lg-4">
{{-- Identificación --}}
<x-vuexy-admin::card.basic title="Identificación">
<x-vuexy-admin::form.input :uid="$uniqueId" model="code" label="Identificador único" icon="ti ti-tag" placeholder="UID code" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="name" label="Nombre de la sucursal" />
<x-vuexy-admin::form.textarea :uid="$uniqueId" model="description" label="Descripción" placeholder="Descripción de la sucursal" :autosize=true />
</x-vuexy-admin::card.basic>
{{-- Series de facturación --}}
<x-vuexy-admin::card.basic title="Series de facturación">
<x-vuexy-admin::form.input :uid="$uniqueId" model="serie_ingresos" label="Serie para Ingresos" inline=true :labelCol=6 :inputCol=6 />
<x-vuexy-admin::form.input :uid="$uniqueId" model="serie_egresos" label="Serie para Egresos" inline=true :labelCol=6 :inputCol=6 />
<x-vuexy-admin::form.input :uid="$uniqueId" model="serie_pagos" label="Serie para Pagos" inline=true :labelCol=6 :inputCol=6 />
</x-vuexy-admin::card.basic>
{{-- Configuraciones --}}
<x-vuexy-admin::card.basic title="Configuraciones">
<x-vuexy-admin::form.checkbox uid="random" model="status" label="Habilitar sucursal" switch="true" />
<x-vuexy-admin::form.checkbox uid="random" model="show_on_website" label="Mostrar en sitio web" switch="true" />
<x-vuexy-admin::form.checkbox uid="random" model="enable_ecommerce" label="eCommerce habilitado en sitio Web" switch="true" />
</x-vuexy-admin::card.basic>
</div>
<div class="col-lg-4">
{{-- Información de contacto --}}
<x-vuexy-admin::card.basic title="Información de contacto">
<x-vuexy-admin::form.input :uid="$uniqueId" model="tel" label="Teléfono" icon="ti ti-phone" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="tel2" label="Teléfono secundario" icon="ti ti-phone" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="email" label="Correo electrónico" icon="ti ti-mail" />
<x-vuexy-admin::form.select :uid="$uniqueId" model="manager_id" label="Gerente" :options="$manager_id_options" placeholder="Selecciona el gerente" />
</x-vuexy-admin::card.basic>
{{-- Información fiscal --}}
<x-vuexy-admin::card.basic title="Información fiscal">
<x-vuexy-admin::form.input :uid="$uniqueId" model="rfc" label="RFC" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="nombre_fiscal" label="Nombre fiscal" />
<x-vuexy-admin::form.select :uid="$uniqueId" model="c_regimen_fiscal" label="Régimen fiscal" :options="$c_regimen_fiscal_options" placeholder="Selecciona el régimen fiscal" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="domicilio_fiscal" label="Domicilio fiscal" max="5" />
</x-vuexy-admin::card.basic>
</div>
<div class="col-lg-4">
{{-- Dirección --}}
<x-vuexy-contacts::card.address :uid="$uniqueId" :paisOptions="$c_pais_options" :estadoOptions="$c_estado_options" :localidadOptions="$c_localidad_options" :municipioOptions="$c_municipio_options" :coloniaOptions="$c_colonia_options"/>
{{-- Ubicación --}}
<x-vuexy-contacts::card.location :uid="$uniqueId" />
</div>
</div>
</x-vuexy-admin::form>
</div>
@push('page-script')
<script>
const initializeStoreForm = (mode) => {
const initializeContactInformation = () => {
let $manager_id = $("#manager_id_{{ $uniqueId }}");
$manager_id
.select2({
language: "es",
placeholder: "Selecciona el gerente",
allowClear: true,
width: "100%"
})
.on('select2:select select2:clear', function (e) {
@this.manager_id = e.params?.data?.id || null;
});
}
const initializeFiscalInformation = () => {
let $c_regimen_fiscal = $("#c_regimen_fiscal_{{ $uniqueId }}");
$c_regimen_fiscal
.select2({
language: "es",
placeholder: "Selecciona el regimen fiscal",
allowClear: true,
width: "100%"
})
.on('select2:select select2:clear', function (e) {
@this.c_regimen_fiscal = e.params?.data?.id || null;
});
}
const initializeLocationIQ = () => {
//
}
const initializeAddressFormHandler = () => {
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
// Definición de selectores AddressFormHandler
formSelectors = {
c_pais: '#c_pais_{{ $uniqueId }}',
c_estado: '#c_estado_{{ $uniqueId }}',
c_localidad: '#c_localidad_{{ $uniqueId }}',
c_municipio: '#c_municipio_{{ $uniqueId }}',
c_colonia: '#c_colonia_{{ $uniqueId }}',
c_codigo_postal: '#c_codigo_postal_{{ $uniqueId }}',
direccion: '#direccion_{{ $uniqueId }}',
notification: '#{{ $formId }} .address-notification'
};
// Definición de rutas AJAX Componente AddressFormHandler
const ajaxRoutes = {
codigo_postal: "{{ route('admin.core.sat.get.ajax', 'codigo_postal') }}",
localidad: "{{ route('admin.core.sat.get.ajax', 'localidad') }}",
estado: "{{ route('admin.core.sat.get.ajax', 'estado') }}",
municipio: "{{ route('admin.core.sat.get.ajax', 'municipio') }}",
colonia: "{{ route('admin.core.sat.get.ajax', 'colonia') }}"
};
// Inicializamos el handler de la información de la dirección
new AddressFormHandler(formSelectors, ajaxRoutes, @this, csrfToken);
}
const initializeLocationCard = (mode) => {
const locationInputs = {
search: '#location_search_{{ $uniqueId }}',
btnSearch: '#btn_search_{{ $uniqueId }}',
lat: '#lat_{{ $uniqueId }}',
lng: '#lng_{{ $uniqueId }}',
btnClear: '#{{ $formId }} .btn-clear-coords',
mapId: 'locationMap_{{ $uniqueId }}',
}
leafletMap = LeafletMapHelper.initializeMap(locationInputs, mode, @this);
}
// Inicializamos Tarjeta de Información de contacto
initializeContactInformation();
// Inicializamos Tarjeta de Información fiscal
initializeFiscalInformation();
// Inicializamos Tarjeta de Dirección
initializeAddressFormHandler();
// Inicializamos Tarjeta de Ubicación
initializeLocationCard(mode);
// Deshabilitamos el formulario si estamos eliminando
if (mode === 'delete') {
window.disableStoreForm('#{{ $formId }}');
}
}
// Evento para inicializar el formulario
window.addEventListener("DOMContentLoaded", () => {
window.addEventListener('on-failed-validation-store', (event) => {
setTimeout(() => {
initializeStoreForm('{{ $mode }}');
}, 10);
});
initializeStoreForm('{{ $mode }}');
});
</script>
@endpush

View File

@ -0,0 +1,7 @@
<x-vuexy-admin::table.bootstrap.manager :tagName="$tagName" :datatableConfig="$bt_datatable" :routes="$routes" noFilterButtons>
<x-slot name="tools">
<div class="mb-4 pr-2">
<x-vuexy-admin::button.basic icon="ti ti-pencil-plus" :label="$singularName" route='admin.store-manager.stores.create' />
</div>
</x-slot>
</x-vuexy-admin::table.bootstrap.manager>

View File

@ -0,0 +1,118 @@
<div>
<x-vuexy-admin::offcanvas.basic :id="$offcanvasId" :tag-name="$tagName">
<x-vuexy-admin::form :id="$formId" :mode="$mode" wireSubmit="onSubmit" actionPosition="both">
<x-slot name="actions">
<x-vuexy-admin::button.offcanvasButtons :mode="$mode" :tagName="$tagName" />
</x-slot>
<x-vuexy-admin::form.input :uid="$uniqueId" type="hidden" model="id" />
<x-vuexy-admin::form.input :uid="$uniqueId" type="hidden" model="mode" />
<x-vuexy-admin::form.select :uid="$uniqueId" model="store_id" label="Sucursal" placeholder="Selecciona una sucursal" :options="$store_options" />
<div class="row">
<x-vuexy-admin::form.input :uid="$uniqueId" model="code" label="Código de centro de trabajo" icon="ti ti-tag" parentClass="col-md-8" />
</div>
<x-vuexy-admin::form.input :uid="$uniqueId" model="name" label="Nombre del centro de trabajo" />
<x-vuexy-admin::form.textarea :uid="$uniqueId" model="description" label="Descripción" />
<hr>
<x-vuexy-admin::form.select :uid="$uniqueId" model="manager_id" label="Gerente" placeholder="Selecciona un gerente" :options="$manager_options" class="select2 form-select" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="tel" label="Teléfono" icon="ti ti-phone" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="tel2" label="Teléfono alternativo" icon="ti ti-phone" />
<hr>
<x-vuexy-admin::form.textarea :uid="$uniqueId" name="location_search" label="Dirección de búsqueda" placeholder="Buscar dirección" rows="2" button-icon="ti ti-map-pin-search" onClickButton="clearCoordinates()" />
<div class="row">
<x-vuexy-admin::form.input :uid="$uniqueId" model="lat" label="Latitud" type="number" step="0.000001" max="90" min="-90" parentClass="col-5" align="center" size="small" />
<x-vuexy-admin::form.input :uid="$uniqueId" model="lng" label="Longitud" type="number" step="0.000001" max="180" min="-180" parentClass="col-5" align="center" size="small" />
<div class="col-2 mt-5 !pl-0">
<x-vuexy-admin::button.basic variant="secondary" outline size="sm" icon="ti ti-map-pin-off ti-md" onClick="clearCoordinates()" />
</div>
</div>
<div style="height:400px; z-index: 1;" id="locationMap_{{ $uniqueId }}"></div>
<hr>
{{ $status }}
<x-vuexy-admin::form.checkbox :uid="$uniqueId" model="status" label="Activo" switch=true />
</x-vuexy-admin::form>
</x-vuexy-admin::offcanvas.basic>
</div>
@push('page-script')
<script>
// Evento para inicializar el formulario cuando se carga la página
window.addEventListener("DOMContentLoaded", () => {
const clearCoordinates = () => {
console.log('clearCoordinates');
// Aqui coloca la logica para limpiar la ubicación
//LeafletMapHelper.removeMarker();
}
/**
* Inicializa el formulario de centro de trabajo
*/
const initializeWorkCenterForm = () => {
const initializeSelect2 = () => {
const select2Selectors = {
[`#manager_id_{{ $uniqueId }}`]: {
placeholder: 'Selecciona un gerente',
onSelect: (id) => {
@this.set('updateManagerId', id, false);
},
onClear: () => {
@this.set('updateManagerId', null, false);
}
}
};
const parent = $('#storeWorkCenterForm');
$.each(select2Selectors, (selector, config) => {
const $element = parent.find(selector);
if ($element.length) {
$element
.select2({
placeholder: config.placeholder,
allowClear: true,
closeOnSelect: false
})
.on('select2:select', (e) => {
let selectedId = e.params.data.id;
config.onSelect(selectedId);
})
.on('select2:clear', () => {
config.onClear();
});
}
});
};
const initializeLocationCard = () => {
const locationInputs = {
search: '#location_search_{{ $uniqueId }}',
btnSearch: '#btn_search_{{ $uniqueId }}',
lat: '#lat_{{ $uniqueId }}',
lng: '#lng_{{ $uniqueId }}',
btnClear: '#storeWorkCenterForm .btn-clear-coords',
mapId: 'locationMap_{{ $uniqueId }}',
}
LeafletMapHelper.initializeMap(locationInputs, mode, @this);
}
const mode = @this.get('mode')?? 'create';
// Inicializa los select2
initializeSelect2();
// Inicializa el card de ubicación
initializeLocationCard(mode);
}
var myOffcanvas = document.getElementById('{{ $offcanvasId }}')
myOffcanvas.addEventListener('show.bs.offcanvas', function () {
initializeWorkCenterForm();
});
});
</script>
@endpush

View File

@ -0,0 +1,12 @@
<x-vuexy-admin::table.bootstrap.manager :tagName="$tagName" :datatableConfig="$bt_datatable">
<x-slot name="tools">
<div class="mb-4 pr-2">
<x-vuexy-admin::button.IndexOffcanvas :label="$singularName" :tagName="$tagName" />
</div>
@if(count($storeOptions) > 1)
<div class="mb-4 pr-2" style="max-width: 320px; min-width: 220px;">
<x-vuexy-admin::form.select model="store_id" :options="$storeOptions" placeholder="[Sucursal]" size="sm" />
</div>
@endif
</x-slot>
</x-vuexy-admin::table.bootstrap.manager>

View File

@ -0,0 +1,24 @@
@extends('vuexy-admin::layouts.vuexy.layoutMaster')
@section('title', $store? (ucfirst($mode) . ': ' . $store?->name) : 'Nueva Sucursal')
@section('vendor-style')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.scss',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/leaflet/leaflet.scss',
])
@endsection
@section('vendor-script')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.js',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/es.js',
'vendor/koneko/laravel-vuexy-admin/resources/assets/js/notifications/LivewireNotification.js',
'vendor/koneko/laravel-vuexy-admin/resources/assets/js/maps/LeafletMapHelper.js',
'vendor/koneko/laravel-vuexy-contacts/resources/assets/js/addresses/AddressFormHandler.js',
])
@endsection
@section('content')
@livewire('store-form', compact('mode', 'store'))
@endsection

View File

@ -0,0 +1,25 @@
@extends('vuexy-admin::layouts.vuexy.layoutMaster')
@section('title', 'Sucursales')
@section('vendor-style')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.scss',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/bootstrap-table/bootstrap-table.scss',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/fonts/bootstrap-icons.scss',
])
@endsection
@section('vendor-script')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.js',
])
@endsection
@push('page-script')
@vite('vendor/koneko/laravel-vuexy-admin/resources/assets/js/bootstrap-table/bootstrapTableManager.js')
@endpush
@section('content')
@livewire('store-index')
@endsection

View File

@ -0,0 +1,9 @@
@extends('vuexy-admin::layouts.vuexy.layoutMaster')
@section('title', $store->name)
@section('content')
<pre>
{{ print_r($store) }}
</pre>
@endsection

View File

@ -0,0 +1,26 @@
@extends('vuexy-admin::layouts.vuexy.layoutMaster')
@section('title', 'Centro de trabajo')
@section('vendor-style')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.scss',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/bootstrap-table/bootstrap-table.scss',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/fonts/bootstrap-icons.scss',
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/leaflet/leaflet.scss',
])
@endsection
@push('page-script')
@vite([
'vendor/koneko/laravel-vuexy-admin/resources/assets/vendor/libs/select2/select2.js',
'vendor/koneko/laravel-vuexy-admin/resources/assets/js/bootstrap-table/bootstrapTableManager.js',
'vendor/koneko/laravel-vuexy-admin/resources/assets/js/forms/formConvasHelper.js',
'vendor/koneko/laravel-vuexy-admin/resources/assets/js/maps/LeafletMapHelper.js',
])
@endpush
@section('content')
@livewire('work-center-index')
@livewire('work-center-form')
@endsection

View File

@ -0,0 +1,9 @@
@extends('vuexy-admin::layouts.vuexy.layoutMaster')
@section('title', $workcenter->name)
@section('content')
<pre>
{{ print_r($workcenter) }}
</pre>
@endsection