mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-20 01:39:57 +00:00
* fix(controllers): source trend report labels from the master item_name, customer_name, territory and supplier_name are stored on each transaction and editable, so they are not functionally dependent on the grouped key and historical documents can hold different values for the same item, customer or supplier. Aggregating them with Max() is a text sort, and MariaDB folds case while PostgreSQL orders by byte value, so the two engines can label the same row differently. Read each from its master instead. Those values ARE dependent on the grouped key, so they can be grouped without splitting rows and agree on both engines by construction rather than by an assumption about the data. Supplier needed no new join -- the Supplier master was already joined as t3 for supplier_group. A Quotation's party_name is a dynamic link to either a Customer or a Lead, so neither master can be joined without dropping the other; there the values come from correlated subqueries over both, keyed only on the grouped party_name. Row counts and every numeric total are unchanged. What changes is that a renamed record now shows its current name rather than whichever historical snapshot happened to sort highest. * test(selling): assert which label the trends report returns The existing tests assert the customer stays one row but never which territory or name comes back, so a divergence between engines passes unnoticed. Asserts both equal the Customer master's values while an order stores a different territory. * fix(controllers): resolve a Quotation's party label through quotation_to party_name is a dynamic link, so looking it up in Customer and Lead alone was wrong twice over: a Quotation raised against a Prospect or a CRM Deal got a blank label, and when a Lead shared its name with a Customer the Customer-first lookup returned the wrong record's name and territory. Resolve through the quotation_to discriminator instead, mirroring Quotation.set_customer_name -- Customer, Lead (company_name falling back to lead_name), Prospect, and CRM Deal. The CRM Deal branch is emitted only when its table exists, since it ships with the CRM app. quotation_to joins the GROUP BY as well: two parties of different types can share a name, and merging them into one row was never right. * style(controllers): name the quotation CASE branches semgrep's string-concat-in-list flags adjacent string literals inside a list, since that shape is usually a missing comma rather than deliberate. Bind each branch to a name first so the concatenation is unambiguous.
Selling management module. Includes forms for capturing / managing the sales process:
- Customer
- Campaign
- Quotation
- Sales Order
Moved to CRM Module:
- Lead
- Opportunity