Updatable comments field in Jobhead table

Hi all,

I have been asked if I can add an updatable comments field on jobs which I can add no problem, the problem is when it comes to updating. It cannot update the field without unreleasing and un-engineering the job first and then re-releasing etc afterwards which is a pain.

Is there a way I can automate this process as part of the update? I have not used any update methods other than the built in ones so I have no idea what I’m doing with any advanced updating methods.

Thanks in advance.

Well, one “easy” solution is to uncheck this checkbox in Company Config (which I’m assuming must be checked in your case):

image

BUT… I cannot speak for your organization’s wants/needs and whether this is acceptable. Someone, or someones, chose to prevent changes to engineered job in your company configuration, but I at least wanted to bring it up.

Hi David,

Yes I found that one this morning and tested it. It unlocks far too much for our liking and it turns off the audit log which we really need.

1 Like

So I wouldn’t normally recommend this, because it’s typically very bad practice… But since it’s a comment field I am 98% sure that it’s safe.

You could add an “Update Comment” button to the UI, and call a function, passing in the Job Number and Job Comment input parameters.

Give the function DB Write access (this is the dangerous part), and add the JobHead table. Do a custom code function along these lines:

var jh = Db.JobHead.FirstOrDefault( x => x.Company == thisCompany && x.JobNum == JobNumParam );

if ( jh == null ) return;

jh.CommentText = JobCommentParam;

Db.SaveChanges();
1 Like

To take advantage of DB index, you’ll want to include the Company field, too

Db.JobHead.FirstOrDefault(x => x.Company == thisCompany && x.JobNum == JobNumParam);

Essential if multi-company
Just throwing that out there … I know it was a small example, but little things can bite

2 Likes

Good call!

I’m sure it would be much more complex, but couldn’t a function call the proper BOs to un-engineer, un-release, perform the update and then re-engineer, re-release, re-schedule?

Not saying I have the slightest clue the code required to do so… but this would at least just automate the manual process instead of granting write access.

I have a Data Directive that was created for us (way out of my expertise) that automatically creates, engineers, releases jobs. It is based on OrderLines and if a certain part number is entered it automatically kicks off the job (scheduled forward).

        JobEntrySvcContract jobEntryBO = ServiceRenderer.GetService<JobEntrySvcContract>(Db); 
        string warningList;
        var jobEntryTS = jobEntryBO.GetDetailsMsgWarning(jobNum, 0, "Method", 0, 0, "", 0, "EngReq", "0", "", true, false, false, false, out warningList);
        jobEntryTS.JobHead[0].JobEngineered = true;
        jobEntryTS.JobHead[0].RowMod = "U";
        jobEntryBO.ChangeJobHeadJobEngineered(ref jobEntryTS);
        jobEntryTS.JobHead[0].JobReleased = true;
        jobEntryTS.JobHead[0].RowMod = "U";
        jobEntryBO.ChangeJobHeadJobReleased(ref jobEntryTS);
        jobEntryBO.Update(ref jobEntryTS);
        ScheduleEngineSvcContract scheduleEngineBO = ServiceRenderer.GetService<ScheduleEngineSvcContract>(Db); 
        ScheduleEngineTableset scheduleEngineTS = new ScheduleEngineTableset();
        ScheduleEngineRow scheduleEngine = new ScheduleEngineRow();
        scheduleEngine.Company = jobEntryTS.JobHead[0].Company;
        scheduleEngine.JobNum = jobEntryTS.JobHead[0].JobNum;
        scheduleEngine.StartDate = DateTime.Now;
        scheduleEngine.EndDate = DateTime.Now;
        scheduleEngine.SchedTypeCode = "JJ";
        scheduleEngine.ScheduleDirection = "Start";
        scheduleEngine.OverRideHistDateSetting = 2;
        scheduleEngine.SysRowID = jobEntryTS.JobHead[0].SysRowID;
        scheduleEngine.RowMod = "A";
        scheduleEngineTS.ScheduleEngine.Add(scheduleEngine);
        bool finished;
        string warnLogTxt;
        scheduleEngineBO.MoveJobItem(scheduleEngineTS, out finished, out warnLogTxt);

Obviously there’s more to it than just the above… but it should be possible.

1 Like

You could definitely do that, and in most cases I’d recommend exactly that. It would be more complex, but not too terrible. In that case, I’d be worried about unintended side-effects of rescheduling, more than anything else. It’s nothing that couldn’t be mitigated with lots of testing, and can definitely be done.

That said, since this is a comment field, I think granting a single, published, internal-use only function the write access to update a comment might be the better option, if only because it can be done quickly without a ton of coding, testing, debugging, etc.

I have one of those too, but mine is super simple! I just trigger the Order Job Wizard Service / BO that the sales team would use from SO Entry. There’s a BAQ with all the conditions built-in, so if it’s on the BAQ, it’s ready to have a job created:

/*== Create Jobs for OrderLines in BAQ =======================================

    Epicor Function | Library: AutomationSS | Name: createJobsFromBaq

        Author:    Kevin Veldman
        Created:   2022/09/26
        Version:   3.2.0

    Request Parameters: None
    Response Parameters: None

    Info: Send Orders in BAQ to OrderJobWizard to create jobs from Order Lines

            --Kevin.Veldman <Kevin.Veldman@rfptSolutions.com>
============================================================================*/

//
// Set up Order Job Wizard Delegate (or move this to another function)
//
    string warnings = "";
    string errors = "";
    string exceptions = "";

    Action<int> OrderJobWizard = order => {
       
        CallService<OrderJobWizSvcContract>( jobWiz => {
            try {
                // Params: CreateJob, GetDetails, ScheduleJob, ReleaseJob
                var ds = jobWiz.SelectAll(order, true, true, true, true); 

                jobWiz.ValidateJobs( ref ds, out warnings );
                jobWiz.CreateJobs( ref ds, out errors );
            }
            catch ( System.Exception ex ) 
            {
                exceptions = ex.Message;
            }
        });
    };



//
// Get JobCreate Dataset
//
    string baqID = "ConfigOrderJobQueue";

    var results = this.EfxLib.util_Query.GetBaqDataSet( baqID );

    if ( results.Tables["Results"].Rows.Count <= 0 ) 
        return;



//
// Create Jobs from BAQ Dataset
//
    foreach (DataRow r in results.Tables["Results"].Rows)
    {
        var orderNum = (int)r["OrderRel_OrderNum"];
        var custCredHold = (bool)r["Customer_CreditHold"];

        var sbErrors  = new System.Text.StringBuilder();
        
        warnings = "";
        errors = "";
        exceptions = "";


        // If Cust is on credit hold, set to hold & skip JobCreate
        if ( custCredHold ) 
        { 
            this.ThisLib.setOrderHeld( orderNum );
            continue;
        }


        // Create Jobs using Order Job Wizard
        OrderJobWizard( orderNum );
        
        sbErrors.AppendLine( errors ).AppendLine( exceptions );

        bool ErrorsExist = sbErrors.ToString().Trim().Length > 0;
        
        if ( ErrorsExist )
        {
            string errorFile = $"JobCreate_Error_{orderNum}_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
            this.ThisLib.logJobCreate( errorFile, sbErrors.ToString() );
        }
    }






/*== CHANGE LOG ==============================================================


============================================================================*/



    /*__ Reference _______________________________________________________

        using Erp.Contracts;

    ____________________________________________________________________*/
1 Like