Compartir a través de


Generar códigos QR e imprimirlos en recibos para Arabia Saudí

Nota

La funcionalidad descrita en este artículo está destinada a respaldar los requisitos de la Fase 1 de la implementación de la facturación electrónica en el Reino de Arabia Saudita. Para obtener información sobre las características destinadas a cumplir los requisitos de la Fase 2 de la implementación de la facturación electrónica en el Reino de Arabia Saudí, consulte Generar y enviar facturas electrónicas simplificadas para Arabia Saudí.

En este artículo se proporciona información general sobre la funcionalidad de impresión de códigos QR disponible para Arabia Saudí en Microsoft Dynamics 365 Commerce.

En una tienda que está vinculada a una entidad jurídica que tiene su dirección principal en Arabia Saudí, los usuarios pueden imprimir un código QR en el recibo de una transacción de venta al contado o pedido de cliente. El código QR contiene la siguiente información.

Secuencia Campo Origen de datos
1 Nombre de la empresa El nombre de la entidad jurídica
2 Número de registro de IVA de la empresa El número de registro fiscal de la entidad jurídica
3 Fecha y hora de la transacción La fecha y hora de la transacción de la tienda
4 Importe total del recibo (incluido el impuesto sobre el valor añadido [IVA]) El importe total de la transacción de la tienda
5 Importe total de IVA incluido en el recibo El importe total del impuesto de transacción de la tienda

Nota

Cuando se crean transacciones de pedidos de cliente, el importe total del recibo se calcula sumando los importes totales de todas las líneas de transacción que usan el modo de entrega para llevar.

El código QR se genera aplicando la transformación base64 a la información de la transacción codificada en el formato Etiqueta-Longitud-Valor (TLV). Zakat, la Autoridad Tributaria y Aduanera (ZATCA) proporciona herramientas que se pueden utilizar para validar el código QR. Para obtener más información sobre los requisitos de facturación electrónica y las capacidades de validación de códigos QR, consulte Portal de facturación electrónica de ZATCA.

Configurar códigos QR

Para generar códigos QR e imprimirlos en recibos para Arabia Saudí, debe completar las siguientes tareas.

  1. Configure campos personalizados para que puedan usarse en formatos de recibos de ventas.
  2. Configurar formatos de recibo.
  3. Especificar dimensiones de código QR en parámetros de Commerce.
  4. Habilitar las extensiones de Commerce Runtime (CRT).

Configure campos personalizados para que se puedan usar en formatos de recibo para recibos de ventas

Puede configurar el idioma, el texto y los campos personalizados que se utilizan en los formatos de recibo de apuntar de venta (PDV). Sobre la página Texto de idioma, agregue los siguientes registros para las etiquetas de los campos personalizados para diseños de recibos. Tenga en cuenta que los valores ID de idioma, ID de texto y Texto que se muestran en la tabla son solo ejemplos. Puede cambiarlos fácilmente para satisfacer sus necesidades. Sin embargo, los valores de Text ID que use deben ser únicos y deben ser iguales o superiores a 900001.

Id. del idioma Id. de texto Text
es-es 900001 Código QR (SA)

Nota

La empresa predeterminada del usuario que crea la configuración del recibo debe ser la misma entidad legal donde se crea la configuración del texto del idioma. Alternativamente, los textos en el mismo idioma deben crearse tanto en la empresa predeterminada del usuario como en la entidad legal de la tienda para la que se creó la configuración.

Sobre la página Campos personalizados, agregue los siguientes registros para los campos personalizados para diseños de recibos. Tenga en cuenta que los valores ID de texto de subtítulo deben corresponder a los valores de ID de texto que especificó en la página Texto de idioma.

Name Escriba Id. de texto de leyenda
INVOICEQRCODE_SA Recepción 900001

Configurar formatos de recibo

Para cada formato de recibo requerido, cambie el valor del campo Comportamiento de impresión a Imprimir siempre.

En el diseñador de formato de recibo, agregue el siguiente campo personalizado a la sección Pie de página del recibo. Tenga en cuenta que los nombres de los campos corresponden a los textos de idioma que definió en la sección anterior.

  • Código QR (SA): este campo imprime el código QR en el recibo.

Para obtener más información sobre cómo trabajar con formatos de recibos, consulte Configurar y diseñar formatos de recibos.

Especificar dimensiones de código QR en parámetros de Commerce

En la pestaña Parámetros de configuración de la página Parámetros de Commerce, agregue los siguientes parámetros de configuración:

  • QrCodeWidth : el ancho de la imagen del código QR, en píxeles. Especifique un valor adecuado para el parámetro.
  • QrCodeHeight : la altura de la imagen del código QR, en píxeles. Especifique un valor adecuado para el parámetro.

Nota

Es obligatorio especificar los valores de estos parámetros de configuración para imprimir códigos QR en los recibos. Es posible que en futuras actualizaciones se agregue compatibilidad con valores predeterminados de los parámetros.

Permitir extensiones CRT

Advertencia

Esta funcionalidad de localización no se puede utilizar con el nuevo modelo de empaquetado y extensión independiente ni con el kit de desarrollo de software (SDK) de Commerce. Debe utilizar la versión anterior de Retail SDK en una máquina virtual (VM) de desarrollador en Microsoft Dynamics Lifecycle Services (LCS). Para obtener información sobre las funciones de localización para Arabia Saudí disponibles en el SDK de Commerce, consulte Generar y enviar facturas electrónicas simplificadas para Arabia Saudí

Entorno de desarrollo

Seguir estos pasos para configurar un ambiente de desarrollo para que pueda probar y ampliar la funcionalidad de localización.

  1. Busque el archivo de configuración de la extensión para CRT:

    • Retail Server: el archivo se denomina commerceruntime.ext.config y se puede encontrar en la carpeta bin\ext en la ubicación del sitio de Retail Server Internet Information Services (IIS).
    • Local CRT en Modern POS: el archivo se denomina CommerceRuntime.MPOSOffline.Ext.config y se puede encontrar en la ubicación del agente de clientes local CRT .
  2. Registre el CRT cambio en el archivo de configuración de la extensión, como se muestra en el siguiente ejemplo.

    <add source="assembly" value="Microsoft.Dynamics.Commerce.Runtime.ReceiptsSaudiArabia" />
    <add source="assembly" value="Microsoft.Dynamics.Commerce.Runtime.ElectronicReporting" />
    

Entorno de producción

Siga estos pasos para crear paquetes desplegables que contengan componentes de Commerce y aplicar esos paquetes en un entorno de producción.

  1. En los archivos de configuración del paquete commerceruntime.ext.config y CommerceRuntime.MPOSOffline.Ext.config en la carpeta RetailSdk\Assets , agregue las siguientes líneas a la sección de composición .

    <add source="assembly" value="Microsoft.Dynamics.Commerce.Runtime.ReceiptsSaudiArabia" />
    <add source="assembly" value="Microsoft.Dynamics.Commerce.Runtime.ElectronicReporting" />
    
  2. Abra el símbolo del sistema de MSBuild para Visual Studio la utilidad y ejecute msbuild en la carpeta SDK de Retail para crear paquetes implementables.

  3. Aplique los paquetes a través de LCS o manualmente. Para obtener más información, consulte Crear paquetes implementables.

Al utilizar una impresora con el vínculo y la integración de objetos para Retail POS (OPOS), es posible que deba implementar personalizaciones adicionales para admitir los requisitos específicos de la impresora para la imagen del código QR. Por ejemplo, puede que tenga que convertir la imagen del código QR del formato PNG al formato BMP;. En esta sección se muestra un ejemplo de este tipo de personalización.

Nota

Este ejemplo de personalización se probó con la impresora EPSON TM-T88V OPOS. Es posible que tenga que modificarse para admitir diferentes marcas o modelos de impresoras.

Seguir estos pasos para crear una nueva extensión y agregarla a su ambiente.

  1. Instale el SDK de Retail. Para obtener más información, consulte Kit de desarrollo de software (SDK) de Retail.

  2. En el SDK de Retail, use el siguiente código, basado en su versión de Commerce, para crear un proyecto de C# en la solución CommerceRuntimeSamples.sln en RetailSdk\SampleExtensions\CommerceRuntime.

    <Project Sdk="Microsoft.NET.Sdk">
        <Import Project="..\..\..\BuildTools\Microsoft.Dynamics.RetailSdk.Build.props" />
        <Import Project="..\..\..\BuildTools\Common.props" />
        <Import Project="..\..\..\BuildTools\Microsoft.Dynamics.RetailSdk.Build.settings" />
    
        <PropertyGroup>
            <TargetFramework>netstandard2.0</TargetFramework>
            <AssemblyName>$(AssemblyNamePrefix).Commerce.Runtime.QrCodeExtension</AssemblyName>
            <RootNamespace>Contoso.Commerce.Runtime.QrCodeExtension</RootNamespace>
            <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
        </PropertyGroup>
    
        <Import Project="..\..\..\BuildTools\Microsoft.Dynamics.RetailSdk.Build.targets" />
    
        <ItemGroup>
            <PackageReference Include="Microsoft.Dynamics.Commerce.Runtime.Framework" Version="$(FrameworkRepoPackagesVersion)" />
            <PackageReference Include="Microsoft.Dynamics.Commerce.Runtime.Services.Messages" Version="$(ChannelRepoPackagesVersion)" />
            <PackageReference Include="System.Drawing.Common" Version="4.7.0" />
        </ItemGroup>
    
        <ItemGroup>
            <Reference Include="Microsoft.Dynamics.Commerce.Runtime.ElectronicReporting">
                <HintPath>..\..\..\..\..\nuget packages\microsoft.dynamics.commerce.runtime.electronicreporting.9.35.21321.4\lib\netstandard2.0\Microsoft.Dynamics.Commerce.Runtime.ElectronicReporting.dll</HintPath>
            </Reference>
        </ItemGroup>
    
        <ItemGroup>
            <Folder Include="Properties\" />
        </ItemGroup>
    </Project>
    

    También debe cambiar el valor del elemento HintPath para hacer referencia a Microsoft.Dynamics.Commerce.Runtime.ElectronicReporting.DLL biblioteca en la ubicación del sitio de IIS Retail Server.

  3. Utilice el siguiente código, según su versión de Commerce, para crear una clase de extensión.

    /**
     * SAMPLE CODE NOTICE
     * 
     * THIS SAMPLE CODE IS MADE AVAILABLE AS IS. MICROSOFT MAKES NO WARRANTIES, WHETHER EXPRESS OR IMPLIED,
     * OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OR CONDITIONS OF MERCHANTABILITY.
     * THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS SAMPLE CODE REMAINS WITH THE USER.
     * NO TECHNICAL SUPPORT IS PROVIDED. YOU MAY NOT DISTRIBUTE THIS CODE UNLESS YOU HAVE A LICENSE AGREEMENT WITH MICROSOFT THAT ALLOWS YOU TO DO SO.
     */
    
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    
    namespace Contoso
    {
        namespace Commerce.Runtime.QrCodeExtension
        {
            using System;
            using System.Collections.Generic;
            using System.Threading.Tasks;
            using Microsoft.Dynamics.Commerce.Runtime;
            using Microsoft.Dynamics.Commerce.Runtime.Messages;
            using Microsoft.Dynamics.Commerce.Runtime.Services.Messages;
    
            /// <summary>
            /// The extension for QR code printing.
            /// </summary>
            internal class QrCodeServiceExtension : IRequestHandlerAsync
            {
                /// <summary>
                /// Printer horizontal resolution for image.
                /// </summary>
                private const float PrinterXDpi = 60f;
    
                /// <summary>
                /// Printer vertical resolution for image.
                /// </summary>
                private const float PrinterYDpi = 90f;
    
                /// <summary>
                /// Printer pixel format for image.
                /// </summary>
                private const PixelFormat PrinterPixelFormat = PixelFormat.Format8bppIndexed;
    
                /// <summary>
                /// Gets the collection of supported request types by this service.
                /// </summary>
                public IEnumerable<Type> SupportedRequestTypes
                {
                    get => new[] {typeof(EncodeQrCodeServiceRequest)};
                }
    
                /// <summary>
                /// Processes the request.
                /// </summary>
                /// <param name="request">The request.</param>
                /// <returns>The response.</returns>
                public async Task<Response> Execute(Request request)
                {
                    ThrowIf.Null(request, nameof(request));
    
                    switch (request)
                    {
                        case EncodeQrCodeServiceRequest encodeQrCodeServiceRequest:
                        {
                            EncodeQrCodeServiceResponse nextResponse = await this.ExecuteNextAsync<EncodeQrCodeServiceResponse>(encodeQrCodeServiceRequest).ConfigureAwait(false);
    
                            if (nextResponse != null)
                            {
                                var qrCodeBmp = string.IsNullOrWhiteSpace(nextResponse.QRcode) ? nextResponse.QRcode : ConvertToGenericCompatibilityImage(nextResponse.QRcode);
                                return new EncodeQrCodeServiceResponse(qrCodeBmp);
                            }
    
                            return nextResponse;
                        }
                    }
    
                    return new NotHandledResponse();
                }
    
                /// <summary>
                /// Converts QR code image from any format to compatible with printer.
                /// </summary>
                /// <param name="base64data">Base64 image.</param>
                /// <returns>Image that Compatible with printer.</returns>
                private static string ConvertToGenericCompatibilityImage(string base64data)
                {
                    string convertedQrCode = base64data;
                    byte[] imageBytes = Convert.FromBase64String(convertedQrCode);
                    using (MemoryStream msOriginal = new MemoryStream(imageBytes))
                    using (MemoryStream msConverted = new MemoryStream())
                    {
                        var bitmapOriginal = new Bitmap(msOriginal);
                        if (!IsFormatCompatible(bitmapOriginal) || !AreResolutionAndPixelFormatCompatible(bitmapOriginal))
                        {
                            var bitmapConverted = bitmapOriginal;
    
                            if (!AreResolutionAndPixelFormatCompatible(bitmapOriginal))
                            {
                                var rectangle = new Rectangle(0, 0, bitmapOriginal.Width, bitmapOriginal.Height);
                                bitmapConverted = bitmapOriginal.Clone(rectangle, PrinterPixelFormat);
                                bitmapConverted.SetResolution(PrinterXDpi, PrinterYDpi);
                            }
    
                            bitmapConverted.Save(msConverted, ImageFormat.Bmp);
                        }
    
                        convertedQrCode = Convert.ToBase64String(msConverted.ToArray());
                    }
    
                    return convertedQrCode;
                }
    
                /// <summary>
                /// Verifies if the resolution and pixel format of bitmap are compatible with printer requirements.
                /// </summary>
                /// <param name="source">Bitmap.</param>
                /// <returns>True if compatible; otherwise false.</returns>
                private static bool AreResolutionAndPixelFormatCompatible(Bitmap source)
                {
                    return source.VerticalResolution == PrinterYDpi &&
                           source.HorizontalResolution == PrinterXDpi &&
                           source.PixelFormat == PrinterPixelFormat;
                }
    
                /// <summary>
                /// Verifies if the format of bitmap is compatible with printer requirements.
                /// </summary>
                /// <param name="source">Bitmap.</param>
                /// <returns>True if compatible; otherwise false.</returns>
                private static bool IsFormatCompatible(Bitmap source)
                {
                    return source.RawFormat.Equals(ImageFormat.Bmp);
                }
            }
        }
    }
    
  4. En los archivos de configuración commerceruntime.ext.config y CommerceRuntime.MPOSOffline.Ext.config en la carpeta RetailSdk\Assets , agregue las siguientes líneas a la sección de composición .

    <add source="assembly" value="Contoso.Commerce.Runtime.QrCodeExtension" />
    <add source="assembly" value="Microsoft.Dynamics.Commerce.Runtime.ReceiptsSaudiArabia" />
    <add source="assembly" value="Microsoft.Dynamics.Commerce.Runtime.ElectronicReporting" />
    
  5. En el archivo de configuración de personalización del paquete Customization.settings en la carpeta BuildTools , agregue las siguientes líneas para incluir las extensiones en los CRT paquetes implementables.

    <ISV_CommerceRuntime_CustomizableFile Include="$(SdkReferencesPath)\Contoso.Commerce.Runtime.QrCodeExtension.dll" />
    
  6. Inicie el símbolo del sistema de MSBuild para la utilidad Visual Studio y ejecute msbuild en la carpeta Retail SDK para crear paquetes implementables.

  7. Aplique los paquetes a través de LCS o manualmente. Para obtener más información, consulte Crear paquetes implementables.