Updateable Dashboard to Add Multiple Make To Job Demands

Hi,

Is it possible to create an updateable dashboard to add Make To Job Demands to a job? There is a bit Make to Job demands, so we want to make it easier for the users to add the mtlseq.

Our current process is doing a DMT to JobProd table with a Job MakeToType with all the AsmSeq and MtlSeq. But we are trying to avoid giving users access to DMT. So we though of updateable dashboard. Has anyone done something like this?

Any ideas would be greatly appreciated!

Thank you,

Sure. You can make the entire job in a ubaq. I have a dashboard that our planners do a paste insert into and then they can create a bunch of jobs.

I’ve been meaning to strip out all of our quirky stuff and post a generic version, so I will try to make that happen.

4 Likes

Good to hear, thank you. If you can share it when you’ve got the generic version, I would really appreciate it. :slight_smile:

This is very stripped down. It either makes all make direct or all make to stock from a sales order. I started down a rabbit hole of trying to slice out some releases as direct and the rest as stock which can be done, but there is a lot of conditions to make that work. As a test I made 100 jobs in one pass tonight.

Here is the base code and alot of it I got from here, so this is a community work.

/* create jobs E10help */

/* Add references for JobEntry and ScheduleEngine */

var job = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.JobEntrySvcContract>(Db);
var boSched = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.ScheduleEngineSvcContract>(Db);

string jobNum = "" ;
string primWhse = string.Empty;
string Msg = "" ;
bool logit = true ;
//int count = 0;

var resultsList  = queryResultDataset.Results;

//=========================================================================================================================================
// m a i n   c o d e  m a i n   c o d e   m a i n   c o d e   m a i n   c o d e   m a i n   c o d e   m a i n   c o d e   m a i n   c o d e
//=========================================================================================================================================


switch (actionID)
{

  case "CREATEJOB":
  foreach (var ttr in queryResultDataset.Results) //.Where(r=> r.Calculated_Select == true ))
  {
    //count = 0;
    DateTime schStartDate = DateTime.Today ;
    DateTime? dueDate = null;
    
     if(ttr.OrderRel_Make == true)
     {
      dueDate   = ttr.OrderRel_ReqDate;
     }
     else
     {
      dueDate   = ttr.OrderDtl_RequestDate;
     }

    string jobpart = string.Empty;
    decimal directQty = 0m;
    decimal stockQty = 0m;
    int kitDays = 0;
    int prodDays = 0;
    //var primWhse = string.Empty;

    
    jobpart = ttr.OrderDtl_PartNum;
    jobNum = ttr.Calculated_JobNumber;
    
     directQty = resultsList.Where(w => w.OrderRel_OrderNum == ttr.OrderRel_OrderNum && w.OrderRel_OrderLine == ttr.OrderRel_OrderLine && ttr.OrderRel_Make == true).Sum(x => (decimal?) x.OrderRel_OurReqQty) ?? 0m;
    
     stockQty = resultsList.Where(w => w.OrderRel_OrderNum == ttr.OrderRel_OrderNum && w.OrderRel_OrderLine == ttr.OrderRel_OrderLine && ttr.OrderRel_Make == false).Sum(x => (decimal?) x.OrderRel_OurReqQty) ?? 0m; 
    
    if(stockQty != 0 && directQty != 0)
      continue;
    
    var revnum = Db.PartRev.Where(x=>x.Company == CompanyID && x.PartNum ==  jobpart && x.Approved == true).Select(r=> r.RevisionNum).FirstOrDefault();
    if(revnum == null)
    {
      ttr.Calculated_Status = $"Part {jobpart} has no approved Revision.";
      continue;
    }

    Ice.Diagnostics.Log.WriteEntry($"Trying to make {jobNum} for {jobpart} due {dueDate}");

    if (jobNum == string.Empty)
    continue;

    bool jobExists = Db.JobHead.Any(x=>x.Company == CompanyID && x.JobNum ==  jobNum);

    if(jobExists == true)
    {
      ttr.Calculated_Status = string.Format("Job {0} already exists.", jobNum);
      continue;
    }

    bool partExists = Db.PartRev.Any(x=>x.Company == CompanyID && x.PartNum ==  jobpart); //&& x.RevisionNum == ttr.Rev);

    if(partExists == false)
    {
      ttr.Calculated_Status = $"Part {jobpart} does not exist.";
      continue;
    }

    using (var txScope = IceContext.CreateDefaultTransactionScope())
    {
      var part = Db.Part.Where(p => p.Company == CompanyID && p.PartNum == jobpart).Select( p => new { p.PartNum, p.PartDescription }).FirstOrDefault();
      if (part != null)
      {


        var partPlant = Db.PartPlant.Where(p => p.Company == CompanyID && p.PartNum == part.PartNum).Select( p => new {p.MaxMfgLotSize,p.PrimWhse}).FirstOrDefault();
        if (partPlant != null)
        {
          primWhse = partPlant.PrimWhse;
        }



        Erp.Tablesets.JobEntryTableset ds = new Erp.Tablesets.JobEntryTableset();

        job.GetNewJobHead(ref ds);

        foreach (var headerRow in ( from dsRow in ds.JobHead select dsRow))
        {
          if (headerRow.RowMod.ToUpper() == "A")
          {
            headerRow.JobNum = jobNum;
            headerRow.PartNum = part.PartNum;
            job.ChangeJobHeadPartNum(ref ds);
            headerRow.PartDescription = part.PartDescription;
            //headerRow.RevisionNum = ttr.rev;
            headerRow.Plant = Session.PlantID;
            headerRow.ReqDueDate = dueDate;
            headerRow.JobEngineered = true;
            job.ChangeJobHeadJobEngineered(ref ds);
            //headerRow.JobReleased = true;
            //job.ChangeJobHeadJobReleased(ref ds);
            job.Update(ref ds);

            ds = job.GetByID(headerRow.JobNum);
            
            if(ttr.OrderRel_Make == false)
            {
                job.GetNewJobProd(ref ds, headerRow.JobNum, headerRow.PartNum, 0, 0, 0, primWhse, string.Empty, 0);
                ds.JobProd[0].MakeToStockQty  = Convert.ToDecimal(Math.Ceiling(stockQty));
                job.ChangeJobProdMakeToStockQty(ref ds);
            }

            if(ttr.OrderRel_Make == true)
            {
                job.GetNewJobProd(ref ds, headerRow.JobNum, headerRow.PartNum, ttr.OrderRel_OrderNum, ttr.OrderRel_OrderLine, ttr.OrderRel_OrderRelNum, string.Empty, string.Empty, 0);
                ds.JobProd[0].ProdQty  = Convert.ToDecimal(Math.Ceiling(ttr.OrderRel_OurReqQty));
                job.ChangeJobProdProdQty(ref ds);
            
            }
          
            

            job.Update(ref ds);


            string currJobNum = headerRow.JobNum;
            int currAsmSeq = 0;
            string sourceFile = "Method";
            int sourceQuote = 0;
            int sourceLine = 0;
            string sourceJob = "";
            int sourceAsm = 0;
            string sourcePart = headerRow.PartNum;
            string sourceRev = headerRow.RevisionNum;
            string sourceAltMethod = "";
            bool resequence = false;
            bool useMethodForParts = false;
            bool getCostsFromInv = false; // Required paramter for 10.1 but not 10.0
            bool getCostsFromTemp = false; // Required paramter for 10.1 but not 10.0

            job.GetDetails(currJobNum,currAsmSeq,sourceFile,sourceQuote,
            sourceLine,sourceJob,sourceAsm,sourcePart,
            sourceRev,sourceAltMethod,resequence,
            useMethodForParts,getCostsFromInv,getCostsFromTemp);



            //=====================================




            Erp.Tables.JobAsmbl JobAsmbl;
            Erp.Tables.JobOper JobOper;
            Erp.Tables.JobOpDtl JobOpDtl;


            bool finished = false ;
            try
            {
              var schedDS = new Erp.Tablesets.ScheduleEngineTableset() ;
              var sp = schedDS.ScheduleEngine.NewRow() ;
              sp["Company"]        = callContextClient.CurrentCompany ;
              sp["JobNum"]         = jobNum ;
              sp["AssemblySeq"]    = 0 ;
              sp["OprSeq"]         = 0 ;
              sp["OpDtlSeq"]       = 0 ;
              sp["StartDate"]      = schStartDate ;
              sp["StartTime"]      = 0 ;
              sp["EndDate"]        = dueDate ;
              sp["EndTime"]        = 82800 ;
              sp["WhatIf"]         = false ;
              sp["Finite"]         = false ;
              sp["SchedTypeCode"]      = "jj" ;
              sp["ScheduleDirection"]  = "End" ; //"Start" ;
              sp["SetupComplete"]      = false ;
              sp["ProductionComplete"] = false ;
              sp["OverrideMtlCon"]     = true ;
              sp["OverRideHistDateSetting"] = 2 ;
              sp["RecalcExpProdYld"]        = false ;
              sp["UseSchedulingMultiJob"]   = false ;
              sp["SchedulingMultiJobIgnoreLocks"]  = false ;
              sp["SchedulingMultiJobMinimizeWIP"]  = false ;
              sp["SchedulingMultiJobMoveJobsAcrossPlants"] = false ;
              sp["SysRowID"]      = Guid.NewGuid() ;
              sp["RowMod"]        = "A" ;
              schedDS.ScheduleEngine.Add( sp );
              Ice.Diagnostics.Log.WriteEntry("In MoveJobitem " + jobNum.ToString() + " pn " + dueDate.ToString());
              boSched.MoveJobItem( schedDS, out finished, out Msg  ) ;
              ttr.Calculated_Status = ttr.Calculated_Status + "Job: " + jobNum.ToString()  + Msg ;
            } catch (Exception ex) {
              ttr.Calculated_Status = string.Format("Error: {0} Scheduling Job: {1}", ex.Message, jobNum) ;
            }

          }



        }
      }
      
      Db.Validate();
      txScope.Complete();

      

    }

  }
  return ;
  break;



}











E10-CreateJobs.baq (39.7 KB)

Not sure if you are using MRP or not, but if you set up your parts correctly, MRP will make the Make To Job demand links automatically. :man_shrugging:

2 Likes

Thank you so much for sharing this, this should be a good start for me to look into. :slight_smile:

1 Like

We thought of MRP, but we are currently not using it. This is in our list to implement. :slight_smile: