Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur 2024-01-10 15:16:12 +01:00
commit 706fecb97f
5 changed files with 128 additions and 37 deletions

View File

@ -16,6 +16,7 @@
* Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2023 Lenin Rivas <lenin.rivas777@gmail.com>
* Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -235,6 +236,16 @@ if (empty($reshook)) {
}
}
}
} elseif ($action == 'confirm_cancel' && $confirm == 'yes' && $usercanclose) {
// Cancel proposal
$result = $object->setCancel($user);
if ($result > 0) {
header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
exit();
} else {
$langs->load("errors");
setEventMessages($object->error, $object->errors, 'errors');
}
} elseif ($action == 'confirm_delete' && $confirm == 'yes' && $usercandelete) {
// Delete proposal
$result = $object->delete($user);
@ -785,7 +796,7 @@ if (empty($reshook)) {
} elseif ($action == 'confirm_reopen' && $usercanclose && !GETPOST('cancel', 'alpha')) {
// Reopen proposal
// prevent browser refresh from reopening proposal several times
if ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED) {
if ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED || $object->statut == Propal::STATUS_CANCELED) {
$db->begin();
$result = $object->reopen($user, !getDolGlobalString('PROPAL_SKIP_ACCEPT_REFUSE'));
@ -2383,6 +2394,9 @@ if ($action == 'create') {
} else {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?statut=3&id=' . $object->id, $langs->trans('Close'), '', 'confirm_closeas', $formquestion, '', 1, 250);
}
} elseif ($action == 'cancel') {
// Confirm cancel
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans("CancelPropal"), $langs->trans('ConfirmCancelPropal', $object->ref), 'confirm_cancel', '', 0, 1);
} elseif ($action == 'delete') {
// Confirm delete
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteProp'), $langs->trans('ConfirmDeleteProp', $object->ref), 'confirm_delete', '', 0, 1);
@ -3005,7 +3019,7 @@ if ($action == 'create') {
}
// ReOpen
if (((getDolGlobalString('PROPAL_REOPEN_UNSIGNED_ONLY') && $object->statut == Propal::STATUS_NOTSIGNED) || (!getDolGlobalString('PROPAL_REOPEN_UNSIGNED_ONLY') && ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED))) && $usercanclose) {
if (((getDolGlobalString('PROPAL_REOPEN_UNSIGNED_ONLY') && $object->statut == Propal::STATUS_NOTSIGNED) || (!getDolGlobalString('PROPAL_REOPEN_UNSIGNED_ONLY') && ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED || $object->statut == Propal::STATUS_CANCELED))) && $usercanclose) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken().(!getDolGlobalString('MAIN_JUMP_TAG') ? '' : '#reopen').'"';
print '>'.$langs->trans('ReOpen').'</a>';
}
@ -3085,6 +3099,11 @@ if ($action == 'create') {
}
}
// Cancel propal
if ($object->status > Propal::STATUS_DRAFT && $usercanclose) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'">'.$langs->trans("CancelPropal").'</a>';
}
// Clone
if ($usercancreate) {
print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&token='.newToken().'&object='.$object->element.'">'.$langs->trans("ToClone").'</a>';

View File

@ -18,6 +18,7 @@
* Copyright (C) 2022 ATM Consulting <contact@atm-consulting.fr>
* Copyright (C) 2022 OpenDSI <support@open-dsi.fr>
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -136,14 +137,14 @@ class Propal extends CommonObject
* Status of the quote
* @var int
* @deprecated Try to use $status now
* @see Propal::STATUS_DRAFT, Propal::STATUS_VALIDATED, Propal::STATUS_SIGNED, Propal::STATUS_NOTSIGNED, Propal::STATUS_BILLED
* @see Propal::STATUS_DRAFT, Propal::STATUS_VALIDATED, Propal::STATUS_SIGNED, Propal::STATUS_NOTSIGNED, Propal::STATUS_BILLED, Propal::STATUS_CANCELED
*/
public $statut;
/**
* Status of the quote
* @var int
* @see Propal::STATUS_DRAFT, Propal::STATUS_VALIDATED, Propal::STATUS_SIGNED, Propal::STATUS_NOTSIGNED, Propal::STATUS_BILLED
* @see Propal::STATUS_DRAFT, Propal::STATUS_VALIDATED, Propal::STATUS_SIGNED, Propal::STATUS_NOTSIGNED, Propal::STATUS_BILLED, Propal::STATUS_CANCELED
*/
public $status;
@ -373,6 +374,10 @@ class Propal extends CommonObject
);
// END MODULEBUILDER PROPERTIES
/**
* Canceled status
*/
const STATUS_CANCELED = -1;
/**
* Draft status
*/
@ -2859,6 +2864,53 @@ class Propal extends CommonObject
}
}
/**
* Cancel the proposal
*
* @param User $user Object user
* @return int Return integer if KO <0 , if OK >0
*/
public function setCancel(User $user)
{
$error = 0;
$this->db->begin();
$sql = "UPDATE ". MAIN_DB_PREFIX . "propal";
$sql .= " SET fk_statut = " . self::STATUS_CANCELED . ",";
$sql .= " fk_user_modif = " . ((int) $user->id);
$sql .= " WHERE rowid = " . ((int) $this->id);
dol_syslog(get_class($this)."::cancel", LOG_DEBUG);
if ($this->db->query($sql)) {
if (!$error) {
// Call trigger
$result = $this->call_trigger('PROPAL_CANCEL', $user);
if ($result < 0) {
$error++;
}
// End call triggers
}
if (!$error) {
$this->statut = self::STATUS_CANCELED;
$this->db->commit();
return 1;
} else {
foreach ($this->errors as $errmsg) {
dol_syslog(get_class($this)."::cancel ".$errmsg, LOG_ERR);
$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
}
$this->db->rollback();
return -1;
}
} else {
$this->error = $this->db->error();
$this->db->rollback();
return -1;
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Set draft status
@ -3410,11 +3462,13 @@ class Propal extends CommonObject
if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
global $langs;
$langs->load("propal");
$this->labelStatus[-1] = $langs->transnoentitiesnoconv("PropalStatusCanceled");
$this->labelStatus[0] = $langs->transnoentitiesnoconv("PropalStatusDraft");
$this->labelStatus[1] = $langs->transnoentitiesnoconv("PropalStatusValidated");
$this->labelStatus[2] = $langs->transnoentitiesnoconv("PropalStatusSigned");
$this->labelStatus[3] = $langs->transnoentitiesnoconv("PropalStatusNotSigned");
$this->labelStatus[4] = $langs->transnoentitiesnoconv("PropalStatusBilled");
$this->labelStatusShort[-1] = $langs->transnoentitiesnoconv("PropalStatusCanceledShort");
$this->labelStatusShort[0] = $langs->transnoentitiesnoconv("PropalStatusDraftShort");
$this->labelStatusShort[1] = $langs->transnoentitiesnoconv("PropalStatusValidatedShort");
$this->labelStatusShort[2] = $langs->transnoentitiesnoconv("PropalStatusSignedShort");
@ -3423,7 +3477,9 @@ class Propal extends CommonObject
}
$statusType = '';
if ($status == self::STATUS_DRAFT) {
if ($status == self::STATUS_CANCELED) {
$statusType = 'status9';
} elseif ($status == self::STATUS_DRAFT) {
$statusType = 'status0';
} elseif ($status == self::STATUS_VALIDATED) {
$statusType = 'status1';

View File

@ -38,6 +38,8 @@ function isValidSiren($siren)
return false;
}
// TODO : use the Luhn algorithm instead
// we take each figure one by one and:
// - if its index is odd then we double its value,
// - if the latter is higher than 9 then we substract 9 from it,
@ -56,3 +58,41 @@ function isValidSiren($siren)
// the siren is valid if the sum is a multiple of 10
return (($sum % 10) == 0) ? true : false;
}
/**
* Check the validity of a SIRET.
*
* @param string $siret SIRET to check
* @return boolean True if valid, False otherwise
*/
function isValidSiret($siret)
{
$siret = trim($siret);
$siret = preg_replace('/(\s)/', '', $siret);
if (!is_numeric($siret) || dol_strlen($siret) != 14) {
return false;
}
// TODO: use the Luhn algorithm instead
// TODO: handle the exception of "La Poste" (356 000 000 #####)
// we take each figure one by one and:
// - if its index is even then we double its value,
// - if the latter is higher than 9 then we substract 9 from it,
// - and finally we add the result to the overall sum.
$sum = 0;
for ($index = 0; $index < 14; $index++) {
$number = (int) $siret[$index];
if ($index % 2 == 0) {
if (($number *= 2) > 9) {
$number -= 9;
}
}
$sum += $number;
}
// the SIRET is valid if the sum is a multiple of 10
return $sum % 10 == 0;
}

View File

@ -12,9 +12,11 @@ NewPropal=New proposal
Prospect=Prospect
DeleteProp=Delete commercial proposal
ValidateProp=Validate commercial proposal
CancelPropal=Cancel
AddProp=Create proposal
ConfirmDeleteProp=Are you sure you want to delete this commercial proposal?
ConfirmValidateProp=Are you sure you want to validate this commercial proposal under name <b>%s</b>?
ConfirmCancelPropal=Are you sure you want to cancel commercial proposal <b>%s</b>?
LastPropals=Latest %s proposals
LastModifiedProposals=Latest %s modified proposals
AllPropals=All proposals
@ -27,11 +29,13 @@ NbOfProposals=Number of commercial proposals
ShowPropal=Show proposal
PropalsDraft=Drafts
PropalsOpened=Open
PropalStatusCanceled=Canceled (Abandoned)
PropalStatusDraft=Draft (needs to be validated)
PropalStatusValidated=Validated (proposal is open)
PropalStatusSigned=Signed (needs billing)
PropalStatusNotSigned=Not signed (closed)
PropalStatusBilled=Billed
PropalStatusCanceledShort=Canceled
PropalStatusDraftShort=Draft
PropalStatusValidatedShort=Validated (open)
PropalStatusClosedShort=Closed

View File

@ -3846,42 +3846,14 @@ class Societe extends CommonObject
return 1;
}
// Check SIREN if country FR
// Check SIREN
if ($idprof == 1 && $soc->country_code == 'FR' && !isValidSiren($this->idprof1)) {
return -1;
}
// Verifie SIRET si pays FR
if ($idprof == 2 && $soc->country_code == 'FR') {
$chaine = trim($this->idprof2);
$chaine = preg_replace('/(\s)/', '', $chaine);
if (!is_numeric($chaine)) {
return -1;
}
if (dol_strlen($chaine) != 14) {
return -1;
}
// on prend chaque chiffre un par un
// si son index (position dans la chaîne en commence à 0 au premier caractère) est pair
// on double sa valeur et si cette dernière est supérieure à 9, on lui retranche 9
// on ajoute cette valeur à la somme totale
$sum = 0;
for ($index = 0; $index < 14; $index++) {
$number = (int) $chaine[$index];
if (($index % 2) == 0) {
if (($number *= 2) > 9) {
$number -= 9;
}
}
$sum += $number;
}
// le numéro est valide si la somme des chiffres est multiple de 10
if ($sum % 10 != 0) {
return -1;
}
// Check SIRET
if ($idprof == 2 && $soc->country_code == 'FR' && !isValidSiret($this->idprof2)) {
return -1;
}
//Verify CIF/NIF/NIE if pays ES