Application of costing lot size

Thank you for the write up!

John hereā€™s what I want to ask.

Imagine you have 3 machines you run a part on. Each machine can produce the part within tolerance, in other words, it doesnā€™t matter what machine you run it on. However, each machine requires different speeds, amounts of materials, and labor.

You want to cost based on machine 1.

But you want your operator to use the right amount of materials and speeds when you use machine 2 next week cause machine 1 is at capacity.

How do you make sure your operator runs the machine and picks the right amount of material to run the job on machine 2 next week? Furthermore you want to be able to quote based on either machine and you need to plan based on the machines being used/methods that are going to be used at the time you run the job.

This is where I see the divergence of a costing method of manufacture and a manufacturing method of manufacture. Again, I agree with you, ā€œyour method should ALWAYS reflect what is actually needed to be done,ā€ thatā€™s why I am saying when I run on machine 2 I shouldnā€™t use the costing method that was based off of machine 1. I wouldnā€™t want to use an average amount either because then my product would be out of spec on machine 2.

You could look into alternate methods and cost your alternate methods.

1 Like

Iā€™ll have to look into this Jenn, thanks!

You donā€™t want to cost based off of your ā€œbestā€ machine. You want to cost off of the average that is likely to happen. That is what Standard Cost is. A brand new part, you take your best guess at the initial cost and review it at year end. But moving forward, you should be reviewing each cost to see how it actually performed against Standard. There is no one answer to costing, which is why there is the Cost Engineer position. At year end, the pluses and minuses should almost be a wash and your margin should absorb any crazy minuses that may occur. Unless your process is completely replicable, you will never ā€œhitā€ your standard, you will always be off.

If you have APS, I would create Capabilities and change the factors on the machines. Another route you could go with APS is to create Operation Standards, but that would require your Resource Groups be setup to support it. This would take care of the labor and speed.

For employees using the correct speed and material per machine, I would put that in the work instructions in the MOM.

Even if you do somehow figure out a way to do this extremely granular costing, will it give you what you want or just add more work to employees (that would add to the overhead cost)? At the end of the day, I am sure if you averaged everything out, you would get the same results as costing at a higher level.

What are your margins? This should not be an issue for your company unless your margins are under 10%.

3 Likes

This. :point_up: If one chooses to use Standard costing then this is what we do. If we want flexibility, then use Average. If we want complexity and a lot of error correction, use Lot Costing. :wink:

Hahaha I love both yā€™all. thanks for indulging in the costing discussion.

I appreciate the input and the guidance.

This is the balance beam I am onā€¦ what is acceptable to the organization and how much work are they willing to put in.

Its all good discussions and @jgiese.wci and I are absorbing the info, as we plan to possibly move away from Standard, good to see all perspectives.

Another consideration is transaction timing. The reason Standard Cost became popular years and years ago was that transactions were not entered promptly or in chronological order. For Average or Lot costing to work, timing of transactions is essential. Costs completely breakdown if inventory ever goes negative. But this isnā€™t an issue with Standard Costing. The cost is set and we recognize variances on the way into inventory and then move everything at the standard. For MTO or Project work, this is not ideal since we want to see variances on the order or project. But for make to stock for repeatable jobs, standard costing makes life easier.

1 Like

Good points Mark.

Always good discussions here.

By the way, we are MTO so we are Last :grinning:

1 Like

Thatā€™s my only concern with average is timing especially with our rolls of paper. Example scenario I see sucking rocks.

  1. We need to make 10 cases.
  2. Job calls for 100 pounds of paper
  3. We issue a roll of paper and that roll weighs 500 pounds
  4. We finish and ship the job with all 500 pounds of paper on it
  5. We realize the mistake and return the excess weā€™ll call it 350 Lbs (take 50 for scrap)

What cost gets applied to those transactions? The 500 pounds or the 150 pounds? I think itā€™s the 150 because the job would be closed and the invoice would get the final cost applied to it. Is that accurate?

What if you partial ship a MTO job mid way through? What happens with costs then? Beyond that Iā€™m pushing for Average on MTO and Standard on Stock especially because of the timing of the receipts to inventory mid way through the job. I suppose in the end if timing is off and you bring 10 in at 5 dollars and 10 more later in at 10 dollars your average should still be good? But then again we realize material wasnā€™t settled and now the parts have excess cost?

This is about the only part of it all I can think of that Iā€™m real fuzzy on.

1 Like

It is the COS/WIP capture that you need to be careful of. Once you cross that threshold, you canā€™t go back.

I think the important thing to remember here is that regardless of your costing method, the cost of every job is using the same numbers to get to itā€™s conclusion. Choosing a different costing method does not change how a JOB cost is calculated, it changes how the PART cost is shown.

Also, invoicing has nothing to do with costing. Invoicing will charge the price on the sales order whether or not you made money or lost money. The cost is an after the fact to make sure you are estimating correctly.

The capture process controls everything. Nothing is posted to the GL until it is run. As long as you are not running that for fun, you will be fine.

1 Like

All the job unit costs get pulled into the invoice dtl at job closing and that drives the SGM so it kind of matters what numbers get pulled into there no?

I guess to be clearer Iā€™m less concerned about what posts to GL whatā€™s going to post is going to balance so Iā€™m good there. Iā€™m more concerned with that analysis and appearance portion of it.

1 Like

I am constantly blown away by the level of expertise and depth of discussion on this forum.

1 Like

This is incorrect, it would just be a snapshot in time since nothing is posted. If you ship and invoice with the 500 pounds on the job, it will look bad at that time. As long as you have not captured, you can still remove the extra 350 pounds. Then when you look again, everything is peachy. People should not trust any numbers until AFTER the capture is done.

From Epicor Help:

You can simulate this functionality using the WIP, Sales Gross Margin, and Inventory/WIP Reconciliation reports. The reports attempt to determine COS and WIP using the latest information in the database. Because all costs have not posted to jobs, these reports do not necessarily display accurate, final manufacturing variances (PartTran MFG-VAR records).

1 Like

The posting doesnā€™t change SGM, we just messed around with this heavily. We have a bug fix in place too that if you close the job before invoicing that your SGM doesnā€™t show 100% margin with 0 costs. When the Job is closed this is the logic Epicor runs to drive the SGM. The fix we wrote causes the invoice to get job costs on GetShipments in the event the MTO job has been closed already.

  // This is the exact same algorithm Epicor uses when you close a Job
  foreach (var idRow in invDetailRows)
  {
    var JobAsmblRow = Db.JobAsmbl.Where(w => w.Company == idRow.Company && w.JobNum == idRow.JobNum && w.AssemblySeq == 0).FirstOrDefault();
    if (JobAsmblRow != null)
    {
      var JobPartJobProd =
        (from jp in Db.JobPart
          join jp2 in Db.JobProd on new { jp.Company, jp.JobNum, jp.PartNum } equals new { jp2.Company, jp2.JobNum, jp2.PartNum }
          where jp.Company == idRow.Company
            && jp.JobNum == idRow.JobNum
            && jp.ShippedQty > 0
            && jp2.ShippedQty > 0
          select new {
            JobPart = jp,
            JobProd = jp2
          }
        ).ToList();

      foreach (var JobProdRow in JobPartJobProd)
      {
        var JoinResult = JobProdRow;
        decimal varShippedQty = (idRow.PartTranShippedQty <= 0) ? idRow.JobProdQty : idRow.PartTranShippedQty;

        // Get InvcDtl Rows to update including historical partial shipments
        // this is the exact same algorithm Epicor uses when you close a Job
        var InvcDtlRows =
          (from id in Db.InvcDtl
            where id.Company == JoinResult.JobProd.Company
              //&& id.InvoiceNum == idRow.InvoiceNum
              //&& id.InvoiceLine == idRow.InvoiceLine
              && id.OrderNum == JoinResult.JobProd.OrderNum
              && id.OrderLine == JoinResult.JobProd.OrderLine
              && id.OrderRelNum == JoinResult.JobProd.OrderRelNum
              && id.OurShipQty > 0
              && id.ConsolidateLines == false
            select id
          ).ToList();

        //
        // Update Costs
        //
        using (var txScope = IceContext.CreateDefaultTransactionScope())
        {
          foreach (var InvcDtl in InvcDtlRows)
          {
            InvcDtl.JCBurUnitCost = Math.Round((JobAsmblRow.TLABurdenCost + JobAsmblRow.LLABurdenCost) / varShippedQty, nCostDecimals, MidpointRounding.AwayFromZero);
            InvcDtl.JCLbrUnitCost = Math.Round((JobAsmblRow.TLALaborCost + JobAsmblRow.LLALaborCost) / varShippedQty, nCostDecimals, MidpointRounding.AwayFromZero);
            InvcDtl.JCMtlBurUnitCost = Math.Round((JobAsmblRow.TLAMtlBurCost + JobAsmblRow.LLAMtlBurCost) / varShippedQty, nCostDecimals, MidpointRounding.AwayFromZero);
            InvcDtl.JCMtlUnitCost = Math.Round((JobAsmblRow.TLAMaterialCost + JobAsmblRow.LLAMaterialCost) / varShippedQty, nCostDecimals, MidpointRounding.AwayFromZero);
            InvcDtl.JCSubUnitCost = Math.Round((JobAsmblRow.TLASubcontractCost + JobAsmblRow.LLASubcontractCost) / varShippedQty, nCostDecimals, MidpointRounding.AwayFromZero);

            Ice.Diagnostics.Log.WriteEntry($"[ Updated ] InvoiceNum: {InvcDtl.InvoiceNum} - InvoiceLine: {InvcDtl.InvoiceLine} - JCBurUnitCost: {InvcDtl.JCBurUnitCost} - JCLbrUnitCost: {InvcDtl.JCLbrUnitCost} - JCMtlBurUnitCost: {InvcDtl.JCMtlBurUnitCost} - JCMtlUnitCost: {InvcDtl.JCMtlUnitCost} - JCSubUnitCost: {InvcDtl.JCSubUnitCost}");
          }

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

        // Epicor is also doing something with InvcDtlPack
        // we have not tested this scenario but it may be in the future
        // leaving this in for reference
        //
        // using (libCreateInvcDtlPack = new AR.CreateInvcDtlPack(Db))
        // {
        //   libCreateInvcDtlPack.UpdateInvcDtlPackJobClosing(JoinResult.JobProd, JobAsmbl, varShippedQty, nCostDecimals);
        // }
      }
    } 
  }
}
1 Like

What is your current costing method?

And what is your definition of Closed? The job is closed or the Capture process has run? Or something else?

I canā€™t wait to learn more from your experiences @jgiese.wci and @hkeric.wci ā€¦ it canā€™t be a coincidence that all three of us are working on costing at the same timeā€¦ How long has this been brewing for you?