diff --git a/make_post_sell/views/product.py b/make_post_sell/views/product.py index f246ee7..e09d92f 100644 --- a/make_post_sell/views/product.py +++ b/make_post_sell/views/product.py @@ -255,30 +255,6 @@ def product_edit(request): product_modified = False product = request.product - # TEMPORARY DEBUG: log every product_edit hit so we can confirm the - # view is even being reached when fox attempts to save pricing_mode. - import os as _os_dbg - import time as _time_dbg - for _path_dbg in ( - "/opt/make_post_sell/pricing-debug.log", - "/tmp/mps-pricing-debug.log", - ): - try: - with open(_path_dbg, "a") as _f_dbg: - _f_dbg.write( - f"{_time_dbg.time():.3f} pid={_os_dbg.getpid()} ENTER product_edit " - f"product={product.uuid_str} method={request.method} " - f"submit={'submit' in request.params} " - f"pricing_mode={request.params.get('pricing_mode')!r}\n" - ) - try: - _os_dbg.chmod(_path_dbg, 0o644) - except Exception: - pass - break - except Exception: - continue - title = request.params.get("title", product.title).strip() description = request.params.get("description", product.description).strip() price = request.params.get("price", product.price) @@ -336,63 +312,20 @@ def product_edit(request): request.session.flash(("You updated the product's price.", "success")) # MPS-20 + MPS-21: pricing_mode + allow_offers (per-product overrides). - if "submit" in request.params: - # TEMPORARY DEBUG: log raw POST params for pricing_mode investigation. - # Writes to /tmp/mps-pricing-debug.log so we can read without sudo. - # Remove once the save defect is diagnosed. + # Gated on the pricing_mode field being present — it only appears on + # the product-title-and-description edit form, so other forms on the + # page (uploads, inventory, bundle) won't trigger this block. + # NOTE: do NOT gate on "submit" in request.params — the edit form's + # onsubmit handler disables the submit button before the browser + # collects form data, so "submit" is never sent. + if "pricing_mode" in request.params: try: - import logging as _logging - _logging.getLogger(__name__).warning( - "PRICING_MODE_DEBUG product=%s current=%s pricing_mode_param=%r " - "all_pricing_mode=%r submit=%r", - product.uuid_str, - product.pricing_mode, - request.params.get("pricing_mode"), - request.params.getall("pricing_mode") - if hasattr(request.params, "getall") else "no-getall", - request.params.get("submit"), - ) - except Exception: - pass - # Write to a path under /opt/make_post_sell where uwsgi has - # write access; /tmp may be sandboxed under PrivateTmp on some - # systemd configurations. World-readable so fox can tail without sudo. - import os as _os - import time as _time - for _path in ( - "/opt/make_post_sell/pricing-debug.log", - "/tmp/mps-pricing-debug.log", - ): - try: - with open(_path, "a") as _f: - _f.write( - f"{_time.time():.3f} pid={_os.getpid()} " - f"product={product.uuid_str} " - f"current={product.pricing_mode} " - f"pricing_mode={request.params.get('pricing_mode')!r} " - f"all_modes={list(request.params.getall('pricing_mode')) if hasattr(request.params, 'getall') else 'no-getall'} " - f"submit={request.params.get('submit')!r} " - f"all_keys={sorted(request.params.keys())}\n" - ) - try: - _os.chmod(_path, 0o644) - except Exception: - pass - break - except Exception: - continue - try: - new_mode = int(request.params.get("pricing_mode", product.pricing_mode)) + new_mode = int(request.params["pricing_mode"]) except (TypeError, ValueError): new_mode = product.pricing_mode if new_mode in (0, 1, 2, 3, 4) and new_mode != product.pricing_mode: product_modified = True product.pricing_mode = new_mode - # Flush immediately so the change persists even if a later - # block in this view raises. Defense in depth — the trailing - # dbsession.add(product) at function end also flushes, but we - # want to commit the pricing_mode change as soon as it is - # validated. request.dbsession.add(product) request.dbsession.flush() mode_label = { @@ -423,14 +356,15 @@ def product_edit(request): "success", )) - # allow_offers — three-state radio: inherit / yes / no. - allow_raw = request.params.get("allow_offers", "inherit") - new_allow = { - "inherit": None, "yes": True, "no": False, - }.get(allow_raw, None) - if new_allow != product.allow_offers: - product_modified = True - product.allow_offers = new_allow + # allow_offers — three-state radio: inherit / yes / no. Only + # process when the radio is actually present in the form. + if "allow_offers" in request.params: + new_allow = { + "inherit": None, "yes": True, "no": False, + }.get(request.params["allow_offers"], None) + if new_allow != product.allow_offers: + product_modified = True + product.allow_offers = new_allow # MPS-20: auction config — only meaningful when product has an # auction and the auction is still in DRAFT (locked once SCHEDULED). @@ -546,8 +480,14 @@ def product_edit(request): request.dbsession.add(auction) # torrent_opt_in — explicit per-product seeding consent. - # MPS-22: gated by global torrent kill switch. - if request.torrent_enabled and product.shop.torrent_enabled and "submit" in request.params: + # MPS-22: gated by global torrent kill switch. Gated on pricing_mode + # being present (signals the product-edit form, not uploads/inventory) + # rather than "submit" — see the pricing_mode block note above. + if ( + request.torrent_enabled + and product.shop.torrent_enabled + and "pricing_mode" in request.params + ): new_opt_in = request.params.get("torrent_opt_in", "off") == "on" if new_opt_in != product.torrent_opt_in: product_modified = True