diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php new file mode 100644 index 0000000000000000000000000000000000000000..6adbd4ebf06f0eb8964b5b418e78700d47905b15 --- /dev/null +++ b/htdocs/compta/stats/cabyprodserv.php @@ -0,0 +1,390 @@ +<?php +/* Copyright (C) 2013 Antoine Iauch <aiauch@gpcsolutions.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License 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 + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/compta/stats/cabyprodserv.php + * \brief Page reporting TO by Products & Services + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + +$langs->load("products"); +$langs->load("categories"); +$langs->load("errors"); + +// Security pack (data & check) +$socid = GETPOST('socid','int'); + +if ($user->societe_id > 0) $socid = $user->societe_id; +if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user,'compta','','','resultat'); +if (! empty($conf->accounting->enabled)) $result=restrictedArea($user,'accounting','','','comptarapport'); + +// Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES') +$modecompta = $conf->global->COMPTA_MODE; +if (GETPOST("modecompta")) $modecompta=GETPOST("modecompta"); + +$sortorder=isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"]; +$sortfield=isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"]; +if (! $sortorder) $sortorder="asc"; +if (! $sortfield) $sortfield="name"; + +// Category +$selected_cat = (int)GETPOST('search_categ', 'int'); +$subcat = false; +if (GETPOST('subcat', 'alpha') === 'yes') { + $subcat = true; +} + +// Date range +$year=GETPOST("year"); +$month=GETPOST("month"); +$date_startyear = GETPOST("date_startyear"); +$date_startmonth = GETPOST("date_startmonth"); +$date_startday = GETPOST("date_startday"); +$date_endyear = GETPOST("date_endyear"); +$date_endmonth = GETPOST("date_endmonth"); +$date_endday = GETPOST("date_endday"); +if (empty($year)) +{ + $year_current = strftime("%Y",dol_now()); + $month_current = strftime("%m",dol_now()); + $year_start = $year_current; +} else { + $year_current = $year; + $month_current = strftime("%m",dol_now()); + $year_start = $year; +} +$date_start=dol_mktime(0,0,0,$_REQUEST["date_startmonth"],$_REQUEST["date_startday"],$_REQUEST["date_startyear"]); +$date_end=dol_mktime(23,59,59,$_REQUEST["date_endmonth"],$_REQUEST["date_endday"],$_REQUEST["date_endyear"]); +// Quarter +if (empty($date_start) || empty($date_end)) // We define date_start and date_end +{ + $q=GETPOST("q")?GETPOST("q"):0; + if ($q==0) + { + // We define date_start and date_end + $month_start=GETPOST("month")?GETPOST("month"):($conf->global->SOCIETE_FISCAL_MONTH_START?($conf->global->SOCIETE_FISCAL_MONTH_START):1); + $year_end=$year_start; + $month_end=$month_start; + if (! GETPOST("month")) // If month not forced + { + if (! GETPOST('year') && $month_start > $month_current) + { + $year_start--; + $year_end--; + } + $month_end=$month_start-1; + if ($month_end < 1) $month_end=12; + else $year_end++; + } + $date_start=dol_get_first_day($year_start,$month_start,false); $date_end=dol_get_last_day($year_end,$month_end,false); + } + if ($q==1) { $date_start=dol_get_first_day($year_start,1,false); $date_end=dol_get_last_day($year_start,3,false); } + if ($q==2) { $date_start=dol_get_first_day($year_start,4,false); $date_end=dol_get_last_day($year_start,6,false); } + if ($q==3) { $date_start=dol_get_first_day($year_start,7,false); $date_end=dol_get_last_day($year_start,9,false); } + if ($q==4) { $date_start=dol_get_first_day($year_start,10,false); $date_end=dol_get_last_day($year_start,12,false); } +} else { + // TODO We define q +} + +$commonparams=array(); +$commonparams['modecompta']=$modecompta; +$commonparams['sortorder'] = $sortorder; +$commonparams['sortfield'] = $sortfield; + +$headerparams = array(); +$headerparams['date_startyear'] = $date_startyear; +$headerparams['date_startmonth'] = $date_startmonth; +$headerparams['date_startday'] = $date_startday; +$headerparams['date_endyear'] = $date_endyear; +$headerparams['date_endmonth'] = $date_endmonth; +$headerparams['date_endday'] = $date_endday; +$headerparams['q'] = $q; + +$tableparams = array(); +$tableparams['search_categ'] = $selected_cat; +$tableparams['subcat'] = ($subcat === true)?'yes':''; + +// Adding common parameters +$allparams = array_merge($commonparams, $headerparams, $tableparams); +$headerparams = array_merge($commonparams, $headerparams); +$tableparams = array_merge($commonparams, $tableparams); + +foreach($allparams as $key => $value) { + $paramslink .= '&' . $key . '=' . $value; +} +/* + * View + */ +llxHeader(); +$form=new Form($db); +$formother = new FormOther($db); + +// Show report header +$nom=$langs->trans("SalesTurnover").', '.$langs->trans("ByProductsAndServices"); + +if ($modecompta=="CREANCES-DETTES") { + $nom.='<br>('.$langs->trans("SeeReportInInputOutputMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=RECETTES-DEPENSES">','</a>').')'; + + $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); + + $description=$langs->trans("RulesCADue"); + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $description.= $langs->trans("DepositsAreNotIncluded"); + } else { + $description.= $langs->trans("DepositsAreIncluded"); + } + + $builddate=time(); +} else { + $nom.='<br>('.$langs->trans("SeeReportInDueDebtMode",'<a href="'.$_SERVER["PHP_SELF"].'?year='.$year.'&modecompta=CREANCES-DETTES">','</a>').')'; + + $period=$form->select_date($date_start,'date_start',0,0,0,'',1,0,1).' - '.$form->select_date($date_end,'date_end',0,0,0,'',1,0,1); + + $description=$langs->trans("RulesCAIn"); + $description.= $langs->trans("DepositsAreIncluded"); + + $builddate=time(); +} + +report_header($nom,$nomlink,$period,$periodlink,$description,$builddate,$exportlink,$tableparams); + + +// SQL request +$catotal=0; + +if ($modecompta == 'CREANCES-DETTES') { + $sql = "SELECT DISTINCT p.rowid as rowid, p.ref as ref, p.label as label,"; + $sql.= " sum(DISTINCT l.total_ht) as amount, sum(DISTINCT l.total_ttc) as amount_ttc"; + $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; + $sql.= " JOIN ".MAIN_DB_PREFIX."facturedet as l"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON l.fk_facture = f.rowid"; + if ($selected_cat === -2) { + $sql.=" LEFT OUTER JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = " . $selected_cat; + if ($subcat) { + $sql.=" OR c.fk_parent = " . $selected_cat; + } + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON cp.fk_categorie = c.rowid"; + } + $sql.= " WHERE l.fk_product = p.rowid"; + $sql.= " AND f.fk_statut in (1,2)"; + if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql.= " AND f.type IN (0,1,2)"; + } else { + $sql.= " AND f.type IN (0,1,2,3)"; + } + if ($date_start && $date_end) { + $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + } + if ($selected_cat === -2) { + $sql.=" AND cp.fk_product is null"; + } + if ($selected_cat && $selected_cat !== -2) { + $sql.= " AND cp.fk_product = p.rowid"; + } + $sql.= " AND f.entity = ".$conf->entity; + $sql.= " GROUP BY p.rowid "; + $sql.= "ORDER BY p.ref "; + + $result = $db->query($sql); + if ($result) { + $num = $db->num_rows($result); + $i=0; + while ($i < $num) { + $obj = $db->fetch_object($result); + $amount_ht[$obj->rowid] = $obj->amount; + $amount[$obj->rowid] = $obj->amount_ttc; + $name[$obj->rowid] = $obj->ref . ' - ' . $obj->label; + $catotal_ht+=$obj->amount; + $catotal+=$obj->amount_ttc; + $i++; + } + } else { + dol_print_error($db); + } + + // Show Array + $i=0; + print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">'; + // Extra parameters management + foreach($headerparams as $key => $value) + { + print '<input type="hidden" name="'.$key.'" value="'.$value.'">'; + } + + print '<table class="noborder" width="100%">'; + // Category filter + print '<tr class="liste_titre">'; + print '<td>'; + print $langs->trans("Category") . ': ' . $formother->select_categories(0, $selected_cat, 'search_categ', true); + print ' '; + print $langs->trans("SubCats") . '? '; + print '<input type="checkbox" name="subcat" value="yes"'; + if ($subcat) { + print ' checked'; + } + print '></td>'; + print '<td colspan="3" align="right">'; + print '<input type="image" class="liste_titre" name="button_search" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">'; + print '</td></tr>'; + // Array header + print "<tr class=\"liste_titre\">"; + print_liste_field_titre( + $langs->trans("Product"), + $_SERVER["PHP_SELF"], + "name", + "", + $paramslink, + "", + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans('AmountHT'), + $_SERVER["PHP_SELF"], + "amount_ht", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans("AmountTTC"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + print_liste_field_titre( + $langs->trans("Percentage"), + $_SERVER["PHP_SELF"], + "amount_ttc", + "", + $paramslink, + 'align="right"', + $sortfield, + $sortorder + ); + // TODO: statistics? + print "</tr>\n"; + + // Array Data + $var=true; + + if (count($amount)) { + $arrayforsort=$name; + // defining arrayforsort + if ($sortfield == 'nom' && $sortorder == 'asc') { + asort($name); + $arrayforsort=$name; + } + if ($sortfield == 'nom' && $sortorder == 'desc') { + arsort($name); + $arrayforsort=$name; + } + if ($sortfield == 'amount_ht' && $sortorder == 'asc') { + asort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ht' && $sortorder == 'desc') { + arsort($amount_ht); + $arrayforsort=$amount_ht; + } + if ($sortfield == 'amount_ttc' && $sortorder == 'asc') { + asort($amount); + $arrayforsort=$amount; + } + if ($sortfield == 'amount_ttc' && $sortorder == 'desc') { + arsort($amount); + $arrayforsort=$amount; + } + foreach($arrayforsort as $key=>$value) { + $var=!$var; + print "<tr ".$bc[$var].">"; + + // Third party + $fullname=$name[$key]; + if ($key >= 0) { + $linkname='<a href="'.DOL_URL_ROOT.'/product/fiche.php?id='.$key.'">'.img_object($langs->trans("ShowProduct"),'product').' '.$fullname.'</a>'; + } else { + $linkname=$langs->trans("PaymentsNotLinkedToProduct"); + } + + print "<td>".$linkname."</td>\n"; + + // Amount w/o VAT + print '<td align="right">'; + if ($key > 0) { + print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?productid='.$key.'">'; + } else { + print '<a href="#">'; + } + print price($amount_ht[$key]); + print '</td>'; + + // Amount with VAT + print '<td align="right">'; + if ($key > 0) { + print '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?productid='.$key.'">'; + } else { + print '<a href="#">'; + } + print price($amount[$key]); + print '</a>'; + print '</td>'; + + // Percent; + print '<td align="right">'.($catotal > 0 ? round(100 * $amount[$key] / $catotal, 2).'%' : ' ').'</td>'; + + // TODO: statistics? + + print "</tr>\n"; + $i++; + } + + // Total + print '<tr class="liste_total">'; + print '<td>'.$langs->trans("Total").'</td>'; + print '<td align="right">'.price($catotal_ht).'</td>'; + print '<td align="right">'.price($catotal).'</td>'; + print '<td> </td>'; + print '</tr>'; + + $db->free($result); + } + print "</table>"; + print '</form>'; +} else { + // $modecompta != 'CREANCES-DETTES' + // TODO: better message + print '<div class="warning">' . $langs->trans("WarningNotRelevant") . '</div>'; +} + +llxFooter(); +$db->close(); +?>