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デモンストレーションを表示します。
オーダー・ヘッダーに保留を適用
効率性を高めます。 販売オーダーに複数のオーダー明細がある場合は、各明細に個別の保留を適用するのではなく、オーダー・ヘッダーに単一の保留を適用します。 これは、オーダーに数百または数千の明細がある場合に特に役立ちます。 各明細に個別の保留を適用するかわりに、オーダー・ヘッダーに単一の保留を適用できます。
この例では、オーダー・ヘッダーに保留を適用します。
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 (!header.isFirstDraftOrder()) {
// Make sure the order is in draft status, and not already submitted to fulfillment.
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")) {
// 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 (header.canApplyHold("SHIP_ALL_HOLD")) {
def holdResult = header.applyHold("SHIP_ALL_HOLD", "Apply Header Hold through Extension"); // Create a hold and use the SHIP_ALL_HOLD 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;
// Run the extension only on sales orders that are on hold.
def poNumber = header.getAttribute("CustomerPONumber")
if (poNumber != "ApplyHold") return;
if (!header.isFirstDraftOrder()) {
// Make sure the order is in draft status, and not already submitted to fulfillment.
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")) {
// 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 (line.canApplyHold("RESERVE_HOLD")) {
def hold = line.applyHold("RESERVE_HOLD"); // Create a hold and use the RESERVE_HOLD 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.");
}
}
}
プロファイルを使用可能にした場合のオーダー明細の保留の適用
HoldComments属性の値(line.applyHold("RESERVE_HOLD", "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( !header.isFirstDraftOrder() ) {
return;
}
if( !context.isUserInRole("ORA_DOO_ORDER_MANAGER_JOB") ) {
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(line.canApplyHold("RESERVE_HOLD")) {
def holdResult = line.applyHold("RESERVE_HOLD", "We're holding this line so we can manually review and approve it."); // Create a hold and use the RESERVE_HOLD 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( !header.isFirstDraftOrder() ) {
// Make sure the sales order is 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") ) {
// 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(line.canApplyHold("RESERVE_HOLD")) {
def hold = line.applyHold("RESERVE_HOLD"); // Create a hold and use the RESERVE_HOLD 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(line.canApplyHold("RESERVE_HOLD")) {
def hold = line.applyHold("RESERVE_HOLD"); // Create a hold and use the RESERVE_HOLD hold code
hold.setAttribute("HoldComments", "We're holding this line so we can manually review and approve it.");
}
}
}
}