Independent IFS Cloud practice · Implementation
Key takeaways
Most articles about ERP business impact are written from the brochure. This one is written from the projects. I have spent seventeen years inside IFS, from Apps 7.5 through Cloud, and the pattern that repeats is not that companies pick the wrong system. They pick a capable one and then implement it in a way that throws the capability away: a template nobody reuses, an automation layer nobody trusts, reports rebuilt one for one from the old system because nobody had the authority to delete any of them.
So this is not a list of what IFS Cloud can do. It is a walk through the places where a decision taken during implementation determines whether the platform pays for itself or just replaces one kind of manual work with another. Where a topic deserves its own treatment, I have linked to the longer piece on the ifs-erp.com blog rather than compressing it into two sentences here.
Grouping sites so they share parts, defaults and process setup is sold as a speed feature. It is really a consistency feature, and the speed is a side effect. When site four inherits the purchasing parameters that sites one to three already run on, you are not just saving a week of configuration. You are removing the possibility that site four quietly does receiving differently, which is what costs you two years later when someone tries to compare performance across the group and finds the numbers are not measuring the same event.
The catch is that a cluster only helps if the template being cloned is one somebody defended. Rolling out a bad standard quickly is worse than rolling it out slowly, because a slow rollout at least gives each site a chance to object. I ask for the template to be signed off by the person who will own the process across all sites, not by the site that happened to go first. That is also where the multi-site purchasing decisions belong: whether demand consolidates centrally, and how stock moves between sites once it has.
Further reading: centralised purchasing in IFS Cloud, distribution orders between sites, and from planning to go-live.
IFS Cloud gives you three tools that cover most of what people used to write code for, and knowing which one to reach for is the whole skill. A Quick Report reads data out: a saved query for a list or an extract, with no logic. A Custom Field stores something the standard data model does not. A Custom Event reacts when a row changes, and can hand off to a Workflow that routes an approval, sends a notification, or calls out to another system.
The failure mode is predictable. Teams discover Custom Events, like them, and attach one to everything. Six months later there is an event layer nobody can explain, firing on saves that were never meant to be significant, and the business has learned to ignore the notifications it produces. The second failure mode is subtler: reaching for a Custom Event when the requirement is actually a scheduled check. An event fires when a row changes. It cannot fire because a row has not changed, which is exactly what an unconfirmed order or an untouched receipt is.
Where the requirement crosses a system boundary, the answer is usually an interface rather than an in-system automation. IFS Cloud's OData projections are the normal integration surface, and keeping the orchestration outside IFS keeps that logic out of your ERP, where it would otherwise become one more thing to retest at every release.
Further reading: Custom Events explained, Quick Reports vs Custom Fields vs Custom Events, IFS Cloud API integration, orchestrating IFS Cloud with n8n. Work that has already been built once sits in the configurations and interfaces sections of the marketplace.
IFS Cloud ships R1 and R2 every year. That cadence is the biggest single change in how you should think about customisation, and it is where legacy habits do the most damage. On Apps 9 or 10 an upgrade was an event you prepared for over months, so carrying technical debt between them felt survivable. On Cloud it arrives twice a year, and anything built outside the Extensibility Framework has to be checked, and often reworked, on that same rhythm.
The boundary is simple to state and easy to cross by accident. Extending the data model with Custom Fields, adding logic through Custom Events and Workflows, adapting screens through configuration: all inside the contract, all carried forward. Touching a core object, or building a report or an interface directly against an internal view rather than a published projection, puts you outside it. Nothing stops you at the time. The bill arrives at the next release, and at every release after that.
I have watched this go wrong in both directions. Companies that refuse all extension end up with a shadow layer of spreadsheets doing the work the system was not allowed to do, which is worse, because at least a customisation is visible. The honest position is that some extension is necessary, and the only real question is whether it is built where the platform will maintain it for you.
Further reading: update-safe extensions, the true cost of customisation, clean core in an SCM context, the upgrade tax, the upgrade readiness checklist, and what a release actually brings, with 25R2 purchasing as the worked example. Scoped modification work is listed under marketplace modifications.
Ask a buyer what goes wrong and you get something dramatic: a late shipment, a line stopped for a missing part. Look in the data and the costly problems are the undramatic ones, because nothing in the system objects to them.
| What is sitting there | Why nobody sees it | What it turns into |
|---|---|---|
| A released PO the supplier never acknowledged | The order is valid and open. No field says "ignored" | A delivery date everyone planned around that was never agreed |
| Goods received, invoice never matched | Both records are individually correct | An accrual that grows quietly until period end |
| A supplier price that moved between orders | The new price applies cleanly, exactly as configured | Margin erosion found during an annual review |
| A buyer who stopped ordering from a usual source | Every individual order is legitimate | Concentration risk, or a supplier problem nobody escalated |
All of this is detectable, and all of it is readable through standard OData projections on a read-only account. That means a monitor can look for it daily without touching a record, installing an object, or adding anything the next release has to be checked against. It is the design principle behind the SCM Automation Pack, and the reason the five-day exception scan exists as a way to see what is already in your own data before committing to anything ongoing.
On the physical side the same principle applies to warehouse work. Picking strategy and packing proposals are configuration decisions that quietly set your throughput ceiling, and they are rarely revisited after go-live.
Further reading: unconfirmed purchase orders, what unmatched receipts do at period end, supplier price changes, advanced picking strategies, the packing proposal.
Anomaly detection, demand forecasting and predictive maintenance are genuinely useful, and they all rest on the same unglamorous foundation: whether your master data is good enough for a model to learn from. A forecast built on lead times copied out of the legacy system in 2019 and never reviewed will be precise, confident and wrong, and it will be harder to challenge than a human guess because it arrives with a number attached.
The second thing the demo leaves out is what happens to the output. Detection is the easy half. The half that decides whether any of it pays off is routing: who receives the signal, how it reaches them, and what happens when they do nothing. An alert stream with no named owner and no escalation is a mailing list, and people unsubscribe from mailing lists in their heads long before they do it in the client.
That is why I design exception rules around the recipient rather than the condition. One deduplicated digest per owner per day beats forty individual notifications that are each technically correct. And a rule that cannot state in one sentence what the recipient is supposed to do about it does not ship.
Further reading: alert fatigue and exception design, the cost of missed exceptions, detecting supplier behaviour change, the data attention gap, assumed vs confirmed records, read-only OData monitoring.
Crystal Reports layouts from Apps 9 and 10 do not carry across to IFS Cloud. That is the fact that matters for your plan, whatever any vendor's support calendar says, and it is usually discovered later than it should be, because reporting gets treated as a workstream that can start once the real configuration is done.
IFS Cloud splits the job across different tools. Quick Reports handle lists and extracts: saved queries, no layout ambition, self-service for anyone who can be trusted with a data set. Laid-out business documents are produced through IFS Cloud's own report layout tooling. Analysis and dashboards belong in the reporting and analytics layer rather than in a printed report at all. Trying to recreate a 200-item Crystal inventory inside any one of these is how reporting becomes the critical path.
The work that actually saves you time is triage, and it is a business job rather than a technical one. Pull the usage data first. Most report inventories contain a long tail nobody has run in two years, a middle band that exists because one person likes the format, and a small core the business genuinely runs on. Rebuild the core properly, convert the middle band to Quick Reports or a dashboard, retire the tail. The conversation about retiring the tail is the hard part, which is why it needs to start early and needs someone senior to close it.
Further reading: when a Quick Report is the right answer, and the reports section of the marketplace.
Permission sets in IFS Cloud are capable enough to express proper segregation of duties. Whether they end up doing so is decided in the first six weeks of the project, when someone is under time pressure and the fastest way to unblock testing is to grant a broad set to a group and move on. That grant is almost never revisited, because nothing breaks. It surfaces at the first external audit, when a tester asks who can both create a supplier and approve a payment to it, and the honest answer takes a fortnight to assemble.
Design the role model against the process rather than the org chart, and build it while the process design is still fresh in everyone's head. It costs days then and weeks later. The same applies to standards work: if you operate under ISO requirements, the evidence those audits want is largely a by-product of decisions you are already taking, provided you record them as you go instead of reconstructing them afterwards.
Further reading: RBAC and segregation of duties, permission sets in IFS Cloud, ISO standards in IFS Cloud, and the security section of the marketplace. My own view on the wider ownership question sits on the data governance page.
Every implementation plan has a migration workstream, and most are optimistic by the same margin. The reason is consistent: the effort is not in loading the data, it is in deciding what the data should say. Loading is mechanical. Agreeing that these 4,000 part records are the ones worth keeping, that this status code maps to that one, and that a customer with no valid tax ID is a customer you are not going to migrate, is a series of business decisions with no obvious owner.
Two habits change the outcome. Rehearse the load more than once, on a schedule, with a defined cut of source data each time, so the failure list shrinks between rehearsals instead of being discovered on cutover weekend. And treat validation as its own deliverable with its own sign-off rather than as the last step of loading, because IFS Cloud enforces its business rules at load time: well-formed source data can still be rejected for violating application logic nobody had read.
Further reading: the data migration checklist, how FNDMIG and the Data Migration Manager fit together, and the data migration section of the marketplace.
In most of the companies I work with, a large amount of operational knowledge lives in one person's head and one person's spreadsheet. The buyer who knows which supplier actually delivers on time regardless of what the lead time field says. The planner whose workbook reconciles two things the system does not reconcile. None of this shows up in an ERP assessment, and all of it walks out of the building when that person leaves.
An implementation is the one moment when you have a mandate to surface it. Every shadow spreadsheet is a documented requirement waiting to be read: it exists because the system does not do something, and finding out what that something is tells you more about your real process than a workshop will. Some of them should become configuration. Some should become a Quick Report. A few are genuinely someone's judgement and should stay human, but at least then you know where they are.
The same logic applies to the implementation record itself. Decisions taken in month two get questioned in month eleven by people who were not in the room, and a project that cannot answer "why is it set up this way" reopens settled arguments for the rest of its life.
Further reading: shadow spreadsheet risk, knowledge loss when people leave, buyer knowledge concentration, and the implementation documentation kit if you would rather not build the templates from scratch.
I am wary of quoting percentage improvements. Published ranges come from situations you cannot inspect, with baselines nobody defined, and a number borrowed from another company's business case is not evidence about yours. What I can offer is the short list of measures that survive contact with an actual steering committee.
Further reading: ERP ROI analysis, why go-live is a load test, the implementation crisis.
If you are live on IFS Cloud and this article has described your situation rather than your plan, the order that works is roughly this. Find out what is actually in your data before redesigning anything, because the exception population usually contradicts the received wisdom about where the problems are. Then fix the governance decisions that get harder with time: the role model, the report inventory, the ownership of master data. Automation comes after that, not before, because automating a process nobody owns only makes it produce wrong answers faster.
What I do is on the offer page, the platform view is on the IFS Cloud page, and the process side sits under business process optimisation. The applications themselves, including the read-only exception monitoring described in section 4, live on ifs-erp.com.
No, but the work changes shape. Before go-live it is a design decision that costs nothing extra. After go-live it is an inventory exercise: list everything built outside the Extensibility Framework, establish what each item actually does, and decide case by case whether to rebuild it inside the contract, replace it with standard functionality, or accept the maintenance cost knowingly. The last option is legitimate. What is not legitimate is not knowing which category each item falls into, which is the usual starting position.
No. In most projects I see, the unclaimed value sits in exceptions a plain query would find: orders nobody confirmed, receipts nobody invoiced, prices that moved. That is rule-based detection rather than machine learning, and it works on data that is merely adequate. Model-driven forecasting is worth doing once master data has an owner and a maintenance routine, and worth postponing until it does.
Yes, and that is the approach I prefer for anything that only needs to read. Standard OData projections plus an integration account with read permission are enough to detect the exception patterns in section 4. Nothing is installed in IFS, nothing is written back, and there is no object for the next R1 or R2 release to break. If you want to see the output before committing to anything ongoing, the five-day exception scan produces the same report in observation mode only.
Budget the triage, not the rebuild. Pulling usage statistics and getting a decision on what to retire takes longer than rebuilding the reports that survive, because it needs business sign-off rather than developer time. Start it in parallel with configuration rather than after it, and give the retire list an owner with the authority to say no. Teams that skip this step rebuild everything one for one and carry the whole inventory forward, including the part nobody has opened since 2019.
The configuration saving is small at that scale. The consistency saving is not, and it compounds: two sites configured independently will diverge on receiving, costing and reporting definitions within a couple of years, and reconciling them later is considerably more work than agreeing a shared template now. If there is any prospect of a fourth site, an acquisition, or a group-level report, treat it as worth it.
Dariusz Myśliwiec: 25+ years in ERP and supply chain, 17+ on IFS (Apps 7.5–10 and IFS Cloud). IFS Certified Associate Consultant. PRINCE2® 7. Based in Kraków, delivering remotely across Europe and globally through an independent practice.
Selected clients: Fugro · LGC · BVI Medical · Betafence (PRÆSIDIAD) · Barlinek · NGK Ceramics · Newag · Oleofarm.
IFS is a registered trademark of IFS AB; this practice is not affiliated with IFS AB.
If you are scoping an IFS Cloud implementation, or you are already live and suspect the value case has quietly gone missing, a short call is the fastest way to work out which two or three of the eleven sections above are actually costing you something.
Independent IFS Cloud practice · Extensibility & Upgrades
A PL/SQL customisation or Custom Event that breaks with an exception is a bad afternoon. One that keeps compiling, keeps executing, and just silently stops doing what it used to do is a bad quarter, because nothing in the system tells you it happened. This is the mechanics of why it happens after an R1/R2 release specifically, the four concrete patterns that cause it, and the diagnostic sequence I actually run when a client says “this used to work.”
Key takeaways
An error is loud because something the platform expects did not happen: a mandatory field was null, a constraint was violated, a procedure call did not resolve. Silent failure is different in kind, not just in visibility. It happens when the platform changes something the custom logic depended on, but not in a way that produces an exception: a status value gets relabeled, a trigger point’s position in the transaction sequence shifts, a procedure gains an optional parameter that a hand-built wrapper never learns to pass. The custom code keeps compiling and keeps running. It simply stops matching anything, or starts running at a point where the data it needs is not populated yet, and every code path it takes from there is technically valid and semantically wrong.
This is why it clusters around R1/R2 releases specifically rather than happening at random. A release is exactly the event that changes enum labels, reorders standard business logic, and adds parameters to existing procedures, all while keeping the outer interface backward-compatible enough that nothing refuses to compile. Extensions built strictly inside the Extensibility Framework, against published Custom Event trigger points and Custom Fields, are far less exposed to this because the framework’s contract is explicitly versioned. Extensions that reach past that boundary into internal package logic or hard-coded status strings inherit every internal change the release makes, with no compatibility guarantee attached to any of it.
| Pattern | What actually changes | Why no error surfaces |
|---|---|---|
| Renamed or restructured enum/status value | A status constant the custom comparison hard-codes as a literal string is relabeled or split into two values in the release | The comparison is syntactically valid PL/SQL; it just never evaluates true again |
| Resequenced Custom Event trigger point | The standard logic around a trigger point is reordered, so the custom logic now fires before a field it reads has been populated for that transaction | The custom code runs successfully against a null or stale value instead of the intended one - no exception, just a wrong branch taken |
| Wrapper that ignores a new parameter | A standard procedure gains an additional optional parameter in the release; a custom wrapper built against the old signature still compiles because the parameter is optional | The new behaviour the parameter controls simply never activates through the custom path, silently diverging from the standard path |
| Broad exception handler | Nothing in the platform changes here - a WHEN OTHERS THEN NULL-style handler was already present, added earlier to survive one specific edge case |
Any new error class the release introduces into that code path is swallowed by the same handler, indistinguishable from the edge case it was written for |
The fourth pattern deserves its own emphasis, because it is not really an upgrade problem at all, it is a pre-existing landmine the upgrade steps on. A handler written to catch one known, harmless exception and continue is functionally identical to a handler that catches every possible exception and continues, from the platform’s point of view. The moment the release introduces any new failure mode into that code path, whether related to the original edge case or not, it disappears into the same catch block with the same silent continuation.
Illustrative scenario, not a claim about a specific real trigger point or status value [VERIFY against your own customisation]. A Custom Event fires on purchase order line approval, checks whether the line’s value exceeds a budget threshold, and if a status field on the order reads a particular value, blocks the approval and routes it to a manager instead:
| Before the release | After the release |
|---|---|
| Status field holds the literal value the custom comparison checks for | The release restructures the status enum; the same business state is now represented by a different literal, or split across two fields |
| Comparison evaluates true for over-budget lines, event blocks and routes them | Comparison never evaluates true against the new literal; the event executes every time but takes the “no action” branch every time |
| Manager sees a routed approval whenever a line exceeds budget | Every over-budget line auto-approves silently; nothing errors, nothing logs, nothing routes |
Nobody notices for months, because the failure produces exactly the same visible outcome as a correctly functioning system with no over-budget lines that quarter: nothing shows up in the manager’s queue. The gap is only found when someone reconciles actual spend against the budget threshold independently of the control that was supposed to be enforcing it, which is precisely the kind of check that should not have to be the detection mechanism in the first place.
Every one of the four patterns above is detectable, in principle, by reading the diff between release versions. What actually makes it invisible in practice is a specific pre-existing habit: custom logic that produces no output, no log entry and no counter increment on either the success or the no-action path. If the budget-gate event in the example above had written one row to a log table every time it evaluated, regardless of outcome, someone would have noticed the “blocked” count drop to zero the week after go-live. Because it wrote nothing on the no-action path, and the no-action path is indistinguishable from correct behaviour when there is genuinely nothing to block, there was no signal to notice at all.
The trap compounds when combined with the broad exception handler pattern: code that swallows errors and logs nothing on any path is, by construction, a black box that only a human explicitly reconciling outcomes against expectation will ever catch. That reconciliation should not be the primary control. It should be the last line of defence behind logging that was designed in from the start.
When a client says “this used to work and I think it stopped,” this is the sequence, deliberately starting from outcome data rather than code, because reading the custom logic first wastes time on code that may be entirely correct against a world that no longer exists:
WHEN OTHERS or equivalent catch-all, and temporarily narrow it or add logging inside it during diagnosis, since it may already be hiding the actual failure.The diagnostic sequence above finds a failure after someone has already noticed something feels wrong. The better position is designing custom logic so a silent failure cannot stay silent for long:
Clients running this kind of structured, canary-backed regression approach across their customisation footprint report up to 60% less regression testing effort per release, because the testing is targeted at outcomes known to matter rather than a full manual click-through of every custom screen and rule after each upgrade.
Because the platform change it depends on is usually not a broken interface, it is a changed meaning: a renamed status value, a reordered trigger sequence, or a wrapper that never learns about a new parameter. The code stays syntactically and semantically valid PL/SQL, it just stops matching the data it was written against, so it compiles, executes, and quietly takes the wrong branch every time.
A release is exactly the event that relabels enum values, reorders standard business logic around trigger points, and adds parameters to existing procedures, while keeping enough backward compatibility that nothing refuses to compile. Extensions built strictly against the Extensibility Framework's published Custom Event trigger points and Custom Fields are largely insulated from this, because that contract is explicitly versioned. Extensions that reach into internal package logic or hard-coded literals inherit every internal change with no compatibility guarantee.
Compare the outcome volume before and after the release, not the code. How often did the rule's visible side effect - a block, a routed approval, a flagged record - occur per week before the release versus after. A sudden drop or flatline is the signal that something changed; reading the custom logic is the second step, not the first, because it wastes time confirming code that may be entirely correct against data that no longer exists in that shape.
Log the outcome on every code path, including the "evaluated, no action taken" path, replace broad exception handlers with narrow, logged ones, and add a scheduled canary test that runs a known scenario and checks the expected side effect actually occurred. This turns a silent failure into a logged, alertable event instead of something only a human reconciliation happens to catch months later.
Dariusz Myśliwiec - 18 years hands-on with IFS (Apps 7.5–10 and IFS Cloud). IFS Certified Associate Consultant. PRINCE2® 7. Based in Kraków, delivering remotely across Europe and globally through an independent practice.
Selected clients: Fugro · LGC · BVI Medical · Betafence (PRÆSIDIAD) · Barlinek · NGK Ceramics · Newag · Oleofarm.
IFS is a registered trademark of IFS AB; this practice is not affiliated with IFS AB.
Before your next R1/R2 upgrade, I can run outcome-volume checks across your custom Events and PL/SQL logic and tell you which ones stopped doing what they were built to do, and when.
Independent IFS Cloud practice · Expert notes
Key takeaways
Every cycle count programme eventually produces a variance report nobody fully trusts. Warehouse staff recount the same locations and get a different number each time; finance asks why the adjustment account keeps moving the same direction for the same part family; and the honest answer, more often than anyone wants to admit, is that the variance was never real, it was a side effect of when the count was taken relative to what else was moving through that location. Getting this right is not a tuning exercise on a tolerance field. It requires understanding what a count transaction actually compares itself against, why a flat threshold is structurally wrong for a mixed inventory, and how to build a rule that separates a genuine stock discrepancy from a transaction that simply had not posted yet.
A cycle count in IFS Cloud does not compare a physical count to “the current on-hand balance.” It compares a physical count, entered at a specific time, to whatever the system balance was for that part, at that inventory location, at the moment the count line was captured. That distinction matters because the on-hand balance is not static between the moment a counter writes a quantity on a handheld and the moment that count result is confirmed and posted. Every receipt, pick, issue, and internal move that touches the same location in that window changes the balance the system is holding, and the variance calculation has to decide, implicitly or explicitly, whether those changes belong to the counted balance or not.
The count itself typically runs through three stages: a count order or count point is generated for a location or a part, a count result is entered against it, and a variance is calculated as counted quantity minus expected quantity at the time of comparison. A variance inside tolerance is usually auto-approved as a routine adjustment; one outside tolerance routes to review and posts, once approved, at standard or average cost depending on the part’s costing method. The adjustment transaction itself is unremarkable; the part that deserves scrutiny is what “expected quantity at the time of comparison” actually included, and whether it included transactions still in flight.
The simplest variance tolerance configuration is a single flat percentage, such as five percent of counted quantity, applied uniformly across every part. That setting is defensible for exactly one slice of the inventory and wrong for every other slice, because tolerance needs to track two independent variables that a flat percentage ignores: unit value and transaction velocity.
The practical failure mode of a flat threshold is not that it generates too many exceptions or too few in aggregate. It is that it generates the wrong exceptions: it buries the loss that matters financially inside a percentage that looks acceptable, and it drowns the review team in noise from parts whose variance was never worth anyone’s time to investigate.
A true variance means the physical stock genuinely differs from what the system believes is there: a real discrepancy caused by unrecorded scrap, theft, a picking error that issued the wrong part or quantity, or a receipt that was put away against the wrong location. A timing variance means the physical count and the system balance disagree only because a transaction that affects one of them had not yet posted, or had posted but not yet been reflected in the balance the count was compared against, at the instant the count was captured. Both produce an identical-looking variance line: a quantity, a value, a part, a location. The distinction only becomes visible when the count result is joined against the transaction log for the same part and location, filtered to the window around the count.
| Signal in the transaction log | What it indicates |
|---|---|
| A goods receipt posted to the same location within minutes after the count was captured | Timing variance. The physical goods were likely already on the shelf when counted, but had not yet been posted to on-hand at that moment. |
| A pick confirmed against the location after the count snapshot but before the count result was approved | Timing variance. The counter saw stock that was about to leave; the system balance the count is compared to may or may not have caught up depending on when the comparison ran. |
| No transaction of any kind against the part and location for several count cycles preceding this one | Candidate true variance. With nothing moving, there is no timing explanation left; the discrepancy needs a physical explanation. |
| A repeated variance in the same direction, same part, across multiple consecutive cycles | Candidate true variance, and specifically a structural one such as a wrong unit-of-measure conversion or a bill-of-material issue quantity that consistently under- or over-relieves stock, rather than a one-off error. |
The practical rule of thumb worth internalising: a variance explained by a transaction dated within a short window either side of the count capture time is a timing variance and should be excluded from the “needs investigation” population entirely, not merely deprioritised. A variance with no transactional explanation in that window is a genuine candidate for physical investigation, and it is the only category worth sending a supervisor to walk the aisle for.
The naive reconciliation query compares counted quantity to on-hand quantity at the moment the report runs and flags anything outside a flat tolerance. A working version classifies each variance before it ever reaches a human, illustrated here as generic, PL/SQL-flavoured pseudocode using aliases rather than an assertion about a specific release’s exact schema:
| Signal | What it tells you |
|---|---|
| count_result.qty_counted - onhand_snapshot.qty_at_capture | The raw variance, computed against the balance as it stood at the exact capture timestamp, not against a later report-run balance. |
| EXISTS (SELECT 1 FROM inv_transaction_history t WHERE t.part_no = count_result.part_no AND t.location_id = count_result.location_id AND t.posted_at BETWEEN count_result.captured_at - :window_before AND count_result.captured_at + :window_after) | A transaction touched the same part and location inside the timing window around the count. This is the join that separates timing from true variance; skipping it collapses the rule back into the naive reconciliation query described above and reintroduces exactly the timing noise section 3 describes. |
| ABS(variance_value) > part_class.abc_tolerance_value OR ABS(variance_pct) > part_class.abc_tolerance_pct | Tolerance evaluated per ABC class rather than one flat number, catching material A-class loss and ignoring routine C-class noise as described in section 2. |
| COUNT(*) OVER (PARTITION BY part_no ORDER BY cycle_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) same-direction variances | Flags a repeated same-direction pattern across consecutive cycles, the structural signature described in section 3, rather than treating each cycle’s variance as an independent event. |
The transaction-window join is the piece worth defending if anyone proposes simplifying this rule. Without it, every count taken in an active location generates variance noise proportional to how busy that location is, which correlates with count scheduling, not with actual inventory accuracy.
A “hot count” is a count taken against a location that remains transactable, receiving and issuing normally, while the count is in progress. It manufactures variance directly, because ordinary receiving and picking activity during the count window changes the balance the count is compared against, and it is a scheduling decision rather than a system misconfiguration, which is why it survives round after round of tolerance tuning without ever being fixed. Freezing the location until the count is confirmed eliminates the problem structurally; loosening the tolerance to absorb the noise does not, it just hides real variance inside a wider band.
A second recurring misconfiguration is a unit-of-measure conversion factor that is wrong or missing between the stocking unit and the counting unit. A part counted in individual pieces but stocked and issued in a case quantity will show a variance that looks like shrinkage but is actually an arithmetic mismatch, and it will reproduce identically at every future count of that part until the conversion factor itself is corrected, not the count.
A third trap sits with lot- and serial-tracked parts. Quantity can be zero at the part level while individual lots are wrong: one lot short, another of the same part over by the same amount, because a picker took stock from the wrong lot without recording it. A rule that only checks part-level quantity will miss this; it needs lot or serial granularity to catch a misallocation that nets to zero but is a real traceability failure.
A true variance means the physical stock genuinely differs from the system balance, caused by unrecorded scrap, a picking error, or a misplaced receipt. A timing variance means a transaction affecting that balance simply had not posted yet at the exact moment the count was captured. Both produce an identical-looking variance line, and the only way to tell them apart is to join the count against the transaction log inside a window around the capture timestamp.
Because unit value and transaction velocity vary enormously across a mixed inventory. A flat percentage masks material loss on high-value, low-velocity parts inside a band that looks acceptable, while it flags constant routine noise on low-value, high-velocity parts. Tolerance needs to be set per ABC or value classification, not applied uniformly.
A hot count is a count taken against a location that remains transactable while the count is in progress. It manufactures variance directly: ordinary receiving and picking activity during the count window changes the balance the count is compared against. Freezing the location for the count eliminates the problem structurally rather than requiring a wider tolerance to absorb it.
Yes, when the classification logic and the Custom Event that routes surviving true variances to a supervisor are built inside the Extensibility Framework against the standard count result and inventory transaction entities, with no modification to the core count or adjustment logic itself.
Dariusz Myśliwiec: 18 years hands-on with IFS (Apps 7.5–10 and IFS Cloud). IFS Certified Associate Consultant. PRINCE2® 7. Based in Kraków, delivering remotely across Europe and globally through an independent practice.
Selected clients: Fugro · LGC · BVI Medical · Betafence (PRÆSIDIAD) · Barlinek · NGK Ceramics · Newag · Oleofarm.
IFS is a registered trademark of IFS AB; this practice is not affiliated with IFS AB.
If your cycle count report is flooded with noise or, worse, has quietly stopped catching real loss, the classification logic is the fix, not another round of recounting. A short scoping conversation is enough to tell you which.
Independent IFS Cloud practice · Sales
You confirmed the order to the customer: this quantity, this date. Later someone edits the line. A quantity moves, a date slips, a part is swapped. IFS Cloud accepts the change, because editing a confirmed order is allowed and often necessary. What it does not do is mark that the promise the customer is holding has quietly stopped matching the order in the system. The customer waits for what they were told. The warehouse ships what the record now says. The difference between the two surfaces at delivery, when it is too late to have the conversation that should have happened when the line changed.
Key takeaways
A confirmation is a moment: at that point the order said one thing and the customer was told it. After that the order is a live record that many hands can touch. Planning reschedules a line to match supply. A rep adjusts a quantity after a call. A part is substituted. Each edit is a reasonable thing to do, and IFS Cloud is right to allow it. None of these edits carries an obligation to go back to the customer, because the system does not treat the edit as breaking a promise. It just treats it as an update.
So the order and the promise drift apart. The record is current and correct. The customer’s understanding is current and correct as of the confirmation. Both are internally consistent, and neither knows the other has moved. Nothing sits between them asking whether this particular change is one the customer needs to hear about.
The silent change is not a broken process. It is a normal edit that happened to alter a promise, with no step that separates the edits worth a phone call from the ones that do not matter.
Amending a confirmed order is routine. The value is in separating the harmless edits from the ones that changed what the customer is expecting.
| What you see | What it usually points to |
|---|---|
| Confirmed delivery date moved later after confirmation | A promise the customer still holds at the old date, now unmet unless someone tells them. |
| Confirmed quantity reduced or a line removed after confirmation | A short shipment against what was agreed, likely to surface as a complaint or a query at delivery. |
| Part or item substituted on a confirmed line | A different product than the one confirmed, which the customer may or may not accept. |
| Repeated post-confirmation edits on orders to the same customer | A pattern that erodes trust in your confirmations, not a one-off adjustment. |
The first row is the quiet one. The date moved for a good internal reason, the order is accurate, and the customer is still planning around the date you confirmed. A rep looking at the order sees a valid delivery date and no reason to act. Compare the confirmed date to the current one, and the broken promise is right there to be fixed with a call.
The confirmed values and the current line values are both available through standard OData projections, so they can be read without touching a record. Detection compares what was confirmed to what the order says now and looks for two things:
Because it is a read-only monitoring pattern, it runs beside sales and writes nothing back to IFS. It adds no object inside the client system, and a standard R1 or R2 release does not touch it, because it only reads standard projections. It hands the rep a short list of confirmed orders that changed, and the call on which customer needs to hear about it stays with the person who owns the account.
It records the current state of the order and allows confirmed lines to be edited, which is by design. What it does not do on its own is compare the current line to what was confirmed and raise the ones that diverged, or distinguish an edit from a communication to the customer. That comparison, and the reminder that the customer may not know, is the gap this monitoring fills.
A promise gap at entry is visible the moment the order is taken, when the wanted date and the planned date do not match. This is later and quieter: the order was confirmed cleanly, everyone moved on, and only afterwards did an edit move a term the customer was already holding. It needs the confirmed value checked against the current one, not a check at entry.
No. Changing a confirmed order is often the right thing to do when supply or the customer's needs move. The aim is to make sure a change that alters the promise gets seen, so the account owner can decide whether the customer needs to be told, rather than the change slipping through silently and surfacing as a delivery the customer did not expect.
No. The confirmed values and the current line values are read through standard OData projections and compared outside IFS. Nothing is written back, so there is no upgrade footprint and no new object inside the client system.
Dariusz Myśliwiec brings 18 years of hands-on work with IFS (Apps 7.5–10 and IFS Cloud). IFS Certified Associate Consultant. PRINCE2® 7. Based in Kraków, delivering remotely across Europe and globally as an independent practice, so you talk to the consultant who builds it.
Selected clients: Fugro · LGC · BVI Medical · Betafence (PRÆSIDIAD) · Barlinek · NGK Ceramics · Newag · Oleofarm.
IFS is a registered trademark of IFS AB; this practice is not affiliated with IFS AB.
Tell me which accounts feel it most when a confirmed order changes without a call. On a 30-minute fit call I’ll show you how the SCM Automation Pack reads your confirmed values and current lines, flags the orders whose promise changed after confirmation, and does it read-only, with a dry-run period before anything reaches a rep.
Independent IFS Cloud practice · Sales
A promised date is a calculation dressed up as a commitment. At order entry the system offers a date, someone accepts it, and the customer hears a promise. Behind that promise sits an assumption about components, capacity, and timing. When the assumption holds, the promise holds. When the plan moves and the promise does not move with it, you have told a customer something the supply chain can no longer deliver, and you will find out when it is late.
Key takeaways
When a promise date is calculated, it reflects a picture of the world at that instant: what is on hand, what is on order, what capacity is free, and how long each step takes. Give the same order to the system a week later and the picture has changed. A supplier moved a date. A shared component was consumed by another order. A work centre filled up. None of that is unusual. It is what a live supply chain does.
The promise, though, was captured at a single moment and does not automatically re-plan itself as the world moves. It sits on the order as the number the customer was told. High fidelity means the promise and the plan stay close enough that the date is still real. Low fidelity means the promise is a fossil: accurate the day it was made, wrong ever since, and nobody looked.
These two questions get confused because both end in a worried planner. They are not the same check, and they fail in different ways.
| Question | What it checks | How it fails |
|---|---|---|
| Coverage | Does supply exist for what the order needs at all | An order with no supply behind it, covered in sales orders without coverage |
| Promising | Does that supply arrive in time for the date the customer was given | Supply exists, but later than the promise, so the date is quietly no longer achievable |
An order can pass coverage and still miss its promise. The parts are coming. They are just coming after the date you quoted. That is the gap this article is about, and it is the one that turns into a late delivery without anyone having made an obvious mistake.
Promised dates on sales lines and the planned supply behind them are readable through standard OData projections, without touching a record. Detection is a matter of comparing the two on a daily cycle, so the drift is caught while there is still room to act:
This is a read-only pattern. It runs beside IFS, writes nothing back, and does not re-quote the customer or move the promise for you. It surfaces the orders whose date and plan have come apart and lets a planner decide whether to expedite, re-plan, or call the customer early, which is a far better conversation than an apology after the fact.
A promise is high fidelity when the date given to the customer still matches what the plan can actually deliver. It is calculated from the availability of the components and capacity the order needs, and it stays close to the plan as that plan changes. Fidelity is lost when the promise is made once and never reconciled against later movement.
Coverage asks whether supply exists for the order at all. Promising asks whether that supply arrives in time for the date the customer was given. An order can have full coverage and still miss its promise, because the parts are coming later than the date quoted.
On-time delivery tells you the promise was missed after the delivery has already happened or failed. Watching the promise-to-plan gap tells you while the order is still open and there is time to expedite, re-plan, or warn the customer. One is a scorecard; the other is a chance to act.
No. Promised dates and the planned supply behind them are read through standard OData projections and compared outside IFS. Nothing is written back, so there is no new object inside the client system and the monitor cannot move a date or re-quote an order.
Dariusz Myśliwiec brings 18 years of hands-on work with IFS (Apps 7.5–10 and IFS Cloud). IFS Certified Associate Consultant. PRINCE2® 7. Based in Kraków, delivering remotely across Europe and globally as an independent practice, so you talk to the consultant who builds it.
Selected clients: Fugro · LGC · BVI Medical · Betafence (PRÆSIDIAD) · Barlinek · NGK Ceramics · Newag · Oleofarm.
IFS is a registered trademark of IFS AB; this practice is not affiliated with IFS AB.
Tell me which customers hold your tightest dates. On a 30-minute fit call I’ll show you how the SCM Automation Pack lists the orders whose promise and plan have drifted apart, with a dry-run week before anyone is asked to chase them.