CodeIgniter4 Boilerplatetypesmovement CRUD MVCfor the types of movement inventory, with fields as companye, description, type Input/Output, and it’s transfer
Esta biblioteca es una extensión del texto estándar de CodeIgniter4, diseñada específicamente para facilitar la interacción con bases de datos a través de un enfoque intuitivo y eficiente. Con una interfaz sencilla de base de datos de copias de seguridad para MariaDB/MySQL, permite a los desarrolladores gestionar respaldos de manera rápida y segura, eliminando la complejidad que a menudo acompaña a estos procesos. Además, cuenta con diversas funcionalidades adicionales, como la programación de tareas automáticas y la restauración fácil de datos, lo que la convierte en una herramienta esencial para aquellos que buscan optimizar el manejo de sus bases de datos en aplicaciones web.
Instalación
Ejecutar el siguiente comando
composer require julio101290/boilerplatbackup
Ejecutar el siguiente comando para crear las tablas y sembrar los datos de los permisos
php spark boilerplatebackup:installbackup
Crear el menú tal cual se ve en la imagen
Listo
Uso
Puede descubrir cómo funciona con las rutas de lectura de código, el controlador y las vistas, etc. Finalmente… ¡Feliz codificación!
Changelog
Please see CHANGELOG for more information what has changed recently.
Contribuciones
Las contribuciones son muy bienvenidas.
License
This package is free software distributed under the terms of the MIT license.
El complemento de pago es un archivo electrónico que se agrega a una factura electrónica para proporcionar información adicional sobre los pagos recibidos. Este complemento es obligatorio en México para todas las facturas que se emiten con un método de pago distinto al de contado.
El complemento de pago incluye los siguientes datos:
Forma de pago: La forma en que se recibió el pago, por ejemplo, efectivo, cheque, transferencia bancaria, etc.
Monto del pago: El monto del pago recibido.
Fecha del pago: La fecha en que se recibió el pago.
Documento origen: El número de la factura o documento que se pagó.
Método de pago: El método que se utilizó para realizar el pago, por ejemplo, banca electrónica, banca móvil, etc.
El complemento de pago se debe emitir a más tardar al décimo día natural del mes siguiente al que se recibió el pago. Se puede emitir a través de un software de facturación electrónica o de manera manual.
El kardex de inventario es un documento o sistema de registro que permite llevar un control de las entradas y salidas de mercancías o productos en un almacén. En él se registran los datos básicos de cada producto, como el código, la descripción, la unidad de medida, el precio unitario y el stock.
El kardex de inventario es una herramienta fundamental para la gestión del inventario. Permite conocer la cantidad de cada producto en existencia, así como su valor total. También ayuda a identificar las tendencias de consumo y a detectar posibles problemas de desabastecimiento.
El kardex de inventario se puede llevar de forma manual o automatizada. En el caso de la gestión manual, el registro se realiza en una hoja de cálculo o en un libro. En el caso de la gestión automatizada, el registro se realiza en un sistema informático.
Los datos que se registran en el kardex de inventario son los siguientes:
Código: Identificador único del producto.
Descripción: Nombre o descripción del producto.
Unidad de medida: Unidad en la que se mide el producto (unidades, kilos, metros, etc.).
Precio unitario: Precio de venta o de compra del producto.
Stock inicial: Cantidad de producto en existencia al inicio del periodo.
Entradas: Cantidad de producto que ha entrado en el almacén durante el periodo.
Salidas: Cantidad de producto que ha salido del almacén durante el periodo.
Stock final: Cantidad de producto en existencia al final del periodo.
El kardex de inventario se actualiza con cada movimiento de inventario. Cuando se recibe un producto, se registra la entrada con la cantidad recibida y el precio unitario. Cuando se vende un producto, se registra la salida con la cantidad vendida y el precio unitario.
El kardex de inventario es una herramienta esencial para la gestión del inventario. Permite conocer la cantidad de cada producto en existencia, así como su valor total. También ayuda a identificar las tendencias de consumo y a detectar posibles problemas de desabastecimiento.
Para registrar los movimientos requerimos especificar que tipo de movimiento es como puede ser entradas por compra, salidas por venta, entrada por devolución de cliente, saluda por devolución a proveedor
Para ello crearemos el siguiente catalogo de Tipos de movimiento con los siguientes campos
Empresa
Descripción
tipo
Es traspaso
Primero creamos el archivo de migración App/Database/2023-08-17222335_Tipos_movimientos_inventario.php con el siguiente código
Creamos el archivo de lenguaje en español en App/Languaje/es/proveedores.php con el siguiente código.
<?php
$proveedores["logDescription"] = "El registro en proveedores fue guardado con los siguientes datos:";
$proveedores["logUpdate"] = "El registro en proveedores fue actualizado con los siguientes datos:";
$proveedores["logDeleted"] = "El registro en proveedores fue eliminado con los siguientes datos:";
$proveedores["msg_delete"] = "El Registro en clieproveedoresntes fue eliminado correctamente:";
$proveedores["add"] = "Agregar Proveedor";
$proveedores["edit"] = "Editar Proveedor";
$proveedores["createEdit"] = "Crear / Editar";
$proveedores["title"] = "Admon. Proveedores";
$proveedores["subtitle"] = "Lista de Proveedores";
$proveedores["fields"]["firstname"] = "Nombre";
$proveedores["fields"]["lastname"] = "Apellido";
$proveedores["fields"]["taxID"] = "RFC";
$proveedores["fields"]["email"] = "Correo Electronico";
$proveedores["fields"]["direction"] = "Direccion";
$proveedores["fields"]["birthdate"] = "Fecha de nacimiento";
$cusproveedorestumers["fields"]["created_at"] = "Fecha de creacion";
$proveedores["fields"]["updated_at"] = "Ultima modificacion";
$proveedores["fields"]["deleted_at"] = "Fecha de eliminacion";
$proveedores["fields"]["actions"] = "Acciones";
$proveedores["msg"]["msg_insert"] = "Registro agregado correctamente.";
$proveedores["msg"]["msg_update"] = "Registro modificado correctamente.";
$proveedores["msg"]["msg_delete"] = "Registro eliminado correctamente.";
$proveedores["msg"]["msg_get"] = "Registro obtenido correctamente.";
$proveedores["msg"]["msg_get_fail"] = "Registro no encontrado o eliminado.";
return $proveedores;
Creamos el archivo de lenguaje en ingles en App/Languaje/en/proveedores.php con el siguiente código.
<?php
$proveedores["logDescription"] = "The custumers was saved with the following data:";
$proveedores["logUpdate"] = "The custumers was updated with the following data:";
$proveedores["logDeleted"] = "The custumers was deleted with the following data:";
$proveedores["msg_delete"] = "The custumers was deleted correctly:";
$proveedores["add"] = "Add Vendor";
$proveedores["edit"] = "Edit Vendor";
$proveedores["createEdit"] = "Create / Edit";
$proveedores["title"] = "Vendors management";
$proveedores["subtitle"] = "Vendors list";
$proveedores["fields"]["firstname"] = "Firstname";
$proveedores["fields"]["lastname"] = "Lastname";
$proveedores["fields"]["taxID"] = "TaxID";
$proveedores["fields"]["email"] = "Email";
$proveedores["fields"]["direction"] = "Direction";
$proveedores["fields"]["birthdate"] = "Birthdate";
$proveedores["fields"]["created_at"] = "Created_at";
$proveedores["fields"]["updated_at"] = "Updated_at";
$proveedores["fields"]["deleted_at"] = "Deleted_at";
$proveedores["fields"]["actions"] = "Actions";
$proveedores["msg"]["msg_insert"] = "The Vendor has been correctly added.";
$proveedores["msg"]["msg_update"] = "The Vendor has been correctly modified.";
$proveedores["msg"]["msg_delete"] = "The Vendor has been correctly deleted.";
$proveedores["msg"]["msg_get"] = "The Vendor has been successfully get.";
$proveedores["msg"]["msg_get_fail"] = "The Vendor not found or already deleted.";
return $proveedores;
En App/Config/Routes.php en el grupo admin agregamos las siguientes rutas
Bien como ya saben para hacer una venta se requiere saber de que sucursal es así como ciertas configuraciones particulares por sucursal como la configuración de las series electrónicas para el timbrado del CFDI, así como los datos que saldran en las impresiones de los reportes, como la dirección etc
Por esta ocasión agregaremos lo siguientes datos, posterior mente se pueden agregar mas si se necesitan
Primeramente creamos el archivo de migración app/database/migrations/2023-02-14110147_Branchoffices.php , se dan cuenta que dice Branchoffice, es por que en su momento lo quise empezar en ingles para practicar
Creamos el archivo del modelo usuarios por sucursal app/model/UsuariosSucursalModel.php
<?php
namespace App\Models;
use CodeIgniter\Model;
class UsuariosSucursalModel extends Model
{
protected $table = 'usuarios_sucursal';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = 'array';
protected $useSoftDeletes = true;
protected $allowedFields = ['id', 'idEmpresa', 'idSucursal', 'idUsuario', 'status', 'created_at', 'updated_at', 'deleted_at'];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $deletedField = 'deleted_at';
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
public function mdlSucursalesPorUsuario($sucursal, $empresasID)
{
$result = $this->db->table('users a, usuariosempresa b')
->select(
'ifnull(a.id,0) as id
,a.username
,b.idEmpresa
,' . $sucursal . ' as idSucursal
,ifnull((select status
from usuarios_sucursal z
where z.idUsuario = a.id
and z.idEmpresa=b.idEmpresa
and z.idSucursal=' . $sucursal . '
),\'off\') as status
,ifnull((select id
from usuarios_sucursal z
where z.idUsuario = a.id
and z.idEmpresa=b.idEmpresa
and z.idSucursal=' . $sucursal . '
),0) as idSucursalUsuario
'
)
->where('a.id', 'b.idUsuario', FALSE)
->where('b.idEmpresa', $empresasID);
return $result;
}
}
Creamos el archivo app/controller/BranchofficesController.php
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use \App\Models\{
BranchofficesModel
};
use App\Models\LogModel;
use CodeIgniter\API\ResponseTrait;
use App\Models\EmpresasModel;
use App\Models\UsuariosSucursalModel;
class BranchofficesController extends BaseController {
use ResponseTrait;
protected $log;
protected $branchoffices;
protected $empresas;
protected $usuariosPorSucursal;
public function __construct() {
$this->branchoffices = new BranchofficesModel();
$this->log = new LogModel();
$this->empresas = new EmpresasModel();
$this->usuariosPorSucursal = new UsuariosSucursalModel();
helper('menu');
}
public function index() {
helper('auth');
$idUser = user()->id;
$titulos["empresas"] = $this->empresas->mdlEmpresasPorUsuario($idUser);
if (count($titulos["empresas"]) == "0") {
$empresasID[0] = "0";
} else {
$empresasID = array_column($titulos["empresas"], "id");
}
if ($this->request->isAJAX()) {
$datos = $this->branchoffices->select('id
,key
,name
,cologne
,city
,postalCode
,timeDifference
,tax,dateAp
,phone
,fax
,companie
,created_at
,deleted_at
,updated_at')->where('deleted_at', null)
->whereIn('companie', $empresasID);;
return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
}
// $empresas = $this->empresas->select("id,nombre")->asObject()->findAll();
// $titulos["empresas"] = $empresas;
$titulos["title"] = lang('branchoffices.title');
$titulos["subtitle"] = lang('branchoffices.subtitle');
return view('branchoffices', $titulos);
}
/**
* Read Branchoffices
*/
public function getBranchoffices() {
$idBranchoffices = $this->request->getPost("idBranchoffices");
$datosBranchoffices = $this->branchoffices->find($idBranchoffices);
echo json_encode($datosBranchoffices);
}
/**
* Save or update Branchoffices
*/
public function save() {
helper('auth');
$userName = user()->username;
$idUser = user()->id;
$datos = $this->request->getPost();
if ($datos["idBranchoffices"] == 0) {
try {
if ($this->branchoffices->save($datos) === false) {
$errores = $this->branchoffices->errors();
foreach ($errores as $field => $error) {
echo $error . " ";
}
return;
}
$dateLog["description"] = lang("vehicles.logDescription") . json_encode($datos);
$dateLog["user"] = $userName;
$this->log->save($dateLog);
echo "Guardado Correctamente";
} catch (\PHPUnit\Framework\Exception $ex) {
echo "Error al guardar " . $ex->getMessage();
}
} else {
if ($this->branchoffices->update($datos["idBranchoffices"], $datos) == false) {
$errores = $this->branchoffices->errors();
foreach ($errores as $field => $error) {
echo $error . " ";
}
return;
} else {
$dateLog["description"] = lang("branchoffices.logUpdated") . json_encode($datos);
$dateLog["user"] = $userName;
$this->log->save($dateLog);
echo "Actualizado Correctamente";
return;
}
}
return;
}
/**
* Delete Branchoffices
* @param type $id
* @return type
*/
public function delete($id) {
$infoBranchoffices = $this->branchoffices->find($id);
helper('auth');
$userName = user()->username;
if (!$found = $this->branchoffices->delete($id)) {
return $this->failNotFound(lang('branchoffices.msg.msg_get_fail'));
}
$logData["description"] = lang("branchoffices.logDeleted") . json_encode($infoBranchoffices);
$logData["user"] = $userName;
$this->log->save($logData);
return $this->respondDeleted($found, lang('branchoffices.msg_delete'));
}
public function usuariosPorSucursal($sucursal) {
helper('auth');
$idUser = user()->id;
$datosSucursal = $this->branchoffices->select("companie as empresa")->where("id",$sucursal)->first();
if(isset($datosSucursal["empresa"])){
$idEmpresa = $datosSucursal["empresa"];
}else{
$idEmpresa = -1;
}
$usuarios = $this->usuariosPorSucursal->mdlSucursalesPorUsuario($sucursal, $idEmpresa);
return \Hermawan\DataTables\DataTable::of($usuarios)->toJson(true);
}
/**
* Activar Desactivar Usuario Por Empresa
*/
public function ActivarDesactivar() {
$datos = $this->request->getPost();
if ($datos["id"] > 0) {
//ACTUALIZA SI EXISTE
if ($this->usuariosPorSucursal->update($datos["id"], $datos) === false) {
$errores = $this->usuariosPorSucursal->errors();
foreach ($errores as $field => $error) {
echo $error . " ";
}
return;
}
echo "ok";
} else {
//INSERTA SI NO EXISTE
if ($this->usuariosPorSucursal->save($datos) === false) {
$errores = $this->usuariosPorSucursal->errors();
foreach ($errores as $key => $error) {
echo $error . " ";
}
return;
}
echo "ok";
}
}
/**
* Get Storages via AJax
*/
public function getSucursalesAjax() {
$request = service('request');
$postData = $request->getPost();
$response = array();
// Read new token and assign in $response['token']
$response['token'] = csrf_hash();
helper('auth');
$userName = user()->username;
$idUser = user()->id;
$sucursalesPorUsuario = $this->usuariosPorSucursal->select("*")
->where("idUsuario", $idUser)
->where("status", "on")->findAll();
$sucursalesPorUsuario = array_column($sucursalesPorUsuario, "idSucursal");
if (!isset($postData['searchTerm'])) {
// Fetch record
$sucursales = new BranchofficesModel();
$listSucursales = $sucursales->select('id,key,name')->where("deleted_at", null)
->whereIn("id", $sucursalesPorUsuario)
->where("companie", $postData["idEmpresa"])
->orderBy('id')
->orderBy('key')
->orderBy('name')
->findAll();
} else {
$searchTerm = $postData['searchTerm'];
// Fetch record
$sucursales = new BranchofficesModel();
$listSucursales = $sucursales->select('id,key,name')
->where("deleted_at", null)
->whereIn("id", $sucursalesPorUsuario)
->where("companie", $postData["idEmpresa"])
->like('name', $searchTerm)
->orLike('id', $searchTerm)
->orLike('key', $searchTerm)
->findAll();
}
$data = array();
$data[] = array(
"id" => 0,
"text" => "0 Todas las sucursales",
);
foreach ($listSucursales as $sucursal) {
$data[] = array(
"id" => $sucursal['id'],
"text" => $sucursal['key'] . ' ' . $sucursal['name'],
);
}
$response['data'] = $data;
return $this->response->setJSON($response);
}
}
Creamos el archivo del controlador para usuarios por sucursal app/controller/UsuariosSucursalController.php
<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use \App\Models\{
UsuariosSucursalModel
};
use App\Models\LogModel;
use CodeIgniter\API\ResponseTrait;
class UsuariosSucursalController extends BaseController {
use ResponseTrait;
protected $log;
protected $usuariosSucursal;
public function __construct() {
$this->usuariosSucursal = new UsuariosSucursalModel();
$this->log = new LogModel();
helper('menu');
}
public function index() {
if ($this->request->isAJAX()) {
$datos = $this->usuariosSucursal>select('id,idEmpresa,idSucursal,idUsuario,status,created_at,updated_at,deleted_at')->where('deleted_at', null);
return \Hermawan\DataTables\DataTable::of($datos)->toJson(true);
}
$titulos["title"] = "Usuarios Sucursal";
$titulos["subtitle"] = "Usuarios Por Sucursal";
return view('usuariosAlmacen', $titulos);
}
/**
* Read Usuariosempresa
*/
public function getUsuariosAlmacen() {
$idUsuariosAlmacen = $this->request->getPost("idUsuariosSucursal");
$datosUsuariosAlmacen = $this->usuariosAlmacen->find($idUsuariosAlmacen);
echo json_encode($datosUsuariosAlmacen);
}
/**
* Save or update Usuariosempresa
*/
public function save() {
helper('auth');
$userName = user()->username;
$idUser = user()->id;
$datos = $this->request->getPost();
if ($datos["idUsuariosSucursal"] == 0) {
try {
if ($this->usuariosSucursal->save($datos) === false) {
$errores = $this->usuariosSucursal->errors();
foreach ($errores as $field => $error) {
echo $error . " ";
}
return;
}
$dateLog["description"] = "Usuarios Por Sucursal" . json_encode($datos);
$dateLog["user"] = $userName;
$this->log->save($dateLog);
echo "Guardado Correctamente";
} catch (\PHPUnit\Framework\Exception $ex) {
echo "Error al guardar " . $ex->getMessage();
}
} else {
if ($this->usuariosSucursal->update($datos["idUsuariossucursal"], $datos) == false) {
$errores = $this->usuariosSucursal->errors();
foreach ($errores as $field => $error) {
echo $error . " ";
}
return;
} else {
$dateLog["description"] = lang("usuariosSucursal.logUpdated") . json_encode($datos);
$dateLog["user"] = $userName;
$this->log->save($dateLog);
echo "Actualizado Correctamente";
return;
}
}
return;
}
/**
* Delete Usuariosempresa
* @param type $id
* @return type
*/
public function delete($id) {
$infoUsuariosSucursal = $this->usuariosSucursal->find($id);
helper('auth');
$userName = user()->username;
if (!$found = $this->usuariosSucursal->delete($id)) {
return $this->failNotFound(lang('usuariosempresa.msg.msg_get_fail'));
}
$this->usuariosSucursal->purgeDeleted();
$logData["description"] = "Datos Anteriores Usuarios Por Sucursal" . json_encode($infoUsuariosSucursal);
$logData["user"] = $userName;
$this->log->save($logData);
return $this->respondDeleted($found, lang('usuariossucursal.msg_delete'));
}
}
Creamos el archivo principal de la vista de sucursales app/views/branchoffice.php este archivo hará una inclusión a los modales de usuarios por sucursal y captura de sucursales
Usamos cookies en nuestro sitio web para brindarle la experiencia más relevante recordando sus preferencias y visitas repetidas. Al hacer clic en "Aceptar", acepta el uso de TODAS las cookies.
This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.