npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

functional-location-dedup

v1.0.1

Published

Merge duplicate Functional Locations onto a master record.

Downloads

248

Readme

Functional Location De-duplicator — Power Platform ToolBox tool

by Mark Christie

Merge duplicate Functional Locations (msdyn_functionallocation) in Dynamics 365 Field Service onto a single master (survivor) record — reallocating every linked record onto the master, verifying, then deactivating or deleting the duplicates.

This is the Power Platform ToolBox packaging of a single dual-mode HTML app that also runs as a Dataverse web resource and inside XrmToolBox. It auto-detects the host (const PPTB = !!window.dataverseAPI): inside ToolBox all Dataverse calls go through window.dataverseAPI and the active toolboxAPI connection — the tool never handles tokens.


Why this tool exists

Dataverse's native Merge message only supports account, contact, lead and incident. Functional Location is not mergeable that way. So a "merge" here means: pick a master, reallocate every record that references each duplicate onto the master, confirm nothing still points at the duplicate, then retire the duplicate. Relationships are discovered from metadata at runtime, so custom (prx3_) lookups are handled automatically; platform-managed system relationships (async operations, sync errors, duplicate detection, etc.) are excluded.

What it does, in order

  1. Connect — uses the active ToolBox connection (no token handling).
  2. Match key — choose the fields that define a duplicate. Default Street 1 (msdyn_address1) + Postcode (msdyn_postalcode); optionally add a third field (e.g. Name) for a tighter, higher-confidence set. A record is only considered when every match field is populated (a blank match field is skipped — never merge on a blank postcode).
  3. Relationships — tick which related tables are counted, reallocated and verified. Default Account, Work Order, Agreement; add more (assets, property logs, warranty claims, …). Fewer relationships = faster.
  4. Search (optional) — limit the scan to records whose Name / Address Line 1 / Post Code contains a term (applied server-side).
  5. Duplicate groups to return — cap how many groups come back (10 / 100 / 1000 / 5000 / All), largest first.
  6. Scan (read-only) — Dataverse finds the duplicate keys via a server-side groupby aggregate; the tool then fetches just those groups and scores each record. Nothing is written.
  7. Review the dry-run — one row per record under each group, sorted by Master %.
  8. Choose the actionDeactivate (default, reversible) or Delete.
  9. Reallocate & merge — for every non-master in each ticked group: reallocate all linked records (of the ticked relationships) onto the master, re-verify the duplicate has zero remaining references, then deactivate/delete it. A duplicate that still has references is skipped, not forced.
  10. Result — a survivor list with a clickable link to each kept record and its Before (combined group count) vs After (live re-count) references. A full change log is downloadable.

The Master % score

Each record is scored 0–100 and the highest score becomes the master:

| Component | Weight | Meaning | |---|---|---| | Completeness | 45% | populated fields ÷ total fields on the record | | References | 35% | how many linked records it has, relative to the group | | Age | 20% | older createdon scores higher (more likely the original) |

Rows are sorted by score (master starred at the top). You can override the master with the radio button on any row. Oversized groups (> 25 records) skip scoring for speed — tick the group to count and score it on demand.

Safety

  • Scan and the dry-run are 100% read-only. Writes happen only after you confirm the dialog.
  • Deactivate sets statecode = 1 (Inactive) — fully reversible (reactivate the record).
  • Delete is permanent and is skipped automatically if any reference still remains.
  • Every action is recorded in a downloadable change log.
  • Always run against a sandbox first.

Theme

Follows the OS / ToolBox light or dark theme automatically (prefers-color-scheme).


Build & load (development)

cd pptb
npm run build          # copies the shared HTML + icon into dist/

Then in ToolBox → Settings → enable Debug Menu → Debug → Browse → select this pptb folder. Reopen the tool tab after each rebuild.

Publish

npm run build
npm publish --access public

Then submit via the Tool Submission Form at https://www.powerplatformtoolbox.com/. The published tarball contains dist/index.html + dist/icon.svg (see the files allowlist).

Single source of truth: the UI lives in ../webresource/prx3_FunctionalLocationMerge.html. build.js copies it into dist/. Edit that one file and rebuild to keep all hosts in line.