Added closing transactions up to selected date.
authorJanusz Dobrowolski <janusz@frontaccounting.eu>
Wed, 26 Jan 2011 12:53:35 +0000 (12:53 +0000)
committerJanusz Dobrowolski <janusz@frontaccounting.eu>
Wed, 26 Jan 2011 12:53:35 +0000 (12:53 +0000)
12 files changed:
applications/generalledger.php
config.default.php
gl/includes/db/gl_db_trans.inc
gl/inquiry/journal_inquiry.php
gl/manage/close_period.php [new file with mode: 0644]
includes/access_levels.inc
includes/db/audit_trail_db.inc
includes/ui/ui_input.inc
purchasing/po_entry_items.php
themes/aqua/images/closed.png [new file with mode: 0644]
themes/cool/images/closed.png [new file with mode: 0644]
themes/default/images/closed.png [new file with mode: 0644]

index c4c0522b4f3cd4296991c96a45c8a14837e70e89..351e2486d178001483f41216de32e73498bed4de 100644 (file)
@@ -71,7 +71,8 @@ class general_ledger_app extends application
                        "gl/manage/gl_account_types.php?", 'SA_GLACCOUNTGROUP', MENU_MAINTENANCE);
                $this->add_rapp_function(2, _("GL Account &Classes"),
                        "gl/manage/gl_account_classes.php?", 'SA_GLACCOUNTCLASS', MENU_MAINTENANCE);
-               $this->add_rapp_function(2, "","");
+               $this->add_rapp_function(2, _("&Closing GL Transactions"),
+                       "gl/manage/close_period.php?", 'SA_GLSETUP', MENU_MAINTENANCE);
                $this->add_rapp_function(2, _("&Revaluation of Currency Accounts"),
                        "gl/manage/revaluate_currencies.php?", 'SA_EXCHANGERATE', MENU_MAINTENANCE);
 
index 6705918f5be30bc876144d02a1c1065832b66c27..55820f5a583d3808f334541a3213eaeee0215a7e 100644 (file)
@@ -120,7 +120,10 @@ if (!isset($path_to_root) || isset($_GET['path_to_root']) || isset($_POST['path_
 
        /* suppress tax rates on documents. 0 = no, 1 = yes. */
        $suppress_tax_rates = 0;
-       
+
+       /* allow reopening closed transactions */
+       $allow_gl_reopen = 0;
+
        $dateformats    = array("MMDDYYYY", "DDMMYYYY", "YYYYMMDD");
        $dateseps               = array("/", ".", "-", " ");
        $thoseps                = array(",", ".", " ");
@@ -204,25 +207,26 @@ if(isset($_SESSION["wa_current_user"])) {
 
 if (!defined('ICON_EDIT'))
 {
-       define("ICON_EDIT", "edit.gif");        
-       define("ICON_DELETE", "delete.gif");    
-       define("ICON_ADD", "ok.gif");   
-       define("ICON_UPDATE", "ok.gif");        
-       define("ICON_OK", "ok.gif");    
-       define("ICON_CANCEL", "cancel.png");    
-       define("ICON_GL", "gl.png");    
-       define("ICON_PRINT", "print.png");      
-       define("ICON_PDF", "pdf.gif");  
-       define("ICON_DOC", "invoice.gif");      
-       define("ICON_CREDIT", "credit.gif");    
-       define("ICON_RECEIVE", "receive.gif");  
-       define("ICON_DOWN", "download.gif");    
-       define("ICON_MONEY", "money.png");      
-       define("ICON_REMOVE", "remove.png");    
-       define("ICON_REPORT", "report.png");    
-       define("ICON_VIEW", "view.gif");        
+       define("ICON_EDIT", "edit.gif");
+       define("ICON_DELETE", "delete.gif");
+       define("ICON_ADD", "ok.gif");
+       define("ICON_UPDATE", "ok.gif");
+       define("ICON_OK", "ok.gif");
+       define("ICON_CANCEL", "cancel.png");
+       define("ICON_GL", "gl.png");
+       define("ICON_PRINT", "print.png");
+       define("ICON_PDF", "pdf.gif");
+       define("ICON_DOC", "invoice.gif");
+       define("ICON_CREDIT", "credit.gif");
+       define("ICON_RECEIVE", "receive.gif");
+       define("ICON_DOWN", "download.gif");
+       define("ICON_MONEY", "money.png");
+       define("ICON_REMOVE", "remove.png");
+       define("ICON_REPORT", "report.png");
+       define("ICON_VIEW", "view.gif");
        define("ICON_SUBMIT", "ok.gif");
-       define("ICON_ESCAPE", "escape.png");    
+       define("ICON_ESCAPE", "escape.png");
+       define("ICON_CLOSED", "closed.png");
 }
 
 ?>
\ No newline at end of file
index 7677fa3ec328042f5ed988f47db09d8acab7c552..b976571371067defa4dc18908cd50b7fa27b49e5 100644 (file)
@@ -92,7 +92,7 @@ function add_gl_balance($type, $trans_id, $date_, $amount, $person_type_id=null,
                        $amount, null, $person_type_id, $person_id, "The balanced GL transaction could not be inserted");
        else
                return 0;
-}      
+}
 
 //--------------------------------------------------------------------------------
 
@@ -145,28 +145,31 @@ function get_gl_transactions($from_date, $to_date, $trans_no=0,
 function get_gl_trans($type, $trans_id)
 {
        $sql = "SELECT gl.*, cm.account_name, IF(ISNULL(refs.reference), '', refs.reference) AS reference FROM "
-               .TB_PREF."gl_trans as gl
-               LEFT JOIN ".TB_PREF."chart_master as cm ON gl.account = cm.account_code
-               LEFT JOIN ".TB_PREF."refs as refs ON (gl.type=refs.type AND gl.type_no=refs.id)"
-               ." WHERE gl.type= ".db_escape($type) 
-               ." AND gl.type_no = ".db_escape($trans_id)
-               ." ORDER BY counter";
+               .TB_PREF."gl_trans as gl"
+               . " LEFT JOIN ".TB_PREF."chart_master as cm ON gl.account = cm.account_code
+                       LEFT JOIN ".TB_PREF."refs as refs ON (gl.type=refs.type AND gl.type_no=refs.id)";
+               $sql .= " WHERE gl.type= ".db_escape($type) 
+               ." AND gl.type_no = ".db_escape($trans_id);
+       $sql .= " ORDER BY counter";
        return db_query($sql, "The gl transactions could not be retrieved");
 }
 
 //--------------------------------------------------------------------------------
 
-function get_gl_wo_cost_trans($trans_id, $person_id=-1)
+function get_gl_wo_cost_trans($trans_id, $cost_type=-1)
 {
-       $sql = "SELECT ".TB_PREF."gl_trans.*, ".TB_PREF."chart_master.account_name FROM "
-               .TB_PREF."gl_trans, ".TB_PREF."chart_master
-               WHERE ".TB_PREF."chart_master.account_code=".TB_PREF."gl_trans.account
-               AND ".TB_PREF."gl_trans.type=".ST_WORKORDER
-               ." AND ".TB_PREF."gl_trans.type_no=".db_escape($trans_id)."
-               AND ".TB_PREF."gl_trans.person_type_id=".PT_WORKORDER;
-       if ($person_id != -1)
-               $sql .= " AND ".TB_PREF."gl_trans.person_id=".db_escape($person_id);
-       $sql .= " AND amount < 0";      
+       $sql = "SELECT costing.*, gl.*, chart.account_name, com.memo_ FROM "
+               .TB_PREF."wo_costing costing, "
+               .TB_PREF."gl_trans gl LEFT JOIN ".TB_PREF."comments com ON gl.type=com.type     AND gl.type_no=com.id,"
+               .TB_PREF."chart_master chart
+               WHERE 
+                       costing.workorder_id=".db_escape($trans_id)
+               ."      AND chart.account_code=gl.account
+                       AND gl.type=costing.trans_type
+                       AND gl.type_no=costing.trans_no";
+       if ($cost_type != -1)
+               $sql .= " AND costing.cost_type=".db_escape($cost_type);
+       $sql .= " AND amount < 0";
 
        return db_query($sql, "The gl transactions could not be retrieved");
 }
@@ -642,7 +645,10 @@ function get_sql_for_journal_inquiry($filter, $from, $to, $ref='', $memo='', $al
        if (!$alsoclosed) {
                $sql .= " AND gl_seq=0";
        }
-       $sql .= " GROUP BY gl.type, gl.type_no";
+       else
+               $sql .= " AND NOT ISNULL(a.gl_seq)";
+
+               $sql .= " GROUP BY tran_date, gl_seq, gl.type, gl.type_no";
        return $sql;
 }
 ?>
\ No newline at end of file
index dccef78f5c568c503730cb8c06bedfc5504eb6cc..3fd59521e59157fdd96c81777b983490a29ce4e6 100644 (file)
@@ -79,38 +79,9 @@ function gl_link($row)
        return get_gl_view_str($row["type"], $row["type_no"]);
 }
 
-$editors = array(
-       ST_JOURNAL => "/gl/gl_journal.php?ModifyGL=Yes&trans_no=%d&trans_type=%d",
-       ST_BANKPAYMENT => "/gl/gl_bank.php?ModifyPayment=Yes&trans_no=%d&trans_type=%d",
-       ST_BANKDEPOSIT => "/gl/gl_bank.php?ModifyDeposit=Yes&trans_no=%d&trans_type=%d",
-//     4=> Funds Transfer,
-   ST_SALESINVOICE => "/sales/customer_invoice.php?ModifyInvoice=%d",
-//   11=>
-// free hand (debtors_trans.order_==0)
-//     "/sales/credit_note_entry.php?ModifyCredit=%d"
-// credit invoice
-//     "/sales/customer_credit_invoice.php?ModifyCredit=%d"
-//      12=> Customer Payment,
-   ST_CUSTDELIVERY => "/sales/customer_delivery.php?ModifyDelivery=%d",
-//   16=> Location Transfer,
-//   17=> Inventory Adjustment,
-//   20=> Supplier Invoice,
-//   21=> Supplier Credit Note,
-//   22=> Supplier Payment,
-//   25=> Purchase Order Delivery,
-//   28=> Work Order Issue,
-//   29=> Work Order Production",
-//   35=> Cost Update,
-);
-
 function edit_link($row)
 {
-       global $editors;
-
-       return isset($editors[$row["type"]]) && !is_closed_trans($row["type"], $row["type_no"]) ? 
-               pager_link(_("Edit"), 
-                       sprintf($editors[$row["type"]], $row["type_no"], $row["type"]),
-                       ICON_EDIT) : '';
+       return edit_trans_link($row["type"], $row["type_no"]);
 }
 
 $sql = get_sql_for_journal_inquiry(get_post('filterType', -1), get_post('FromDate'),
@@ -118,7 +89,7 @@ $sql = get_sql_for_journal_inquiry(get_post('filterType', -1), get_post('FromDat
 
 $cols = array(
        _("#") => array('fun'=>'journal_pos', 'align'=>'center'), 
-       _("Date") =>array('name'=>'tran_date','type'=>'date','ord'=>'desc'),
+       _("Date") =>array('name'=>'tran_date','type'=>'date', 'ord' => check_value('AlsoClosed') ? 'asc' : 'desc'),
        _("Type") => array('fun'=>'systype_name'), 
        _("Trans #") => array('fun'=>'view_link'), 
        _("Reference"), 
diff --git a/gl/manage/close_period.php b/gl/manage/close_period.php
new file mode 100644 (file)
index 0000000..76fc317
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+/**********************************************************************
+    Copyright (C) FrontAccounting, LLC.
+       Released under the terms of the GNU General Public License, GPL, 
+       as published by the Free Software Foundation, either version 3 
+       of the License, or (at your option) any later version.
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+    See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+
+$page_security = 'SA_GLCLOSE';
+$path_to_root = "../..";
+include_once($path_to_root . "/includes/session.inc");
+
+include_once($path_to_root . "/includes/date_functions.inc");
+include_once($path_to_root . "/includes/ui.inc");
+include_once($path_to_root . "/includes/banking.inc");
+
+$js = "";
+if ($use_date_picker)
+       $js .= get_js_date_picker();
+page(_($help_context = "Closing GL Transactions"), false, false, "", $js);
+
+//---------------------------------------------------------------------------------------------
+function check_data()
+{
+       global $Refs, $allow_gl_reopen;
+       
+       if (!is_date($_POST['date']) || date1_greater_date2($_POST['date'], Today()))
+       {
+               display_error( _("The entered date is invalid."));
+               set_focus('date');
+               return false;
+       }
+       if (date1_greater_date2(sql2date(get_company_pref('gl_closing_date')), $_POST['date']))
+       {
+               if (!$allow_gl_reopen) {
+                       display_error(_("The entered date is earlier than date already selected as closing date."));
+                       set_focus('date');
+                       return false;
+               } elseif (!user_check_access('SA_GLREOPEN')) {
+                       display_error(_("You are not allowed to reopen already closed transactions."));
+                       set_focus('date');
+                       return false;
+               }
+       }
+       return true;
+}
+
+//---------------------------------------------------------------------------------------------
+
+function handle_submit()
+{
+       if (!check_data())
+               return;
+
+       if (!close_transactions($_POST['date']))
+       {
+               display_notification(
+                       sprintf( _("All transactions resulting in GL accounts changes up to %s has been closed for further edition."),
+                       sql2date(get_company_pref('gl_closing_date'))) );
+       }
+
+}
+
+
+//---------------------------------------------------------------------------------------------
+
+function clear_data()
+{
+       unset($_POST['date_']);
+}
+
+//---------------------------------------------------------------------------------------------
+
+if (get_post('submit'))
+       handle_submit();
+else
+       display_note(_("Using this feature you can prevent entering new transactions <br>
+       and disable edition of already entered transactions up to specified date.<br>
+       Only transactions which can generate GL postings are subject to the constraint."));
+
+//---------------------------------------------------------------------------------------------
+
+br(1);
+start_form();
+start_table(TABLESTYLE2);
+if (!isset($_POST['date'])) {
+       $cdate = sql2date(get_company_pref('gl_closing_date'));
+       $_POST['date'] = $cdate ;// ? end_month(add_months($cdate, 1)) : Today();
+}
+date_row(_("End date of closing period:"), 'date');
+end_table(1);
+
+submit_center('submit', _("Close Transactions"), true, false);
+end_form();
+
+end_page();
+
+?>
index 7ea510a621a827188c51a1e568ce9e5c792d19bb..afc364f313e658d0d93ba4d8ad752672cb17dade 100644 (file)
@@ -227,6 +227,8 @@ $security_areas =array(
        'SA_FISCALYEARS' => array(SS_GL_C|9, _("Fiscal years maintenance")),
        'SA_GLSETUP' => array(SS_GL_C|10, _("Company GL setup")),
        'SA_GLACCOUNTTAGS' => array(SS_GL_C|11, _("GL Account tags")),
+       'SA_GLCLOSE' => array(SS_GL_C|14, _("Closing GL transactions")),
+       'SA_GLREOPEN' => array(SS_GL_C|15, _("Reopening GL transactions")), // see below
        'SA_MULTIFISCALYEARS' => array(SS_GL_C|13, _("Allow entry on non closed Fiscal years")),
 
        'SA_BANKTRANSVIEW' => array(SS_GL|1, _("Bank transactions view")),
@@ -247,6 +249,9 @@ $security_areas =array(
        'SA_BANKREP' => array(SS_GL_A|3, _("Bank reports and inquiries")),
        'SA_GLREP' => array(SS_GL_A|4, _("GL reports and inquiries")),
 );
+
+if (!@$allow_gl_reopen)
+       unset($security_areas['SA_GLREOPEN']);
 /*
        This function should be called whenever we want to extend core access level system
        with new security areas and/or sections i.e.: 
index f9efe9a01861a2d3016dbdbf21e7c4d1fcec4904..49abe1ca78bce27659eff9a381c179d368e259a9 100644 (file)
 
 function add_audit_trail($trans_type, $trans_no, $trans_date, $descr='')
 {
+       $date = date2sql($trans_date);
        $sql = "INSERT INTO ".TB_PREF."audit_trail"
-               . " (type, trans_no, user, fiscal_year, gl_date, description, gl_seq)
+               . " (type, trans_no, user, gl_date, description)
                        VALUES(".db_escape($trans_type).", ".db_escape($trans_no).","
-                       . $_SESSION["wa_current_user"]->user. ","
-                       . get_company_pref('f_year') .","
-                       . "'". date2sql($trans_date) ."',"
-                       . db_escape($descr). ", 0)";
+                       . $_SESSION["wa_current_user"]->user . ","
+                       . "'$date',". db_escape($descr). ")";
 
        db_query($sql, "Cannot add audit info");
        
-       // all audit records beside latest one should have gl_seq set to NULL
+       // all audit records beside just inserted one should have gl_seq set to NULL
        // to avoid need for subqueries (not existing in MySQL 3) all over the code
-       $sql = "UPDATE ".TB_PREF."audit_trail SET gl_seq = NULL"
+       $sql = "UPDATE ".TB_PREF."audit_trail audit LEFT JOIN ".TB_PREF."fiscal_year year ON year.begin<='$date' AND year.end>='$date'
+               SET audit.gl_seq = IF(audit.id=".db_insert_id().", 0, NULL),"
+               ."audit.fiscal_year=year.id"
                . " WHERE type=".db_escape($trans_type)." AND trans_no="
-               .db_escape($trans_no)." AND id!=".db_insert_id();
+               . db_escape($trans_no);
 
        db_query($sql, "Cannot update audit gl_seq");
 }
@@ -58,83 +59,72 @@ function get_audit_trail_last($trans_type, $trans_no)
        and reindex     journal.
 */
 function close_transactions($todate) {
+
+       begin_transaction();
+
        $errors = 0;
-       $sql = "SELECT DISTINCT a.id, a.gl_date, a.fiscal_year"
+       // select only those audit trail records which produce any GL postings
+       $sql = "SELECT a.id, gl.tran_date, a.fiscal_year, a.gl_seq,
+                gl.tran_date <= '". date2sql($todate) ."' as closed"
                ." FROM ".TB_PREF."gl_trans gl"
                ." LEFT 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";
+               . " WHERE NOT ISNULL(a.gl_seq) AND gl.amount!=0"        // skip old audit records and voided transactions
+               . " GROUP BY  a.id, gl.tran_date, a.fiscal_year, a.gl_seq ORDER BY a.fiscal_year, gl.tran_date, a.id";
 
        $result = db_query($sql, "Cannot select transactions for closing");
 
        if (db_num_rows($result)) {
                $last_year = 0;
-
                while ($row = db_fetch($result)) {
+
                        if ($row['fiscal_year'] == null) {
                                $errors = 1; continue;
                        }
+
                        if ($last_year != $row['fiscal_year']) {
                                $last_year = $row['fiscal_year'];
-                               $counter = 1; // reset counter on fiscal year change
-                       } else
-                               $counter++;
-                       $sql2 = "UPDATE ".TB_PREF."audit_trail SET"
-                               . " gl_seq=$counter"
-                               . " WHERE id=".$row['id'];
-                                                                                       
-                       db_query($sql2, "Cannot reindex journal");
+                               $counter = 0; // reset counter on fiscal year change
+                       }
+                       
+                       $seq = $row['closed'] ? ++$counter : 0;
+                       if ($row['gl_seq'] != $seq)     { // update transaction status only when gl_seq has changed
+                               $sql2 = "UPDATE ".TB_PREF."audit_trail SET"
+                                       . " gl_seq=$seq"
+                                       . " WHERE id=".$row['id'];
+                               db_query($sql2, "Cannot reindex journal");
+                       }
                }
        }
-       
        if ($errors) 
                display_warning(_("Some transactions journal GL postings were not indexed due to lack of audit trail record."));
-}
-
-/*
-       Reopen all transactions for edition up from date $fromdate
-*/
-function open_transactions($fromdate) {
-
-       $sql = "SELECT a.id, a.gl_date, a.fiscal_year"
-               ." FROM ".TB_PREF."gl_trans gl"
-               ." LEFT JOIN ". TB_PREF."audit_trail a ON 
-                       (gl.type=a.type AND gl.type_no=a.trans_no)"
-               . " WHERE gl_date>='". date2sql($fromdate) ."'"
-               . " AND !ISNULL(gl_seq)"
-               . " ORDER BY a.fiscal_year, a.gl_date, a.id";
-
-       $result = db_query($sql, "Cannot select transactions for openning");
-
-       if (db_num_rows($result)) {
-               $last_year = 0;
+       else
+               update_company_prefs(array('gl_closing_date'=> date2sql($todate)));
+       commit_transaction();
 
-               while ($row = db_fetch($result)) {
-                       if ($row['fiscal_year'] == null) {
-                               continue;
-                       }
-                       $sql2 = "UPDATE ".TB_PREF."audit_trail SET"
-                               . " gl_seq=0"
-                               . " WHERE id=".$row['id'];
-                                                                                       
-                       db_query($sql2, "Cannot clear journal order");
-               }
-       }
+       return $errors;
 }
+
 /*
        Closed transactions have gl_seq number assigned.
 */
 function is_closed_trans($type, $trans_no) {
+
+       $cdate = get_company_pref('gl_closing_date');
+       if (!$cdate)
+               return false;
+
+// FIXME: gl_date can be badly entered for some transactions due to bug in previous FA versions 
        $sql = "SELECT  gl_seq  FROM ".TB_PREF."audit_trail"
                . " WHERE type=".db_escape($type)
                ." AND trans_no=".db_escape($trans_no)
-               ." AND gl_seq>0";
+               ." AND gl_date<='$cdate'"; // date is stored in sql format
+//             ." AND (gl_date<='$cdate'" // some transaction can be not sequenced due to 0 amount, however after edition this could change
+//             ." OR gl_seq>0)";
 
        $res = db_query($sql, "Cannot check transaction");
-
        return db_num_rows($res);
+
 }
 
 ?>
index 1889962d28b56e30ee65f724de901a523e3a73c0..ee84f0fd61cb80b9925f9cab4ee7ac448662d2ae 100644 (file)
@@ -931,4 +931,25 @@ function supplier_credit_row($supplier, $credit, $parms='')
                ."</a>", $parms);
 }
 
+/*
+       Edit transaction link to be used in transaction inquires
+*/
+function edit_trans_link($trans_type, $trans_no, $url='')
+{
+       global $path_to_root, $trans_editors;
+
+       if (!$url) $url = @$trans_editors[$trans_type];
+
+       if (!$trans_no || !$url)
+               return '';
+
+       if (is_closed_trans($trans_type, $trans_no)) {
+               return set_icon(ICON_CLOSED, _('Closed'));
+       } else {
+               $link_text = user_graphic_links() ? set_icon(ICON_EDIT, _('Edit')) : _('Edit');
+               return "<a href='".$path_to_root . sprintf($url, $trans_no, $trans_type)."'>$link_text</a>";
+       }
+
+}
+
 ?>
\ No newline at end of file
index d1713d03abf5d82f0c1196f642768ccb76283c47..a6ca4c33a3689ccedb1febeaef8f4358e0a71196 100644 (file)
@@ -57,6 +57,9 @@ if (isset($_GET['ModifyOrderNumber']) && is_numeric($_GET['ModifyOrderNumber']))
 
 page($_SESSION['page_title'], false, false, "", $js);
 
+if (isset($_GET['ModifyOrderNumber']))
+       check_is_closed(ST_PURCHORDER, $_GET['ModifyOrderNumber']);
+
 //---------------------------------------------------------------------------------------------------
 
 check_db_has_suppliers(_("There are no suppliers defined in the system."));
@@ -412,7 +415,6 @@ function handle_commit_order()
                        }
                        $order_no = add_po($cart);
                        new_doc_date($cart->orig_order_date); 
-               $cart->order_no = $order_no;
 
                        if ($cart->trans_type == ST_PURCHORDER) {
                                unset($_SESSION['PO']);
diff --git a/themes/aqua/images/closed.png b/themes/aqua/images/closed.png
new file mode 100644 (file)
index 0000000..624c9ed
Binary files /dev/null and b/themes/aqua/images/closed.png differ
diff --git a/themes/cool/images/closed.png b/themes/cool/images/closed.png
new file mode 100644 (file)
index 0000000..624c9ed
Binary files /dev/null and b/themes/cool/images/closed.png differ
diff --git a/themes/default/images/closed.png b/themes/default/images/closed.png
new file mode 100644 (file)
index 0000000..624c9ed
Binary files /dev/null and b/themes/default/images/closed.png differ