Skip to content
English
  • There are no suggestions because the search field is empty.

How Product Deletion and Soft-Delete Logic Works

Source: products_controller.rb:240-264, products_controller.rb:249-257, product.rb:7

  • Three-tier deletion: (1) If the product has active invoice items, PO items, vendor invoice items, or a Xero ID, deletion is completely blocked. (2) If it only has historical (unscoped) references, it is soft-deleted (deleted = true). (3) If it has zero references and no active stocktake, it is hard-deleted permanently.
  • A product currently included in an active stocktake cannot be deleted at all -- the error message explicitly mentions the stocktake
  • The default scope on the Product model excludes deleted and inactive products from all standard queries: where("products.deleted is not true and products.inactive is not true")
  • Soft-deleted products still exist in the database and may appear in reports or unscoped queries
  • Reactivating a product requires an unscoped query because the default scope hides it from normal lookups

Support scenarios

  • "Why can't I delete this product?" → It has active invoice items, a purchase order reference, or a Xero ID linked to it
  • "Why does my deleted product still show up in reports?" → It was soft-deleted (marked deleted = true) rather than permanently removed because it had historical references
  • "I'm getting an error about stocktake when deleting" → The product is in an active stocktake; process or cancel the stocktake first
  • "How do I find my deleted product to reactivate it?" → Use the reactivate function, which uses an unscoped query to find inactive/deleted products