Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'hotcrm': patch
---

Two fields that were stored but shown on no list now appear in the panels
where people read them.

- **Subtotal** on a quote line item is now a column in the line items panel on
a quote's *Related* tab. It sits between **Sales Price** and **Total**. It is
the line after its own discount and before tax, so a rep can see how much of
a line's total is tax without opening each line.
- **Comment** on article feedback is now a column in the feedback panel on a
knowledge article, after **Verdict** and **Reader**. That is the note a
reader types to explain a *Not Helpful* vote. The article's author could
only read it by opening each feedback row.

Nothing is added, removed or renamed on either object. Both panels still show
every column they showed before.
2 changes: 2 additions & 0 deletions content/docs/sales/quotes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ A quote can have any number of line items — one per product being sold. Each l

The sum of line items rolls up into the quote subtotal.

On the quote's *Related* tab, the line items panel shows each line's product, quantity, sales price, subtotal and total. The subtotal is the line after its own discount and before tax; the total adds the line's tax rate on top.

## Built-in rules

- **Expiration date must be after the quote date** — no expired-on-creation quotes.
Expand Down
2 changes: 2 additions & 0 deletions content/docs/sales/quotes.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ Total Price = Subtotal − Discount + Tax + Shipping & Handling

行项目之和汇总到报价小计中。

在报价的 *Related* 标签页上,行项目面板列出每一行的产品、数量、单价、小计和合计。小计是扣除该行自身折扣之后、计税之前的金额;合计在此基础上再加上该行的税率。

## 内置规则

- **到期日期必须晚于报价日期**——不能创建即过期的报价。
Expand Down
2 changes: 2 additions & 0 deletions content/docs/sales/quotes.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ Total Price = Subtotal − Discount + Tax + Shipping & Handling

行項目之和彙總到報價小計中。

在報價的 *Related* 標籤頁上,行項目面板列出每一行的產品、數量、單價、小計和合計。小計是扣除該行自身折扣之後、計稅之前的金額;合計在此基礎上再加上該行的稅率。

## 內建規則

- **到期日期必須晚於報價日期**——不能建立即到期的報價。
Expand Down
14 changes: 14 additions & 0 deletions src/revenue/objects/quote_line_item.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ export const QuoteLineItem = ObjectSchema.create({
required: true,
storage: { notNull: true },
deleteBehavior: 'cascade',

// Curates the line-items panel on a quote's detail page (#1199) — the
// mechanism that panel reads first (#944; the long note is on
// `crm_campaign_member.crm_campaign`). A SUPERSET of the fallback it
// replaces (`highlightFields` minus this lookup: Product / Quantity /
// Sales Price / Total) plus `subtotal`, the line's price after its own
// discount and before tax — the formula was evaluated on every read and
// shown in no list. It sits before `total_price` because Total is
// Subtotal with the tax multiplier applied on top.
//
// ⛔ Not added to `highlightFields`: the detail page hoists the first
// four of that strip, so a fifth entry never reaches the strip, and
// reordering it would evict `total_price` from the record's header.
relatedListColumns: ['crm_product', 'quantity', 'unit_price', 'subtotal', 'total_price'],
}),

// Left on the restricting default on purpose — see the twin object: a
Expand Down
3 changes: 1 addition & 2 deletions src/sales/objects/account.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,7 @@ export const Account = ObjectSchema.create({
// reads off the derived form. ⛔ Do NOT answer the warning by authoring a
// `record:details` section — that is the escape hatch AGENTS.md reserves
// for a named customer demand, and it would trade acceptance 3 for a
// quieter log. `crm_article_feedback.comment` carries the same verdict on
// `main` for the same reason. No guard reads this warning.
// quieter log. No guard reads this warning.

incumbent_vendor: Field.text({
label: 'Incumbent Vendor',
Expand Down
17 changes: 16 additions & 1 deletion src/service/objects/article_feedback.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ export const ArticleFeedback = ObjectSchema.create({
// heading on forms and silently vanishes from detail pages
// (`field-group-shadowed`, the same trap `crm_campaign_member`'s `basic`
// group and `crm_task`'s `assignment` group each had to be rescued from).
// So the comment is the group's own content, one click into the row.
// So the comment is the group's own content on the row's detail page,
// and reaches the panel through `relatedListColumns` on the article
// lookup below instead (#1199).
highlightFields: ['crm_knowledge_article', 'verdict', 'owner_id'],

fieldGroups: [
Expand Down Expand Up @@ -135,6 +137,19 @@ export const ArticleFeedback = ObjectSchema.create({
group: 'basic',
deleteBehavior: 'cascade',
description: 'Knowledge article this feedback is about.',

// Curates the feedback panel on the article's detail page — the surface
// the article's AUTHOR reads (#1199). A related list reads
// `relatedListColumns` on the child's lookup before it falls back to
// `highlightFields` minus that lookup (#944), so this is a SUPERSET of
// the fallback (Verdict / Reader) plus `comment`: the note a reader
// types to explain a verdict was stored and shown on no list, and the
// author the field's own description names could not see it without
// opening each row. Last, because it is the one long value.
//
// ⛔ Deliberately NOT solved by adding `comment` to `highlightFields` —
// see the note above that list (`field-group-shadowed`).
relatedListColumns: ['verdict', 'owner_id', 'comment'],
}),

verdict: Field.select({
Expand Down
Loading