0

リストとトランザクションの 2 つのカスタム オブジェクトがあります。最初は、トランザクション オブジェクトにリスティング オブジェクトへのルックアップ フィールドがありました。関連するリスティング オブジェクトの複数のユーザー ルックアップ フィールドとトランザクションを共有するように、Apex Managed Sharing をセットアップしました。それは完璧に機能していました。

トランザクション オブジェクトのリスティング フィールドのフィールド タイプを Master-Detail に変更しましたが、新しいトランザクションを保存しようとするたびに次のエラーが発生します。

「TransactionApexSharing: 原因による AfterInsert の実行: 行 1、列 1: トリガー本体が無効であり、再コンパイルに失敗しました: エンティティは組織からアクセスできません」

Transaction オブジェクトと Listing オブジェクトは両方とも Private に設定されており、コードにタイプミスは見つかりません。ルックアップ フィールドで動作していたので、トリガーは変更されていません。

これが私のコードです:

trigger TransactionApexSharing on Transaction__c (after insert, after update) {

if(trigger.isInsert || trigger.isUpdate){



    Set<id> triggerIds = trigger.newMap.keyset();

    List<Transaction__c> listWithParentData = [select Listing__r.Listing_Agent_1__r.id, Listing__r.Listing_Agent_2__r.id, Listing__r.Listing_Agent_3__r.id from Transaction__c where id in :triggerIds];


    List<Transaction__Share> tranShrs = new List<Transaction__Share>();

    Transaction__Share laShr;
    Transaction__Share la2Shr;
    Transaction__Share la3Shr;
    Transaction__Share saShr;
    Transaction__Share sa2Shr;
    Transaction__Share sa3Shr;


    for(Transaction__c atransaction : listWithParentData){

        laShr = new Transaction__Share();
        la2Shr = new Transaction__Share();
        la3Shr = new Transaction__Share();

        laShr.ParentId = atransaction.Id;
        la2Shr.ParentId = atransaction.Id;
        la3Shr.ParentId = atransaction.Id;

        if (atransaction.Listing__r.Listing_Agent_1__c != null)
        {
            // Set the ID of user or group being granted access 
            laShr.UserOrGroupId = atransaction.Listing__r.Listing_Agent_1__c;
            // Set the access level 
            laShr.AccessLevel = 'edit';
            // Set the Apex sharing reason 
            laShr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            // Add objects to list for insert 
            tranShrs.add(laShr);
        }

        if (atransaction.Listing__r.Listing_Agent_2__c != null)
        {
            la2Shr.UserOrGroupId = atransaction.Listing__r.Listing_Agent_2__c;
            la2Shr.AccessLevel = 'edit';
            la2Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(la2Shr);
        }

        if (atransaction.Listing__r.Listing_Agent_3__c != null)
        {
            la3Shr.UserOrGroupId = atransaction.Listing__r.Listing_Agent_3__c;
            la3Shr.AccessLevel = 'edit';
            la3Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(la3Shr);
        }

    }

    for(Transaction__c mytransaction : trigger.new){
        // Instantiate the sharing objects 

        saShr = new Transaction__Share();
        sa2Shr = new Transaction__Share();
        sa3Shr = new Transaction__Share();

        // Set the ID of record being shared 


        saShr.ParentId = mytransaction.Id;
        sa2Shr.ParentId = mytransaction.Id;
        sa3Shr.ParentId = mytransaction.Id;


        if (mytransaction.Selling_Agent_1_User__c != null)
        {
            saShr.UserOrGroupId = mytransaction.Selling_Agent_1_User__c;
            saShr.AccessLevel = 'edit';
            saShr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(saShr);
        }

        if (mytransaction.Selling_Agent_2_User__c != null)
        {
            sa2Shr.UserOrGroupId = mytransaction.Selling_Agent_2_User__c;
            sa2Shr.AccessLevel = 'edit';
            sa2Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(sa2Shr);
        }

        if (mytransaction.Selling_Agent_3_User__c != null)
        {
            sa3Shr.UserOrGroupId = mytransaction.Selling_Agent_3_User__c;
            sa3Shr.AccessLevel = 'edit';
            sa3Shr.RowCause = Schema.Transaction__Share.RowCause.Share_Transaction_with_Agency_Agents__c;
            tranShrs.add(sa3Shr);
        }



    }

    // Insert sharing records and capture save result  

    // The false parameter allows for partial processing if multiple records are passed  

    // into the operation  

    Database.SaveResult[] lsr = Database.insert(tranShrs,false);

    // Create counter 

    Integer i=0;

    // Process the save results 

    for(Database.SaveResult sr : lsr){
        if(!sr.isSuccess()){
            // Get the first save result error 

            Database.Error err = sr.getErrors()[0];

            // Check if the error is related to a trivial access level 

            // Access levels equal or more permissive than the object's default  

            // access level are not allowed.  

            // These sharing records are not required and thus an insert exception is  

            // acceptable.  

            if(!(err.getStatusCode() == StatusCode.FIELD_FILTER_VALIDATION_EXCEPTION  
                                           &&  err.getMessage().contains('AccessLevel'))){
                // Throw an error when the error is not related to trivial access level. 

                trigger.newMap.get(tranShrs[i].ParentId).
                  addError(
                   'Unable to grant sharing access due to following exception: '
                   + err.getMessage());
            }
        }
        i++;
    } 
}

}
4

1 に答える 1

1

関係をルックアップからマスターディテールに切り替えると、多くの変更が行われます。あなたは細部へのきめ細かいアクセスを失います、それだけです。ユーザーがマスターに対して持つ権利は何でも-彼は詳細についてもそれらを持っています(プロファイルにある「読み取り/作成/編集/削除」のようなものを除いて、私は一般的な権利ではなく、特定のレコードへのアクセスについて話している) 。

  1. 詳細については、「OwnerId」が表示されなくなります(クエリ、説明などはできません)
  2. これまでにいくつかの細かい点があります:
    • 詳細な承認プロセスが必要で、突然キューを使用できなくなり、ユーザーを直接指定する必要があります。
    • ユーザーは、リストビューまたはレポートで「マイトランザクションに何が起こったのか」を尋ねます
  3. 最後になりましたが、Detail__Shareテーブルも表示されなくなります。

サンドボックスでトリガーを編集してみてください(スペースを1つ追加するだけです)。おそらく、そのようなテーブルがないと文句を言うでしょうTransaction_Share

エージェントが親リストに対する編集権限を持っていることを確認し(ただし、関連するすべてのトランザクションを編集できることを意味します)、トリガーを破棄するか、MDを元に戻すことができます。これは、実際にはユーザーに戻ってビジネスロジックを要求する場合です;)

なぜそれをMDに変えたのですか?カスケード削除、ロールアップなどは、各トランザクションへのこのきめ細かい編集アクセスを失う余裕がないことが判明した場合、少しのコードで実行できます。

しかし、コードをざっと見てみると、詳細ではなくリストレベルでアクセスを制御することに問題がないように思われますか?

于 2013-01-19T09:30:32.503 に答える