MidCOM svn: r15065 - in trunk/midcom/org.openpsa.reports: . config handler/invoices style

flack midcom-commits at lists.midgard-project.org
Sun Feb 17 12:44:37 CET 2008


Author: flack
Date: Sun Feb 17 12:44:37 2008
New Revision: 15065
URL: http://trac.midgard-project.org/software/changeset/15065

Log:
added basic invoice reporting

Added:
   trunk/midcom/org.openpsa.reports/config/schemadb_default_queryform_invoices.inc
   trunk/midcom/org.openpsa.reports/handler/invoices/
   trunk/midcom/org.openpsa.reports/handler/invoices/report.php
   trunk/midcom/org.openpsa.reports/style/invoices_query_form.php
   trunk/midcom/org.openpsa.reports/style/invoices_report-end.php
   trunk/midcom/org.openpsa.reports/style/invoices_report-footer.php
   trunk/midcom/org.openpsa.reports/style/invoices_report-header.php
   trunk/midcom/org.openpsa.reports/style/invoices_report-item.php
   trunk/midcom/org.openpsa.reports/style/invoices_report-start.php
   trunk/midcom/org.openpsa.reports/style/show-org.openpsa.invoices-quick_reports.php
Modified:
   trunk/midcom/org.openpsa.reports/config/config.inc
   trunk/midcom/org.openpsa.reports/viewer.php

Modified: trunk/midcom/org.openpsa.reports/config/config.inc
==============================================================================
--- trunk/midcom/org.openpsa.reports/config/config.inc	(original)
+++ trunk/midcom/org.openpsa.reports/config/config.inc	Sun Feb 17 12:44:37 2008
@@ -1,4 +1,5 @@
 "schemadb_queryform_projects" => "file:/org/openpsa/reports/config/schemadb_default_queryform_projects.inc",
 "schemadb_queryform_sales" => "file:/org/openpsa/reports/config/schemadb_default_queryform_sales.inc",
+"schemadb_queryform_invoices" => "file:/org/openpsa/reports/config/schemadb_default_queryform_invoices.inc",
 'temporary_report_max_age'  =>  3, //Days
 

Added: trunk/midcom/org.openpsa.reports/config/schemadb_default_queryform_invoices.inc
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/config/schemadb_default_queryform_invoices.inc	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,217 @@
+'newquery' => array (
+    'name'        => 'newquery',
+    'description' => 'Query settings for Invoices module reports',
+    'save_text'   => 'Generate report',
+    'fields'      => array (
+            //Hidden field for orgOpenpsaObtype
+            'type' => array(
+                //'hidden'        => true,
+                'description'   => 'Save report for future',
+                'default'       => ORG_OPENPSA_OBTYPE_REPORT_TEMPORARY,
+                'location'      => 'orgOpenpsaObtype',
+                'datatype'      => 'integer',
+                'widget'        => 'select',
+                'widget_select_choices' => array(
+                        ORG_OPENPSA_OBTYPE_REPORT_TEMPORARY => 'no',
+                        ORG_OPENPSA_OBTYPE_REPORT => 'yes',
+                ),
+                'start_fieldgroup'  => array (
+                    'title'     => 'Metadata',
+                    'css_group' => 'area hidden',
+                ),
+            ),
+            'component' => array(
+                //'hidden'        => true,
+                'description'   => 'Component this report is related to',
+                'datatype'      => 'text',
+                'location'      => 'relatedcomponent',
+                'default'       => 'org.openpsa.invoices',
+            ),
+            'mimetype' => array(
+                //'hidden'        => true,
+                'description'   => 'Report content-type',
+                'datatype'      => 'text',
+                'location'      => 'mimetype',
+                'default'       => 'text/html',
+            ),
+            'extension' => array(
+                //'hidden'        => true,
+                'description'   => 'Report file extension',
+                'datatype'      => 'text',
+                'location'      => 'extension',
+                'default'       => '.html',
+                'end_fieldgroup'  => '',
+            ),
+            'style' => array(
+                'description'   => 'Report style',
+                'datatype'      => 'text',
+                'location'      => 'style',
+                'default'       => 'builtin:basic',
+                'widget'        => 'select',
+                'widget_select_choices' => array(
+                    'builtin:invoice'     => 'invoice report',
+                ),
+                'start_fieldgroup'  => array (
+                    'title'     => 'report style',
+                    'css_group' => 'area',
+                ),
+                'end_fieldgroup'  => '',
+            ),
+            /*
+            'grouping' => array(
+                'description'   => 'Report grouping',
+                'datatype'      => 'text',
+                'location'      => 'parameter',
+                'default'       => 'date',
+                'widget'        => 'select',
+                'widget_select_choices' => array(
+                    'date'      => 'date',
+                    'person'    => 'person',
+                ),
+                'end_fieldgroup'  => '',
+            ),
+            */
+            'start' => array (
+                'description'   => 'Start time',
+                /* 'default'       => mktime(0,0,1,date('n')-1,1,date('Y')), */
+                'default'       => mktime(0,0,1,date('n'),1,date('Y')),
+                'datatype'      => 'unixdate',
+                'location'      => 'start',
+                'date_withtime' => false,
+                'widget_date_enable_outside_ais' => true,
+                'start_fieldgroup'  => array (
+                    'title'     => 'Timeframe',
+                    'css_group' => 'area',
+                ),
+            ),
+            'end' => array (
+                'description'   => 'End time',
+                /* 'default'       => mktime(0,0,1,date('n'),0,date('Y')), */
+                'default'       => mktime(0,0,1,date('n')+1,0,date('Y')),
+                'datatype'      => 'unixdate',
+                'location'      => 'end',
+                'date_withtime' => false,
+                'widget_date_enable_outside_ais' => true,
+                'end_fieldgroup'    => '',
+            ),
+            'resource' => array (
+                'description'   => 'Workgroup/Person',
+                'location'      => 'parameter',
+                'datatype'      => 'text',
+                'widget'        => 'select',
+                'widget_select_choices' => array_merge(array('all' => 'all'), org_openpsa_helpers_workgroups('first', true)),
+                'start_fieldgroup'  => array (
+                    'title'     => 'Scope',
+                    'css_group' => 'area',
+                ),
+                'end_fieldgroup'    => '',
+            ),
+    ),
+),
+'default' => array (
+    'name'        => 'default',
+    'description' => 'Query settings for Invoice module reports',
+    'fields'      => array (
+            'type' => array(
+                'description'   => 'Save query for future',
+                'default'       => ORG_OPENPSA_OBTYPE_REPORT,
+                'location'      => 'orgOpenpsaObtype',
+                'datatype'      => 'integer',
+                'widget'        => 'select',
+                'widget_select_choices' => array(
+                        ORG_OPENPSA_OBTYPE_REPORT => 'yes',
+                        ORG_OPENPSA_OBTYPE_REPORT_TEMPORARY => 'no',
+                ),
+                'start_fieldgroup'  => array (
+                    'title'     => 'Metadata',
+                    'css_group' => 'area',
+                ),
+            ),
+            'component' => array(
+                //'hidden'        => true,
+                'description'   => 'Component this report is related to',
+                'datatype'      => 'text',
+                'location'      => 'relatedcomponent',
+                'default'       => 'org.openpsa.invoices',
+            ),
+            'mimetype' => array(
+                //'hidden'        => true,
+                'description'   => 'Report content-type',
+                'datatype'      => 'text',
+                'location'      => 'mimetype',
+                'default'       => 'text/html',
+            ),
+            'extension' => array(
+                //'hidden'        => true,
+                'description'   => 'Report file extension',
+                'datatype'      => 'text',
+                'location'      => 'extension',
+                'default'       => '.html',
+                'end_fieldgroup'  => '',
+            ),
+            'style' => array(
+                'description'   => 'Report style',
+                'datatype'      => 'text',
+                'location'      => 'style',
+                'default'       => 'builtin:basic',
+                'widget'        => 'select',
+                'widget_select_choices' => array(
+                    'builtin:invoice'     => 'invoice report',
+                ),
+                'start_fieldgroup'  => array (
+                    'title'     => 'report style',
+                    'css_group' => 'area',
+                ),
+                'end_fieldgroup'  => '',
+            ),
+            /*
+            'grouping' => array(
+                'description'   => 'Report grouping',
+                'datatype'      => 'text',
+                'location'      => 'parameter',
+                'default'       => 'date',
+                'widget'        => 'select',
+                'widget_select_choices' => array(
+                    'date'      => 'date',
+                    'person'    => 'person',
+                ),
+                'end_fieldgroup'  => '',
+            ),
+            */
+            'start' => array (
+                'description'   => 'Start time',
+                /* 'default'       => mktime(0,0,1,date('n')-1,1,date('Y')), */
+                'default'       => mktime(0,0,1,date('n'),1,date('Y')),
+                'datatype'      => 'unixdate',
+                'location'      => 'start',
+                'date_withtime' => false,
+                'widget_date_enable_outside_ais' => true,
+                'start_fieldgroup'  => array (
+                    'title'     => 'Timeframe',
+                    'css_group' => 'area',
+                ),
+            ),
+            'end' => array (
+                'description'   => 'End time',
+                /* 'default'       => mktime(0,0,1,date('n'),0,date('Y')), */
+                'default'       => mktime(0,0,1,date('n')+1,0,date('Y')),
+                'datatype'      => 'unixdate',
+                'location'      => 'end',
+                'date_withtime' => false,
+                'widget_date_enable_outside_ais' => true,
+                'end_fieldgroup'    => '',
+            ),
+            'resource' => array (
+                'description'   => 'Workgroup/Person',
+                'location'      => 'parameter',
+                'datatype'      => 'text',
+                'widget'        => 'select',
+                'widget_select_choices' => array_merge(array('all' => 'all'), org_openpsa_helpers_workgroups('first', true)),
+                'start_fieldgroup'  => array (
+                    'title'     => 'Scope',
+                    'css_group' => 'area',
+                ),
+                'end_fieldgroup'    => '',
+            ),
+    ),
+),
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/handler/invoices/report.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/handler/invoices/report.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,173 @@
+<?php
+/**
+ * @package org.openpsa.projects
+ * @author The Midgard Project, http://www.midgard-project.org
+ * @version $Id: view.php 3757 2006-07-27 14:32:42Z bergie $
+ * @copyright The Midgard Project, http://www.midgard-project.org
+ * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
+ */
+
+/**
+ * Invoices reporting
+ *
+ * @package org.openpsa.projects
+ */
+class org_openpsa_reports_handler_invoices_report extends org_openpsa_reports_handler_reports_base
+{
+    /**
+     * Simple default constructor.
+     */
+    function org_openpsa_reports_handler_invoices_report()
+    {
+        parent::org_openpsa_reports_handler_reports_base();
+    }
+
+    function _on_initialize()
+    {
+        // We need sales classes etc here
+        $_MIDCOM->componentloader->load('org.openpsa.invoices');
+        $this->module = 'invoices';
+        $this->_initialize_datamanager1($this->module, $this->_config->get('schemadb_queryform_'. $this->module));
+        return true;
+    }
+
+    /**
+     * @param mixed $handler_id The ID of the handler.
+     * @param Array $args The argument list.
+     * @param Array &$data The local request data.
+     * @return boolean Indicating success.
+     */
+    function _handler_generator($handler_id, $args, &$data)
+    {
+        $_MIDCOM->auth->require_valid_user();
+
+        if (!$this->_generator_load_redirect($args))
+        {
+            return false;
+        }
+        $this->_component_data['active_leaf'] = "{$this->_topic->id}:generator_invoices";
+        $this->_handler_generator_style();
+
+
+        /*** Copied from sales/handler/deliverable/report.php ***/
+        $data['invoices'] = Array();
+
+        // Calculate time range
+        /*
+        // TODO: Make more configurable
+        $time = time();
+        require_once 'Calendar/Month.php';
+        $this_month =& new Calendar_Month(date('Y', $time), date('m', $time));
+        $next_month = $this_month->nextMonth('object');
+
+        $data['start'] = $this_month->getTimestamp();
+        $data['end'] = $next_month->getTimestamp();
+        */
+        $data['start'] = $this->_request_data['query_data']['start']['timestamp'];
+        $data['end'] = $this->_request_data['query_data']['end']['timestamp'];
+
+        // List invoices
+        $invoice_qb = org_openpsa_invoices_invoice::new_query_builder();
+		$invoice_qb->begin_group('AND');
+			$invoice_qb->add_constraint('due', '>=', $data['start']);
+			$invoice_qb->add_constraint('due', '<', $data['end']);
+		$invoice_qb->end_group();
+        if ($this->_request_data['query_data']['resource'] != 'all')
+        {
+            $this->_request_data['query_data']['resource_expanded'] = $this->_expand_resource($this->_request_data['query_data']['resource']);
+            $invoice_qb->begin_group('OR');
+            foreach ($this->_request_data['query_data']['resource_expanded'] as $pid)
+            {
+                $invoice_qb->add_constraint('owner', '=', $pid);
+            }
+            $invoice_qb->end_group();
+        }
+        $invoice_qb->add_order('id', 'DESC');
+
+        $data['invoices'] = $invoice_qb->execute();
+
+        return true;
+    }
+
+    /**
+     *
+     * @param mixed $handler_id The ID of the handler.
+     * @param mixed &$data The local request data.
+     */
+    function _show_generator($handler_id, &$data)
+    {
+        debug_push_class(__CLASS__, __FUNCTION__);
+        midcom_show_style('invoices_report-start');
+
+        /*** Copied from sales/handler/deliverable/report.php ***/
+        midcom_show_style('invoices_report-header');
+
+        $invoices_node = midcom_helper_find_node_by_component('org.openpsa.invoices');
+
+        $sums_per_person = Array();
+        $sums_all = Array
+        (
+            'price'  => 0,
+        );
+        $this->_request_data['contacts_node'] = midcom_helper_find_node_by_component('org.openpsa.contacts');
+        $odd = true;
+        foreach ($data['invoices'] as $invoice)
+        {
+
+            $customer = new midcom_db_group($invoice->customer);
+
+            if (!array_key_exists($invoice->owner, $sums_per_person))
+            {
+                $sums_per_person[$invoice->owner] = Array
+                (
+                    'price'  => 0,
+                );
+            }
+
+            if ($odd)
+            {
+                $data['row_class'] = '';
+                $odd = false;
+            }
+            else
+            {
+                $data['row_class'] = ' class="even"';
+                $odd = true;
+            }
+
+            // Calculate the price and cost from invoices
+            $data['invoice_string'] = '';
+            $invoice_cycle_numbers = Array();
+            $invoice_class = $invoice->get_invoice_class();
+
+            if ($invoices_node)
+            {
+                $invoice_label = "<a target=\"_blank\" class=\"{$invoice_class}\" href=\"{$invoices_node[MIDCOM_NAV_FULLURL]}invoice/{$invoice->guid}/\">{$invoice->invoiceNumber}</a>";
+            }
+            else
+            {
+                $invoice_label = $invoice->invoiceNumber;
+            }
+
+            $data['invoice_string'] = $invoice_label;
+
+            $data['customer'] = $customer;
+
+            $sums_per_person[$invoice->owner]['price'] += $invoice->sum;
+            $sums_all['price'] += $invoice->sum;
+
+			$data['invoice'] = $invoice;
+
+            midcom_show_style('invoices_report-item');
+        }
+
+        $data['sums_per_person'] = $sums_per_person;
+        $data['sums_all'] = $sums_all;
+        midcom_show_style('invoices_report-footer');
+        midcom_show_style('invoices_report-end');
+
+        debug_pop();
+    }
+
+}
+?>
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/style/invoices_query_form.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/style/invoices_query_form.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,3 @@
+<?php
+midcom_show_style('generic_query_form');
+?>
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/style/invoices_report-end.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/style/invoices_report-end.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,10 @@
+<?php
+//$data =& $_MIDCOM->get_custom_context_data('request_data');
+$prefix = $_MIDCOM->get_context_data(MIDCOM_CONTEXT_ANCHORPREFIX);
+?>
+        <form method="post" action="&(prefix);csv/&(data['filename']);.csv" onSubmit="return table2csv('org_openpsa_reports_deliverable_reporttable');">
+            <input type="hidden" id="csvdata" name="org_openpsa_reports_csv" value="" />
+            <input class="button" type="submit" value="<?php echo $data['l10n']->get('download as CSV'); ?>" />
+        </form>
+    </body>
+</html>
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/style/invoices_report-footer.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/style/invoices_report-footer.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,29 @@
+<?php
+//$data =& $_MIDCOM->get_custom_context_data('request_data');
+$sums_all = $data['sums_all'];
+?>
+                </tbody>
+                <tfoot>
+                    <?php
+                    $colspan = 4;
+                    foreach ($data['sums_per_person'] as $person_id => $sums)
+                    {
+                        $owner = new midcom_db_person($person_id);
+                        $owner_card = new org_openpsa_contactwidget($owner);
+                        ?>
+                        <tr>
+                            <td colspan="&(colspan);"><?php echo $owner_card->show_inline(); ?></td>
+                            <td class="sum"><?php echo sprintf("%01.2f", $sums['price']); ?></td>
+                            <td></td>
+                        </tr>
+                        <?php
+                    }
+                    ?>
+                    <tr>
+                        <td colspan="&(colspan);"><?php echo $data['l10n']->get('total'); ?></td>
+                        <td class="sum"><?php echo sprintf("%01.2f", $sums_all['price']); ?></td>
+                        <td></td>
+                    </tr>
+                </tfoot>
+            </table>
+        </div>
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/style/invoices_report-header.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/style/invoices_report-header.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,25 @@
+<?php
+//$data =& $_MIDCOM->get_custom_context_data('request_data');
+$nap = new midcom_helper_nav();
+$node = $nap->get_node($nap->get_current_node());
+$report =& $data['report'];
+
+?>
+        <div class="org_openpsa_reports_report org_openpsa_invoices">
+            <div class="header">
+                <?php midcom_show_style('projects_report-basic-header-logo'); ?>
+                <h1>&(report['title']);</h1>
+            </div>
+
+            <table class="report sales_report invoices" id="org_openpsa_reports_deliverable_reporttable">
+                <thead>
+                    <tr>
+                        <th><?php echo $_MIDCOM->i18n->get_string('invoice number', 'org.openpsa.invoices'); ?></th>
+                        <th><?php echo $_MIDCOM->i18n->get_string('due', 'org.openpsa.invoices'); ?></th>
+                        <th><?php echo $_MIDCOM->i18n->get_string('customer', 'org.openpsa.invoices'); ?> </th>
+                        <th><?php echo $_MIDCOM->i18n->get_string('customer contact', 'org.openpsa.invoices'); ?></th>
+                        <th><?php echo $_MIDCOM->i18n->get_string('sum', 'org.openpsa.invoices'); ?></th>
+                        <th><?php echo $_MIDCOM->i18n->get_string('vat', 'org.openpsa.invoices'); ?></th>
+                    </tr>
+                </thead>
+                <tbody>
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/style/invoices_report-item.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/style/invoices_report-item.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,25 @@
+<?php
+//$data =& $_MIDCOM->get_custom_context_data('request_data');
+$customer_card = $data['l10n']->get('no customer');
+$customerContact = new midcom_db_person($data['invoice']->customerContact);
+$customerContact_card = new org_openpsa_contactwidget($customerContact);
+if ($data['invoice']->customer)
+{
+    if ($data['contacts_node'])
+    {
+        $customer_card = "<a href=\"{$data['contacts_node'][MIDCOM_NAV_FULLURL]}group/{$data['customer']->guid}/\">{$data['customer']->official}</a>";
+    }
+    else
+    {
+        $customer_card =  $data['customer']->official;
+    }
+}
+?>
+    <tr&(data['row_class']:h);>
+        <td class="id">&(data['invoice_string']:h);</td>
+    	<td><?php echo strftime('%x', $data['invoice']->due); ?></td>
+        <td>&(customer_card:h);</td>
+        <td class="contact"><?php echo $customerContact_card->show_inline(); ?></td>
+        <td class="sum"><?php echo sprintf("%01.2f", $data['invoice']->sum); ?></td>
+        <td><?php echo $data['invoice']->vat . " %"; ?></td>
+    </tr>
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/style/invoices_report-start.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/style/invoices_report-start.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,24 @@
+<?php
+//$data =& $_MIDCOM->get_custom_context_data('request_data');
+//If we need to do any specific mangling to the report data etc, we do it here.
+$query =& $data['query_data'];
+$report =& $data['report'];
+if (!is_array($report))
+{
+    $report = array();
+}
+if (   !array_key_exists('title', $report)
+    || empty($report['title']))
+{
+    $report['title'] = sprintf($data['l10n']->get('invoice report %s - %s'), strftime('%x', $data['start']), strftime('%x', $data['end']));
+}
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="" lang="">
+    <head>
+        <title>OpenPsa - &(report['title']);</title>
+        <link rel="stylesheet" type="text/css" href="<?php echo MIDCOM_STATIC_URL; ?>/org.openpsa.reports/common.css" />
+        <link rel="stylesheet" type="text/css" href="<?php echo MIDCOM_STATIC_URL; ?>/org.openpsa.invoices/invoices.css" />
+        <script type="text/javascript" src="<?php echo MIDCOM_STATIC_URL; ?>/org.openpsa.reports/table2csv.js"></script>
+    </head>
+    <body>
\ No newline at end of file

Added: trunk/midcom/org.openpsa.reports/style/show-org.openpsa.invoices-quick_reports.php
==============================================================================
--- (empty file)
+++ trunk/midcom/org.openpsa.reports/style/show-org.openpsa.invoices-quick_reports.php	Sun Feb 17 12:44:37 2008
@@ -0,0 +1,10 @@
+<?php
+//$data =& $_MIDCOM->get_custom_context_data('request_data');
+?>
+<ul>
+    <li>
+        <a href="&(data['report_prefix']);">
+            <?php echo $data['l10n']->get('define custom report'); ?>
+        </a>
+    </li>
+</ul>
\ No newline at end of file

Modified: trunk/midcom/org.openpsa.reports/viewer.php
==============================================================================
--- trunk/midcom/org.openpsa.reports/viewer.php	(original)
+++ trunk/midcom/org.openpsa.reports/viewer.php	Sun Feb 17 12:44:37 2008
@@ -195,6 +195,7 @@
                 // TODO: better localization strings
                 'org.openpsa.projects' => $_MIDCOM->i18n->get_string('org.openpsa.projects', 'org.openpsa.projects'),
                 'org.openpsa.sales' => $_MIDCOM->i18n->get_string('org.openpsa.sales', 'org.openpsa.sales'),
+                'org.openpsa.invoices' => $_MIDCOM->i18n->get_string('org.openpsa.invoices', 'org.openpsa.invoices'),
                 //'org.openpsa.directmarketing' => $_MIDCOM->i18n->get_string('org.openpsa.directmarketing', 'org.openpsa.reports'),
             );
         }


More information about the midcom-commits mailing list