1. 程式人生 > 實用技巧 >使用SAP C4C自定義BO實現自定義的Number Range

使用SAP C4C自定義BO實現自定義的Number Range

My series of Cloud Application Studio Blogs

In On-Premise world customer could use transaction code SNRO to create and maintain their custom number range object and consume via function module NUMBER_GET_NEXT.


In C4C it is not possible to use this backend approach for partner. In this blog a simple approach is introduced which fulfill the custom number range by leveraging custom Business object developed via Cloud studio.

Here below is what I have achieved:
(1) Every time a new Custom transaction BO is created, the new ID is automatically populated by the Number Range Business Object. This behavior is exactly the same as the one in On-Premise world.

In C4C it is not possible to use this backend approach for partner. In this blog a simple approach is introduced which fulfill the custom number range by leveraging custom Business object developed via Cloud studio.

Here below is what I have achieved:
(1) Every time a new Custom transaction BO is created, the new ID is automatically populated by the Number Range Business Object. This behavior is exactly the same as the one in On-Premise world.


(2) The current number interval is stored via an instance of Number Range object, which means even if you log off and log on system again, the current number range interval is loaded from backend persistence, instead of starting from scratch.

Detail implementation of this solution

(1) Create a Custom BO in Cloud Studio and paste the following source code:

import AP.Common.GDT as apCommonGDT;

businessobject NumberRange {

		// Used to distinguish between different number ranges.
	    [AlternativeKey] element Topic:ID;
		// Constant prefix of the generated number.
		element Prefix : LANGUAGEINDEPENDENT_EXTENDED_Text;
		element PrefixSeparatedByBlank : Indicator;
		
		// The (formatted) number itself.
		element Number : LANGUAGEINDEPENDENT_EXTENDED_Text;

		// If true, a blank will be placed between the formatted number and the suffix.		
		element SuffixSeparatedByBlank : Indicator;
		element Suffix : LANGUAGEINDEPENDENT_EXTENDED_Text;
      
		// Latest generated number (Prefix + Number + Suffix).
		element PresentValue : LANGUAGEINDEPENDENT_EXTENDED_Text;
      
		// Counter for the number generation itself.
		element Counter : IntegerValue;

		// Minimum and maximum values of the counter.
		element MinValue : IntegerValue;
		element MaxValue : IntegerValue;

		// true as long as we haven't reached the maximum value of the counter.
		element Ready : Indicator;

		action GenerateNextNumber;
		action InitializeInstance;
}

(2) Implement action InitializeInstance. Here I hard code the max number as 999999999.

import ABSL;

if(!this.Topic.IsInitial()){
	 this.Prefix = this.Topic;
	 this.Suffix = "";
	 this.PrefixSeparatedByBlank = false;
	 this.SuffixSeparatedByBlank = false;
	 this.MaxValue = 999999999;
	 this.MinValue = 1;
	 this.Ready = true;
}

(3) Implement action GenerateNextNumber. The logic is a simplified version of the good old function module NUMBER_GET_NEXT.

import ABSL;

var lv_sFormat = "";
var lv_sAux;

if (this.Ready) {
	  
	  if(!this.MinValue.IsInitial()){
		if(!this.MaxValue.IsInitial()){
			if(this.MinValue < this.MaxValue){      
				  // Initialize the counter in case the object is new.
				  if (this.Number.Length() == 0) {
						this.Counter = this.MinValue - 1;
				  }
      
				  this.Counter = this.Counter + 1;
				  this.Number = this.Counter.ToString();
   
     
				  // Put the new value together.
				  if (this.Prefix.Length() > 0) {
						if (this.PrefixSeparatedByBlank) {
							  lv_sAux = this.Prefix + " ";
						}
						else {
							  lv_sAux = this.Prefix;
						}
				  }
				  else {
						lv_sAux = "";
				  }
      
				  lv_sAux = lv_sAux + this.Number;
      
				  if (this.Suffix.Length() > 0) 
				  {
						if (this.SuffixSeparatedByBlank) {
							  lv_sAux = lv_sAux + " ";
						}
						this.PresentValue = lv_sAux + this.Suffix; 
				  }
				  else {
						this.PresentValue = lv_sAux;
				  }
      
				  if (this.Counter == this.MaxValue) {
						this.Ready = false;
				  }
			}
		}
	}
}

(4) In your transaction custom BO, consume the function exposed by Number Range BO in AfterModify.absl.

Here I hard code the number range prefix as “JerryBO”. You can for sure even use different prefix based on for example different transaction type of your custom BO.

import ABSL;
var lv_my_topic: NumberRange.Topic;
var lo_number_range;

if (this.AgreementID.IsInitial()) {
 lv_my_topic = "JerryBO";
  lo_number_range = NumberRange.Retrieve(lv_my_topic);
  if(!lo_number_range.IsSet()) {
   lo_number_range = NumberRange.Create();
   lo_number_range.Topic = lv_my_topic;
   lo_number_range.InitializeInstance();
  }
  
  if(lo_number_range.Ready==true) {
    lo_number_range.GenerateNextNumber();
    this.AgreementID = lo_number_range.PresentValue;
    return;
   }
}

要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":