Order Management拡張を使用した保留の適用
オーダー管理拡張を使用して、オーダー・ヘッダーまたはオーダー明細に保留を適用します。
- Oracle Order Managementの事前定義済の保留動作では満たせないビジネス要件がある場合は、オーダー管理拡張を使用します。
- 保留を適用するには、発行リクエストの開始時または保存時拡張ポイントを使用します。
- Order Management Extensionsの管理(FOM_MANAGE_ORDER_MANAGEMENT_EXTENSIONS_PRIV)権限があることを確認します。
保留を適用するには、applyHoldメソッドを使用します。 applyHoldを使用する場合は、拡張で次の条件を確認する必要があります:
保留のみ適用 | 条件を満たす方法 |
---|---|
新規販売オーダーまたは下書きステータスの販売オーダー。 applyHoldは、履行のためにすでに発行した変更オーダーまたは販売オーダーとともに使用できません。 |
isFirstDraftOrder |
オーダー明細がモデルまたはキットの子明細でない場合、および明細に保留を適用していない場合。 | canApplyHold |
これらのメソッドも役立つ場合があります。
- holdExists
- isChildLine
- デバッグ
詳細は、「Order Managementの拡張機能で使用できるメソッド」を参照してください。
CustomerPONumber属性をテストとして使用して、保留中の販売オーダーに対してのみ拡張が実行されるようにします。 テスト環境では、テキストApplyHoldを属性に追加します。 顧客の購買オーダー番号は、常にオーダー・ヘッダーで使用可能なテキスト属性であるため、使用します。 必要に応じて別の属性を使用できます。
拡張機能を本番環境に公開する前に、必ずこのテストを削除してください:
def poNumber = header.getAttribute("CustomerPONumber")
if (poNumber != "ApplyHold") return;
- 販売オーダーで保留を設定するためのガイドライン
- オーダー管理拡張の作成の概要
- 「続きを読み込む」をクリックして、niftyデモンストレーションを表示します。
プロファイルを設定
オーダー・ヘッダーに保留を適用する場合は、プロファイル・オプションを有効にする必要があります。 オーダー明細に保留を適用する場合はオプションです。 プロファイルを有効にすると、Order Managementでは、より迅速かつ効率的に保留を処理できます。 オーダー明細にのみ保留を適用する場合でも、有効にすることをお薦めします。
- プロファイル・オプションを作成します。
- 「設定および保守」作業領域に移動し、「タスク」→「検索」をクリックして、「プロファイル・オプションの管理」タスクを検索します。
- 「プロファイル・オプションの管理」ページの検索結果で、「処理」→「新規」をクリックします
- 「プロファイル・オプションの作成」ページで、値を設定します。
属性 値 プロファイル・オプション・コード FOM_NEW_HOLDS_PROCESSING プロファイル表示名 FOM新規保留処理 アプリケーション オーダー管理 モジュール オーダーの管理 SQL検証 FND_LOOKUPSからMEANING、LOOKUP_CODEを選択します(LOOKUP_TYPE='YES_NO')。 開始日 今日または将来の日付。 - 「プロファイル・オプション・レベル」領域で、値を設定します。
属性 値 レベル サイト 使用可能 チェック・マークが含まれます。 更新可能 チェック・マークが含まれます。 - 「保存してクローズ」をクリックします。
- プロファイル値を管理します。
- 概要ページで、管理者プロファイル値の管理タスクを検索して開きます。
- 「管理者プロファイル値の管理」ページで、値を検索します。
属性 値 プロファイル・オプション・コード FOM_NEW_HOLDS_PROCESSING - プロファイル値領域で値を設定し、「保存してクローズ」をクリックします。
属性 値 プロファイル・レベル サイト プロファイル値 Yes
オーダー・ヘッダーに保留を適用
効率性を高めます。 販売オーダーに複数のオーダー明細がある場合は、各明細に個別の保留を適用するのではなく、オーダー・ヘッダーに単一の保留を適用します。 これは、オーダーに数百または数千の明細がある場合に特に役立ちます。 各明細に個別の保留を適用するかわりに、オーダー・ヘッダーに単一の保留を適用できます。
この例では、オーダー・ヘッダーに保留を適用します。
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
import oracle.apps.scm.doo.common.extensions.HoldResult;
// Run the extension only on sales orders that are on hold.
def poNumber = header.getAttribute("CustomerPONumber")
if (poNumber != "ApplyHeaderHold") return;
if (!isFirstDraftOrder()) {
// Make sure the order is in draft status, and not already submitted to fulfillment.
debug("order is not in draft status");
return;
}
// Make sure the current user has the privilege they need to apply hold. You can remove this code to meet your needs.
if (!context.isUserInRole("ORA_DOO_ORDER_MANAGER_JOB")) {
debug("user does not have privilege");
// Display a warning message that the user does doesn't have the privilege to apply a hold. As an option, you can display an error message or
// silently return from the extension without raising any error or warning.
throw new ValidationException(new Message(Message.MessageType.WARNING, "User " + context.getUserName() + " does not have privilege to apply hold"));
}
if (canApplyHold(header, "DOO_SHIP_ALL")) {
debug("Applying hold");
def holdResult = header.applyHold("DOO_SHIP_ALL", "Apply Header Hold through Extension"); // Create a hold and use the DOO_SHIP_ALL hold code.
def status = holdResult.getStatus();
def message = holdResult.getMessage();
if ("FAILURE".equals(status)) {
throw new ValidationException(message);
}
}
オーダー明細に保留を適用
def hold = line.applyHold("DOO_RSRV");
hold.setAttribute("HoldComments", "comment"
この例では、明細の数量が10より大きいオーダー明細に保留を適用します。
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
// Run the extension only on sales orders that are on hold.
def poNumber = header.getAttribute("CustomerPONumber")
if (poNumber != "ApplyHold") return;
if (!isFirstDraftOrder()) {
// Make sure the order is in draft status, and not already submitted to fulfillment.
debug("order is not in draft status");
return;
}
// Make sure the current user has the privilege they need to apply hold. You can remove this code to meet your needs.
if (!context.isUserInRole("ORA_DOO_ORDER_MANAGER_JOB")) {
debug("user does not have privilege");
// Display a warning message to explain that the user doesn't have the privilege they need to apply a hold. You can remove this code to meet your needs.
throw new ValidationException(new Message(Message.MessageType.WARNING, "The " + context.getUserName() + " user doesn't have the privilege they need to apply a hold."));
}
def lines = header.getAttribute("Lines");
while (lines.hasNext()) {
def line = lines.next();
// Make sure the ordered quantity is greater than 10.
BigDecimal qty = line.getAttribute("OrderedQuantity");
if (qty.compareTo(new BigDecimal(10)) > 0) {
if (canApplyHold(line, "DOO_RSRV")) {
debug("Applying hold");
def hold = line.applyHold("DOO_RSRV"); // Create a hold and use the DOO_RSRV hold code.
// Display text that explains what we're doing.
hold.setAttribute("HoldComments", "We're holding this line so we can manually review and approve it.");
}
}
}
プロファイルを使用可能にした場合のオーダー明細の保留の適用
FOM_NEW_HOLDS_PROCESSINGプロファイルを有効にすると、HoldComments属性の値を暗黙的に設定できます: line.applyHold("DOO_RSRV", "comment");
.
たとえば:
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
import oracle.apps.scm.doo.common.extensions.HoldResult;
def poNumber = header.getAttribute("CustomerPONumber")
if(poNumber != "ApplyHold") return;
if( !isFirstDraftOrder() ) {
debug("order is not in draft status");
return;
}
if( !context.isUserInRole("ORA_DOO_ORDER_MANAGER_JOB") ) {
debug("user does not have privilege");
throw new ValidationException( new Message(Message.MessageType.WARNING, "User " + context.getUserName() + " does not have privilege to apply hold") );
}
def lines = header.getAttribute("Lines");
while(lines.hasNext()) {
def line = lines.next();
BigDecimal qty = line.getAttribute("OrderedQuantity");
if(qty.compareTo(new BigDecimal(10)) > 0) {
if(canApplyHold(line, "DOO_RSRV")) {
debug("Applying hold");
def holdResult = line.applyHold("DOO_RSRV", "We're holding this line so we can manually review and approve it."); // Create a hold and use the DOO_RSRV hold code
def status = holdResult.getStatus();
def message = holdResult.getMessage();
if("FAILURE".equals(status)) {
throw new ValidationException(message);
}
}
}
}
出荷セットの保留の適用
この例では、オーダー数量が10より大きい出荷セットのすべての明細に保留を適用します。
import oracle.apps.scm.doo.common.extensions.ValidationException;
import oracle.apps.scm.doo.common.extensions.Message;
// These two lines are only for testing. They make sure the extension applies only when customer purchase order number is ApplyHold
def poNumber = header.getAttribute("CustomerPONumber")
if(poNumber != "ApplyHold") return;
if( !isFirstDraftOrder() ) {
// Make sure the sales order is in draft status.
debug("order is not in draft status");
return;
}
// Make sure the current user has the privilege they need to apply a hold. This is optional.
if( !context.isUserInRole("ORA_DOO_ORDER_MANAGER_JOB") ) {
debug("user does not have privilege");
// Display a warning message here to explain that the user doesn't have the privilege to apply a hold. This is optional.
throw new ValidationException( new Message(Message.MessageType.WARNING, "User " + context.getUserName() + " does not have privilege to apply hold") );
}
// Map the lines that are on hold. We will populate this map while we put lines on hold.
Set linesOnHold = new HashSet<Long>();
Set shipsetsToHold = new HashSet<String>();
def lines = header.getAttribute("Lines");
while(lines.hasNext()) {
def line = lines.next();
// Make sure the line is eligible to apply a hold. Make sure the line has an ordered quantity that's greater than 10.
BigDecimal qty = line.getAttribute("OrderedQuantity");
if(qty.compareTo(new BigDecimal(10)) > 0) {
if(canApplyHold(line, "DOO_RSRV")) {
debug("Applying hold");
def hold = line.applyHold("DOO_RSRV"); // Create a hold and use the DOO_RSRV hold code.
hold.setAttribute("HoldComments", "We're holding this line so we can manually review and approve it.");
Long fulfillLineId = line.getAttribute("FulfillmentLineIdentifier");
linesOnHold.add(fulfillLineId);
String shipsetName = line.getAttribute("ShipSetName");
if( shipsetName != null ) {
// The line that we're hold is part of a shipment set. Let's remember the shipset name in a set. Later we will make another pass over the lines to find other
// lines in the same shipment set and hold them too.
shipsetsToHold.add(shipsetName);
}
}
}
}
// We are done making one pass over the lines. Some of the lines that we held might be part of a shipment set. Let's make another pass over all lines and hold the other lines
// from the shipment sets.
lines = header.getAttribute("Lines");
while(lines.hasNext()) {
def line = lines.next();
Long fulfillLineId = line.getAttribute("FulfillmentLineIdentifier");
if( linesOnHold.contains(fulfillLineId) ) {
// We already held this line during the first pass. Let's continue to the next line in the loop.
continue;
}
String shipsetName = line.getAttribute("ShipSetName");
if( shipsetName != null ) {
// The line is in a shipment set. Let's see whether we should hold this shipment set. If yes, then we will hold the line.
if( shipsetsToHold.contains(shipsetName) ) {
if(canApplyHold(line, "DOO_RSRV")) {
debug("Applying hold");
def hold = line.applyHold("DOO_RSRV"); // Create a hold and use the DOO_RSRV hold code
hold.setAttribute("HoldComments", "We're holding this line so we can manually review and approve it.");
}
}
}
}