dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[Salesforce]見積(Quote)をコピーする方法

Salesforceのほとんどの標準オブジェクトには、
レコードの詳細画面を開いた時に「コピー」ボタンがついてる。

f:id:dackdive:20140601195625p:plain

ところが、なぜか「見積り(Quote)」オブジェクトにはそれがない。

f:id:dackdive:20140601201347p:plain

というわけで、その機能を実現するまでのメモ。
条件として、「見積商品も一緒にコピー」する。
また、Apexは使用しない。

以下、コピーの実現手順。
自分への備忘録として経緯も含めて長々と書いてるので、
方法だけ確認する場合は「まとめ」の項だけ見て下さい。

通常のオブジェクトコピーするには

まず、通常の標準オブジェクトに備わっている「コピー」ボタンの機能は
以下のURLで実現していると思われる。

https://ap.salesforce.com/[コピー元のレコードID]/e?clone=1&retURL=[コピー元のレコードID]

インスタンス名は組織による)

つまり、

レコードIDの後ろにeをつけると編集モードになり、
その時のパラメータにclone=1をつけるとコピーモードである

ということ。(retURLは保存した時にリダイレクトするURLなので、今回の話とはあまり関係なし)

ところがこれ、見積オブジェクトに対しては権限がないとかでできません。
(英語だとInsufficient Privilegesエラー)

見積のコピーを実現するには

どうしよう...と色々調べていた結果、こちらの記事に書いてある方法でいけることがわかった。

カスタムボタンでJavascriptを実行する。
以下、その設定手順。

カスタマイズ > 見積 > ボタンとリンク > 新規ボタンまたはリンク

を開きます。

「表示の種類」:「詳細ページボタン」、
「動作」:「Javascriptを実行」、 「内容のソース」:「OnClick JavaScript」を選び、
一番下のテキストエリアに以下をそのまま貼付け。

{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}
result = sforce.connection.query("select id,opportunityid from Quote where id = '{!Quote.Id}'");
window.top.location.href = "{!URLFOR( $Action.Quote.NewQuote ,null, 
    [clone=1,id=Quote.Id,retURL="/"&Quote.Id],true)}&oppid=" + result.records.OpportunityId;

さらに、見積のページレイアウト画面で、作成したカスタムボタンをレイアウトに追加しておくのを忘れないように。

実行してみる

こんな新規見積を作り、保存。

f:id:dackdive:20140601212633p:plain

見積詳細画面から「コピー」ボタンをクリック。

f:id:dackdive:20140601212848p:plain

すると...

f:id:dackdive:20140601212944p:plain

こんな感じで、見積の編集画面になる。
コピー元の見積を作成した時の項目値が保持されてますね。

では、見積名を「新規見積のコピー」に変更して、「保存」。

f:id:dackdive:20140601213213p:plain

とりあえずこの画面では、「見積商品」の項目も保持されてる!

問題はコピー元の見積が残ってるかどうかだけど、
商談の詳細レコードに戻ると...

f:id:dackdive:20140601213412p:plain

残ってます!

というわけで、無事に見積オブジェクトの、商品も含めたコピーができました。

が、ここで重大な問題に気づく

確認したんですが、見積をコピーした時の見積商品は
「コピー元の見積商品」ではなく「商談商品」からコピーされてたみたいです。。。

うーん、これは何とかならないか...

まとめ

  • 見積のコピーは、Javascriptを実行するカスタムボタンを作成し、以下をソース部分に貼付ければ可能
{!REQUIRESCRIPT("/soap/ajax/30.0/connection.js")}
result = sforce.connection.query("select id,opportunityid from Quote where id = '{!Quote.Id}'");
window.top.location.href = "{!URLFOR( $Action.Quote.NewQuote ,null, 
    [clone=1,id=Quote.Id,retURL="/"&Quote.Id],true)}&oppid=" + result.records.OpportunityId;
  • ただし、↑の方法だと、見積商品は商談商品の情報からコピーされる
  • その他、本当に全部の項目がコピー元の見積から引き継がれているかは未検証