Kinetic Code Camp - Bring your skills, or lack thereof.. :dumpster_fire:

Can’t do that one, no knowledge. I did our one for Vantage way back but nothing in modern epicor.

2 Likes

Star Trek Ideas GIF by Goldmaster

Still needed, work and side work breaking my brain. Need distraction.

1 Like

Manipulating Datasets and DataTables … can we add/remove tables? can we add/remove rows? remove/add columns? can we sort rows - and if we can, is order preserved?
:face_with_spiral_eyes:

1 Like

Coupling and Cohesion

We don’t talk about this here directly, but it applies to much of the customization work we do. Here’s a quick video that explains it well. It’s less than 14 minutes for those weird people who listen at full speed.

Video:Coupling and Cohesion - Derek Comartin

Coupling

Briefly, processes can be tightly or loosely coupled. In a tightly coupled system, each process has to know a lot about the internals of the service being called. For example, when we call an Epicor REST end point for a business object, we might need to know about the RowMod property. This is tightly coupled. If I call an Epicor Function and pass it just data and the function calls the business object on our behalf, it hides those implementation details. This coupling is looser. If I use a local .DLL to interact with Kinetic, that is really highly coupled since I also have to match the version with the server. If I create my own REST API that interfaces with an Epicor Function, that coupling is looser.

In general, highly coupled systems are harder to test and more difficult to change as the requirements or environment changes.

Cohesion

On the other hand, we have cohesion. This is the measure of how well the elements of some module all work toward solving a single task. My favorite example of cohesion is with notifications. If I have a BPM or Function whose primary task is to validate a record, then all of the code should be related to checking that record. If it does, that code has high functional cohesion. Now, let’s say we want to be notified when the record is not valid. Because most of us grew up with AOL, the only possible way there is to notify someone is by email - sorry Gen Z and Gen Alpha. If we add code that directly calls the SMTP server to send an email notification, this code has low cohesion. Sending mail is NOT the primary task of the validation routine.

Instead, we can set a status on the record. A trigger then calls a service whose primary task is to notify when the status contains the value “FAILED.” This keeps the details of sending emails out of our validation code. It does even more than that. It promotes code reuse so there is only one notification service to maintain, and other triggers can use this service too. It also promotes the ability to notify users in a way they want to be notified: text, Slack/Teams, mobile app, Help Desk Ticket, Planner Task, or yes, even an email. (:nauseated_face:)

As Derek mentions in the video, often these goals pull us in different directions. While highly coupled solutions work at first, they are difficult to test, maintain, and adapt. High cohesion solutions also work but can lead to systems with more moving pieces. It takes time and context to find the right balance.

BTW, Derek has many other great videos related to architecture and design, and I highly recommend them.

4 Likes

I’m those people, except in those cases where it’s excruciatingly slow. Of course the one I’m thinking of atm is more over-thorough than slow, but the content is so good. I want to cry sometimes lol.

But anyway, this will make a nice addition. Thanks Mark.

2 Likes

Some more video resources:

DavesGarage Content Rating: A+ / Pacing: A+ Former Microsoft Dev / More than Programming
IAmTimCorey Content Rating: A / Pacing: D !
nickchapsas Content Rating: A+ / Pacing: A
BaldBeardedBuilder Content Rating: A / Pacing: A (Just started watching)
Fireship Content Rating: B+ / Pacing: A (Lots of shorter snippets)
NDC Conferences Content Rating: Varies / Pacing: Varies (Lots of good stuff)
The Coding Sloth Content Rating: A / Pacing: A (He’s funny)
Computerphile Content Rating: A+ / Pacing: Varies (Various)
Thriving Technologist Content Rating: Evaluating / Pacing: A (So far so good)
AMantinband Content Rating: A+ Pacing: A (Has odd inflections in accent… :rofl: )

2 Likes

Ooooh, nice list. Similar to NDC, there is also the GOTO; Conferences:

Goto; Conferences Content Rating: Varies / Pacing: Varies (Lots of good stuff)
Programming with Palermo Jeffry Palermo, good content and pacing. Creator of the Onion architecture

Can we add PodCasts?

EpiUsers Mostly smart guests
.NET Rocks Carl Franklin and Richard Campbell talk .NET
Hanselminutes Scott Hanselman’s long time podcast. Great stuff.
Azure DevOps Jeffrey Palermo on DevOps procedures and not just the Microsoft product
Microsoft Azure Content Rating: varies | Pacing: varies - Azure Friday is quite good.
Microsoft Developer All the codie things from Visual Studio, to 365, to CoPilot
Breakpoint Show Newish but promising. Chris Woodruff, Khalid Abuhakmeh, Maarten Baliauw. Definitely for coders.
Google Cloud Security Podcast Anton Chuvakin and Timothy Peacock
Directions on Microsoft MaryJo Foley talks Microsoft Product Strategy and Licensing
The Intrazone M365 topics with Mark Kashman
Legacy Code Rocks Giving love to legacy code
Packet Pusher Podcasts All things networking from IPv6 to Security.
M365 Developer Podcast It’s in the name
Microsoft Threat Intelligence Podcast Sherrod DeGrippo shares info from the MS Threat Intel team
Risky.biz podcasts Best Security podcasts IMHO
RunAs Radio Richard Campbell talking all things IT Adminsitration
SANS Daily StormCast Short daily recap of current threats found by the SANS honeypots with Johannes Ullrich
Security Now Longest running Security podcast with Steve Gibson and Leo Laporte.
Smashing Security Easy to consume security podcast
Windows Weekly Paul Thurrott, Richard Campbell, and Leo Laporte. Old men bitching about Microsoft for long periods of time - so I like it.

And yes, as an empty-nester, I listen to all of these.

2 Likes

You can add pictures of your feet, as long as it is helpful or funny.

1 Like

Oooh, forgot about that one.

1 Like

Save those for OnlyFans

1 Like

Wiki updated

1 Like

Har har har, I know why you said that.

3 Likes

(All this was done in notepad with little coffee, please point out any mistakes…)

Conditionals

Conditionals are used to control program flow.

Since we are teaching C#, I will show the common C# conditionals, but these
apply to all programming languages, at least in concept.

These are mostly self explanatory, but I will expand on them all.

IF

An if statement checks a condition. If (pun intended) that condition evaluates to true, then the next associated code block or statement will execute.

string name  = "Kevin"; //Assign a name

if(name == "Kevin") //Check a condition
{//This is a code block, and it will execute if the above condition is true.
    MessageBox.Show("Awesome");
}

Output

Awesome
string name  = "Kevin"; //Assign a name

//Check a condition
if(name == "Kevin") MessageBox.Show("Awesome"); //This is also valid, but this executes the next statement only up to the semicolon.

//The next statement is not part of the "if" above.
Console.WriteLine(name + " is a smoking monkey.");

Output

Awesome
Kevin is a smoking monkey. 

IF-ELSE

A little more complicated, but not by much.
An if-else statement checks a condition. If that condition evaluates to true, then the next associated code block or statement will execute, if it evaluates to false, then the associated code block or statement after the “else” will execute.

string name  = "Kevin V"; //Assign a name

if(name == "Kevin") //Check a condition
{//This is a code block, and it will execute if the above condition is true.
    MessageBox.Show("Awesome");
}
else
{//This is a code block, and it will execute if the first condition (the if condition) is false.
    MessageBox.Show(name + " - The jury is still out.");
}

Output

Kevin V - The jury is still out.

Ladder Type IF-ELSE
Hmmm, how to explain this? Maybe just show you…

string name  = "Mark"; //Assign a name

if(name == "Kevin") //Check a condition
{//This is a code block, and it will execute if the above condition is true.
    MessageBox.Show(name + " - Awesome, but easily distracted.");
}
else if(name == "Jose") //Check another condition
{//This is a code block, and it will execute if the above condition is true.
    MessageBox.Show(name + " - Awesome as well, has a tldr issue.");
}
else if(name == "Mark") //Check another condition
{//This is a code block, and it will execute if the above condition is true.
    MessageBox.Show(name + " - Awesome, but a huge corndog.");
}
else //None of the above were true so... execute the following code block:
{
    MessageBox.Show("Who am I kidding, you are all awesome.");
}

Output

Mark - Awesome, but a huge corndog.

SWITCH
Ahh, good old select-case :wink:
This is what you use when you need to test a lot of different values (“cases”) against a single condition / expression.

Now switch has a few rules to remember.

  • The data types of what you are checking and the case must be the same.
  • Case values must be a constant, can’t use a variable.
  • No duplicates. (Including default)
  • The “default” case is optional.
  • “break” is used to terminate a “case”.
  • You can use multiple case statements, and “fall through” to a code block or statement.

Here is an example:

string name  = "Bryan"; //Assign a name

switch(name) //We will be checking the name variable..
{
    case "Brandon": //"Brandon" is a constant string, and constantly cranky, but that's ok.
        //This will execute if "name" is "Brandon".
        Console.WriteLine(name + " - Wore thicker soled shoes so he could be taller than me");
        break; //This is the end of this case statement.

    case "Hannah":
        //This will execute if "name" is "Hannah".
        Console.WriteLine("Was missed at Insights 2024.");
        break; //This is the end of this case statement.

    case "Simon":
    case "Bryan": //We'll enter here, and fall on through
    case "Haso":
        //This will execute if "name" is "Simon", "Bryan", or "Haso"
        Console.WriteLine(name + " - I can't think of anything funny at the moment.");
        break; //This is the end of this case statement.

    default: //Optional catch all... This will execute if everything else fails
        Console.WriteLine( "Sorry, I can't put EVERYONE in the examples, but I'll try ;)" );
        break; //This is the end of this default statement.
}

Output

Bryan - I can't think of anything funny at the moment.

Also notice the colon beside the “case”… Yep, see that do ya? a case statement is a label
Which means, you can alter the logic with “goto:”

Usually that is done by replacing the “break” statement with “goto”.
Most often used when you want to execute the “default” statement AND the “case” statement.

List<string> names = new List<string>(){"Mike", "Greg"}; //Make a list of names

foreach(string name in names)
{
    switch(name) //We will be checking the name variable..
    {
        case "Mike":
            Console.WriteLine(name + " - Cannot be tamed.");
            goto default:

        case "Evan":
            Console.WriteLine(name + " - Has very long private messages..");
            goto default:

        case "Greg":
            Console.WriteLine(name + " - Knows way more than me.");
            goto case "Woot": //I jumped to a "case"

        case "Woot":
            Console.WriteLine(name + " - This will execute also if the name is Greg... or 'Woot' obviously.."); //Why, no idea, but you can..
            goto default:


        default: //In this case, this will always run..
            Console.WriteLine( "I like to make silly examples.." );
            break; //This is the end of this default statement.
    }
}

Output

Mike - Cannot be tamed.
I like to make silly examples..

Greg - Knows way more than me.
Greg - This will execute also if the name is Greg... or 'Woot' obviously..
I like to make silly examples..


Nesting…
All of these can be nested, so you can have conditionals inside conditionals:slight_smile:

Mtv Television GIF by Animation Domination High-Def

Simple Example, IF, with a NESTED IF-ELSE:

string name  = "Chris"; //Assign a name

if(name.StartsWith("C"))
{
    if(name == "Chris")
    {
        Console.WriteLine(name + " - Likes to make 'interesting' music...");
    }
    else Console.WriteLine("Insert poop joke?"); //Notice, just a statement, no code block... This is valid. Recommmended ? Ahh depends, subjective, just make sure it's clear.
}

Output

Chris - Likes to make 'interesting' music...

I’m not doing a NESTED SWITCH, they look ridiculous, but can be done :rofl:


Thus concludeth todayeth metthage, it ith knowenth.

Mike Tyson Smile GIFgame of thrones khaleesi GIF

7 Likes

Ok two things.

1

New content added, Conditionals, right above this post, and wiki updated.

2

Discussion Question →

I was asked to do a post on functions, so I am going to attempt it, however there are already two very good ones on the topic:

So I reached out to Mark and others, to see what he thought I should cover.

His response was as follows:


Which helped quite a bit, and now I have a few ideas, but then I figured, if I’m going to go in-depth, I should probably ask the community too…

So first, I suggest you guys read those threads linked if you haven’t already, and then I’m asking what you would like to see in a “Epicor Functions” thread / post.

  • What is missing ?
  • What is unclear ?
  • Can be technical
  • Can be procedural
  • Can be theoretical
  • Can post recipes for smoking meats
  • Etc

What say the wise?

Help Me Monday GIF by Foo Fighters

3 Likes

I’ll be back to re-:dumpster_fire: the Lamba discussion at some point. I started that a week before an upgrade here, and then we rolled straight into fiscal-year-end prep/panic.

3 Likes

Last type: Ternary operators, which are if/then/else statements in a single line which are mainly used to assign values to variables. Basically the same thing as inline-ifs (IIF) functions in other MS products. It’s main value is conciseness. It otherwise behaves and compiles identically to an if-else block.

You do not use ternaries to control program flow directly. I mean, you could so long as the methods used returned a value compatible with the left side of the assignment. However, you shouldn’t unless you like to make enemies and/or hate yourself. It’s almost always less readable than other conditionals.

Ternary syntax: variable = condition ? value if true : value if false;

Here’s an example from a form customization I did a while back. It was needed because sometimes unpopulated dataviews return -1 as the row. Note that I’m declaring the variable AND conditionally setting it in one line.

int rowNum = edv.ParentView.Row < 0 ? 0 : edv.ParentView.Row;

A traditional if-else would have to be written like this. Note that the variable must be declared before setting it in the conditon blocks.

int rowNum;
if (edv.ParentView.Row < 0)
{
    rowNum = 0;
}
else
{
    rowNum = edv.ParentView.Row;
}

You can nest ternaries, but do not do this. Like ever. Just look at the example below See how bad it is? I cried a little just writing it. Ternaries are about simplicity and brevity, and that goes away when the second ? shows up.

int x = yourString == "A" ? 1 : yourString == "B" ? 2 : 3;

Just as an FYI, there is the ternary operator (?) and also the null-coalescing operator (??). The latter is often found is LINQ queries when outer table joins or nullable fields (date fields in Epicor can return null) are involved. Works like ISNULL in SQL, in that if the value left of the operator is null, it will fall back to using the value on the right.

//From a LINQ query that looks for jobs not on the newest part revision.
where j.RevisionNum != (lr.NewestRev ?? j.RevisionNum)

Nullable types and LINQ in general is for a later entry.

5 Likes

Perfect. Added to the Wiki.

1 Like

Glad to see that article still helping folks.

I must say, even a bigger fan of functions since this creation - though in my new world it’s Azure functions.

I hope all are well!

5 Likes

You’re welcome to come back and teach us a few things… :rofl:

1 Like

Yes! Great way to show us education can be durable!

Miss me, @Bart_Elia ? :face_with_hand_over_mouth:

2 Likes