NOT a lost cause - a function for new labor dtl with no code

@SimsTrak

Again, not trying to rehash this, but you do a trace, there are objects. You do widgets, and you interact with the objects. But code is a geek saying, “Oh I know I’ll just do this ‘Usings’ and Reference and Adapter.”

Like, there is no correlation between thing happening and code written.

And you know, some people like washing dishes by hand. I use the dishwasher.

It’s cool.

I disagree, the code is doing exactly what the trace is doing (assuming you follow the trace … which you should), you are literally invoking the same objects. The widget by the way is doing the exact same thing too it just generates that code for you (most of the time less efficiently) but in the end it is still the same code happening.

Benefit of widgets is solely upgradeability IMO (which is a good benefit)

However complexity swings that pendulum around, the second you have to “hack around” the widgets to get them to work correctly it swings hard the other direction.

Also when the widgets get so complex (too many of them etc) it becomes less readable / harder to maintain and understand.

2 Likes

Again, the use case… upgradeability is different for everyone and maybe upgrading custom code isn’t a big deal for some and maybe for others it is.

It all depends!

I still don’t know how to write the proper code, but now that I can look at what is being generated from the widgets (thanks @hkeric.wci) I should be able to get started.

For me I would write custom code if I was sure that I was doing it correctly. For now I have to use widgets because I am not 100% proficient.

1 Like

@josecgomez I’m not seeing how this is in the trace. There’s not a row in any of these BPM sources that I would have gathered from the trace.

All / Most of this is framework related nonsense it has nothing to do with the trace

1 Like

I guess to try to see it your way, I need to pull the source of an EFx - which apparently I have to change the web.config to do that, so that’s for another day.

But I have to say right now I am not seeing the path to learning code here. I see nothing remotely intuitive - and I’m not exactly new to Epicor.

1 Like

Well, instead of the web.config, I just copied the EFx widgets (see pic earlier today) into a Method Directive, which apparently is a thing you can do…

So here is what I got for code:

Expand if you dare
using Epicor.Data;
using Epicor.Hosting;
using Epicor.Utilities;
using Erp.Contracts;
using Erp.Tables;
using Erp.Tablesets;
using Ice;
using Ice.Contracts;
using Ice.ExtendedData;
using Ice.Tables;
using Ice.Tablesets;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.ServiceModel;

namespace Epicor.Customization.Bpm.BO244CB901FD9E4BABB2EBCF6DCE65EF74
{
    internal sealed class ChangePCIDPreProcessingDirective_TestForJose_7A0FBC59A24944C3BCF9141E84D236FE : ChangePCIDDirectiveBase
    {
        #region Local variables

        private System.Guid EmptyGUID;

        private System.String EmptyStr;

        private System.Boolean boolFalse;

        private Erp.Tablesets.InvTransferTableset dsXfer;

        private System.String PartNumber;

        private System.String FromWhse;

        private System.String FromBin;

        private System.String ToWhse;

        private System.String ToBin;

        private System.Decimal Qty;

        #endregion // Local variables

        public ChangePCIDPreProcessingDirective_TestForJose_7A0FBC59A24944C3BCF9141E84D236FE(ChangePCIDImpl owner, Erp.ErpContext ctx, Epicor.Hosting.Session session)
            : base(
                owner,
                ctx,
                session,
                new Epicor.Customization.Bpm.DirectiveDescription
                {
                    Id = new Guid("7a0fbc59-a249-44c3-bcf9-141e84d236fe"),
                    Name = "TestForJose",
                    Type = Ice.BO.BpMethod.MethodDirectiveType.PreProcessing,
                    TypeName = "PreProcessing",
                    VisibilityScope = Ice.BO.BpMethod.DirectiveScope.CompanySpecific,
                    Company = "29632",
                    TenantId = null,
                })
        {
        }

        protected override void InitializeLocalVariables(bool preparation)
        {
            this.EmptyGUID = default(System.Guid);
            this.EmptyStr = default(System.String);
            this.boolFalse = default(System.Boolean);
            this.dsXfer = TablesetFactory.Create<Erp.Tablesets.InvTransferTableset>();
            this.PartNumber = default(System.String);
            this.FromWhse = default(System.String);
            this.FromBin = default(System.String);
            this.ToWhse = default(System.String);
            this.ToBin = default(System.String);
            this.Qty = default(System.Decimal);
        }

        protected override void TeardownLocalVariables()
        {
            this.EmptyGUID = default(System.Guid);
            this.EmptyStr = default(System.String);
            this.boolFalse = default(System.Boolean);
            this.dsXfer = null;
            this.PartNumber = default(System.String);
            this.FromWhse = default(System.String);
            this.FromBin = default(System.String);
            this.ToWhse = default(System.String);
            this.ToBin = default(System.String);
            this.Qty = default(System.Decimal);
        }

        protected override bool ExecuteCore()
        {
            var conditionBlockValue = false;

            if (this.BpmFormJump != null)
            {
                if (this.BpmFormJump.JumpToActionId == "e0b42487-c308-462c-b574-bae23e256a68") goto block003;
                if (this.BpmFormJump.JumpToActionId == "a9c60f9c-5bc9-41c8-b260-5c8f586dac7d") goto block004;
                if (this.BpmFormJump.JumpToActionId == "ed09756c-f47c-4178-aa9c-d5ac76b60c57") goto block005;
                if (this.BpmFormJump.JumpToActionId == "27fc1173-a7c8-4448-8396-c6f08de72476") goto block006;
                if (this.BpmFormJump.JumpToActionId == "547b9f71-34aa-41a8-8585-66d4e9567306") goto block007;
                if (this.BpmFormJump.JumpToActionId == "7c8c5913-30aa-476e-b1f0-15cf0a31160e") goto block008;
                if (this.BpmFormJump.JumpToActionId == "094d8f4b-d7de-4dbb-bde6-fd4273ee256e") goto block009;
                if (this.BpmFormJump.JumpToActionId == "f3291100-2389-40a4-9f97-93e171112570") goto block010;
                if (this.BpmFormJump.JumpToActionId == "498366bd-af2a-4dd2-b89c-7f9e05efa81a") goto block011;
                if (this.BpmFormJump.JumpToActionId == "a84db42a-1266-46af-99f5-9c8359fd2edd") goto block012;
                if (this.BpmFormJump.JumpToActionId == "0aee559f-635a-44f7-bcbe-a0693f74c1c8") goto block013;
                if (this.BpmFormJump.JumpToActionId == "8450bf81-73cc-4482-9501-a985750bf327") goto block014;
                if (this.BpmFormJump.JumpToActionId == "3964dd70-128b-4fd8-ba3c-35d7ed96c7e2") goto block015;
                if (this.BpmFormJump.JumpToActionId == "a4d045f4-ae78-4a2f-a50d-3b7ed6e3d92d") goto block016;
                if (this.BpmFormJump.JumpToActionId == "47a49b7a-cef5-456b-9a09-3858664e3413") goto block017;
                throw new Ice.Common.BusinessObjectException("Unexpected BpmForm jump block");
            }

start: // Name = "Empty GUID 1", Id = "4a5ea0c7-2230-4c32-8932-b39c5d710a7c"
            this.UseDataFilter = true;
            try
            {
                this.A001_SetArgumentAction();
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block001: // Name = "Empty String 1", Id = "17f98058-2d71-4684-9fe6-3606654ac6e3"
            this.UseDataFilter = true;
            try
            {
                this.A002_SetArgumentAction();
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block002: // Name = "False 1", Id = "59e64956-6ea8-4525-a4e5-888a37b5d4af"
            this.UseDataFilter = true;
            try
            {
                this.A003_SetArgumentAction();
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block003: // Name = "GetTransferRecord 1", Id = "e0b42487-c308-462c-b574-bae23e256a68"
            this.UseDataFilter = true;
            try
            {
                this.A004_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("e0b42487-c308-462c-b574-bae23e256a68");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block004: // Name = "Qty Row Mod 1", Id = "a9c60f9c-5bc9-41c8-b260-5c8f586dac7d"
            this.UseDataFilter = false;
            try
            {
                this.A005_CustomCodeAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("a9c60f9c-5bc9-41c8-b260-5c8f586dac7d");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: true);

block005: // Name = "ChangeTransferQty 1", Id = "ed09756c-f47c-4178-aa9c-d5ac76b60c57"
            this.UseDataFilter = true;
            try
            {
                this.A006_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("ed09756c-f47c-4178-aa9c-d5ac76b60c57");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block006: // Name = "From Whse RowMod 1", Id = "27fc1173-a7c8-4448-8396-c6f08de72476"
            this.UseDataFilter = false;
            try
            {
                this.A007_CustomCodeAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("27fc1173-a7c8-4448-8396-c6f08de72476");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: true);

block007: // Name = "ChangeFromWhse 1", Id = "547b9f71-34aa-41a8-8585-66d4e9567306"
            this.UseDataFilter = true;
            try
            {
                this.A008_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("547b9f71-34aa-41a8-8585-66d4e9567306");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block008: // Name = "From Bin RowMod 1", Id = "7c8c5913-30aa-476e-b1f0-15cf0a31160e"
            this.UseDataFilter = false;
            try
            {
                this.A009_CustomCodeAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("7c8c5913-30aa-476e-b1f0-15cf0a31160e");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: true);

block009: // Name = "ChangeFromBin 1", Id = "094d8f4b-d7de-4dbb-bde6-fd4273ee256e"
            this.UseDataFilter = true;
            try
            {
                this.A010_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("094d8f4b-d7de-4dbb-bde6-fd4273ee256e");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block010: // Name = "To Whse RowMod 1", Id = "f3291100-2389-40a4-9f97-93e171112570"
            this.UseDataFilter = false;
            try
            {
                this.A011_CustomCodeAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("f3291100-2389-40a4-9f97-93e171112570");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: true);

block011: // Name = "ChangeToWhse 1", Id = "498366bd-af2a-4dd2-b89c-7f9e05efa81a"
            this.UseDataFilter = true;
            try
            {
                this.A012_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("498366bd-af2a-4dd2-b89c-7f9e05efa81a");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block012: // Name = "To Bin Row Mod 1", Id = "a84db42a-1266-46af-99f5-9c8359fd2edd"
            this.UseDataFilter = false;
            try
            {
                this.A013_CustomCodeAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("a84db42a-1266-46af-99f5-9c8359fd2edd");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: true);

block013: // Name = "ChangeToBin 1", Id = "0aee559f-635a-44f7-bcbe-a0693f74c1c8"
            this.UseDataFilter = true;
            try
            {
                this.A014_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("0aee559f-635a-44f7-bcbe-a0693f74c1c8");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block014: // Name = "MasterInvBinTests 1", Id = "8450bf81-73cc-4482-9501-a985750bf327"
            this.UseDataFilter = true;
            try
            {
                this.A015_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("8450bf81-73cc-4482-9501-a985750bf327");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block015: // Name = "PreCommitTransfer 1", Id = "3964dd70-128b-4fd8-ba3c-35d7ed96c7e2"
            this.UseDataFilter = true;
            try
            {
                this.A016_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("3964dd70-128b-4fd8-ba3c-35d7ed96c7e2");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

block016: // Name = "Commit Row Mod 1", Id = "a4d045f4-ae78-4a2f-a50d-3b7ed6e3d92d"
            this.UseDataFilter = false;
            try
            {
                this.A017_CustomCodeAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("a4d045f4-ae78-4a2f-a50d-3b7ed6e3d92d");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: true);

block017: // Name = "CommitTransfer 1", Id = "47a49b7a-cef5-456b-9a09-3858664e3413"
            this.UseDataFilter = true;
            try
            {
                this.A018_InvokeBOMethodAction();
                if (this.BpmDataFormIsPublished())
                {
                    this.BpmDataFormSerializeInterimPoint("47a49b7a-cef5-456b-9a09-3858664e3413");
                    return false;
                }
            }
            catch (Ice.Common.BusinessObjectException ex)
            {
                this.RememberException(ex);
            }
            this.RefreshData(matched: false);

finish:
            return true;
        }

        private void A001_SetArgumentAction()
        {
            this.EmptyGUID = (Guid.NewGuid());
        }

        private void A002_SetArgumentAction()
        {
            this.EmptyStr = ("");
        }

        private void A003_SetArgumentAction()
        {
            this.boolFalse = (false);
        }

        private void A004_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                bo.GetTransferRecord(
                    this.PartNumber,
                    this.EmptyGUID,
                    this.EmptyStr,
                    this.EmptyStr,
                    out this.boolFalse,
                    ref this.dsXfer);
            }
        }

        private void A005_CustomCodeAction()
        {
            dsXfer.InvTrans[0].RowMod= "U";
        }

        private void A006_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                bo.ChangeTransferQty(
                    this.Qty,
                    ref this.dsXfer);
            }
        }

        private void A007_CustomCodeAction()
        {
            dsXfer.InvTrans[0].RowMod= "U";
        }

        private void A008_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                bo.ChangeFromWhse(
                    this.FromWhse,
                    ref this.dsXfer);
            }
        }

        private void A009_CustomCodeAction()
        {
            dsXfer.InvTrans[0].RowMod= "U";
        }

        private void A010_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                bo.ChangeFromBin(
                    this.FromBin,
                    ref this.dsXfer);
            }
        }

        private void A011_CustomCodeAction()
        {
            dsXfer.InvTrans[0].RowMod= "U";
        }

        private void A012_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                bo.ChangeToWhse(
                    this.ToWhse,
                    ref this.dsXfer);
            }
        }

        private void A013_CustomCodeAction()
        {
            dsXfer.InvTrans[0].RowMod= "U";
        }

        private void A014_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                bo.ChangeToBin(
                    this.ToBin,
                    ref this.dsXfer);
            }
        }

        private void A015_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                System.String arg02;
                System.String arg03;
                System.String arg04;
                System.String arg05;
                System.String arg06;
                System.String arg07;
        
                bo.MasterInventoryBinTests(
                    ref this.dsXfer,
                    out arg02,
                    out arg03,
                    out arg04,
                    out arg05,
                    out arg06,
                    out arg07);
            }
        }

        private void A016_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                bo.PreCommitTransfer(
                    ref this.dsXfer,
                    out this.boolFalse);
            }
        }

        private void A017_CustomCodeAction()
        {
            dsXfer.InvTrans[0].RowMod= "U";
        }

        private void A018_InvokeBOMethodAction()
        {
            var bo = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.InvTransferSvcContract>(this.Db);
            if (bo == null)
            {
                throw new Ice.Common.EpicorServerException("Can't resolve instance of 'Erp:BO:InvTransfer' service.");
            }
        
            using (bo)
            {
                System.String arg02;
                System.String arg03;
        
                bo.CommitTransfer(
                    ref this.dsXfer,
                    out arg02,
                    out arg03);
            }
        }

        protected override void StoreVariables(Epicor.Customization.Bpm.ISerializationBufferBuilder builder)
        {
            builder
                .AddVariable("EmptyGUID", this.EmptyGUID)
                .AddVariable("EmptyStr", this.EmptyStr)
                .AddVariable("boolFalse", this.boolFalse)
                .AddVariable("dsXfer", this.dsXfer)
                .AddVariable("PartNumber", this.PartNumber)
                .AddVariable("FromWhse", this.FromWhse)
                .AddVariable("FromBin", this.FromBin)
                .AddVariable("ToWhse", this.ToWhse)
                .AddVariable("ToBin", this.ToBin)
                .AddVariable("Qty", this.Qty);
        }

        protected override void BpmDataFormRestoreVariables(IReadOnlyDictionary<string, object> variables)
        {
            this.VerifyNumberOfStoredVariables(10, variables.Count);

            this.EmptyGUID = this.GetStoredValue<System.Guid>(variables, "EmptyGUID");
            this.EmptyStr = this.GetStoredValue<System.String>(variables, "EmptyStr");
            this.boolFalse = this.GetStoredValue<System.Boolean>(variables, "boolFalse");
            this.dsXfer = this.GetStoredValue<Erp.Tablesets.InvTransferTableset>(variables, "dsXfer");
            this.PartNumber = this.GetStoredValue<System.String>(variables, "PartNumber");
            this.FromWhse = this.GetStoredValue<System.String>(variables, "FromWhse");
            this.FromBin = this.GetStoredValue<System.String>(variables, "FromBin");
            this.ToWhse = this.GetStoredValue<System.String>(variables, "ToWhse");
            this.ToBin = this.GetStoredValue<System.String>(variables, "ToBin");
            this.Qty = this.GetStoredValue<System.Decimal>(variables, "Qty");
        }
    }
}

Again, I cannot see the connection to the trace of an inventory transfer or why that would lead me to Ice.Assemblies.ServiceRenderer.GetService etc.

It is doing the same logic but since the code is generated, it follows a generic theme. The ServiceRenderer method can call any service, otherwise, Epicor would have a big ole case statement:


when “Bo.Erp.InvTransfer”

If you look at where it says, bo., you can pick out the method calls for that object.

                bo.GetTransferRecord(
                    this.PartNumber,
                    this.EmptyGUID,
                    this.EmptyStr,
                    this.EmptyStr,
                    out this.boolFalse,
                    ref this.dsXfer);

The rest of it is just just control flow.

However, I’m going to land in the middle here. Putting all code in a code block is putting business logic too deep in the implementation. I think all widgets can get unwieldy and hide the logic. Maybe there’s a happy middle? Maybe putting common code elements into functions so the business logic can be expressed in fewer widgets and keep the code duplication to a minimum. Just a thought.

1 Like

@Mark_Wonsil I think we (all) are maybe arguing from two different perspectives.

What I see is that most of you on this thread already know how to code a BPM and are defending it, and maybe because you think I am trying to say “code is stupid or bad” or something.

Maybe what is not clear is that I am stupider than all of you and I don’t get this coding nonsense. I’m not trying to get you to change. I want you all to see that I can’t.

Yes, you all won’t change and neither will I, and we knew that at the start.

But I just don’t think you all understand that there is no path forward from “I don’t get this” to “Oh, I forgot the service renderer!”

Like, I have reverse engineered code in my life. I make macros in VBA. I can make an EFx with widgets. Those have a translation from “thing I want to do” to “code to accomplish it,” and I can do that by observing other code.

But this C# nonsense, naw, man.

Like, you all try to brush it aside with

or

But if this extra stuff is necessary to get the BPM/EFx to run, it’s not so simple as “Oh well, yeah there is a bunch of other non-intuitive stuff you need to add in there and it’s not documented anywhere.” This is the exact problem.

Or I guess maybe it is a tad intuitive if you already know C# inside and out?

But that’s not really a reasonable thing to ask of everyone as a prerequisite.

Anyway, :heart: all of you and I’m off my soapbox for the morning.

2 Likes

Actually, I’m a widget person. :person_shrugging: Love you too! :kissing:

1 Like