Introducción
La palabra clave protected en C# permite el acceso a sus propiedades y métodos desde dentro de la clase y clases derivadas. Usted establecería propiedades públicas para permitir el acceso desde otras funciones. Esta es una práctica estándar para forzar el uso de funciones y propiedades específicas que deben ser utilizadas y evitar que los métodos internos sean llamados.
Típicamente en Acumatica, tenemos métodos públicos que pueden ser llamados desde otros gráficos que requieren enviar un caché, o tener un objeto enviado como parámetro para realizar una o muchas acciones sobre él. Un método protegido típico en un gráfico es algo que se llama en el objeto actual que se establece. Por ejemplo, SOShipmentEntry tiene una función protegida SyncShipDateWithLinks. Esta función recorre el registro de envío actual en la caché y actualiza la fecha de envío en el registro SOOrderShipment vinculado. Esta función no debe ser llamada fuera del gráfico, razón por la cual está marcada como protegida.
Extensiones de gráficos
Al hacer una extensión del gráfico, es posible que necesitemos acceder, o incluso anular estas propiedades y métodos. Sería dentro del mismo gráfico, por lo que el uso de estos métodos protegidos tendría sentido lógico. El problema es que no se puede acceder a ellos a través de la Base de la extensión, porque están protegidos. Aquí es donde PXProtectedAccess entra en juego.
El primer ejemplo sería acceder a una propiedad protegida en la pantalla SOOrderEntry. Tengo un proceso que desencadenará un comando personalizado CopyOrder. Esta propiedad tiene un get público, pero un set protegido. El único lugar donde esta propiedad se establece es durante la acción CopyOrder.
Hay dos formas de acceder a la propiedad.
La primera forma sería crear una extensión abstracta del grafo de acceso protegido, y declarar las propiedades protegidas como abstractas y públicas. Esto anularía el ámbito del grafo inicial. A partir de ahí, extenderías ese grafo, y serías capaz de usar la propiedad.
GIST: https://gist.github.com/kjrichardson/698684c2c1806fdd437abb7dd457627a
Como puedes ver, estamos extendiendo tanto el gráfico principal como la extensión. Base1 llamaría a la extensión, que tiene el setter IsCopyOrder establecido a public. Esto nos permitiría ejecutar nuestra función personalizada de orden de copia sin tener que llamar a la acción que establece esa propiedad desde el gráfico SOOrderEntry.
La otra forma en que podríamos lograr esto sería con una sola clase. Realizaríamos todo el código en una única clase abstracta. Ambos métodos funcionan en la versión actual de Acumatica.
GIST: https://gist.github.com/kjrichardson/04642c509aa3849b1fafeafd8ecaf56f
Sobreescritura de funciones protegidas
A continuación, veremos cómo anular una función protegida. Los manejadores de eventos normales le permiten hacer esto sin tener que utilizar el acceso protegido, pero a veces es posible que tenga que anular la funcionalidad adicional que no está controlada por eventos. Una función que tuve que sobreescribir fue la función LinkPOLineToSOLineSplit en el gráfico POCreate. Necesitaba vincular la información de la orden de venta a la línea de la orden de compra cuando estaba vinculada. Los manejadores de eventos para la actualización de estos campos o DACs no se disparaban, por lo que anular la función que lo establecía era el siguiente paso. Al hacer un override típico, se obtendrían los siguientes errores:
Para crear un override, debe tener dos funciones. La extensión de primer nivel tendría su código PXOverride que sería llamado. Si te detuvieras aquí, obtendrías fallos de acceso. El segundo paso sería crear una extensión ProtectedAccess que extienda tanto el grafo base, como la extensión del grafo que tiene tu override.
GIST: https://gist.github.com/kjrichardson/e5e8b7d2656fa66617e0cb301defebe1
Nota, el delegado y el método etiquetado con PXOverride deben establecerse como públicos. Esto permite a la extensión gráfica secundaria acceder a la función anulada y la vincula con el acceso protegido.
Resumen
A veces, conectarse a un evento mediante FieldUpdated, RowUpdated u otro evento estándar no es suficiente. A veces, el código se introduce en eventos protegidos. A veces este método es beneficioso por razones de rendimiento, ya que sólo necesita atrapar el evento protegido y no ejecutar lógica cada vez que se actualiza otro campo o fila. Me alegra que Acumatica haya agregado esta funcionalidad en 2020 R1 y he encontrado muchos beneficios al usarla, ¡y espero que usted también lo haga!
¡Feliz codificación!