Salesforce CPQ 报价模板(Quote Templates in Salesforce CPQ)

本模块系统讲解 Salesforce CPQ 报价模板:从 CPQ 的配置/定价/报价三环节与生成报价文档讲起,逐步创建并自定义报价模板——用 HTML、合并字段、模板分区与条件打印搭建结构,配置报价行表格与分组/小计/筛选,插入 Visualforce 自定义内容与预制内容,排查模板故障,并用动态报价条款、编号与条件逻辑生成专业、动态的提案 PDF。...

📅 2027/1/1 ✍️ ponybai 🏷️ salesforce, sales

一、Salesforce CPQ 报价模板入门(Get Started with Quote Templates)

slide_2

本单元介绍报价模板如何帮助完成销售、如何注册带 Salesforce CPQ 的 Developer Edition org,以及如何生成团队都能访问的报价 PDF。学完本单元,你将能够:描述报价模板如何帮助完成销售;注册一个启用 CPQ 的开发者 org;生成所有团队成员都能访问的报价 PDF。

快速把报价详情交给客户(一):CPQ 的作用(What CPQ Does)

slide_3

Salesforce CPQ 为销售代表提供了大量帮助,让他们既快又准地成交。CPQ 里的 C 是配置(Configuration)——轻松为客户挑选最合适的产品;P 是定价(Pricing)——点一下按钮就能完美计算出价格;Q 是报价(Quote)——把报价详情以 PDF 之类的提案文档交给客户。

那种在文字处理器里打开模板、逐字替换信息来为每笔交易定制提案的日子已经一去不复返了。Salesforce CPQ 早已掌握客户详情,也清楚这笔交易包含哪些产品和价格。只需几下点击,就能把所有这些数据合并进你自己的定制模板,在几秒钟内生成一份专业的提案——没有错别字、没有遗漏细节、没有未经批准的价格。下面就是一个 3 页提案的示例:

提案的第 2 页与第 3 页:

快速把报价详情交给客户(二):动态与电子签名(Dynamic + eSignature)

slide_4

提案不仅好看,还是动态(dynamic)的。比如,某位购买了订阅产品的客户,其提案可能需要包含一个特殊小节;而没有订阅的另一位客户则不需要看到它。Salesforce CPQ 利用它对这笔交易的了解来控制提案里出现什么内容。所以,管理员无需创建和维护两套模板,只需做一套就能同时应对两种情况。

最后,你还可以集成 DocuSign 之类的电子签名(eSignature)解决方案,让客户更快地返回签署好的文档。集成电子签名超出了本 badge 的范围,但下方资源可以帮助你。

在本 badge 中,你将了解销售代表如何用 Salesforce CPQ 把提案发送给客户和同事,也学习创建 CPQ 用来生成输出文档的模板。

注册带 Salesforce CPQ 的 Developer Edition org

slide_5

要完成本模块,你需要一个包含 Salesforce CPQ 和示例数据的特殊 Developer Edition org。现在注册免费的 Developer Edition 并连接到 Trailhead,以便完成本模块的挑战。注意,这个 Developer Edition 是专为本 badge 的挑战设计的,可能不适用于其他 badge。

  1. 注册一个免费的带 Salesforce CPQ 的 Developer Edition org。
  2. 填写表单:Email 输入一个有效的邮箱地址;Username 输入一个看起来像邮箱、且唯一的用户名(不必是真实邮箱,例如 yourname@cpq4ever.com)。
  3. 填完后点击 Sign me up。
  4. 收到激活邮件(可能要等几分钟)后打开,点击 Verify Account。
  5. 设置密码和密保问题完成注册。提示:记下用户名、密码和登录 URL 以便后续访问。

然后把新的 Developer Edition org 连接到 Trailhead:在 Challenge 区点击 playground 名称再点击 Connect Org,登录并点击 Allow、Yes! Save it。最后别忘了:本 badge 的活动只有在浏览器允许 force.com 弹出窗口时才有效。

生成第一份报价文档(一):生成与预览(Generate + Preview)

slide_6

先看看销售代表在发送报价时会经历什么。你从 Team Trailhead 为本 badge 专门制作的一份现成报价开始:

  1. 点击 App Launcher,点击 Salesforce CPQ 磁贴。
  2. 在导航栏点击 Quotes,选择 All 列表视图。
  1. 点击 Q-00053。这份报价有很多报价行,数量和折扣都做了调整以展示一些变化;本 badge 会反复用它测试你的成果,请保持产品和价格不变。
  2. 点击 Generate Document。此时文档尚未生成——销售代表会先得到一个选择不同模板的机会。
  3. 点击 Preview。几秒后出现生成文档的预览窗口。默认是 fit-to-page 视图(较小);想在包级设置里展开成全屏,可勾选 Full Page Preview。
  4. 点击 X 关闭预览窗口。

生成第一份报价文档(二):保存并发送邮件(Save & Email)

slide_7

现在记录这份报价的当前形态,并把副本发给客户:

  1. 在 Document Name 字段末尾加上 -Trailhead。文档名由报价编号和生成时间组合而成。
  2. 点击 Save & Email。这一下点击会做很多事:弹出邮件窗口,To 字段已根据报价的 Primary Contact 预填好,窗口底部还附上了提案 PDF。
  3. Subject 输入 Quote for laptops(真实销售里还要写邮件正文,这里可跳过)。
  4. 点击 Send。你注册 org 用的邮箱会被自动放进 BCC,所以你会收到和客户一样的邮件。
  5. 关闭弹出窗口。原来的 CPQ 标签页现在会显示一条 Quote Document 记录——CPQ 在你点击 Save & Email 的瞬间就创建了它。

生成第一份报价文档(三):报价文档记录(Quote Document Record)

slide_8

Quote Document 是一条记录留存工具,它精确显示提案是何时生成的、以及版本号(首次生成 Version 显示为 “1”)。这在回顾整个销售过程中发给客户的提案时特别有用;随时点击 View 就能查看这一版。

Quote Documents 相关列表显示了整笔销售中生成的每个版本。文档文件还会出现在商机(opportunity)的 Notes & Attachments 相关列表(因为包级设置 Attachment Target 被设为 Opportunity),也会作为一条 Chatter 帖子出现(因为 Post to Feed? 被勾选)。

如果只想生成记录而不邮件发送,在 Generate Document 页点 Save 即可;想快速查看提案,则用 Quote 记录上的 Preview Document 按钮。

二、创建你的第一个报价模板(Create Your First Quote Template)

slide_9

本单元介绍如何创建一个基础报价模板来生成简单提案、如何添加动态出现的水印,以及如何无痛迁移报价模板。学完本单元,你将能够:创建基础报价模板;添加动态水印;迁移模板而不出错。

一个简单的起点(一):创建 AW Proposal 模板

slide_10

销售代表通过点击 Generate Document 按钮来生成提案,并有机会选择模板。你的 CPQ org 自带一个示例模板,但实际中你可能想创建自己的模板来满足特定业务需求——比如不再需要传真号码,但想链接到社交媒体。

不修改模板直接输出,你会得到一个相当基础的文档,包含公司信息、客户、销售代表、产品和价格,以及签名块。下面是一个基础提案示例:

创建新模板很容易,先创建一个作为后续单元基础的模板:

  1. 导航栏点击 Quote Templates,点击 New。
  2. Template Name 输入 AW Proposal。
  3. 勾选 Default(让它在 Generate Document 页被自动选中)。
  4. Top Margin 输入 0.5。
  5. Company Name 输入 AW Computing,Company Slogan 输入 Always Winning!,Company Phone 输入 (650) 555-1212。
  6. Shading Color 输入 CCEEFF(一个漂亮的蓝色十六进制码,用来区分你的新模板)。
  7. 点击 Save。

一个简单的起点(二):预览它(Preview It)

slide_11

看看它在 Q-00053 上的效果:

  1. 导航栏点击 Quotes → Q-00053。
  2. 点击 Preview Document(AW Proposal 应自动选中)。
  3. 点击 Preview。看起来和上一单元很像,但带上了你自定义的蓝色底纹。
  4. 点击 X 关闭预览。

你可能会惊讶地发现新提案的 Terms & Conditions 下有一些文字——那是因为你的 CPQ org 预置了示例 Quote Terms,CPQ 会自动把它们加进所有提案。后面的单元会教你如何创建报价条款并管理它们的行为。

添加动态水印(一):找到水印 ID(Find the Watermark ID)

slide_12

销售代表在谈判时常会为一笔交易生成多份提案,这些「进行中」的提案通常还没被管理层批准,所以要让客户清楚自己收到的不是最终版。Salesforce CPQ 内置了在特定条件下(如报价未获批准时)显示水印的能力。

设置动态水印需要几步,且要进入 Salesforce Classic 一下,但非常值得。先找到 CPQ 托管包里水印图片的文档 ID:

  1. 点击个人头像图标,点击 Switch to Salesforce Classic。
  2. 点击标签栏的 + 号显示全部标签。
  3. 点击 Documents。
  4. 点击 Salesforce CPQ Assets 文件夹旁的 Go!。
  5. 点击 Draft Watermark。
  1. 从地址栏 URL 末尾复制 15 位 ID。
  2. 点击 Switch to Lightning Experience。
  3. 导航到 Quote Templates → AW Proposal → Edit。
  4. 把复制的 ID 粘贴进 Watermark ID,点击 Save。

添加动态水印(二):显示它 + 自定义图片

slide_13

现在水印「可能」出现在提案上,但默认不显示——报价上的 Watermark Shown 字段必须被勾选。实际中不建议让销售代表手动控制这个字段,而是用 Process Flow 自动化:当报价 Status 不是 Approved 或 Accepted 时勾选它,否则取消勾选。

测试:从 Quotes 标签点击 Q-00053,勾选 Watermark Shown 并 Save,再 Preview Document → Preview,草稿水印就会出现在每一页的背景层。

为简单起见,本模块其余部分假设 Watermark Shown 未勾选。如果你想用自己的 PNG 图片作水印,把它上传到 Documents 下的某个文件夹,并勾选 Externally Available Image,然后把模板的 Watermark ID 换成你自己文档的 ID。若忘记标记为 externally available,水印就根本无法出现在提案里。

开发和迁移模板(Developing and Migrating Templates)

slide_14

负责任的 admin 会在沙盒里开发和测试,再迁移到生产环境。迁移报价模板时要注意几点:

  • 如果你用了自定义草稿水印,迁移时也要迁移水印文档;迁移完报价模板后,要把它的 Watermark ID 字段更新为生产 org 里新水印的 ID。
  • 迁移记录时,有时需要先打开导出的 CSV 文件微调再上传。这个看似无害的步骤可能会坑到报价模板:一些表格软件会「好心」地把 000000 这样的数字重格式化成 0。而 000000 不仅是数字,还是表示黑色的十六进制码,是报价模板里很常见的颜色。于是 CSV 上传后,Border Color 之类字段可能被误设成 0,导致模板损坏,销售代表预览或生成提案时报错。所以编辑 CSV 时,要撤销表格软件的重格式化,并把颜色相关列设为文本。

最后,报价模板的 Deployment Status 默认是 In Development——该状态的模板只有 admin 能在 Preview Document 和 Generate Document 页看到。迁移完并验证无误后,把它改为 Deployed,销售代表就能看到并使用它了。

三、构建自定义报价模板结构(Structure a Customized Template)

slide_15

本单元介绍如何创建包含表格和文本的模板内容、如何把报价及相关记录的数据合并进模板内容,以及如何用模板分区组装报价模板。学完本单元,你将能够:创建包含表格和文本的模板内容;合并数据;组装模板;描述 HTML 的作用。

模板的构建模块(The Building Blocks of Templates)

slide_16

上一单元的基础模板能以一致的方式把报价详情分享给客户,但有一些明显局限:无法改变文档结构,布局始终一样,而且缺少封面页等典型提案部件。大多数企业都想更灵活地控制提案结构,Salesforce CPQ 为此提供了定制模板的工具。

定制模板的关键是 Template Content(模板内容)。可以把一条模板内容记录想象成拼图的一小块,拼起来就是完整提案。例如,你可能需要一块显示客户和销售代表联系信息的模板内容,它看起来像这样:

作为 admin,你会创建很多块模板内容,逐步建立一个可复用的内容库,然后用这些内容块组装出一个自定义报价模板,让提案逐块逐块地显示出来。

用 HTML 编辑器创建内容(一):构建表格(Build the Table)

slide_17

你的 CPQ org 已预置了一些模板内容,但先创建一块自己的、用于显示联系信息的内容:

  1. 导航栏点击 Template Content → New。
  2. 类型选 HTML,点击 Continue。
  3. Content Name 输入 AW Contact Details。
  4. 点击 Table 图标,Rows 输入 2,点 OK。
  5. 左上单元格输入 Prepared For,右上单元格输入 Prepared By。
  6. 把下面这段代码粘贴进左下单元格:{!quote.SBQQ__BillingName__c}、{!primaryContact.Name}、{!primaryContact.Email}、{!primaryContact.Phone}。
  7. 把这段代码粘贴进右下单元格:{!template.SBQQ__CompanyName__c}、{!salesRep.Name}、{!salesRep.Email}、{!template.SBQQ__CompanyPhone__c}。
  8. 点击 Save。

内容看起来像这样:

用 HTML 编辑器创建内容(二):合并字段来源(Merge Field Sources)

slide_18

你刚粘贴的是一堆合并字段(merge fields),CPQ 会在生成提案时把它们替换成某份报价的真实数据。合并字段总是用「数据源 + 字段」的格式来描述,例如 {!quote.SBQQ__BillingName__c} 表示数据源是 quote、字段是 SBQQ__BillingName__c。数据源以感叹号开头,源与字段之间用句点分隔,整体包在花括号里。

有五个可以引用的数据源:

  • !quote:报价记录本身。
  • !primaryContact:报价 Primary Contact 查找所引用的联系人记录。
  • !salesRep:报价 Sales Rep 查找所引用的用户记录。
  • !template:预览或生成提案时选中的报价模板记录。
  • !document:CPQ 生成提案时创建的报价文档记录。

无法直接插入其他对象(如商机)的数据——需要先在报价上创建一个公式字段返回你想展示的值,再用 !quote 源合并它。!quote 和 !template 支持自定义字段,!primaryContact 和 !salesRep 不支持。

给 HTML 添加样式(Add Styling to HTML)

slide_19

现在这块内容能用,但样子有点单调——基本是黑白、没有边框和底纹。在把它关联到模板之前,先用 HTML 样式标签美化一下:

  1. 在 AW Contact Details 记录上点击 Edit,再点击 Source。
  2. 把 Markup 窗口的全部内容替换成带样式的 HTML 代码(设置列宽 35%、3px 内边距、黑色实线边框,并用 {!template.SBQQ__ShadingColor__c} 合并字段给第一行上底色)。
  3. 点击 Save。

用合并字段取颜色而不是硬编码,这样只需在模板层面改一次,你的内容也会跟着变。

把模板内容添加到模板(Add Template Content to a Template)

slide_20

那 CPQ 怎么知道该用哪些模板内容、以什么顺序放进提案?答案是 Template Section(模板分区)记录。每个分区关联一条模板内容,并用 Display Order 字段从上到下排序。把内容加到模板:

  1. 导航栏 Quote Templates → AW Proposal → Related 标签。
  2. 在 Sections 相关列表点 New。
  3. Section Name 输入 Contact Details,Content 选 AW Contact Details。
  4. Display Order 输入 10(建议按 10 的间隔编号,方便以后在中间插入)。
  5. 点击 Save。

注意:一旦你给模板添加了分区,就相当于告诉 CPQ 不再使用基础提案的标准结构,剩下的部分需要你自己搭建。模板内容可以在不同模板间复用,日后更新一处,所有使用它的模板都会同步更新。

四、给模板分区添加条件(Add Conditions to Template Sections)

slide_21

本单元介绍如何基于条件显示和隐藏模板分区、如何给报价模板附加一个重复出现的页眉,以及如何设置两个互斥的分区。学完本单元,你将能够:按条件显示/隐藏分区;添加重复页眉;设置二选一的分区。

知道何时显示(一):设置条件打印(Set Up Conditional Print)

slide_22

企业往往需要不止一种提案来应对不同报价场景——比如有封面页的正式提案,和跳过封面的更随意的提案。能否在一个模板里同时支持两者?可以,通过分区的 Conditional Print Field。

Conditional Print Field 告诉 CPQ 用哪个报价字段来决定该分区是否出现。例如,在报价上建一个名为 Include Cover Page 的复选框,销售代表按需勾选。生成提案时 CPQ 检查这个复选框,勾选就把该分区放进提案。先创建这个复选框:

  1. 点击设置图标进入 Setup → Object Manager → Quote → Fields & Relationships → New。
  2. 类型选 Checkbox,Field Label 输入 Include Cover Page(确认 Field Name 是 Include_Cover_Page)。
  3. 一路 Next 到 Save。

然后更新 Conditional Print Field 的 picklist:在 Template Section 对象里找到 Conditional Print Field 字段,新增值 Include_Cover_Page__c(CPQ 的 picklist 里引用字段要用 API 名)。

知道何时显示(二):封面分区 + 测试(Cover Page Section + Test)

slide_23

接着创建封面页的模板内容,再做一个响应这个字段的分区:

  1. 新建 AW Cover Page 内容(HTML,含 logo 和合并字段)。
  2. 在 AW Proposal 的 Sections 里新建分区:Section Name Cover Page,Display Order 1,Conditional Print Field 选 Include_Cover_Page__c,Page Break 选 After。
  3. 点击 Save。

测试:在 Q-00053 上勾选 Include Cover Page 并保存,再 Preview Document → Preview,封面页就会作为第一页出现,并用分页符与下一个分区隔开。除了复选框,能触发分区出现的字段类型还有:值为 “true” 的文本/picklist 字段、非零的数值/货币字段、以及返回 true 或非零值的公式字段。

添加一个简单的页眉(Add a Simple Header)

slide_24

有些模板内容需要出现在每一页,而不只是分区记录定义的那一处——页眉和页脚通常就是这样反复出现的。CPQ 允许你把一些模板内容直接关联到报价模板本身。做一个包含报价编号、到期日和 AW Computing logo 的简单页眉,让它出现在除第一页外的所有页:

  1. 新建 AW Header 内容(HTML,含报价编号、版本、到期日和 logo)。
  2. 在 AW Proposal 上点击 Edit:Header Content 选 AW Header;Exclude Header & Footer 选 First Page;Header Height 输入 60。
  3. 点击 Save。

Header Height 会为页眉预留 60px 空间;如果留空,页眉会和页面第一个分区重叠。

创建反向条件公式(Create a Reverse Conditional Formula)

slide_25

现在 AW Proposal 被设为在第一页跳过页眉,因为我们不想让页眉出现在封面页上。但有时提案会因为 Conditional Print Field 而没有封面页,这样提案就会直接从联系信息分区开始,看起来不太好。更好的做法是:当没有封面页时,在第一页显示页眉。为此要做一个公式复选框,让它始终返回 Include Cover Page 的相反值:

  1. 在 Quote 对象上新建 Formula 字段,Field Label 输入 Include Header(Field Name 为 Include_Header),返回类型选 Checkbox。
  2. Simple Formula 输入 IF(Include_Cover_Page__c, false, true)。
  3. 把 Include_Header__c 加进 Conditional Print Field picklist。
  4. 新建一个 First Page Header 分区,Content 选 AW Header,Display Order 1,Conditional Print Field 选 Include_Header__c。

现在当 Include Cover Page 为 false 时,Include Header 就为 true。用同一个 Display Order 也没关系,因为两个分区中永远只有一个会出现。借助公式和 Flow 等核心 Salesforce 功能,提案可以变得真正动态。

五、在表格中显示报价行数据(Show Quote Line Data in a Table)

slide_26

本单元介绍如何创建报价行表格来展示产品和价格、如何确定表格显示哪些报价行字段、如何按条件显示/隐藏列,以及如何用开箱即用的选项调整样式。学完本单元,你将能够:创建报价行表格;确定字段;按条件显示列;调整样式。

指定报价行表格位置(一):Line Items 内容

slide_27

模板渐渐成形了,但还没向客户展示你谈好的产品和价格。报价行数据表格正合适。先创建一个特殊的模板内容:

  1. 导航栏 Template Content → New,类型选 Line Items(它是个占位符,会随报价行增加而自动扩展)。
  2. Content Name 输入 AW Line Items,点击 Save。

再为它建一个分区:Section Name Line Items,Content 选 AW Line Items,Display Order 30。预览 Q-00053 就会看到产品和价格表格:

CPQ 怎么决定显示哪些字段?答案在模板的 Line Column(行列)记录里。每次创建报价模板,CPQ 都会自动生成一组相关的行记录,每个对应表格的一列,包含列标题、显示顺序、宽度、字段名等。

指定报价行表格位置(二):调整列(Tweak the Columns)

slide_28

开箱即用的列是不错的起点,但可以微调。先调整 part number 列:

  1. 在 Line Columns 相关列表中,对 PART # 记录点 Edit。
  2. Column Heading 改为 PRODUCT,Field Name 改为 SBQQ__ProductName__c(显示用户友好的产品名而非零件号),Width 改为 35。
  3. 点击 Save。

再更新 UNIT PRICE、DISC (%)、EXTENDED 这几列的标题和字段,并删除 DESCRIPTION 列腾出空间。记住:所有可见列的宽度总和不要超过 100,否则表格会超出页边距。

按条件显示列(Show Columns Conditionally)

slide_29

你可能注意到表格只占了 75% 宽——这是为了再加 Partner Discount 和 Partner Price 两列。它们是特殊列,只在确实存在合作伙伴折扣时才出现。切换列的开关是行记录上的 Conditional Print Field 字段,它指向一个报价级字段,用法和分区的条件打印一样。

这里用报价字段 SBQQ__AveragePartnerDiscount__c 来驱动:如果它为零,这两列就消失。

  1. 新建行记录:PARTNER DISC (%),Display Order 70,Field Name SBQQ__PartnerDiscount__c,Width 10,Alignment Right,Conditional Print Field 选 SBQQ__AveragePartnerDiscount__c。
  2. 再新建:PARTNER PRICE,Display Order 80,Field Name SBQQ__PartnerTotal__c,Width 15,同样设置条件字段。

打印一份没有合作伙伴折扣的报价时,默认 CPQ 会把缺失的列宽加到最宽的剩余列上,表格会被拉宽(如上图右)。如果你不希望这样,勾选该行记录上的 Discard Width When Hidden。

其他外观调整(Other Appearance Tweaks)

slide_30

每条行记录都有一些样式字段,模板和相关记录上也有不少能快速改变表格结构的字段:

  • Separate Line:把报价行数据放到自己单独的一行,若字段无数据则自动移除。
  • Hide On Product Options:如果报价行是 bundle 中的选项,把 $0 显示为 “Included”。
  • Table Style(仅 Line Items 类型内容):对分段的订阅产品,用专门格式展示每段详情——Price Dimensions as Columns 或 Price Dimensions as Rows with Summary。
  • Hide Column Header(分区复选框):去掉表头。
  • Show Discount Schedule(模板复选框):为有量价的产品显示折扣层级明细。
  • Line Sort Field(模板 picklist):按所选字段字母排序,而非 Line Number。

设置多个报价行表格(Setting Up Multiple Line Item Tables)

slide_31

有这么多自定义方式,有些企业可能想在提案中展示多个版本的表格——一个简化的表格信息量较少,另一个则包含大量定价细节和详细描述。

两个表格意味着两套行记录。每套行记录都可以通过 Section 查找字段关联到不同的分区。比如一个 Simplified Table 分区关联产品名、数量、净价等列,而 Detailed Table 分区则关联更多其他列。

如果某个列(如 Quantity)在所有分区里属性都一样,就把它 Section 字段留空,它就会出现在所有分区里。

六、重新排列报价行表格(Rearrange the Line Item Table)

slide_32

本单元介绍如何把报价行拆成多个表格、在表格中创建含小计的组、控制表格下的合计,以及按各种条件显示/隐藏报价行。学完本单元,你将能够:拆分报价行;创建含小计的组;控制合计;按条件隐藏行。

必须把它们分开(Gotta Keep 'Em Separated)

slide_33

预览 Q-00053 时,所有报价行都放进了一个表格,通常没问题。但有些企业想把报价行拆成多个表格,让报价更好读,并展示相关产品的小计。用 Salesforce CPQ,你几乎可以按任何标准对报价行分组。

分组只需告诉 CPQ 按哪个报价行文本字段分组。先用一个公式字段把订阅产品和非订阅产品分开:

  1. 在 Quote Line 对象新建 Formula 字段,Field Label Purchase Type,返回类型 Text。
  2. Formula 输入 IF(ISPICKVAL(SBQQ__SubscriptionPricing__c, ""),"One-time Purchases","Subscriptions")。
  3. 把 API 名 Purchase_Type__c 加进 Quote Template 对象的 Group Field picklist。
  4. 在 AW Proposal 上:Group Shading Color 输入 F5F5F5,Group Font Size 输入 12,Group Field 选 Purchase_Type__c。

注意几点:捆绑产品可以拆到不同组;如果销售代表在 Quote Line Editor 用了 Quote Line Groups,CPQ 始终以他们的分组为准;分区记录上的 Group Field 优先级高于模板上的。

组中再分组(Groups Within Groups)

slide_34

如果你喜欢分组,会更喜欢子分组(subgrouping)——它基于另一个报价行字段再加一层。分两步:先选 Product Family,再让 CPQ 对某列求和:

  1. 在 AW Proposal 上 Edit:Sub Group Field 选 Product Family。
  2. 在 Line Columns 里编辑 CUSTOMER TOTAL:Summary Level 选 Sub Group,Summary Function 选 SUM;对 PARTNER PRICE 也做同样设置。
  3. 编辑 PRODUCT 列:Summary Level 选 Sub Group,Sub Group Summary Label 输入 {0} Subtotal({0} 会被替换成产品族名,如 “Hardware”)。

现在每个产品族内会出现带标签和小计的汇总行。

完全控制合计(Total Control of Totals)

slide_35

默认表格右下角有个合计,但有很多字段可以改变表格下、以及所有表格后显示的内容,它们分布在模板和分区上:

  • Print Quote Totals(分区):分组时在组表格后显示整体报价合计。
  • Subtotal Field(模板):添加 List/Regular/Customer/Net 其中一种小计。
  • Show Customer Discount / Customer Discount Field(模板):勾选后添加所选客户折扣字段的值。
  • Show Partner Discount(模板):添加计算出的合作伙伴折扣。
  • Total Field(模板):选择 List/Customer/Net 其中一种合计(留空显示 List Price)。
  • Hide Group Subtotals / Hide Totals(模板):分别隐藏小计或合计。
  • Summary Display(分区):“Always” 无条件显示小计与合计,“Never” 无条件移除。

用基本控件隐藏报价行(Hide Line Items Using Basic Controls)

slide_36

虽然我们平等地爱每一行报价,但有些行没那么重要。有几个字段能快速决定某行是否出现在提案里(都在报价模板上):

  • Hide Component Products:勾选后移除 bundle 的选项产品(默认显示)。
  • Show Bundled Products:勾选后显示标记为 “Bundled” 的选项(默认排除)。
  • Show All Package Products:勾选后显示零值 “virtual bundle” 父级(默认排除)。
  • Show Renewed Products:勾选后显示续约报价中已续约订阅的非订阅父级和同级(默认排除)。
  • Quote Line Visibility(产品选项):设为 “Never” 或 “Editor Only” 时移除该选项行。

要留意:被 Hide Component Products 和 Quote Line Visibility 隐藏的行仍会算进报价合计。如果用到这两者,考虑把价格相关列换成 Package List Total 和 Package Total 字段,它们显示选项与父级价格之和。

用筛选隐藏报价行(Hide Line Items Using Filtering)

slide_37

预置的隐藏复选框虽然方便,但很有限。还有一种按任意条件隐藏行的方法。例如,你不想显示标记为 Optional 的报价行(Optional 行用于标识潜在 upsell,不计入报价合计):

  1. 在 AW Proposal 的 Sections 里,对 Line Items 分区点 Edit。
  2. Filter Field 选 Optional,Filter Operator 选 equals,Filter Value 输入 false。
  3. 点击 Save。

Q-00053 上被标记为 optional 的 Tablet 产品现在从表格里消失了。注意:这样筛选不会把它们的价值从报价合计里移除——对 optional 产品无所谓,因为它们本来就不计值;但若筛掉了有值的产品,最好另建一个只显示这些产品的表格,让客户明白总报价来自哪里。

七、插入 Visualforce 内容并排查模板(Visualforce + Troubleshoot)

slide_38

本单元介绍如何添加基于 Apex 和 Visualforce 的自定义模板内容、如何使用预制内容创建常见提案分区,以及如何排查损坏的报价模板。学完本单元,你将能够:添加自定义内容;使用预制内容;排查模板问题。

自定义代码内容(一):Apex + Visualforce

slide_39

前面你看到如何添加 HTML 内容和可定制的报价行表格。这些工具能带你走很远,但有时会遇到它们的极限——比如你想显示一个随报价产品数量增长的项目符号列表或表格,而静态 HTML 处理不了动态尺寸。这类特殊场景有一个技术性强但很强大的方案:Apex 和 Visualforce。这些代码工具几乎能按任何你需要的方式处理报价数据。

我们不假设你是编程专家,所以直接给你代码,重点放在设置机制上。用我们给的代码,你创建一个动态的 Consumption Schedules 表格(用于展示像手机流量套餐那样的分层用量费率)。先创建一个 Apex 类:

  1. 在 Setup 的 Quick Find 输入 apex,点击 Apex Classes → New。
  2. 把 CustomTemplateController 类的代码粘贴进编辑器,点击 Save。
  3. 再输入 visual,点击 Visualforce Pages → New。
  4. Label 输入 ConsumptionSchedulesVFP,把 <apex:page> 的标记代码粘贴进去,点击 Save。

自定义代码内容(二):在分区中引用它(Reference It in a Section)

slide_40

最后一步是在自定义内容里引用这个 Visualforce 页面,并放进报价模板:

  1. 导航栏 Template Content → New,类型选 Custom。
  2. Content Name 输入 AW Consumption Schedules,Custom Source 输入 /apex/c__ConsumptionSchedulesVFP,点击 Save。
  3. 在 AW Proposal 的 Sections 里新建分区:Section Name Consumption Schedules,Content 选 AW Consumption Schedules,Top Margin 0.25,Display Order 40。

我们的代码内置了逻辑:只要报价不含带 consumption schedule 的产品,就什么都不显示。Q-00053 里有 Smartphone Standard Plan 这样的产品,所以预览时会出现一张拆解单价费率的表格。只要你能维护代码,Visualforce 是引入复杂内容的绝佳方式。

插入预制内容(Drop In Premade Content)

slide_41

几乎每个报价模板开头都需要展示报价编号、联系信息等基本信息,结尾也需要签名块。Salesforce CPQ 为这两块关键内容提供了便捷的预制内容。

  1. 新建 Template Bottom 类型内容,Content Name AW Signatures,删掉签名表上方所有内容后 Save。
  2. 新建分区 Signatures,Content 选 AW Signatures,Top Margin 0.5,Display Order 50。

类似地,Template Top 内容类型给你一个可修改的基础起点,展示报价编号等报价详情:

注意:Template Top 和 Template Bottom 的内容源自 Documents 里 SteelBrick CPQ Template Resources 文件夹中的 HTML 文件,改动那些文件会影响每一块新建的 Top/Bottom 内容。

排查报价模板(Troubleshooting Quote Templates)

slide_42

HTML 和 Visualforce 内容给了你很大灵活性,但必须小心处理。格式错误的代码很可能损坏模板,导致用户侧报错。

可惜出现的报错信息不一定能帮你定位问题。这时你要当侦探,我们推荐这样排查:

  • 先用 Clone with Related 按钮克隆模板;
  • 清空克隆模板的 Header Content 和 Footer Content 字段;
  • 预览克隆提案看是否正常渲染——正常则问题在页眉/页脚内容;
  • 不正常就逐个删除克隆模板的分区并重新预览,直到定位到问题分区。

另外,报价模板里多处用到 API 名,拼错的 API 名同样会破坏模板(系统没有校验),所以尽量复制粘贴。这也是为什么把模板内容拆成多个小块比一大块更好——更容易定位问题。

八、显示动态报价条款(Show Dynamic Quote Terms)

slide_43

本单元介绍如何在报价模板中创建专门的报价条款分区、如何用父子关系组织条款、如何按条件显示/隐藏条款,以及如何决定用户是否可以编辑条款。学完本单元,你将能够:创建条款分区;组织条款;按条件显示条款;控制编辑权限。

排版你的条款(Lay Out Your Terms)

slide_44

提案不只是把客户感兴趣的产品信息交给客户,通常还包含交易的重要条款和条件(比如退货政策)。这类附加文本在报价模板中以 Quote Terms(报价条款)表示。

一条 Quote Term 记录代表你想要出现在提案中的条款之一。CPQ 把这些条款组装成一块,放在你想要的任何位置(如签名区上方)。先为条款安排位置:

  1. 新建 Quote Terms 类型内容,Content Name AW Terms,Font Size 输入 10。
  2. 在 AW Proposal 的 Sections 新建分区 Terms,Content 选 AW Terms,Top Margin 0.25,Display Order 45(夹在 consumption schedules 和签名块之间)。
  3. 导航到 Quote Terms → New:Print Order 输入 10,勾选 Active,Body 粘贴退货政策文本(如「产品可在交付后 60 天内退货……」)。

条款里也能像 HTML 内容那样用合并字段,比如用 {!quote.SBQQ__ExpirationDate__c} 让到期日动态显示。

组织和编号条款(Organize and Number Terms)

slide_45

条款一多,那一大块文本就会显得臃肿。可以用父子关系组织条款,并开启编号让客户更易读:

  1. 在 Quote Terms 的 All 列表视图里,把 QT-0000 和 QT-0001 的 Parent Term 设为你刚创建的 QT-0006。
  2. 在 AW Proposal 上勾选 Number Terms,点击 Save。

这样条款就会显示成 1.1、1.2 这样的编号。若想在不同位置显示不同条款,可以创建两块模板内容(如 AW Terms 1、AW Terms 2)放进不同分区,再用每条条款记录上的 Template Content 查找字段分配内容。注意两点:父子条款可能被拆散(此时子条款会按独立条款编号);没有分配内容的条款会出现在每个条款分区里。

让报价条款按条件显示(一):条款条件(Term Conditions)

slide_46

并非所有客户和所有交易都相同,所以企业希望特定条款只在特定交易里出现。Salesforce CPQ 知道报价的所有细节,可以用它们判断某条条款是否属于某份提案。

例如,让退货政策条款对有铂金服务等级协议(SLA)的客户消失。为此要创建一条与条款相关的 Term Condition:

  1. 导航到 QT-0006 → Related → Term Conditions → New。
  2. Tested Field 选 AccountSLA__c,Operator 选 equals,Value 输入 bronze,silver,gold(逗号分隔可一次测试多个值)。
  3. 点击 Save。

Q-00053 是 University of Arizona 这个铂金客户,所以这条条款不应出现——而且它的两条子条款也一起消失了(父级消失,子级跟着消失)。

让报价条款按条件显示(二):高级逻辑(Advanced Logic)

slide_47

除了测试单个字段,还有更多条件选项:

  • 测试一个汇总变量(summary variable)——它是一种强大的 CPQ 工具,能把一组数据(如报价行)汇总成单个值。例如统计订阅报价行的数量,大于 0 时就显示一条关于提前终止的条款。
  • Conditions Met 字段默认为 “All”(所有条件都满足才显示),改成 “Any” 则任一条件满足即显示。

还支持复杂的条件逻辑。例如「第一个条件为真,或者第二、三个同时为真」,分三步:给每个条件的 Index 字段设唯一值(如 100、200、300);在条款的 Advanced Condition 字段用 AND、OR 和括号写逻辑,如 100 OR (200 AND 300);把 Conditions Met 改为 “Custom”。

让用户修改条款(Let Users Modify Terms)

slide_48

大多数时候销售代表不该改动精心编写的条款。不过你也可以给他们编辑权限。报价记录上有个 Modify Quote Terms 按钮,点击后会展示某模板所有满足条件的条款,点某条条款即可打开一个简单编辑器。

如果保存了对条款的修改,不会更新原始条款记录(那会是一场灾难),CPQ 会创建一条关联到当前报价的克隆记录。即便如此,允许代表改条款仍可能有风险——有些条款永远不该被改,这时就勾选条款记录上的 Locked 复选框,界面会给该条款显示一个挂锁图标。

从封面页到签名行,你的报价模板现在已经能在几下点击内生成专业、动态的提案了。干得漂亮,admin!


文章来源:Trailhead - Quote Templates in Salesforce CPQ