Check posting when check amount differs from pending receipt amount

Discussions concerning general integration topics.

Moderator: Phil Barton

joe.mag
Posts: 116
Joined: Thu Aug 04, 2011 3:11 pm

Check posting when check amount differs from pending receipt amount

Post by joe.mag » Fri Mar 05, 2021 11:37 am

We are running SoftPro Select 4.2.41028.10 (but will be upgrading soon). I have used the excellent sample code on this forum to get myself to the point where I can mark a receipt in the register as posted provided the check amount exactly matches the receipting amount. I'm hitting a snag when there's a discrepancy. When I go to set the receipt transaction amount, a security exception is thrown and provides no useful information, as best I can tell.

I notice the SoftPro Select user interface appears to perform various actions when I post a payment as a human would (as opposed to via the API). I'm guessing that, when using the API, I need to be performing these steps myself.

Would it be possible to get guidance on how to successfully post a check in the two scenarios of:
1) Check larger than expected
2) Check smaller than expected

Thanks!

BobRichards
Posts: 1060
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Check posting when check amount differs from pending receipt amount

Post by BobRichards » Mon Mar 08, 2021 7:19 pm

Please post your code for the activity of posting a check in the registry. As so far as security permissions associated with the issue, anything you can present would be useful - or at least a stack trace.

You are correct that the Select UI (and Select Server for that matter) might do multiple steps that must be emulated by API applications. The best bet at doing it right is to first do it in the Select UI then copy the order of the steps. In fact, I find many API problems are solved by doing it manually in the Select UI (and sometimes realizing that it can't be done that way either).
Bob Richards, Software Developer, SoftPro

joe.mag
Posts: 116
Joined: Thu Aug 04, 2011 3:11 pm

Re: Check posting when check amount differs from pending receipt amount

Post by joe.mag » Mon Mar 08, 2021 8:39 pm

Our code is written to allow repeated execution so there's a check to avoid duplicate posting. Otherwise, it's been stripped down to provide the simplest possible sample code. If I populate the constants appropriately, I can post successfully (if check amount is exactly same as pending receipt amount) or see the security exception (if the check amount is greater than the pending receipt amount).

Code: Select all

            // this code relies heavily on code samples from the SoftPro dev forum
            try
            {
                // set up the various constants for sample code
                string c_strOrderNumber = "<order number here>";
                string c_strCheckNumber = "123456";
                decimal c_dCheckAmount = 100; // for success, make this match pending receipt amount, different for failure

                // find the order
                IOrderInfo search = os.Orders.Where(t => t.Number == c_strOrderNumber).FirstOrDefault();
                if (search != null)
                {
                    using (dynamic order = os.OpenOrder(search, false))
                    {
                        // build the objects needed to access the ledger
                        ILedgersManager lm = server.GetService<ILedgersManager>();
                        ITransactionsManager tm = server.GetService<ITransactionsManager>();
                        IOrder orderObject = order;
                        Guid orderID = orderObject.Identifier.Guid;
                        ILedgerInfo ledInfo = lm.GetLedgerForOrder(orderID);
                        if (ledInfo != null)
                        {
                            // we always treat the ATtorney as the payor
                            string strATName = "";
                            foreach (var con in order.Contacts)
                            {
                                if (con.Code == "AT")
                                {
                                    strATName = con.Name;
                                    break;
                                }
                            }

                            // prepare to operate on the ledger
                            IOrderLedger ledger = (IOrderLedger)lm.GetLedger(ledInfo);
                            foreach (var trans in ledger.Transactions)
                            {
                                // we expect one pending receipt if no check has been posted, one posted receipt if one has
                                if (trans.Kind == TransactionKind.Receipt)
                                {
                                    IReceiptTransaction rec = (IReceiptTransaction)tm.GetTransaction(trans);

                                    // simply ignore all but posted or pending
                                    if ((rec.Status == TransactionStatus.Voided) ||
                                        (rec.Status == TransactionStatus.Held) ||
                                        (rec.Status == TransactionStatus.InTransit) ||
                                        (rec.Status == TransactionStatus.StopPayment))
                                    {
                                        continue;
                                    }
                                    else if (rec.Status == TransactionStatus.Posted)
                                    {
                                        // if match, then we've already posted a check
                                        if ((rec.Amount == c_dCheckAmount) &&
                                            (rec.FromCheck == c_strCheckNumber) &&
                                            (rec.Name == strATName))
                                        {
                                            // done w/ loop
                                            break;
                                        }
                                    }
                                    // pending
                                    else
                                    {
                                        // keep the expected amount (i.e. the receipt amount) handy
                                        Decimal expectedAmount = rec.Amount;

                                        // we have to make sure the apply lines add up to the expected amount
                                        var applied = rec.Splits.Single(s => s.Kind == TransactionSplitKind.Applied);
                                        applied.Amount = expectedAmount;

                                        // check is larger than expected so route the remainder to the overage field
                                        if (c_dCheckAmount > expectedAmount)
                                        {
                                            var overage = rec.Splits.Single(s => s.Kind == TransactionSplitKind.Overage);
                                            overage.Amount = c_dCheckAmount - expectedAmount;
                                        }

                                        // this should force the payor to the AT enumeration value
                                        rec.Name = strATName;
                                        rec.Amount = c_dCheckAmount;
                                        rec.FromCheck = c_strCheckNumber;
                                        rec.Status = TransactionStatus.Posted;

                                        tm.ApplyChanges("cash from borrower", rec);

                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string strMessage = ex.Message;
            }


BobRichards
Posts: 1060
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Check posting when check amount differs from pending receipt amount

Post by BobRichards » Mon Mar 08, 2021 9:08 pm

Can you please post the exception message and stack trace?
Bob Richards, Software Developer, SoftPro

joe.mag
Posts: 116
Joined: Thu Aug 04, 2011 3:11 pm

Re: Check posting when check amount differs from pending receipt amount

Post by joe.mag » Tue Mar 09, 2021 1:06 pm

BTW, I am operating as the default admin for these operations in SoftPro Select.

See attached for screen shot of exception

Text versions:

Exception of type 'System.Security.SecurityException' was thrown.

stack trace:

at SoftPro.ClientModel.DomainObject.ThrowIfCannotWrite(String propertyName)
at SoftPro.ClientModel.DomainObject.SetProperty[T](String propertyName, T& field, T value)
at SoftPro.Accounting.Client.Transactions.Transaction.set_Amount(Decimal value)
at DBToSoftPro.Form1.buttonTestCode_Click(Object sender, EventArgs e) in C:\\Users\\jmagura\\Documents\\Visual Studio 2017\\Projects\\SoftPro Finals Processor\\SoftPro Finals Processor\\Form1.cs:line 1538
Attachments
Security Exception.png
Security Exception.png (44.76 KiB) Viewed 142 times

BobRichards
Posts: 1060
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Check posting when check amount differs from pending receipt amount

Post by BobRichards » Wed Mar 17, 2021 11:55 am

Sorry to take so long to respond to you. I lost track of your question.

When you are changing the amount of the transaction, make sure the transaction funds are "applied to closing". If not, Select will complain. You can do this with the code below.

Code: Select all

/// <summary>
/// Send amount to "Apply to Closing" split and zero out all others.
/// </summary>
/// <param name="tran">The tran.</param>
/// <param name="amount">The new amount.</param>
private void ApplyAmountToUnappliedSplit(ITransaction tran, decimal amount)
{
    foreach (var split in tran.Splits)
    {
        if (split.Kind == TransactionSplitKind.Applied)
        {
            split.Amount = amount;
        }
    }
}
Also, being a member of the Administrators group does not grant all security permissions. You may be running into some ProTrust security violation.

Let me know if this takes care of it.
Bob Richards, Software Developer, SoftPro

joe.mag
Posts: 116
Joined: Thu Aug 04, 2011 3:11 pm

Re: Check posting when check amount differs from pending receipt amount

Post by joe.mag » Thu Mar 18, 2021 11:40 am

There seem to be two main recommendations -- make sure permissions match attempted operations and make sure the splits add up and make sense. I revisited the code and re-applied your logic of trying things in the UI first and then mimicking in the code in terms of sequencing.

Permissions: I tried my test code running as a user who has full privileges in the accounting and ledger areas and there was no change in behavior

Logic: In the UI, when I go to post a payment, I enter a check amount that exceeds the pending receipt. The UI automatically applies the full amount to the all to the Apply to Closing. I then manually adjust the AtoC to be the amount of the pending receipt and put the overage into the Overage cell. I then press OK. All is well.

In code, I would logically start by specifying the receipt.Amount as the check amount and then reconcile the Apply lines just like in the UI. I can't even start since setting receipt.Amount throws the security exception. If I try to ajust the Apply lines beforehand, the exception is still thrown when I later set the receipt amount. I can't mimick the UI and I can't seem to stumble on the correct sequence to make things work.

Note: If the check amount matches the pending receipt, I can move the order of reconciling Apply lines and setting receipt.Amount around and it doesn't matter--the code always works.

So, the short of it is -- I'm still stuck.

BobRichards
Posts: 1060
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Check posting when check amount differs from pending receipt amount

Post by BobRichards » Thu Mar 18, 2021 2:08 pm

I have written code to to this on a prior project to create a new check then set it to posted. One thing to know is ProTrust is very picky about what properties you set depending on the transaction Status value. I don't have any direct experience with dealing with overages or under payments. Below is the code I used. Perhaps reviewing the steps can help.

Can I assume that when you do work in this order - pay particular attention to WHEN I set the transaction status to Posted. I have supplied other properties to show when I did operations in my code.

Code: Select all

// Create a new PENDING item so can set fields that will become read only once set
//  to different status (i.e Posted).
//  (Note: This is all that is required for a pending check.)
ITransactionsManager transMgr = ss.GetService<ITransactionsManager>();
ICheckTransaction tran = transMgr.NewTransaction<ICheckTransaction>(ledgerInfo);
tran.Status = TransactionStatus.Pending;
tran.Amount = amount;
tran.Medium = medium;
tran.Memo = memo;
tran.MemoExtended = memoExtended;
tran.Name = name;
tran.Address.UseForeignAddress = false;
Address.Address1 = taddr1;
...

// Now post the check.
tran.Status = TransactionStatus.Posted;
tran.ReferenceNumber = checkNumber;
SetTransactionSplits(); // Set Apply to Order, Overage,... values

// Set date based on transaction type.
if (tran.Status == TransactionStatus.Posted)
{
	tran.ClearedOn = d;
}
else
{
	// Voided.
	tran.VoidedOn = d;
}

// Save the transaction and give a reason if the transaction is a void.
transMgr.ApplyChanges(tran.RequiresAdjustmentReason ? transactionReason : null, tran);
Bob Richards, Software Developer, SoftPro

joe.mag
Posts: 116
Joined: Thu Aug 04, 2011 3:11 pm

Re: Check posting when check amount differs from pending receipt amount

Post by joe.mag » Thu Mar 18, 2021 4:08 pm

Bob, Thanks for the sample code! I'm not sure how to set some of the field values (e.g. was would "medium" be -- I see it's an enumeration but not sure how to specify 'check'). Doing my best to adopt your code, I get a "payee code is required" exception. I don't see how to access the Payor or Payee code in the object model so kind of stumped.

Stack trace is SoftPro.Accounting.Client.Transactions.TransactionManagerUtils.ThrowIfPayorPayeeIsNull

I can see how, when I use the UI, the Payor code on a transaction can be changed but, as stated, I don't see how to access the property to set it.

BobRichards
Posts: 1060
Joined: Wed Jan 15, 2014 3:50 pm
Location: Raleigh, NC
Contact:

Re: Check posting when check amount differs from pending receipt amount

Post by BobRichards » Thu Mar 18, 2021 5:21 pm

The order ledger holds a small cache of information the ProTrust uses to process orders.

Code: Select all

// Load the full ledger object
ILedgersManager lm = this.GetService<ILedgersManager>();
IOrderLedger ledger = (IOrderLedger)lm.GetLedger(this.Ledger);
IOrderInformation orderInformation = ledger.GetOrderInformation();
You will see in the SDK that the IOrderInformation has lots of information - including the order contacts (IOrderInformation.Contacts). To fill in the transaction contact, you need to pick one of the order contacts and load its ID (Guid string) into a specific transaction tag.

Code: Select all

// OrderContact
IOrderContact allBuyers = orderInformation.Contacts.Where(c => c.Type == "BA").Single();
relatedCredit.Tags.Add(new Tag(Constants.OrderContactIDProperty, allBuyers.ID.ToString()));
relatedCredit.Name = allBuyers.Name;
Internally, we created the tag name in a project constant.

Code: Select all

/// <summary>
/// The order contact id property
/// </summary>
public const string OrderContactIDProperty = "OrderContactID";
Useless trivia - If the entire amount is written the to "Unapplied" split, then you don't need a contact.
Bob Richards, Software Developer, SoftPro

Post Reply