1<?php 2/* Copyright (C) 2012-2013 Christophe Battarel <christophe.battarel@altairis.fr> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18/** 19 * \file htdocs/margin/tabs/thirdpartyMargins.php 20 * \ingroup product margins 21 * \brief Page for invoice margins of a thirdparty 22 */ 23 24require '../../main.inc.php'; 25require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; 26require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; 27require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; 28 29$langs->loadLangs(array("companies", "bills", "products", "margins")); 30 31// Security check 32$socid = GETPOST('socid', 'int'); 33if (!empty($user->socid)) $socid = $user->socid; 34$result = restrictedArea($user, 'societe', '', ''); 35 36 37$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; 38$sortfield = GETPOST("sortfield", 'alpha'); 39$sortorder = GETPOST("sortorder", 'alpha'); 40$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); 41if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 42$offset = $limit * $page; 43$pageprev = $page - 1; 44$pagenext = $page + 1; 45if (!$sortorder) $sortorder = "DESC"; 46if (!$sortfield) $sortfield = "f.datef"; 47 48$object = new Societe($db); 49if ($socid > 0) $object->fetch($socid); 50 51// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context 52$hookmanager->initHooks(array('thirdpartymargins', 'globalcard')); 53 54 55/* 56 * Actions 57 */ 58 59$parameters = array('id'=>$socid); 60$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks 61if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); 62 63 64 65/* 66 * View 67 */ 68 69$invoicestatic = new Facture($db); 70$form = new Form($db); 71 72$title = $langs->trans("ThirdParty").' - '.$langs->trans("Margins"); 73if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) $title = $object->name.' - '.$langs->trans("Files"); 74$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; 75llxHeader('', $title, $help_url); 76 77if ($socid > 0) 78{ 79 $object = new Societe($db); 80 $object->fetch($socid); 81 82 /* 83 * Affichage onglets 84 */ 85 86 $head = societe_prepare_head($object); 87 88 print dol_get_fiche_head($head, 'margin', $langs->trans("ThirdParty"), -1, 'company'); 89 90 $linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>'; 91 92 dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom'); 93 94 print '<div class="fichecenter">'; 95 96 print '<div class="underbanner clearboth"></div>'; 97 print '<table class="border tableforfield" width="100%">'; 98 99 if ($object->client) 100 { 101 print '<tr><td class="titlefield">'; 102 print $langs->trans('CustomerCode').'</td><td colspan="3">'; 103 print $object->code_client; 104 $tmpcheck = $object->check_codeclient(); 105 if ($tmpcheck != 0 && $tmpcheck != -5) { 106 print ' <font class="error">('.$langs->trans("WrongCustomerCode").')</font>'; 107 } 108 print '</td></tr>'; 109 } 110 111 if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) && $object->fournisseur && !empty($user->rights->fournisseur->lire)) 112 { 113 print '<tr><td class="titlefield">'; 114 print $langs->trans('SupplierCode').'</td><td colspan="3">'; 115 print $object->code_fournisseur; 116 $tmpcheck = $object->check_codefournisseur(); 117 if ($tmpcheck != 0 && $tmpcheck != -5) { 118 print ' <font class="error">('.$langs->trans("WrongSupplierCode").')</font>'; 119 } 120 print '</td></tr>'; 121 } 122 123 // Total Margin 124 print '<tr><td class="titlefield">'.$langs->trans("TotalMargin").'</td><td colspan="3">'; 125 print '<span id="totalMargin"></span>'; // set by jquery (see below) 126 print '</td></tr>'; 127 128 // Margin Rate 129 if (!empty($conf->global->DISPLAY_MARGIN_RATES)) { 130 print '<tr><td>'.$langs->trans("MarginRate").'</td><td colspan="3">'; 131 print '<span id="marginRate"></span>'; // set by jquery (see below) 132 print '</td></tr>'; 133 } 134 135 // Mark Rate 136 if (!empty($conf->global->DISPLAY_MARK_RATES)) { 137 print '<tr><td>'.$langs->trans("MarkRate").'</td><td colspan="3">'; 138 print '<span id="markRate"></span>'; // set by jquery (see below) 139 print '</td></tr>'; 140 } 141 142 print "</table>"; 143 144 print '</div>'; 145 print '<div style="clear:both"></div>'; 146 147 print dol_get_fiche_end(); 148 149 print '<br>'; 150 151 $sql = "SELECT distinct s.nom, s.rowid as socid, s.code_client,"; 152 $sql .= " f.rowid as facid, f.ref, f.total as total_ht,"; 153 $sql .= " f.datef, f.paye, f.fk_statut as statut, f.type,"; 154 $sql .= " sum(d.total_ht) as selling_price,"; // may be negative or positive 155 $sql .= " sum(d.qty * d.buy_price_ht * (d.situation_percent / 100)) as buying_price,"; // always positive 156 $sql .= " sum(abs(d.total_ht) - (d.buy_price_ht * d.qty * (d.situation_percent / 100))) as marge"; // always positive 157 $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; 158 $sql .= ", ".MAIN_DB_PREFIX."facture as f"; 159 $sql .= ", ".MAIN_DB_PREFIX."facturedet as d"; 160 $sql .= " WHERE f.fk_soc = s.rowid"; 161 $sql .= " AND f.fk_statut > 0"; 162 $sql .= " AND f.entity IN (".getEntity('invoice').")"; 163 $sql .= " AND d.fk_facture = f.rowid"; 164 $sql .= " AND f.fk_soc = $socid"; 165 $sql .= " AND d.buy_price_ht IS NOT NULL"; 166 // We should not use this here. Option ForceBuyingPriceIfNull should have effect only when inserting data. Once data is recorded, it must be used as it is for report. 167 // We keep it with value ForceBuyingPriceIfNull = 2 for retroactive effect but results are unpredicable. 168 if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 2) { 169 $sql .= " AND d.buy_price_ht <> 0"; 170 } 171 $sql .= " GROUP BY s.nom, s.rowid, s.code_client, f.rowid, f.ref, f.total, f.datef, f.paye, f.fk_statut, f.type"; 172 $sql .= $db->order($sortfield, $sortorder); 173 // TODO: calculate total to display then restore pagination 174 //$sql.= $db->plimit($conf->liste_limit +1, $offset); 175 176 dol_syslog('margin:tabs:thirdpartyMargins.php', LOG_DEBUG); 177 $result = $db->query($sql); 178 if ($result) 179 { 180 $num = $db->num_rows($result); 181 182 print_barre_liste($langs->trans("MarginDetails"), $page, $_SERVER["PHP_SELF"], "&socid=".$object->id, $sortfield, $sortorder, '', $num, $num, ''); 183 184 $i = 0; 185 print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table 186 print "<table class=\"noborder\" width=\"100%\">"; 187 188 print '<tr class="liste_titre">'; 189 print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder); 190 print_liste_field_titre("DateInvoice", $_SERVER["PHP_SELF"], "f.datef", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder, 'center '); 191 print_liste_field_titre("SoldAmount", $_SERVER["PHP_SELF"], "selling_price", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder, 'right '); 192 print_liste_field_titre("PurchasedAmount", $_SERVER["PHP_SELF"], "buying_price", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder, 'right '); 193 print_liste_field_titre("Margin", $_SERVER["PHP_SELF"], "marge", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder, 'right '); 194 if (!empty($conf->global->DISPLAY_MARGIN_RATES)) 195 print_liste_field_titre("MarginRate", $_SERVER["PHP_SELF"], "", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder, 'right '); 196 if (!empty($conf->global->DISPLAY_MARK_RATES)) 197 print_liste_field_titre("MarkRate", $_SERVER["PHP_SELF"], "", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder, 'right '); 198 print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "f.paye,f.fk_statut", "", "&socid=".$_REQUEST["socid"], '', $sortfield, $sortorder, 'right '); 199 print "</tr>\n"; 200 201 $cumul_achat = 0; 202 $cumul_vente = 0; 203 204 if ($num > 0) 205 { 206 while ($i < $num /*&& $i < $conf->liste_limit*/) 207 { 208 $objp = $db->fetch_object($result); 209 210 $marginRate = ($objp->buying_price != 0) ? (100 * $objp->marge / $objp->buying_price) : ''; 211 $markRate = ($objp->selling_price != 0) ? (100 * $objp->marge / $objp->selling_price) : ''; 212 213 $sign = ''; 214 if ($objp->type == Facture::TYPE_CREDIT_NOTE) { 215 $sign = '-'; 216 } 217 218 print '<tr class="oddeven">'; 219 print '<td>'; 220 $invoicestatic->id = $objp->facid; 221 $invoicestatic->ref = $objp->ref; 222 print $invoicestatic->getNomUrl(1); 223 print "</td>\n"; 224 print "<td class=\"center\">"; 225 print dol_print_date($db->jdate($objp->datef), 'day')."</td>"; 226 print "<td class=\"right\">".price(price2num($objp->selling_price, 'MT'))."</td>\n"; 227 print "<td class=\"right\">".price(price2num(($objp->type == 2 ? -1 : 1) * $objp->buying_price, 'MT'))."</td>\n"; 228 print "<td class=\"right\">".$sign.price(price2num($objp->marge, 'MT'))."</td>\n"; 229 if (!empty($conf->global->DISPLAY_MARGIN_RATES)) 230 print "<td class=\"right\">".(($marginRate === '') ? 'n/a' : $sign.price(price2num($marginRate, 'MT'))."%")."</td>\n"; 231 if (!empty($conf->global->DISPLAY_MARK_RATES)) 232 print "<td class=\"right\">".(($markRate === '') ? 'n/a' : price(price2num($markRate, 'MT'))."%")."</td>\n"; 233 print '<td class="right">'.$invoicestatic->LibStatut($objp->paye, $objp->statut, 5).'</td>'; 234 print "</tr>\n"; 235 $i++; 236 $cumul_vente += $objp->selling_price; 237 $cumul_achat += ($objp->type == 2 ? -1 : 1) * $objp->buying_price; 238 } 239 } 240 241 // affichage totaux marges 242 243 $totalMargin = $cumul_vente - $cumul_achat; 244 if ($totalMargin < 0) 245 { 246 $marginRate = ($cumul_achat != 0) ?-1 * (100 * $totalMargin / $cumul_achat) : ''; 247 $markRate = ($cumul_vente != 0) ?-1 * (100 * $totalMargin / $cumul_vente) : ''; 248 } else { 249 $marginRate = ($cumul_achat != 0) ? (100 * $totalMargin / $cumul_achat) : ''; 250 $markRate = ($cumul_vente != 0) ? (100 * $totalMargin / $cumul_vente) : ''; 251 } 252 253 // Total 254 print '<tr class="liste_total">'; 255 print '<td colspan=2>'.$langs->trans('TotalMargin')."</td>"; 256 print "<td class=\"right\">".price(price2num($cumul_vente, 'MT'))."</td>\n"; 257 print "<td class=\"right\">".price(price2num($cumul_achat, 'MT'))."</td>\n"; 258 print "<td class=\"right\">".price(price2num($totalMargin, 'MT'))."</td>\n"; 259 if (!empty($conf->global->DISPLAY_MARGIN_RATES)) 260 print "<td class=\"right\">".(($marginRate === '') ? 'n/a' : price(price2num($marginRate, 'MT'))."%")."</td>\n"; 261 if (!empty($conf->global->DISPLAY_MARK_RATES)) 262 print "<td class=\"right\">".(($markRate === '') ? 'n/a' : price(price2num($markRate, 'MT'))."%")."</td>\n"; 263 print '<td class="right"> </td>'; 264 print "</tr>\n"; 265 } else { 266 dol_print_error($db); 267 } 268 print "</table>"; 269 print '</div>'; 270 271 print '<br>'; 272 $db->free($result); 273} else { 274 dol_print_error('', 'Parameter socid not defined'); 275} 276 277 278print ' 279 <script type="text/javascript"> 280 $(document).ready(function() { 281 $("#totalMargin").html("'. price(price2num($totalMargin, 'MT')).'"); 282 $("#marginRate").html("'.(($marginRate === '') ? 'n/a' : price(price2num($marginRate, 'MT'))."%").'"); 283 $("#markRate").html("'.(($markRate === '') ? 'n/a' : price(price2num($markRate, 'MT'))."%").'"); 284 }); 285 </script> 286'; 287 288// End of page 289llxFooter(); 290$db->close(); 291