Merge remote-tracking branch 'origin/3.8' into develop

Conflicts:
	ChangeLog
	htdocs/comm/propal/class/propal.class.php
	htdocs/compta/facture/admin/facture_cust_extrafields.php
	htdocs/compta/facture/admin/facturedet_cust_extrafields.php
	htdocs/compta/facture/class/facture.class.php
	htdocs/contrat/card.php
This commit is contained in:
Laurent Destailleur 2015-10-16 10:12:36 +02:00
commit b3491ef4e5
54 changed files with 1624 additions and 1402 deletions

View File

@ -17,6 +17,75 @@ Dolibarr better:
- Trigger LINECONTRACT_INSERT has been renamed into LINECONTRACT_CREATE to match common denomination. - Trigger LINECONTRACT_INSERT has been renamed into LINECONTRACT_CREATE to match common denomination.
***** ChangeLog for 3.8.1 compared to 3.8.0 *****
FIX: #3521 postgresql migration error
FIX: #3524
FIX: #3529
FIX: #3530
FIX: #3533
FIX: #3533 Load categories language
FIX: #3534
FIX: #3572 Impossible to attach project in order
FIX: #3599 Not saving legal form
FIX: #3606
FIX: #3607 Better categories setting and unsetting
FIX: #3628
FIX: #3630 - Wrong balance report when module salaries and donation disabled
FIX: Add a test to save life when ref of object (invoice ref, order ref, ...) was empty. The was no way to go back to a clean situation, even after vaidating again the object.
FIX: Admin fiche inter page do not take good action
FIX: Always use type send in parameters in showCategories method
FIX: avoid SQL error in getValueFrom common object when all params are not send
FIX: avoid SQL error when no sortfield send to method
FIX: bad link into project box
FIX: Bad title line in project view when using jmobile
FIX: Bad translation key for project "Overview"
FIX: Can create Proposal on close thridparty #3526
FIX: Can't change state on a contact
FIX: Can't change the admin with default setup
FIX: Can't delete thirdparty if there is some discounts
FIX: Can't reopen a canceled invoice.
FIX: Creation of tables or keys must not be done with a random order.
FIX: debian install when module mysqli is not installed.
FIX: Description of tags was mandatory in edit mode but not in create mode. Should not be mandatory.
FIX: display error on extrafields on ficheinter
FIX: Email selector contact must not include inactive contact
FIX: error in SQL due to a previous fix
FIX: Error retrieving customer prices
FIX: Event from ical stream should not be movable into calendar view
FIX: facturestat bad sql when customer view is limited
FIX: Filter on status of thirdparty list and bad encoding of url
FIX: icon into export profile may be not correctly output
FIX: Init into bad var
FIX: Link of project must be cickable if user has permission to read all projects FIX: Missing information into the alt of project picto
FIX: List of project for user that are restrited as sale repreentative to some thirdparties.
FIX: Mass Mailing activity don't display all status
FIX: Missing contracts into list in page of Refering objects of a thirdparty.
FIX: Missing menu entry for list of thirdparties when using auguria menu manager
FIX: Missing validate button if permission are not valid.
FIX: New adherent from, always redirect on entity
FIX: not closing CSS.
FIX: not responsive part for project page
FIX: Only are showing one object linked
FIX: order ref must not be translated
FIX: Payment form for paypal and paybox was not centered.
FIX: Pb into pagination scroll widget FIX: Style of previous-next card when using dolidroid
FIX: Regression on bad use of fk_account showing the bad bank account on PDF.
FIX: Removed warnings
FIX: remove twice same test
FIX: select of project using ajax autocomplete option
FIX: sortder field was missing so manually added values were moved to begin.
FIX: Syntax error in Debian Apache configuration
FIX: The admin flag is mising.
FIX: The filter on thirdparty prices should be visible if there is at least one thirdparty price.
FIX: Thirdparty is missing on card
FIX: update2.php test res befre assign it
FIX: When delete actioncomm also delete actioncomm_resources
FIX: when editing time spent, date of line suggested was a rubbish value
FIX: When filter with empty status, by default get canceled status (-1)
FIX: When update a member login for a member linked to a user, the login of user was not sync (not updated).
FIX: Wizard for restore does not show import command
***** ChangeLog for 3.8 compared to 3.7.* ***** ***** ChangeLog for 3.8 compared to 3.7.* *****
For users: For users:
FIX: #2519 FIX: #2519
@ -473,6 +542,12 @@ Dolibarr better:
warehouse module and your Point Of Sale module setup if you use one. warehouse module and your Point Of Sale module setup if you use one.
- Replaced USER_UPDATE_SESSION trigger with an updateSession hook may break modules using it. - Replaced USER_UPDATE_SESSION trigger with an updateSession hook may break modules using it.
***** ChangeLog for 3.6.5 compared to 3.6.4 *****
- Fix: [ bug #1776 ] Undefined $deliverycompany variable in pdf_build_address
- Fix: [ bug #1794 ] Error when cloning Proposal gives error in a malformed page
***** ChangeLog for 3.6.4 compared to 3.6.3 *****
- Fix: [ bug #2893 ] Dolibarr error when viewing an invoice after changing invoice mask
***** ChangeLog for 3.6.3 compared to 3.6.2 ***** ***** ChangeLog for 3.6.3 compared to 3.6.2 *****
- Fix: ref_ext was not saved when recording a customer order from web service - Fix: ref_ext was not saved when recording a customer order from web service

View File

@ -8,7 +8,9 @@ This files describe steps made by Dolibarr packaging team to make a
beta version of Dolibarr, step by step. beta version of Dolibarr, step by step.
- Check all files are commited. - Check all files are commited.
- Update version/info in ChangeLog. To generate a changelog, you can do "git log `git merge-base 3.7.0 origin/develop`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" - Update version/info in ChangeLog.
To generate a changelog of a major new version x.y.0, you can do "cd ~/git/dolibarr_x.y; git log `git merge-base x-1.y-1.0 origin/develop`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log `git merge-base x.y.z-1 origin/develop`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
- Update version number with x.y.z-w in htdocs/filefunc.inc.php - Update version number with x.y.z-w in htdocs/filefunc.inc.php
- Commit all changes. - Commit all changes.
@ -28,7 +30,9 @@ This files describe steps made by Dolibarr packaging team to make a
complete release of Dolibarr, step by step. complete release of Dolibarr, step by step.
- Check all files are commited. - Check all files are commited.
- Update version/info in ChangeLog. To generate a changelog, you can do "git log `git merge-base 3.7.0 origin/develop`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa" - Update version/info in ChangeLog.
To generate a changelog of a major new version x.y.0, you can do "cd ~/git/dolibarr_x.y; git log `git merge-base x-1.y-1.0 origin/develop`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log `git merge-base x.y.z-1 origin/develop`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
- Update version number with x.y.z in htdocs/filefunc.inc.php - Update version number with x.y.z in htdocs/filefunc.inc.php
- Commit all changes. - Commit all changes.

View File

@ -231,7 +231,7 @@ class Skeleton_Class extends CommonObject
} }
if (!empty($sortfield)) { if (!empty($sortfield)) {
$sql .= ' ORDER BY ' . $sortfield . ' ' . $sortorder; $sql .= $this->db->order($sortfield,$sortorder);
} }
if (!empty($limit)) { if (!empty($limit)) {
$sql .= ' ' . $this->db->plimit($limit + 1, $offset); $sql .= ' ' . $this->db->plimit($limit + 1, $offset);

View File

@ -200,7 +200,7 @@ if (! empty($conf->paybox->enabled) || ! empty($conf->paypal->enabled))
print '<tr '.$bc[$var].' id="tremail"><td>'; print '<tr '.$bc[$var].' id="tremail"><td>';
print $langs->trans("MEMBER_PAYONLINE_SENDEMAIL"); print $langs->trans("MEMBER_PAYONLINE_SENDEMAIL");
print '</td><td align="right">'; print '</td><td align="right">';
print '<input type="text" id="MEMBER_PAYONLINE_SENDEMAIL" name="MEMBER_PAYONLINE_SENDEMAIL" size="24" value="'.(! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL)?$conf->global->MEMBER_PAYONLINE_SENDEMAIL:'').'">';; print '<input type="text" id="MEMBER_PAYONLINE_SENDEMAIL" name="MEMBER_PAYONLINE_SENDEMAIL" size="24" value="'.(! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL)?$conf->global->MEMBER_PAYONLINE_SENDEMAIL:'').'">';
print "</td></tr>\n"; print "</td></tr>\n";
} }

View File

@ -1976,12 +1976,14 @@ class Adherent extends CommonObject
// Process // Process
foreach ($to_del as $del) { foreach ($to_del as $del) {
$c->fetch($del); if ($c->fetch($del) > 0) {
$c->del_type($this, 'member'); $c->del_type($this, 'member');
}
} }
foreach ($to_add as $add) { foreach ($to_add as $add) {
$c->fetch($add); if ($c->fetch($add) > 0) {
$c->add_type($this, 'member'); $c->add_type($this, 'member');
}
} }
return; return;

View File

@ -679,7 +679,16 @@ if ($rowid > 0)
print '<br><br><table class="border" width="100%">'; print '<br><br><table class="border" width="100%">';
foreach($extrafields->attribute_label as $key=>$label) foreach($extrafields->attribute_label as $key=>$label)
{ {
$value=(isset($_POST["options_".$key])?$_POST["options_".$key]:(isset($object->array_options['options_'.$key])?$object->array_options['options_'.$key]:'')); if (isset($_POST["options_" . $key])) {
if (is_array($_POST["options_" . $key])) {
// $_POST["options"] is an array but following code expects a comma separated string
$value = implode(",", $_POST["options_" . $key]);
} else {
$value = $_POST["options_" . $key];
}
} else {
$value = $adht->array_options["options_" . $key];
}
print '<tr><td width="30%">'.$label.'</td><td>'; print '<tr><td width="30%">'.$label.'</td><td>';
print $extrafields->showInputField($key,$value); print $extrafields->showInputField($key,$value);
print "</td></tr>\n"; print "</td></tr>\n";

View File

@ -323,7 +323,7 @@ if ($action == 'add')
unset($_SESSION['assignedtouser']); unset($_SESSION['assignedtouser']);
$moreparam=''; $moreparam='';
if ($user->id != $object->ownerid) $moreparam="usertodo=-1"; // We force to remove filter so created record is visible when going back to per user view. if ($user->id != $object->userownerid) $moreparam="usertodo=-1"; // We force to remove filter so created record is visible when going back to per user view.
$db->commit(); $db->commit();
if (! empty($backtopage)) if (! empty($backtopage))
@ -1304,7 +1304,16 @@ if ($id > 0)
print '<br><br><table class="border" width="100%">'; print '<br><br><table class="border" width="100%">';
foreach($extrafields->attribute_label as $key=>$label) foreach($extrafields->attribute_label as $key=>$label)
{ {
$value=(isset($_POST["options_".$key])?$_POST["options_".$key]:(isset($object->array_options['options_'.$key])?$object->array_options['options_'.$key]:'')); if (isset($_POST["options_" . $key])) {
if (is_array($_POST["options_" . $key])) {
// $_POST["options"] is an array but following code expects a comma separated string
$value = implode(",", $_POST["options_" . $key]);
} else {
$value = $_POST["options_" . $key];
}
} else {
$value = $object->array_options["options_" . $key];
}
print '<tr><td width="30%">'.$label.'</td><td>'; print '<tr><td width="30%">'.$label.'</td><td>';
print $extrafields->showOutputField($key,$value); print $extrafields->showOutputField($key,$value);
print "</td></tr>\n"; print "</td></tr>\n";

View File

@ -1264,12 +1264,12 @@ class AskPriceSupplier extends CommonObject
$soc->fetch($this->socid); $soc->fetch($this->socid);
// Define new ref // Define new ref
if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($soc); $num = $this->getNextNumRef($soc);
} }
else else
{ {
$num = $this->ref; $num = $this->ref;
} }
$this->newref = $num; $this->newref = $num;

View File

@ -129,7 +129,7 @@ if (empty($reshook))
// Action clone object // Action clone object
if ($action == 'confirm_clone' && $confirm == 'yes') if ($action == 'confirm_clone' && $confirm == 'yes')
{ {
if (1 == 0 && ! GETPOST('clone_content') && ! GETPOST('clone_receivers')) if (! GETPOST('socid', 3))
{ {
setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors'); setEventMessage($langs->trans("NoCloneOptionsSpecified"), 'errors');
} }
@ -141,7 +141,7 @@ if (empty($reshook))
header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result); header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $result);
exit(); exit();
} else { } else {
setEventMessage($object->error, 'errors'); if (count($object->errors) > 0) setEventMessage($object->errors, 'errors');
$action = ''; $action = '';
} }
} }

View File

@ -438,7 +438,8 @@ class Propal extends CommonObject
$localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc); $localtaxes_type=getLocalTaxesFromRate($txtva,0,$this->thirdparty,$mysoc);
$tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, '', $localtaxes_type); $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $mysoc, $localtaxes_type);
$total_ht = $tabprice[0]; $total_ht = $tabprice[0];
$total_tva = $tabprice[1]; $total_tva = $tabprice[1];
$total_ttc = $tabprice[2]; $total_ttc = $tabprice[2];
@ -1039,7 +1040,7 @@ class Propal extends CommonObject
{ {
global $db, $user,$langs,$conf,$hookmanager; global $db, $user,$langs,$conf,$hookmanager;
dol_include_once('/projet/class.project.class.php'); dol_include_once('/projet/class/project.class.php');
$this->context['createfromclone']='createfromclone'; $this->context['createfromclone']='createfromclone';
@ -1052,44 +1053,42 @@ class Propal extends CommonObject
foreach($this->lines as $line) foreach($this->lines as $line)
$line->fetch_optionals($line->rowid); $line->fetch_optionals($line->rowid);
// Load source object // Load dest object
$objFrom = clone $this; $clonedObj = clone $this;
$objsoc=new Societe($this->db); $objsoc=new Societe($this->db);
// Change socid if needed // Change socid if needed
if (! empty($socid) && $socid != $this->socid) if (! empty($socid) && $socid != $clonedObj->socid)
{ {
if ($objsoc->fetch($socid) > 0) if ($objsoc->fetch($socid) > 0)
{ {
$this->socid = $objsoc->id; $clonedObj->socid = $objsoc->id;
$this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); $clonedObj->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
$this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); $clonedObj->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
$clonedObj->fk_delivery_address = '';
$project = new Project($db); $project = new Project($db);
if ($this->fk_project > 0 && $project->fetch($this->fk_project)) {
if($objFrom->fk_project > 0 && $project->fetch($objFrom->fk_project)) { if ($project->socid <= 0) $clonedObj->fk_project = $this->fk_project;
if($project->socid <= 0) $this->fk_project = $objFrom->fk_project; else $clonedObj->fk_project = '';
else $this->fk_project = '';
} else { } else {
$this->fk_project = ''; $clonedObj->fk_project = '';
} }
$this->fk_delivery_address = '';
} }
// reset ref_client // reset ref_client
$this->ref_client = ''; $clonedObj->ref_client = '';
// TODO Change product price if multi-prices // TODO Change product price if multi-prices
} }
else else
{ {
$objsoc->fetch($this->socid); $objsoc->fetch($clonedObj->socid);
} }
$this->id=0; $clonedObj->id=0;
$this->statut=self::STATUS_DRAFT; $clonedObj->statut=self::STATUS_DRAFT;
if (empty($conf->global->PROPALE_ADDON) || ! is_readable(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php")) if (empty($conf->global->PROPALE_ADDON) || ! is_readable(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php"))
{ {
@ -1098,32 +1097,32 @@ class Propal extends CommonObject
} }
// Clear fields // Clear fields
$this->user_author = $user->id; $clonedObj->user_author = $user->id;
$this->user_valid = ''; $clonedObj->user_valid = '';
$this->date = $now; $clonedObj->date = $now;
$this->datep = $now; // deprecated $clonedObj->datep = $now; // deprecated
$this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600); $clonedObj->fin_validite = $clonedObj->date + ($clonedObj->duree_validite * 24 * 3600);
if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) $this->ref_client = ''; if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) $clonedObj->ref_client = '';
// Set ref // Set ref
require_once DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.'.php'; require_once DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.'.php';
$obj = $conf->global->PROPALE_ADDON; $obj = $conf->global->PROPALE_ADDON;
$modPropale = new $obj; $modPropale = new $obj;
$this->ref = $modPropale->getNextValue($objsoc,$this); $clonedObj->ref = $modPropale->getNextValue($objsoc,$clonedObj);
// Create clone // Create clone
$result=$this->create($user); $result=$clonedObj->create($user);
if ($result < 0) $error++; if ($result < 0) $error++;
else else
{ {
// copy internal contacts // copy internal contacts
if ($this->copy_linked_contact($objFrom, 'internal') < 0) if ($clonedObj->copy_linked_contact($this, 'internal') < 0)
$error++; $error++;
// copy external contacts if same company // copy external contacts if same company
elseif ($objFrom->socid == $this->socid) elseif ($this->socid == $clonedObj->socid)
{ {
if ($this->copy_linked_contact($objFrom, 'external') < 0) if ($clonedObj->copy_linked_contact($this, 'external') < 0)
$error++; $error++;
} }
} }
@ -1133,9 +1132,9 @@ class Propal extends CommonObject
// Hook of thirdparty module // Hook of thirdparty module
if (is_object($hookmanager)) if (is_object($hookmanager))
{ {
$parameters=array('objFrom'=>$objFrom); $parameters=array('objFrom'=>$this,'clonedObj'=>$clonedObj);
$action=''; $action='';
$reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks $reshook=$hookmanager->executeHooks('createFrom',$parameters,$clonedObj,$action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) $error++; if ($reshook < 0) $error++;
} }
@ -1151,7 +1150,7 @@ class Propal extends CommonObject
if (! $error) if (! $error)
{ {
$this->db->commit(); $this->db->commit();
return $this->id; return $clonedObj->id;
} }
else else
{ {
@ -1457,12 +1456,12 @@ class Propal extends CommonObject
$soc->fetch($this->socid); $soc->fetch($this->socid);
// Define new ref // Define new ref
if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($soc); $num = $this->getNextNumRef($soc);
} }
else else
{ {
$num = $this->ref; $num = $this->ref;
} }
$this->newref = $num; $this->newref = $num;

View File

@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2014 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com> * Copyright (C) 2005 Marc Barilley / Ocebo <marc@ocebo.com>
* Copyright (C) 2005-2015 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2005-2015 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr> * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
@ -151,7 +151,7 @@ if (empty($reshook))
// Reopen a closed order // Reopen a closed order
else if ($action == 'reopen' && $user->rights->commande->creer) else if ($action == 'reopen' && $user->rights->commande->creer)
{ {
if ($object->statut == STATUS_CANCELED || $object->statut == Commande::STATUS_CLOSED) if ($object->statut == Commande::STATUS_CANCELED || $object->statut == Commande::STATUS_CLOSED)
{ {
$result = $object->set_reopen($user); $result = $object->set_reopen($user);
if ($result > 0) if ($result > 0)
@ -166,7 +166,7 @@ if (empty($reshook))
} }
} }
// Suppression de la commande // Remove order
else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer) else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->commande->supprimer)
{ {
$result = $object->delete($user); $result = $object->delete($user);

View File

@ -227,14 +227,14 @@ class Commande extends CommonOrder
// Protection // Protection
if ($this->statut == self::STATUS_VALIDATED) if ($this->statut == self::STATUS_VALIDATED)
{ {
dol_syslog(get_class($this)."::valid no draft status", LOG_WARNING); dol_syslog(get_class($this)."::valid action abandonned: no draft status", LOG_WARNING);
return 0; return 0;
} }
if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer)) if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->creer))
|| (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate)))) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate))))
{ {
$this->error='Permission denied'; $this->error='ErrorPermissionDenied';
dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
return -1; return -1;
} }
@ -251,7 +251,7 @@ class Commande extends CommonOrder
$result=$soc->set_as_client(); $result=$soc->set_as_client();
// Define new ref // Define new ref
if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($soc); $num = $this->getNextNumRef($soc);
} }
@ -1009,116 +1009,112 @@ class Commande extends CommonOrder
$error=0; $error=0;
// Signed proposal
if ($object->statut == 2) $this->date_commande = dol_now();
$this->source = 0;
$num=count($object->lines);
for ($i = 0; $i < $num; $i++)
{ {
$this->date_commande = dol_now(); $line = new OrderLine($this->db);
$this->source = 0;
$num=count($object->lines); $line->libelle = $object->lines[$i]->libelle;
for ($i = 0; $i < $num; $i++) $line->label = $object->lines[$i]->label;
{ $line->desc = $object->lines[$i]->desc;
$line = new OrderLine($this->db); $line->price = $object->lines[$i]->price;
$line->subprice = $object->lines[$i]->subprice;
$line->tva_tx = $object->lines[$i]->tva_tx;
$line->localtax1_tx = $object->lines[$i]->localtax1_tx;
$line->localtax2_tx = $object->lines[$i]->localtax2_tx;
$line->qty = $object->lines[$i]->qty;
$line->fk_remise_except = $object->lines[$i]->fk_remise_except;
$line->remise_percent = $object->lines[$i]->remise_percent;
$line->fk_product = $object->lines[$i]->fk_product;
$line->info_bits = $object->lines[$i]->info_bits;
$line->product_type = $object->lines[$i]->product_type;
$line->rang = $object->lines[$i]->rang;
$line->special_code = $object->lines[$i]->special_code;
$line->fk_parent_line = $object->lines[$i]->fk_parent_line;
$line->fk_unit = $object->lines[$i]->fk_unit;
$line->libelle = $object->lines[$i]->libelle; $line->date_start = $object->lines[$i]->date_start;
$line->label = $object->lines[$i]->label; $line->date_end = $object->lines[$i]->date_end;
$line->desc = $object->lines[$i]->desc;
$line->price = $object->lines[$i]->price;
$line->subprice = $object->lines[$i]->subprice;
$line->tva_tx = $object->lines[$i]->tva_tx;
$line->localtax1_tx = $object->lines[$i]->localtax1_tx;
$line->localtax2_tx = $object->lines[$i]->localtax2_tx;
$line->qty = $object->lines[$i]->qty;
$line->fk_remise_except = $object->lines[$i]->fk_remise_except;
$line->remise_percent = $object->lines[$i]->remise_percent;
$line->fk_product = $object->lines[$i]->fk_product;
$line->info_bits = $object->lines[$i]->info_bits;
$line->product_type = $object->lines[$i]->product_type;
$line->rang = $object->lines[$i]->rang;
$line->special_code = $object->lines[$i]->special_code;
$line->fk_parent_line = $object->lines[$i]->fk_parent_line;
$line->fk_unit = $object->lines[$i]->fk_unit;
$line->date_start = $object->lines[$i]->date_start; $line->fk_fournprice = $object->lines[$i]->fk_fournprice;
$line->date_end = $object->lines[$i]->date_end; $marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht);
$line->pa_ht = $marginInfos[0];
$line->fk_fournprice = $object->lines[$i]->fk_fournprice; $line->marge_tx = $marginInfos[1];
$marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht); $line->marque_tx = $marginInfos[2];
$line->pa_ht = $marginInfos[0];
$line->marge_tx = $marginInfos[1];
$line->marque_tx = $marginInfos[2];
// get extrafields from original line
$object->lines[$i]->fetch_optionals($object->lines[$i]->rowid);
foreach($object->lines[$i]->array_options as $options_key => $value)
$line->array_options[$options_key] = $value;
$this->lines[$i] = $line;
}
$this->socid = $object->socid;
$this->fk_project = $object->fk_project;
$this->cond_reglement_id = $object->cond_reglement_id;
$this->mode_reglement_id = $object->mode_reglement_id;
$this->fk_account = $object->fk_account;
$this->availability_id = $object->availability_id;
$this->demand_reason_id = $object->demand_reason_id;
$this->date_livraison = $object->date_livraison;
$this->shipping_method_id = $object->shipping_method_id;
$this->fk_delivery_address = $object->fk_delivery_address;
$this->contact_id = $object->contactid;
$this->ref_client = $object->ref_client;
$this->note_private = $object->note_private;
$this->note_public = $object->note_public;
$this->origin = $object->element;
$this->origin_id = $object->id;
// get extrafields from original line // get extrafields from original line
$object->fetch_optionals($object->id); $object->lines[$i]->fetch_optionals($object->lines[$i]->rowid);
foreach($object->lines[$i]->array_options as $options_key => $value)
$line->array_options[$options_key] = $value;
$e = new ExtraFields($db); $this->lines[$i] = $line;
$element_extrafields = $e->fetch_name_optionals_label($this->element); }
foreach($object->array_options as $options_key => $value) { $this->socid = $object->socid;
if(array_key_exists(str_replace('options_', '', $options_key), $element_extrafields)){ $this->fk_project = $object->fk_project;
$this->array_options[$options_key] = $value; $this->cond_reglement_id = $object->cond_reglement_id;
} $this->mode_reglement_id = $object->mode_reglement_id;
$this->fk_account = $object->fk_account;
$this->availability_id = $object->availability_id;
$this->demand_reason_id = $object->demand_reason_id;
$this->date_livraison = $object->date_livraison;
$this->shipping_method_id = $object->shipping_method_id;
$this->fk_delivery_address = $object->fk_delivery_address;
$this->contact_id = $object->contactid;
$this->ref_client = $object->ref_client;
$this->note_private = $object->note_private;
$this->note_public = $object->note_public;
$this->origin = $object->element;
$this->origin_id = $object->id;
// get extrafields from original line
$object->fetch_optionals($object->id);
$e = new ExtraFields($db);
$element_extrafields = $e->fetch_name_optionals_label($this->element);
foreach($object->array_options as $options_key => $value) {
if(array_key_exists(str_replace('options_', '', $options_key), $element_extrafields)){
$this->array_options[$options_key] = $value;
} }
// Possibility to add external linked objects with hooks }
$this->linked_objects[$this->origin] = $this->origin_id; // Possibility to add external linked objects with hooks
if (is_array($object->other_linked_objects) && ! empty($object->other_linked_objects)) $this->linked_objects[$this->origin] = $this->origin_id;
if (is_array($object->other_linked_objects) && ! empty($object->other_linked_objects))
{
$this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects);
}
$ret = $this->create($user);
if ($ret > 0)
{
// Actions hooked (by external module)
$hookmanager->initHooks(array('orderdao'));
$parameters=array('objFrom'=>$object);
$action='';
$reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) $error++;
if (! $error)
{ {
$this->linked_objects = array_merge($this->linked_objects, $object->other_linked_objects); // Ne pas passer par la commande provisoire
} if ($conf->global->COMMANDE_VALID_AFTER_CLOSE_PROPAL == 1)
$ret = $this->create($user);
if ($ret > 0)
{
// Actions hooked (by external module)
$hookmanager->initHooks(array('orderdao'));
$parameters=array('objFrom'=>$object);
$action='';
$reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) $error++;
if (! $error)
{ {
// Ne pas passer par la commande provisoire $this->fetch($ret);
if ($conf->global->COMMANDE_VALID_AFTER_CLOSE_PROPAL == 1) $this->valid($user);
{
$this->fetch($ret);
$this->valid($user);
}
return $ret;
} }
else return -1; return $ret;
} }
else return -1; else return -1;
} }
else return 0; else return -1;
} }

View File

@ -65,8 +65,8 @@ $textobject=strtolower($langs->transnoentitiesnoconv("BillsCustomers"));
llxHeader('',$langs->trans("BillsSetup")); llxHeader('',$langs->trans("BillsSetup"));
$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>'; $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("BillsSetup"),$linkback,'title_setup'); print load_fiche_titre($langs->trans("BillsSetup"),$linkback,'title_setup');
print '<br>';
$head = invoice_admin_prepare_head(); $head = invoice_admin_prepare_head();

View File

@ -66,8 +66,8 @@ $textobject=strtolower($langs->transnoentitiesnoconv("BillsCustomers"));
llxHeader('',$langs->trans("BillsSetup")); llxHeader('',$langs->trans("BillsSetup"));
$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>'; $linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("BillsSetup"),$linkback,'title_setup'); print load_fiche_titre($langs->trans("BillsSetup"),$linkback,'title_setup');
print '<br>';
$head = invoice_admin_prepare_head(); $head = invoice_admin_prepare_head();

View File

@ -122,6 +122,64 @@ class Facture extends CommonInvoice
*/ */
public $situation_final; public $situation_final;
/**
* Standard invoice
*/
const TYPE_STANDARD = 0;
/**
* Replacement invoice
*/
const TYPE_REPLACEMENT = 1;
/**
* Credit note invoice
*/
const TYPE_CREDIT_NOTE = 2;
/**
* Deposit invoice
*/
const TYPE_DEPOSIT = 3;
/**
* Proforma invoice (should not be used. a proforma is an order)
*/
const TYPE_PROFORMA = 4;
/**
* Situation invoice
*/
const TYPE_SITUATION = 5;
/**
* Draft
*/
const STATUS_DRAFT = 0;
/**
* Validated (need to be paid)
*/
const STATUS_VALIDATED = 1;
/**
* Classified paid.
* If paid partially, $this->close_code can be:
* - CLOSECODE_DISCOUNTVAT
* - CLOSECODE_BADDEBT
* If paid completelly, this->close_code will be null
*/
const STATUS_CLOSED = 2;
/**
* Classified abandoned and no payment done.
* $this->close_code can be:
* - CLOSECODE_BADDEBT
* - CLOSECODE_ABANDONED
* - CLOSECODE_REPLACED
*/
const STATUS_ABANDONED = 3;
const CLOSECODE_DISCOUNTVAT = 'discount_vat'; const CLOSECODE_DISCOUNTVAT = 'discount_vat';
const CLOSECODE_BADDEBT = 'badcustomer'; const CLOSECODE_BADDEBT = 'badcustomer';
const CLOSECODE_ABANDONED = 'abandon'; const CLOSECODE_ABANDONED = 'abandon';
@ -1732,7 +1790,7 @@ class Facture extends CommonInvoice
{ {
$num = $force_number; $num = $force_number;
} }
else if (preg_match('/^[\(]?PROV/i', $this->ref)) else if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life
{ {
if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date if (! empty($conf->global->FAC_FORCE_DATE_VALIDATION)) // If option enabled, we force invoice date
{ {

View File

@ -1144,12 +1144,14 @@ class Contact extends CommonObject
// Process // Process
foreach ($to_del as $del) { foreach ($to_del as $del) {
$c->fetch($del); if ($c->fetch($del) > 0) {
$c->del_type($this, 'contact'); $c->del_type($this, 'contact');
}
} }
foreach ($to_add as $add) { foreach ($to_add as $add) {
$c->fetch($add); if ($c->fetch($add) > 0) {
$c->add_type($this, 'contact'); $c->add_type($this, 'contact');
}
} }
return; return;

View File

@ -369,7 +369,7 @@ class Contrat extends CommonObject
$result=$this->thirdparty->set_as_client(); $result=$this->thirdparty->set_as_client();
// Define new ref // Define new ref
if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($this->thirdparty); $num = $this->getNextNumRef($this->thirdparty);
} }
@ -1251,7 +1251,7 @@ class Contrat extends CommonObject
$localtaxes_type=getLocalTaxesFromRate($txtva, 0, $this->societe, $mysoc); $localtaxes_type=getLocalTaxesFromRate($txtva, 0, $this->societe, $mysoc);
$tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, 1,'', $localtaxes_type); $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, 1,$mysoc, $localtaxes_type);
$total_ht = $tabprice[0]; $total_ht = $tabprice[0];
$total_tva = $tabprice[1]; $total_tva = $tabprice[1];
$total_ttc = $tabprice[2]; $total_ttc = $tabprice[2];
@ -1424,7 +1424,7 @@ class Contrat extends CommonObject
$localtaxes_type=getLocalTaxesFromRate($tvatx, 0, $this->societe, $mysoc); $localtaxes_type=getLocalTaxesFromRate($tvatx, 0, $this->societe, $mysoc);
$tabprice=calcul_price_total($qty, $pu, $remise_percent, $tvatx, $localtax1tx, $localtax2tx, 0, $price_base_type, $info_bits, 1, '', $localtaxes_type); $tabprice=calcul_price_total($qty, $pu, $remise_percent, $tvatx, $localtax1tx, $localtax2tx, 0, $price_base_type, $info_bits, 1, $mysoc, $localtaxes_type);
$total_ht = $tabprice[0]; $total_ht = $tabprice[0];
$total_tva = $tabprice[1]; $total_tva = $tabprice[1];
$total_ttc = $tabprice[2]; $total_ttc = $tabprice[2];
@ -2416,7 +2416,7 @@ class ContratLigne extends CommonObjectLine
*/ */
function update($user, $notrigger=0) function update($user, $notrigger=0)
{ {
global $conf, $langs; global $conf, $langs, $mysoc;
$error=0; $error=0;
@ -2458,7 +2458,9 @@ class ContratLigne extends CommonObjectLine
// qty, pu, remise_percent et txtva // qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
$tabprice=calcul_price_total($this->qty, $this->price_ht, $this->remise_percent, $this->tva_tx, $this->localtax1_tx, $this->localtax2_tx, 0, 'HT', 0, 1); $localtaxes_type = getLocalTaxesFromRate($this->txtva, 0, $this->societe, $mysoc);
$tabprice=calcul_price_total($this->qty, $this->price_ht, $this->remise_percent, $this->tva_tx, $this->localtax1_tx, $this->localtax2_tx, 0, 'HT', 0, 1, $mysoc, $localtaxes_type);
$this->total_ht = $tabprice[0]; $this->total_ht = $tabprice[0];
$this->total_tva = $tabprice[1]; $this->total_tva = $tabprice[1];
$this->total_ttc = $tabprice[2]; $this->total_ttc = $tabprice[2];

View File

@ -104,7 +104,7 @@ class box_project extends ModeleBoxes
'td' => 'align="left"', 'td' => 'align="left"',
'text' => $objp->ref, 'text' => $objp->ref,
'tooltip' => $tooltip, 'tooltip' => $tooltip,
'url' => DOL_URL_ROOT."/product/card.php?id=".$objp->rowid, 'url' => DOL_URL_ROOT."/projet/card.php?id=".$objp->rowid,
); );
$this->info_box_contents[$i][2] = array( $this->info_box_contents[$i][2] = array(

View File

@ -3949,10 +3949,10 @@ abstract class CommonObject
/** /**
* Function to show lines of extrafields with output datas * Function to show lines of extrafields with output datas
* *
* @param object $extrafields Extrafield Object * @param Extrafields $extrafields Extrafield Object
* @param string $mode Show output ('view') or input ('edit') for extrafield * @param string $mode Show output (view) or input (edit) for extrafield
* @param array $params Optionnal parameters. Example: array('colspan'=>2) * @param array $params Optional parameters
* @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names)
* *
* @return string * @return string
*/ */
@ -3983,7 +3983,16 @@ abstract class CommonObject
$value=$this->array_options["options_".$key]; $value=$this->array_options["options_".$key];
break; break;
case "edit": case "edit":
$value=(isset($_POST["options_".$key])?$_POST["options_".$key]:$this->array_options["options_".$key]); if (isset($_POST["options_" . $key])) {
if (is_array($_POST["options_" . $key])) {
// $_POST["options"] is an array but following code expects a comma separated string
$value = implode(",", $_POST["options_" . $key]);
} else {
$value = $_POST["options_" . $key];
}
} else {
$value = $this->array_options["options_" . $key];
}
break; break;
} }
if ($extrafields->attribute_type[$key] == 'separate') if ($extrafields->attribute_type[$key] == 'separate')

View File

@ -815,7 +815,9 @@ class ExtraFields
{ {
$sqlwhere.= ' WHERE '.$InfoFieldList[4]; $sqlwhere.= ' WHERE '.$InfoFieldList[4];
} }
}else { }
else
{
$sqlwhere.= ' WHERE 1'; $sqlwhere.= ' WHERE 1';
} }
if (in_array($InfoFieldList[0],array('tablewithentity'))) $sqlwhere.= ' AND entity = '.$conf->entity; // Some tables may have field, some other not. For the moment we disable it. if (in_array($InfoFieldList[0],array('tablewithentity'))) $sqlwhere.= ' AND entity = '.$conf->entity; // Some tables may have field, some other not. For the moment we disable it.
@ -1451,7 +1453,7 @@ class ExtraFields
else if (in_array($key_type,array('checkbox'))) else if (in_array($key_type,array('checkbox')))
{ {
$value_arr=GETPOST($keysuffix."options_".$key.$keyprefix); $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
$value_key=implode($value_arr,','); $value_key=implode(',', $value_arr);
} }
else if (in_array($key_type,array('price','double'))) else if (in_array($key_type,array('price','double')))
{ {

View File

@ -3235,7 +3235,7 @@ class Form
if (! empty($more)) { if (! empty($more)) {
$formconfirm.= '<div class="confirmquestions">'.$more.'</div>'; $formconfirm.= '<div class="confirmquestions">'.$more.'</div>';
} }
$formconfirm.= ($question ? '<div class="confirmmessage"'.img_help('','').' '.$question . '</div>': ''); $formconfirm.= ($question ? '<div class="confirmmessage">'.img_help('','').' '.$question . '</div>': '');
$formconfirm.= '</div>'."\n"; $formconfirm.= '</div>'."\n";
$formconfirm.= "\n<!-- begin ajax formconfirm page=".$page." -->\n"; $formconfirm.= "\n<!-- begin ajax formconfirm page=".$page." -->\n";
@ -4797,7 +4797,7 @@ class Form
if ($rendermode == 0) if ($rendermode == 0)
{ {
$cate_arbo = $this->select_all_categories(Categorie::TYPE_PRODUCT, '', 'parent', 64, 0, 1); $cate_arbo = $this->select_all_categories($type, '', 'parent', 64, 0, 1);
foreach($categories as $c) { foreach($categories as $c) {
$arrayselected[] = $c->id; $arrayselected[] = $c->id;
} }

View File

@ -386,7 +386,6 @@ function pdf_build_address($outputlangs,$sourcecompany,$targetcompany='',$target
if ($mode == 'source' && ! is_object($sourcecompany)) return -1; if ($mode == 'source' && ! is_object($sourcecompany)) return -1;
if ($mode == 'target' && ! is_object($targetcompany)) return -1; if ($mode == 'target' && ! is_object($targetcompany)) return -1;
if ($mode == 'delivery' && ! is_object($deliverycompany)) return -1;
if (! empty($sourcecompany->state_id) && empty($sourcecompany->departement)) $sourcecompany->departement=getState($sourcecompany->state_id); //TODO: Deprecated if (! empty($sourcecompany->state_id) && empty($sourcecompany->departement)) $sourcecompany->departement=getState($sourcecompany->state_id); //TODO: Deprecated
if (! empty($sourcecompany->state_id) && empty($sourcecompany->state)) $sourcecompany->state=getState($sourcecompany->state_id); if (! empty($sourcecompany->state_id) && empty($sourcecompany->state)) $sourcecompany->state=getState($sourcecompany->state_id);

View File

@ -53,7 +53,7 @@ function project_prepare_head($object)
|| ! empty($conf->ficheinter->enabled) || ! empty($conf->agenda->enabled) || ! empty($conf->deplacement->enabled)) || ! empty($conf->ficheinter->enabled) || ! empty($conf->agenda->enabled) || ! empty($conf->deplacement->enabled))
{ {
$head[$h][0] = DOL_URL_ROOT.'/projet/element.php?id='.$object->id; $head[$h][0] = DOL_URL_ROOT.'/projet/element.php?id='.$object->id;
$head[$h][1] = $langs->trans("Overview"); $head[$h][1] = $langs->trans("ProjectOverview");
$head[$h][2] = 'element'; $head[$h][2] = 'element';
$h++; $h++;
} }
@ -348,7 +348,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t
$projectstatic->id=$lines[$i]->fk_project; $projectstatic->id=$lines[$i]->fk_project;
$projectstatic->ref=$lines[$i]->projectref; $projectstatic->ref=$lines[$i]->projectref;
$projectstatic->public=$lines[$i]->public; $projectstatic->public=$lines[$i]->public;
if ($lines[$i]->public || in_array($lines[$i]->fk_project,$projectsArrayId)) print $projectstatic->getNomUrl(1); if ($lines[$i]->public || in_array($lines[$i]->fk_project,$projectsArrayId) || ! empty($user->rights->projet->all->lire)) print $projectstatic->getNomUrl(1);
else print $projectstatic->getNomUrl(1,'nolink'); else print $projectstatic->getNomUrl(1,'nolink');
if ($showlineingray) print '</i>'; if ($showlineingray) print '</i>';
print "</td>"; print "</td>";

View File

@ -68,6 +68,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left
-- Third parties -- Third parties
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 500__+MAX_llx_menu__, 'companies', 'thirdparties', 2__+MAX_llx_menu__, '/societe/index.php?leftmenu=thirdparties', 'ThirdParty', 0, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 500__+MAX_llx_menu__, 'companies', 'thirdparties', 2__+MAX_llx_menu__, '/societe/index.php?leftmenu=thirdparties', 'ThirdParty', 0, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 501__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/soc.php?action=create', 'MenuNewThirdParty', 1, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 501__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/soc.php?action=create', 'MenuNewThirdParty', 1, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 502__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/societe/list.php?action=create', 'List', 1, 'companies', '$user->rights->societe->lire', '', 2, 0, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 503__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/fourn/list.php?leftmenu=suppliers', 'ListSuppliersShort', 1, 'suppliers', '$user->rights->societe->lire && $user->rights->fournisseur->lire', '', 2, 5, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 503__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/fourn/list.php?leftmenu=suppliers', 'ListSuppliersShort', 1, 'suppliers', '$user->rights->societe->lire && $user->rights->fournisseur->lire', '', 2, 5, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 504__+MAX_llx_menu__, 'companies', '', 503__+MAX_llx_menu__, '/societe/soc.php?leftmenu=supplier&amp;action=create&amp;type=f', 'NewSupplier', 2, 'suppliers', '$user->rights->societe->creer', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled && $conf->fournisseur->enabled', __HANDLER__, 'left', 504__+MAX_llx_menu__, 'companies', '', 503__+MAX_llx_menu__, '/societe/soc.php?leftmenu=supplier&amp;action=create&amp;type=f', 'NewSupplier', 2, 'suppliers', '$user->rights->societe->creer', '', 2, 0, __ENTITY__);
insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 506__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/comm/prospect/list.php?leftmenu=prospects', 'ListProspectsShort', 1, 'companies', '$user->rights->societe->lire', '', 2, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->societe->enabled', __HANDLER__, 'left', 506__+MAX_llx_menu__, 'companies', '', 500__+MAX_llx_menu__, '/comm/prospect/list.php?leftmenu=prospects', 'ListProspectsShort', 1, 'companies', '$user->rights->societe->lire', '', 2, 3, __ENTITY__);

View File

@ -7,7 +7,7 @@
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr> * Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
* Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com> * Copyright (C) 2014-2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2014 Francis Appels <francis.appels@yahoo.com> * Copyright (C) 2014-2015 Francis Appels <francis.appels@yahoo.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -568,7 +568,7 @@ class Expedition extends CommonObject
$result=$soc->set_as_client(); $result=$soc->set_as_client();
// Define new ref // Define new ref
if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
{ {
$numref = $this->getNextNumRef($soc); $numref = $this->getNextNumRef($soc);
} }
@ -981,7 +981,7 @@ class Expedition extends CommonObject
} }
} }
/** /**
* Delete shipment. * Delete shipment.
* Warning, do not delete a shipment if a delivery is linked to (with table llx_element_element) * Warning, do not delete a shipment if a delivery is linked to (with table llx_element_element)
* *
@ -990,9 +990,13 @@ class Expedition extends CommonObject
function delete() function delete()
{ {
global $conf, $langs, $user; global $conf, $langs, $user;
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
if ($conf->productbatch->enabled)
{
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php';
}
$error=0; $error=0;
$this->error='';
// Add a protection to refuse deleting if shipment has at least one delivery // Add a protection to refuse deleting if shipment has at least one delivery
$this->fetchObjectLinked($this->id, 'shipping', 0, 'delivery'); // Get deliveries linked to this shipment $this->fetchObjectLinked($this->id, 'shipping', 0, 'delivery'); // Get deliveries linked to this shipment
@ -1003,15 +1007,6 @@ class Expedition extends CommonObject
} }
$this->db->begin(); $this->db->begin();
if ($conf->productbatch->enabled)
{
require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php';
if (ExpeditionLineBatch::deletefromexp($this->db,$this->id) < 0)
{
$error++;$this->errors[]="Error ".$this->db->lasterror();
}
}
// Stock control // Stock control
if ($conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > 0) if ($conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > 0)
{ {
@ -1020,7 +1015,7 @@ class Expedition extends CommonObject
$langs->load("agenda"); $langs->load("agenda");
// Loop on each product line to add a stock movement // Loop on each product line to add a stock movement
$sql = "SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot"; $sql = "SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot, ed.rowid as expeditiondet_id";
$sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,";
$sql.= " ".MAIN_DB_PREFIX."expeditiondet as ed"; $sql.= " ".MAIN_DB_PREFIX."expeditiondet as ed";
$sql.= " WHERE ed.fk_expedition = ".$this->id; $sql.= " WHERE ed.fk_expedition = ".$this->id;
@ -1036,22 +1031,58 @@ class Expedition extends CommonObject
dol_syslog(get_class($this)."::delete movement index ".$i); dol_syslog(get_class($this)."::delete movement index ".$i);
$obj = $this->db->fetch_object($resql); $obj = $this->db->fetch_object($resql);
//var_dump($this->lines[$i]);
$mouvS = new MouvementStock($this->db); $mouvS = new MouvementStock($this->db);
$mouvS->origin = &$this; // we do not log origin because it will be deleted
// We decrement stock of product (and sub-products) $mouvS->origin = null;
// We use warehouse selected for each line // get lot/serial
$result=$mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentDeletedInDolibarr",$this->ref)); $lotArray = null;
if ($result < 0) if ($conf->productbatch->enabled)
{ {
$error++; $lotArray = ExpeditionLineBatch::fetchAll($this->db,$obj->expeditiondet_id);
break; if (! is_array($lotArray))
{
$error++;$this->errors[]="Error ".$this->db->lasterror();
}
}
if (empty($lotArray)) {
// no lot/serial
// We increment stock of product (and sub-products)
// We use warehouse selected for each line
$result=$mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentDeletedInDolibarr", $this->ref));
if ($result < 0)
{
$error++;$this->errors=$this->errors + $mouvS->errors;
break;
}
}
else
{
// We increment stock of batches
// We use warehouse selected for each line
foreach($lotArray as $lot)
{
$result=$mouvS->reception($user, $obj->fk_product, $obj->fk_entrepot, $lot->dluo_qty, $obj->subprice, $langs->trans("ShipmentDeletedInDolibarr", $this->ref), $lot->eatby, $lot->sellby, $lot->batch);
if ($result < 0)
{
$error++;$this->errors=$this->errors + $mouvS->errors;
break;
}
}
} }
} }
} }
else else
{ {
$error++; $error++;$this->errors[]="Error ".$this->db->lasterror();
}
}
// delete batch expedition line
if (! $error && $conf->productbatch->enabled)
{
if (ExpeditionLineBatch::deletefromexp($this->db,$this->id) < 0)
{
$error++;$this->errors[]="Error ".$this->db->lasterror();
} }
} }
@ -1073,13 +1104,13 @@ class Expedition extends CommonObject
if ($this->db->query($sql)) if ($this->db->query($sql))
{ {
// Call trigger // Call trigger
$result=$this->call_trigger('SHIPPING_DELETE',$user); $result=$this->call_trigger('SHIPPING_DELETE',$user);
if ($result < 0) { $error++; } if ($result < 0) { $error++; }
// End call triggers // End call triggers
if (! $error) if (! $error)
{ {
$this->db->commit(); $this->db->commit();
// We delete PDFs // We delete PDFs
@ -1106,8 +1137,8 @@ class Expedition extends CommonObject
} }
return 1; return 1;
} }
else else
{ {
$this->db->rollback(); $this->db->rollback();
return -1; return -1;

View File

@ -188,11 +188,12 @@ class ExpeditionLineBatch extends CommonObject
$sql.= " WHERE fk_expeditiondet=".(int) $id_line_expdet; $sql.= " WHERE fk_expeditiondet=".(int) $id_line_expdet;
dol_syslog(__METHOD__ ."", LOG_DEBUG); dol_syslog(__METHOD__ ."", LOG_DEBUG);
$resql=$db->query($sql); $resql=$db->query($sql);
if ($resql) if ($resql)
{ {
$num=$db->num_rows($resql); $num=$db->num_rows($resql);
$i=0; $i=0;
$ret = array();
while ($i<$num) while ($i<$num)
{ {
$tmp=new self($db); $tmp=new self($db);

View File

@ -1669,7 +1669,7 @@ else
print img_picto($langs->trans("Document"), "object_generic"); print img_picto($langs->trans("Document"), "object_generic");
print ' <span>'.$piece_comptable.'</span></td>'; print ' <span>'.$piece_comptable.'</span></td>';
} }
print '<td style="text-align:center;">'.$objp->date.'</td>'; print '<td style="text-align:center;">'.dol_print_date($db->jdate($objp->date), 'day').'</td>';
print '<td style="text-align:center;">'; print '<td style="text-align:center;">';
if ($objp->projet_id > 0) if ($objp->projet_id > 0)
{ {

View File

@ -392,7 +392,7 @@ class Fichinter extends CommonObject
$now=dol_now(); $now=dol_now();
// Define new ref // Define new ref
if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref))) if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($this->thirdparty); $num = $this->getNextNumRef($this->thirdparty);
} }

View File

@ -392,7 +392,7 @@ class CommandeFournisseur extends CommonOrder
$soc->fetch($this->fourn_id); $soc->fetch($this->fourn_id);
// Check if object has a temporary ref // Check if object has a temporary ref
if (preg_match('/^[\(]?PROV/i', $this->ref)) if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($soc); $num = $this->getNextNumRef($soc);
} }
@ -688,7 +688,7 @@ class CommandeFournisseur extends CommonOrder
$soc->fetch($this->fourn_id); $soc->fetch($this->fourn_id);
// Check if object has a temporary ref // Check if object has a temporary ref
if (preg_match('/^[\(]?PROV/i', $this->ref)) if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($soc); $num = $this->getNextNumRef($soc);
} }

View File

@ -930,7 +930,7 @@ class FactureFournisseur extends CommonInvoice
{ {
$num = $force_number; $num = $force_number;
} }
else if (preg_match('/^[\(]?PROV/i', $this->ref)) else if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life
{ {
$num = $this->getNextNumRef($this->client); $num = $this->getNextNumRef($this->client);
} }

View File

@ -1675,7 +1675,10 @@ elseif (! empty($object->id))
$object->date_commande=dol_now(); $object->date_commande=dol_now();
// We check if number is temporary number // We check if number is temporary number
if (preg_match('/^[\(]?PROV/i',$object->ref)) $newref = $object->getNextNumRef($object->thirdparty); if (preg_match('/^[\(]?PROV/i',$object->ref) || empty($object->ref)) // empty should not happened, but when it occurs, the test save life
{
$newref = $object->getNextNumRef($object->thirdparty);
}
else $newref = $object->ref; else $newref = $object->ref;
if ($newref < 0) if ($newref < 0)

1
htdocs/install/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/filelist.xml

File diff suppressed because it is too large Load Diff

View File

@ -376,13 +376,13 @@ function pHeader($subtitle,$next,$action='set',$param='',$forcejqueryurl='')
print '<!-- Includes CSS for JQuery -->'."\n"; print '<!-- Includes CSS for JQuery -->'."\n";
if ($jQueryUiCustomPath) print '<link rel="stylesheet" type="text/css" href="'.$jQueryUiCustomPath.'css/'.$jquerytheme.'/jquery-ui.min.css" />'."\n"; // JQuery if ($jQueryUiCustomPath) print '<link rel="stylesheet" type="text/css" href="'.$jQueryUiCustomPath.'css/'.$jquerytheme.'/jquery-ui.min.css" />'."\n"; // JQuery
else print '<link rel="stylesheet" type="text/css" href="../includes/jquery/css/'.$jquerytheme.'/jquery-ui.custom.css" />'."\n"; // JQuery else print '<link rel="stylesheet" type="text/css" href="../includes/jquery/css/'.$jquerytheme.'/jquery-ui.min.css" />'."\n"; // JQuery
print '<!-- Includes JS for JQuery -->'."\n"; print '<!-- Includes JS for JQuery -->'."\n";
if ($jQueryCustomPath) print '<script type="text/javascript" src="'.$jQueryCustomPath.'jquery.min.js"></script>'."\n"; if ($jQueryCustomPath) print '<script type="text/javascript" src="'.$jQueryCustomPath.'jquery.min.js"></script>'."\n";
else print '<script type="text/javascript" src="../includes/jquery/js/jquery.min.js"></script>'."\n"; else print '<script type="text/javascript" src="../includes/jquery/js/jquery.min.js"></script>'."\n";
if ($jQueryUiCustomPath) print '<script type="text/javascript" src="'.$jQueryUiCustomPath.'jquery-ui.min.js"></script>'."\n"; if ($jQueryUiCustomPath) print '<script type="text/javascript" src="'.$jQueryUiCustomPath.'jquery-ui.min.js"></script>'."\n";
else print '<script type="text/javascript" src="../includes/jquery/js/jquery-ui.custom.min.js"></script>'."\n"; else print '<script type="text/javascript" src="../includes/jquery/js/jquery-ui.min.js"></script>'."\n";
print '<title>'.$langs->trans("DolibarrSetup").'</title>'."\n"; print '<title>'.$langs->trans("DolibarrSetup").'</title>'."\n";
print '</head>'."\n"; print '</head>'."\n";

View File

@ -36,7 +36,7 @@ MargeNette=Net margin
MargeType1=Margin on Best supplier price MargeType1=Margin on Best supplier price
MargeType2=Margin on Weighted Average Price (WAP) MargeType2=Margin on Weighted Average Price (WAP)
MARGIN_TYPE_DETAILS=Raw margin : Selling price - Buying price<br/>Net margin : Selling price - Cost price MARGIN_TYPE_DETAILS=Raw margin : Selling price - Buying price<br/>Net margin : Selling price - Cost price
MarginTypeDesc=Margin on best buying price : Selling price - Best supplier price defined on product card<br/>Margin on Weighted Average Price (WAP) : Selling price - Product Weighted Average Price MarginTypeDesc=Margin on best buying price : Selling price - Best supplier price defined on product card<br/>Margin on Weighted Average Price (WAP) : Selling price - Product Weighted Average Price (WAP) or best supplier price if WAP not yet defined
CostPrice=Cost price CostPrice=Cost price
BuyingCost=Cost price BuyingCost=Cost price
UnitCharges=Unit charges UnitCharges=Unit charges

View File

@ -44,7 +44,8 @@ ListOfUsers=List of users
Administrator=Administrator Administrator=Administrator
SuperAdministrator=Super Administrator SuperAdministrator=Super Administrator
SuperAdministratorDesc=Global administrator SuperAdministratorDesc=Global administrator
AdministratorDesc=Administrator's entity AdministratorDesc=Administrator
AdministratorDescEntity=Administrator (for its company)
DefaultRights=Default permissions DefaultRights=Default permissions
DefaultRightsDesc=Define here <u>default</u> permissions that are automatically granted to a <u>new created</u> user (Go on user card to change permission of an existing user). DefaultRightsDesc=Define here <u>default</u> permissions that are automatically granted to a <u>new created</u> user (Go on user card to change permission of an existing user).
DolibarrUsers=Dolibarr users DolibarrUsers=Dolibarr users

View File

@ -36,7 +36,7 @@ MargeNette=Marge nette
MargeType1=Marge sur le meilleur prix fournisseur MargeType1=Marge sur le meilleur prix fournisseur
MargeType2=Marge sur le Prix Moyen Pondéré (PMP) MargeType2=Marge sur le Prix Moyen Pondéré (PMP)
MARGIN_TYPE_DETAILS=Marge brute : Prix de vente HT - Prix d'achat HT<br/>Marge nette : Prix de vente HT - Weighted Average Price MARGIN_TYPE_DETAILS=Marge brute : Prix de vente HT - Prix d'achat HT<br/>Marge nette : Prix de vente HT - Weighted Average Price
MarginTypeDesc=Marge sur le meilleur prix d'achat fournisseur: Prix de vente - Meilleur prix d'achat défini sur la fiche produit<br/>Marge sur le Prix Moyen Pondéré (PMP): Prix de vente - Prix Moyen Pondéré du produit MarginTypeDesc=Marge sur le meilleur prix d'achat fournisseur: Prix de vente - Meilleur prix d'achat défini sur la fiche produit<br/>Marge sur le Prix Moyen Pondéré (PMP): Prix de vente - Prix Moyen Pondéré du produit (PMP) ou meilleur prix d'achat si PMP non défini
CostPrice=Prix de revient CostPrice=Prix de revient
BuyingCost=Coût de revient BuyingCost=Coût de revient
UnitCharges=Charge unitaire UnitCharges=Charge unitaire

View File

@ -361,7 +361,7 @@ class Livraison extends CommonObject
$soc = new Societe($this->db); $soc = new Societe($this->db);
$soc->fetch($this->socid); $soc->fetch($this->socid);
if (preg_match('/^[\(]?PROV/i', $this->ref)) if (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref)) // empty should not happened, but when it occurs, the test save life
{ {
$numref = $objMod->livraison_get_num($soc,$this); $numref = $objMod->livraison_get_num($soc,$this);
} }

View File

@ -164,7 +164,6 @@ print '<td>';
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'" class="button">'; print '<input type="submit" class="button" value="'.$langs->trans("Modify").'" class="button">';
print '</td>'; print '</td>';
print '<td>'.$langs->trans('MarginTypeDesc'); print '<td>'.$langs->trans('MarginTypeDesc');
print ' ('.$langs->trans("PMPValueShort").')';
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
print '</form>'; print '</form>';

View File

@ -354,7 +354,7 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) $current_rule='PRODUI
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) $current_rule='PRODUIT_CUSTOMER_PRICES'; if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) $current_rule='PRODUIT_CUSTOMER_PRICES';
if ((!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) && (!empty($conf->global->PRODUIT_MULTIPRICES))) $current_rule='PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES'; if ((!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) && (!empty($conf->global->PRODUIT_MULTIPRICES))) $current_rule='PRODUIT_CUSTOMER_PRICES_BY_QTY&PRODUIT_MULTIPRICES';
print $form->selectarray("princingrule",$select_pricing_rules,$current_rule); print $form->selectarray("princingrule",$select_pricing_rules,$current_rule);
print '</td><td align="right" rowspan="'.$rowspan.'">'; print '</td><td align="right" rowspan="'.$rowspan.'" class="nohover">';
print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">'; print '<input type="submit" class="button" value="'.$langs->trans("Modify").'">';
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';

View File

@ -3959,12 +3959,14 @@ class Product extends CommonObject
// Process // Process
foreach($to_del as $del) { foreach($to_del as $del) {
$c->fetch($del); if ($c->fetch($del) > 0) {
$c->del_type($this, 'product'); $c->del_type($this, 'product');
}
} }
foreach ($to_add as $add) { foreach ($to_add as $add) {
$c->fetch($add); if ($c->fetch($add) > 0) {
$c->add_type($this, 'product'); $c->add_type($this, 'product');
}
} }
return; return;

View File

@ -314,7 +314,8 @@ if ($result)
} }
} }
print '<td align="right">'; print '<td align="right">';
print price($objp->price).' '.$langs->trans("HT"); if (isset($objp->price_base_type) && $objp->price_base_type == 'TTC') print price($objp->price_ttc).' '.$langs->trans("TTC");
else print price($objp->price).' '.$langs->trans("HT");
print '</td>'; print '</td>';
} }
print '<td align="right" class="nowrap">'; print '<td align="right" class="nowrap">';

View File

@ -1286,18 +1286,18 @@ if (! empty($conf->global->PRODUIT_CUSTOMER_PRICES))
print '<td>&nbsp;</td>'; print '<td>&nbsp;</td>';
print '</tr>'; print '</tr>';
print '<tr class="liste_titre">';
print '<td><input type="text" class="flat" name="search_soc" value="' . $search_soc . '" size="20"></td>';
print '<td colspan="8">&nbsp;</td>';
// Print the search button
print '<td class="liste_titre" align="right">';
print '<input class="liste_titre" name="button_search" type="image" 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>';
print '</tr>';
if (count($prodcustprice->lines) > 0) if (count($prodcustprice->lines) > 0)
{ {
$var = False; print '<tr class="liste_titre">';
print '<td><input type="text" class="flat" name="search_soc" value="' . $search_soc . '" size="20"></td>';
print '<td colspan="8">&nbsp;</td>';
// Print the search button
print '<td class="liste_titre" align="right">';
print '<input class="liste_titre" name="button_search" type="image" 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>';
print '</tr>';
$var = False;
foreach ($prodcustprice->lines as $line) foreach ($prodcustprice->lines as $line)
{ {

View File

@ -130,14 +130,14 @@ class Entrepot extends CommonObject
*/ */
function update($id, $user) function update($id, $user)
{ {
$this->libelle=$this->db->escape(trim($this->libelle)); $this->libelle=trim($this->libelle);
$this->description=$this->db->escape(trim($this->description)); $this->description=trim($this->description);
$this->lieu=$this->db->escape(trim($this->lieu)); $this->lieu=trim($this->lieu);
$this->address=$this->db->escape(trim($this->address)); $this->address=trim($this->address);
$this->zip=$this->zip?trim($this->zip):trim($this->zip); $this->zip=trim($this->zip);
$this->town=$this->town?trim($this->town):trim($this->town); $this->town=trim($this->town);
$this->country_id=($this->country_id > 0 ? $this->country_id : $this->country_id); $this->country_id=($this->country_id > 0 ? $this->country_id : $this->country_id);
$sql = "UPDATE ".MAIN_DB_PREFIX."entrepot "; $sql = "UPDATE ".MAIN_DB_PREFIX."entrepot ";

View File

@ -878,15 +878,17 @@ class Project extends CommonObject
$result = ''; $result = '';
$link = ''; $link = '';
$linkend = ''; $linkend = '';
$label = '<u>' . $langs->trans("ShowProject") . '</u>'; $label='';
if ($option != 'nolink') $label = '<u>' . $langs->trans("ShowProject") . '</u>';
if (! empty($this->ref)) if (! empty($this->ref))
$label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref; $label .= ($label?'<br>':'').'<b>' . $langs->trans('Ref') . ': </b>' . $this->ref; // The space must be after the : to not being explode when showing the title in img_picto
if (! empty($this->title)) if (! empty($this->title))
$label .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $this->title; $label .= ($label?'<br>':'').'<b>' . $langs->trans('Label') . ': </b>' . $this->title; // The space must be after the : to not being explode when showing the title in img_picto
if ($moreinpopup) $label.='<br>'.$moreinpopup; if ($moreinpopup) $label.='<br>'.$moreinpopup;
$linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
if ($option != 'nolink') { if ($option != 'nolink')
{
if (preg_match('/\.php$/',$option)) { if (preg_match('/\.php$/',$option)) {
$link = '<a href="' . dol_buildpath($option,1) . '?id=' . $this->id . $linkclose; $link = '<a href="' . dol_buildpath($option,1) . '?id=' . $this->id . $linkclose;
$linkend = '</a>'; $linkend = '</a>';

View File

@ -48,9 +48,9 @@ if ($socid > 0)
if (!$user->rights->projet->lire) accessforbidden(); if (!$user->rights->projet->lire) accessforbidden();
$sortfield = isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"]; $sortfield = GETPOST("sortfield","alpha");
$sortorder = isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"]; $sortorder = GETPOST("sortorder");
$page = isset($_GET["page"])? $_GET["page"]:$_POST["page"]; $page = GETPOST("page");
$page = is_numeric($page) ? $page : 0; $page = is_numeric($page) ? $page : 0;
$page = $page == -1 ? 0 : $page; $page = $page == -1 ? 0 : $page;
@ -141,7 +141,7 @@ $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls on p.fk_opp_status = cls.rowid"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_lead_status as cls on p.fk_opp_status = cls.rowid";
// We'll need this table joined to the select in order to filter by sale // We'll need this table joined to the select in order to filter by sale
if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid";
if ($search_user > 0) if ($search_user > 0)
{ {
$sql.=", ".MAIN_DB_PREFIX."element_contact as c"; $sql.=", ".MAIN_DB_PREFIX."element_contact as c";
@ -191,7 +191,8 @@ if ($search_opp_status)
if ($search_opp_status == 'none') $sql .= " AND p.fk_opp_status IS NULL"; if ($search_opp_status == 'none') $sql .= " AND p.fk_opp_status IS NULL";
} }
if ($search_public!='') $sql .= " AND p.public = ".$db->escape($search_public); if ($search_public!='') $sql .= " AND p.public = ".$db->escape($search_public);
if ($search_sale > 0 || (! $user->rights->societe->client->voir && ! $socid)) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$search_sale; if ($search_sale > 0) $sql.= " AND sc.fk_user = " .$search_sale;
if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))";
if ($search_user > 0) $sql.= " AND c.fk_c_type_contact = tc.rowid AND tc.element='project' AND tc.source='internal' AND c.element_id = p.rowid AND c.fk_socpeople = ".$search_user; if ($search_user > 0) $sql.= " AND c.fk_c_type_contact = tc.rowid AND tc.element='project' AND tc.source='internal' AND c.element_id = p.rowid AND c.fk_socpeople = ".$search_user;
// Add where from hooks // Add where from hooks
$parameters=array(); $parameters=array();

View File

@ -430,6 +430,8 @@ if ($id > 0 || ! empty($ref))
/* /*
* List of time spent * List of time spent
*/ */
$tasks = array();
$sql = "SELECT t.rowid, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note, t.thm"; $sql = "SELECT t.rowid, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note, t.thm";
$sql.= ", u.lastname, u.firstname"; $sql.= ", u.lastname, u.firstname";
$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
@ -444,7 +446,6 @@ if ($id > 0 || ! empty($ref))
{ {
$num = $db->num_rows($resql); $num = $db->num_rows($resql);
$i = 0; $i = 0;
$tasks = array();
while ($i < $num) while ($i < $num)
{ {
$row = $db->fetch_object($resql); $row = $db->fetch_object($resql);
@ -470,7 +471,7 @@ if ($id > 0 || ! empty($ref))
print '<td>'.$langs->trans("By").'</td>'; print '<td>'.$langs->trans("By").'</td>';
print '<td align="left">'.$langs->trans("Note").'</td>'; print '<td align="left">'.$langs->trans("Note").'</td>';
print '<td align="right">'.$langs->trans("TimeSpent").'</td>'; print '<td align="right">'.$langs->trans("TimeSpent").'</td>';
if ($conf->salaries->enabled) if (! empty($conf->salaries->enabled))
{ {
print '<td align="right">'.$langs->trans("Value").'</td>'; print '<td align="right">'.$langs->trans("Value").'</td>';
} }
@ -491,11 +492,11 @@ if ($id > 0 || ! empty($ref))
print '<td class="nowrap">'; print '<td class="nowrap">';
if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid) if ($_GET['action'] == 'editline' && $_GET['lineid'] == $task_time->rowid)
{ {
print $form->select_date($db->jdate($date2?$date2:$date1),'timeline',1,1,2,"timespent_date",1,0,1); print $form->select_date(($date2?$date2:$date1),'timeline',1,1,2,"timespent_date",1,0,1);
} }
else else
{ {
print dol_print_date($date2?$date2:$date1,($task_time->task_date_withhour?'dayhour':'day')); print dol_print_date(($date2?$date2:$date1),($task_time->task_date_withhour?'dayhour':'day'));
} }
print '</td>'; print '</td>';

View File

@ -726,7 +726,7 @@ Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
this.comment = comment; this.comment = comment;
}; };
})();; })();
// lib/handlebars/utils.js // lib/handlebars/utils.js
Handlebars.Exception = function(message) { Handlebars.Exception = function(message) {
var tmp = Error.prototype.constructor.apply(this, arguments); var tmp = Error.prototype.constructor.apply(this, arguments);
@ -791,7 +791,7 @@ Handlebars.SafeString.prototype.toString = function() {
} }
} }
}; };
})();; })();
// lib/handlebars/compiler/compiler.js // lib/handlebars/compiler/compiler.js
/*jshint eqnull:true*/ /*jshint eqnull:true*/

View File

@ -156,7 +156,7 @@ Handlebars.SafeString.prototype.toString = function() {
} }
} }
}; };
})();; })();
// lib/handlebars/runtime.js // lib/handlebars/runtime.js
Handlebars.VM = { Handlebars.VM = {
template: function(templateSpec) { template: function(templateSpec) {

View File

@ -304,7 +304,6 @@ if ($action == 'add')
$urlback=DOL_MAIN_URL_ROOT.'/public/paybox/newpayment.php?from=membernewform&source=membersubscription&ref='.$adh->ref; $urlback=DOL_MAIN_URL_ROOT.'/public/paybox/newpayment.php?from=membernewform&source=membersubscription&ref='.$adh->ref;
if (price2num(GETPOST('amount'))) $urlback.='&amount='.price2num(GETPOST('amount')); if (price2num(GETPOST('amount'))) $urlback.='&amount='.price2num(GETPOST('amount'));
if (GETPOST('email')) $urlback.='&email='.urlencode(GETPOST('email')); if (GETPOST('email')) $urlback.='&email='.urlencode(GETPOST('email'));
if (! empty($entity)) $urlback.='&entity='.$entity;
} }
else if ($conf->global->MEMBER_NEWFORM_PAYONLINE == 'paypal') else if ($conf->global->MEMBER_NEWFORM_PAYONLINE == 'paypal')
{ {
@ -315,7 +314,7 @@ if ($action == 'add')
{ {
$urlback.='&securekey='.dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $adh->ref, 2); $urlback.='&securekey='.dol_hash($conf->global->PAYPAL_SECURITY_TOKEN . 'membersubscription' . $adh->ref, 2);
} }
if (! empty($entity)) $urlback.='&entity='.$entity;
} }
else else
{ {
@ -324,6 +323,7 @@ if ($action == 'add')
} }
} }
if (! empty($entity)) $urlback.='&entity='.$entity;
dol_syslog("member ".$adh->ref." was created, we redirect to ".$urlback); dol_syslog("member ".$adh->ref." was created, we redirect to ".$urlback);
Header("Location: ".$urlback); Header("Location: ".$urlback);
exit; exit;

View File

@ -3393,8 +3393,6 @@ class Societe extends CommonObject
// Diff // Diff
if (is_array($existing)) { if (is_array($existing)) {
var_dump($existing);
var_dump($categories);
$to_del = array_diff($existing, $categories); $to_del = array_diff($existing, $categories);
$to_add = array_diff($categories, $existing); $to_add = array_diff($categories, $existing);
} else { } else {
@ -3404,12 +3402,14 @@ class Societe extends CommonObject
// Process // Process
foreach ($to_del as $del) { foreach ($to_del as $del) {
$c->fetch($del); if ($c->fetch($del) > 0) {
$c->del_type($this, $type_text); $c->del_type($this, $type_text);
}
} }
foreach ($to_add as $add) { foreach ($to_add as $add) {
$c->fetch($add); if ($c->fetch($add) > 0) {
$c->add_type($this, $type_text); $c->add_type($this, $type_text);
}
} }
return; return;

View File

@ -1812,10 +1812,16 @@ else
else else
{ {
print '<td>'; print '<td>';
$nbSuperAdmin = $user->getNbOfUsers('superadmin'); $nbAdmin = $user->getNbOfUsers('active','',1);
if ($user->admin $nbSuperAdmin = $user->getNbOfUsers('active','superadmin',1);
&& ($user->id != $object->id) // Don't downgrade ourself //var_dump($nbAdmin);
&& ($object->entity > 0 || $nbSuperAdmin > 1) // Don't downgrade a superadmin if alone //var_dump($nbSuperAdmin);
if ($user->admin // Need to be admin to allow downgrade of an admin
&& ($user->id != $object->id) // Don't downgrade ourself
&& (
(empty($conf->multicompany->enabled) && $nbAdmin > 1)
|| (! empty($conf->multicompany->enabled) && ($object->entity > 0 || $nbSuperAdmin > 1)) // Don't downgrade a superadmin if alone
)
) )
{ {
print $form->selectyesno('admin',$object->admin,1); print $form->selectyesno('admin',$object->admin,1);

View File

@ -2194,25 +2194,27 @@ class User extends CommonObject
/** /**
* Return number of existing users * Return number of existing users
* *
* @param string $limitTo Limit to 'active' or 'superadmin' users * @param string $limitTo Limit to '' or 'active'
* @param bool $all Return for all entities * @param string $option 'superadmin' = return for entity 0 only
* @param int $admin Filter on admin tag
* @return int Number of users * @return int Number of users
*/ */
function getNbOfUsers($limitTo='active', $all=false) function getNbOfUsers($limitTo, $option='', $admin=-1)
{ {
global $conf; global $conf;
$sql = "SELECT count(rowid) as nb"; $sql = "SELECT count(rowid) as nb";
$sql.= " FROM ".MAIN_DB_PREFIX."user"; $sql.= " FROM ".MAIN_DB_PREFIX."user";
if ($limitTo == 'superadmin') if ($option == 'superadmin')
{ {
$sql.= " WHERE entity = 0"; $sql.= " WHERE entity = 0";
if ($admin >= 0) $sql.= " AND admin = ".$admin;
} }
else else
{ {
if ($all) $sql.= " WHERE entity > 0"; // all users except superadmins $sql.=" WHERE entity IN (".getEntity('user',0).")";
else $sql.= " WHERE entity = ".$conf->entity;
if ($limitTo == 'active') $sql.= " AND statut = 1"; if ($limitTo == 'active') $sql.= " AND statut = 1";
if ($admin >= 0) $sql.= " AND admin = ".$admin;
} }
$resql=$this->db->query($sql); $resql=$this->db->query($sql);
@ -2226,7 +2228,7 @@ class User extends CommonObject
} }
else else
{ {
$this->error=$this->db->error(); $this->error=$this->db->lasterror();
return -1; return -1;
} }
} }
@ -2355,7 +2357,7 @@ class User extends CommonObject
$this->load_parentof(); $this->load_parentof();
// Init $this->users array // Init $this->users array
$sql = "SELECT DISTINCT u.rowid, u.firstname, u.lastname, u.fk_user, u.fk_soc, u.login, u.email, u.gender, u.statut, u.entity"; // Distinct reduce pb with old tables with duplicates $sql = "SELECT DISTINCT u.rowid, u.firstname, u.lastname, u.fk_user, u.fk_soc, u.login, u.email, u.gender, u.admin, u.statut, u.entity"; // Distinct reduce pb with old tables with duplicates
$sql.= " FROM ".MAIN_DB_PREFIX."user as u"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u";
if(! empty($conf->multicompany->enabled) && $conf->entity == 1 && (! empty($conf->multicompany->transverse_mode) || (! empty($user->admin) && empty($user->entity)))) if(! empty($conf->multicompany->enabled) && $conf->entity == 1 && (! empty($conf->multicompany->transverse_mode) || (! empty($user->admin) && empty($user->entity))))
{ {
@ -2385,6 +2387,7 @@ class User extends CommonObject
$this->users[$obj->rowid]['entity'] = $obj->entity; $this->users[$obj->rowid]['entity'] = $obj->entity;
$this->users[$obj->rowid]['email'] = $obj->email; $this->users[$obj->rowid]['email'] = $obj->email;
$this->users[$obj->rowid]['gender'] = $obj->gender; $this->users[$obj->rowid]['gender'] = $obj->gender;
$this->users[$obj->rowid]['admin'] = $obj->admin;
$i++; $i++;
} }
} }

View File

@ -88,6 +88,8 @@ foreach($fulltree as $key => $val)
$userstatic->email=$val['email']; $userstatic->email=$val['email'];
$userstatic->gender=$val['gender']; $userstatic->gender=$val['gender'];
$userstatic->societe_id=$val['fk_soc']; $userstatic->societe_id=$val['fk_soc'];
$userstatic->admin=$val['admin'];
$userstatic->entity=$val['entity'];
$entity=$val['entity']; $entity=$val['entity'];
$entitystring=''; $entitystring='';
@ -109,7 +111,16 @@ foreach($fulltree as $key => $val)
} }
} }
$li=$userstatic->getNomUrl(1,'').' ('.$val['login'].($entitystring?' - '.$entitystring:'').')'; $li=$userstatic->getNomUrl(1,'',0,1);
if (! empty($conf->multicompany->enabled) && $userstatic->admin && ! $userstatic->entity)
{
$li.=img_picto($langs->trans("SuperAdministrator"),'redstar');
}
else if ($userstatic->admin)
{
$li.=img_picto($langs->trans("Administrator"),'star');
}
$li.=' ('.$val['login'].($entitystring?' - '.$entitystring:'').')';
$data[] = array( $data[] = array(
'rowid'=>$val['rowid'], 'rowid'=>$val['rowid'],