Yes, I checked the Direct Invoice (Purchases).
http://fa.boxygen.biz/fa2325/purchasing/view/view_supp_invoice.php?trans_no=10
I will now test the Supplier Invoice.
It's much more fun, when you can discuss your problems with others...
You are not logged in. Please login or register.
FrontAccounting forum → Posts by apmuthu
Yes, I checked the Direct Invoice (Purchases).
http://fa.boxygen.biz/fa2325/purchasing/view/view_supp_invoice.php?trans_no=10
I will now test the Supplier Invoice.
Created a Direct Invoice under Purchasing in the Training Co - FA v2.3.25. The dimension appears in the GL View and not in the Invoice. The Dimension is set in the Supplier page and any Dimension can be chosen for the Direct Purchase Invoice during creation time.
What theme are you using - any changes in it's template you have done that may be erroneous or missing data? The standard FA 2.3 theme does not even display the Dimension column for the Supplier Invoice. Please use the Training Co (en_US-demo.sql Chart) for testing and comparing with your specific installs.
Yes it is blank in both screenshots - probably record did not have any dimension attached. Only in the second line it appears on the JV. How do you want it to be?
Line 288 of purchasing/includes/ui/invoice_ui.inc below is responsible for display of Dimension 1:
label_cell(get_dimension_string($entered_gl_code->gl_dim, true));
@joe: is this an error?
In the file admin/db/fiscalyears_db.inc, at the end of the function delete_this_fiscalyear(), deletion of remaining (unlinked to gl_trans) comments and refs table records does not check whether comments.date_ <= '$to' and refs.reference being within the fiscal year. Is this okay?
Void the GRN first before voiding the Invoice. It is possible that you may want to assign the GRN to another invoice later and hence it is possibly left for manual decision.
It is present in the 3rd field in the lower table in both cases.
Images zipped up in this post.
Lines 308 to 315 of the function delete_this_fiscalyear($selected_id) in admin/db/fiscal_years_db.inc:
while ($row2 = db_fetch_row($res))
{
$sql = "DELETE FROM ".TB_PREF."wo_issue_items WHERE issue_id = {$row2[0]}";
db_query($sql, "Could not delete wo issue items");
}
delete_attachments_and_comments(ST_MANUISSUE, $row['id']);
$sql = "DELETE FROM ".TB_PREF."wo_issues WHERE workorder_id = {$row['id']}";
db_query($sql, "Could not delete wo issues");
should actually be corrected (translation string) and optimised like the rest to be:
while ($row2 = db_fetch_row($res))
{
$sql = "DELETE FROM ".TB_PREF."wo_issue_items WHERE issue_id = {$row2[0]}";
db_query($sql, "Could not delete wo issue items");
$sql = "DELETE FROM ".TB_PREF."wo_issues WHERE workorder_id = {$row2[0]}";
db_query($sql, "Could not delete wo issues");
delete_attachments_and_comments(ST_MANUISSUE, {$row2[0]});
}
Line 303 in the same file:
$result = db_query($sql, "Could not retrieve supp trans");
should be:
$result = db_query($sql, "Could not retrieve workorders");
Line 326 in the same file:
$result = db_query($sql, "Could not retrieve supp trans");
should be:
$result = db_query($sql, "Could not retrieve stock moves");
Line 344 in the same file:
db_query($sql, "Could not delete exchange rates");
should be:
db_query($sql, "Could not delete budget transactions");
@joe: please verify and commit.
Lines 1029-1040 of the the function End() in reporting/includes/pdf_reports.inc:
if ($mail->send()) $sent++;
} // foreach contact
unlink($fname);
$this->SetLang(user_language());
if (!$try) {
display_warning(sprintf(_("You have no email contact defined for this type of document for '%s'."), $this->formData['recipient_name']));
} elseif (!$sent)
display_warning($this->title . " " . $this->formData['document_number'] . ". "
. _("Sending document by email failed") . ". " . _("Email:") . $emails);
else
display_notification($this->title . " " . $this->formData['document_number'] . " "
. _("has been sent by email to destination.") . " " . _("Email:") . $emails);
The variable $sent is false or 0. This is because the first line above failed, ie., $mail->send() failed. It is clear that the value of $contact['email'] is okay as the error clearly displays it as: INVOICE 3. Sending document by email failed. Email: faisalayub1980@gmail.com
Inspect the values of the variables: $msg and the object properties of $mail at this point and see what is missing.
The delete attachments function called during fiscal year deletion may leave orphan entries ib the attachments table. Listed below is the function for reference from admin/db/fiscalyears_db.inc lines 188-210:
function delete_attachments_and_comments($type_no, $trans_no)
{
$sql = "SELECT * FROM ".TB_PREF."attachments WHERE type_no = $type_no AND trans_no = $trans_no";
$result = db_query($sql, "Could not retrieve attachments");
$delflag = false;
while ($row = db_fetch($result))
{
$delflag = true;
$dir = company_path(). "/attachments";
if (file_exists($dir."/".$row['unique_name']))
unlink($dir."/".$row['unique_name']);
}
if ($delflag)
{
$sql = "DELETE FROM ".TB_PREF."attachments WHERE type_no = $type_no AND trans_no = $trans_no";
db_query($sql, "Could not delete attachment");
}
$sql = "DELETE FROM ".TB_PREF."comments WHERE type = $type_no AND id = $trans_no";
db_query($sql, "Could not delete comments");
$sql = "DELETE FROM ".TB_PREF."refs WHERE type = $type_no AND id = $trans_no";
db_query($sql, "Could not delete refs");
}
Only if the attachment file is deleted will the entry get removed from the attachments table - this may not always be the case if the attachment got deleted from the folder earlier say through some command line usage / SFTP.
Is this the intended functionality?
Will it not be better to keep separate folders for attachments for each fiscal_year?
We need to keep in mind that not all transactions finish completely within the fiscal_year.
@joe: Thanks for the explanation. Wiki-ed it.
Create a custom report and upload to your company/#/reporting folder as a rep###.php file - see extension examples and existing reporting/rep###.php files to help make your own or commercially engage FA consultants.
The final version of functions close_transactions() and open_transactions in the file includes/db/audit_trail_db.inc that works even for large datasets has been committed to my GitHub repo. It is now an entirely MySQL affair and no updation by cycling through redundant id instances of the audit_trail table and is as follows:
/*
Confirm and close for edition all transactions up to date $todate,
and reindex journal.
*/
function close_transactions($todate) {
$errors = 0;
begin_transaction();
$sql = "DROP TABLE IF EXISTS ".TB_PREF."audit_tmp";
db_query($sql, "Cannot drop hold table if present");
$sql2 = "CREATE TABLE ".TB_PREF."audit_tmp SELECT id, Counter AS gl_seq FROM
( SELECT id, gl_date, fiscal_year
, (@counter:=IF(fiscal_year <> @lastyr, 1, @counter+1)) AS Counter
, (@lastyr:=IF(fiscal_year <> @lastyr, fiscal_year, @lastyr)) AS LastYr FROM
( SELECT DISTINCT a.id, a.gl_date, a.fiscal_year
FROM ".TB_PREF."gl_trans gl INNER JOIN ".TB_PREF."audit_trail a
ON (gl.type=a.type AND gl.type_no=a.trans_no)
WHERE gl_date<='". date2sql($todate) ."' AND NOT ISNULL(gl_seq)
ORDER BY a.fiscal_year, a.gl_date, a.id) b, (SELECT (@lastyr:=0), (@counter:=1)
) w
) c";
db_query($sql2, "Cannot create hold table for gl_seq sequential values");
$sql3 = "UPDATE ".TB_PREF."audit_tmp a LEFT JOIN ".TB_PREF."audit_trail b USING (id)
SET b.gl_seq=a.gl_seq";
$result = db_query($sql3, "Cannot update audit_trail.gl_seq from hold table");
db_query($sql, "Cannot drop hold table");
commit_transaction();
}
/*
Reopen all transactions for edition up from date $fromdate
*/
function open_transactions($fromdate) {
$sql = "UPDATE ".TB_PREF."audit_trail SET gl_seq=0
WHERE gl_date>='". date2sql($fromdate) ."'
AND !ISNULL(gl_seq) AND !ISNULL(fiscal_year)";
$result = db_query($sql, "Cannot open transactions");
}
The Audit Trail relationships section of Wiki has been updated.
An example of the Opening / Closing entries in the gl_trans table is attached. The sql to extract it is:
$sql = "SELECT * FROM ".TB_PREF".gl_trans WHERE `type`=0 AND memo_ IN ("._('Open Balance').", "._('Closing Year').")";
or in plain sql with no translation and no table prefix:
SELECT * FROM gl_trans WHERE `type`=0 AND memo_ IN ('Open Balance', 'Closing Year');
Thanks for the perseverance and testing.
Linux calls it "C" perhaps for "common" or just "C" as in C Language..... where it all started.
@joe: try to make this as part of the codebase or as comments in the generated lang/languages_installed.inc file.
First, does the language specific option work?
Second, the default language is "C" which must exist in your lang/installed_languages.inc like:
<?php
/* How to make new entries here for non-packaged languages:
-- 'code' should match the name of the directory for the language under \lang
.-- 'name' is the name that will be displayed in the language selection list (in Users and Display Setup)
-- 'rtl' only needs to be set for right-to-left languages like Arabic and Hebrew
-- 'encoding' used in translation file
-- 'version' always set to '' for manually installed languages.
-- 'path' installation path related to FA root (e.g. 'lang/en_US').
*/
$installed_languages = array (
0 =>
array (
'code' => 'C',
'name' => 'English',
'encoding' => 'iso-8859-1',
),
);
$dflt_lang = 'C';
?>
Now we need to study the code as to where these routines in the said file are called and how the defaults get assumed.
The file locale.inc is "included" in the
1. function install_hooks() in the file includes/hooks.inc
2. function set_language($code) in the file includes/lang/language.php
See if a backport of this commit works.
FA is self balanced as all transactions have their contra.
The gl_trans table is generally balanced.
Copy the locale file to say lang/en_US/locale.inc and edit the first method's name:
class hooks_xx_XX extends hooks {
to
class hooks_en_US extends hooks {
Now check it out by choosing the specific language en_US as US English in FA.
For a start, if you have a large amount of transactions in each year you wish to close/open, the function open_transactions can be replaced with:
function open_transactions($fromdate) {
$sql = "UPDATE ".TB_PREF."audit_trail SET gl_seq=0 WHERE gl_date>='". date2sql($fromdate) ."' AND !ISNULL(gl_seq) AND !ISNULL(fiscal_year)";
db_query($sql, "Cannot open transactions");
}
The above has been committed in my GitHub Repo - 1, 2.
The function close_transactions called in function close_year in admin/db/fiscalyears_db.inc be commented out and it's functionality be manually executed from the sql obtained from:
$sql = "
DROP TABLE IF EXISTS ".TB_PREF."audit_tmp;
CREATE TEMPORARY TABLE ".TB_PREF."audit_tmp SELECT id, Counter AS gl_seq FROM (
SELECT id, gl_date, fiscal_year
, (@counter:=IF(fiscal_year <> @lastyr, 1, @counter+1)) AS Counter
, (@lastyr:=IF(fiscal_year <> @lastyr, fiscal_year, @lastyr)) AS LastYr FROM
( SELECT DISTINCT a.id, a.gl_date, a.fiscal_year
FROM ".TB_PREF."gl_trans gl INNER JOIN ".TB_PREF."audit_trail a ON (gl.type=a.type AND gl.type_no=a.trans_no)
WHERE gl_date<='". date2sql($todate) ."' AND NOT ISNULL(gl_seq)
ORDER BY a.fiscal_year, a.gl_date, a.id) b, (SELECT (@lastyr:=0), (@counter:=1)) w
) c;
UPDATE ".TB_PREF."audit_tmp a LEFT JOIN ".TB_PREF."audit_trail b USING (id) SET b.gl_seq=a.gl_seq;
DROP TABLE ".TB_PREF."audit_tmp;
";
We also need to see if there is any performance gain by indexing gl_seq in the audit_trail table.
Only closed fiscal years will have the audit_table.gl_seq chronologically sequentially numbered (some will be NULL and some others 0 as well). All open fiscal years will have the said field as 0 or NULL only.
At the end of successful closure of a fiscal year, on it's last date as the last 2 gl_trans.counter entries we get the memo_ field set to Closing Year with the amount values in contra. When the fiscal year is then re-opened, these entries still remain and will need to be manually deleted to be re-created when it is subsequently closed.
The Audit Trail ERD is available in the Wiki.
Even if we mimic the mysqli_multi_query in the mysql driver used in FA 2.3.x, it is still very slow when the equivalent function below is used:
function multiQuery($queryBlock, $delimiter = ';') {
$inString = false;
$escChar = false;
$sql = '';
$stringChar = '';
$queryLine = array();
$sqlRows = explode ( "\n", $queryBlock );
$delimiterLen = strlen ( $delimiter );
do {
$sqlRow = current ( $sqlRows ) . "\n";
$sqlRowLen = strlen ( $sqlRow );
for ( $i = 0; $i < $sqlRowLen; $i ) {
if ( ( substr ( ltrim ( $sqlRow ), $i, 2 ) === '--' || substr ( ltrim ( $sqlRow ), $i, 1 ) === '#' ) && !$inString ) {
break;
}
$znak = substr ( $sqlRow, $i, 1 );
if ( $znak === '\'' || $znak === '"' ) {
if ( $inString ) {
if ( !$escChar && $znak === $stringChar ) {
$inString = false;
}
}
else {
$stringChar = $znak;
$inString = true;
}
}
if ( $znak === '\\' && substr ( $sqlRow, $i - 1, 2 ) !== '\\\\' ) {
$escChar = !$escChar;
}
else {
$escChar = false;
}
if ( substr ( $sqlRow, $i, $delimiterLen ) === $delimiter ) {
if ( !$inString ) {
$sql = trim ( $sql );
$delimiterMatch = array();
if ( preg_match ( '/^DELIMITER[[:space:]]*([^[:space:]] )$/i', $sql, $delimiterMatch ) ) {
$delimiter = $delimiterMatch [1];
$delimiterLen = strlen ( $delimiter );
}
else {
$queryLine [] = $sql;
}
$sql = '';
continue;
}
}
$sql .= $znak;
}
} while ( next( $sqlRows ) !== false );
return $queryLine;
}
It's usage will be:
$multiple_queries = 'SELECT CURRENT_USER();
SELECT Name FROM City ORDER BY ID LIMIT 20, 5;';
$sql_queries = multiQuery($multiple_queries);
foreach($sql_queries as $sql_query) {
// Execute each query
mysql_query($sql_query) or exit('SQL: '.$sql_query.', Error: '.mysql_error());
}
The file includes/db/audit_trail_db.inc has the functions close_transactions() and open_transactions() and in both, only the audit_trail.gl_seq field is updated and the gl_trans.gl_date field is unnecessarily being called in for ordering whereas the audit_trail.gl_date already has the info taken from the former at the time of transaction creation.
In the function open_transactions() there is no need for any ordering as a mere set to 0 of the gl_seq field is all that is done wholesale.
In the close_transactions(), the LEFT JOIN should be an INNER JOIN as there is no point in attempting to update records in audit_trail table where no id exists if it only existed in the gl_trans table!
A pure MySQL implementation of the close_transactions sql would reduce to:
SET @lastyr:=0;
SET @counter:=1;
CREATE TEMPORARY TABLE audit_tmp SELECT id, Counter AS gl_seq FROM (
SELECT id, gl_date, fiscal_year
, (@counter:=IF(fiscal_year <> @lastyr, 1, @counter+1)) AS Counter
, (@lastyr:=IF(fiscal_year <> @lastyr, fiscal_year, @lastyr)) AS LastYr FROM
( SELECT DISTINCT a.id, a.gl_date, a.fiscal_year
FROM gl_trans gl INNER JOIN audit_trail a ON (gl.type=a.type AND gl.type_no=a.trans_no)
WHERE gl_date<='2015-12-31' AND NOT ISNULL(gl_seq)
ORDER BY a.fiscal_year, a.gl_date, a.id) b
) c;
UPDATE audit_tmp a LEFT JOIN audit_trail b USING (id) SET b.gl_seq=a.gl_seq;
DROP TABLE audit_tmp;
Likewise, the open_transactions sql would reduce to:
UPDATE audit_trail SET gl_seq=0 WHERE gl_date>='2016-01-01' AND !ISNULL(gl_seq);
Failure to correct this will cause a timeout when trying to close large fiscal years.
1. Start with a new FA install and create a Supplier and a few items
2. Take a backup 1.
3. Create your PO entry to a supplier
4. Make an Advance Payment
5. Enter the deposit Refund
6. Delete the PO
7. Take a backup 2.
8. Restore backup 1
9. Make an Advance Payment to some Supplier
10. Enter the deposit Refund
11. Check that the Allocation line for the supplier is absent (since no PO)
12. Take backup 3.
Now compare backup 2 and 3 and see which field needs to be manually changed for the allocation entry to vanish.
For those who need to know what Fund Accounting Compliance is, these links would prove useful.
Job Description of a Fund Accountant
Fund Accounting manual - 90 pages, 592 Kb
Just disable Manufacturing in FA (and possibly remove the related tables) to simplify for use in Fund Accounting (FA pun)
The payment is still linked to a purchase order. Delink the payment and then void the purchase order in that sequence.
Done.
The default English language one is available at lang/new_language_template/locale.inc and will possibly be taken when no specific one a any chosen language is unavailable.
FrontAccounting forum → Posts by apmuthu
Powered by PunBB, supported by Informer Technologies, Inc.
Currently installed 4 official extensions. Copyright © 2003–2009 PunBB.