(1 replies, posted in FA Modifications)

The FA extension Import Transactions can create both invoices and payments.

Yes, everything you describe makes sense, as this is exactly how FA currently works.  I agree that it is a bug at worst and inconsistent at best.

As Rafat pointed out, I offered a fix for the blank Person/Item when the Pay To is Miscellaneous or Quick Entry. However, it was never incorporated into FA for unknown reasons.

Which memo is displayed depends on whether it is a transaction query or a G/L account query.  Transaction queries do not display the line memos because there could be many lines of memos, one per G/L account in an multi-account transaction.  G/L queries can show all the memos.

Why some reports show the memo and others don't probably has to do with trying to fit the information on a page.

The Bank Inquiry and Reconcile Bank Account pages are transaction queries.  They show one line per transaction and can only show the transaction memo.

In order to show the line memos, one could create an extension that shows the G/L info, either with a hyperlink that expands the info or simply indents the G/L info underneath the transaction. Per the request of my accounting staff, I had to create an extension to do exactly that (QuickReport, modeled after Quickbooks).   Personally, I do not use it because it is just too crowded for my liking.

Can you use the FA demo site to demonstrate the problem?

My guess is that you posting about a bug as well as a feature and have everyone thoroughly confused.

Lets start with the bug report.  My guess is that you are entering a Bank Payment with a Pay To ("person") of Miscellaneous.   This is a good guess because in vanilla FA, this will not show up in the Person/Item field on the banking reports or on the reconcile page, whereas all other Pay To types (supplier, customer, qe) will show up.

Using the FA Demo site, I created Bank Payment 23 to the BCA bank to illustrate the problem.  Anyone is welcome to view this transaction on the demo site.  Note that the Pay To person appears in Bank Inquiry but does not show up on Reconcile.

You can also use the FA Demo site to illustrate your problem.  Just create a transaction as I have done and tell us the bank account and transaction number and what does not work about the transaction.

I haven't fully investigated why this does not work on vanilla FA.  It does work on my fork, but that is because at some point I changed bank_account_reconcile.php and other pages to call:

function fmt_person($trans)
    return payment_person_name_link($trans["person_type_id"],$trans["person_id"],true,sql2date($trans["trans_date"]));

which is a new function in my fork that calls payment_person_name rather than

function fmt_person($trans)
    return get_counterparty_name($trans["type"], $trans["trans_no"]);

I haven't investigated any further than that.

The other part of your posting appears to be a feature request regarding the two memo fields.  Many accounting systems, like FA, have a line memo as well as a transaction memo.  Some people are horribly confused by this, even within my own company.  This especially arises when there is only one line item.  I advise people to use the line memo for their explanatory notes and the transaction memo only for the check number and the description that will be displayed on the bottom of the actual check, if it were printed out.  That is, the transaction memo is public information.

However, this policy was impossible to enforce, and therefore, I have had to modify FA to concatenate all the line memos and the transaction memo on certain reports and inquiries, so wherever the user enters the data, it will appear.

In vanilla FA, only the transaction memo appears on transaction reports and the line memo appears on G/L reports.  On the transaction inquiry pages, you can click the G/L icon (open book with two pages) to view the G/L information and line memo.


(14 replies, posted in Setup)

Sending invoices with PHP 8 works for me, so the problem is neither FA or PHP 8.

If FA shows the invoice was mailed in green, it means that your mailer returned success.

Because you are able to send with PHP 7 and not PHP 8, you may have some differing mailer setting in your php.ini file for each version.

If the php.ini files are identical, then you need to enable debug on your system mailer to see exactly what and where the email was sent.  You could compare the mailer debug output when running PHP 7 and PHP 8.

If there is no difference in mailer debug output, then you have run out of options to find the problem.

Sorry if this post is not of much help.


(7 replies, posted in Setup)

Its a feature.  You should open a bug report.

The reason this happens is that the voided transactions are never removed, but only zeroed out.  It may be because some of the info might be needed in an audit trail.  Or maybe it doesn't matter and the design could be changed.

I encountered a similar issue with g/l accounts.

Or simply make the customer inactive and forget about it.


(20 replies, posted in Report Bugs here)

Sorry, I meant to say ST_SALESINVOICE instead of ST_SALES_INVOICE.

Line 48 should read:
if ($type == ST_SALESINVOICE && is_cust_invoice_credited($type_no))

That way, the call to is_cust_invoice_credited is not called unless the type is an invoice.


(20 replies, posted in Report Bugs here)

The reason you are encountering this problem is because you won the lottery: you happen to have an invoice with the same transaction number that cannot be voided.

The code is indeed broken.  A void of a customer payment shouldn't fall through the case statement and check for an invoice using the same transaction number (is_cust_invoice_credited).

This should be an easy fix.  You can condition the call to cust_invoice_credited with && $type == ST_SALES_INVOICE

FA does not support the concept of a customer-supplier in any integrated fashion, but here are two approaches that you might want to consider.

A general approach is use a common dimension for the customer-supplier.  Then you can use the GL transactions report filtered by dimension to see all the activity for the customer and supplier identified by the dimension.  This also works to group several customers or suppliers together for reporting purposes.

If the customer-supplier is primarily a customer and you do not use AP supplier tracking (at least for the customer-supplier), another approach is make the customer-supplier only a customer and allow negative quantities/amounts on the customer invoice.  The negative amounts are the purchases that you make from the customer.  This requires minor changes to the sales entry form and database, but the rest of FA works fine negative amounts and increases your inventory.   This also works for returns that go back to inventory, which conceptually is just like buying stuff from your customer.


(4 replies, posted in Wish List)

Kvvaradha describes the generalized approach (making item code a reference, thus reusing existing code).  This would be a great addition to the base, and assuming your part numbers are numeric, would be easy to implement, using the {1} definition.  If they are not strictly numeric, you would have to add the meta code to handle those fields.

The quick and dirty approach is what I did in my fork.  This hard codes an assumption of how item codes are formatted, and may need to changed depending on how your item codes are formatted.  In my case, they have an alpha prefix and a numeric suffix.


function item_settings(&$stock_id, $new_item)
if ($new_item)

function numeric_offset($text) {
    preg_match('/\d/', $text, $m, PREG_OFFSET_CAPTURE);
    if (sizeof($m))
        return $m[0][1];

    // the case when there's no numbers in the string
    return strlen($text);

    This function returns the next unused stock_id in stock_master.
    To work correctly, stock_ids should be numeric or end in a numeric.
function next_stock_id() {
    $sql = "SELECT max(stock_id) as max FROM ".TB_PREF."stock_master";
    $result = db_query($sql, "Can not find max stock_id");
    $row = db_fetch_row($result);
    if (!$row[0]) return null;
    $offset= numeric_offset($row[0]);
    $num=substr($row[0], $offset);
    if (!is_numeric($num))
    return null;
    $num += 1;
    return substr($row[0], 0, $offset) . $num;

Alas, the procedure that I suggested is not foolproof if the inventory created by the delivery has already been used.  Because the void doesn't realize that you are just editing the delivery rather than removing it permanently.

As a quick workaround, you can disable the inventory check in void_transaction.php.  The check begins

if ($_POST['filterType'] == ST_SUPPRECEIVE) {

The inventory will go negative after voiding the delivery, But after receiving the PO again, it will go positive.  I haven't tried this, so be careful, and test this first in a demo database.

Another workaround without changing code would be to temporarily make an inventory adjustment, and then delete it afterwards.  The error message that you describe should tell you the stock_id and description of the affected item.

Yes I know this is a pain, and the real solution is for someone to post the code for a true supplier invoice editor that would not apply the inventory checks until the update key is pressed.

Close 2022 and all other open years and try again.  FA has a bug with multiple years open.  Usually it works but not always.


(2 replies, posted in Items and Inventory)

Or you can define separate sales types per customer and define the prices in Items->Sales Pricing.


(154 replies, posted in Modules Add-on's)

Probably at one time mysql allowed implicit conversion of null into zero and now it doesn't, breaking the sales order import code.

I am not familiar with this code, but it appears that the extension's read function fails to call update_payments function, unlike the base code.  So prep_amount is never set.  This is a problem with the code.

If you don't care about the prep_amount feature, you could initialize it to zero in the constructor (__construct function in /var/www/nts/modules/import_transactions/includes/import_sales_cart_class.inc):

$this->prep_amount = 0;

The FA "Bank Account Transfer" page supports "Bank Charges".  Those charges are subtracted from the transfer-to amount, but you would like them shown because your bank shows them.

To answer your question directly, yes, you can modify a page without modifying the core by including an extension that overrides a FA core page (see, https://frontaccounting.com/punbb/viewtopic.php?pid=34035#p34035).

But you can also duplicate the desired G/L behavior by creating a general journal quickentry (four lines: +-100% base, +-10%).

The latter approach is advised if the percentage is always the same because then you only need to enter just the base amount and then the charges are auto-calculated.

One notable caveat (gotcha) with using the "Bank Charges" feature of "Bank Account Transfer" is that FA does not edit the transaction correctly; it forgets about the bank charges.  Be sure to fix this bug when you create your extension.


(154 replies, posted in Modules Add-on's)

When I run into corruption issues (almost always my own doing), I usually try to use the usual FA web interface to remove the transactions, because it usually is tolerant of the corruption and often cleans it up correctly.  And if it leaves any residue, the residue is usually easy to remove with mysql or phpadmin.

This is often easier than trying to repair the damage.  Afterwards, you would then recreate the transactions correctly.


(154 replies, posted in Modules Add-on's)

Hmm, if you tried journal entries for bank transfers as I suggested (which works for me), and that resulted in the data corruption that you experienced, then that would be a bug.

Can you post the the input file, or at least the relevant part, that caused the missing g/l entries?  If you do, and I can confirm the bug, I may be able to fix it.

I also recommend commenting out:
// error_reporting(E_ALL);

Oddly enough, errors and notices are not shown otherwise.

My guess is that you found a bug in the API and fixed it.


(1 replies, posted in Modules/Add-on's)

set_posts() is an optional function.  You can either delete the line containing set_posts() or download the latest extension.

Read the wiki for more information.  Because every bank statement csv download is different, you have to customize the $items array.


(2 replies, posted in Accounts Receivable)

For edit of direct purchase orders: https://frontaccounting.com/fawiki/index.php?n=Help.DirectPurchaseInvoiceEntry.


(3 replies, posted in Items and Inventory)

Do you have any backups?  If so, restore the database for the desired date.

If not, and your db still has transactions (not closed out) you may have to change the report to back out the transactions.    As you point out, that is more accurate than simply using the current average cost.


(10 replies, posted in Report Bugs here)

The code fix:

--- a/core/sales/includes/db/sales_invoice_db.inc
+++ b/core/sales/includes/db/sales_invoice_db.inc
@@ -249,8 +249,9 @@ function void_sales_invoice($type, $type_no)
                if ($deliveries !== 0) {
                        if ($type == ST_SALESINVOICE && count($deliveries) == 1 && get_reference(ST_CUSTDELIVERY, $deliveries[0]) == "auto")
+                $trans = get_customer_trans($deliveries[0], ST_CUSTDELIVERY);
                                void_sales_delivery(ST_CUSTDELIVERY, $deliveries[0], false);
-                               $date_ = Today();
+                               $date_ = sql2date($trans['tran_date']);
                                add_audit_trail(ST_CUSTDELIVERY, $deliveries[0], $date_, _("Voided."));
                                add_voided_entry(ST_CUSTDELIVERY, $deliveries[0], $date_, "");
diff --git a/core/sales/includes/db/sales_order_db.inc b/core/sales/includes/db/sales_order_db.inc
index 17952e3..4b4734d 100644
--- a/core/sales/includes/db/sales_order_db.inc
+++ b/core/sales/includes/db/sales_order_db.inc
@@ -89,6 +89,8 @@ function delete_sales_order($order_no, $trans_type)
        hook_db_prevoid($trans_type, $order_no);
+    $order = get_sales_order_header($order_no, $trans_type);
        $sql = "DELETE FROM ".TB_PREF."sales_orders WHERE order_no=" . db_escape($order_no) 
                . " AND trans_type=".db_escape($trans_type);
@@ -98,7 +100,7 @@ function delete_sales_order($order_no, $trans_type)
                .db_escape($order_no) . " AND trans_type=".db_escape($trans_type);
        db_query($sql, "order Detail Delete");
-       add_audit_trail($trans_type, $order_no, Today(), _("Deleted."));
+       add_audit_trail($trans_type, $order_no, sql2date($order['ord_date']), _("Deleted."));


(19 replies, posted in Accounts Payable)

All line items on the supplier PO are in the same currency.  All the COGS feature does is to zero out the service line items and adjust the inventory line items so that the PO total remains the same.


(19 replies, posted in Accounts Payable)

I tried cloning my fork and installing the demo database, made no configuration changes and I did not reproduce the problem.  I selected Dinosaurius as the supplier, iPad Air 2 16GB as the first item and Maintenance as the second item to add the COGS.  You might want to test that.  I tested both Firefox and Chrome.

I do not know if it is coincidence, but Ajax is running on the Price Before Tax because of the commit that I added that you posted about recently.   It updates the total after focus leaves the price field.


(3 replies, posted in Setup)

Does this post help?