En el desarrollo de soluciones para Business Central, una de las funcionalidades más útiles y solicitadas es la capacidad de gestionar imágenes asociadas a los registros, como por ejemplo, fotos de productos. Esta funcionalidad es particularmente útil en escenarios donde se necesita capturar y asociar fotos directamente desde un dispositivo móvil. Imagina a un empleado en el almacén, utilizando su teléfono para tomar fotos de productos y subirlas instantáneamente a Business Central. Este desarrollo facilita precisamente esa tarea.
¡Vamos manos a la obra! 🤩
Creación de la Página para Imágenes
Para empezar, necesitamos crear una página nueva que se encargue de gestionar las imágenes. Esta página será una CardPart que permitirá visualizar y manipular las imágenes de forma sencilla.
page 50100 "CarPart Picture"
{
DeleteAllowed = false;
InsertAllowed = false;
LinksAllowed = false;
PageType = CardPart;
SourceTable = "Config. Media Buffer";
SourceTableTemporary = true;
UsageCategory = None;
layout
{
area(content)
{
field(Picture; Rec."Media Set")
{
ApplicationArea = All;
ShowCaption = false;
ToolTip = 'Specifies the picture that has been inserted for the item.';
}
}
}
En este fragmento, se define una página de tipo CardPart que utiliza la tabla temporal “Config. Media Buffer” como fuente. La razón para usar una tabla temporal es para evitar que las imágenes se almacenen directamente hasta que se confirme la operación. Dentro del área de contenido, se muestra la imagen almacenada en el campo “Media Set”.
¡Acciones a Montones!
¿Qué es una página sin acciones? Aquí se definen las acciones que permiten tomar, importar, exportar y eliminar imágenes:
actions
{
area(processing)
{
action(ActionTakePhoto)
{
ApplicationArea = All;
Caption = 'Take Photo', Comment = 'ESP="Hacer foto"';
Image = Camera;
ToolTip = 'Activate the camera on the device.', Comment = 'ESP="Activa la cámara en el dispositivo."';
trigger OnAction()
begin
TakePhoto();
end;
}
action(ActionImportPicture)
{
ApplicationArea = All;
Caption = 'Import', Comment = 'ESP="Importar"';
Image = Import;
ToolTip = 'Import a picture file.', Comment = 'ESP="Importar un archivo de imagen."';
trigger OnAction()
begin
ImportPicture();
end;
}
action(ActionExportPicture)
{
ApplicationArea = All;
Caption = 'Export', Comment = 'ESP="Exportar"';
Image = Export;
ToolTip = 'Export the picture to a file.', Comment = 'ESP="Exporte la imagen a un archivo."';
trigger OnAction()
var
begin
ExportPicture()
end;
}
action(ActionDeletePicture)
{
ApplicationArea = All;
Caption = 'Delete', Comment = 'ESP="Eliminar"';
Image = Delete;
ToolTip = 'Delete the record.', Comment = 'ESP="Eliminar el registro."';
trigger OnAction()
begin
DeletePicture();
end;
}
}
}
Cada acción definida aquí tiene un propósito claro:
- Take Photo: Activa la cámara del dispositivo y permite tomar una foto que se asignará al artículo. Esta función es particularmente útil cuando se utiliza Business Central desde un teléfono móvil, permitiendo capturar imágenes en tiempo real sin necesidad de procesos intermedios.
- Import Picture: Permite seleccionar e importar una imagen desde un archivo.
- Export Picture: Exporta la imagen actual a un archivo local.
- Delete Picture: Elimina la imagen asociada al artículo después de una confirmación del usuario.
¿Cómo Funcionan Estas Acciones?
Cada acción ejecuta un procedimiento específico que realiza la tarea deseada. Vamos a profundizar en cómo funcionan estos procedimientos:
Procedimiento TakePhoto()
local procedure TakePhoto()
var
Camera: Codeunit Camera;
PictureInstream: InStream;
PictureDescription: Text;
MimeTypeTok: Label 'image/jpeg', Locked = true;
begin
if Rec."Media Set".Count() > 0 then
ClearPicture();
if Camera.GetPicture(PictureInstream, PictureDescription) then begin
Clear(Rec."Media Set");
Rec."Media Set".ImportStream(PictureInstream, PictureDescription, MimeTypeTok);
FieldRefe.Value := Rec."Media Set";
RecordRefe.Modify();
end;
end;
Este procedimiento se encarga de capturar una foto utilizando la cámara del dispositivo. La codeunit Camera maneja la interacción con la cámara. Al llamar a Camera.GetPicture, se abre la cámara del dispositivo y se captura una imagen, la cual se almacena en el InStream PictureInstream. Si ya existe una imagen asociada al artículo, se elimina utilizando ClearPicture() para evitar duplicidades.
Una vez que se captura la imagen, se limpia el campo “Media Set” y se importa la nueva imagen mediante ImportStream. Finalmente, el valor del campo se actualiza y el registro se modifica para almacenar la imagen en la tabla temporal, manteniendo la consistencia de los datos.
Procedimiento ImportPicture()
local procedure ImportPicture()
begin
if not UploadIntoStream('', '', '', FileName, DocInStream) then
exit;
if Rec."Media Set".Count() > 0 then
ClearPicture();
Rec."Media Set".ImportStream(DocInStream, FileName);
FieldRefe.Value := Rec."Media Set";
RecordRefe.Modify();
end;
ImportPicture() permite al usuario importar una imagen desde un archivo. Primero, se solicita al usuario seleccionar un archivo para subir mediante UploadIntoStream, que abre un diálogo de selección de archivos y almacena el archivo seleccionado en un InStream (DocInStream). Al igual que en TakePhoto(), si ya hay una imagen existente, se elimina antes de importar la nueva.
El archivo importado se asocia al campo “Media Set” mediante ImportStream. Finalmente, se actualiza el valor del campo en el registro, asegurando que la nueva imagen esté correctamente vinculada al artículo.
Procedimiento ExportPicture()
local procedure ExportPicture()
begin
Clear(DocInStream);
TenantMedia.Get(Rec."Media Set".Item(Rec."Media Set".Count));
TenantMedia.CalcFields(Content);
TenantMedia.Content.CreateInStream(DocInStream);
FileName := TenantMedia.Description;
DownloadFromStream(DocInStream, '', '', '', FileName);
end;
El procedimiento ExportPicture() se encarga de exportar la imagen asociada a un archivo local. Primero, se limpia cualquier dato previo en DocInStream. Luego, se obtiene el contenido de la imagen desde el campo “Media Set” utilizando TenantMedia.Get y se carga en el InStream.
Una vez que el contenido está disponible, se asigna un nombre de archivo basado en la descripción de la imagen y se descarga al sistema local mediante DownloadFromStream. Este procedimiento es muy útil cuando se necesita acceder a la imagen fuera del entorno de Business Central.
Procedimiento DeletePicture()
local procedure DeletePicture()
var
DeleteImageQst: Label 'Do you want to delete the image?', Comment = 'ESP="¿Quieres eliminar la imagen?"';
begin
if not Confirm(DeleteImageQst) then
exit;
ClearPicture();
end;
Finalmente, DeletePicture() maneja la eliminación de la imagen asociada al artículo. Antes de proceder, se muestra un cuadro de diálogo de confirmación al usuario, utilizando el método Confirm. Si el usuario confirma la eliminación, se llama a ClearPicture() para eliminar la imagen del campo “Media Set” y limpiar la referencia en el registro.
Integración de la Página de Imágenes en la Ficha de Artículos
Después de crear la página para las imágenes, lo siguiente es integrarla en la ficha de artículos. Esto se logra mediante una extensión de página.
pageextension 50101 "Item Card" extends "Item Card"
{
layout
{
addlast(Item)
{
part("CardPicture"; "CarPart Picture")
{
ApplicationArea = All;
Caption = ' ';
}
}
}
trigger OnAfterGetRecord()
begin
CurrPage."CardPicture".Page.SetParams(Rec, Rec.FieldNo(Picture));
end;
}
Aquí, simplemente añadimos la nueva CardPart al final de la ficha de artículos. Además, en el evento OnAfterGetRecord, pasamos los parámetros necesarios para que la CardPart funcione correctamente con el registro actual.
Beneficios y Aplicaciones Prácticas
Implementar esta funcionalidad de gestión de imágenes directamente en Business Central aporta múltiples beneficios
para las empresas:
- Mejora en la Presentación de Productos: La capacidad de asociar imágenes a los artículos permite que los usuarios tengan una referencia visual inmediata, mejorando la precisión en la gestión de inventarios y ventas.
- Captura en Tiempo Real: Utilizando dispositivos móviles, los empleados pueden tomar fotos y asignarlas a los artículos directamente desde el almacén o la tienda, eliminando la necesidad de pasos adicionales o de regresar a la oficina para completar el proceso.
- Ahorro de Tiempo: Al centralizar la gestión de imágenes en Business Central, se simplifican los flujos de trabajo y se evita la duplicación de esfuerzos.
- Accesibilidad y Flexibilidad: Business Central es accesible desde cualquier lugar y dispositivo, lo que permite a los empleados realizar tareas críticas en tiempo real, mejorando la eficiencia operativa.
Esta integración es especialmente útil en industrias donde la visualización de productos es crucial, como el comercio minorista, la gestión de inventarios o la fabricación.
Conclusión
Implementar la gestión de imágenes en Business Central no solo mejora la experiencia de usuario, sino que también añade un valor significativo a la personalización del sistema. Permitir a los empleados capturar y gestionar imágenes directamente desde sus dispositivos móviles es una opción excelente para empresas que buscan optimizar sus operaciones y ofrecer un servicio más dinámico.
Si quieres ver el código completo, está en GitHub.
¡Espero que este post te haya sido útil! Hasta la próxima.