Overview 
The following provides information when using the API for the creation of records in the billing, cash receipt and revenue recognition cycles of Accounting Seed including the following:
  • Object API names
  • Required fields for inserting a record
  • calling a global class to post a record
Billings
 
The billing object is a common integration point for the Accounting Seed Financial Suite. Please note the following:
  1. The billing is a single object that handles both sales invoices and credit memos. The net total of the Billing_Line__c.Total__c field on the billing line determines if the Billing is an Invoice or Credit Memo. This is represented in a Roll-Up Summary called Total__c on the Billing object. If Total__c is a positive number then the Type__c is automatically determined to be "Invoice" on the Billing. If Total__c is a negative number, then Type__c is automatically determined to be a "Credit Memo." 
  2. There is a limit of 1000 Billing Lines to a single Billing.
The following fields are required on the Billing Object: AcctSeed__Billing__c
 
Field Name  API Name  Type
 Customer  AcctSeed__Customer__c  Lookup (Customer)
 Billing Date  AcctSeed__Billing_Date__c  Date
The following fields are required on the Billing Line object: AcctSeed__Billing_Line__c
 
 Field Name  API Name  Type
 Billing  AcctSeed__Billing__c  Master-Detail (Billing)
 Units  AcctSeed__Units__c  Number (12,6)
 Rate  AcctSeed__Rate__c  Currency (12,6)

 

Posting or Unposting a Billing via Apex Code
 
There is a global class in the Accounting Seed Financial Suite managed package called BillingPostService. This class can be called through Apex Code external to the Accounting Seed Financial Suite package to post or unpost a set of billing records. Please note the following: 
  • This class contains two static global methods. One of the static methods is related to posting billing records and is called postBillings. The other static method is related to unposting billing records and is called unpostBillings.
  • You cannot call either the post or unpost methods with a set of billing records where the aggregate line count is more than 1,000 billing lines. If you need to post or unpost more than 1,000 billing lines, you will need to call the class static method from a class which supports batch apex.
  • Each method returns a list of post result records, which will indicate if the billing was posted or unposted successfully. If the record was not posted or unposted successfully, an error status code is provided documenting the reason the record was not posted or unposted.
  • The following error status codes are supported for the BillingPostService class:
Billing Post Method   
    • LINE_COUNT_LIMIT_EXCEEDED - Attempted to post a set of billing records where the aggregate number of billing lines exceeded 1,000.
    • NO_LINES – The billing records do not have any associated billing lines and cannot be posted. 
    • STATUS_NOT_APPROVED - The billing posting status is not approved.
    • ALREADY_POSTED - Record you are attempting to post is already posted.
    • NO_CONTROL_AR_ACCOUNT_DEFINED - No AR GL Control Account is defined on the accounting settings tab.
    • NO_BILLING_LINES - No billing lines are associated with the billing.
    • CLOSED_ACCOUNTING_PERIOD - The accounting period associated with the billing is closed.
    • SYSTEM_EXCEPTION - Internal exception.
Billing Unpost Method
    • LINE_COUNT_LIMIT_EXCEEDED - Attempted to unpost a set of billing records where the aggregate number of billing lines exceeded 1,000.
    • BILLING_CASH_RECEIPTS_EXIST - Billing cash receipts exist associated with the billing. You must delete all billing cash receipts before you can unpost.
    • BILLING_CREDIT_MEMOS_EXIST - Billing credit memo exist which are associated with this billing. You must delete all billing credit memos before you can unpost.
    • CLOSED_ACCOUNTING_PERIOD - The accounting period associated with the billing is closed.
    • SYSTEM_EXCEPTION - Internal exception.
 

Example using the BillingPostService class to post and unpost a set of billing records.

// Create billing records to post and unpost
AcctSeed__Billing__c[] billings = new List <AcctSeed__Billing__c> ();
billings.add(
    new AcctSeed__Billing__c(
        AcctSeed__Billing_Cycle_Start_Date__c = System.today(),
        AcctSeed__Billing_Cycle_End_Date__c = System.today() + 30,
        AcctSeed__Date__c = System.today(),
        AcctSeed__Customer__c = [Select Id From Account limit 1].Id,
        AcctSeed__Status__c = 'Approved',
        AcctSeed__Due_Date2__c = System.today() + 30
    )
);

billings.add(
    new AcctSeed__Billing__c(
        AcctSeed__Billing_Cycle_Start_Date__c = System.today(),
        AcctSeed__Billing_Cycle_End_Date__c = System.today() + 30,
        AcctSeed__Date__c = System.today(),
        AcctSeed__Customer__c = [Select Id From Account limit 1].Id,
        AcctSeed__Status__c = 'Approved',
        AcctSeed__Due_Date2__c = System.today() + 30
    )
);

insert billings;

// Create billing line records to post and unpost
AcctSeed__Billing_Line__c[] bLines = new List <AcctSeed__Billing_Line__c> ();
AcctSeed__GL_Account__c glAccount = [Select Id From AcctSeed__GL_Account__c limit 1];

for (AcctSeed__Billing__c bill : billings) {
    AcctSeed__Billing_Line__c objBillingLine = new AcctSeed__Billing_Line__c();
    objBillingLine.AcctSeed__Billing__c = bill.id;
    objBillingLine.AcctSeed__Date__c = System.today();
    objBillingLine.AcctSeed__Rate__c = 25;
    objBillingLine.AcctSeed__Hours_Units__c = 1;
    objBillingLine.AcctSeed__Revenue_GL_Account__c = glAccount.Id;
    bLines.add(objBillingLine);

    objBillingLine = new AcctSeed__Billing_Line__c();
    objBillingLine.AcctSeed__Billing__c = bill.id;
    objBillingLine.AcctSeed__Date__c = System.today();
    objBillingLine.AcctSeed__Rate__c = 25;
    objBillingLine.AcctSeed__Hours_Units__c = 2;
    objBillingLine.AcctSeed__Revenue_GL_Account__c = glAccount.Id;
    bLines.add(objBillingLine);
}

insert bLines;

// Call the post billings service
AcctSeed.PostResult[] postResults = AcctSeed.BillingPostService.postBillings(billings);

// Loop through post results
for (AcctSeed.PostResult theResult : postResults) {
    if (theResult.isSuccess) {
        System.debug('Successfully posted billing: ' + theResult.id);
    } 
    else {
        System.debug('Error posting billing ' + theResult.id);
        for (AcctSeed.PostResult.PostErrorResult errorResult: theResult.errors) {
            System.debug('Error status code ' + errorResult.statusCode);
            System.debug('Error message ' + errorResult.message);
        }
    }
}

// Call the unpost billings service
AcctSeed.PostResult[] unpostResults = AcctSeed.BillingPostService.unpostBillings(billings);

// Loop through unpost results
for (AcctSeed.PostResult theResult : unpostResults) {
    if (theResult.isSuccess) {
        System.debug('Successfully unposted billing: ' + theResult.id);
    } 
    else {
        System.debug('Error unposting billing ' + theResult.id);
        for (AcctSeed.PostResult.PostErrorResult errorResult: theResult.errors) {
            System.debug('Error status code ' + errorResult.statusCode);
            System.debug('Error message ' + errorResult.message);
        }
    }
} 
Posting or Unposting a Billing via the REST Webservice:
 
Below is the URI you can leverage to post and unpost billings utilizing the REST webservice. The same set of error codes associated with the Apex Code BillingPostService class can be returned for both posting and unposting via the REST webservice.
 
Billing Post Method
    • Use the HTTP PUT method to invoke the REST webservice.     
    • Same set of error status codes as invoking postBilling method in BillingPostService class via Apex Code. In addition the following error code can be returned:
      • INVALID_BILLING_ID - An invalid billing ID has been provided.
URI
<SERVER>/services/apexrest/AcctSeed/v1.0/billing/post/<BILLING_ID>
 
Example
https://na9.salesforce.com/services/apexrest/AcctSeed/v1.0/billing/post/a0EE0000000VzMI
 
Billing Unpost Method
    • Use the HTTP DELETE method to invoke the REST webservice.
    • Same set of error status codes as invoking unpostBilling method in BillingPostService class via Apex Code. In addition the following error code can be returned:
      • INVALID_BILLING_ID - An invalid billing ID has been provided.
URI
<SERVER>/services/apexrest/AcctSeed/v1.0/billing/post/<BILLING_ID>
 
Example
https://na9.salesforce.com/services/apexrest/AcctSeed/v1.0/billing/post/a0EE00000
Cash Receipts
 
The cash receipt object is a common integration point for the Accounting Seed Financial Suite. Please note the following: 
  • The cash receipt is a single object. The billing cash receipt is a junction object that matches a cash receipt to a billing. 
  • Both the cash receipt and billing cash receipt automatically post when a record is created. There is no need to call a posting process.
  • Below are the required fields for cash receipt and billing cash receipt.  
The following fields are required on the cash receipt object: AcctSeed__Cash_Receipt__c

Field Name  API Name  Type
 Customer  AcctSeed__Account__c  Lookup (Account)
 Payment Reference  AcctSeed__Payment_Reference__c  Text (255)
 Amount  AcctSeed__Amount__c  Currency (16,2)
 Receipt Date  AcctSeed__Receipt_Date__c  Date
The following fields are required on the Billing Cash Receipt object: AcctSeed__Billing_Cash_Receipt__c
 
 Field Name  API Name  Type
 Applied Amount  AcctSeed__Applied_Amount__c  Currency (16,2)
 Billing  AcctSeed__Billing__c  Master-Detail (Billing__c)
 Cash Receipt  AcctSeed__Cash_Receipt__c  Master-Detail (Cash_Receipt__c)
 Accounting Period  AcctSeed__Accounting_Period__c  Lookup (Accounting Period)
 
 
Posting or Unposting a Cash Receipt via Apex Code
As of Accounting Seed Financial Suite 2.21, there is a global class in the Accounting Seed Financial Suite managed package called CashReceiptPostService. This class can be called through Apex Code external to the Accounting Seed Financial Suite package to post or unpost a set of cash receipt records. Please note the following: 
  • This class contains two static global methods. One of the static methods is related to posting cash receipt records and is called postCashReceipts. The other static method is related to unposting cash receipt records and is called unpostCashReceipts.
  • You cannot call either the post or unpost methods with a set of cash receipt records where the number of cash receipts is more than 1,000. If you need to post or unpost more than 1,000 cash receipts, you will need to call the class static method from a class which supports batch apex.
  • Each method returns a list of post result records, which will indicate if the billing was posted or unposted successfully. If the record was not posted or unposted successfully, an error status code is provided documenting the reason the record was not posted or unposted.
  • The following error status codes are supported for the CashReceiptPostService class:
Cash Receipt Post Method   
    • LINE_COUNT_LIMIT_EXCEEDED - Attempted to post a set of cash receipt records where the number of cash receipts exceeds 1,000.
    • STATUS_NOT_APPROVED - The billing posting status is not approved.
    • ALREADY_POSTED - Record you are attempting to post is already posted.
    • NO_UNAPPLIED_CASH_CONTROL_ACCOUNT_DEFINED - No Unapplied Cash GL Control Account is defined on the accounting settings tab.
    • CLOSED_ACCOUNTING_PERIOD - The accounting period associated with the cash receipt is closed.
    • SYSTEM_EXCEPTION - Internal exception.
Cash Receipt Unpost Method
    • LINE_COUNT_LIMIT_EXCEEDED - Attempted to post a set of cash receipt records where the number of cash receipts exceeds 1,000.
    • BILLING_CASH_RECEIPTS_EXIST - Billing cash receipts exist associated with the cash receipt. You must delete all billing cash receipts before you can unpost.
    • CLEARED_BANK_RECONCILIATION -The cash receipt is associated with a bank reconciliation. You must unassociate the cash receipt from the bank reconciliation before you have unpost.
    • CLEARED_BANK_DEPOSIT - The cash receipt is associated with a bank deposit. You must unassociate the cash receipt from the bank deposit before you have unpost.
    • CLOSED_ACCOUNTING_PERIOD - The accounting period associated with the cash receipt is closed.
    • SYSTEM_EXCEPTION - Internal exception.
 
 
Example using the CashReceiptPostService class to post and unpost a set of cash receipt records.
 
// Create cash receipt records to post and unpost
AcctSeed__Cash_Receipt__c[] receipts = new List <AcctSeed__Cash_Receipt__c>();
AcctSeed__GL_Account__c glAccount = [Select Id From AcctSeed__GL_Account__c limit 1];

receipts.add(
    new AcctSeed__Cash_Receipt__c(
        AcctSeed__Receipt_Date__c = System.today(),
        AcctSeed__Account__c = [Select Id From Account limit 1].Id,
        AcctSeed__Status__c = 'Approved',
        AcctSeed__Amount__c = 34,
        AcctSeed__Credit_GL_Account__c = glAccount.Id,
        AcctSeed__Payment_Reference__c = 'ThisIsATestPaymentReference123'
    )
);

receipts.add(
    new AcctSeed__Cash_Receipt__c(
        AcctSeed__Receipt_Date__c = System.today(),
        AcctSeed__Account__c = [Select Id From Account limit 1].Id,
        AcctSeed__Status__c = 'Approved',
        AcctSeed__Amount__c = 67,
        AcctSeed__Credit_GL_Account__c = glAccount.Id,
        AcctSeed__Payment_Reference__c = 'ThisIsATestPaymentReference456'
    )
);

// Initial insert auto posts cash receipts
insert receipts;

// Unpost the cash receipts
AcctSeed.PostResult[] unpostResults = AcctSeed.CashReceiptPostService.unpostCashReceipts(receipts);

// Loop through unpost results
for (AcctSeed.PostResult theResult : unpostResults) {
    if (theResult.isSuccess) {
        System.debug('Successfully unposted cash receipt: ' + theResult.id);
    } 
    else {
        System.debug('Error unposting cash receipt ' + theResult.id);
        for (AcctSeed.PostResult.PostErrorResult errorResult: theResult.errors) {
            System.debug('Error status code ' + errorResult.statusCode);
            System.debug('Error message ' + errorResult.message);
        }
    }
}

// Post the cash receipts
AcctSeed.PostResult[] postResults = AcctSeed.CashReceiptPostService.postCashReceipts(receipts);

// Loop through post results
for (AcctSeed.PostResult theResult : postResults) {
    if (theResult.isSuccess) {
        System.debug('Successfully posted billing: ' + theResult.id);
    } 
    else {
        System.debug('Error posting billing ' + theResult.id);
        for (AcctSeed.PostResult.PostErrorResult errorResult: theResult.errors) {
            System.debug('Error status code ' + errorResult.statusCode);
            System.debug('Error message ' + errorResult.message);
        }
    }
}
Amoritization Entry

The Amoritization Entry is used to amortize or recognize deferred revenue. 

The following fields are required on the Amoritization Entry: AcctSeed__Scheduled_Revenue_Expense__c 

 Field Name  API Name  Type
 Amoritization Entry Name  Name  Text (80)
 Amount  AcctSeed__Amount__c  Currency (16,2)
 Accounting Period  AcctSeed__Accounting_Period__c  Lookup (Accounting Period)
 Debit GL Account  AcctSeed__Debit_GL_Account__c  Lookup (GL Account)
 Credit GL Account  AcctSeed__Credit_GL_Account__c  Lookup (GL Account)

Was this article helpful?
1 out of 1 found this helpful
Have more questions? Submit a request

5 Comments

  • 0
    Avatar
    Jorge Fernandez

    Hi,

    Our team has the following technical question. What is the difference between applying a Cash Receipt via the "Apply" button (CashReceiptApplyBillings page) vs creating the Billing Cash Receipts via APEX. Assuming that all the fields are correct like Applied Account Period, Amount, etc, when creating the record in APEX, is there any additional logic that is missing using this approach?  We have done so using the two approaches and everything looks to be the same, but we want to make sure.

     

    On a side note, we understand that the Visualforce is more user-friendly. But our particular use case requires applying the cash receipts via APEX.

    Thanks!

    Jorge

  • 1
    Avatar
    Tony

    Jorge,

    Creating a billing cash receipt through the API is fine. There is no special logic fired when inserting this data record via the apply button or through the API.

  • 0
    Avatar
    Jorge Fernandez

    Hi Tony,

    Thank you very much for your answer. Additionally, is there any possibility to leverage the functionality of creating a Stripe Payment via APEX. If we need to do this, what would be your advice taking into account the reusability of the existing functionalities?

    Thanks again.

     

     

    Edited by Jorge Fernandez
  • 0
    Avatar
    Tony

    Hi Jorge,

    Currently the interactions we have with Stripe are not global classes. As such you can not call them through custom code. This is something we are looking to expand to. For now you would need to interact directly with Stripe and AS on and customizations you wanted to code. 

  • 0
    Avatar
    Jorge Fernandez

    Thank you.

Please sign in to leave a comment.