Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Under the action created, click add to add a profile question, configure it as below (both for percentage or flat fee). When you add the action to credit rating, it will request the percentage or flat fee you want to add according to the action you've selected in this article.

...

Code Block
languagec#
//Name: LateFeeFlatFee
//Description:
//EventCode:
if (context.ContainsKey("InvoiceID"))
{
    var invoice = Invoice.GetByID(Convert.ToInt32(context["InvoiceID"]));

    if (Logic.Core.User.GetUserBalance(invoice.UserID) > 0)
    {
        var rate = Convert.ToDouble(context["Rate"]);
        var statement = Logisense.Boss.Logic.Billing.Bill.RetrieveStatement(Logisense.Boss.Logic.Billing.Bill.FindTopLevelParent(invoice.UserID));

        using (var invoiceSummaryCalculator = new InvoiceSummaryCalculator(statement))
        {
            Logisense.Boss.Logic.Billing.Bill.AddCharge(statement.ID, invoice.UserID, rate, "Late charge", DateTime.MinValue, DateTime.MinValue,
                false, invoiceSummaryCalculator, Service.SearchByName("Invoice Late Fee CDN")[0]);
            invoiceSummaryCalculator.UpdateAggregate();
        }
    }
    return true;
}
return false;


To add a GL Code, you can insert a service name as shown in the below script:

Code Block
languagec#
if (context.ContainsKey("InvoiceID"))
{
    Invoice invoice = Invoice.GetByID(Convert.ToInt32(context["InvoiceID"]));
    double rate = Convert.ToDouble(context["Rate"]);
    double total = Logisense.Boss.Logic.Invoicing.GetInvoiceTotal(invoice);
    int statementID = Logisense.Boss.Logic.Billing.Bill.RetrieveStatement(Logisense.Boss.Logic.Billing.Bill.FindTopLevelParent(invoice.UserID));
    double amount = Logisense.Boss.Logic.Billing.Rounding.Round(total * (rate / 100), 2);
    Logisense.Boss.Logic.Billing.Bill.AddCharge(statementID, invoice.UserID, amount, "Late charge", DateTime.MinValue, DateTime.MinValue, true,Service.SearchByName("Invoice Late Fee CDN")[0]);
    return true;
}
else
{
    return false;
}

...

This script will add a dollar amount late fee to an account as a percentage of the invoice total but will not have taxes applied to the late fee.

Code Block
languagec#
//Name: LateFeePercentageNoTaxApplied
//Description:
//EventCode:
if (context.ContainsKey("InvoiceID"))
{
    var invoice = Invoice.GetByID(Convert.ToInt32(context["InvoiceID"]));
    var rate = Convert.ToDouble(context["Rate"]);
    var total = Invoicing.GetInvoiceTotal(invoice);

    var totalTax = 0d;
    var statement = Logisense.Boss.Logic.Billing.Bill.RetrieveStatement(Logisense.Boss.Logic.Billing.Bill.FindTopLevelParent(invoice.UserID));

    foreach (var statementDetail in statement.GetStatementDetailsCollection())
    {
        foreach (var statementDetailsTax in statementDetail.GetStatementDetailsTaxCollection())
        {
            totalTax += statementDetailsTax.Amount;
        }
    }

    total -= totalTax;
    var amount = Logisense.Boss.Logic.Billing.Rounding.Round(total * (rate / 100), 2);

    using (var invoiceSummaryCalculator = new InvoiceSummaryCalculator(statement))
    {
        Logisense.Boss.Logic.Billing.Bill.AddCharge(statement.ID, invoice.UserID, amount, "Late charge", DateTime.MinValue, DateTime.MinValue, false,
            invoiceSummaryCalculator, Service.SearchByName("Invoice Late Fee CDN")[0]);
        invoiceSummaryCalculator.UpdateAggregate();
    }
    return true;
}
return false;

...

The script below adds a flat fee when credit rating runs and the invoice has an overdue balance.

Code Block
languagec#
//Name: LateFeeFlatFee
//Description:
//EventCode:
if (context.ContainsKey("InvoiceID"))
{
    var invoice = Invoice.GetByID(Convert.ToInt32(context["InvoiceID"]));

    if (Logic.Core.User.GetUserBalance(invoice.UserID) > 0)
    {
        var rate = Convert.ToDouble(context["Rate"]);
        var statement = Logisense.Boss.Logic.Billing.Bill.RetrieveStatement(Logisense.Boss.Logic.Billing.Bill.FindTopLevelParent(invoice.UserID));

        using (var invoiceSummaryCalculator = new InvoiceSummaryCalculator(statement))
        {
            Logisense.Boss.Logic.Billing.Bill.AddCharge(statement.ID, invoice.UserID, rate, "Late charge", DateTime.MinValue, DateTime.MinValue,
                false, invoiceSummaryCalculator, Service.SearchByName("Invoice Late Fee CDN")[0]);
            invoiceSummaryCalculator.UpdateAggregate();
        }
    }
    return true;
}
return false;

...

This script sends an email when an invoice has an overdue balance. The profile questions will take the name of the email message setup under 'email messages' on the setup page.

Code Block
languagec#
//Name: SendEmail
//Description:
//EventCode:
var user = User.GetByID(Convert.ToInt32(context["UserID"]));
var emails = user.GetOwner().SearchEmailMessageByName(context["EmailMessage"].ToString());

if (emails.Length > 0)
{
    var coreEmail = (Logic.Core.EmailMessage)emails[0];
    coreEmail.SendTo(user.ID);
    return true;
}
return false;

...

Info

Note: this script references the back end status, not the defined label status on the setup tab. Available back end statuses are 'Canceled', 'Active', 'Suspended' and 'Prospect'.

Code Block
languagec#
//Name: SendEmailUserStatusNotCanceled
//Description:
//EventCode:
var user = User.GetByID(Convert.ToInt32(context["UserID"]));
EventLogger.Log(user.ID, user.ID, "SendEmailUserStatusNotCanceled", "CustomCode", string.Format("User's current StatusType: {0}", user.GetCurrent_StatusType().Name),
    user.OwnerID, "User", user.ID, null);

if (user.GetCurrent_StatusType().Name != "Canceled")
{
    var emails = user.GetOwner().SearchEmailMessageByName(context["EmailMessage"].ToString());

    if (emails.Length > 0)
    {
        var coreEmail = (Logic.Core.EmailMessage)emails[0];
        coreEmail.SendTo(user.ID);
        return true;
    }
}
return false;

...

Info

Note: When setting an account status to canceled the system will cancel any packages and add a prorated refund by default. If you do not want a prorated refund you can create a status of 'Suspended' with a back end status of 'Active'. You can then track who has this status and perform administrative tasks on them as needed, enable, charge credit card manually, etc.

Code Block
languagec#
//Name: SetUserStatusWhereNotCanceled
//Description:
//EventCode:
var user = User.GetByID(Convert.ToInt32(context["UserID"]));
EventLogger.Log(user.ID, user.ID, "SetUserStatusWhereNotCanceled", "CustomCode", string.Format("User's current StatusType: {0}", user.GetCurrent_StatusType().Name),
    user.OwnerID, "User", user.ID, null);

if (user.GetCurrent_StatusType().Name != "Canceled")
{
    var userStatusType = user.GetActingOwner().SearchUserStatusTypeByName(context["UserStatus"].ToString())[0];

    if (userStatusType != default(UserStatusType))
    {
        user.UserStatusTypeID = userStatusType.ID;
        user.Update();
        return true;
    }
}
return false;

...

The below script checks profile question on the action called 'Threshold' and will only execute its payload (in this case an email user script) if the invoice balance is greater than x (as //configured in the profile question.

Code Block
languagec#
//Name: PaymentTermsWithBalanceThreshold
//Description:
//EventCode:
var threshold = Convert.ToDouble(context["Threshold"]);

if (context.ContainsKey("InvoiceID") && threshold > 0)
{
    var invoice = ViewInvoice.GetByID(Convert.ToInt32(context["InvoiceID"]));
    var user = User.GetByID(Convert.ToInt32(context["UserID"]));

    if (invoice.Balance > threshold)
    {
        EventLogger.Log(user.ID, user.ID, "PaymentTermsWithBalanceThreshold", "PaymentTerms", "Executing Payment Term PaymentTermsWithBalanceThreshold", user.OwnerID, "Invoice", invoice.ID, null);

        var emails = user.GetOwner().SearchEmailMessageByName(context["EmailMessage"].ToString());

        if (emails.Length > 0)
        {
            var email = (Logic.Core.EmailMessage)emails[0];
            email.SendTo(user.ID);
            return true;
        }
    }
    else
    {
        EventLogger.Log(user.ID, user.ID, "PaymentTermsWithBalanceThreshold", "PaymentTerms", "Error returned from Threshold PT", user.OwnerID, "Invoice", invoice.ID, null);
    }
}
return false;


Second Example - To run the payment term IF the recurring total is greater then y, use the following script which will send an email but can be implanted with other action scripts to do things like applying a late fee or other functionality.

Code Block
languagec#
//Name: PaymentTermsWithInvoiceRecurringTotalThreshold
//Description:
//EventCode:
var threshold = Convert.ToDouble(context["Threshold"]);

if (context.ContainsKey("InvoiceID") && threshold > 0)
{
    var user = User.GetByID(Convert.ToInt32(context["UserID"]));
    var invoice = ViewInvoice.GetByID(Convert.ToInt32(context["InvoiceID"]));
    var total = 0d;

    foreach (var statementDetail in ViewStatementdetailsInvoiceByPackageGroup.SearchByInvoiceID(Convert.ToInt32(context["InvoiceID"])))
    {
        total += statementDetail.Amount * statementDetail.Quantity;
    }

    if (total > threshold)
    {
        EventLogger.Log(user.ID, user.ID, "PaymentTermsWithInvoiceRecurringTotalThreshold", "PaymentTerms", "Executing Payment Term PaymentTermsWithInvoiceRecurringTotalThreshold",
            user.OwnerID, "Invoice", invoice.ID, null);
                   
        //Execute other logic here
        var emails = user.GetOwner().SearchEmailMessageByName(context["EmailMessage"].ToString());

        if (emails.Length > 0)
        {
            var email = (Logic.Core.EmailMessage) emails[0];
            email.SendTo(user.ID);
            return true;
        }
    }
    EventLogger.Log(user.ID, user.ID, "PaymentTermsWithInvoiceRecurringTotalThreshold", "PaymentTerms", context["EventLogMessageOnThresholdNotMet"].ToString(), user.OwnerID, "Invoice", invoice.ID, null);
}
return false;

...

This write off script is fired by payment terms for invoices that are past due by a set amount. It will set the user status on the account to that which you have selected and add a credit to the account to zero out the accounts balance effectively removing it from reports (because its balanced).

Code Block
languagec#
//Name: PaymentTermsWriteOff
//Description:
//EventCode:
var user = User.GetByID(Convert.ToInt32(context["UserID"]));

var userBalanceFutureQuery = new ViewUserBalanceFutureQuery { UserID = user.ID };
var balance = 0d;

foreach (var userBalanceFuture in ViewUserBalanceFuture.GetCollection(ref userBalanceFutureQuery))
{
    balance += userBalanceFuture.Balance;
}

var statusType = StatusType.GetByID(user.Current_StatusTypeID);
//This message is only logged to the EventLog if the user is NOT canceled
var message = Convert.ToString(context["EventLogMessage"]);

if (statusType.Name == "Canceled")
{
    if (balance > 0)
    {
        balance = balance * -1;
        var coreUser = (Logic.Core.User) user;
        coreUser.refundOptionName = Logic.Core.RefundOption.NONE;

        Logisense.Boss.Logic.Billing.Bill.AddCredit(coreUser.ID, balance, "Write Off (Payment Terms)", DateTime.MinValue, true);

        var userStatusType = user.GetActingOwner().SearchUserStatusTypeByName(context["UserStatus"].ToString())[0];
        coreUser.UserStatusTypeID = userStatusType.ID;
        coreUser.Update();
                   
        EventLogger.Log(user.ID, user.ID, "PaymentTermsWriteOff", "PaymentTerms", "User was canceled and balance was written off successfully.", user.OwnerID, "User", user.ID, null);
        return true;
    }
    else
    {
        EventLogger.Log(user.ID, user.ID, "PaymentTermsWriteOff", "PaymentTerms", message, user.OwnerID, "User", user.ID, null);
    }
}
else
{
    EventLogger.Log(user.ID, user.ID, "PaymentTermsWriteOff", "PaymentTerms", message, user.OwnerID, "User", user.ID, null);
}
return false;